Esempio n. 1
0
 def _verify_configuration(self):
     allowed_driver_methods = [m for m in dir(self) if m[0] != '_']
     allowed_driver_methods.extend([
         "_setup_server",
         "_teardown_server",
         "_get_pools_info",
         "_update_share_stats",
     ])
     disallowed_driver_methods = (
         "get_admin_network_allocations_number",
         "get_network_allocations_number",
         "get_share_server_pools",
     )
     for k, v in self.configuration.safe_get(
             "dummy_driver_driver_methods_delays").items():
         if k not in allowed_driver_methods:
             raise exception.BadConfigurationException(
                 reason=("Dummy driver does not have '%s' method." % k))
         elif k in disallowed_driver_methods:
             raise exception.BadConfigurationException(
                 reason=("Method '%s' does not support delaying." % k))
         try:
             float(v)
         except (TypeError, ValueError):
             raise exception.BadConfigurationException(reason=(
                 "Wrong value (%(v)s) for '%(k)s' dummy driver method time "
                 "delay is set in 'dummy_driver_driver_methods_delays' "
                 "config option." % {
                     "k": k,
                     "v": v
                 }))
Esempio n. 2
0
    def __init__(self, *args, **kwargs):
        """Do initialization."""
        LOG.debug('Initializing Nexenta driver.')
        super(NexentaNasDriver, self).__init__((True, False), *args, **kwargs)
        self.configuration = kwargs.get('configuration')
        if self.configuration:
            self.configuration.append_config_values(
                options.nexenta_connection_opts)
            self.configuration.append_config_values(options.nexenta_nfs_opts)
            self.configuration.append_config_values(
                options.nexenta_dataset_opts)
        else:
            raise exception.BadConfigurationException(
                reason=_('Nexenta configuration missing.'))
        required_params = ['nas_host', 'user', 'password', 'pool', 'folder']
        for param in required_params:
            if not getattr(self.configuration, 'nexenta_%s' % param):
                msg = 'Required parameter nexenta_%s is not provided.' % param
                raise exception.NexentaException(msg)

        self.nef = None
        self.verify_ssl = self.configuration.nexenta_ssl_cert_verify
        self.nef_host = self.configuration.nexenta_rest_address
        self.nas_host = self.configuration.nexenta_nas_host
        self.nef_port = self.configuration.nexenta_rest_port
        self.nef_user = self.configuration.nexenta_user
        self.nef_password = self.configuration.nexenta_password

        self.pool_name = self.configuration.nexenta_pool
        self.parent_fs = self.configuration.nexenta_folder

        self.nfs_mount_point_base = self.configuration.nexenta_mount_point_base
        self.dataset_compression = (
            self.configuration.nexenta_dataset_compression)
        self.provisioned_capacity = 0
Esempio n. 3
0
def get_backend_configuration(backend_name):
    config_stanzas = CONF.list_all_sections()
    if backend_name not in config_stanzas:
        msg = _("Could not find backend stanza %(backend_name)s in "
                "configuration which is required for replication or migration "
                "workflows with the source backend. Available stanzas are "
                "%(stanzas)s")
        params = {
            "stanzas": config_stanzas,
            "backend_name": backend_name,
        }
        raise exception.BadConfigurationException(reason=msg % params)

    config = configuration.Configuration(driver.share_opts,
                                         config_group=backend_name)
    if config.driver_handles_share_servers:
        # NOTE(dviroel): avoid using a pre-create vserver on DHSS == True mode
        # when retrieving remote backend configuration.
        config.netapp_vserver = None
    config.append_config_values(na_opts.netapp_cluster_opts)
    config.append_config_values(na_opts.netapp_connection_opts)
    config.append_config_values(na_opts.netapp_basicauth_opts)
    config.append_config_values(na_opts.netapp_transport_opts)
    config.append_config_values(na_opts.netapp_support_opts)
    config.append_config_values(na_opts.netapp_provisioning_opts)
    config.append_config_values(na_opts.netapp_data_motion_opts)

    return config
Esempio n. 4
0
    def _get_managed_ports(self, port_conf, sp):
        # Get the real ports from the backend storage
        real_ports = set([port.id for port in self.client.get_ip_ports(sp)])

        if not port_conf:
            LOG.debug("No ports are specified, so all ports in storage "
                      "system will be managed.")
            return real_ports

        matched_ports, unmanaged_ports = unity_utils.do_match(
            real_ports, port_conf)

        if not matched_ports:
            msg = (_("All the specified storage ports to be managed "
                     "do not exist. Please check your configuration "
                     "emc_interface_ports in manila.conf. "
                     "The available ports in the backend are %s") %
                   ",".join(real_ports))
            raise exception.BadConfigurationException(reason=msg)

        if unmanaged_ports:
            LOG.info(
                _LI("The following specified ports "
                    "are not managed by the backend: "
                    "%(un_managed)s. This host will only manage "
                    "the storage ports: %(exist)s"), {
                        'un_managed': ",".join(unmanaged_ports),
                        'exist': ",".join(matched_ports)
                    })
        else:
            LOG.debug("Ports: %s will be managed.", ",".join(matched_ports))

        return matched_ports
Esempio n. 5
0
    def _get_managed_pools(self, pool_conf):
        # Get the real pools from the backend storage
        real_pools = set(pool.name for pool in self.client.get_pool())

        if not pool_conf:
            LOG.debug("No storage pool is specified, so all pools in storage "
                      "system will be managed.")
            return real_pools

        matched_pools, unmanaged_pools = unity_utils.do_match(
            real_pools, pool_conf)

        if not matched_pools:
            msg = (_("All the specified storage pools to be managed "
                     "do not exist. Please check your configuration "
                     "emc_nas_pool_names in manila.conf. "
                     "The available pools in the backend are %s") %
                   ",".join(real_pools))
            raise exception.BadConfigurationException(reason=msg)

        if unmanaged_pools:
            LOG.info(
                "The following specified storage pools "
                "are not managed by the backend: "
                "%(un_managed)s. This host will only manage "
                "the storage pools: %(exist)s", {
                    'un_managed': ",".join(unmanaged_pools),
                    'exist': ",".join(matched_pools)
                })
        else:
            LOG.debug("Storage pools: %s will be managed.",
                      ",".join(matched_pools))

        return matched_pools
Esempio n. 6
0
    def connect(self, emc_share_driver, context):
        """Connect to Unity storage."""
        config = emc_share_driver.configuration
        storage_ip = enas_utils.convert_ipv6_format_if_needed(
            config.emc_nas_server)
        username = config.emc_nas_login
        password = config.emc_nas_password
        self.client = client.UnityClient(storage_ip, username, password)

        pool_conf = config.safe_get('unity_share_data_pools')
        self.pool_set = self._get_managed_pools(pool_conf)

        self.reserved_percentage = config.safe_get('reserved_share_percentage')
        if self.reserved_percentage is None:
            self.reserved_percentage = 0

        self.max_over_subscription_ratio = config.safe_get(
            'max_over_subscription_ratio')
        self.port_ids_conf = config.safe_get('unity_ethernet_ports')
        self.unity_share_server = config.safe_get('unity_share_server')
        self.driver_handles_share_servers = config.safe_get(
            'driver_handles_share_servers')
        if (not self.driver_handles_share_servers) and (
                not self.unity_share_server):
            msg = ("Make sure there is NAS server name "
                   "configured for share creation when driver "
                   "is in DHSS=False mode.")
            raise exception.BadConfigurationException(reason=msg)
        self.validate_port_configuration(self.port_ids_conf)
        pool_name = config.unity_server_meta_pool
        self._config_pool(pool_name)
Esempio n. 7
0
    def validate_port_configuration(self, port_ids_conf):
        """Initializes the SP and ports based on the port option."""

        ports = self.client.get_file_ports()

        sp_ports_map, unmanaged_port_ids = unity_utils.match_ports(
            ports, port_ids_conf)

        if not sp_ports_map:
            msg = (_("All the specified storage ports to be managed "
                     "do not exist. Please check your configuration "
                     "unity_ethernet_ports in manila.conf. "
                     "The available ports in the backend are %s.") %
                   ",".join([port.get_id() for port in ports]))
            raise exception.BadConfigurationException(reason=msg)

        if unmanaged_port_ids:
            LOG.info(
                "The following specified ports are not managed by "
                "the backend: %(unmanaged)s. This host will only "
                "manage the storage ports: %(exist)s", {
                    'unmanaged': ",".join(unmanaged_port_ids),
                    'exist': ",".join(map(",".join, sp_ports_map.values()))
                })
        else:
            LOG.debug("Ports: %s will be managed.",
                      ",".join(map(",".join, sp_ports_map.values())))

        if len(sp_ports_map) == 1:
            LOG.info(
                "Only ports of %s are configured. Configure ports "
                "of both SPA and SPB to use both of the SPs.",
                list(sp_ports_map)[0])

        return sp_ports_map
Esempio n. 8
0
    def __init__(self, *args, **kwargs):
        """Do initialization."""
        LOG.debug('Initializing Nexenta driver.')
        super(NexentaNasDriver, self).__init__(False, *args, **kwargs)
        self.configuration = kwargs.get('configuration')
        if self.configuration:
            self.configuration.append_config_values(
                options.nexenta_connection_opts)
            self.configuration.append_config_values(
                options.nexenta_nfs_opts)
            self.configuration.append_config_values(
                options.nexenta_dataset_opts)
        else:
            raise exception.BadConfigurationException(
                reason=_('Nexenta configuration missing.'))

        self.nef = None
        self.nef_protocol = self.configuration.nexenta_rest_protocol
        self.nef_host = self.configuration.nexenta_host
        self.nef_port = self.configuration.nexenta_rest_port
        self.nef_user = self.configuration.nexenta_user
        self.nef_password = self.configuration.nexenta_password

        self.pool_name = self.configuration.nexenta_pool
        self.fs_prefix = self.configuration.nexenta_nfs_share

        self.storage_protocol = 'NFS'
        self.nfs_mount_point_base = self.configuration.nexenta_mount_point_base
        self.dataset_compression = (
            self.configuration.nexenta_dataset_compression)
        self.provisioned_capacity = 0
    def _nas_product(self, xml_root):
        text = xml_root.findtext('Storage/Product')
        if not text:
            msg = _("Storage product is not configured.")
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        if text not in constants.VALID_PRODUCTS:
            msg = _("Invalid storage product %(text)s, must be "
                    "in %(valid)s."
                    ) % {'text': text,
                         'valid': constants.VALID_PRODUCTS}
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        setattr(self.config, 'nas_product', text)
Esempio n. 10
0
 def _config_pool(self, pool_name):
     try:
         self.nas_server_pool = self.client.get_pool(pool_name)
     except storops_ex.UnityResourceNotFoundError:
         message = (_("The storage pools %s to store NAS server "
                      "configuration do not exist.") % pool_name)
         LOG.exception(message)
         raise exception.BadConfigurationException(reason=message)
Esempio n. 11
0
    def _nas_user(self, xml_root):
        text = xml_root.findtext('Storage/UserName')
        if not text:
            msg = _("UserName is not configured.")
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        setattr(self.config, 'nas_user', text.strip())
Esempio n. 12
0
 def _safe_get_from_config_or_fail(self, config_parameter):
     config_value = self.configuration.safe_get(config_parameter)
     if not config_value:    # None or empty string
         reason = (_("%(config_parameter)s configuration parameter "
                     "must be specified") %
                   {'config_parameter': config_parameter})
         LOG.error(reason)
         raise exception.BadConfigurationException(reason=reason)
     return config_value
Esempio n. 13
0
 def _config_sp(self, sp_name):
     self.storage_processor = self.client.get_storage_processor(
         sp_name.lower())
     if self.storage_processor is None:
         message = (_LE("The storage processor %s does not exist or "
                        "is unavailable. Please reconfigure it in "
                        "manila.conf.") % sp_name)
         LOG.error(message)
         raise exception.BadConfigurationException(reason=message)
Esempio n. 14
0
    def _nas_address(self, xml_root):
        text = xml_root.findtext('Storage/RestURL')
        if not text:
            msg = _("RestURL is not configured.")
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        addrs = set([x.strip() for x in text.split(';') if x.strip()])
        setattr(self.config, 'nas_address', list(addrs))
Esempio n. 15
0
    def _storage_pools(self, xml_root):
        text = xml_root.findtext('Filesystem/StoragePool')
        if not text:
            msg = _('StoragePool must be configured.')
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        pools = set()
        for pool in text.split(';'):
            if pool.strip():
                pools.add(pool.strip())

        if not pools:
            msg = _('No valid storage pool configured.')
            LOG.error(msg)
            raise exception.BadConfigurationException(reason=msg)

        setattr(self.config, 'storage_pools', list(pools))
Esempio n. 16
0
 def _safe_get_from_config_or_fail(self, config_parameter):
     config_value = self.configuration.safe_get(config_parameter)
     if not config_value:
         reason = _("%(config_parameter)s configuration parameter "
                    "must be specified") % {
                        "config_parameter": config_parameter
                    }
         LOG.exception(reason)
         raise exception.BadConfigurationException(reason=reason)
     return config_value
Esempio n. 17
0
    def _load_auth_plugin(self):
        if self.admin_auth:
            return self.admin_auth
        self.auth_plugin = ks_loading.load_auth_from_conf_options(
            CONF, self.group)

        if self.auth_plugin:
            return self.auth_plugin

        msg = _('Cannot load auth plugin for %s') % self.group
        raise exception.BadConfigurationException(reason=msg)
Esempio n. 18
0
    def get_share(self, name, share_proto):
        # Validate the share protocol
        proto = share_proto.upper()

        if proto == 'CIFS':
            return self.system.get_cifs_share(name=name)
        elif proto == 'NFS':
            return self.system.get_nfs_share(name=name)
        else:
            raise exception.BadConfigurationException(
                reason=_('Invalid NAS protocol supplied: %s.') % share_proto)
Esempio n. 19
0
    def _timeout(self, xml_root):
        timeout = constants.DEFAULT_TIMEOUT
        text = xml_root.findtext('Filesystem/Timeout')
        if text:
            timeout = int(text.strip())
            if timeout <= 0:
                msg = _("Invalid Timeout config %s, must be "
                        "a positive digit.") % text
                LOG.error(msg)
                raise exception.BadConfigurationException(reason=msg)

        setattr(self.config, 'timeout', timeout)
Esempio n. 20
0
    def _wait_interval(self, xml_root):
        interval = constants.DEFAULT_WAIT_INTERVAL
        text = xml_root.findtext('Filesystem/WaitInterval')
        if text:
            interval = int(text.strip())
            if interval <= 0:
                msg = _("Invalid WaitInterval config %s, "
                        "must be a positive digit.") % text
                LOG.error(msg)
                raise exception.BadConfigurationException(reason=msg)

        setattr(self.config, 'wait_interval', interval)
Esempio n. 21
0
 def __init__(self, *args, **kwargs):
     """Do initialization."""
     LOG.debug('Initializing Nexenta driver.')
     super(NexentaNasDriver, self).__init__(False, *args, **kwargs)
     self.configuration = kwargs.get('configuration')
     if self.configuration:
         self.configuration.append_config_values(
             options.nexenta_connection_opts)
         self.configuration.append_config_values(options.nexenta_nfs_opts)
         self.configuration.append_config_values(
             options.nexenta_dataset_opts)
         self.helper = nexenta_nfs_helper.NFSHelper(self.configuration)
     else:
         raise exception.BadConfigurationException(
             reason=_('Nexenta configuration missing.'))
Esempio n. 22
0
    def __init__(self, *args, **kwargs):
        super(CephFSDriver, self).__init__(False, *args, **kwargs)
        self.backend_name = self.configuration.safe_get(
            'share_backend_name') or 'CephFS'

        self._volume_client = None

        self.configuration.append_config_values(cephfs_opts)

        try:
            self._cephfs_volume_mode = int(
                self.configuration.cephfs_volume_mode, 8)
        except ValueError:
            msg = _("Invalid CephFS volume mode %s")
            raise exception.BadConfigurationException(
                msg % self.configuration.cephfs_volume_mode)
Esempio n. 23
0
def get_backend_configuration(backend_name):
    config_stanzas = CONF.list_all_sections()
    if backend_name not in config_stanzas:
        msg = _("Could not find backend stanza %(backend_name)s in "
                "configuration which is required for share replication and "
                "migration. Available stanzas are %(stanzas)s")
        params = {
            "stanzas": config_stanzas,
            "backend_name": backend_name,
        }
        raise exception.BadConfigurationException(reason=msg % params)

    config = configuration.Configuration(driver.share_opts,
                                         config_group=backend_name)
    config.append_config_values(dummy_opts)
    config.append_config_values(share_manager_opts)
    config.append_config_values(driver.ssh_opts)

    return config
Esempio n. 24
0
def setup_tracing(trace_flags_string, api_trace_pattern=API_TRACE_PATTERN):
    global TRACE_METHOD
    global TRACE_API
    global API_TRACE_PATTERN
    TRACE_METHOD = False
    TRACE_API = False
    API_TRACE_PATTERN = api_trace_pattern
    if trace_flags_string:
        flags = trace_flags_string.split(',')
        flags = [flag.strip() for flag in flags]
        for invalid_flag in list(set(flags) - set(VALID_TRACE_FLAGS)):
            LOG.warning('Invalid trace flag: %s', invalid_flag)
        try:
            re.compile(api_trace_pattern)
        except re.error:
            msg = _('Cannot parse the API trace pattern. %s is not a '
                    'valid python regular expression.') % api_trace_pattern
            raise exception.BadConfigurationException(reason=msg)
        TRACE_METHOD = 'method' in flags
        TRACE_API = 'api' in flags
Esempio n. 25
0
    def get_managed_ports(self):
        # Get the real ports(devices) list from the backend storage
        real_ports = self._get_physical_devices(self.mover_name)

        if not self.port_conf:
            LOG.debug("No ports are specified, so any of the ports on the "
                      "Data Mover can be used.")
            return real_ports

        matched_ports, unmanaged_ports = vnx_utils.do_match_any(
            real_ports, self.port_conf)

        if not matched_ports:
            msg = (_("None of the specified network ports exist. "
                     "Please check your configuration vnx_ethernet_ports "
                     "in manila.conf. The available ports on the Data Mover "
                     "are %s.") % ",".join(real_ports))
            raise exception.BadConfigurationException(reason=msg)

        LOG.debug("Ports: %s can be used.", ",".join(matched_ports))

        return list(matched_ports)
Esempio n. 26
0
    def __init__(self, *args, **kwargs):
        super(CephFSDriver, self).__init__(False, *args, **kwargs)
        self.backend_name = self.configuration.safe_get(
            'share_backend_name') or 'CephFS'

        setup_rados()
        setup_json_command()
        self._rados_client = None
        # name of the filesystem/volume used by the driver
        self._volname = None
        self._ceph_mon_version = None
        self.configuration.append_config_values(cephfs_opts)

        try:
            int(self.configuration.cephfs_volume_mode, 8)
        except ValueError:
            msg = _("Invalid CephFS volume mode %s")
            raise exception.BadConfigurationException(
                msg % self.configuration.cephfs_volume_mode)

        self._cephfs_volume_mode = self.configuration.cephfs_volume_mode
        self.ipv6_implemented = True
Esempio n. 27
0
def get_backend_configuration(backend_name):
    config_stanzas = CONF.list_all_sections()
    if backend_name not in config_stanzas:
        msg = _("Could not find backend stanza %(backend_name)s in "
                "configuration which is required for replication with "
                "the backend. Available stanzas are %(stanzas)s")
        params = {
            "stanzas": config_stanzas,
            "backend_name": backend_name,
        }
        raise exception.BadConfigurationException(reason=msg % params)

    config = configuration.Configuration(driver.share_opts,
                                         config_group=backend_name)
    config.append_config_values(na_opts.netapp_cluster_opts)
    config.append_config_values(na_opts.netapp_connection_opts)
    config.append_config_values(na_opts.netapp_basicauth_opts)
    config.append_config_values(na_opts.netapp_transport_opts)
    config.append_config_values(na_opts.netapp_support_opts)
    config.append_config_values(na_opts.netapp_provisioning_opts)
    config.append_config_values(na_opts.netapp_replication_opts)

    return config
Esempio n. 28
0
    def manage_existing(self, share, driver_options, share_server=None):
        """Manages a share that exists on backend.

        :param share: Share that will be managed.
        :param driver_options: Driver-specific options provided by admin.
        :param share_server: Share server name provided by admin in DHSS=True.
        :returns: Returns a dict with share size and export location.
        """
        export_locations = share['export_locations']
        if not export_locations:
            message = ("Failed to manage existing share: %s, missing "
                       "export locations." % share['id'])
            raise exception.ManageInvalidShare(reason=message)

        try:
            share_size = int(driver_options.get("size", 0))
        except (ValueError, TypeError):
            msg = _("The driver options' size to manage the share "
                    "%(share_id)s, should be an integer, in format "
                    "driver-options size=<SIZE>. Value specified: "
                    "%(size)s.") % {
                        'share_id': share['id'],
                        'size': driver_options.get("size")
                    }
            raise exception.ManageInvalidShare(reason=msg)

        if not share_size:
            msg = _("Share %(share_id)s has no specified size. "
                    "Using default value 1, set size in driver options if you "
                    "want.") % {
                        'share_id': share['id']
                    }
            LOG.warning(msg)
            share_size = 1

        share_id = unity_utils.get_share_backend_id(share)
        backend_share = self.client.get_share(share_id, share['share_proto'])
        if not backend_share:
            message = ("Could not find the share in backend, please make sure "
                       "the export location is right.")
            raise exception.ManageInvalidShare(reason=message)

        # Check the share server when in DHSS=true mode
        if share_server:
            backend_share_server = self._get_server_name(share_server)
            if not backend_share_server:
                message = ("Could not find the backend share server: %s, "
                           "please make sure that share server with the "
                           "specified name exists in the backend.",
                           share_server)
                raise exception.BadConfigurationException(message)
        LOG.info(
            "Share %(shr_path)s is being managed with ID "
            "%(shr_id)s.", {
                'shr_path': share['export_locations'][0]['path'],
                'shr_id': share['id']
            })
        # export_locations was not changed, return original value
        return {
            "size": share_size,
            'export_locations': {
                'path': share['export_locations'][0]['path']
            }
        }