def _is_alias_folder(self, path): """ Check if the delimited path is a folder or attribute :param path: '|' delimited path :return: true if it is a folder otherwise false """ debug("DEBUG: Entering is_alias_folder %s", path) path_tokens = path.split(PATH_TOKEN) model_context = ModelContext("test", {}) aliases = Aliases(model_context=model_context, wlst_mode=WlstModes.OFFLINE) location = LocationContext() last_token = path_tokens[-1] alias_helper = AliasHelper(aliases, __logger, ExceptionType.COMPARE) found = True name_token_next = False for path_token in path_tokens[1:]: if name_token_next: token_name = aliases.get_name_token(location) location.add_name_token(token_name, path_token) name_token_next = False else: location.append_location(path_token) if last_token == path_token: break name_token_next = alias_helper.supports_multiple_mbean_instances( location) attrib_names = alias_helper.get_model_attribute_names(location) if last_token in attrib_names: found = False debug("DEBUG: is_alias_folder %s %s", path, found) return found
class DomainResourceExtractor: """ Create a domain resource file for use with Kubernetes deployment. """ _class_name = "DomainResourceExtractor" # the name field keys corresponding to named model elements NAME_KEY_MAP = {CHANNELS: 'channelName', CLUSTERS: CLUSTER_NAME} def __init__(self, model, model_context, aliases, logger): self._model = model self._model_context = model_context self._aliases = AliasHelper(aliases, logger, ExceptionType.DEPLOY) self._logger = logger return def extract(self): """ Deploy resource model elements at the domain level, including multi-tenant elements. """ _method_name = 'extract' resource_file = self._model_context.get_domain_resource_file() self._logger.info("WLSDPLY-10000", resource_file, method_name=_method_name, class_name=self._class_name) # create the target file directory, if needed resource_dir = File(resource_file).getParentFile() if (not resource_dir.isDirectory()) and (not resource_dir.mkdirs()): mkdir_ex = exception_helper.create_deploy_exception( 'WLSDPLY-10001', resource_dir) raise mkdir_ex # build the resource file structure from the kubernetes section of the model resource_dict = self._create_domain_resource_dictionary() # revise the resource file structure with values from command line, and elsewhere in model self._update_resource_dictionary(resource_dict) # write the resource file structure to the output file writer = PythonToFile(resource_dict) writer.write_to_file(resource_file) return def _create_domain_resource_dictionary(self): """ Build the resource file structure from the kubernetes section of the model. :return: the resource file structure """ kubernetes_map = self._model.get_model_kubernetes() resource_dict = PyOrderedDict() attribute_location = self._aliases.get_model_section_attribute_location( KUBERNETES) top_attributes_map = self._aliases.get_model_attribute_names_and_types( attribute_location) top_folders = self._aliases.get_model_section_top_level_folder_names( KUBERNETES) self._process_fields(kubernetes_map, top_folders, top_attributes_map, LocationContext(), resource_dict) return resource_dict def _process_fields(self, model_dict, folder_names, attributes_map, location, target_dict): """ Transfer folders and attributes from the model dictionary to the target domain resource dictionary. For the top level, the folders and attributes are not derived directly from the location. :param model_dict: the source model dictionary :param folder_names: the names of the folders at this location :param attributes_map: the map of attribute names to types for this location :param location: the location used for alias processing :param target_dict: the target dictionary for the domain resource file. """ for key, model_value in model_dict.items(): if key in attributes_map.keys(): type_name = attributes_map[key] target_dict[key] = _get_target_value(model_value, type_name) elif key in folder_names: child_location = LocationContext(location).append_location(key) if self._aliases.supports_multiple_mbean_instances( child_location): target_dict[key] = self._build_dictionary_list( key, model_value, child_location) else: if key not in target_dict: target_dict[key] = PyOrderedDict() target_child_dict = target_dict[key] self._process_location_fields(model_value, child_location, target_child_dict) return def _process_location_fields(self, model_dict, location, target_dict): """ Transfer folders and attributes from the model dictionary to the target domain resource dictionary. Below the top level, the folders and attributes can be derived from the location. :param model_dict: the source model dictionary :param location: the location used for alias processing :param target_dict: the target dictionary for the domain resource file. """ attributes_map = self._aliases.get_model_attribute_names_and_types( location) folder_names = self._aliases.get_model_subfolder_names(location) self._process_fields(model_dict, folder_names, attributes_map, location, target_dict) return def _build_dictionary_list(self, model_key, name_dictionary, location): """ Build a dictionary list object based on the name dictionary and location. :param name_dictionary: a dictionary containing named levels :param location: the location used for alias resolution :return: """ child_list = DictionaryList() for name in name_dictionary: model_named_dict = name_dictionary[name] name_key = self._get_name_key(model_key) target_list_dict = PyOrderedDict() target_list_dict[name_key] = name self._process_location_fields(model_named_dict, location, target_list_dict) child_list.append(target_list_dict) return child_list def _get_name_key(self, key): """ Return the key to be used for the name in a dictionary list element. :param key: the folder key in the model :return: the name key """ key = dictionary_utils.get_element(self.NAME_KEY_MAP, key) if key is not None: return key return 'name' def _update_resource_dictionary(self, resource_dict): """ Revise the resource file structure with values from defaults, command line, and elsewhere in model :param resource_dict: the resource file dictionary """ _method_name = '_update_resource_dictionary' # add API version if not present if API_VERSION not in resource_dict: resource_dict[API_VERSION] = DEFAULT_API_VERSION # add kind if not present if KIND not in resource_dict: resource_dict[KIND] = DEFAULT_KIND # add a metadata section if not present, since we'll at least add name if METADATA not in resource_dict: resource_dict[METADATA] = PyOrderedDict() metadata_section = resource_dict[METADATA] # if metadata name not present, use the domain name from the model, or default if K_NAME not in metadata_section: domain_name = dictionary_utils.get_element( self._model.get_model_topology(), NAME) if domain_name is None: domain_name = DEFAULT_WLS_DOMAIN_NAME metadata_section[K_NAME] = domain_name # add a spec section if not present, since we'll at least add domain home if SPEC not in resource_dict: resource_dict[SPEC] = PyOrderedDict() spec_section = resource_dict[SPEC] # only set domain home if it is not present in spec section if DOMAIN_HOME not in spec_section: spec_section[DOMAIN_HOME] = self._model_context.get_domain_home() # only set image if it is not present in spec section if IMAGE not in spec_section: spec_section[IMAGE] = DEFAULT_IMAGE # imagePullSecrets is required unless imagePullPolicy is Never pull_secrets_required = True if IMAGE_PULL_POLICY in spec_section: policy = str(spec_section[IMAGE_PULL_POLICY]) pull_secrets_required = (policy != NEVER) # if imagePullSecrets required and not present, add a list with one FIX ME value if pull_secrets_required and (IMAGE_PULL_SECRETS not in spec_section): secrets_list = DictionaryList() secrets_list.append({'name': DEFAULT_IMAGE_PULL_SECRETS}) spec_section[IMAGE_PULL_SECRETS] = secrets_list # if webLogicCredentialsSecret not present, add it using the FIX ME value if WEBLOGIC_CREDENTIALS_SECRET not in spec_section: spec_section[ WEBLOGIC_CREDENTIALS_SECRET] = DEFAULT_WEBLOGIC_CREDENTIALS_SECRET # only update clusters if section is not present in spec section if CLUSTERS not in spec_section: topology = self._model.get_model_topology() model_clusters = dictionary_utils.get_dictionary_element( topology, CLUSTER) if len(model_clusters) > 0: cluster_list = DictionaryList() spec_section[CLUSTERS] = cluster_list for cluster_name, cluster_values in model_clusters.items(): server_count = k8s_helper.get_server_count( cluster_name, cluster_values, self._model.get_model()) cluster_dict = PyOrderedDict() cluster_dict[CLUSTER_NAME] = cluster_name cluster_dict[REPLICAS] = server_count self._logger.info("WLSDPLY-10002", cluster_name, server_count, method_name=_method_name, class_name=self._class_name) cluster_list.append(cluster_dict) return
class Deployer(object): """ The base class for deployers. Maintains model, model context, WLST mode, etc. Has common methods for deployers. """ _class_name = "Deployer" _mbean_interface = Class.forName('weblogic.management.configuration.ConfigurationMBean') _object_name_class = Class.forName('javax.management.ObjectName') _list_interface = Class.forName('java.util.List') def __init__(self, model, model_context, aliases, wlst_mode=WlstModes.OFFLINE): self.name = self._class_name self.model = model self.wlst_mode = wlst_mode self.model_context = model_context self.aliases = aliases self.logger = PlatformLogger('wlsdeploy.deploy') self.alias_helper = AliasHelper(aliases, self.logger, ExceptionType.DEPLOY) self.wls_helper = WebLogicHelper(self.logger) self.wlst_helper = WlstHelper(self.logger, ExceptionType.DEPLOY) self.attribute_setter = AttributeSetter(self.aliases, self.logger, ExceptionType.DEPLOY, wlst_mode=wlst_mode) self.archive_helper = None archive_file_name = self.model_context.get_archive_file_name() if archive_file_name is not None: self.archive_helper = ArchiveHelper(archive_file_name, self.model_context.get_domain_home(), self.logger, exception_helper.ExceptionType.DEPLOY) return def _add_named_elements(self, type_name, model_nodes, location): """ Add each named element from the specified nodes in WLST and set its attributes. Sub-folders are processed in a generic manner if present. It is assumed that there are no attributes or sub-folders with special processing. :param type_name: the type name of the child nodes :param model_nodes: the child nodes of a model element :param location: the location where elements should be added """ _method_name = '_add_named_elements' if len(model_nodes) == 0: return parent_type, parent_name = self.get_location_type_and_name(location) location = LocationContext(location).append_location(type_name) if not self._check_location(location): return deployer_utils.check_flattened_folder(location, self.alias_helper) existing_names = deployer_utils.get_existing_object_list(location, self.alias_helper) token = self.alias_helper.get_name_token(location) for name in model_nodes: is_add = name not in existing_names log_helper.log_updating_named_folder(type_name, name, parent_type, parent_name, is_add, self._class_name, _method_name) if token is not None: location.add_name_token(token, name) deployer_utils.create_and_cd(location, existing_names, self.alias_helper) child_nodes = dictionary_utils.get_dictionary_element(model_nodes, name) self._set_attributes_and_add_subfolders(location, child_nodes) return def _add_subfolders(self, model_nodes, location, excludes=None): """ Add each model sub-folder from the specified nodes and set its attributes. :param model_nodes: the child nodes of a model element :param location: the location where sub-folders should be added :param excludes: optional list of sub-folder names to be excluded from processing """ location = LocationContext(location) model_subfolder_names = self.alias_helper.get_model_subfolder_names(location) for subfolder in model_nodes: key_excluded = (excludes is not None) and (subfolder in excludes) if subfolder in model_subfolder_names and not key_excluded: subfolder_nodes = model_nodes[subfolder] if len(subfolder_nodes) != 0: sub_location = LocationContext(location).append_location(subfolder) if self.alias_helper.supports_multiple_mbean_instances(sub_location): self._add_named_elements(subfolder, subfolder_nodes, location) else: self._add_model_elements(subfolder, subfolder_nodes, location) return def _add_model_elements(self, type_name, model_nodes, location): """ Add each model element from the specified nodes at the specified location and set its attributes. :param model_nodes: the child nodes of a model element :param location: the location where sub-folders should be added :param type_name: the name of the model folder to add """ _method_name = '_add_model_elements' parent_type, parent_name = self.get_location_type_and_name(location) location = LocationContext(location).append_location(type_name) if not self._check_location(location): return deployer_utils.check_flattened_folder(location, self.alias_helper) existing_subfolder_names = deployer_utils.get_existing_object_list(location, self.alias_helper) mbean_name = deployer_utils.get_mbean_name(location, existing_subfolder_names, self.alias_helper) is_add = mbean_name not in existing_subfolder_names log_helper.log_updating_folder(type_name, parent_type, parent_name, is_add, self._class_name, _method_name) deployer_utils.create_and_cd(location, existing_subfolder_names, self.alias_helper) self._set_attributes_and_add_subfolders(location, model_nodes) return def _set_attributes_and_add_subfolders(self, location, model_nodes): """ Set the attributes and add sub-folders for the specified location. This method can be overridden for finer control of the ordering :param location: the location of the attributes and sub-folders :param model_nodes: a map of model nodes including attributes and sub-folders :raise: DeployException: if an error condition is encountered """ self.set_attributes(location, model_nodes) self._add_subfolders(model_nodes, location) return def set_attributes(self, location, model_nodes, excludes=None): """ Set all the attributes in the model_nodes list. Exclude items that are sub-folders. :param location: the location of the attributes to be set :param model_nodes: a map of model nodes with attributes to be set :param excludes: a list of items that should not be set :raise: DeployException: if an error condition is encountered """ _method_name = 'set_attributes' attribute_names = self.alias_helper.get_model_attribute_names(location) uses_path_tokens_attribute_names = self.alias_helper.get_model_uses_path_tokens_attribute_names(location) restart_attribute_names = self.alias_helper.get_model_restart_required_attribute_names(location) merge_attribute_names = self.alias_helper.get_model_merge_required_attribute_names(location) lsa_required_attribute_names = self.aliases.get_model_lsa_required_attribute_names(location) set_method_map = self.alias_helper.get_model_mbean_set_method_attribute_names_and_types(location) for key in model_nodes: key_excluded = (excludes is not None) and (key in excludes) if key in attribute_names and not key_excluded: value = model_nodes[key] if key in uses_path_tokens_attribute_names: self._extract_from_archive_if_needed(location, key, value) wlst_merge_value = None if key in merge_attribute_names: wlst_merge_value = self._get_existing_wlst_value(location, key, lsa_required_attribute_names) if not self._skip_setting_attribute(key, value, wlst_merge_value, restart_attribute_names) and \ (not self.set_special_attribute(location, key, value, wlst_merge_value, set_method_map)): try: self.attribute_setter.set_attribute(location, key, value, wlst_merge_value) except PyWLSTException, pwe: loc_type, loc_name = self.get_location_type_and_name(location) ex = exception_helper.create_deploy_exception('WLSDPLY-09200', key, loc_type, loc_name, pwe.getLocalizedMessage(), error=pwe) self.logger.throwing(ex, class_name=self._class_name, method_name=_method_name) raise ex return
class Creator(object): """ The base class used by the DomainCreator. """ __class_name = 'Creator' def __init__(self, model, model_context, aliases, exception_type=ExceptionType.CREATE, logger=PlatformLogger('wlsdeploy.create')): self.logger = logger self.aliases = aliases self._exception_type = exception_type self.alias_helper = AliasHelper(self.aliases, self.logger, exception_type) self.wlst_helper = WlstHelper(self.logger, exception_type) self.model = Model(model) self.model_context = model_context self.wls_helper = WebLogicHelper(self.logger) self.attribute_setter = AttributeSetter(self.aliases, self.logger, exception_type) self.custom_folder_helper = CustomFolderHelper(self.aliases, self.logger, self.model_context, exception_type) # Must be initialized by the subclass since only it has # the knowledge required to compute the domain name. self.archive_helper = None self.files_to_extract_from_archive = list() return def _create_named_mbeans(self, type_name, model_nodes, base_location, log_created=False): """ Create the specified type of MBeans that support multiple instances in the specified location. :param type_name: the model folder type :param model_nodes: the model dictionary of the specified model folder type :param base_location: the base location object to use to create the MBeans :param log_created: whether or not to log created at INFO level, by default it is logged at the FINE level :raises: CreateException: if an error occurs """ _method_name = '_create_named_mbeans' self.logger.entering(type_name, str(base_location), log_created, class_name=self.__class_name, method_name=_method_name) if model_nodes is None or len( model_nodes) == 0 or not self._is_type_valid( base_location, type_name): return location = LocationContext(base_location).append_location(type_name) self._process_flattened_folder(location) token_name = self.alias_helper.get_name_token(location) create_path = self.alias_helper.get_wlst_create_path(location) list_path = self.alias_helper.get_wlst_list_path(location) existing_folder_names = self._get_existing_folders(list_path) for model_name in model_nodes: name = self.wlst_helper.get_quoted_name_for_wlst(model_name) if token_name is not None: location.add_name_token(token_name, name) wlst_type, wlst_name = self.alias_helper.get_wlst_mbean_type_and_name( location) if wlst_name not in existing_folder_names: if log_created: self.logger.info('WLSDPLY-12100', type_name, name, class_name=self.__class_name, method_name=_method_name) else: self.logger.fine('WLSDPLY-12100', type_name, name, class_name=self.__class_name, method_name=_method_name) self.wlst_helper.create_and_cd(self.alias_helper, wlst_type, wlst_name, location, create_path) else: if log_created: self.logger.info('WLSDPLY-12101', type_name, name, class_name=self.__class_name, method_name=_method_name) else: self.logger.fine('WLSDPLY-12101', type_name, name, class_name=self.__class_name, method_name=_method_name) attribute_path = self.alias_helper.get_wlst_attributes_path( location) self.wlst_helper.cd(attribute_path) child_nodes = dictionary_utils.get_dictionary_element( model_nodes, name) self._process_child_nodes(location, child_nodes) self.logger.exiting(class_name=self.__class_name, method_name=_method_name) return def _create_mbean(self, type_name, model_nodes, base_location, log_created=False): """ Create the specified type of MBean that support a single instance in the specified location. :param type_name: the model folder type :param model_nodes: the model dictionary of the specified model folder type :param base_location: the base location object to use to create the MBean :param log_created: whether or not to log created at INFO level, by default it is logged at the FINE level :raises: CreateException: if an error occurs """ _method_name = '_create_mbean' self.logger.entering(type_name, str(base_location), log_created, class_name=self.__class_name, method_name=_method_name) if model_nodes is None or len( model_nodes) == 0 or not self._is_type_valid( base_location, type_name): return location = LocationContext(base_location).append_location(type_name) result, message = self.alias_helper.is_version_valid_location(location) if result == ValidationCodes.VERSION_INVALID: self.logger.warning('WLSDPLY-12123', message, class_name=self.__class_name, method_name=_method_name) return create_path = self.alias_helper.get_wlst_create_path(location) existing_folder_names = self._get_existing_folders(create_path) mbean_type, mbean_name = self.alias_helper.get_wlst_mbean_type_and_name( location) token_name = self.alias_helper.get_name_token(location) if token_name is not None: if self.alias_helper.requires_unpredictable_single_name_handling( location): existing_subfolder_names = deployer_utils.get_existing_object_list( location, self.alias_helper) if len(existing_subfolder_names) > 0: mbean_name = existing_subfolder_names[0] location.add_name_token(token_name, mbean_name) self._process_flattened_folder(location) if mbean_type not in existing_folder_names: if log_created: self.logger.info('WLSDPLY-12102', type_name, class_name=self.__class_name, method_name=_method_name) else: self.logger.fine('WLSDPLY-12102', type_name, class_name=self.__class_name, method_name=_method_name) self.wlst_helper.create_and_cd(self.alias_helper, mbean_type, mbean_name, location, create_path) else: if log_created: self.logger.info('WLSDPLY-20013', type_name, class_name=self.__class_name, method_name=_method_name) else: self.logger.fine('WLSDPLY-12102', type_name, class_name=self.__class_name, method_name=_method_name) attribute_path = self.alias_helper.get_wlst_attributes_path( location) self.wlst_helper.cd(attribute_path) self._process_child_nodes(location, model_nodes) self.logger.exiting(class_name=self.__class_name, method_name=_method_name) return def _create_named_subtype_mbeans(self, type_name, model_nodes, base_location, log_created=False): """ Create the specified type of MBeans that support multiple instances, and require an artificial subtype layer after each name. There is no default behavior for this method. Sub-classes (currently only SecurityProviderCreator) will implement specialized behavior. :param type_name: the model folder type :param model_nodes: the model dictionary of the specified model folder type :param base_location: the base location object to use to create the MBeans :param log_created: whether or not to log created at INFO level, by default it is logged at the FINE level :raises: CreateException: if an error occurs """ return def _create_subfolders(self, location, model_nodes): """ Create the child MBean folders at the specified location. :param location: the location :param model_nodes: the model dictionary :raises: CreateException: if an error occurs """ _method_name = '_create_subfolders' self.logger.entering(location.get_folder_path(), class_name=self.__class_name, method_name=_method_name) model_subfolder_names = self.alias_helper.get_model_subfolder_names( location) for key in model_nodes: if key in model_subfolder_names: subfolder_nodes = model_nodes[key] # don't check for empty subfolder nodes here, some create methods allow them sub_location = LocationContext(location).append_location(key) if self.alias_helper.requires_artificial_type_subfolder_handling( sub_location): self.logger.finest('WLSDPLY-12116', key, str(sub_location), subfolder_nodes, class_name=self.__class_name, method_name=_method_name) self._create_named_subtype_mbeans(key, subfolder_nodes, location, True) elif self.alias_helper.supports_multiple_mbean_instances( sub_location): self.logger.finest('WLSDPLY-12109', key, str(sub_location), subfolder_nodes, class_name=self.__class_name, method_name=_method_name) self._create_named_mbeans(key, subfolder_nodes, location) elif self.alias_helper.is_artificial_type_folder(sub_location): # these should have been handled inside create_named_subtype_mbeans ex = exception_helper.create_create_exception( 'WLSDPLY-12120', str(sub_location), key, str(location)) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex else: self.logger.finest('WLSDPLY-12110', key, str(sub_location), subfolder_nodes, class_name=self.__class_name, method_name=_method_name) self._create_mbean(key, subfolder_nodes, location) self.logger.exiting(class_name=self.__class_name, method_name=_method_name) return def _process_child_nodes(self, location, model_nodes): """ Process the model nodes at the specified location. The default behavior is to process attributes, then sub-folders. Sub-classes may override to reverse this order, or for other special processing. :param location: the location where the nodes should be applied :param model_nodes: the model dictionary of the nodes to be applied :raises: CreateException: if an error occurs """ _method_name = '_process_child_nodes' self.logger.finest('WLSDPLY-12111', self.alias_helper.get_model_folder_path(location), self.wlst_helper.get_pwd(), class_name=self.__class_name, method_name=_method_name) self._set_attributes(location, model_nodes) self._create_subfolders(location, model_nodes) def _set_attributes(self, location, model_nodes): """ Set the attributes for the MBean at the specified location. :param location: the location :param model_nodes: the model dictionary :raises: CreateException: if an error occurs """ _method_name = '_set_attributes' model_attribute_names = self.alias_helper.get_model_attribute_names_and_types( location) password_attribute_names = self.alias_helper.get_model_password_type_attribute_names( location) set_method_map = self.alias_helper.get_model_mbean_set_method_attribute_names_and_types( location) uses_path_tokens_attribute_names = self.alias_helper.get_model_uses_path_tokens_attribute_names( location) model_folder_path = self.alias_helper.get_model_folder_path(location) pwd = self.wlst_helper.get_pwd() for key, value in model_nodes.iteritems(): if key in model_attribute_names: if key in set_method_map: self.logger.finest('WLSDPLY-12112', key, pwd, model_folder_path, class_name=self.__class_name, method_name=_method_name) self._set_mbean_attribute(location, key, value, set_method_map) elif key in password_attribute_names: self.logger.finest('WLSDPLY-12113', key, pwd, model_folder_path, class_name=self.__class_name, method_name=_method_name) self._set_attribute(location, key, value, uses_path_tokens_attribute_names, masked=True) else: self.logger.finest('WLSDPLY-12113', key, pwd, model_folder_path, class_name=self.__class_name, method_name=_method_name) self._set_attribute(location, key, value, uses_path_tokens_attribute_names) return def _set_mbean_attribute(self, location, model_key, model_value, set_method_map): """ Set the attributes for the MBean that require an MBean value to set at the specified location. :param location: the location :param model_key: the model attribute name :param model_value: the model attribute value :param set_method_map: the set method map that maps the attribute names requiring MBean values to the attribute setter method name :raises: CreateException: if an error occurs """ _method_name = '_set_mbean_attribute' set_method_info = dictionary_utils.get_dictionary_element( set_method_map, model_key) set_method_name = dictionary_utils.get_element(set_method_info, 'set_method') if set_method_name is not None: try: self.logger.finest('WLSDPLY-12114', model_key, model_value, set_method_name, class_name=self.__class_name, method_name=_method_name) set_method = getattr(self.attribute_setter, set_method_name) set_method(location, model_key, model_value, None) except AttributeError, ae: ex = exception_helper.create_create_exception( 'WLSDPLY-12104', set_method_name, model_key, self.alias_helper.get_model_folder_path(location), error=ae) self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name) raise ex else:
class ModelHelpPrinter(object): """ Class for printing the recognized model metadata to STDOUT. """ def __init__(self, aliases, logger): """ :param aliases: A reference to an Aliases class instance :param logger: A reference to the platform logger to write to, if a log entry needs to be made """ self._logger = logger self._alias_helper = AliasHelper(aliases, self._logger, ExceptionType.CLA) def print_model_help(self, model_path, control_option, as_sample=False): """ Prints out the help information for a given '''model_path'''. '''model_path''' needs to be specified using the following pattern: <model_section>[:/<section_folder>[/<section_subfolder>|...]] Examples: 'domainInfo', 'domainInfo:' or 'domainInfo:/' (all 3 are equivalent) 'topology:/Server' 'resources:/JDBCSystemResource/JdbcResource/JDBCDriverParams' 'appDeployments:/Application' :param model_path: a formatted string containing the model path :param control_option: a command-line switch that controls what is output :param as_sample: specifies that a model sample should be output :raises CLAException: if a problem is encountered """ # print filter information, if not NORMAL if control_option == ControlOptions.RECURSIVE: print print _format_message('WLSDPLY-10102') elif control_option == ControlOptions.FOLDERS_ONLY: print print _format_message('WLSDPLY-10103') elif control_option == ControlOptions.ATTRIBUTES_ONLY: print print _format_message('WLSDPLY-10104') model_path_tokens = self._parse_model_path(model_path) section_name = model_path_tokens[0] valid_section_folder_keys = self._alias_helper.get_model_section_top_level_folder_names( section_name) if as_sample: sample_printer = ModelSamplePrinter(self._alias_helper, self._logger) sample_printer.print_model_sample(model_path_tokens, control_option) else: if model_path_tokens[0] == 'top': self._print_model_top_level_help() elif len(model_path_tokens) == 1: self._print_model_section_help(section_name, valid_section_folder_keys, control_option) else: self._print_model_folder_help(model_path_tokens, valid_section_folder_keys, control_option) def _parse_model_path(self, model_path): """ Parse the specified model_path into a Python list of elements. The first element will be the section name. If not specified, the section name will be derived from the first path element. :param model_path: a string contain the model path to parse :return: a python list containing the section name, then each folder element :raises: CLAException if the path cannot be parsed, or the section name is invalid """ _method_name = '_parse_model_path' self._logger.entering(model_path, class_name=_class_name, method_name=_method_name) match = MODEL_PATH_PATTERN.match(model_path) if match is None: ex = exception_helper.create_cla_exception('WLSDPLY-10108', model_path) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) raise ex self._logger.finest('match.group(1)={0}, match.group(2)={1}', str(match.group(1)), str(match.group(2)), class_name=_class_name, method_name=_method_name) section = match.group(1) path = match.group(2) folders = [] if path is not None: for folder in path.split('/'): # trailing or duplicate slashes may cause empty folder name if len(folder) > 0: folders.append(folder) if section is None: section = self._get_section_for_folder_list(folders) section = section.replace(':', '') top_level_keys = model.get_model_top_level_keys() # 'top' is a special case for listing the sections all_section_keys = ['top'] all_section_keys.extend(top_level_keys) if section not in all_section_keys: ex = exception_helper.create_cla_exception( 'WLSDPLY-10109', section, str(', '.join(top_level_keys))) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) raise ex model_path_tokens = [section] model_path_tokens.extend(folders) return model_path_tokens def _get_section_for_folder_list(self, folder_list): """ Derive the section name from the first folder in the specified list. :param folder_list: the list of folders in the model path :return: the section name :raises: CLAException if the section name cannot be determined """ _method_name = '_get_section_for_folder_list' top_folder = folder_list[0] for section in KNOWN_TOPLEVEL_MODEL_SECTIONS: folder_keys = self._alias_helper.get_model_section_top_level_folder_names( section) if top_folder in folder_keys: return section ex = exception_helper.create_cla_exception('WLSDPLY-10101', top_folder) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) raise ex def _print_model_top_level_help(self): """ Prints out all the valid section names for a model. The -recursive flag is disregarded for this case. """ _method_name = '_print_model_top_level_help' self._logger.finest('sections={0}', KNOWN_TOPLEVEL_MODEL_SECTIONS, class_name=_class_name, method_name=_method_name) title = _format_message('WLSDPLY-10113') # Print 'All Sections:' header print _print_indent(title, 0) print for section in KNOWN_TOPLEVEL_MODEL_SECTIONS: _print_indent(section, 1) def _print_model_section_help(self, section_name, valid_section_folder_keys, control_option): """ Prints the help for a section of a model, when just the section_name[:] is provided :param section_name: the name of the model section :param valid_section_folder_keys: list of the valid top folders in the specified section :param control_option: A command-line switch that controls what is output to STDOUT """ _method_name = '_print_model_section_help' self._logger.finest('1 section_name={0}', section_name, class_name=_class_name, method_name=_method_name) location_path = '%s:' % section_name self._logger.finest('1 location_path={0}', location_path, class_name=_class_name, method_name=_method_name) model_section = _format_message('WLSDPLY-10106', location_path) # Print 'Section: <model_section>' label and field print _print_indent(model_section, 0) if model_help_utils.show_attributes(control_option): attributes_location = self._alias_helper.get_model_section_attribute_location( section_name) if attributes_location is not None: self._print_attributes_help(attributes_location, 1) if model_help_utils.show_folders(control_option): print _print_indent(_format_message('WLSDPLY-10107'), 1) valid_section_folder_keys.sort() for section_folder_key in valid_section_folder_keys: _print_indent(section_folder_key, 2) if control_option == ControlOptions.RECURSIVE: model_location = LocationContext().append_location( section_folder_key) self._print_subfolders_help(model_location, control_option, 2) def _print_model_folder_help(self, model_path_tokens, valid_section_folder_keys, control_option): """ Prints the help for a folder in a model, when more than just the section_name[:] is provided. The section name in the first token was already validated. :param model_path_tokens: a Python list of path elements built from model path :param valid_section_folder_keys: A list of valid folder names for the model section in the path :param control_option: A command-line switch that controls what is output to STDOUT """ _method_name = '_print_model_folder_help' self._logger.finest( '1 model_path_tokens={0}, control_option={1}, valid_section_folder_keys={0}', str(model_path_tokens), ControlOptions.from_value(control_option), str(valid_section_folder_keys), class_name=_class_name, method_name=_method_name) section_name = model_path_tokens[0] top_folder = model_path_tokens[1] if top_folder not in valid_section_folder_keys: ex = exception_helper.create_cla_exception( 'WLSDPLY-10110', section_name + ':', top_folder, ', '.join(valid_section_folder_keys)) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) raise ex # Populate the location context using model_path_tokens[1:] model_location = LocationContext() for folder_key in model_path_tokens[1:]: model_location.append_location(folder_key) name_token = self._alias_helper.get_name_token(model_location) if name_token is not None: model_location.add_name_token(name_token, '%s-0' % folder_key) self._logger.finest('2 model_location={0}', model_location, class_name=_class_name, method_name=_method_name) folder_path = '/'.join(model_path_tokens[1:]) model_path = _format_message('WLSDPLY-10105', '%s:/%s' % (section_name, folder_path)) type_name = self._get_folder_type_name(model_location) if type_name is not None: model_path += " (" + type_name + ")" # Print 'Path: <model_section>' header print _print_indent(model_path, 0) if model_help_utils.show_attributes(control_option): # Print the attributes associated with location context self._print_attributes_help(model_location, 1) if model_help_utils.show_folders(control_option): # Print the folders associated with location context print _print_indent(_format_message('WLSDPLY-10107'), 1) self._print_subfolders_help(model_location, control_option, 1) self._logger.exiting(class_name=_class_name, method_name=_method_name) return def _print_subfolders_help(self, model_location, control_option, indent_level): """ Prints the help for the folders in a model location, without header or leading space. :param model_location: the model location being worked on :param control_option: a command-line switch that controls what is output to STDOUT :param indent_level: the level to indent by, before printing output """ _method_name = '_print_subfolders_help' valid_subfolder_keys = self._alias_helper.get_model_subfolder_names( model_location) self._logger.finest( '3 aliases.get_model_subfolder_names(model_location) returned: {0}', str(valid_subfolder_keys), class_name=_class_name, method_name=_method_name) if not valid_subfolder_keys: return valid_subfolder_keys.sort() for key in valid_subfolder_keys: model_location.append_location(key) name_token = self._alias_helper.get_name_token(model_location) if name_token is not None: model_location.add_name_token(name_token, '%s-0' % key) self._logger.finest('3 model_location={0}', model_location, class_name=_class_name, method_name=_method_name) text = key type_name = self._get_folder_type_name(model_location) if type_name is not None: text += " (" + type_name + ")" _print_indent(text, indent_level + 1) if control_option == ControlOptions.RECURSIVE: # Call this method recursively self._print_subfolders_help(model_location, control_option, indent_level + 1) model_location.pop_location() def _print_attributes_help(self, model_location, indent_level): """ Prints out the help for the attributes in a model location :param model_location: An object containing data about the model location being worked on :param indent_level: The level to indent by, before printing output """ _method_name = '_print_attributes_help' attr_infos = self._alias_helper.get_model_attribute_names_and_types( model_location) self._logger.finer('WLSDPLY-05012', str(model_location), str(attr_infos), class_name=_class_name, method_name=_method_name) # Print 'Valid Attributes:' area label print _print_indent(_format_message('WLSDPLY-10111'), indent_level) if attr_infos: maxlen = 0 for key in attr_infos: if len(key) > maxlen: maxlen = len(key) formatted_string = '%-' + str(maxlen) + 's\t%s' attr_list = attr_infos.keys() attr_list.sort() for attr_name in attr_list: msg = formatted_string % (attr_name, attr_infos[attr_name]) _print_indent(msg, indent_level + 1) def _get_folder_type_name(self, location): """ Return text indicating the type of a folder, such as "multiple". :param location: the location to be checked :return: name of the folder type to be displayed, or None """ if self._alias_helper.is_artificial_type_folder(location): return None if self._alias_helper.supports_multiple_mbean_instances(location): return "multiple" return None
class PrepareModel: """ This is the main driver for the caller. It compares two model files whether they are json or yaml format. """ def __init__(self, model_files, model_context, logger, output_dir=None): self.model_files = model_files self.output_dir = output_dir self.model_context = model_context self._aliases = Aliases(model_context=model_context, wlst_mode=WlstModes.OFFLINE) self._alias_helper = AliasHelper(self._aliases, logger, ExceptionType.COMPARE) self._logger = logger self._name_tokens_location = LocationContext() self._name_tokens_location.add_name_token('DOMAIN', "testdomain") self.current_dict = None self.cache = OrderedDict() self.secrets_to_generate = sets.Set() def __walk_model_section(self, model_section_key, model_dict, valid_section_folders): _method_name = '__validate_model_section' if model_section_key not in model_dict.keys(): return # only specific top-level sections have attributes attribute_location = self._alias_helper.get_model_section_attribute_location(model_section_key) valid_attr_infos = [] path_tokens_attr_keys = [] if attribute_location is not None: valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(attribute_location) path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(attribute_location) model_section_dict = model_dict[model_section_key] for section_dict_key, section_dict_value in model_section_dict.iteritems(): # section_dict_key is either the name of a folder in the # section, or the name of an attribute in the section. validation_location = LocationContext() model_folder_path = model_section_key + ":/" if section_dict_key in valid_attr_infos: # section_dict_key is the name of an attribute in the section self.__walk_attribute(section_dict_key, section_dict_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, attribute_location) elif section_dict_key in valid_section_folders: # section_dict_key is a folder under the model section # Append section_dict_key to location context validation_location.append_location(section_dict_key) # Call self.__validate_section_folder() passing in section_dict_value as the model_node to process self.__walk_section_folder(section_dict_value, validation_location) def __walk_section_folder(self, model_node, validation_location): _method_name = '__validate_section_folder' model_folder_path = self._alias_helper.get_model_folder_path(validation_location) if self._alias_helper.supports_multiple_mbean_instances(validation_location): for name in model_node: expanded_name = name new_location = LocationContext(validation_location) name_token = self._alias_helper.get_name_token(new_location) if name_token is not None: new_location.add_name_token(name_token, expanded_name) value_dict = model_node[name] self.__walk_model_node(value_dict, new_location) elif self._alias_helper.requires_artificial_type_subfolder_handling(validation_location): for name in model_node: expanded_name = name new_location = LocationContext(validation_location) name_token = self._alias_helper.get_name_token(new_location) if name_token is not None: new_location.add_name_token(name_token, expanded_name) value_dict = model_node[name] self.__walk_model_node(value_dict, new_location) else: name_token = self._alias_helper.get_name_token(validation_location) if name_token is not None: name = self._name_tokens_location.get_name_for_token(name_token) if name is None: name = '%s-0' % name_token validation_location.add_name_token(name_token, name) self.__walk_model_node(model_node, validation_location) def __walk_model_node(self, model_node, validation_location): _method_name = '__process_model_node' valid_folder_keys = self._alias_helper.get_model_subfolder_names(validation_location) valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(validation_location) model_folder_path = self._alias_helper.get_model_folder_path(validation_location) for key, value in model_node.iteritems(): if key in valid_folder_keys: new_location = LocationContext(validation_location).append_location(key) if self._alias_helper.is_artificial_type_folder(new_location): # key is an ARTIFICIAL_TYPE folder valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(new_location) self.__walk_attributes(value, valid_attr_infos, new_location) else: self.__walk_section_folder(value, new_location) elif key in valid_attr_infos: # aliases.get_model_attribute_names_and_types(location) filters out # attributes that ARE NOT valid in the wlst_version being used, so if # we're in this section of code we know key is a bonafide "valid" attribute valid_data_type = valid_attr_infos[key] if valid_data_type in ['properties']: valid_prop_infos = {} properties = validation_utils.get_properties(value) self.__walk_properties(properties, valid_prop_infos, validation_location) else: path_tokens_attr_keys = \ self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location) self.__walk_attribute(key, value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location) def __walk_attributes(self, attributes_dict, valid_attr_infos, validation_location): _method_name = '__validate_attributes' path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location) model_folder_path = self._alias_helper.get_model_folder_path(validation_location) for attribute_name, attribute_value in attributes_dict.iteritems(): self.__walk_attribute(attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location) def __walk_attribute(self, attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location): _method_name = '__validate_attribute' if attribute_name in valid_attr_infos: expected_data_type = valid_attr_infos[attribute_name] if expected_data_type == 'password': self.__substitute_password_with_token(model_folder_path, attribute_name, validation_location) self._logger.exiting(class_name=_class_name, method_name=_method_name) def __walk_properties(self, properties_dict, valid_prop_infos, validation_location): _method_name = '__walk_properties' for property_name, property_value in properties_dict.iteritems(): valid_prop_infos[property_name] = validation_utils.get_python_data_type(property_value) self.__walk_property(property_name, property_value, valid_prop_infos, validation_location) def __walk_property(self, property_name, property_value, valid_prop_infos, model_folder_path, validation_location): _method_name = '__walk_property' self._logger.entering(property_name, property_value, str(valid_prop_infos), model_folder_path, class_name=_class_name, method_name=_method_name) if property_name in valid_prop_infos: expected_data_type = valid_prop_infos[property_name] if expected_data_type == 'password': self.__substitute_password_with_token(model_folder_path, property_name, validation_location) def __format_variable_name(self, location, attribute): _method_name = '__format_variable_name' def __traverse_location(iterate_location, name_list, last_folder=None, last_folder_short=None): current_folder = iterate_location.get_current_model_folder() if current_folder == model_constants.DOMAIN: if last_folder is not None: # If a short name is not defined for the top level folder, use the full name if len(last_folder_short) == 0: last_folder_short = last_folder name_list.insert(0, last_folder_short) else: current_folder = iterate_location.get_current_model_folder() short_folder = self._aliases.get_folder_short_name(iterate_location) if last_folder_short is not None: name_list.insert(0, last_folder_short) try: if not self._aliases.is_artificial_type_folder(location) and \ (self._aliases.supports_multiple_mbean_instances(iterate_location) or self._aliases.is_custom_folder_allowed(iterate_location)): name_token = self._aliases.get_name_token(iterate_location) name = iterate_location.get_name_for_token(name_token) name_list.insert(0, name) iterate_location.remove_name_token(name_token) iterate_location.pop_location() except AliasException, ae: self._logger.warning('WLSDPLY-19531', str(location), attribute, ae.getLocalizedMessage(), class_name=_class_name, method_name=_method_name) __traverse_location(iterate_location, name_list, current_folder, short_folder) return name_list short_list = __traverse_location(LocationContext(location), list()) short_name = '' for node in short_list: if node is not None and len(node) > 0: short_name += node + '.' short_name += attribute _fake_name_replacement = re.compile('.fakename') _white_space_replacement = re.compile('\s') short_name = short_name.replace('/', '.') short_name = _white_space_replacement.sub('-', short_name) short_name = _fake_name_replacement.sub('', short_name) return short_name
class PrepareModel: """ This is the main driver for the caller. It compares two model files whether they are json or yaml format. """ def __init__(self, model_files, model_context, logger, output_dir=None): self.model_files = model_files self.output_dir = output_dir self.model_context = model_context self._aliases = Aliases(model_context=model_context, wlst_mode=WlstModes.OFFLINE) self._alias_helper = AliasHelper(self._aliases, logger, ExceptionType.COMPARE) self._logger = logger self._name_tokens_location = LocationContext() self._name_tokens_location.add_name_token('DOMAIN', "testdomain") self.current_dict = None self.cache = OrderedDict() self.secrets_to_generate = sets.Set() def __walk_model_section(self, model_section_key, model_dict, valid_section_folders): _method_name = '__validate_model_section' if model_section_key not in model_dict.keys(): return # only specific top-level sections have attributes attribute_location = self._alias_helper.get_model_section_attribute_location( model_section_key) valid_attr_infos = [] path_tokens_attr_keys = [] if attribute_location is not None: valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types( attribute_location) path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names( attribute_location) model_section_dict = model_dict[model_section_key] for section_dict_key, section_dict_value in model_section_dict.iteritems( ): # section_dict_key is either the name of a folder in the # section, or the name of an attribute in the section. validation_location = LocationContext() model_folder_path = model_section_key + ":/" if section_dict_key in valid_attr_infos: # section_dict_key is the name of an attribute in the section self.__walk_attribute(section_dict_key, section_dict_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, attribute_location) elif section_dict_key in valid_section_folders: # section_dict_key is a folder under the model section # Append section_dict_key to location context validation_location.append_location(section_dict_key) # Call self.__validate_section_folder() passing in section_dict_value as the model_node to process self.__walk_section_folder(section_dict_value, validation_location) def __walk_section_folder(self, model_node, validation_location): _method_name = '__validate_section_folder' model_folder_path = self._alias_helper.get_model_folder_path( validation_location) if self._alias_helper.supports_multiple_mbean_instances( validation_location): for name in model_node: expanded_name = name new_location = LocationContext(validation_location) name_token = self._alias_helper.get_name_token(new_location) if name_token is not None: new_location.add_name_token(name_token, expanded_name) value_dict = model_node[name] self.__walk_model_node(value_dict, new_location) elif self._alias_helper.requires_artificial_type_subfolder_handling( validation_location): for name in model_node: expanded_name = name new_location = LocationContext(validation_location) name_token = self._alias_helper.get_name_token(new_location) if name_token is not None: new_location.add_name_token(name_token, expanded_name) value_dict = model_node[name] self.__walk_model_node(value_dict, new_location) else: name_token = self._alias_helper.get_name_token(validation_location) if name_token is not None: name = self._name_tokens_location.get_name_for_token( name_token) if name is None: name = '%s-0' % name_token validation_location.add_name_token(name_token, name) self.__walk_model_node(model_node, validation_location) def __walk_model_node(self, model_node, validation_location): _method_name = '__process_model_node' valid_folder_keys = self._alias_helper.get_model_subfolder_names( validation_location) valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types( validation_location) model_folder_path = self._alias_helper.get_model_folder_path( validation_location) for key, value in model_node.iteritems(): if key in valid_folder_keys: new_location = LocationContext( validation_location).append_location(key) if self._alias_helper.is_artificial_type_folder(new_location): # key is an ARTIFICIAL_TYPE folder valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types( new_location) self.__walk_attributes(value, valid_attr_infos, new_location) else: self.__walk_section_folder(value, new_location) elif key in valid_attr_infos: # aliases.get_model_attribute_names_and_types(location) filters out # attributes that ARE NOT valid in the wlst_version being used, so if # we're in this section of code we know key is a bonafide "valid" attribute valid_data_type = valid_attr_infos[key] if valid_data_type in ['properties']: valid_prop_infos = {} properties = validation_utils.get_properties(value) self.__walk_properties(properties, valid_prop_infos, model_folder_path, validation_location) else: path_tokens_attr_keys = \ self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location) self.__walk_attribute(key, value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location) def __walk_attributes(self, attributes_dict, valid_attr_infos, validation_location): _method_name = '__validate_attributes' path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names( validation_location) model_folder_path = self._alias_helper.get_model_folder_path( validation_location) for attribute_name, attribute_value in attributes_dict.iteritems(): self.__walk_attribute(attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location) def __walk_attribute(self, attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location): _method_name = '__walk_attribute' if attribute_name in valid_attr_infos: expected_data_type = valid_attr_infos[attribute_name] if (expected_data_type == 'password') or (attribute_name == ADMIN_USERNAME): self.__substitute_password_with_token(model_folder_path, attribute_name, validation_location) self._logger.exiting(class_name=_class_name, method_name=_method_name) def __walk_properties(self, properties_dict, valid_prop_infos, model_folder_path, validation_location): _method_name = '__walk_properties' for property_name, property_value in properties_dict.iteritems(): valid_prop_infos[ property_name] = validation_utils.get_python_data_type( property_value) self.__walk_property(property_name, property_value, valid_prop_infos, model_folder_path, validation_location) def __walk_property(self, property_name, property_value, valid_prop_infos, model_folder_path, validation_location): _method_name = '__walk_property' self._logger.entering(property_name, property_value, str(valid_prop_infos), model_folder_path, class_name=_class_name, method_name=_method_name) if property_name in valid_prop_infos: expected_data_type = valid_prop_infos[property_name] if expected_data_type == 'password': self.__substitute_password_with_token(model_folder_path, property_name, validation_location) def __substitute_password_with_token(self, model_path, attribute_name, validation_location): """ Add the secret for the specified attribute to the cache. If the target specifies credentials_method: secrets, substitute the secret token into the model. :param model_path: text representation of the model path :param attribute_name: the name of the attribute or (property) :param validation_location: the model location """ model_path_tokens = model_path.split('/') tokens_length = len(model_path_tokens) variable_name = variable_injector_functions.format_variable_name( validation_location, attribute_name, self._aliases) if tokens_length > 1: credentials_method = self.model_context.get_target_configuration( ).get_credentials_method() # by default, don't do any assignment to attribute model_value = None # use attribute name for admin password if model_path_tokens[0] == 'domainInfo:' and model_path_tokens[ 1] == '': cache_key = attribute_name else: cache_key = variable_name # for normal secrets, assign the secret name to the attribute if credentials_method == SECRETS_METHOD: model_value = target_configuration_helper.format_as_secret_token( cache_key) self.cache[cache_key] = '' # for config override secrets, assign a placeholder password to the attribute. # config overrides will be used to override the value in the target domain. if credentials_method == CONFIG_OVERRIDES_SECRETS_METHOD: model_value = PASSWORD_PLACEHOLDER self.cache[cache_key] = '' if model_value is not None: p_dict = self.current_dict for index in range(0, len(model_path_tokens)): token = model_path_tokens[index] if token == '': break if token[-1] == ':': token = token[:-1] p_dict = p_dict[token] p_dict[attribute_name] = model_value def walk(self): """ Replace password attributes in each model file with secret tokens, and write each model. Generate a script to create the required secrets. Create any additional output specified for the target environment. """ _method_name = "walk" model_file_name = None try: model_file_list = self.model_files.split(',') for model_file in model_file_list: self.cache.clear() if os.path.splitext(model_file)[1].lower() == ".yaml": model_file_name = model_file FileToPython(model_file_name, True).parse() aliases = Aliases(model_context=self.model_context, wlst_mode=WlstModes.OFFLINE) validator = Validator(self.model_context, aliases, wlst_mode=WlstModes.OFFLINE) # Just merge and validate but without substitution model_dictionary = cla_helper.merge_model_files( model_file_name, None) variable_file = self.model_context.get_variable_file() if not os.path.exists(variable_file): variable_file = None return_code = validator.validate_in_tool_mode( model_dictionary, variables_file_name=variable_file, archive_file_name=None) if return_code == Validator.ReturnCode.STOP: self._logger.severe('WLSDPLY-05705', model_file_name) return VALIDATION_FAIL self.current_dict = model_dictionary self.__walk_model_section( model.get_model_domain_info_key(), self.current_dict, aliases.get_model_section_top_level_folder_names( DOMAIN_INFO)) self.__walk_model_section( model.get_model_topology_key(), self.current_dict, aliases.get_model_topology_top_level_folder_names()) self.__walk_model_section( model.get_model_resources_key(), self.current_dict, aliases.get_model_resources_top_level_folder_names()) self.current_dict = self._apply_filter_and_inject_variable( self.current_dict, self.model_context, validator) file_name = os.path.join(self.output_dir, os.path.basename(model_file_name)) fos = JFileOutputStream(file_name, False) writer = JPrintWriter(fos, True) pty = PythonToYaml(self.current_dict) pty._write_dictionary_to_yaml_file(self.current_dict, writer) writer.close() self.cache.clear() for key in self.secrets_to_generate: self.cache[key] = '' # use a merged, substituted, filtered model to get domain name and create additional target output. full_model_dictionary = cla_helper.load_model( _program_name, self.model_context, self._alias_helper, "discover", WlstModes.OFFLINE) target_configuration_helper.generate_k8s_script( self.model_context, self.cache, full_model_dictionary) # create any additional outputs from full model dictionary target_configuration_helper.create_additional_output( Model(full_model_dictionary), self.model_context, self._alias_helper, ExceptionType.VALIDATE) except ValidateException, te: self._logger.severe('WLSDPLY-20009', _program_name, model_file_name, te.getLocalizedMessage(), error=te, class_name=_class_name, method_name=_method_name) ex = exception_helper.create_compare_exception( te.getLocalizedMessage(), error=te) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) return VALIDATION_FAIL except VariableException, ve: self._logger.severe('WLSDPLY-20009', _program_name, model_file_name, ve.getLocalizedMessage(), error=ve, class_name=_class_name, method_name=_method_name) ex = exception_helper.create_compare_exception( ve.getLocalizedMessage(), error=ve) self._logger.throwing(ex, class_name=_class_name, method_name=_method_name) return VALIDATION_FAIL