示例#1
0
class MBeanInfoAttributes(MBeanAttributes):
    """
    MBeanInfoAttributes extends the MBeanAttributes class. It encapsulates the attribute information found from the
    PropertyDescriptors in the MBeanInfo for the MBean type.
    """

    __class_name = 'MBeanInfoAttributes'

    def __init__(self, model_context, alias_helper, exception_type, location):
        MBeanAttributes.__init__(self, model_context, alias_helper,
                                 exception_type, location)

        self.__weblogic_helper = WebLogicHelper(_logger)
        self.__mbean_info_descriptors = None
        self.__mbean_info_map = None

    def get_mbean_attributes(self):
        """
        Return the sorted list of attributes compiled from the MBeanInfo PropertyDescriptors including the
        child MBeans.
        :return: list of all attributes from the MBeanInfo property descriptors, or an empty list if none
        """
        _method_name = 'get_mbean_attributes'
        _logger.entering(class_name=self.__class__.__name__,
                         method_name=_method_name)
        map_to_list = list()
        attributes = self.__get_mbean_info_map()
        if len(attributes) > 0:
            map_to_list = [attribute for attribute in attributes.iterkeys()]
            map_to_list.sort()
        _logger.exiting(class_name=self.__class__.__name__,
                        method_name=_method_name,
                        result=len(map_to_list))
        return map_to_list

    def exists(self, attribute_name):
        """
        Determine if the attribute name exists for the MBean in MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is found in the MBeanInfo
        """
        return attribute_name in self.__get_mbean_info_map()

    def is_child_mbean(self, attribute_name):
        """
        Determine if the attribute exists in MBeanInfo and if the attribute is a child MBean.

        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is a child MBean or None if the attribute is not found in MBeanInfo
        """
        _method_name = 'is_child_mbean'
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            relationship = descriptor.getValue('relationship')
            is_child = relationship == 'containment' or \
                (relationship == 'reference' and self.is_read_only(attribute_name))
            if is_child:
                _logger.finer('WLSDPLY-01780',
                              attribute_name,
                              class_name=self.__class__.__name__,
                              method_name=_method_name)
            return is_child
        return None

    def is_read_only(self, attribute_name):
        """
        Determine if the attribute exists in MBeanInfo and if the attribute is readonly.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is readonly or None if the attribute does not exist in MBeanInfo
        """
        if self.exists(attribute_name):
            return self.setter(attribute_name) is None
        return None

    def getter(self, attribute_name):
        """
        Return the read method name string for the attribute in the MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: getter for the attribute or None if the attribute does not exist
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getReadMethod().getName()
        return None

    def is_valid_getter(self, attribute_name):
        """
        Try to invoke the getter method on the mbean_instance. Some of the attributes in the PropertyDescriptors
        have read methods that cannot be invoked on the MBean instance.
        :return: True if can invoke the getter on the MBean instance
        """
        _method_name = 'is_valid_getter'
        _logger.entering(attribute_name,
                         class_name=self.__class__.__name__,
                         method_name=_method_name)

        valid = False
        getter = self.getter(attribute_name)
        if getter is not None:
            valid, __ = self._get_from_bean_proxy(getter)
        _logger.exiting(class_name=self.__class__.__name__,
                        method_name=_method_name,
                        result=Boolean(valid))
        return valid

    def setter(self, attribute_name):
        """
        Return the set method name for the attribute in the MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: setter for the attribute or None if the attribute is readonly or the attribute does not exist
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            setter = descriptor.getWriteMethod()
            if setter is not None and str(setter.getReturnType()) == 'void':
                return setter.getName()
        return None

    def is_encrypted(self, attribute_name):
        """
        Determine if the property is an encrypted attribute.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if it is an encrypted attribute or None if the attribute does not exist in the MBeanInfo
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getValue('encrypted') is True
        return None

    def is_clear_text_encrypted(self, attribute_name):
        """
        The tool does not discover security attributes that are clear text. Determine if the attribute is a
        an attribute returning clear text form of the matching encrypted attribute and skip if True.
        :param attribute_name: name of the attribute to test
        :return: True if the attribute is a clear text security attribute
        """
        return self.is_encrypted(attribute_name) and str(
            self.get_type(attribute_name)) == 'java.lang.String'

    def get_type(self, attribute_name):
        """
        Return the type of the attribute value if the attribute exists in MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: Type of the property attribute or None if the attribute does not exist in the MBeanInfo
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getPropertyType()
        return None

    def get_default_value(self, attribute_name):
        """
        Return the default value if the attribute exists in MBeanInfo
        :param attribute_name: to search for in the MBeanInfo
        :return: The default value for the attribute
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        values = _get_descriptor_values_keys(descriptor)
        if 'defaultValueNull' in values and descriptor.getValue(
                'defaultValueNull') is True:
            default = None
        else:
            default = descriptor.getValue('default')
        return default

    def get_value(self, attribute_name):
        """
        Return the attribute value from the mbean instance.
        :param attribute_name: name of the attribute
        :return: Value of the MBean attribute in the format retrieved from the mbean instance
        """
        value = None
        getter = self.getter(attribute_name)
        if getter is not None:
            __, value = self._get_from_bean_proxy(getter)
        return value

    def __get_mbean_info_map(self):
        if self.__mbean_info_map is None:
            self.__mbean_info_map = dict()
            for descriptor in self.__get_mbean_descriptors():
                self.__mbean_info_map[descriptor.getName()] = descriptor

        return self.__mbean_info_map

    def __get_mbean_descriptors(self):
        _method_name = '__get_mbean_descriptors'
        if self.__mbean_info_descriptors is None:
            mbean_info = self.__weblogic_helper.get_bean_info_for_interface(
                self.get_mbean_interface_name())
            if mbean_info is None:
                ex = exception_helper.create_exception(
                    self._get_exception_type(), 'WLSDPLY-01774',
                    self.get_mbean_interface_name(), self.mbean_string())
                _logger.throwing(ex,
                                 class_name=self.__class__.__name__,
                                 method_name=_method_name)
                raise ex
            self.__mbean_info_descriptors = mbean_info.getPropertyDescriptors()
        return self.__mbean_info_descriptors

    def __get_mbean_attribute(self, attribute):
        descriptor_map = self.__get_mbean_info_map()
        if attribute in descriptor_map:
            return descriptor_map[attribute]
        return None

    def __str__(self):
        return self.__class__.__name__ + self._get_mbean_name()
class CustomFolderHelper(object):
    """
    Shared code for custom (user-defined) folders in the model.
    These require special handling, since they do not have alias definitions.
    """
    __class_name = 'CustomFolderHelper'
    __cipher_text_prefixes = ["{AES}", "{AES-256}"]

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

    def update_security_folder(self, location, model_type, model_subtype,
                               model_name, model_nodes):
        """
        Update the specified security model nodes in WLST.
        :param location: the location for the provider
        :param model_type: the type of the provider to be updated, such as AuthenticationProvider
        :param model_subtype: the subtype of the provider to be updated, such as 'custom.my.CustomIdentityAsserter'
        :param model_name: the name of the provider to be updated, such as 'My custom IdentityAsserter'
        :param model_nodes: a child model nodes of the provider to be updated
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = 'update_security_folder'

        location_path = self.alias_helper.get_model_folder_path(location)
        self.logger.entering(location_path,
                             model_subtype,
                             model_name,
                             class_name=self.__class_name,
                             method_name=_method_name)

        self.logger.info('WLSDPLY-12124',
                         model_type,
                         model_name,
                         model_subtype,
                         location_path,
                         class_name=self.__class_name,
                         method_name=_method_name)

        create_path = self.alias_helper.get_wlst_subfolders_path(location)
        self.wlst_helper.cd(create_path)

        # create the MBean using the model type, name, and subtype

        type_location = LocationContext(location).append_location(model_type)
        token = self.alias_helper.get_name_token(type_location)
        type_location.add_name_token(token, model_name)

        mbean_type = self.alias_helper.get_wlst_mbean_type(type_location)
        self.wlst_helper.create(model_name, model_subtype, mbean_type)

        provider_path = self.alias_helper.get_wlst_attributes_path(
            type_location)
        provider_mbean = self.wlst_helper.cd(provider_path)

        interface_name = model_subtype + 'MBean'
        bean_info = self.weblogic_helper.get_bean_info_for_interface(
            interface_name)
        if bean_info is None:
            ex = exception_helper.create_exception(self.exception_type,
                                                   'WLSDPLY-12125',
                                                   interface_name)
            self.logger.throwing(ex,
                                 class_name=self.__class_name,
                                 method_name=_method_name)
            raise ex

        property_map = dict()
        for property_descriptor in bean_info.getPropertyDescriptors():
            self.logger.finer('WLSDPLY-12126',
                              str(property_descriptor),
                              class_name=self.__class_name,
                              method_name=_method_name)
            property_map[property_descriptor.getName()] = property_descriptor

        for model_key in model_nodes:
            model_value = model_nodes[model_key]
            property_descriptor = property_map.get(model_key)

            if not property_descriptor:
                ex = exception_helper.create_exception(self.exception_type,
                                                       'WLSDPLY-12128',
                                                       model_key)
                self.logger.throwing(ex,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                raise ex

            # find the setter method for the attribute

            method = property_descriptor.writeMethod
            if not method:
                # this must be a read-only attribute, just log it and continue with next attribute
                self.logger.info('WLSDPLY-12129',
                                 str(model_key),
                                 class_name=self.__class_name,
                                 method_name=_method_name)
                continue

            self.logger.finer('WLSDPLY-12127',
                              str(model_key),
                              str(model_value),
                              class_name=self.__class_name,
                              method_name=_method_name)

            # determine the data type from the set method

            parameter_types = method.getParameterTypes()
            parameter_count = len(parameter_types)

            if parameter_count != 1:
                ex = exception_helper.create_exception(self.exception_type,
                                                       'WLSDPLY-12130',
                                                       model_key,
                                                       parameter_count)
                self.logger.throwing(ex,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                raise ex

            # if the property requires encryption, and the value is not encrypted,
            # encrypt the value with domain encryption.

            requires_encrypted = property_descriptor.getValue('encrypted')
            if requires_encrypted and not self.is_encrypted(
                    model_value) and isinstance(model_value, str):
                model_value = self.weblogic_helper.encrypt(
                    model_value, self.model_context.get_domain_home())

            property_type = parameter_types[0]

            # convert the model value to the target type and call the setter with the target value.
            # these are done together in Java to avoid automatic Jython type conversions.

            try:
                CustomBeanUtils.callMethod(provider_mbean, method,
                                           property_type, model_value)

            # failure converting value or calling method
            except (IllegalAccessException, IllegalArgumentException,
                    InvocationTargetException), ex:
                ex = exception_helper.create_exception(
                    self.exception_type,
                    'WLSDPLY-12131',
                    method,
                    str(model_value),
                    ex.getLocalizedMessage(),
                    error=ex)
                self.logger.throwing(ex,
                                     class_name=self.__class_name,
                                     method_name=_method_name)
                raise ex