def write_yaml_with_docker(self, yml_unified, yml_data, script_obj): """Write out the yaml file taking into account the dockerimage45 tag. If it is present will create 2 integration files One for 4.5 and below and one for 5.0. Arguments: output_path {str} -- output path yml_unified {dict} -- unified yml dict yml_data {dict} -- yml object script_obj {dict} -- script object Returns: dict -- dictionary mapping output path to unified data """ output_map = {self.dest_path: yml_unified} if 'dockerimage45' in script_obj: # we need to split into two files 45 and 50. Current one will be from version 5.0 if self.is_script_package: # scripts del yml_unified['dockerimage45'] else: # integrations del yml_unified['script']['dockerimage45'] yml_unified45 = copy.deepcopy(yml_unified) # validate that this is a script/integration which targets both 4.5 and 5.0+. if server_version_compare(yml_data.get('fromversion', '0.0.0'), '5.0.0') >= 0: raise ValueError(f'Failed: {self.dest_path}. dockerimage45 set for 5.0 and later only') yml_unified['fromversion'] = '5.0.0' # validate that this is a script/integration which targets both 4.5 and 5.0+. if server_version_compare(yml_data.get('toversion', '99.99.99'), '5.0.0') < 0: raise ValueError(f'Failed: {self.dest_path}. dockerimage45 set for 4.5 and earlier only') yml_unified45['toversion'] = '4.5.9' if script_obj.get('dockerimage45'): # we have a value for dockerimage45 set it as dockerimage if self.is_script_package: # scripts yml_unified45['dockerimage'] = script_obj.get('dockerimage45') else: # integrations yml_unified45['script']['dockerimage'] = script_obj.get('dockerimage45') else: # no value for dockerimage45 remove the dockerimage entry del yml_unified45['dockerimage'] output_path45 = re.sub(r'\.yml$', '_45.yml', self.dest_path) output_map = { self.dest_path: yml_unified, output_path45: yml_unified45, } for file_path, file_data in output_map.items(): if os.path.isfile(file_path) and self.use_force is False: raise ValueError(f'Output file already exists: {self.dest_path}.' ' Make sure to remove this file from source control' ' or rename this package (for example if it is a v2).') with io.open(file_path, mode='w', encoding='utf-8') as file_: self.ryaml.dump(file_data, file_) return output_map
def check_test_version_compatible_with_server(test, server_version, prints_manager): """ Checks if a given test is compatible wis the given server version. Arguments: test: (dict) Test playbook object from content conf.json. May contain the following fields: "playbookID", "integrations", "instance_names", "timeout", "nightly", "fromversion", "toversion. server_version: (int) The server numerical version. prints_manager: (ParallelPrintsManager) Print manager object. Returns: (bool) True if test is compatible with server version or False otherwise. """ test_from_version = test.get('fromversion', '0.0.0') test_to_version = test.get('toversion', '99.99.99') if (server_version_compare(test_from_version, server_version) > 0 or server_version_compare(test_to_version, server_version) < 0): warning_message = 'Test Playbook: {} was ignored in the content installation test due to version mismatch ' \ '(test versions: {}-{}, server version: {})'.format(test.get('playbookID'), test_from_version, test_to_version, server_version) prints_manager.add_print_job(warning_message, print_warning, 0) return False return True
def is_runnable_in_server_version(from_v, server_v, to_v): """ Checks whether an obj is runnable in a version Args: from_v (string): string representing Demisto version (fromversion comparable) server_v (string): string representing Demisto version (version to be ran on) to_v (string): string representing Demisto version (toversion comparable) Returns: bool. true if obj is runnable """ return server_version_compare(from_v, server_v) <= 0 and server_version_compare(server_v, to_v) <= 0
def release_notes_section(self, store, title_prefix, current_server_version): res = "" beta_rn_paths = list() if store: new_str = "" new_count = 0 for path in store: with open(path, 'r') as file_obj: raw_content = file_obj.read() cnt = self.load_data(raw_content) from_version = cnt.get("fromversion") or cnt.get("fromVersion") to_version = cnt.get("toversion") or cnt.get("toVersion") if from_version is not None and server_version_compare(current_server_version, from_version) < 0: print(f'{path}: Skipped because from version: {from_version}' f' is greater than current server version: {current_server_version}') beta_rn_paths.append(path) print(f"{path} has added to beta release notes") continue if to_version is not None and server_version_compare(to_version, current_server_version) < 0: print(f'{path}: Skipped because of to version" {to_version}' f' is smaller: than current server version: {current_server_version}') continue if title_prefix == NEW_RN: ans = self.added_release_notes(path, cnt) elif title_prefix == MODIFIED_RN: ans = self.modified_release_notes(path, cnt) else: # should never get here print_error('Error:\n Unknown release notes type {}'.format(title_prefix)) return None if ans is None: print_error("Error:\n[{}] is missing releaseNotes entry, Please add it under {}".format( path, get_release_notes_file_path(path))) self.is_missing_release_notes = True elif ans: new_count += 1 new_str += ans if new_str: if self.show_secondary_header: count_str = "" if new_count > 1: count_str = " " + str(new_count) res = "\n#### %s %s %s\n" % (count_str, title_prefix, self.get_header()) res += new_str print("Collected {} beta notes".format(len(beta_rn_paths))) return res, beta_rn_paths
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 is_valid_pwsh(self) -> bool: if self.current_file.get("type") == TYPE_PWSH: from_version = self.current_file.get("fromversion", "0.0.0") if not from_version or server_version_compare("5.5.0", from_version) > 0: print_error(Errors.pwsh_wrong_version(self.file_path, from_version)) print_error(Errors.suggest_fix(self.file_path, '--from-version', '5.5.0')) return False return True
def is_valid_pwsh(self) -> bool: if self.current_file.get("script", {}).get("type") == TYPE_PWSH: from_version = self.current_file.get("fromversion", "0.0.0") if not from_version or server_version_compare("5.5.0", from_version) > 0: error_message, error_code = Errors.pwsh_wrong_version(from_version) if self.handle_error(error_message, error_code, file_path=self.file_path, suggested_fix=Errors.suggest_fix(self.file_path, '--from-version', '5.5.0')): return False return True
def is_valid_pwsh(self) -> bool: if self.current_file.get('type') == TYPE_PWSH: from_version = self.current_file.get('fromversion', DEFAULT_CONTENT_ITEM_FROM_VERSION) if not from_version or server_version_compare('5.5.0', from_version) > 0: error_message, error_code = Errors.pwsh_wrong_version(from_version) if self.handle_error(error_message, error_code, file_path=self.file_path, suggested_fix=Errors.suggest_fix(self.file_path, '--from-version', '5.5.0')): return False return True
def is_valid_feed(self): # type: () -> bool if self.current_file.get("script", {}).get("feed"): from_version = self.current_file.get("fromversion", "0.0.0") if not from_version or server_version_compare( "5.5.0", from_version) == 1: print_error( Errors.feed_wrong_from_version(self.file_path, from_version)) return False return True
def is_valid_feed(self): # type: () -> bool valid_from_version = valid_feed_params = True if self.current_file.get("script", {}).get("feed"): from_version = self.current_file.get("fromversion", "0.0.0") if not from_version or server_version_compare("5.5.0", from_version) == 1: error_message, error_code = Errors.feed_wrong_from_version(from_version) if self.handle_error(error_message, error_code, file_path=self.file_path, suggested_fix=Errors.suggest_fix(self.file_path, '--from-version', '5.5.0')): valid_from_version = False valid_feed_params = self.all_feed_params_exist() return valid_from_version and valid_feed_params
def is_valid_feed(self): # type: () -> bool valid_from_version = valid_feed_params = True if self.current_file.get("script", {}).get("feed"): from_version = self.current_file.get("fromversion", "0.0.0") if not from_version or server_version_compare( "5.5.0", from_version) == 1: print_error( Errors.feed_wrong_from_version(self.file_path, from_version)) valid_from_version = False valid_feed_params = self.all_feed_params_exist() return valid_from_version and valid_feed_params
def is_docker_image_changed(self): # type: () -> bool """Check if the docker image as been changed.""" # Unnecessary to check docker image only on 5.0 and up if server_version_compare(self.old_file.get('fromversion', '0'), '5.0.0') < 0: old_docker = get_dockerimage45(self.old_file) new_docker = get_dockerimage45(self.current_file) if old_docker != new_docker: print_error( Errors.breaking_backwards_docker(self.file_path, old_docker, new_docker)) return True return False
def is_docker_image_changed(self): """Check if the Docker image was changed or not.""" # Unnecessary to check docker image only on 5.0 and up if server_version_compare(self.old_file.get('fromversion', '0'), '5.0.0') < 0: old_docker = get_dockerimage45(self.old_file.get('script', {})) new_docker = get_dockerimage45(self.current_file.get('script', {})) if old_docker != new_docker: print_error( Errors.breaking_backwards_docker(self.file_path, old_docker, new_docker)) self.is_valid = False return True return False
def should_clear(file_path, current_server_version="0.0.0"): """ scan folder and remove all references to release notes :param file_path: path of the yml/json file :param current_server_version: current server version """ data = get_file_data(file_path) if not data: return False version = data.get('fromversion') or data.get('fromVersion') if version and server_version_compare(current_server_version, str(version)) < 0: print_warning('keeping release notes for ({})\nto be published on {} version release'.format(file_path, version)) return False return True
def test_server_version_compare(self, left, right, answer): assert server_version_compare(left, right) == answer
def write_yaml_with_docker(self, yml_unified, yml_data, script_obj): """Write out the yaml file taking into account the dockerimage45 tag. If it is present will create 2 integration files One for 4.5 and below and one for 5.0. Arguments: output_path {str} -- output path yml_unified {dict} -- unified yml dict yml_data {dict} -- yml object script_obj {dict} -- script object Returns: dict -- dictionary mapping output path to unified data """ output_map = {self.dest_path: yml_unified} if 'dockerimage45' in script_obj: # we need to split into two files 45 and 50. Current one will be from version 5.0 if self.is_script_package: # scripts del yml_unified['dockerimage45'] else: # integrations del yml_unified['script']['dockerimage45'] yml_unified45 = copy.deepcopy(yml_unified) # validate that this is a script/integration which targets both 4.5 and 5.0+. if server_version_compare( yml_data.get('fromversion', DEFAULT_CONTENT_ITEM_FROM_VERSION), '5.0.0') >= 0: raise ValueError( f'Failed: {self.dest_path}. dockerimage45 set for 5.0 and later only' ) yml_unified['fromversion'] = '5.0.0' # validate that this is a script/integration which targets both 4.5 and 5.0+. if server_version_compare( yml_data.get('toversion', DEFAULT_CONTENT_ITEM_TO_VERSION), '5.0.0') < 0: raise ValueError( f'Failed: {self.dest_path}. dockerimage45 set for 4.5 and earlier only' ) yml_unified45['toversion'] = '4.5.9' if script_obj.get( 'dockerimage45' ): # we have a value for dockerimage45 set it as dockerimage if self.is_script_package: # scripts yml_unified45['dockerimage'] = script_obj.get( 'dockerimage45') else: # integrations yml_unified45['script']['dockerimage'] = script_obj.get( 'dockerimage45') else: # no value for dockerimage45 remove the dockerimage entry del yml_unified45['dockerimage'] output_path45 = re.sub(r'\.yml$', '_45.yml', self.dest_path) # type: ignore[type-var] output_map = { self.dest_path: yml_unified, output_path45: yml_unified45, } for file_path, file_data in output_map.items(): self._output_yaml(file_path, file_data) return output_map