def _filter_unsupported_templates(self): """Remove template descriptors which is not supported.""" # No need to filter templates if CSE is configured in legacy mode. if self.legacy_mode: msg = "Skipping filtering templates as CSE is being" \ " executed in legacy mode" self.filtered_cookbook = self.unfiltered_cookbook self.logger.debug(msg) self.msg_update_callback.general(msg) return # Fetch current CSE version current_cse_version = server_utils.get_installed_cse_version() supported_templates = [] for template_description in self.unfiltered_cookbook['templates']: # only include the template if the current CSE version # supports it # template is supported if current CSE version is between # min_cse_version and max_cse_version of the template template_supported_cse_versions = semantic_version.SimpleSpec( f">={template_description[RemoteTemplateKey.MIN_CSE_VERSION]}," f"<={template_description[RemoteTemplateKey.MAX_CSE_VERSION]}") msg = f"Template {template_description['name']}" if template_supported_cse_versions.match(current_cse_version): msg += " is supported" supported_templates.append(template_description) else: msg += " is not supported" msg += f" by CSE {current_cse_version}" self.logger.debug(msg) self.msg_update_callback.general(msg) self.filtered_cookbook = {'templates': supported_templates} msg = "Successfully filtered unsupported templates." self.logger.debug(msg) self.msg_update_callback.general(msg)
def _filter_unsupported_templates(self): """Remove template descriptors which is not supported.""" # No need to filter templates if CSE is configured in legacy mode. if self.legacy_mode: msg = "Skipping filtering templates as CSE is being" \ " executed in legacy mode" self.filtered_cookbook = self.unfiltered_cookbook self.logger.debug(msg) self.msg_update_callback.general(msg) return # Cookbook version 1.0 doesn't have supported version information. if self.cookbook_version < \ RemoteTemplateCookbookVersion.Version2.value: msg = "Skipping filtering templates as cookbook version " \ f"{self.cookbook_version} doesn't have supported " \ "CSE version information." self.logger.debug(msg) self.msg_update_callback.general(msg) return # Fetch current CSE version current_cse_version = server_utils.get_installed_cse_version() supported_templates = [] remote_template_key = server_utils.get_template_descriptor_keys( self.cookbook_version) # noqa: E501 for template_description in self.unfiltered_cookbook['templates']: # only include the template if the current CSE version # supports it # template is supported if current CSE version is between # min_cse_version and max_cse_version of the template template_supported_cse_versions = semantic_version.SimpleSpec( f">={template_description[remote_template_key.MIN_CSE_VERSION]}," # noqa: E501 f"<={template_description[remote_template_key.MAX_CSE_VERSION]}" ) # noqa: E501 msg = f"Template {template_description['name']}" if template_supported_cse_versions.match(current_cse_version): msg += " is supported" supported_templates.append(template_description) else: msg += " is not supported" msg += f" by CSE {current_cse_version}" self.logger.debug(msg) self.msg_update_callback.general(msg) self.filtered_cookbook = self.unfiltered_cookbook # update templates list with only supported templates self.filtered_cookbook['templates'] = supported_templates msg = "Successfully filtered unsupported templates." self.logger.debug(msg) self.msg_update_callback.general(msg)
def verify_version_compatibility(sysadmin_client: Client, target_vcd_api_version, is_mqtt_extension): cse_version = server_utils.get_installed_cse_version() ext_cse_version, ext_vcd_api_version = \ configure_cse.parse_cse_extension_description( sysadmin_client, is_mqtt_extension) if cse_version == server_constants.UNKNOWN_CSE_VERSION or \ ext_vcd_api_version == server_constants.UNKNOWN_VCD_API_VERSION: # version data doesn't exist, so CSE <= 2.6.1 was installed raise cse_exception.VersionCompatibilityError( "CSE and VCD API version data not found on VCD. " "Upgrade CSE to update version data.") version_error_msg = '' if cse_version > ext_cse_version: version_error_msg += \ f"CSE Server version ({cse_version}) is higher than what was " \ f"previously registered with VCD ({ext_cse_version}). " \ f"Upgrade CSE to update CSE version on VCD." if cse_version < ext_cse_version: version_error_msg += \ f"CSE Server version ({cse_version}) cannot be lower than what " \ f"was previously registered with VCD ({ext_cse_version})." if target_vcd_api_version > ext_vcd_api_version: version_error_msg += \ f"Target VCD API version ({target_vcd_api_version}) is higher " \ f"than what was previously registered by CSE " \ f"({ext_vcd_api_version}). Upgrade CSE to update " \ f"registered VCD API version." if target_vcd_api_version < ext_vcd_api_version: version_error_msg += \ f"Target VCD API version ({target_vcd_api_version}) cannot be " \ f"lower than what was previously registered by " \ f"CSE ({ext_vcd_api_version})." if version_error_msg: raise cse_exception.VersionCompatibilityError(version_error_msg)
def verify_version_compatibility(sysadmin_client: Client, should_cse_run_in_legacy_mode: bool, is_mqtt_extension: bool): ext_description = configure_cse.get_extension_description( sysadmin_client, is_mqtt_extension) dikt = configure_cse.parse_cse_extension_description(ext_description) ext_cse_version = dikt[server_constants.CSE_VERSION_KEY] ext_in_legacy_mode = dikt[server_constants.LEGACY_MODE_KEY] ext_rde_in_use = dikt[server_constants.RDE_VERSION_IN_USE_KEY] # version data doesn't exist, so installed CSE is <= 2.6.1 if ext_cse_version == server_constants.UNKNOWN_CSE_VERSION: raise cse_exception.VersionCompatibilityError( "CSE and VCD API version data not found on VCD. " "Please upgrade CSE and retry.") error_msg = '' cse_version = server_utils.get_installed_cse_version() # Trying to use newer version of CSE without running `cse upgrade` if cse_version > ext_cse_version: error_msg += \ f"CSE Server version ({cse_version}) is higher than what was " \ f"previously registered with VCD ({ext_cse_version}). " \ "Please upgrade CSE and retry." # Trying to use an older version of CSE if cse_version < ext_cse_version: error_msg += \ f"CSE Server version ({cse_version}) cannot be lower than what " \ f"was previously registered with VCD ({ext_cse_version}). " \ "Please use a newer version of CSE." # Trying to run a legacy CSE in non-legacy mode if not should_cse_run_in_legacy_mode and ext_in_legacy_mode: error_msg += \ "Installed CSE is configured in legacy mode. Unable to run it " \ "in non-legacy mode. Please use `cse upgrade` to configure " \ "CSE to operate in non-legacy mode." # Trying to run a non legacy CSE in legacy mode if should_cse_run_in_legacy_mode and not ext_in_legacy_mode: error_msg += \ "Installed CSE is configured in non-legacy mode. Unable to run " \ "it in legacy mode." expected_runtime_rde_version = semantic_version.Version( server_utils.get_rde_version_in_use()) # noqa: E501 if not ext_in_legacy_mode: # VCD downgrade? if ext_rde_in_use > expected_runtime_rde_version: error_msg += \ "Installed CSE Runtime Defined Entity (RDE) version " \ f"({ext_rde_in_use}) is higher than the expected RDE " \ f"version ({expected_runtime_rde_version}). Please " \ "upgrade VCD to proceed." # VCD got upgraded without `cse upgrade` being run. if ext_rde_in_use < expected_runtime_rde_version: error_msg += \ "Installed CSE Runtime Defined Entity (RDE) version " \ f"({ext_rde_in_use}) is lower than the expected RDE " \ f"version ({expected_runtime_rde_version}). Please " \ "use `cse upgrade` to upgrade CSE RDE version and " \ "retry." if error_msg: raise cse_exception.VersionCompatibilityError(error_msg)
def get_all_k8s_local_template_definition( client, catalog_name, org=None, org_name=None, legacy_mode=False, logger_debug=logger.NULL_LOGGER, msg_update_callback=utils.NullPrinter()): # noqa: E501 """Fetch all CSE k8s templates in a catalog. A CSE k8s template is a catalog item that has all the necessary metadata stamped onto it. If only partial metadata is present on a catalog item, that catalog item will be disqualified from the result. :param pyvcloud.vcd.Client client: A sys admin client to be used to retrieve metadata off the catalog items. :param str catalog_name: Name of the catalog where the template resides. :param pyvcloud.vcd.Org org: Org object which hosts the catalog. :param str org_name: Name of the org that is hosting the catalog. Can be provided in lieu of param org, however param org takes precedence. :param bool legacy_mode: True, if CSE is running in legacy mode :param logging.Logger logger_debug: :param utils.NullPrinter msg_update_callback: :return: list of dictionaries containing template data :rtype: list of dicts """ if not org: org = get_org(client, org_name=org_name) catalog_item_names = [ entry['name'] for entry in org.list_catalog_items(catalog_name) ] templates = [] # Select the right Key enum based on legacy_mode flag localTemplateKey = LocalTemplateKey if legacy_mode: # if template is loaded in legacy mode, make sure to avoid the keys # min_cse_version and max_cse_version localTemplateKey = LegacyLocalTemplateKey for item_name in catalog_item_names: md = org.get_all_metadata_from_catalog_item(catalog_name=catalog_name, item_name=item_name) metadata_dict = metadata_to_dict(md) # if catalog item doesn't have all the required metadata keys, # CSE should not recognize it as a template expected_metadata_keys = \ set([entry.value for entry in localTemplateKey]) missing_metadata_keys = expected_metadata_keys - metadata_dict.keys() num_missing_metadata_keys = len(missing_metadata_keys) if num_missing_metadata_keys == len(expected_metadata_keys): # This catalog item has no CSE related metadata, so skip it. continue if num_missing_metadata_keys > 0: # This catalog item has partial CSE metadata, so skip it but also # log relevant information. msg = f"Catalog item '{item_name}' missing " \ f"{num_missing_metadata_keys} metadata: " \ f"{missing_metadata_keys}" # noqa: F841 logger_debug.debug(msg) msg_update_callback.info(msg) continue if not legacy_mode: # Do not load the template in non-legacy_mode if # min_cse_version and max_cse_version are not present # in the metadata_dict curr_cse_version = server_utils.get_installed_cse_version() valid_cse_versions = semantic_version.SimpleSpec( f">={metadata_dict[localTemplateKey.MIN_CSE_VERSION]}," f"<={metadata_dict[localTemplateKey.MAX_CSE_VERSION]}") if not valid_cse_versions.match(curr_cse_version): template_name = \ metadata_dict.get(localTemplateKey.NAME, "Unknown") template_revision = \ metadata_dict.get(localTemplateKey.REVISION, "Unknown") msg = f"Template '{template_name}' at " \ f"revision '{template_revision}' exists but is " \ f"not valid for CSE {curr_cse_version}" logger_debug.debug(msg) msg_update_callback.info(msg) continue # non-string metadata is written to the dictionary as a string # when 'upgrade_from' metadata is empty, vcd returns it as: "['']" # when 'upgrade_from' metadata is not empty, vcd returns it as an array # coerce "['']" to the more usable empty array [] if isinstance(metadata_dict[localTemplateKey.UPGRADE_FROM], str): metadata_dict[localTemplateKey.UPGRADE_FROM] = \ ast.literal_eval(metadata_dict[localTemplateKey.UPGRADE_FROM]) if metadata_dict[localTemplateKey.UPGRADE_FROM] == ['']: metadata_dict[localTemplateKey.UPGRADE_FROM] = [] templates.append(metadata_dict) return templates