Exemplo n.º 1
0
class TargetHelper(object):
    """
    Shared code for targeting clusters and servers. Domain create and update use this code.
    """
    __class_name = 'TargetHelper'

    def __init__(self, model, model_context, aliases, exception_type, logger):
        self.logger = logger
        self.model = model
        self.model_context = model_context
        self.alias_helper = AliasHelper(aliases, self.logger, exception_type)
        self.wlst_helper = WlstHelper(self.logger, exception_type)
        self.exception_type = exception_type

        topology = model.get_model_topology()
        if ADMIN_SERVER_NAME in topology:
            self._admin_server_name = topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

    def target_jrf_groups_to_clusters_servers(self, should_update=True):
        """
        Call applyJRF to for those versions of wlst that cannot target servers to server groups.
        This assigns the JRF resources to all managed servers. If the managed server is in a
        cluster, this method assigns the JRF resources are assigned to the cluster. Else, if
        the managed server is stand-alone, the resources are assigned to the managed server.
        :param should_update: Control how the applyJRF applies the changes. By default, allow
        the applyJRF to automatically update the values
        """
        _method_name = 'target_jrf_groups_to_clusters_servers'
        self.logger.entering(should_update, class_name=self.__class_name,
                             method_name=_method_name)

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)
        admin_server_name = self.wlst_helper.get(ADMIN_SERVER_NAME)

        # We need to get the effective list of servers for the domain.  Since any servers
        # referenced in the model have already been created but the templates may have
        # defined new servers not listed in the model, get the list from WLST.
        server_names = self.get_existing_server_names()
        if admin_server_name in server_names:
            server_names.remove(admin_server_name)

        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()

        self.wlst_helper.save_and_close(self.model_context)
        
        # Get the clusters and and their members
        for cluster_name, cluster_servers in cluster_map.iteritems():
            self.logger.info('WLSDPLY-12233', 'Cluster', cluster_name, class_name=self.__class_name,
                             method_name=_method_name)
            self.wlst_helper.apply_jrf(cluster_name, self.model_context, should_update=should_update)
            for member in cluster_servers:
                if member in server_names:
                    server_names.remove(member)
        for ms_name in server_names:
            self.logger.info('WLSDPLY-12233', 'Managed Server', ms_name, class_name=self.__class_name,
                             method_name=_method_name)
            self.wlst_helper.apply_jrf(ms_name, self.model_context, should_update=should_update)

        self.wlst_helper.reopen(self.model_context)
        
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def target_server_groups_to_servers(self, server_groups_to_target):
        """
        Target the server groups to the servers.
        :param server_groups_to_target: the list of server groups to target
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = 'target_server_groups_to_servers'

        self.logger.entering(server_groups_to_target, class_name=self.__class_name, method_name=_method_name)
        if len(server_groups_to_target) == 0:
            return list(), list()

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)

        # We need to get the effective list of servers for the domain.  Since any servers
        # referenced in the model have already been created but the templates may have
        # defined new servers not listed in the model, get the list from WLST.
        server_names = self._get_existing_server_names()

        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()
        dynamic_cluster_names = list()
        for cluster_name in cluster_map:
            if DYNAMIC_SERVERS in cluster_map[cluster_name]:
                dynamic_cluster_names.append(cluster_name)

        # Get any limits that may have been defined in the model
        domain_info = self.model.get_model_domain_info()
        server_group_targeting_limits = \
            dictionary_utils.get_dictionary_element(domain_info, SERVER_GROUP_TARGETING_LIMITS)
        if len(server_group_targeting_limits) > 0:
            server_group_targeting_limits = \
                self._get_server_group_targeting_limits(server_group_targeting_limits, cluster_map)

        self.logger.finer('WLSDPLY-12240', str(server_group_targeting_limits),
                          class_name=self.__class_name, method_name=_method_name)

        # Get the map of server names to server groups to target
        server_to_server_groups_map =\
            self._get_server_to_server_groups_map(self._admin_server_name,
                                                  server_names,
                                                  dynamic_cluster_names,
                                                  server_groups_to_target,
                                                  server_group_targeting_limits)  # type: dict
        self.logger.finer('WLSDPLY-12242', str(server_to_server_groups_map), class_name=self.__class_name,
                          method_name=_method_name)

        final_assignment_map = dict()
        dynamic_cluster_assigns = dict()
        # Target servers and dynamic clusters to the server group resources
        if len(server_names) > 0 or len(dynamic_cluster_names) > 0:
            for server, server_groups in server_to_server_groups_map.iteritems():
                if len(server_groups) > 0:
                    if server in server_names:
                        final_assignment_map[server] = server_groups
                    elif server in dynamic_cluster_names:
                        dynamic_cluster_assigns[server] = server_groups

        #
        # Domain has not targeted the server groups to managed servers (configured), or the
        # domain has no managed servers (configured) but has user server groups. The resources for the
        # user server groups must be targeted before the write/update domain or the write/update will fail.
        # Thus assign the user server groups to the admin server.
        #
        # Because of the interaction of the working context in the different wlst helpers, the dynamic
        # clusters will be applied to the resources separately and after the write/update domain.
        #
        # (From original blurb)
        #  This is really a best effort attempt.  It works for JRF domains but it is certainly possible
        # that it may cause problems with other custom domain types.  Of course, creating a domain with
        # no managed servers is not a primary use case of this tool so do it and hope for the best...
        #
        # (New comment)
        # As we have added the intricacies of the dynamic clusters, if the targeting is to dynamic
        # clusters only, the set server groups with the admin server will get through the write/update domain
        # and the applyJRF with the dynamic cluster should theoretically unset the AdminServer on the user server
        # groups. It works with JRF type domains.

        if len(server_groups_to_target) > 0:
            if len(final_assignment_map) == 0:
                # This is a quickie to fix the issue where server groups are not targeted because no configured
                #  managed servers exist in the domain
                final_assignment_map[server_names[0]] = server_groups_to_target
            else:
                # If a server group or groups is not targeted in the assignments, log it to stdout
                no_targets = [server_target for server_target in server_groups_to_target if server_target not in
                              [server_target for row in final_assignment_map.itervalues() for
                               server_target in server_groups_to_target if server_target in row]]
                if len(no_targets) > 0:
                    self.logger.info('WLSDPLY-12248', no_targets,
                                     class_name=self.__class_name, method_name=_method_name)

        self.logger.exiting(result=str(dynamic_cluster_assigns),
                            class_name=self.__class_name, method_name=_method_name)
        return final_assignment_map, dynamic_cluster_assigns

    def target_server_groups(self, server_assigns):
        """
        Perform the targeting of the server groups to server from the list of assignments made in the
        target helper assignment step. This is separate from creating the list of assignments in order
        to control the state of the domain when the target is done.
        :param server_assigns: map of server to server group
        """
        _method_name = 'target_server_groups'
        self.logger.entering(str(server_assigns), class_name=self.__class_name, method_name=_method_name)

        for server, server_groups in server_assigns.iteritems():
            server_name = self.wlst_helper.get_quoted_name_for_wlst(server)
            self.logger.info('WLSDPLY-12224', str(server_groups), server_name,
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.set_server_groups(server_name, server_groups)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)

    def target_server_groups_to_dynamic_clusters(self, dynamic_cluster_assigns):
        """
        Dynamic clusters need special handling to assign the server group resources to the dynamic cluster.
        You cannot assign servergroups to a server template. So must search each templates that contain the server group
        for resources and specifically add the dynamic target to the resource target.
        If JRF or RestrictedJRF skip the check and do the applyJRF function to automatically target to the cluster.
        :param dynamic_cluster_assigns: The assignments from domainInfo targeting limits applied to dynamic lusters
        """
        _method_name = 'target_server_group_resources_to_dyanamic_cluster'
        self.logger.entering(str(dynamic_cluster_assigns), class_name=self.__class_name, method_name=_method_name)

        domain_typedef = self.model_context.get_domain_typedef()

        if len(dynamic_cluster_assigns) > 0:
            self.logger.info('WLSDPLY-12247', class_name=self.__class_name, method_name=_method_name)
            # TBD assign server group resources to cluster. The JRF resources could still be applied separately
            # using this technique - or remove this technique and replace with the resource targeting
            if domain_typedef.has_jrf_resources():
                self._target_jrf_resources(dynamic_cluster_assigns)
            else:
                self.logger.warning('WLSDPLY-12238', domain_typedef.get_domain_type(),
                                    class_name=self.__class_name, method_name=_method_name)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def _target_jrf_resources(self, dynamic_cluster_assigns):
        # Target the JRF resources directly using the applyJRF method.
        _method_name = '_target_jrf_resources'
        names_only = list()
        for name in dynamic_cluster_assigns:
            names_only.append(name)
        if self.model_context.is_wlst_online() and \
                self.model_context.get_domain_typedef().is_restricted_jrf_domain_type():
            self.logger.warning('WLSDPLY-12244', str(names_only), class_name=self.__class_name,
                                _method_name=_method_name)
        else:
            self.logger.info('WLSDPLY-12236', str(names_only),
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.apply_jrf_control_updates(names_only, self.model_context)

    def _get_existing_server_names(self):
        """
        Get the list of server names from WLST.
        :return: the list of server names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_existing_server_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        result = self.wlst_helper.get_existing_object_list(server_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _get_clusters_and_members_map(self):
        """
        Get a map keyed by cluster name with values that are a list of member server names
        :return: the cluster name to member server names map
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_clusters_and_members_map'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        server_names = self.wlst_helper.get_existing_object_list(server_list_path)
        server_token = self.alias_helper.get_name_token(server_location)
        cluster_map = OrderedDict()
        for server_name in server_names:
            server_location.add_name_token(server_token, server_name)
            server_attributes_path = self.alias_helper.get_wlst_attributes_path(server_location)
            self.wlst_helper.cd(server_attributes_path)

            server_attributes_map = self.wlst_helper.lsa()
            cluster_name = dictionary_utils.get_element(server_attributes_map, CLUSTER)
            if string_utils.is_empty(cluster_name):
                # if server is not part of a cluster, continue with the next server
                continue

            if cluster_name not in cluster_map:
                cluster_map[cluster_name] = list()
            cluster_map[cluster_name].append(server_name)

        clusters_location = LocationContext().append_location(CLUSTER)
        cluster_list_path = self.alias_helper.get_wlst_list_path(clusters_location)
        cluster_names = self.wlst_helper.get_existing_object_list(cluster_list_path)
        cluster_token = self.alias_helper.get_name_token(clusters_location)
        # Add the cluster with dynamic servers, if not already in the cluster member list.
        # A cluster may contain both dynamic and configured servers (referred to as mixed cluster).
        # Add a token marking DYNAMIC SERVERS in the member list.
        for cluster_name in cluster_names:
            cluster_location = LocationContext(clusters_location)
            cluster_location.add_name_token(cluster_token, cluster_name)
            cluster_attributes_path = self.alias_helper.get_wlst_attributes_path(cluster_location)
            self.wlst_helper.cd(cluster_attributes_path)
            cluster_location.append_location(DYNAMIC_SERVERS)
            wlst_subfolder_name = self.alias_helper.get_wlst_mbean_type(cluster_location)
            if self.wlst_helper.subfolder_exists(wlst_subfolder_name):
                if cluster_name not in cluster_map:
                    cluster_map[cluster_name] = list()
                cluster_map[cluster_name].append(DYNAMIC_SERVERS)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=cluster_map)
        return cluster_map

    def get_existing_server_names(self):
        """
        Get the list of server names from WLST.
        :return: the list of server names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_existing_server_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        result = self.wlst_helper.get_existing_object_list(server_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def get_existing_cluster_names(self):
        """
        Get the list of cluster names from WLST.
        :return: the list of cluster names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = 'get_existing_cluster_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        cluster_location = LocationContext().append_location(CLUSTER)
        cluster_list_path = self.alias_helper.get_wlst_list_path(cluster_location)
        result = self.wlst_helper.get_existing_object_list(cluster_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _get_server_group_targeting_limits(self, server_group_targeting_limits, clusters_map):
        """
        Get any server group targeting limits specified in the model, converting any cluster
        names to the list of members.  This method assumes that the limits dictionary is not
        None or empty.
        :param server_group_targeting_limits: the raw server group targeting_limits from the model
        :param clusters_map: the map of cluster names to member server names
        :return: the map of server groups to server names to target
        """
        _method_name = '_get_server_group_targeting_limits'

        self.logger.entering(str(server_group_targeting_limits), str(clusters_map),
                             class_name=self.__class_name, method_name=_method_name)
        sg_targeting_limits = copy.deepcopy(server_group_targeting_limits)
        for server_group_name, sg_targeting_limit in sg_targeting_limits.iteritems():
            if type(sg_targeting_limit) is str:
                if MODEL_LIST_DELIMITER in sg_targeting_limit:
                    sg_targeting_limit = sg_targeting_limit.split(MODEL_LIST_DELIMITER)
                else:
                    # convert a single value into a list of one...
                    new_list = list()
                    new_list.append(sg_targeting_limit)
                    sg_targeting_limit = new_list

            # Convert any references to a cluster name into the list of member server names
            new_list = list()
            for target_name in sg_targeting_limit:
                target_name = target_name.strip()
                if target_name in clusters_map:
                    cluster_members = dictionary_utils.get_element(clusters_map, target_name)
                    if DYNAMIC_SERVERS in cluster_members:
                        # This will need special handling to target server group resources
                        cluster_members.remove(DYNAMIC_SERVERS)
                        cluster_members.append(target_name)
                    new_list.extend(cluster_members)
                else:
                    # Assume it is a server name and add it to the new list
                    # Stand-alone Managed Servers were not added to the cluster: server_name_list map
                    # which was built from the existing servers and clusters.
                    new_list.append(target_name)
            sg_targeting_limits[server_group_name] = new_list

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=sg_targeting_limits)
        return sg_targeting_limits

    def _get_server_to_server_groups_map(self, admin_server_name, server_names, dynamic_cluster_names,
                                         server_groups, sg_targeting_limits):
        """
        Get the map of server names to the list of server groups to target to that server.
        :param admin_server_name: the admin server name
        :param server_names: the list of server names
        :param server_groups: the complete list of server groups that will, by default, be targeted to
                              all managed servers unless the server is listed in the targeting limits map
        :param sg_targeting_limits: the targeting limits map
        :return: the map of server names to the list of server groups to target to that server
        """
        _method_name = '_get_server_to_server_groups_map'

        self.logger.entering(admin_server_name, str(server_names), str(server_groups), str(sg_targeting_limits),
                             class_name=self.__class_name, method_name=_method_name)
        result = OrderedDict()
        revised_server_groups = self._revised_list_server_groups(server_groups, sg_targeting_limits)
        for server_name in server_names:
            server_groups_for_server = self.__get_server_groups_for_entity(server_name, sg_targeting_limits)
            if len(server_groups_for_server) > 0:
                result[server_name] = server_groups_for_server
            elif server_name != admin_server_name:
                # By default, we only target managed servers unless explicitly listed in the targeting limits
                result[server_name] = list(revised_server_groups)
            else:
                result[admin_server_name] = list()
        for cluster_name in dynamic_cluster_names:
            server_groups_for_cluster = \
                self.__get_server_groups_for_entity(cluster_name, sg_targeting_limits)
            if len(server_groups_for_cluster) > 0:
                result[cluster_name] = server_groups_for_cluster
            else:
                result[cluster_name] = list(revised_server_groups)
            self.logger.finer('WLSDPLY-12239', result[cluster_name], cluster_name,
                              class_name=self.__class_name, method_name=_method_name)
        if admin_server_name not in result:
            result[admin_server_name] = list()
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _revised_list_server_groups(self, server_groups, sg_targeting_limits):
        """
        Remove all server groups that are explicitly targeted to a cluster, server set or stand-alone
        managed server.
        :param server_groups: list of server groups applied by the extension templates
        :param sg_targeting_limits: list of targeting from the domainInfo section
        :return: server group list with the specific targeted server groups removed
        """
        _method_name = '_revised_list_server_groups'
        self.logger.entering(sg_targeting_limits, class_name=self.__class_name, method_name=_method_name)
        result = list()
        targeted_server_groups = sg_targeting_limits.keys()
        for server_group in server_groups:
            if server_group not in targeted_server_groups:
                result.append(server_group)
        return result

    def __get_server_groups_for_entity(self, entity_name, sg_targeting_limits):
        """
        Get the servers groups to target for a given server or dynamic cluster name.
        :param entity_name: the server or dynamic_cluster name
        :param sg_targeting_limits: the targeting limits
        :return: the list of server groups to target to the specified entity name, or None
                 if the entity name does not appear in the targeting limits
        """
        _method_name = '__get_server_groups_for_entity'
        result = list()
        for server_group, entity_names_list in sg_targeting_limits.iteritems():
            if entity_name in entity_names_list:
                result.append(server_group)
        if len(result) > 0:
            self.logger.fine('WLSDPLY-12243', entity_name, result, class_name=self.__class_name,
                             method_name=_method_name)
        return result
Exemplo n.º 2
0
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.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)
        # 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.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, child_nodes)
            self._create_subfolders(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:
            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.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)
        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name)
        return

    def _create_security_provider_mbeans(self,
                                         type_name,
                                         model_nodes,
                                         base_location,
                                         log_created=False):
        """
        Create the specified security provider MBean types that support multiple instances but use an
        artificial type subfolder 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_security_provider_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:
            prov_location = LocationContext(location)
            name = self.wlst_helper.get_quoted_name_for_wlst(model_name)
            if token_name is not None:
                prov_location.add_name_token(token_name, name)

            wlst_base_provider_type, wlst_name = self.alias_helper.get_wlst_mbean_type_and_name(
                prov_location)
            model_node = model_nodes[model_name]
            if model_node is not None:
                if len(model_node) == 1:
                    model_type_subfolder_name = list(model_node.keys())[0]
                    prov_location.append_location(model_type_subfolder_name)
                    wlst_type = self.alias_helper.get_wlst_mbean_type(
                        prov_location)
                else:
                    ex = exception_helper.create_create_exception(
                        'WLSDPLY-12117', type_name, model_name,
                        len(model_node))
                    self.logger.throwing(ex,
                                         class_name=self.__class_name,
                                         method_name=_method_name)
                    raise ex
            else:
                # The node is empty so nothing to do...move to the next named node.
                continue

            if wlst_name not in existing_folder_names:
                if log_created:
                    self.logger.info('WLSDPLY-12118',
                                     type_name,
                                     model_type_subfolder_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                else:
                    self.logger.fine('WLSDPLY-12118',
                                     type_name,
                                     model_type_subfolder_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                self.wlst_helper.cd(create_path)
                self.wlst_helper.create(wlst_name, wlst_type,
                                        wlst_base_provider_type)
            else:
                if log_created:
                    self.logger.info('WLSDPLY-12119',
                                     type_name,
                                     model_type_subfolder_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                else:
                    self.logger.fine('WLSDPLY-12119',
                                     type_name,
                                     model_type_subfolder_name,
                                     name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)

            attribute_path = self.alias_helper.get_wlst_attributes_path(
                prov_location)
            self.wlst_helper.cd(attribute_path)

            child_nodes = dictionary_utils.get_dictionary_element(
                model_node, model_type_subfolder_name)
            self.logger.finest(
                'WLSDPLY-12111',
                self.alias_helper.get_model_folder_path(prov_location),
                self.wlst_helper.get_pwd(),
                class_name=self.__class_name,
                method_name=_method_name)
            self._set_attributes(prov_location, child_nodes)
            self._create_subfolders(prov_location, child_nodes)

        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name)
        return

    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:
Exemplo n.º 3
0
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.wlst_helper = WlstHelper(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,
                             delete_now=True):
        """
        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.aliases.get_name_token(location)
        create_path = self.aliases.get_wlst_create_path(location)
        list_path = self.aliases.get_wlst_list_path(location)
        existing_folder_names = self._get_existing_folders(list_path)
        for model_name in model_nodes.keys():
            name = self.wlst_helper.get_quoted_name_for_wlst(model_name)
            if model_helper.is_delete_name(name):
                if delete_now:
                    deployer_utils.delete_named_element(
                        location, name, existing_folder_names, self.aliases)
                continue

            if token_name is not None:
                location.add_name_token(token_name, name)

            wlst_type, wlst_name = self.aliases.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.aliases, 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.aliases.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.aliases.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.aliases.get_wlst_create_path(location)
        existing_folder_names = self._get_existing_folders(create_path)

        mbean_type, mbean_name = self.aliases.get_wlst_mbean_type_and_name(
            location)

        token_name = self.aliases.get_name_token(location)
        if token_name is not None:
            if self.aliases.requires_unpredictable_single_name_handling(
                    location):
                existing_subfolder_names = deployer_utils.get_existing_object_list(
                    location, self.aliases)
                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.aliases, 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.aliases.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.aliases.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.aliases.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.aliases.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.aliases.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.aliases.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.aliases.get_model_attribute_names_and_types(
            location)
        password_attribute_names = self.aliases.get_model_password_type_attribute_names(
            location)
        set_method_map = self.aliases.get_model_mbean_set_method_attribute_names_and_types(
            location)
        uses_path_tokens_attribute_names = self.aliases.get_model_uses_path_tokens_attribute_names(
            location)
        model_folder_path = self.aliases.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.aliases.get_model_folder_path(location),
                    error=ae)
                self.logger.throwing(ex,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                raise ex
        else:
Exemplo n.º 4
0
class TargetHelper(object):
    """
    Shared code for targeting clusters and servers. Domain create and update use this code.
    """
    __class_name = 'TargetHelper'

    def __init__(self, model, model_context, aliases, exception_type, logger):
        self.logger = logger
        self.model = model
        self.model_context = model_context
        self.alias_helper = AliasHelper(aliases, self.logger, exception_type)
        self.wlst_helper = WlstHelper(self.logger, exception_type)

        topology = model.get_model_topology()
        if ADMIN_SERVER_NAME in topology:
            self._admin_server_name = topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

    def target_server_groups_to_servers(self, server_groups_to_target):
        """
        Target the server groups to the servers.
        :param server_groups_to_target: the list of server groups to target
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = '__target_server_groups_to_servers'

        self.logger.entering(server_groups_to_target,
                             class_name=self.__class_name,
                             method_name=_method_name)
        if len(server_groups_to_target) == 0:
            return

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)

        # We need to get the effective list of servers for the domain.  Since any servers
        # referenced in the model have already been created but the templates may have
        # defined new servers not listed in the model, get the list from WLST.
        server_names = self._get_existing_server_names()

        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()

        # Get any limits that may have been defined in the model
        domain_info = self.model.get_model_domain_info()
        server_group_targeting_limits = \
            dictionary_utils.get_dictionary_element(domain_info, SERVER_GROUP_TARGETING_LIMITS)
        if len(server_group_targeting_limits) > 0:
            server_group_targeting_limits = \
                self._get_server_group_targeting_limits(server_group_targeting_limits, cluster_map)

        # Get the map of server names to server groups to target
        server_to_server_groups_map =\
            self._get_server_to_server_groups_map(self._admin_server_name,
                                                  server_names,
                                                  server_groups_to_target,
                                                  server_group_targeting_limits)  # type: dict

        if len(server_names) > 1:
            for server, server_groups in server_to_server_groups_map.iteritems(
            ):
                if len(server_groups) > 0:
                    server_name = self.wlst_helper.get_quoted_name_for_wlst(
                        server)
                    self.logger.info('WLSDPLY-12224',
                                     str(server_groups),
                                     server_name,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                    self.wlst_helper.set_server_groups(server_name,
                                                       server_groups)

        elif len(server_group_targeting_limits) == 0:
            #
            # Domain has no managed servers and there were not targeting limits specified to target
            # server groups to the admin server so make sure that the server groups are targeted to
            # the admin server.
            #
            # This is really a best effort attempt.  It works for JRF domains but it is certainly possible
            # that it may cause problems with other custom domain types.  Of course, creating a domain with
            # no managed servers is not a primary use case of this tool so do it and hope for the best...
            #
            server_name = self.wlst_helper.get_quoted_name_for_wlst(
                server_names[0])
            self.wlst_helper.set_server_groups(server_name,
                                               server_groups_to_target)

        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name)
        return

    def _get_existing_server_names(self):
        """
        Get the list of server names from WLST.
        :return: the list of server names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_existing_server_names'

        self.logger.entering(class_name=self.__class_name,
                             method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(
            server_location)
        result = self.wlst_helper.get_existing_object_list(server_list_path)
        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name,
                            result=result)
        return result

    def _get_clusters_and_members_map(self):
        """
        Get a map keyed by cluster name with values that are a list of member server names
        :return: the cluster name to member server names map
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_clusters_and_members_map'

        self.logger.entering(class_name=self.__class_name,
                             method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(
            server_location)
        server_names = self.wlst_helper.get_existing_object_list(
            server_list_path)
        server_token = self.alias_helper.get_name_token(server_location)
        cluster_map = OrderedDict()
        for server_name in server_names:
            server_location.add_name_token(server_token, server_name)
            server_attributes_path = self.alias_helper.get_wlst_attributes_path(
                server_location)
            self.wlst_helper.cd(server_attributes_path)

            server_attributes_map = self.wlst_helper.lsa()
            cluster_name = dictionary_utils.get_element(
                server_attributes_map, CLUSTER)
            if string_utils.is_empty(cluster_name):
                # if server is not part of a cluster, continue with the next server
                continue

            if cluster_name not in cluster_map:
                cluster_map[cluster_name] = list()
            cluster_map[cluster_name].append(server_name)

        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name,
                            result=cluster_map)
        return cluster_map

    def _get_server_group_targeting_limits(self, server_group_targeting_limits,
                                           clusters_map):
        """
        Get any server group targeting limits specified in the model, converting any cluster
        names to the list of members.  This method assumes that the limits dictionary is not
        None or empty.
        :param server_group_targeting_limits: the raw server group targeting_limits from the model
        :param clusters_map: the map of cluster names to member server names
        :return: the map of server groups to server names to target
        """
        _method_name = '_get_server_group_targeting_limits'

        self.logger.entering(str(server_group_targeting_limits),
                             str(clusters_map),
                             class_name=self.__class_name,
                             method_name=_method_name)
        sg_targeting_limits = copy.deepcopy(server_group_targeting_limits)
        for server_group_name, sg_targeting_limit in sg_targeting_limits.iteritems(
        ):
            if type(sg_targeting_limit) is str:
                if MODEL_LIST_DELIMITER in sg_targeting_limit:
                    sg_targeting_limit = sg_targeting_limit.split(
                        MODEL_LIST_DELIMITER)
                else:
                    # convert a single value into a list of one...
                    new_list = list()
                    new_list.append(sg_targeting_limit)
                    sg_targeting_limit = new_list

            # Convert any references to a cluster name into the list of member server names
            new_list = list()
            for target_name in sg_targeting_limit:
                target_name = target_name.strip()
                if target_name in clusters_map:
                    cluster_members = dictionary_utils.get_element(
                        clusters_map, target_name)
                    new_list.extend(cluster_members)
                else:
                    # Assume it is a server name and add it to the new list
                    new_list.append(target_name)
            sg_targeting_limits[server_group_name] = new_list

        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name,
                            result=sg_targeting_limits)
        return sg_targeting_limits

    def _get_server_to_server_groups_map(self, admin_server_name, server_names,
                                         server_groups, sg_targeting_limits):
        """
        Get the map of server names to the list of server groups to target to that server.
        :param admin_server_name: the admin server name
        :param server_names: the list of server names
        :param server_groups: the complete list of server groups that will, by default, be targeted to
                              all managed servers unless the server is listed in the targeting limits map
        :param sg_targeting_limits: the targeting limits map
        :return: the map of server names to the list of server groups to target to that server
        """
        _method_name = '_get_server_to_server_groups_map'

        self.logger.entering(admin_server_name,
                             str(server_names),
                             str(server_groups),
                             str(sg_targeting_limits),
                             class_name=self.__class_name,
                             method_name=_method_name)
        result = OrderedDict()
        for server_name in server_names:
            server_groups_for_server = self.__get_server_groups_for_server(
                server_name, sg_targeting_limits)
            if server_groups_for_server is not None:
                result[server_name] = server_groups_for_server
            elif server_name != admin_server_name:
                # By default, we only target managed servers unless explicitly listed in the targeting limits
                result[server_name] = list(server_groups)
            else:
                result[admin_server_name] = list()
        if admin_server_name not in result:
            result[admin_server_name] = list()
        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name,
                            result=result)
        return result

    def __get_server_groups_for_server(self, server_name, sg_targeting_limits):
        """
        Get the servers groups to target for a given server name.
        :param server_name: the server name
        :param sg_targeting_limits: the targeting limits
        :return: the list of server groups to target to the specified server name, or None
                 if the server name does not appear in the targeting limits
        """
        _method_name = '__get_server_groups_for_server'

        self.logger.entering(server_name,
                             str(sg_targeting_limits),
                             class_name=self.__class_name,
                             method_name=_method_name)
        result = None
        for server_group, server_names_list in sg_targeting_limits.iteritems():
            if server_name in server_names_list:
                if result is None:
                    result = list()
                result.append(server_group)
        self.logger.exiting(class_name=self.__class_name,
                            method_name=_method_name,
                            result=result)
        return result