Example #1
0
 def wrap(self, *args, **kwargs):
     server = kwargs.get('share_server')
     if not server:
         # For now cmode driver does not support flat networking.
         raise exception.NetAppException(_('Share sever is not provided.'))
     vserver_name = server['backend_details'].get('vserver_name') if \
         server.get('backend_details') else None
     if not vserver_name:
         raise exception.NetAppException(
             _('Vserver name missing in '
               'backend details.'))
     if not self._vserver_exists(vserver_name):
         raise exception.VserverUnavailable(vserver=vserver_name)
     return f(self, *args, **kwargs)
Example #2
0
 def wrap(self, *args, **kwargs):
     server = kwargs.get('share_server')
     if not server:
         # For now cmode driver does not support flat networking.
         raise exception.NetAppException(_('Share server is not provided.'))
     vserver_name = server['backend_details'].get('vserver_name') if \
         server.get('backend_details') else None
     if not vserver_name:
         msg = _('Vserver name is absent in backend details. Please '
                 'check whether vserver was created properly or not.')
         raise exception.NetAppException(msg)
     if not self._vserver_exists(vserver_name):
         raise exception.VserverUnavailable(vserver=vserver_name)
     return f(self, *args, **kwargs)
Example #3
0
    def create_share(self, share, share_name,
                     clear_current_export_policy=True,
                     ensure_share_already_exists=False, replica=False,
                     is_flexgroup=False):
        """Creates CIFS share if does not exist on Data ONTAP Vserver.

        The new CIFS share has Everyone access, so it removes all access after
        creating.

        :param share: share entity.
        :param share_name: share name that must be the CIFS share name.
        :param clear_current_export_policy: ignored, NFS only.
        :param ensure_share_already_exists: ensures that CIFS share exists.
        :param replica: it is a replica volume (DP type).
        :param is_flexgroup: whether the share is a FlexGroup or not.
        """

        cifs_exist = self._client.cifs_share_exists(share_name)
        if ensure_share_already_exists and not cifs_exist:
            msg = _("The expected CIFS share %(share_name)s was not found.")
            msg_args = {'share_name': share_name}
            raise exception.NetAppException(msg % msg_args)
        elif not cifs_exist:
            self._client.create_cifs_share(share_name)
            self._client.remove_cifs_share_access(share_name, 'Everyone')

        # Ensure 'ntfs' security style for RW volume. DP volumes cannot set it.
        if not replica:
            self._client.set_volume_security_style(share_name,
                                                   security_style='ntfs')

        # Return a callback that may be used for generating export paths
        # for this share.
        return (lambda export_address, share_name=share_name:
                r'\\%s\%s' % (export_address, share_name))
Example #4
0
    def wait_for_snapmirror_release_svm(self, source_vserver, dest_vserver,
                                        src_client, timeout=300):
        interval = 10
        retries = (timeout / interval or 1)

        @utils.retry(exception.NetAppException, interval=interval,
                     retries=retries, backoff_rate=1)
        def release_snapmirror():
            snapmirrors = src_client.get_snapmirror_destinations_svm(
                source_vserver=source_vserver, dest_vserver=dest_vserver)
            if not snapmirrors:
                LOG.debug("No snapmirrors to be released in source location.")
            else:
                try:
                    src_client.release_snapmirror_svm(source_vserver,
                                                      dest_vserver)
                except netapp_api.NaApiError as e:
                    if (e.code == netapp_api.EOBJECTNOTFOUND or
                            e.code == netapp_api.ESOURCE_IS_DIFFERENT or
                            "(entry doesn't exist)" in e.message):
                        LOG.debug('Snapmirror relationship does not exists '
                                  'anymore.')

                msg = _('Snapmirror release sent to source vserver. We will '
                        'wait for it to be released.')
                raise exception.NetAppException(vserver=msg)

        try:
            release_snapmirror()
        except exception.NetAppException:
            msg = _("Unable to release the snapmirror from source vserver %s. "
                    "Retries exhausted. Aborting") % source_vserver
            raise exception.NetAppException(message=msg)
    def _create_vserver_if_nonexistent(self, vserver_name, network_info):
        """Creates Vserver with given parameters if it doesn't exist."""

        if self._client.vserver_exists(vserver_name):
            msg = _('Vserver %s already exists.')
            raise exception.NetAppException(msg % vserver_name)

        LOG.debug('Vserver %s does not exist, creating.', vserver_name)
        self._client.create_vserver(
            vserver_name,
            self.configuration.netapp_root_volume_aggregate,
            self.configuration.netapp_root_volume,
            self._find_matching_aggregates())

        vserver_client = self._get_api_client(vserver=vserver_name)
        try:
            self._create_vserver_lifs(vserver_name,
                                      vserver_client,
                                      network_info)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Failed to create network interface(s)."))
                self._client.delete_vserver(vserver_name, vserver_client)

        vserver_client.enable_nfs()

        security_services = network_info.get('security_services')
        if security_services:
            self._client.setup_security_services(security_services,
                                                 vserver_client,
                                                 vserver_name)
Example #6
0
    def get_vserver_root_volume_name(self, vserver_name):
        """Get the root volume name of the vserver."""
        api_args = {
            'query': {
                'vserver-info': {
                    'vserver-name': vserver_name,
                },
            },
            'desired-attributes': {
                'vserver-info': {
                    'root-volume': None,
                },
            },
        }
        vserver_info = self.send_request('vserver-get-iter', api_args)

        try:
            root_volume_name = vserver_info.get_child_by_name(
                'attributes-list').get_child_by_name(
                    'vserver-info').get_child_content('root-volume')
        except AttributeError:
            msg = _('Could not determine root volume name '
                    'for Vserver %s.') % vserver_name
            raise exception.NetAppException(msg)
        return root_volume_name
Example #7
0
    def setup_security_services(self, security_services, vserver_client,
                                vserver_name):
        api_args = {
            'name-mapping-switch': {
                'nmswitch': 'ldap,file',
            },
            'name-server-switch': {
                'nsswitch': 'ldap,file',
            },
            'vserver-name': vserver_name,
        }
        self.send_request('vserver-modify', api_args)

        for security_service in security_services:
            if security_service['type'].lower() == 'ldap':
                vserver_client.configure_ldap(security_service)

            elif security_service['type'].lower() == 'active_directory':
                vserver_client.configure_active_directory(
                    security_service, vserver_name)

            elif security_service['type'].lower() == 'kerberos':
                self.create_kerberos_realm(security_service)
                vserver_client.configure_kerberos(security_service,
                                                  vserver_name)

            else:
                msg = _('Unsupported security service type %s for '
                        'Data ONTAP driver')
                raise exception.NetAppException(msg % security_service['type'])
Example #8
0
    def get_nfs_export_policy_for_volume(self, volume_name):
        """Get the name of the export policy for a volume."""

        api_args = {
            'query': {
                'volume-attributes': {
                    'volume-id-attributes': {
                        'name': volume_name,
                    },
                },
            },
            'desired-attributes': {
                'volume-attributes': {
                    'volume-export-attributes': {
                        'policy': None,
                    },
                },
            },
        }
        result = self.send_request('volume-get-iter', api_args)

        attributes_list = result.get_child_by_name(
            'attributes-list') or netapp_api.NaElement('none')
        volume_attributes = attributes_list.get_child_by_name(
            'volume-attributes') or netapp_api.NaElement('none')
        volume_export_attributes = volume_attributes.get_child_by_name(
            'volume-export-attributes') or netapp_api.NaElement('none')

        export_policy = volume_export_attributes.get_child_content('policy')

        if not export_policy:
            msg = _('Could not find export policy for volume %s.')
            raise exception.NetAppException(msg % volume_name)

        return export_policy
Example #9
0
    def wait_for_vserver_state(self,
                               vserver_name,
                               client,
                               state=None,
                               operational_state=None,
                               subtype=None,
                               timeout=300):
        interval = 10
        retries = (timeout / interval or 1)

        expected = {}
        if state:
            expected['state'] = state
        if operational_state:
            expected['operational_state'] = operational_state
        if subtype:
            expected['subtype'] = subtype

        @utils.retry(exception.VserverNotReady,
                     interval=interval,
                     retries=retries,
                     backoff_rate=1)
        def wait_for_state():
            vserver_info = client.get_vserver_info(vserver_name)
            if not all(item in vserver_info.items()
                       for item in expected.items()):
                raise exception.VserverNotReady(vserver=vserver_name)

        try:
            wait_for_state()
        except exception.VserverNotReady:
            msg = _("Vserver %s did not reach the expected state. Retries "
                    "exhausted. Aborting.") % vserver_name
            raise exception.NetAppException(message=msg)
Example #10
0
    def convert_svm_to_default_subtype(self,
                                       vserver_name,
                                       client,
                                       is_dest_path=True,
                                       timeout=300):
        interval = 10
        retries = (timeout / interval or 1)

        @utils.retry(exception.VserverNotReady,
                     interval=interval,
                     retries=retries,
                     backoff_rate=1)
        def wait_for_state():
            vserver_info = client.get_vserver_info(vserver_name)
            if vserver_info.get('subtype') != 'default':
                if is_dest_path:
                    client.break_snapmirror_svm(dest_vserver=vserver_name)
                else:
                    client.break_snapmirror_svm(source_vserver=vserver_name)
                raise exception.VserverNotReady(vserver=vserver_name)

        try:
            wait_for_state()
        except exception.VserverNotReady:
            msg = _("Vserver %s did not reach the expected state. Retries "
                    "exhausted. Aborting.") % vserver_name
            raise exception.NetAppException(message=msg)
Example #11
0
        def release_snapmirror():
            snapmirrors = src_client.get_snapmirror_destinations(
                source_vserver=src_vserver,
                dest_vserver=dest_vserver,
                source_volume=src_volume_name,
                dest_volume=dest_volume_name)
            if not snapmirrors:
                LOG.debug("No snapmirrors to be released in source volume.")
            else:
                try:
                    src_client.release_snapmirror_vol(
                        src_vserver,
                        src_volume_name,
                        dest_vserver,
                        dest_volume_name,
                        relationship_info_only=relationship_info_only)
                except netapp_api.NaApiError as e:
                    if (e.code == netapp_api.EOBJECTNOTFOUND
                            or e.code == netapp_api.ESOURCE_IS_DIFFERENT
                            or "(entry doesn't exist)" in e.message):
                        LOG.debug('Snapmirror relationship does not exist '
                                  'anymore.')

                msg = _('Snapmirror release sent to source volume. Waiting '
                        'until it has been released.')
                raise exception.NetAppException(vserver=msg)
Example #12
0
 def _setup_security_services(self, security_services, vserver_client,
                              vserver_name):
     modify_args = {
         'name-mapping-switch': {
             'nmswitch': 'ldap,file'
         },
         'name-server-switch': {
             'nsswitch': 'ldap,file'
         },
         'vserver-name': vserver_name
     }
     self._client.send_request('vserver-modify', modify_args)
     for security_service in security_services:
         if security_service['type'].lower() == "ldap":
             self._configure_ldap(security_service, vserver_client)
         elif security_service['type'].lower() == "active_directory":
             self._configure_active_directory(security_service,
                                              vserver_client, vserver_name)
         elif security_service['type'].lower() == "kerberos":
             self._configure_kerberos(vserver_name, security_service,
                                      vserver_client)
         else:
             raise exception.NetAppException(
                 _('Unsupported protocol %s for NetApp driver') %
                 security_service['type'])
Example #13
0
    def _get_helper(self, share):
        """Returns driver which implements share protocol."""
        share_proto = share['share_proto']
        if share_proto.lower() not in self._licenses:
            current_licenses = self._check_licenses()
            if share_proto not in current_licenses:
                msg = _("There is no license for %s at Ontap") % share_proto
                LOG.error(msg)
                raise exception.NetAppException(msg)

        for proto in self._helpers.keys():
            if share_proto.upper().startswith(proto):
                return self._helpers[proto]

        err_msg = _("Invalid NAS protocol supplied: %s. ") % share_proto

        raise exception.NetAppException(err_msg)
Example #14
0
 def _check_if_max_files_is_valid(self, share, value):
     """Check if max_files has a valid value."""
     if int(value) < 0:
         args = {'value': value, 'key': 'netapp:max_files',
                 'type_id': share['share_type_id'], 'share_id': share['id']}
         msg = _('Invalid value "%(value)s" for extra_spec "%(key)s" '
                 'in share_type %(type_id)s for share %(share_id)s.')
         raise exception.NetAppException(msg % args)
Example #15
0
 def _check_vfiler_exists(self):
     vfiler_status = self._client.send_request(
         'vfiler-get-status',
         {'vfiler': self.configuration.netapp_nas_vfiler})
     if vfiler_status.get_child_content('status') != 'running':
         msg = _("Vfiler %s is not running") \
               % self.configuration.netapp_nas_vfiler
         LOG.error(msg)
         raise exception.NetAppException(msg)
Example #16
0
    def allow_access(self, context, share, access):
        """Allows access to a given CIFS storage for IPs in access."""
        if access['access_type'] != 'sid':
            msg = _('NetApp only supports "sid" access type for CIFS.')
            raise exception.NetAppException(msg)

        user = access['access_to']
        target, share_name = self._get_export_location(share)

        self._allow_access_for(user, share_name)
Example #17
0
 def _check_data_ontap_version(self):
     # Temporary check to indicate that the Kilo multi-SVM driver does not
     # support cDOT 8.3 or higher.
     ontapi_version = self._client.get_ontapi_version()
     if ontapi_version >= (1, 30):
         msg = _('Clustered Data ONTAP 8.3.0 or higher is not '
                 'supported by this version of the driver when the '
                 'configuration option driver_handles_share_servers '
                 'is set to True.')
         raise exception.NetAppException(msg)
Example #18
0
 def _get_node_data_port(self, node):
     port_names = self._client.list_node_data_ports(node)
     pattern = self.configuration.netapp_port_name_search_pattern
     matched_port_names = [port_name for port_name in port_names
                           if re.match(pattern, port_name)]
     if not matched_port_names:
         raise exception.NetAppException(
             _('Could not find eligible network ports on node %s on which '
               'to create Vserver LIFs.') % node)
     return matched_port_names[0]
Example #19
0
    def _delete_vserver(self,
                        vserver_name,
                        vserver_client,
                        security_services=None):
        """
        Delete vserver.

        Checks if vserver exists and does not have active shares.
        Offlines and destroys root volumes.
        Deletes vserver.
        """
        if not self._vserver_exists(vserver_name):
            LOG.error(_("Vserver %s does not exists.") % vserver_name)
            return
        volumes_data = vserver_client.send_request('volume-get-iter')
        volumes_count = int(volumes_data.get_child_content('num-records'))
        if volumes_count == 1:
            try:
                vserver_client.send_request(
                    'volume-offline',
                    {'name': self.configuration.netapp_root_volume_name})
            except naapi.NaApiError as e:
                if e.code == '13042':
                    LOG.error(
                        _("Volume %s is already offline.") %
                        self.configuration.netapp_root_volume_name)
                else:
                    raise e
            vserver_client.send_request(
                'volume-destroy',
                {'name': self.configuration.netapp_root_volume_name})
        elif volumes_count > 1:
            msg = _("Error deleting vserver. "
                    "Vserver %s has shares.") % vserver_name
            LOG.error(msg)
            raise exception.NetAppException(msg)
        if security_services:
            for service in security_services:
                if service['type'] == 'active_directory':
                    args = {
                        'admin-password': service['password'],
                        'admin-username': service['sid']
                    }
                    try:
                        vserver_client.send_request('cifs-server-delete', args)
                    except naapi.NaApiError as e:
                        if e.code == "15661":
                            LOG.error(
                                _("Cifs server does not exists for"
                                  " vserver %s") % vserver_name)
                        else:
                            vserver_client.send_request('cifs-server-delete')
        self._client.send_request('vserver-destroy',
                                  {'vserver-name': vserver_name})
Example #20
0
    def _get_helper(self, share):
        """Returns driver which implements share protocol."""
        share_protocol = share['share_proto']
        self._check_license_for_protocol(share_protocol)

        for protocol in self._helpers.keys():
            if share_protocol.upper().startswith(protocol):
                return self._helpers[protocol]

        err_msg = _("Invalid NAS protocol supplied: %s. ") % share_protocol
        raise exception.NetAppException(err_msg)
Example #21
0
    def _create_vserver(self, vserver_name, network_info):
        """Creates Vserver with given parameters if it doesn't exist."""

        if self._client.vserver_exists(vserver_name):
            msg = _('Vserver %s already exists.')
            raise exception.NetAppException(msg % vserver_name)

        # NOTE(lseki): If there's already an ipspace created for the same VLAN
        # port, reuse it. It will be named after the previously created share
        # server's neutron subnet id.
        node_name = self._client.list_cluster_nodes()[0]
        port = self._get_node_data_port(node_name)
        vlan = network_info['segmentation_id']
        ipspace_name = self._client.get_ipspace_name_for_vlan_port(
            node_name, port, vlan) or self._create_ipspace(network_info)

        LOG.debug('Vserver %s does not exist, creating.', vserver_name)
        self._client.create_vserver(
            vserver_name,
            self.configuration.netapp_root_volume_aggregate,
            self.configuration.netapp_root_volume,
            self._find_matching_aggregates(),
            ipspace_name)

        vserver_client = self._get_api_client(vserver=vserver_name)
        security_services = None
        try:
            self._create_vserver_lifs(vserver_name,
                                      vserver_client,
                                      network_info,
                                      ipspace_name)

            self._create_vserver_admin_lif(vserver_name,
                                           vserver_client,
                                           network_info,
                                           ipspace_name)

            self._create_vserver_routes(vserver_client,
                                        network_info)

            vserver_client.enable_nfs(
                self.configuration.netapp_enabled_share_protocols)

            security_services = network_info.get('security_services')
            if security_services:
                self._client.setup_security_services(security_services,
                                                     vserver_client,
                                                     vserver_name)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error("Failed to configure Vserver.")
                self._delete_vserver(vserver_name,
                                     security_services=security_services)
Example #22
0
 def __init__(self, version, vserver=None, *args, **kwargs):
     self.configuration = kwargs.get('configuration', None)
     if not self.configuration:
         raise exception.NetAppException(_("NetApp configuration missing."))
     self._client = naapi.NaServer(
         host=self.configuration.netapp_nas_server_hostname,
         username=self.configuration.netapp_nas_login,
         password=self.configuration.netapp_nas_password,
         transport_type=self.configuration.netapp_nas_transport_type,
     )
     self._client.set_api_version(*version)
     if vserver:
         self._client.set_vserver(vserver)
Example #23
0
 def _create_net_iface(self, ip, netmask, vlan, node, port, vserver_name,
                       allocation_id):
     """Creates lif on vlan port."""
     vlan_iface_name = "%(port)s-%(tag)s" % {'port': port, 'tag': vlan}
     try:
         args = {
             'vlan-info': {
                 'parent-interface': port,
                 'node': node,
                 'vlanid': vlan
             }
         }
         self._client.send_request('net-vlan-create', args)
     except naapi.NaApiError as e:
         if e.code == '13130':
             LOG.debug("Vlan %(vlan)s already exists on port %(port)s" % {
                 'vlan': vlan,
                 'port': port
             })
         else:
             raise exception.NetAppException(
                 _("Failed to create vlan %(vlan)s on "
                   "port %(port)s. %(err_msg)") % {
                       'vlan': vlan,
                       'port': port,
                       'err_msg': e.message
                   })
     iface_name = (self.configuration.netapp_lif_name_template % {
         'node': node,
         'net_allocation_id': allocation_id
     })
     LOG.debug('Creating LIF %(lif)r for vserver %(vserver)s ' % {
         'lif': iface_name,
         'vserver': vserver_name
     })
     args = {
         'address': ip,
         'administrative-status': 'up',
         'data-protocols': [{
             'data-protocol': 'nfs'
         }, {
             'data-protocol': 'cifs'
         }],
         'home-node': node,
         'home-port': vlan_iface_name,
         'netmask': netmask,
         'interface-name': iface_name,
         'role': 'data',
         'vserver': vserver_name,
     }
     self._client.send_request('net-interface-create', args)
Example #24
0
    def _get_helper(self, share):
        """Returns driver which implements share protocol."""
        share_protocol = share['share_proto'].lower()

        if share_protocol not in self.SUPPORTED_PROTOCOLS:
            err_msg = _("Invalid NAS protocol supplied: %s.") % share_protocol
            raise exception.NetAppException(err_msg)

        self._check_license_for_protocol(share_protocol)

        if share_protocol == 'nfs':
            return nfs_cmode.NetAppCmodeNFSHelper()
        elif share_protocol == 'cifs':
            return cifs_cmode.NetAppCmodeCIFSHelper()
Example #25
0
    def get_vserver_aggregate_capacities(self, aggregate_names=None):
        """Calculates capacity of one or more aggregates for a vserver.

        Returns dictionary of aggregate capacity metrics.  This must
        be called against a Vserver LIF.
        """

        if aggregate_names is not None and len(aggregate_names) == 0:
            return {}

        api_args = {
            'desired-attributes': {
                'vserver-info': {
                    'vserver-name': None,
                    'vserver-aggr-info-list': {
                        'vserver-aggr-info': {
                            'aggr-name': None,
                            'aggr-availsize': None,
                        },
                    },
                },
            },
        }
        result = self.send_request('vserver-get', api_args)
        attributes = result.get_child_by_name('attributes')
        if not attributes:
            raise exception.NetAppException('Failed to read Vserver info')

        vserver_info = attributes.get_child_by_name('vserver-info')
        vserver_name = vserver_info.get_child_content('vserver-name')
        vserver_aggr_info_element = vserver_info.get_child_by_name(
            'vserver-aggr-info-list') or netapp_api.NaElement('none')
        vserver_aggr_info_list = vserver_aggr_info_element.get_children()

        if not vserver_aggr_info_list:
            LOG.warning(_LW('No aggregates assigned to Vserver %s.'),
                        vserver_name)

        # Return dict of key-value pair of aggr_name:aggr_size_available.
        aggr_space_dict = {}

        for aggr_info in vserver_aggr_info_list:
            aggr_name = aggr_info.get_child_content('aggr-name')

            if aggregate_names is None or aggr_name in aggregate_names:
                aggr_size = int(aggr_info.get_child_content('aggr-availsize'))
                aggr_space_dict[aggr_name] = {'available': aggr_size}

        LOG.debug('Found available Vserver aggregates: %s', aggr_space_dict)
        return aggr_space_dict
Example #26
0
    def test_delete_vserver_vlan_client_error(self):

        mock_exception_log = self.mock_object(lib_multi_svm.LOG, 'exception')
        self.mock_object(
            self.library._client, 'delete_vlan',
            mock.Mock(side_effect=exception.NetAppException("fake error")))

        self.library._delete_vserver_vlan(c_fake.NETWORK_INTERFACES)
        for interface in c_fake.NETWORK_INTERFACES:
            home_port = interface['home-port']
            port, vlan = home_port.split('-')
            node = interface['home-node']
            self.library._client.delete_vlan.assert_called_once_with(
                node, port, vlan)
            self.assertEqual(1, mock_exception_log.call_count)
Example #27
0
 def _create_export(self, share, vserver, vserver_client):
     """Creates NAS storage."""
     helper = self._get_helper(share)
     helper.set_client(vserver_client)
     share_name = self._get_valid_share_name(share['id'])
     args = {'query': {'net-interface-info': {'vserver': vserver}}}
     ifaces = vserver_client.send_request('net-interface-get-iter', args)
     if not int(ifaces.get_child_content('num-records')):
         raise exception.NetAppException(
             _("Cannot find network interfaces for vserver %s.") % vserver)
     ifaces_list = ifaces.get_child_by_name('attributes-list')\
         .get_children()
     ip_address = ifaces_list[0].get_child_content('address')
     export_location = helper.create_share(share_name, ip_address)
     return export_location
Example #28
0
    def _check_aggregate_extra_specs_validity(self, aggregate_name, specs):

        for specs_key in ('netapp_disk_type', 'netapp_raid_type'):
            aggr_value = self._ssc_stats.get(aggregate_name, {}).get(specs_key)
            specs_value = specs.get(specs_key)

            if aggr_value and specs_value and aggr_value != specs_value:
                msg = _('Invalid value "%(value)s" for extra_spec "%(key)s" '
                        'in aggregate %(aggr)s.')
                msg_args = {
                    'value': specs_value,
                    'key': specs_key,
                    'aggr': aggregate_name
                }
                raise exception.NetAppException(msg % msg_args)
Example #29
0
 def _find_match_aggregates(self):
     """Find all aggregates match pattern."""
     pattern = self.configuration.netapp_aggregate_name_search_pattern
     try:
         aggrs = self._client.send_request('aggr-get-iter')\
             .get_child_by_name('attributes-list').get_children()
     except AttributeError:
         msg = _("Have not found aggregates match pattern %s") % pattern
         LOG.error(msg)
         raise exception.NetAppException(msg)
     aggr_list = [
         aggr for aggr in aggrs
         if re.match(pattern, aggr.get_child_content('aggregate-name'))
     ]
     return aggr_list
Example #30
0
    def _check_license_for_protocol(self, share_protocol):
        """Validates protocol license if cluster APIs are accessible."""
        if not self._have_cluster_creds:
            return

        if share_protocol.lower() not in self._licenses:
            current_licenses = self._get_licenses()
            if share_protocol.lower() not in current_licenses:
                msg_args = {
                    'protocol': share_protocol,
                    'host': self.configuration.netapp_server_hostname
                }
                msg = _('The protocol %(protocol)s is not licensed on '
                        'controller %(host)s') % msg_args
                LOG.error(msg)
                raise exception.NetAppException(msg)