Пример #1
0
 def test_generate_password(self):
     password = volume_utils.generate_password()
     self.assertTrue(any(c for c in password if c in "23456789"))
     self.assertTrue(any(c for c in password if c in "abcdefghijkmnopqrstuvwxyz"))
     self.assertTrue(any(c for c in password if c in "ABCDEFGHJKLMNPQRSTUVWXYZ"))
     self.assertEqual(16, len(password))
     self.assertEqual(10, len(volume_utils.generate_password(10)))
Пример #2
0
 def test_generate_password(self):
     password = volume_utils.generate_password()
     self.assertTrue(any(c for c in password if c in '23456789'))
     self.assertTrue(
         any(c for c in password if c in 'abcdefghijkmnopqrstuvwxyz'))
     self.assertTrue(
         any(c for c in password if c in 'ABCDEFGHJKLMNPQRSTUVWXYZ'))
     self.assertEqual(16, len(password))
     self.assertEqual(10, len(volume_utils.generate_password(10)))
Пример #3
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        iscsi_target, lun = self._get_target_and_lun(context, volume)
        if self.target_name is None:
            iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                                   volume['name'])
        else:
            iscsi_name = self.target_name

        if self.chap_username and self.chap_password:
            chap_auth = (self.chap_username, self.chap_password)
        else:
            chap_auth = self._get_target_chap_auth(context, iscsi_name)
            if not chap_auth:
                chap_auth = (vutils.generate_username(),
                             vutils.generate_password())
        tid = self.create_iscsi_target(iscsi_name, volume['id'], iscsi_target,
                                       lun, volume_path, chap_auth)

        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', *chap_auth)
        return data
Пример #4
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        iscsi_target, lun = self._get_target_and_lun(context, volume)
        if self.target_name is None:
            iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                                   volume['name'])
        else:
            iscsi_name = self.target_name

        if self.chap_username and self.chap_password:
            chap_username = self.chap_username
            chap_password = self.chap_password
        else:
            chap_username = vutils.generate_username()
            chap_password = vutils.generate_password()

        chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
                                               chap_password)
        tid = self.create_iscsi_target(iscsi_name, volume['id'], iscsi_target,
                                       lun, volume_path, chap_auth)

        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', chap_username, chap_password)
        return data
Пример #5
0
    def create_export(self, context, volume, connector):
        """Driver entry point to get the export info for a new volume."""
        target_name = self._get_target_name(volume)
        updates = {}

        if not self._tgt_utils.iscsi_target_exists(target_name):
            self._tgt_utils.create_iscsi_target(target_name)
            updates['provider_location'] = target_name

            if self.configuration.use_chap_auth:
                chap_username = (self.configuration.chap_username or
                                 utils.generate_username())
                chap_password = (self.configuration.chap_password or
                                 utils.generate_password())

                self._tgt_utils.set_chap_credentials(target_name,
                                                     chap_username,
                                                     chap_password)

                updates['provider_auth'] = ' '.join(('CHAP',
                                                     chap_username,
                                                     chap_password))

        # This operation is idempotent
        self._tgt_utils.add_disk_to_target(volume['name'], target_name)

        return updates
Пример #6
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                               volume['name'])
        iscsi_target, lun = self._get_target_and_lun(context, volume)

        # Verify we haven't setup a CHAP creds file already
        # if DNE no big deal, we'll just create it
        current_chap_auth = self._get_target_chap_auth(iscsi_name)
        if current_chap_auth:
            (chap_username, chap_password) = current_chap_auth
        else:
            chap_username = vutils.generate_username()
            chap_password = vutils.generate_password()
        chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
                                               chap_password)
        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        iscsi_write_cache = self.configuration.get('iscsi_write_cache', 'on')
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       0,
                                       volume_path,
                                       chap_auth,
                                       iscsi_write_cache=iscsi_write_cache)
        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication('CHAP', chap_username,
                                                  chap_password)
        return data
Пример #7
0
 def test_generate_password(self):
     password = volume_utils.generate_password()
     self.assertTrue([c for c in password if c in '0123456789'])
     self.assertTrue([c for c in password
                      if c in 'abcdefghijklmnopqrstuvwxyz'])
     self.assertTrue([c for c in password
                      if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'])
Пример #8
0
    def create_export(self, context, volume, connector):
        """Driver entry point to get the export info for a new volume."""
        target_name = self._get_target_name(volume)
        updates = {}

        if not self._tgt_utils.iscsi_target_exists(target_name):
            self._tgt_utils.create_iscsi_target(target_name)
            updates['provider_location'] = target_name

            if self.configuration.use_chap_auth:
                chap_username = (self.configuration.chap_username
                                 or utils.generate_username())
                chap_password = (self.configuration.chap_password
                                 or utils.generate_password())

                self._tgt_utils.set_chap_credentials(target_name,
                                                     chap_username,
                                                     chap_password)

                updates['provider_auth'] = ' '.join(
                    ('CHAP', chap_username, chap_password))

        # This operation is idempotent
        self._tgt_utils.add_disk_to_target(volume.name, target_name)

        return updates
Пример #9
0
    def _create_server(self, connector, client):
        server_info = None
        chap_enabled = self.configuration.hplefthand_iscsi_chap_enabled
        try:
            server_info = client.getServerByName(connector['host'])
            chap_secret = server_info['chapTargetSecret']
            if not chap_enabled and chap_secret:
                LOG.warning(_LW('CHAP secret exists for host %s but CHAP is '
                                'disabled'), connector['host'])
            if chap_enabled and chap_secret is None:
                LOG.warning(_LW('CHAP is enabled, but server secret not '
                                'configured on server %s'), connector['host'])
            return server_info
        except hpexceptions.HTTPNotFound:
            # server does not exist, so create one
            pass

        optional = None
        if chap_enabled:
            chap_secret = utils.generate_password()
            optional = {'chapName': connector['initiator'],
                        'chapTargetSecret': chap_secret,
                        'chapAuthenticationRequired': True
                        }

        server_info = client.createServer(connector['host'],
                                          connector['initiator'],
                                          optional)
        return server_info
Пример #10
0
    def _create_server(self, connector, client):
        server_info = None
        chap_enabled = self.configuration.hplefthand_iscsi_chap_enabled
        try:
            server_info = client.getServerByName(connector["host"])
            chap_secret = server_info["chapTargetSecret"]
            if not chap_enabled and chap_secret:
                LOG.warning(_LW("CHAP secret exists for host %s but CHAP is " "disabled"), connector["host"])
            if chap_enabled and chap_secret is None:
                LOG.warning(_LW("CHAP is enabled, but server secret not " "configured on server %s"), connector["host"])
            return server_info
        except hpexceptions.HTTPNotFound:
            # server does not exist, so create one
            pass

        optional = None
        if chap_enabled:
            chap_secret = utils.generate_password()
            optional = {
                "chapName": connector["initiator"],
                "chapTargetSecret": chap_secret,
                "chapAuthenticationRequired": True,
            }

        server_info = client.createServer(connector["host"], connector["initiator"], optional)
        return server_info
Пример #11
0
 def test_generate_password(self):
     password = volume_utils.generate_password()
     self.assertTrue([c for c in password if c in '0123456789'])
     self.assertTrue(
         [c for c in password if c in 'abcdefghijklmnopqrstuvwxyz'])
     self.assertTrue(
         [c for c in password if c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'])
Пример #12
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        # 'iscsi_name': 'iqn.2010-10.org.openstack:volume-00000001'
        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                               volume['name'])
        iscsi_target, lun = self._get_target_and_lun(context, volume)

        # Verify we haven't setup a CHAP creds file already
        # if DNE no big deal, we'll just create it
        chap_auth = self._get_target_chap_auth(context, volume)
        if not chap_auth:
            chap_auth = (vutils.generate_username(),
                         vutils.generate_password())

        # Get portals ips and port
        portals_config = self._get_portals_config()

        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        tid = self.create_iscsi_target(iscsi_name, iscsi_target, lun,
                                       volume_path, chap_auth,
                                       **portals_config)
        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun,
            self.configuration.iscsi_secondary_ip_addresses)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication('CHAP', *chap_auth)
        return data
Пример #13
0
    def create_export(self, context, volume, volume_path, conf):
        """Creates an export for a logical volume."""
        iscsi_name = "%s%s" % (conf.iscsi_target_prefix,
                               volume['name'])
        max_targets = conf.safe_get('iscsi_num_targets')
        (iscsi_target, lun) = self._get_target_and_lun(context,
                                                       volume,
                                                       max_targets)

        current_chap_auth = self._get_target_chap_auth(iscsi_name)
        if current_chap_auth:
            (chap_username, chap_password) = current_chap_auth
        else:
            chap_username = utils.generate_username()
            chap_password = utils.generate_password()
        chap_auth = self._iscsi_authentication('IncomingUser',
                                               chap_username,
                                               chap_password)
        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       0,
                                       volume_path,
                                       chap_auth,
                                       write_cache=
                                       conf.iscsi_write_cache)
        data = {}
        data['location'] = self._iscsi_location(
            conf.iscsi_ip_address, tid, iscsi_name, conf.iscsi_port, lun)

        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', chap_username, chap_password)
        return data
Пример #14
0
    def create_export(self, context, volume, volume_path, conf):
        """Creates an export for a logical volume."""
        iscsi_name = "%s%s" % (conf.iscsi_target_prefix,
                               volume['name'])
        max_targets = conf.safe_get('iscsi_num_targets')
        (iscsi_target, lun) = self._get_target_and_lun(context,
                                                       volume,
                                                       max_targets)

        chap_username = utils.generate_username()
        chap_password = utils.generate_password()
        chap_auth = self._iscsi_authentication('IncomingUser',
                                               chap_username,
                                               chap_password)
        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       0,
                                       volume_path,
                                       chap_auth,
                                       write_cache=
                                       conf.iscsi_write_cache)
        data = {}
        data['location'] = self._iscsi_location(
            conf.iscsi_ip_address, tid, iscsi_name, conf.iscsi_port, lun)
        data['auth'] = self._iscsi_authentication(
            'CHAP', chap_username, chap_password)
        return data
Пример #15
0
Файл: tgt.py Проект: Qeas/cinder
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                               volume['name'])
        iscsi_target, lun = self._get_target_and_lun(context, volume)

        # Verify we haven't setup a CHAP creds file already
        # if DNE no big deal, we'll just create it
        current_chap_auth = self._get_target_chap_auth(iscsi_name)
        if current_chap_auth:
            (chap_username, chap_password) = current_chap_auth
        else:
            chap_username = vutils.generate_username()
            chap_password = vutils.generate_password()
        chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
                                               chap_password)
        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        iscsi_write_cache = self.configuration.get('iscsi_write_cache', 'on')
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       0,
                                       volume_path,
                                       chap_auth,
                                       iscsi_write_cache=iscsi_write_cache)
        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun,
            self.configuration.iscsi_secondary_ip_addresses)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', chap_username, chap_password)
        return data
Пример #16
0
    def create_export(self, context, volume, connector):
        """Driver entry point to get the export info for a new volume."""
        # Since the iSCSI targets are not reused, being deleted when the
        # volume is detached, we should clean up existing targets before
        # creating a new one.
        self.remove_export(context, volume)

        target_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                                volume['name'])
        updates = {'provider_location': target_name}
        self.utils.create_iscsi_target(target_name)

        if self.configuration.use_chap_auth:
            chap_username = (self.configuration.chap_username
                             or utils.generate_username())
            chap_password = (self.configuration.chap_password
                             or utils.generate_password())

            self.utils.set_chap_credentials(target_name, chap_username,
                                            chap_password)

            updates['provider_auth'] = ' '.join(
                ('CHAP', chap_username, chap_password))
        # Get the disk to add
        vol_name = volume['name']
        self.utils.add_disk_to_target(vol_name, target_name)

        return updates
Пример #17
0
    def create_export(self, context, volume, connector):
        """Driver entry point to get the export info for a new volume."""
        # Since the iSCSI targets are not reused, being deleted when the
        # volume is detached, we should clean up existing targets before
        # creating a new one.
        self.remove_export(context, volume)

        target_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                                volume['name'])
        updates = {'provider_location': target_name}
        self.utils.create_iscsi_target(target_name)

        if self.configuration.use_chap_auth:
            chap_username = (self.configuration.chap_username or
                             utils.generate_username())
            chap_password = (self.configuration.chap_password or
                             utils.generate_password())

            self.utils.set_chap_credentials(target_name,
                                            chap_username,
                                            chap_password)

            updates['provider_auth'] = ' '.join(('CHAP',
                                                 chap_username,
                                                 chap_password))
        # Get the disk to add
        vol_name = volume['name']
        self.utils.add_disk_to_target(vol_name, target_name)

        return updates
Пример #18
0
    def _create_server(self, connector):
        server_info = None
        chap_enabled = self.configuration.hplefthand_iscsi_chap_enabled
        try:
            server_info = self.client.getServerByName(connector['host'])
            chap_secret = server_info['chapTargetSecret']
            if not chap_enabled and chap_secret:
                LOG.warning(
                    _('CHAP secret exists for host %s but CHAP is '
                      'disabled') % connector['host'])
            if chap_enabled and chap_secret is None:
                LOG.warning(
                    _('CHAP is enabled, but server secret not '
                      'configured on server %s') % connector['host'])
            return server_info
        except hpexceptions.HTTPNotFound:
            # server does not exist, so create one
            pass

        optional = None
        if chap_enabled:
            chap_secret = utils.generate_password()
            optional = {
                'chapName': connector['initiator'],
                'chapTargetSecret': chap_secret,
                'chapAuthenticationRequired': True
            }
        server_info = self.client.createServer(connector['host'],
                                               connector['initiator'],
                                               optional)
        return server_info
Пример #19
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        # 'iscsi_name': 'iqn.2010-10.org.openstack:volume-00000001'
        iscsi_name = "%s%s" % (self.configuration.target_prefix,
                               volume['name'])
        iscsi_target, lun = self._get_target_and_lun(context, volume)

        # Verify we haven't setup a CHAP creds file already
        # if DNE no big deal, we'll just create it
        chap_auth = self._get_target_chap_auth(context, volume)
        if not chap_auth:
            chap_auth = (vutils.generate_username(),
                         vutils.generate_password())

        # Get portals ips and port
        portals_config = self._get_portals_config()

        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       lun,
                                       volume_path,
                                       chap_auth,
                                       **portals_config)
        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.target_ip_address, tid, iscsi_name, lun,
            self.configuration.iscsi_secondary_ip_addresses)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', *chap_auth)
        return data
Пример #20
0
    def _configure_chap(self, initiator_name):
        password = volume_utils.generate_password(na_utils.CHAP_SECRET_LENGTH)
        username = na_utils.DEFAULT_CHAP_USER_NAME

        self.zapi_client.set_iscsi_chap_authentication(initiator_name,
                                                       username, password)
        LOG.debug("Set iSCSI CHAP authentication.")

        return username, password
Пример #21
0
    def create_nvmeof_target(self,
                             volume_id,
                             subsystem_name,
                             target_ip,
                             target_port,
                             transport_type,
                             nvmet_port_id,
                             ns_id,
                             volume_path):

        LOG.debug('SPDK create target')

        nqn = self._get_nqn_with_volume_name(volume_id)

        if nqn is None:
            node = self._get_first_free_node()
            nqn = '%s:cnode%s' % (subsystem_name, node)
            choice = string.ascii_uppercase + string.digits
            serial = ''.join(
                utils.generate_password(length=12, symbolgroups=choice))

            params = {
                'nqn': nqn,
                'allow_any_host': True,
                'serial_number': serial,
            }
            self._rpc_call('nvmf_subsystem_create', params)

            listen_address = {
                'trtype': transport_type,
                'traddr': target_ip,
                'trsvcid': str(target_port),
            }
            params = {
                'nqn': nqn,
                'listen_address': listen_address,
            }
            self._rpc_call('nvmf_subsystem_add_listener', params)

            ns = {
                'bdev_name': self._get_spdk_volume_name(volume_id),
                'nsid': ns_id,
            }
            params = {
                'nqn': nqn,
                'namespace': ns,
            }
            self._rpc_call('nvmf_subsystem_add_ns', params)

        location = self.get_nvmeof_location(
            nqn,
            target_ip,
            target_port,
            transport_type,
            ns_id)

        return {'location': location, 'auth': '', 'provider_id': nqn}
Пример #22
0
    def _configure_chap(self, initiator_name):
        password = volume_utils.generate_password(na_utils.CHAP_SECRET_LENGTH)
        username = na_utils.DEFAULT_CHAP_USER_NAME

        self.zapi_client.set_iscsi_chap_authentication(initiator_name,
                                                       username,
                                                       password)
        LOG.debug("Set iSCSI CHAP authentication.")

        return username, password
Пример #23
0
    def _create_export(self, context, volume):
        """Creates an export for a logical volume.""" 
        if volume['name'] is None:
            return None
#         devmeg=zfscm.DEVList()
#         devname=devmeg.get_devname_by_volumename(volume['name'])   
#         volume_path = "/dev/%s" % devname 
        volume_path="/dev/" + self.poolname + "/" + volume['name']
        
        #data = self.target_helper.create_export(context,
        #                                        volume,
        #                                        volume_path,
        #                                        self.configuration)
        conf=self.configuration
        iscsi_name = "%s%s" % (conf.iscsi_target_prefix,
                               volume['name'])
        max_targets = conf.safe_get('iscsi_num_targets')
        (iscsi_target, lun) = self.target_helper._get_target_and_lun(context,
                                                       volume,
                                                       max_targets)
        try:
            current_chap_auth = self.target_helper._get_target_chap_auth(context,iscsi_name)
        except:
            current_chap_auth = self._getzfs_target_chap_auth(context,iscsi_name)
            pass
                      
        if current_chap_auth:
            (chap_username, chap_password) = current_chap_auth
        else:
            chap_username = cutils.generate_username()
            chap_password = cutils.generate_password()
        chap_auth = self.target_helper._iscsi_authentication('IncomingUser',
                                               chap_username,
                                               chap_password)
        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        
        tid = self.targetbase.create_iscsi_target(iscsi_name,iscsi_target, 0,
                                       volume_path,
                                       chap_auth,
                                       write_cache=conf.iscsi_write_cache)
        data = {}
        data['location'] = self.target_helper._iscsi_location(
            conf.iscsi_ip_address, tid, iscsi_name, conf.iscsi_port, lun)
        data['auth'] = self.target_helper._iscsi_authentication(
            'CHAP', chap_username, chap_password)

        return {
            'provider_location': data['location'],
            'provider_auth': data['auth'],
        }
Пример #24
0
    def initialize_connection(self, volume, connector, **kwargs):
        """Attach volume to initiator/host.

        Creates a profile for the initiator, and adds the new profile to the
        target ACL.

        """

        # generate a CHAP secret here -- there is no way to retrieve an
        # existing CHAP secret over the Blockbridge API, so it must be
        # supplied by the volume driver.
        export_params = {
            'chap_user': (kwargs.get('user',
                                     volume_utils.generate_username(16))),
            'chap_secret': (kwargs.get('password',
                                       volume_utils.generate_password(32))),
        }

        LOG.debug("Configuring export for %(initiator)s",
                  connector,
                  resource=volume)

        rsp = self._create_export(volume['id'],
                                  connector['initiator'],
                                  export_params,
                                  user_id=volume['user_id'],
                                  project_id=volume['project_id'])

        # combine locally generated chap credentials with target iqn/lun to
        # present the attach properties.
        target_portal = "%s:%s" % (rsp['target_ip'], rsp['target_port'])

        properties = {
            'target_discovered': False,
            'target_portal': target_portal,
            'target_iqn': rsp['target_iqn'],
            'target_lun': rsp['target_lun'],
            'volume_id': volume['id'],
            'auth_method': 'CHAP',
            'auth_username': rsp['initiator_login'],
            'auth_password': export_params['chap_secret'],
        }

        LOG.debug("Attach properties: %(properties)s",
                  {'properties': properties})

        return {
            'driver_volume_type': 'iscsi',
            'data': properties,
        }
Пример #25
0
    def initialize_connection(self, volume, connector, **kwargs):
        """Attach volume to initiator/host.

        Creates a profile for the initiator, and adds the new profile to the
        target ACL.

        """

        # generate a CHAP secret here -- there is no way to retrieve an
        # existing CHAP secret over the Blockbridge API, so it must be
        # supplied by the volume driver.
        export_params = {
            'chap_user': (
                kwargs.get('user', volume_utils.generate_username(16))),
            'chap_secret': (
                kwargs.get('password', volume_utils.generate_password(32))),
        }

        LOG.debug("Configuring export for %(initiator)s", connector,
                  resource=volume)

        rsp = self._create_export(volume['id'],
                                  connector['initiator'],
                                  export_params,
                                  user_id=volume['user_id'],
                                  project_id=volume['project_id'])

        # combine locally generated chap credentials with target iqn/lun to
        # present the attach properties.
        target_portal = "%s:%s" % (rsp['target_ip'], rsp['target_port'])

        properties = {
            'target_discovered': False,
            'target_portal': target_portal,
            'target_iqn': rsp['target_iqn'],
            'target_lun': rsp['target_lun'],
            'volume_id': volume['id'],
            'auth_method': 'CHAP',
            'auth_username': rsp['initiator_login'],
            'auth_password': export_params['chap_secret'],
        }

        LOG.debug("Attach properties: %(properties)s",
                  {'properties': properties})

        return {
            'driver_volume_type': 'iscsi',
            'data': properties,
        }
Пример #26
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        # 'iscsi_name': 'iqn.2010-10.org.openstack:volume-00000001'
        iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                               volume['name'])
        iscsi_target, lun = self._get_target_and_lun(context, volume)

        # Verify we haven't setup a CHAP creds file already
        # if DNE no big deal, we'll just create it
        chap_auth = self._get_target_chap_auth(context, volume)
        if not chap_auth:
            auth = volume['provider_auth']
            if auth:
                (auth_method, auth_username, auth_secret) = auth.split()
                if auth_method == 'CHAP':
                    chap_auth = (auth_username, auth_secret)
                else:
                    LOG.error("Failed create_export. "
                              "Invalid auth_method: %(a)s for volume: %(v)s",
                              {"a": auth_method, "v": volume['id']})
                    return
            else:
                chap_auth = (vutils.generate_username(),
                             vutils.generate_password())

        # Get portals ips and port
        portals_config = self._get_portals_config()

        # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
        # should clean this all up at some point in the future
        LOG.info(("Creating volume export for %(uuid)s target:%(target)s "
                  "lun:%(lun)s path:%(volume_path)s"),
                 {"uuid": volume['id'], "target": iscsi_target, "lun": lun,
                  "volume_path": volume_path})
        tid = self.create_iscsi_target(iscsi_name,
                                       iscsi_target,
                                       lun,
                                       volume_path,
                                       chap_auth,
                                       **portals_config)
        LOG.info("Volume export for %s created", volume['id'])
        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.iscsi_ip_address, tid, iscsi_name, lun,
            self.configuration.iscsi_secondary_ip_addresses)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication(
            'CHAP', *chap_auth)
        return data
Пример #27
0
    def _target_create(self, identifier):
        if not identifier:
            err = _('Param [identifier] is invalid.')
            raise exception.InvalidParameterValue(err=err)

        # 0 for no auth, 1 for single chap, 2 for mutual chap
        auth_type = 0
        chap_username = ''
        chap_password = ''
        provider_auth = ''
        if self.config.safe_get('use_chap_auth') and self.config.use_chap_auth:
            auth_type = 1
            chap_username = (self.config.safe_get('chap_username') or
                             volutils.generate_username(12))
            chap_password = (self.config.safe_get('chap_password') or
                             volutils.generate_password())
            provider_auth = ' '.join(('CHAP', chap_username, chap_password))

        trg_prefix = self.config.safe_get('iscsi_target_prefix')
        trg_name = (self.TARGET_NAME_PREFIX + '%s') % identifier
        iqn = trg_prefix + trg_name

        try:
            out = self.exec_webapi('SYNO.Core.ISCSI.Target',
                                   'create',
                                   1,
                                   name=trg_name,
                                   iqn=iqn,
                                   auth_type=auth_type,
                                   user=chap_username,
                                   password=chap_password,
                                   max_sessions=0)

            self.check_response(out)

        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception(_LE('Failed to _target_create. [%s]'),
                              identifier)

        if not self.check_value_valid(out, ['data', 'target_id']):
            msg = _('Failed to get target_id of target [%s]') % trg_name
            raise exception.VolumeDriverException(message=msg)

        trg_id = out['data']['target_id']

        return iqn, trg_id, provider_auth
Пример #28
0
 def create_export(self, context, volume, volume_path):
     """Creates an export for a logical volume."""
     iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                            volume['name'])
     iscsi_target, lun = self._get_target_and_lun(context, volume)
     chap_username = vutils.generate_username()
     chap_password = vutils.generate_password()
     chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
                                            chap_password)
     # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
     # should clean this all up at some point in the future
     tid = self.create_iscsi_target(iscsi_name, iscsi_target, 0,
                                    volume_path, chap_auth)
     data = {}
     data['location'] = self._iscsi_location(
         self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
     LOG.debug('Set provider_location to: %s', data['location'])
     data['auth'] = self._iscsi_authentication('CHAP', chap_username,
                                               chap_password)
     return data
Пример #29
0
 def _initialize_connection_iscsi(self, volume, connector):
     volume_name = self._make_volume_name(volume)
     infinidat_volume = self._get_infinidat_volume_by_name(volume_name)
     port = iqn.IQN(connector['initiator'])
     infinidat_host = self._get_or_create_host(port)
     if self.configuration.use_chap_auth:
         chap_username = (self.configuration.chap_username
                          or vol_utils.generate_username())
         chap_password = (self.configuration.chap_password
                          or vol_utils.generate_password())
         infinidat_host.update_fields(
             security_method='CHAP',
             security_chap_inbound_username=chap_username,
             security_chap_inbound_secret=chap_password)
     mapping = self._get_or_create_mapping(infinidat_host, infinidat_volume)
     lun = mapping.get_lun()
     netspace_names = self.configuration.infinidat_iscsi_netspaces
     target_portals = []
     target_iqns = []
     target_luns = []
     for netspace_name in netspace_names:
         netspace = self._get_iscsi_network_space(netspace_name)
         target_portals.append(self._get_iscsi_portal(netspace))
         target_iqns.append(netspace.get_properties().iscsi_iqn)
         target_luns.append(lun)
     result_data = dict(target_discovered=True,
                        target_portal=target_portals[0],
                        target_iqn=target_iqns[0],
                        target_lun=target_luns[0])
     if len(target_portals) > 1:
         # multiple network spaces defined
         result_data.update(
             dict(target_portals=target_portals,
                  target_iqns=target_iqns,
                  target_luns=target_luns))
     if self.configuration.use_chap_auth:
         result_data.update(
             dict(auth_method='CHAP',
                  auth_username=chap_username,
                  auth_password=chap_password))
     return dict(driver_volume_type='iscsi', data=result_data)
Пример #30
0
 def _initialize_connection_iscsi(self, volume, connector):
     volume_name = self._make_volume_name(volume)
     infinidat_volume = self._get_infinidat_volume_by_name(volume_name)
     port = iqn.IQN(connector['initiator'])
     infinidat_host = self._get_or_create_host(port)
     if self.configuration.use_chap_auth:
         chap_username = (self.configuration.chap_username or
                          vol_utils.generate_username())
         chap_password = (self.configuration.chap_password or
                          vol_utils.generate_password())
         infinidat_host.update_fields(
             security_method='CHAP',
             security_chap_inbound_username=chap_username,
             security_chap_inbound_secret=chap_password)
     mapping = self._get_or_create_mapping(infinidat_host,
                                           infinidat_volume)
     lun = mapping.get_lun()
     netspace_names = self.configuration.infinidat_iscsi_netspaces
     target_portals = []
     target_iqns = []
     target_luns = []
     for netspace_name in netspace_names:
         netspace = self._get_iscsi_network_space(netspace_name)
         target_portals.append(self._get_iscsi_portal(netspace))
         target_iqns.append(netspace.get_properties().iscsi_iqn)
         target_luns.append(lun)
     result_data = dict(target_discovered=True,
                        target_portal=target_portals[0],
                        target_iqn=target_iqns[0],
                        target_lun=target_luns[0])
     if len(target_portals) > 1:
         # multiple network spaces defined
         result_data.update(dict(target_portals=target_portals,
                                 target_iqns=target_iqns,
                                 target_luns=target_luns))
     if self.configuration.use_chap_auth:
         result_data.update(dict(auth_method='CHAP',
                                 auth_username=chap_username,
                                 auth_password=chap_password))
     return dict(driver_volume_type='iscsi',
                 data=result_data)
Пример #31
0
    def create_export(self, context, volume, volume_path):
        """Creates an export for a logical volume."""
        iscsi_target, lun = self._get_target_and_lun(context, volume)
        iscsi_name = self._get_iscsi_name(volume)

        if self.chap_username and self.chap_password:
            chap_auth = (self.chap_username, self.chap_password)
        else:
            chap_auth = self._get_target_chap_auth(context, volume)
            if not chap_auth:
                chap_auth = (vutils.generate_username(),
                             vutils.generate_password())
        tid = self.create_iscsi_target(iscsi_name, volume['id'], iscsi_target,
                                       lun, volume_path, chap_auth)

        data = {}
        data['location'] = self._iscsi_location(
            self.configuration.target_ip_address, tid, iscsi_name, lun)
        LOG.debug('Set provider_location to: %s', data['location'])
        data['auth'] = self._iscsi_authentication('CHAP', *chap_auth)
        return data
Пример #32
0
 def create_export(self, context, volume, volume_path):
     """Creates an export for a logical volume."""
     iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
                            volume['name'])
     iscsi_target, lun = self._get_target_and_lun(context, volume)
     chap_username = vutils.generate_username()
     chap_password = vutils.generate_password()
     chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
                                            chap_password)
     # NOTE(jdg): For TgtAdm case iscsi_name is the ONLY param we need
     # should clean this all up at some point in the future
     tid = self.create_iscsi_target(iscsi_name,
                                    iscsi_target,
                                    0,
                                    volume_path,
                                    chap_auth)
     data = {}
     data['location'] = self._iscsi_location(
         self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
     LOG.debug('Set provider_location to: %s', data['location'])
     data['auth'] = self._iscsi_authentication(
         'CHAP', chap_username, chap_password)
     return data
Пример #33
0
 def _generate_chap_secret():
     return volume_utils.generate_password()
Пример #34
0
    def _get_service_target(self, volume):
        """Get the available service parameters

           Get the available service parameters for a given volume using
           its type.
           :param volume: dictionary volume reference
        """

        hdp = self._get_service(volume)
        info = _loc_info(volume['provider_location'])
        (arid, lun_name) = info['id_lu']

        evsid = self.bend.get_evs(self.config['hnas_cmd'],
                                  self.config['mgmt_ip0'],
                                  self.config['username'],
                                  self.config['password'],
                                  hdp)
        svc_label = utils.extract_host(volume['host'], level='pool')
        svc = self.config['services'][svc_label]

        LOG.info(_LI("_get_service_target hdp: %s."), hdp)
        LOG.info(_LI("config[services]: %s."), self.config['services'])

        mapped, lunid, tgt = self.bend.check_lu(self.config['hnas_cmd'],
                                                self.config['mgmt_ip0'],
                                                self.config['username'],
                                                self.config['password'],
                                                lun_name, hdp)

        LOG.info(_LI("Target is %(map)s! Targetlist = %(tgtl)s."),
                 {'map': "mapped" if mapped else "not mapped", 'tgtl': tgt})

        # The volume is already mapped to a LUN, so no need to create any
        # targets
        if mapped:
            service = (svc['iscsi_ip'], svc['iscsi_port'], svc['ctl'],
                       svc['port'], hdp, tgt['alias'], tgt['secret'])
            return service

        # Each EVS can have up to 32 targets. Each target can have up to 32
        # LUNs attached and have the name format 'evs<id>-tgt<0-N>'. We run
        # from the first 'evs1-tgt0' until we find a target that is not already
        # created in the BE or is created but have slots to place new targets.
        found_tgt = False
        for i in range(0, MAX_HNAS_ISCSI_TARGETS):
            tgt_alias = 'evs' + evsid + '-tgt' + six.text_type(i)
            # TODO(erlon): we need to go to the BE 32 times here
            tgt_exist, tgt = self.bend.check_target(self.config['hnas_cmd'],
                                                    self.config['mgmt_ip0'],
                                                    self.config['username'],
                                                    self.config['password'],
                                                    hdp, tgt_alias)
            if tgt_exist and len(tgt['luns']) < 32 or not tgt_exist:
                # Target exists and has free space or, target does not exist
                # yet. Proceed and use the target or create a target using this
                # name.
                found_tgt = True
                break

        # If we've got here and found_tgt is not True, we run out of targets,
        # raise and go away.
        if not found_tgt:
            LOG.error(_LE("No more targets avaliable."))
            raise exception.NoMoreTargets(param=tgt_alias)

        LOG.info(_LI("Using target label: %s."), tgt_alias)

        # Check if we have a secret stored for this target so we don't have to
        # go to BE on every query
        if 'targets' not in self.config.keys():
            self.config['targets'] = {}

        if tgt_alias not in self.config['targets'].keys():
            self.config['targets'][tgt_alias] = {}

        tgt_info = self.config['targets'][tgt_alias]

        # HNAS - one time lookup
        # see if the client supports CHAP authentication and if
        # iscsi_secret has already been set, retrieve the secret if
        # available, otherwise generate and store
        if self.config['chap_enabled'] == 'True':
            # It may not exist, create and set secret.
            if 'iscsi_secret' not in tgt_info.keys():
                LOG.info(_LI("Retrieving secret for service: %s."),
                         tgt_alias)

                out = self.bend.get_targetsecret(self.config['hnas_cmd'],
                                                 self.config['mgmt_ip0'],
                                                 self.config['username'],
                                                 self.config['password'],
                                                 tgt_alias, hdp)
                tgt_info['iscsi_secret'] = out
                if tgt_info['iscsi_secret'] == "":
                    randon_secret = utils.generate_password()[0:15]
                    tgt_info['iscsi_secret'] = randon_secret
                    self.bend.set_targetsecret(self.config['hnas_cmd'],
                                               self.config['mgmt_ip0'],
                                               self.config['username'],
                                               self.config['password'],
                                               tgt_alias, hdp,
                                               tgt_info['iscsi_secret'])

                    LOG.info(_LI("Set tgt CHAP secret for service: %s."),
                             tgt_alias)
        else:
            # We set blank password when the client does not
            # support CHAP. Later on, if the client tries to create a new
            # target that does not exists in the backend, we check for this
            # value and use a temporary dummy password.
            if 'iscsi_secret' not in tgt_info.keys():
                # Warns in the first time
                LOG.info(_LI("CHAP authentication disabled."))

            tgt_info['iscsi_secret'] = ""

        if 'tgt_iqn' not in tgt_info:
            LOG.info(_LI("Retrieving target for service: %s."), tgt_alias)

            out = self.bend.get_targetiqn(self.config['hnas_cmd'],
                                          self.config['mgmt_ip0'],
                                          self.config['username'],
                                          self.config['password'],
                                          tgt_alias, hdp,
                                          tgt_info['iscsi_secret'])
            tgt_info['tgt_iqn'] = out

        self.config['targets'][tgt_alias] = tgt_info

        service = (svc['iscsi_ip'], svc['iscsi_port'], svc['ctl'],
                   svc['port'], hdp, tgt_alias, tgt_info['iscsi_secret'])

        return service
 def _generate_hex_key(self, **kwargs):
     key_length = kwargs.get('key_length', 256)
     # hex digit => 4 bits
     hex_encoded = utils.generate_password(length=key_length // 4,
                                           symbolgroups='0123456789ABCDEF')
     return hex_encoded
Пример #36
0
    def _get_service_target(self, volume):
        """Gets the available service parameters

        Gets the available service parameters for a given volume using its
        type.
        :param volume: dictionary volume reference
        :returns: service target information or raises error
        :raises: NoMoreTargets
        """
        fs_label = self._get_service(volume)
        evs_id = self.backend.get_evs(fs_label)

        svc_label = utils.extract_host(volume.host, level='pool')
        svc = self.config['services'][svc_label]

        lu_info = self.backend.check_lu(volume.name, fs_label)

        # The volume is already mapped to a LU, so no need to create any
        # targets
        if lu_info['mapped']:
            service = (svc['iscsi_ip'], svc['iscsi_port'], svc['evs'],
                       svc['port'], fs_label, lu_info['tgt']['alias'],
                       lu_info['tgt']['secret'])
            LOG.info(
                _LI("Volume %(vol_name)s already mapped on target "
                    "%(tgt)s to LUN %(lunid)s."), {
                        'vol_name': volume.name,
                        'tgt': lu_info['tgt']['alias'],
                        'lunid': lu_info['id']
                    })
            return service

        # Each EVS can have up to 32 targets. Each target can have up to 32
        # LUs attached and have the name format 'evs<id>-tgt<0-N>'. We run
        # from the first 'evs1-tgt0' until we find a target that is not already
        # created in the BE or is created but have slots to place new LUs.
        tgt_alias = ''
        for i in range(0, MAX_HNAS_ISCSI_TARGETS):
            tgt_alias = 'evs' + evs_id + '-tgt' + six.text_type(i)
            tgt = self.backend.check_target(fs_label, tgt_alias)

            if (tgt['found']
                    and len(tgt['tgt']['lus']) < MAX_HNAS_LUS_PER_TARGET
                    or not tgt['found']):
                # Target exists and has free space or, target does not exist
                # yet. Proceed and use the target or create a target using this
                # name.
                break
        else:
            # If we've got here, we run out of targets, raise and go away.
            LOG.error(_LE("No more targets available."))
            raise exception.NoMoreTargets(param=tgt_alias)

        LOG.info(_LI("Using target label: %(tgt)s."), {'tgt': tgt_alias})

        # Check if we have a secret stored for this target so we don't have to
        # go to BE on every query
        if 'targets' not in self.config.keys():
            self.config['targets'] = {}

        if tgt_alias not in self.config['targets'].keys():
            self.config['targets'][tgt_alias] = {}

        tgt_info = self.config['targets'][tgt_alias]

        # HNAS - one time lookup
        # see if the client supports CHAP authentication and if
        # iscsi_secret has already been set, retrieve the secret if
        # available, otherwise generate and store
        if self.config['chap_enabled']:
            # CHAP support is enabled. Tries to get the target secret.
            if 'iscsi_secret' not in tgt_info.keys():
                LOG.info(_LI("Retrieving secret for service: %(tgt)s."),
                         {'tgt': tgt_alias})
                out = self.backend.get_target_secret(tgt_alias, fs_label)
                tgt_info['iscsi_secret'] = out

                # CHAP supported and the target has no secret yet. So, the
                # secret is created for the target
                if tgt_info['iscsi_secret'] == "":
                    random_secret = utils.generate_password()[0:15]
                    tgt_info['iscsi_secret'] = random_secret

                    LOG.info(_LI("Set tgt CHAP secret for service: %(tgt)s."),
                             {'tgt': tgt_alias})
        else:
            # We set blank password when the client does not
            # support CHAP. Later on, if the client tries to create a new
            # target that does not exist in the backend, we check for this
            # value and use a temporary dummy password.
            if 'iscsi_secret' not in tgt_info.keys():
                # Warns in the first time
                LOG.info(_LI("CHAP authentication disabled."))

            tgt_info['iscsi_secret'] = "''"

        # If the target does not exist, it should be created
        if not tgt['found']:
            self.backend.create_target(tgt_alias, fs_label,
                                       tgt_info['iscsi_secret'])
        elif (tgt['tgt']['secret'] == "" and self.config['chap_enabled']):
            # The target exists, has no secret and chap is enabled
            self.backend.set_target_secret(tgt_alias, fs_label,
                                           tgt_info['iscsi_secret'])

        if 'tgt_iqn' not in tgt_info:
            LOG.info(_LI("Retrieving IQN for service: %(tgt)s."),
                     {'tgt': tgt_alias})

            out = self.backend.get_target_iqn(tgt_alias, fs_label)
            tgt_info['tgt_iqn'] = out

        self.config['targets'][tgt_alias] = tgt_info

        service = (svc['iscsi_ip'], svc['iscsi_port'], svc['evs'], svc['port'],
                   fs_label, tgt_alias, tgt_info['iscsi_secret'])

        return service
Пример #37
0
 def add_chap_secret_to_host(self, host_name):
     """Generate and store a randomly-generated CHAP secret for the host."""
     chap_secret = utils.generate_password()
     self.ssh.add_chap_secret(chap_secret, host_name)
     return chap_secret
Пример #38
0
    def _do_export(self, common, volume):
        """Gets the associated account, generates CHAP info and updates."""
        model_update = {}

        if not common._client_conf['hpe3par_iscsi_chap_enabled']:
            model_update['provider_auth'] = None
            return model_update

        # CHAP username will be the hostname
        chap_username = volume['host'].split('@')[0]

        chap_password = None
        try:
            # Get all active VLUNs for the host
            vluns = common.client.getHostVLUNs(chap_username)

            # Host has active VLUNs... is CHAP enabled on host?
            host_info = common.client.getHost(chap_username)

            if not host_info['initiatorChapEnabled']:
                LOG.warning("Host has no CHAP key, but CHAP is enabled.")

        except hpeexceptions.HTTPNotFound:
            chap_password = volume_utils.generate_password(16)
            LOG.warning("No host or VLUNs exist. Generating new " "CHAP key.")
        else:
            # Get a list of all iSCSI VLUNs and see if there is already a CHAP
            # key assigned to one of them.  Use that CHAP key if present,
            # otherwise create a new one.  Skip any VLUNs that are missing
            # CHAP credentials in metadata.
            chap_exists = False
            active_vluns = 0

            for vlun in vluns:
                if not vlun['active']:
                    continue

                active_vluns += 1

                # iSCSI connections start with 'iqn'.
                if ('remoteName' in vlun
                        and re.match('iqn.*', vlun['remoteName'])):
                    try:
                        chap_password = common.client.getVolumeMetaData(
                            vlun['volumeName'], CHAP_PASS_KEY)['value']
                        chap_exists = True
                        break
                    except hpeexceptions.HTTPNotFound:
                        LOG.debug(
                            "The VLUN %s is missing CHAP credentials "
                            "but CHAP is enabled. Skipping.",
                            vlun['remoteName'])
                else:
                    LOG.warning("Non-iSCSI VLUN detected.")

            if not chap_exists:
                chap_password = volume_utils.generate_password(16)
                LOG.warning("No VLUN contained CHAP credentials. "
                            "Generating new CHAP key.")

        # Add CHAP credentials to the volume metadata
        vol_name = common._get_3par_vol_name(volume['id'])
        common.client.setVolumeMetaData(vol_name, CHAP_USER_KEY, chap_username)
        common.client.setVolumeMetaData(vol_name, CHAP_PASS_KEY, chap_password)

        model_update['provider_auth'] = ('CHAP %s %s' %
                                         (chap_username, chap_password))

        return model_update
Пример #39
0
    def _get_service_target(self, volume):
        """Get the available service parameters

           Get the available service parameters for a given volume using
           its type.
           :param volume: dictionary volume reference
        """

        hdp = self._get_service(volume)
        info = _loc_info(volume['provider_location'])
        (arid, lun_name) = info['id_lu']

        evsid = self.bend.get_evs(self.config['hnas_cmd'],
                                  self.config['mgmt_ip0'],
                                  self.config['username'],
                                  self.config['password'], hdp)
        svc_label = utils.extract_host(volume['host'], level='pool')
        svc = self.config['services'][svc_label]

        LOG.info(_LI("_get_service_target hdp: %s."), hdp)
        LOG.info(_LI("config[services]: %s."), self.config['services'])

        mapped, lunid, tgt = self.bend.check_lu(self.config['hnas_cmd'],
                                                self.config['mgmt_ip0'],
                                                self.config['username'],
                                                self.config['password'],
                                                lun_name, hdp)

        LOG.info(_LI("Target is %(map)s! Targetlist = %(tgtl)s."), {
            'map': "mapped" if mapped else "not mapped",
            'tgtl': tgt
        })

        # The volume is already mapped to a LUN, so no need to create any
        # targets
        if mapped:
            service = (svc['iscsi_ip'], svc['iscsi_port'], svc['ctl'],
                       svc['port'], hdp, tgt['alias'], tgt['secret'])
            return service

        # Each EVS can have up to 32 targets. Each target can have up to 32
        # LUNs attached and have the name format 'evs<id>-tgt<0-N>'. We run
        # from the first 'evs1-tgt0' until we find a target that is not already
        # created in the BE or is created but have slots to place new targets.
        found_tgt = False
        for i in range(0, MAX_HNAS_ISCSI_TARGETS):
            tgt_alias = 'evs' + evsid + '-tgt' + six.text_type(i)
            # TODO(erlon): we need to go to the BE 32 times here
            tgt_exist, tgt = self.bend.check_target(self.config['hnas_cmd'],
                                                    self.config['mgmt_ip0'],
                                                    self.config['username'],
                                                    self.config['password'],
                                                    hdp, tgt_alias)
            if tgt_exist and len(tgt['luns']) < 32 or not tgt_exist:
                # Target exists and has free space or, target does not exist
                # yet. Proceed and use the target or create a target using this
                # name.
                found_tgt = True
                break

        # If we've got here and found_tgt is not True, we run out of targets,
        # raise and go away.
        if not found_tgt:
            LOG.error(_LE("No more targets avaliable."))
            raise exception.NoMoreTargets(param=tgt_alias)

        LOG.info(_LI("Using target label: %s."), tgt_alias)

        # Check if we have a secret stored for this target so we don't have to
        # go to BE on every query
        if 'targets' not in self.config.keys():
            self.config['targets'] = {}

        if tgt_alias not in self.config['targets'].keys():
            self.config['targets'][tgt_alias] = {}

        tgt_info = self.config['targets'][tgt_alias]

        # HNAS - one time lookup
        # see if the client supports CHAP authentication and if
        # iscsi_secret has already been set, retrieve the secret if
        # available, otherwise generate and store
        if self.config['chap_enabled'] == 'True':
            # It may not exist, create and set secret.
            if 'iscsi_secret' not in tgt_info.keys():
                LOG.info(_LI("Retrieving secret for service: %s."), tgt_alias)

                out = self.bend.get_targetsecret(self.config['hnas_cmd'],
                                                 self.config['mgmt_ip0'],
                                                 self.config['username'],
                                                 self.config['password'],
                                                 tgt_alias, hdp)
                tgt_info['iscsi_secret'] = out
                if tgt_info['iscsi_secret'] == "":
                    randon_secret = utils.generate_password()[0:15]
                    tgt_info['iscsi_secret'] = randon_secret
                    self.bend.set_targetsecret(self.config['hnas_cmd'],
                                               self.config['mgmt_ip0'],
                                               self.config['username'],
                                               self.config['password'],
                                               tgt_alias, hdp,
                                               tgt_info['iscsi_secret'])

                    LOG.info(_LI("Set tgt CHAP secret for service: %s."),
                             tgt_alias)
        else:
            # We set blank password when the client does not
            # support CHAP. Later on, if the client tries to create a new
            # target that does not exists in the backend, we check for this
            # value and use a temporary dummy password.
            if 'iscsi_secret' not in tgt_info.keys():
                # Warns in the first time
                LOG.info(_LI("CHAP authentication disabled."))

            tgt_info['iscsi_secret'] = ""

        if 'tgt_iqn' not in tgt_info:
            LOG.info(_LI("Retrieving target for service: %s."), tgt_alias)

            out = self.bend.get_targetiqn(self.config['hnas_cmd'],
                                          self.config['mgmt_ip0'],
                                          self.config['username'],
                                          self.config['password'], tgt_alias,
                                          hdp, tgt_info['iscsi_secret'])
            tgt_info['tgt_iqn'] = out

        self.config['targets'][tgt_alias] = tgt_info

        service = (svc['iscsi_ip'], svc['iscsi_port'], svc['ctl'], svc['port'],
                   hdp, tgt_alias, tgt_info['iscsi_secret'])

        return service
Пример #40
0
    def _get_service_target(self, volume):
        """Gets the available service parameters

        Gets the available service parameters for a given volume using its
        type.
        :param volume: dictionary volume reference
        :returns: service target information or raises error
        :raises: NoMoreTargets
        """
        fs_label = self._get_service(volume)
        evs_id = self.backend.get_evs(fs_label)

        svc_label = utils.extract_host(volume.host, level='pool')
        svc = self.config['services'][svc_label]

        lu_info = self.backend.check_lu(volume.name, fs_label)

        # The volume is already mapped to a LU, so no need to create any
        # targets
        if lu_info['mapped']:
            service = (
                svc['iscsi_ip'], svc['iscsi_port'], svc['evs'], svc['port'],
                fs_label, lu_info['tgt']['alias'], lu_info['tgt']['secret'])
            return service

        # Each EVS can have up to 32 targets. Each target can have up to 32
        # LUs attached and have the name format 'evs<id>-tgt<0-N>'. We run
        # from the first 'evs1-tgt0' until we find a target that is not already
        # created in the BE or is created but have slots to place new LUs.
        tgt_alias = ''
        for i in range(0, MAX_HNAS_ISCSI_TARGETS):
            tgt_alias = 'evs' + evs_id + '-tgt' + six.text_type(i)
            tgt = self.backend.check_target(fs_label, tgt_alias)

            if (tgt['found'] and
                    len(tgt['tgt']['lus']) < MAX_HNAS_LUS_PER_TARGET or
                    not tgt['found']):
                # Target exists and has free space or, target does not exist
                # yet. Proceed and use the target or create a target using this
                # name.
                break
        else:
            # If we've got here, we run out of targets, raise and go away.
            LOG.error(_LE("No more targets available."))
            raise exception.NoMoreTargets(param=tgt_alias)

        LOG.info(_LI("Using target label: %(tgt)s."), {'tgt': tgt_alias})

        # Check if we have a secret stored for this target so we don't have to
        # go to BE on every query
        if 'targets' not in self.config.keys():
            self.config['targets'] = {}

        if tgt_alias not in self.config['targets'].keys():
            self.config['targets'][tgt_alias] = {}

        tgt_info = self.config['targets'][tgt_alias]

        # HNAS - one time lookup
        # see if the client supports CHAP authentication and if
        # iscsi_secret has already been set, retrieve the secret if
        # available, otherwise generate and store
        if self.config['chap_enabled']:
            # CHAP support is enabled. Tries to get the target secret.
            if 'iscsi_secret' not in tgt_info.keys():
                LOG.info(_LI("Retrieving secret for service: %(tgt)s."),
                         {'tgt': tgt_alias})
                out = self.backend.get_target_secret(tgt_alias, fs_label)
                tgt_info['iscsi_secret'] = out

                # CHAP supported and the target has no secret yet. So, the
                # secret is created for the target
                if tgt_info['iscsi_secret'] == "":
                    random_secret = utils.generate_password()[0:15]
                    tgt_info['iscsi_secret'] = random_secret

                    LOG.info(_LI("Set tgt CHAP secret for service: %(tgt)s."),
                             {'tgt': tgt_alias})
        else:
            # We set blank password when the client does not
            # support CHAP. Later on, if the client tries to create a new
            # target that does not exist in the backend, we check for this
            # value and use a temporary dummy password.
            if 'iscsi_secret' not in tgt_info.keys():
                # Warns in the first time
                LOG.info(_LI("CHAP authentication disabled."))

            tgt_info['iscsi_secret'] = "''"

        # If the target does not exist, it should be created
        if not tgt['found']:
            self.backend.create_target(tgt_alias, fs_label,
                                       tgt_info['iscsi_secret'])
        elif (tgt['tgt']['secret'] == "" and
                self.config['chap_enabled']):
            # The target exists, has no secret and chap is enabled
            self.backend.set_target_secret(tgt_alias, fs_label,
                                           tgt_info['iscsi_secret'])

        if 'tgt_iqn' not in tgt_info:
            LOG.info(_LI("Retrieving IQN for service: %(tgt)s."),
                     {'tgt': tgt_alias})

            out = self.backend.get_target_iqn(tgt_alias, fs_label)
            tgt_info['tgt_iqn'] = out

        self.config['targets'][tgt_alias] = tgt_info

        service = (svc['iscsi_ip'], svc['iscsi_port'], svc['evs'], svc['port'],
                   fs_label, tgt_alias, tgt_info['iscsi_secret'])

        return service
Пример #41
0
    def _do_export(self, common, volume):
        """Gets the associated account, generates CHAP info and updates."""
        model_update = {}

        if not self.configuration.hp3par_iscsi_chap_enabled:
            model_update['provider_auth'] = None
            return model_update

        # CHAP username will be the hostname
        chap_username = volume['host'].split('@')[0]

        chap_password = None
        try:
            # Get all active VLUNs for the host
            vluns = common.client.getHostVLUNs(chap_username)

            # Host has active VLUNs... is CHAP enabled on host?
            host_info = common.client.getHost(chap_username)

            if not host_info['initiatorChapEnabled']:
                LOG.warning(_LW("Host has no CHAP key, but CHAP is enabled."))

        except hpexceptions.HTTPNotFound:
            chap_password = volume_utils.generate_password(16)
            LOG.warning(_LW("No host or VLUNs exist. Generating new "
                            "CHAP key."))
        else:
            # Get a list of all iSCSI VLUNs and see if there is already a CHAP
            # key assigned to one of them.  Use that CHAP key if present,
            # otherwise create a new one.  Skip any VLUNs that are missing
            # CHAP credentials in metadata.
            chap_exists = False
            active_vluns = 0

            for vlun in vluns:
                if not vlun['active']:
                    continue

                active_vluns += 1

                # iSCSI connections start with 'iqn'.
                if ('remoteName' in vlun and
                        re.match('iqn.*', vlun['remoteName'])):
                    try:
                        chap_password = common.client.getVolumeMetaData(
                            vlun['volumeName'], CHAP_PASS_KEY)['value']
                        chap_exists = True
                        break
                    except hpexceptions.HTTPNotFound:
                        LOG.debug("The VLUN %s is missing CHAP credentials "
                                  "but CHAP is enabled. Skipping.",
                                  vlun['remoteName'])
                else:
                    LOG.warning(_LW("Non-iSCSI VLUN detected."))

            if not chap_exists:
                chap_password = volume_utils.generate_password(16)
                LOG.warning(_LW("No VLUN contained CHAP credentials. "
                                "Generating new CHAP key."))

        # Add CHAP credentials to the volume metadata
        vol_name = common._get_3par_vol_name(volume['id'])
        common.client.setVolumeMetaData(
            vol_name, CHAP_USER_KEY, chap_username)
        common.client.setVolumeMetaData(
            vol_name, CHAP_PASS_KEY, chap_password)

        model_update['provider_auth'] = ('CHAP %s %s' %
                                         (chap_username, chap_password))

        return model_update
Пример #42
0
    def _get_service(self, volume):
        """Get available service parameters.

        Get the available service parameters for a given volume using its type.
        :param volume: dictionary volume reference
        """

        label = utils.extract_host(volume['host'], level='pool')
        LOG.info(_LI("Using service label: %s"), label)

        if label in self.config['services'].keys():
            svc = self.config['services'][label]
            # HNAS - one time lookup
            # see if the client supports CHAP authentication and if
            # iscsi_secret has already been set, retrieve the secret if
            # available, otherwise generate and store
            if self.config['chap_enabled'] == 'True':
                # it may not exist, create and set secret
                if 'iscsi_secret' not in svc:
                    LOG.info(_LI("Retrieving secret for service: %s"), label)

                    out = self.bend.get_targetsecret(self.config['hnas_cmd'],
                                                     self.config['mgmt_ip0'],
                                                     self.config['username'],
                                                     self.config['password'],
                                                     'cinder-' + label,
                                                     svc['hdp'])
                    svc['iscsi_secret'] = out
                    if svc['iscsi_secret'] == "":
                        svc['iscsi_secret'] = utils.generate_password()[0:15]
                        self.bend.set_targetsecret(self.config['hnas_cmd'],
                                                   self.config['mgmt_ip0'],
                                                   self.config['username'],
                                                   self.config['password'],
                                                   'cinder-' + label,
                                                   svc['hdp'],
                                                   svc['iscsi_secret'])

                        LOG.info(_LI("Set tgt CHAP secret for service: %s"),
                                 label)
            else:
                # We set blank password when the client does not
                # support CHAP. Later on, if the client tries to create a new
                # target that does not exists in the backend, we check for this
                # value and use a temporary dummy password.
                if 'iscsi_secret' not in svc:
                    # Warns in the first time
                    LOG.info(_LI("CHAP authentication disabled"))

                svc['iscsi_secret'] = ""

            if 'iscsi_target' not in svc:
                LOG.info(_LI("Retrieving target for service: %s"), label)

                out = self.bend.get_targetiqn(self.config['hnas_cmd'],
                                              self.config['mgmt_ip0'],
                                              self.config['username'],
                                              self.config['password'],
                                              'cinder-' + label,
                                              svc['hdp'],
                                              svc['iscsi_secret'])
                svc['iscsi_target'] = out

            self.config['services'][label] = svc

            service = (svc['iscsi_ip'], svc['iscsi_port'], svc['ctl'],
                       svc['port'], svc['hdp'], svc['iscsi_target'],
                       svc['iscsi_secret'])
        else:
            LOG.info(_LI("Available services: %s"),
                     self.config['services'].keys())
            LOG.error(_LE("No configuration found for service: %s"), label)
            raise exception.ParameterNotFound(param=label)

        return service
Пример #43
0
 def add_chap_secret_to_host(self, host_name):
     """Generate and store a randomly-generated CHAP secret for the host."""
     chap_secret = utils.generate_password()
     self.ssh.add_chap_secret(chap_secret, host_name)
     return chap_secret
Пример #44
0
    def _setup_iscsi_chap_authentication(self, targets, initiator):
        iscsi_chap_enabled = self.configuration.datacore_iscsi_chap_enabled

        self._check_iscsi_chap_configuration(iscsi_chap_enabled, targets)

        server_group = self._get_our_server_group()
        update_access_token = False
        access_token = None
        chap_secret = None
        if iscsi_chap_enabled:
            authentication = 'CHAP'
            chap_secret = self._password_storage.get_password(
                server_group.Id, initiator.PortName)
            update_access_token = False
            if not chap_secret:
                chap_secret = volume_utils.generate_password(length=15)
                self._password_storage.set_password(
                    server_group.Id, initiator.PortName, chap_secret)
                update_access_token = True
            access_token = self._api.build_access_token(
                initiator.PortName,
                None,
                None,
                False,
                initiator.PortName,
                chap_secret)
        else:
            authentication = 'None'
            if self._password_storage:
                self._password_storage.delete_password(server_group.Id,
                                                       initiator.PortName)
        changed_targets = {}
        try:
            for target in targets:
                if iscsi_chap_enabled:
                    target_iscsi_nodes = getattr(target.iSCSINodes, 'Node', [])
                    iscsi_node = datacore_utils.get_first_or_default(
                        lambda node: node.Name == initiator.PortName,
                        target_iscsi_nodes,
                        None)
                    if (not iscsi_node
                            or not iscsi_node.AccessToken.TargetUsername
                            or update_access_token):
                        self._api.set_access_token(target.Id, access_token)
                properties = target.ServerPortProperties
                if properties.Authentication != authentication:
                    changed_targets[target] = properties.Authentication
                    properties.Authentication = authentication
                    self._api.set_server_port_properties(
                        target.Id, properties)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception("Configuring of iSCSI CHAP authentication for "
                              "initiator %(initiator)s failed.",
                              {'initiator': initiator.PortName})
                try:
                    for target in changed_targets:
                        properties = target.ServerPortProperties
                        properties.Authentication = changed_targets[target]
                        self._api.set_server_port_properties(
                            target.Id, properties)
                except datacore_exception.DataCoreException as e:
                    LOG.warning("An error occurred on a cleanup after  failed "
                                "configuration of iSCSI CHAP authentication "
                                "on initiator %(initiator)s: %(error)s.",
                                {'initiator': initiator.PortName, 'error': e})
        if iscsi_chap_enabled:
            return initiator.PortName, chap_secret
Пример #45
0
 def _generate_chap_secret():
     return volume_utils.generate_password()
Пример #46
0
 def _generate_hex_key(self, **kwargs):
     key_length = kwargs.get('key_length', 256)
     # hex digit => 4 bits
     hex_encoded = utils.generate_password(length=key_length // 4,
                                           symbolgroups='0123456789ABCDEF')
     return hex_encoded