diff --git a/CHANGELOG.md b/CHANGELOG.md index cd840f5ca39..40f0edd8b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * Fixed an issue where **update-release-notes** would fail to bump new versions if the feature branch was out of sync with the master branch. * Fixed an issue where a non-descriptive error would be returned when giving the **update-release-notes** command a pack which can not be found. * Added dependencies check for *widgets* in **find-dependencies** command. +* Added a `update-docker` flag to **format** command. * Added a `json-to-outputs` flag to the **run** command. * Added a verbose (`-v`) flag to **format** command. * Fixed an issue where **download** added the prefix "playbook-" to the name of playbooks. diff --git a/demisto_sdk/__main__.py b/demisto_sdk/__main__.py index b4b09028531..eaac4a189a8 100644 --- a/demisto_sdk/__main__.py +++ b/demisto_sdk/__main__.py @@ -447,10 +447,12 @@ def lint(input: str, git: bool, all_packs: bool, verbose: int, quiet: bool, para "-fv", "--from-version", help="Specify fromversion of the pack") @click.option( "-nv", "--no-validate", help="Set when validate on file is not wanted", is_flag=True) +@click.option( + "-ud", "--update-docker", help="Set if you want to update the docker image of the integration/script", is_flag=True) @click.option( "-v", "--verbose", help="Verbose output", is_flag=True) -def format_yml(input=None, output=None, from_version=None, no_validate=None, verbose=False): - return format_manager(input, output, from_version, no_validate, verbose) +def format_yml(**kwargs): + return format_manager(**kwargs) # ====================== upload ====================== # diff --git a/demisto_sdk/commands/common/errors.py b/demisto_sdk/commands/common/errors.py index 8a045ef4cf8..a9274dd98e5 100644 --- a/demisto_sdk/commands/common/errors.py +++ b/demisto_sdk/commands/common/errors.py @@ -454,12 +454,13 @@ def docker_not_formatted_correctly(docker_image): @staticmethod @error_code_decorator - def docker_not_on_the_latest_tag(docker_image_tag, docker_image_latest_tag, docker_image_name): + def docker_not_on_the_latest_tag(docker_image_tag, docker_image_latest_tag, docker_image_name, file_path): return f'The docker image tag is not the latest numeric tag, please update it.\n' \ f'The docker image tag in the yml file is: {docker_image_tag}\n' \ f'The latest docker image tag in docker hub is: {docker_image_latest_tag}\n' \ f'You can check for the most updated version of {docker_image_name} ' \ - f'here: https://hub.docker.com/r/{docker_image_name}/tags\n' + f'here: https://hub.docker.com/r/{docker_image_name}/tags\n' \ + f'To update the docker image run: demisto-sdk format -ud -i {file_path}\n' @staticmethod @error_code_decorator diff --git a/demisto_sdk/commands/common/hook_validations/docker.py b/demisto_sdk/commands/common/hook_validations/docker.py index a62d103de48..4a0e404c676 100644 --- a/demisto_sdk/commands/common/hook_validations/docker.py +++ b/demisto_sdk/commands/common/hook_validations/docker.py @@ -79,7 +79,8 @@ def is_docker_image_latest_tag(self): # If docker image tag is not the most updated one that exists in docker-hub error_message, error_code = Errors.docker_not_on_the_latest_tag(self.docker_image_tag, self.docker_image_latest_tag, - self.docker_image_name) + self.docker_image_name, + self.file_path) if self.handle_error(error_message, error_code, file_path=self.file_path): self.is_latest_tag = False diff --git a/demisto_sdk/commands/format/README.md b/demisto_sdk/commands/format/README.md index c291443c5c3..2a08b57483c 100644 --- a/demisto_sdk/commands/format/README.md +++ b/demisto_sdk/commands/format/README.md @@ -27,6 +27,10 @@ When done formatting, the **validate** command will run, to let you know of thin When no validation on file is needed. +* **-ud ,--update-docker** + + Set if you want to update the docker image of the integration/script to the newest available tag. + ### Examples ``` demisto-sdk format diff --git a/demisto_sdk/commands/format/format_module.py b/demisto_sdk/commands/format/format_module.py index eb21c8cfdd5..449044fac92 100644 --- a/demisto_sdk/commands/format/format_module.py +++ b/demisto_sdk/commands/format/format_module.py @@ -63,8 +63,8 @@ VALIDATE_RES_FAILED_CODE = 3 -def format_manager(input: str = None, output: str = None, from_version: str = '', no_validate: bool = None, - verbose: bool = False): +def format_manager(input: str = None, output: str = None, from_version: str = '', no_validate: bool = False, + verbose: bool = False, update_docker: bool = False): """ Format_manager is a function that activated format command on different type of files. Args: @@ -73,6 +73,7 @@ def format_manager(input: str = None, output: str = None, from_version: str = '' output: (str) The path to save the formatted file to. no_validate (flag): Whether the user specifies not to run validate after format. verbose (bool): Whether to print verbose logs or not + update_docker (flag): Whether to update the docker image. Returns: int 0 in case of success 1 otherwise """ @@ -95,7 +96,7 @@ def format_manager(input: str = None, output: str = None, from_version: str = '' file_type = file_type.value info_res, err_res, skip_res = run_format_on_file(input=file_path, file_type=file_type, from_version=from_version, output=output, - no_validate=no_validate, verbose=verbose) + no_validate=no_validate, verbose=verbose, update_docker=update_docker) if err_res: error_list.append("err_res") if err_res: @@ -130,6 +131,9 @@ def run_format_on_file(input: str, file_type: str, from_version: str, **kwargs) """ schema_path = os.path.normpath( os.path.join(__file__, "..", "..", "common", SCHEMAS_PATH, '{}.yml'.format(file_type))) + if file_type not in ('integration', 'script') and 'update_docker' in kwargs: + # non code formatters don't support update_docker param. remove it + del kwargs['update_docker'] UpdateObject = FILE_TYPE_AND_LINKED_CLASS[file_type](input=input, path=schema_path, from_version=from_version, **kwargs) diff --git a/demisto_sdk/commands/format/tests/test_formatting_yml_test.py b/demisto_sdk/commands/format/tests/test_formatting_yml_test.py index feb601f68d1..d58a56b0c31 100644 --- a/demisto_sdk/commands/format/tests/test_formatting_yml_test.py +++ b/demisto_sdk/commands/format/tests/test_formatting_yml_test.py @@ -6,6 +6,8 @@ import yaml from demisto_sdk.commands.common.constants import (FEED_REQUIRED_PARAMS, FETCH_REQUIRED_PARAMS) +from demisto_sdk.commands.common.hook_validations.docker import \ + DockerImageValidator from demisto_sdk.commands.format.format_module import format_manager from demisto_sdk.commands.format.update_integration import IntegrationYMLFormat from demisto_sdk.commands.format.update_playbook import (PlaybookYMLFormat, @@ -440,3 +442,35 @@ def test_run_format_on_tpb(): assert formatter.data.get('fromversion') == '5.0.0' os.remove(DESTINATION_FORMAT_TEST_PLAYBOOK) os.rmdir(TEST_PLAYBOOK_PATH) + + +def test_update_docker_format(tmpdir, mocker): + """Test that script and integration formatter update docker image tag + """ + test_tag = '1.0.0-test-tag' + mocker.patch.object(DockerImageValidator, 'get_docker_image_latest_tag_request', return_value=test_tag) + schema_dir = f'{GIT_ROOT}/demisto_sdk/commands/common/schemas' + test_files_dir = f'{GIT_ROOT}/demisto_sdk/tests/test_files/update-docker' + dest = str(tmpdir.join('docker-res.yml')) + + # test example script file with version before 5.0.0 + src_file = f'{test_files_dir}/SlackAsk.yml' + with open(src_file) as f: + data = yaml.safe_load(f) + org_docker = data['dockerimage'] + assert data['fromversion'] < '5.0.0' + assert not data.get('dockerimage45') # make sure for the test that dockerimage45 is not set (so we can verify that we set it in format) + format_obj = ScriptYMLFormat(src_file, output=dest, path=f'{schema_dir}/script.yml', no_validate=True, update_docker=True) + assert format_obj.run_format() == 0 + with open(dest) as f: + data = yaml.safe_load(f) + assert data['dockerimage'].endswith(f':{test_tag}') + assert data['dockerimage45'] == org_docker + + # test integration file + src_file = f'{test_files_dir}/Slack.yml' + format_obj = IntegrationYMLFormat(src_file, output=dest, path=f'{schema_dir}/integration.yml', no_validate=True, update_docker=True) + assert format_obj.run_format() == 0 + with open(dest) as f: + data = yaml.safe_load(f) + assert data['script']['dockerimage'].endswith(f':{test_tag}') diff --git a/demisto_sdk/commands/format/update_integration.py b/demisto_sdk/commands/format/update_integration.py index 2e2799f8ce3..b09bb9b3e56 100644 --- a/demisto_sdk/commands/format/update_integration.py +++ b/demisto_sdk/commands/format/update_integration.py @@ -11,6 +11,7 @@ SKIP_RETURN_CODE, SUCCESS_RETURN_CODE) from demisto_sdk.commands.format.update_generic_yml import BaseUpdateYML +from demisto_sdk.commands.format.update_script import ScriptYMLFormat class IntegrationYMLFormat(BaseUpdateYML): @@ -27,9 +28,9 @@ class IntegrationYMLFormat(BaseUpdateYML): } def __init__(self, input: str = '', output: str = '', path: str = '', from_version: str = '', - no_validate: bool = False, verbose: bool = False): - super().__init__(input=input, output=output, path=path, from_version=from_version, no_validate=no_validate, - verbose=verbose) + no_validate: bool = False, verbose: bool = False, update_docker: bool = False): + super().__init__(input, output, path, from_version, no_validate, verbose=verbose) + self.update_docker = update_docker if not from_version and self.data.get("script", {}).get("type") == TYPE_PWSH: self.from_version = '5.5.0' @@ -112,6 +113,10 @@ def set_feed_params_in_config(self): if param not in params: self.data['configuration'].append(param) + def update_docker_image(self): + if self.update_docker: + ScriptYMLFormat.update_docker_image_in_script(self.data['script'], self.data.get(self.from_version_key)) + def run_format(self) -> int: try: click.secho(f'\n======= Updating file: {self.source_file} =======', fg='white') @@ -122,6 +127,7 @@ def run_format(self) -> int: self.set_reputation_commands_basic_argument_as_needed() self.set_fetch_params_in_config() self.set_feed_params_in_config() + self.update_docker_image() self.save_yml_to_destination_file() return SUCCESS_RETURN_CODE except Exception: diff --git a/demisto_sdk/commands/format/update_script.py b/demisto_sdk/commands/format/update_script.py index b34bb8ad0f1..cbdbbfd2631 100644 --- a/demisto_sdk/commands/format/update_script.py +++ b/demisto_sdk/commands/format/update_script.py @@ -1,8 +1,12 @@ -from typing import Tuple +from typing import Optional, Tuple import click -from demisto_sdk.commands.common.constants import TYPE_PWSH +from demisto_sdk.commands.common.constants import TYPE_JS, TYPE_PWSH +from demisto_sdk.commands.common.hook_validations.docker import \ + DockerImageValidator from demisto_sdk.commands.common.hook_validations.script import ScriptValidator +from demisto_sdk.commands.common.tools import (LOG_COLORS, print_color, + server_version_compare) from demisto_sdk.commands.format.format_constants import (ERROR_RETURN_CODE, SKIP_RETURN_CODE, SUCCESS_RETURN_CODE) @@ -17,18 +21,52 @@ class ScriptYMLFormat(BaseUpdateYML): output (str): the desired file name to save the updated version of the YML to. """ - def __init__(self, input: str = '', output: str = '', path: str = '', from_version: str = '', - no_validate: bool = False, verbose: bool = False): - super().__init__(input=input, output=output, path=path, from_version=from_version, no_validate=no_validate, - verbose=verbose) + def __init__(self, input: str = '', output: str = '', path: str = '', from_version: str = '', no_validate: bool = False, + update_docker: bool = False, verbose: bool = False): + super().__init__(input, output, path, from_version, no_validate, verbose=verbose) + self.update_docker = update_docker if not from_version and self.data.get("type") == TYPE_PWSH: self.from_version = '5.5.0' + @staticmethod + def update_docker_image_in_script(script_obj: dict, from_version: Optional[str] = None): + """Update the docker image for the passed script object. Will ignore if this is a javascript + object or using default image (not set). + + Args: + script_obj (dict): script object + """ + if script_obj.get('type') == TYPE_JS: + print_color('Skipping docker image update as this is a Javascript automation.', LOG_COLORS.YELLOW) + return + dockerimage = script_obj.get('dockerimage') + if not dockerimage: # default image -> nothing to do + print_color('Skipping docker image update as default docker image is being used.', LOG_COLORS.YELLOW) + return + image_name = dockerimage.split(':')[0] + latest_tag = DockerImageValidator.get_docker_image_latest_tag_request(image_name) + full_name = f'{image_name}:{latest_tag}' + if full_name != dockerimage: + print(f'Updating docker image to: {full_name}') + script_obj['dockerimage'] = full_name + if (not from_version) or server_version_compare('5.0.0', from_version): + # if this is a script that supports 4.5 and earlier. Make sure dockerimage45 is set + if not script_obj.get('dockerimage45'): + print(f'Setting dockerimage45 to previous image value: {dockerimage} for 4.5 and earlier support') + script_obj['dockerimage45'] = dockerimage + else: + print(f'Already using latest docker image: {dockerimage}. Nothing to update.') + + def update_docker_image(self): + if self.update_docker: + self.update_docker_image_in_script(self.data, self.data.get(self.from_version_key)) + def run_format(self) -> int: try: click.secho(f'\n======= Updating file: {self.source_file} =======', fg='white') super().update_yml() self.update_tests() + self.update_docker_image() self.save_yml_to_destination_file() return SUCCESS_RETURN_CODE except Exception: diff --git a/demisto_sdk/tests/test_files/update-docker/Slack.yml b/demisto_sdk/tests/test_files/update-docker/Slack.yml new file mode 100644 index 00000000000..f7b6345b2d9 --- /dev/null +++ b/demisto_sdk/tests/test_files/update-docker/Slack.yml @@ -0,0 +1,535 @@ +category: Messaging +commonfields: + id: SlackV2 + version: -1 +configuration: +- display: Slack API access token + name: access_token + required: true + type: 4 +- display: Slack API bot token + name: bot_token + required: true + type: 4 +- display: Dedicated Slack channel to receive notifications + name: incidentNotificationChannel + required: false + type: 0 +- defaultvalue: 'true' + display: Send notifications about incidents to the dedicated channel + name: notify_incidents + required: false + type: 8 +- defaultvalue: Low + display: Minimum incident severity to send messages to slack by + name: min_severity + options: + - Unknown + - Low + - Medium + - High + - Critical + required: false + type: 15 +- defaultvalue: Unclassified + display: Type of incidents created in Slack + name: incidentType + required: false + type: 13 +- display: Allow external users to create incidents via DM + name: allow_incidents + required: false + type: 8 +- display: Use system proxy settings + name: proxy + required: false + type: 8 +- display: Trust any certificate (not secure) + name: unsecure + required: false + type: 8 +- defaultvalue: 'true' + display: Long running instance. Required for investigation mirroring and direct + messages. + hidden: true + name: longRunning + required: false + type: 8 +- display: Bot display name in Slack (Cortex XSOAR by default) + name: bot_name + required: false + type: 0 +- display: Bot icon in Slack - Image URL (Cortex XSOAR icon by default) + name: bot_icon + required: false + type: 0 +- defaultvalue: '60' + display: Maximum time to wait for a rate limiting call in seconds + name: max_limit_time + required: false + type: 0 +- defaultvalue: '200' + display: Number of objects to return in each paginated call + name: paginated_count + required: false + type: 0 +- display: Proxy URL to use in Slack API calls + name: proxy_url + required: false + type: 0 +description: Send messages and notifications to your Slack team. +display: Slack v2 +name: SlackV2 +script: + commands: + - arguments: + - auto: PREDEFINED + default: true + defaultValue: all + description: The mirroring type. Can be "all", which mirrors everything, "chat", + which mirrors only chats (not commands), or "none", which stops all mirroring. + isArray: false + name: type + predefined: + - all + - chat + - none + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'true' + description: Whether the channel is auto-closed when an investigation is closed. + Can be "true" or "false". Default is "true". + isArray: false + name: autoclose + predefined: + - 'true' + - 'false' + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: both + description: The mirroring direction. Can be "FromDemisto", "ToDemisto", or + "Both". Default is "Both". + isArray: false + name: direction + predefined: + - Both + - FromDemisto + - ToDemisto + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: group + description: The channel type. Can be "channel" (public) or "group" (private). + isArray: false + name: mirrorTo + predefined: + - channel + - group + required: false + secret: false + deprecated: true + description: Deprecated. Use the "mirror-investigation" command instead. + execution: false + name: slack-mirror-investigation + - arguments: + - auto: PREDEFINED + default: true + defaultValue: all + description: The mirroring type. Can be "all", which mirrors everything, "chat", + which mirrors only chats (not commands), or "none", which stops all mirroring. + isArray: false + name: type + predefined: + - all + - chat + - none + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'true' + description: Whether the channel is auto-closed when an investigation is closed. + Can be "true" or "false". Default is "true". + isArray: false + name: autoclose + predefined: + - 'true' + - 'false' + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: both + description: The mirroring direction. Can be "FromDemisto", "ToDemisto", or + "Both". Default value is "Both". + isArray: false + name: direction + predefined: + - Both + - FromDemisto + - ToDemisto + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: group + description: The channel type. Can be "channel" or "group". The default value + is "group". + isArray: false + name: mirrorTo + predefined: + - channel + - group + required: false + secret: false + - default: false + description: The name of the channel. The default is "incident-". + isArray: false + name: channelName + required: false + secret: false + - default: false + description: The topic of the channel. + isArray: false + name: channelTopic + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'false' + description: Whether to remove the Slack administrator (channel creator) from + the mirrored channel. + isArray: false + name: kickAdmin + predefined: + - 'true' + - 'false' + required: false + secret: false + deprecated: false + description: Mirrors the investigation between Slack and the Demisto War Room. + execution: false + name: mirror-investigation + - arguments: + - default: true + description: The message content. + isArray: false + name: message + required: false + secret: false + - default: false + description: The user to whom to send the message. Can be either the username + or email address. + isArray: false + name: to + required: false + secret: false + - default: false + description: The name of the Slack channel to which to send the message. + isArray: false + name: channel + required: false + secret: false + - default: false + description: An entry ID to send as a link. + isArray: false + name: entry + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'false' + description: Whether to include a URL to the relevant component in Demisto. + Can be "true" or "false". Default value is "false". + isArray: false + name: ignoreAddURL + predefined: + - 'true' + - 'false' + required: false + secret: false + - default: false + description: The ID of the thread to which to reply - can be retrieved from + a previous send-notification command. + isArray: false + name: threadID + required: false + secret: false + - default: false + description: A JSON string of Slack blocks to send in the message. + isArray: false + name: blocks + required: false + secret: false + deprecated: false + description: Sends a message to a user, group, or channel. + execution: false + name: send-notification + outputs: + - contextPath: Slack.Thread.ID + description: The Slack thread ID. + type: String + - arguments: + - default: true + description: The text content of the message. + isArray: false + name: message + required: false + secret: false + - default: false + description: Either a user name or email of a Slack user to send to. + isArray: false + name: to + required: false + secret: false + - default: false + description: A Slack channel name to send to. + isArray: false + name: channel + required: false + secret: false + - default: false + description: A Slack group (private channel) name to send to. + isArray: false + name: group + required: false + secret: false + - default: false + description: An entry ID to send as a link. + isArray: false + name: entry + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'false' + description: Whether to add a URL in Slack to the relevant component in Demisto. + Default is "false". + isArray: false + name: IgnoreAddURL + predefined: + - 'true' + - 'false' + required: false + secret: false + - default: false + description: The ID of the thread to which to reply. + isArray: false + name: threadID + required: false + secret: false + deprecated: true + description: Deprecated. Use the "send-notification" command instead. + execution: false + name: slack-send + - deprecated: true + description: Deprecated. Use the "close-channel" command instead. + execution: false + name: slack-close-channel + - arguments: + - default: false + description: The name of the channel to archive. If not provided, the mirrored + investigation channel is archived (if the channel exists). + isArray: false + name: channel + required: false + secret: false + deprecated: false + description: Archives a Slack channel. + execution: false + name: close-channel + - arguments: + - default: true + description: The ID of the file entry to send. + isArray: false + name: file + required: true + secret: false + - default: false + description: The user to whom to send the file. Can be the username or the email + address. + isArray: false + name: to + required: false + secret: false + - default: false + description: The name of the Slack group (private channel) to which to send + the file. + isArray: false + name: group + required: false + secret: false + - default: false + description: The name of the Slack channel to which to send the file. + isArray: false + name: channel + required: false + secret: false + - default: false + description: The ID of the thread to which to reply - can be retrieved from + a previous send-notification command. + isArray: false + name: threadID + required: false + secret: false + - default: false + description: A comment to add to the file. + isArray: false + name: comment + required: false + secret: false + deprecated: false + description: Sends a file to a user, channel, or group. If not specified, the + file is sent to the mirrored investigation channel (if the channel exists). + execution: false + name: slack-send-file + - arguments: + - default: false + description: The channel name. If not specified, the topic of the mirrored investigation + channel is set (if the channel exists). + isArray: false + name: channel + required: false + secret: false + - default: true + description: The topic for the channel. + isArray: false + name: topic + required: true + secret: false + deprecated: false + description: Sets the topic for a channel. + execution: false + name: slack-set-channel-topic + - arguments: + - auto: PREDEFINED + default: false + defaultValue: private + description: The channel type. Can be "private" or "public". + isArray: false + name: type + predefined: + - private + - public + required: false + secret: false + - default: true + description: The name of the channel. + isArray: false + name: name + required: true + secret: false + - default: false + description: 'A CSV list of user names or email addresses to invite to the channel. + For example: "user1, user2...".' + isArray: false + name: users + required: false + secret: false + deprecated: false + description: Creates a channel in Slack. + execution: false + name: slack-create-channel + - arguments: + - default: true + description: 'A CSV list of usernames or email addresses to invite to join the + channel. For example: "user1, user2...".' + isArray: false + name: users + required: true + secret: false + - default: false + description: The name of the channel to which to invite the users. If the name + of the channel is not specified, the name of the mirrored investigation channel + is used (if the channel exists). + isArray: false + name: channel + required: false + secret: false + deprecated: false + description: Invites users to join a channel. + execution: false + name: slack-invite-to-channel + - arguments: + - default: true + description: 'A CSV list of usernames or email addresses to remove from the + a channel. For example: "user1, user2..."' + isArray: false + name: users + required: true + secret: false + - default: false + description: The name of the channel from which to remove the users. If the + name of the channel is not specified, the mirrored investigation channel is + used (if the channel exists). + isArray: false + name: channel + required: false + secret: false + deprecated: false + description: Removes users from the specified channel. + execution: false + name: slack-kick-from-channel + - arguments: + - default: true + description: The new name of the channel. + isArray: false + name: name + required: true + secret: false + - default: false + description: The current name of the channel. If the name of the channel is + not specified, the mirrored investigation channel is used (if the channel + exists). + isArray: false + name: channel + required: false + secret: false + deprecated: false + description: Renames a channel in Slack. + execution: false + name: slack-rename-channel + - arguments: + - default: true + description: The Slack user (username or email). + isArray: false + name: user + required: true + secret: false + deprecated: false + description: Get details about a specified user. + execution: false + name: slack-get-user-details + outputs: + - contextPath: Slack.User.ID + description: The ID of the user. + type: String + - contextPath: Slack.User.Username + description: The username of the user. + type: String + - contextPath: Slack.User.Name + description: The actual name of the user. + type: String + - contextPath: Slack.User.DisplayName + description: The display name of the user. + type: String + - contextPath: Slack.User.Email + description: The email address of the user. + type: String + dockerimage: demisto/slack:1.0.0.9589 + feed: false + isfetch: false + longRunning: true + longRunningPort: false + runonce: false + script: '-' + subtype: python3 + type: python +fromversion: 5.0.0 +tests: + - no test - to skip test prompt diff --git a/demisto_sdk/tests/test_files/update-docker/SlackAsk.yml b/demisto_sdk/tests/test_files/update-docker/SlackAsk.yml new file mode 100644 index 00000000000..731de01984b --- /dev/null +++ b/demisto_sdk/tests/test_files/update-docker/SlackAsk.yml @@ -0,0 +1,128 @@ +args: +- default: false + description: The Slack user to which to send the message. Can be either an email + address or a Slack user name. + isArray: false + name: user + required: false + secret: false +- default: false + description: The Slack channel to which to send the message. + isArray: false + name: channel + required: false + secret: false +- default: false + description: The message to send to the user or channel. + isArray: false + name: message + required: true + secret: false +- default: false + defaultValue: Yes#green + description: The first reply option. The default is "Yes" with a green button. To + change the color of the button, add the pound sign (#) followed by the name of + the new color (green, red, or black). The default color is "green". For example, + "Yes#green". + isArray: false + name: option1 + required: false + secret: false +- default: false + defaultValue: No#red + description: The second reply option. The default is "No" with a red button. To + change the button color, add the pound sign (#) followed by the name of the new + color (green, red, or black). The default color is "red". For example, "No#red". + isArray: false + name: option2 + required: false + secret: false +- default: false + description: The task to close with the reply. If empty, then no playbook tasks + will be closed. + isArray: false + name: task + required: false + secret: false +- default: false + description: Tag to add to email reply entries. + isArray: false + name: replyEntriesTag + required: false + secret: false +- auto: PREDEFINED + default: false + defaultValue: 'false' + description: Indicates whether to use one-time entitlement or persistent entitlement. + isArray: false + name: persistent + predefined: + - 'true' + - 'false' + required: false + secret: false +- auto: PREDEFINED + default: false + defaultValue: buttons + description: How the user should respond to the question. + isArray: false + name: responseType + predefined: + - buttons + - thread + required: false + secret: false +- default: false + description: A comma-separated list of additional options in the format of "option#color", + for example, "maybe#red". The default color is "black". + isArray: false + name: additionalOptions + required: false + secret: false +- default: false + defaultValue: Thank you for your response. + description: The reply to send to the user. Use the templates {user} and {response} + to incorporate these in the reply. (i.e. "Thank you {user}. You have answered + {response}.") + isArray: false + name: reply + required: false + secret: false +- default: false + defaultValue: 1 day + description: Time until the question expires. For example - 1 day. When it expires, + a default response is sent. + isArray: false + name: lifetime + required: false + secret: false +- default: false + defaultValue: NoResponse + description: Default response in case the question expires. + isArray: false + name: defaultResponse + required: false + secret: false +comment: Sends a message (question) to either user (in a direct message) or to a channel. + The message includes predefined reply options. The response can also close a task + (might be conditional) in a playbook. +commonfields: + id: SlackAsk + version: -1 +enabled: true +name: SlackAsk +script: '-' +subtype: python3 +system: false +tags: +- slack +timeout: '0' +type: python +dockerimage: demisto/python3:3.8.3.9324 +runonce: false +tests: +- no test - Untestable +dependson: + must: + - send-notification +fromversion: 4.5.0 # set to 4.5 to test the update docker add dockerimage45