def host_list_initiators(args): hostObj = Host(args.ip, args.port) from common import TableGenerator try: initiatorList = hostObj.list_initiators(args.hostlabel) if len(initiatorList) > 0: initiatorListDetails = [] from hostinitiators import HostInitiator hostInitiatorObj = HostInitiator(args.ip, args.port) initiatorListDetails = hostInitiatorObj.show(initiatorList) if args.verbose == True: return common.format_json_object(initiatorListDetails) else: if args.largetable == True: TableGenerator( initiatorListDetails, ["name", "protocol", "initiator_node", "initiator_port", "host_name"] ).printTable() else: TableGenerator(initiatorListDetails, ["name", "protocol", "host_name"]).printTable() except SOSError as e: common.format_err_msg_and_raise("list-initiators", "host", e.err_text, e.err_code)
def exportgroup_add_initiator(self, exportgroupname, tenantname, projectname, initators, hostlabel, sync): exportgroup_uri = self.exportgroup_query(exportgroupname, projectname, tenantname) initiator_uris = [] hiObject = HostInitiator(self.__ipAddr, self.__port) for initator in initators: initiator_uris.append(hiObject.query_by_portwwn(initator, hostlabel)) parms = {} # initiator_changes parms["initiator_changes"] = self._add_list(initiator_uris) o = self.send_json_request(exportgroup_uri, parms) return self.check_for_sync(o, sync)
def __init__(self, ipAddr, port, verbose): ''' Constructor: takes IP address and port of the ViPR instance. These are needed to make http requests for REST API ''' self.__ipAddr = ipAddr self.__port = port self._host = Host(self.__ipAddr, self.__port) self._hostinitiator = HostInitiator(self.__ipAddr, self.__port) self._network = Network(self.__ipAddr, self.__port) self._execute = utils.execute self._vipr_info = ViPRInfo(self.VIPR_CONFIG_FILE) self.set_logging(verbose)
def init_vipr_cli_components(self): import common as vipr_utils vipr_utils.COOKIE = None from exportgroup import ExportGroup from host import Host from hostinitiators import HostInitiator from snapshot import Snapshot from virtualarray import VirtualArray from volume import Volume # instantiate a few vipr cli objects for later use self.volume_obj = Volume(self.configuration.vipr_hostname, self.configuration.vipr_port) self.exportgroup_obj = ExportGroup(self.configuration.vipr_hostname, self.configuration.vipr_port) self.host_obj = Host(self.configuration.vipr_hostname, self.configuration.vipr_port) self.hostinitiator_obj = HostInitiator( self.configuration.vipr_hostname, self.configuration.vipr_port) self.varray_obj = VirtualArray(self.configuration.vipr_hostname, self.configuration.vipr_port) self.snapshot_obj = Snapshot(self.configuration.vipr_hostname, self.configuration.vipr_port)
class EMCViPRDriverCommon(object): OPENSTACK_TAG = 'OpenStack' def __init__(self, protocol, default_backend_name, configuration=None): self.protocol = protocol self.configuration = configuration self.configuration.append_config_values(volume_opts) self.check_for_vipr_cli_path() self.init_vipr_cli_components() self.stats = { 'driver_version': '1.0', 'free_capacity_gb': 'unknown', 'reserved_percentage': '0', 'storage_protocol': protocol, 'total_capacity_gb': 'unknown', 'vendor_name': 'EMC', 'volume_backend_name': self.configuration.volume_backend_name or default_backend_name } self.volume_api = cinder_volume.API() def check_for_vipr_cli_path(self): if (self.configuration.vipr_cli_path is None): message = "vipr_cli_path is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (os.path.exists(self.configuration.vipr_cli_path)): sys.path.append(self.configuration.vipr_cli_path) else: message = self.configuration.vipr_cli_path + " path does not" + \ " exist in the system. Please check/add/change" + \ " vipr_cli_path" + \ " in cinder configuration with valid ViPR" + \ " CLI installation path" raise exception.VolumeBackendAPIException(data=message) def init_vipr_cli_components(self): import common as vipr_utils vipr_utils.COOKIE = None from exportgroup import ExportGroup from host import Host from hostinitiators import HostInitiator from snapshot import Snapshot from virtualarray import VirtualArray from volume import Volume # instantiate a few vipr cli objects for later use self.volume_obj = Volume(self.configuration.vipr_hostname, self.configuration.vipr_port) self.exportgroup_obj = ExportGroup(self.configuration.vipr_hostname, self.configuration.vipr_port) self.host_obj = Host(self.configuration.vipr_hostname, self.configuration.vipr_port) self.hostinitiator_obj = HostInitiator( self.configuration.vipr_hostname, self.configuration.vipr_port) self.varray_obj = VirtualArray(self.configuration.vipr_hostname, self.configuration.vipr_port) self.snapshot_obj = Snapshot(self.configuration.vipr_hostname, self.configuration.vipr_port) def check_for_setup_error(self): # validate all of the vipr_* configuration values if (self.configuration.vipr_hostname is None): message = "vipr_hostname is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_port is None): message = "vipr_port is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_username is None): message = "vipr_username is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_password is None): message = "vipr_password is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_tenant is None): message = "vipr_tenant is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_project is None): message = "vipr_project is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) if (self.configuration.vipr_varray is None): message = "vipr_varray is not set in cinder configuration" raise exception.VolumeBackendAPIException(data=message) def authenticate_user(self): global AUTHENTICATED from authentication import Authentication # we should check to see if we are already authenticated before blindly # doing it again if (AUTHENTICATED is False): obj = Authentication(self.configuration.vipr_hostname, self.configuration.vipr_port) # cookiedir = os.getcwd() cookiedir = self.configuration.vipr_cookiedir obj.authenticate_user(self.configuration.vipr_username, self.configuration.vipr_password, cookiedir, None) AUTHENTICATED = True @retry_wrapper def create_volume(self, vol): self.authenticate_user() name = self._get_volume_name(vol) size = int(vol['size']) * 1073741824 from common import SOSError vpool = self._get_vpool(vol) self.vpool = vpool['ViPR:VPOOL'] try: res = self.volume_obj.create( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project, name, size, self.configuration.vipr_varray, self.vpool, protocol=None, # no longer specified in volume # creation sync=True, number_of_volumes=1, thin_provisioned=None, consistencygroup=None) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Volume " + name + ": Tag failed\n" + e.err_text) else: raise e @retry_wrapper def setTags(self, vol): self.authenticate_user() name = self._get_volume_name(vol) from common import SOSError # first, get the current tags that start with the OPENSTACK_TAG # eyecatcher removeTags = [] currentTags = self.volume_obj.getTags(self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + name) for cTag in currentTags: if (cTag.startswith(self.OPENSTACK_TAG)): removeTags.append(cTag) try: if (len(removeTags) > 0): self.volume_obj.tag( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + name, None, removeTags) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): LOG.debug("SOSError adding the tag: " + e.err_text) # now add the tags for the volume addTags = [] # put all the openstack volume properties into the ViPR volume try: for prop, value in vars(vol).iteritems(): try: # don't put the status in, it's always the status before # the current transaction if (not prop.startswith("status")): addTags.append(self.OPENSTACK_TAG + ":" + prop + ":" + value) except Exception: pass except Exception: pass try: self.volume_obj.tag( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + name, addTags, None) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): LOG.debug("SOSError adding the tag: " + e.err_text) return (self.volume_obj.getTags(self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + name)) @retry_wrapper def create_cloned_volume(self, vol, src_vref): """Creates a clone of the specified volume.""" self.authenticate_user() name = self._get_volume_name(vol) srcname = self._get_volume_name(src_vref) number_of_volumes = 1 from common import SOSError try: res = self.volume_obj.clone(self.configuration.vipr_tenant + "/" + self.configuration.vipr_project, name, number_of_volumes, srcname, None, sync=True) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Volume " + name + ": clone failed\n" + e.err_text) else: raise e @retry_wrapper def expand_volume(self, vol, new_size): """expands the volume to new_size specified.""" self.authenticate_user() volume_name = self._get_volume_name(vol) import common as vipr_utils size_in_bytes = vipr_utils.to_bytes(str(new_size) + "G") from common import SOSError try: self.volume_obj.expand( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + volume_name, size_in_bytes, True) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Volume " + volume_name + ": expand failed\n" + e.err_text) else: raise e @retry_wrapper def create_volume_from_snapshot(self, snapshot, volume): """Creates volume from given snapshot ( snapshot clone to volume ).""" self.authenticate_user() src_snapshot_name = snapshot['name'] src_vol_ref = self.volume_api.get(context.get_admin_context(), snapshot['volume_id']) src_vol_name = self._get_volume_name(src_vol_ref) new_volume_name = self._get_volume_name(volume) number_of_volumes = 1 from common import SOSError try: self.volume_obj.clone(self.configuration.vipr_tenant + "/" + self.configuration.vipr_project, new_volume_name, number_of_volumes, src_vol_name, src_snapshot_name, sync=True) except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Snapshot " + src_snapshot_name + ": clone failed\n" + e.err_text) else: raise e @retry_wrapper def delete_volume(self, vol): self.authenticate_user() name = self._get_volume_name(vol) from common import SOSError try: self.volume_obj.delete(self.configuration.vipr_tenant + "/" + self.configuration.vipr_project + "/" + name, volume_name_list=None, sync=True) except SOSError as e: if e.err_code == SOSError.NOT_FOUND_ERR: LOG.info("Volume " + name + " no longer exists; volume deletion is" + " considered success.") elif e.err_code == SOSError.SOS_FAILURE_ERR: raise SOSError( SOSError.SOS_FAILURE_ERR, "Volume " + name + ": Delete failed\n" + e.err_text) else: raise e @retry_wrapper def list_volume(self): import common as vipr_utils from common import SOSError try: uris = self.volume_obj.list_volumes( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project) if (len(uris) > 0): output = [] for uri in uris: output.append(self.volume_obj.show_by_uri(uri)) return vipr_utils.format_json_object(output) else: return except SOSError as e: raise e @retry_wrapper def create_snapshot(self, snapshot): self.authenticate_user() from common import SOSError try: snapshotname = snapshot['name'] vol = snapshot['volume'] volumename = self._get_volume_name(vol) projectname = self.configuration.vipr_project tenantname = self.configuration.vipr_tenant storageresType = 'block' storageresTypename = 'volumes' resourceUri = self.snapshot_obj.storageResource_query( storageresType, fileshareName=None, volumeName=volumename, cgName=None, project=projectname, tenant=tenantname) inactive = False rptype = None sync = True self.snapshot_obj.snapshot_create(storageresType, storageresTypename, resourceUri, snapshotname, inactive, rptype, sync) return except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Snapshot: " + snapshotname + ", Create Failed\n" + e.err_text) else: raise e @retry_wrapper def delete_snapshot(self, snapshot): self.authenticate_user() snapshotname = snapshot['name'] from common import SOSError try: vol = snapshot['volume'] volumename = self._get_volume_name(vol) projectname = self.configuration.vipr_project tenantname = self.configuration.vipr_tenant storageresType = 'block' storageresTypename = 'volumes' resourceUri = self.snapshot_obj.storageResource_query( storageresType, fileshareName=None, volumeName=volumename, cgName=None, project=projectname, tenant=tenantname) if resourceUri is None: LOG.info("Snapshot " + snapshotname + " is not found; snapshot deletion" + " is considered successful.") else: self.snapshot_obj.snapshot_delete(storageresType, storageresTypename, resourceUri, snapshotname, sync=True) return except SOSError as e: if (e.err_code == SOSError.SOS_FAILURE_ERR): raise SOSError( SOSError.SOS_FAILURE_ERR, "Snapshot " + snapshotname + ": Delete Failed\n") else: raise e @retry_wrapper def initialize_connection(self, volume, protocol, initiatorNodes, initiatorPorts, hostname): from common import SOSError try: self.authenticate_user() volumename = self._get_volume_name(volume) foundgroupname = self._find_exportgroup(initiatorPorts) if (foundgroupname is None): for i in xrange(len(initiatorPorts)): # check if this initiator is contained in any ViPR Host # object LOG.debug("checking for initiator port:" + initiatorPorts[i]) foundhostname = self._find_host(initiatorPorts[i]) if (foundhostname is None): hostfound = self._host_exists(hostname) if (hostfound is None): # create a host so it can be added to the export # group hostfound = hostname self.host_obj.create( hostname, platform.system(), hostname, self.configuration.vipr_tenant, port=None, username=None, passwd=None, usessl=None, osversion=None, cluster=None, datacenter=None, vcenter=None, autodiscovery=True) LOG.info("Created host " + hostname) # add the initiator to the host self.hostinitiator_obj.create(hostfound, protocol, initiatorNodes[i], initiatorPorts[i]) LOG.info("Initiator " + initiatorPorts[i] + " added to host " + hostfound) foundhostname = hostfound else: LOG.info("Found host " + foundhostname) # create an export group for this host foundgroupname = foundhostname + 'SG' # create a unique name foundgroupname = foundgroupname + '-' + \ ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6)) res = self.exportgroup_obj.exportgroup_create( foundgroupname, self.configuration.vipr_project, self.configuration.vipr_tenant, self.configuration.vipr_varray, 'Host', foundhostname) LOG.debug("adding the volume to the exportgroup : " + volumename) res = self.exportgroup_obj.exportgroup_add_volumes( True, foundgroupname, self.configuration.vipr_tenant, self.configuration.vipr_project, [volumename], None, None) return self._find_device_info(volume, initiatorPorts) except SOSError as e: raise SOSError( SOSError.SOS_FAILURE_ERR, "Attach volume (" + self._get_volume_name(volume) + ") to host (" + hostname + ") initiator (" + initiatorPorts[0] + ") failed: " + e.err_text) @retry_wrapper def terminate_connection(self, volume, protocol, initiatorNodes, initiatorPorts, hostname): from common import SOSError try: self.authenticate_user() volumename = self._get_volume_name(volume) tenantproject = self.configuration.vipr_tenant + \ '/' + self.configuration.vipr_project voldetails = self.volume_obj.show(tenantproject + '/' + volumename) volid = voldetails['id'] # find the exportgroups exports = self.volume_obj.get_exports_by_uri(volid) exportgroups = set() itls = exports['itl'] for itl in itls: itl_port = itl['initiator']['port'] if (itl_port in initiatorPorts): exportgroups.add(itl['export']['id']) for exportgroup in exportgroups: res = self.exportgroup_obj.exportgroup_remove_volumes_by_uri( exportgroup, volid, True, None, None, None, None) else: LOG.info("No export group found for the host: " + hostname + "; this is considered already detached.") return itls except SOSError as e: raise SOSError( SOSError.SOS_FAILURE_ERR, "Detaching volume " + volumename + " from host " + hostname + " failed: " + e.err_text) @retry_wrapper def _find_device_info(self, volume, initiator_ports): '''Returns the device_info in a list of itls that have the matched initiator (there could be multiple targets, hence a list): [ { "hlu":9, "initiator":{...,"port":"20:00:00:25:B5:49:00:22"}, "export":{...}, "device":{...,"wwn":"600601602B802D00B62236585D0BE311"}, "target":{...,"port":"50:06:01:6A:46:E0:72:EF"}, "san_zone_name":"..." }, { "hlu":9, "initiator":{...,"port":"20:00:00:25:B5:49:00:22"}, "export":{...}, "device":{...,"wwn":"600601602B802D00B62236585D0BE311"}, "target":{...,"port":"50:06:01:62:46:E0:72:EF"}, "san_zone_name":"..." } ] ''' volumename = self._get_volume_name(volume) fullname = self.configuration.vipr_project + '/' + volumename vol_uri = self.volume_obj.volume_query(fullname) ''' The itl info shall be available at the first try since now export is a synchronous call. We are trying a few more times to accommodate any delay on filling in the itl info after the export task is completed. ''' itls = [] for x in xrange(10): exports = self.volume_obj.get_exports_by_uri(vol_uri) LOG.debug(_("Volume exports: %s") % exports) for itl in exports['itl']: itl_port = itl['initiator']['port'] if (itl_port in initiator_ports): found_device_number = itl['hlu'] if (found_device_number is not None and found_device_number != '-1'): # 0 is a valid number for found_device_number. # Only loop if it is None or -1 LOG.debug("Found Device Number: " + str(found_device_number)) itls.append(itl) if itls: break else: LOG.debug("Device Number not found yet." + " Retrying after 10 seconds...") time.sleep(10) if itls is None: # No device number found after 10 tries; return an empty itl LOG.info("No device number has been found after 10 tries;" + "this likely indicates an unsuccessful attach of" + "volume " + volumename + " to" + " initiator " + str(initiator_ports)) return itls def _get_volume_name(self, vol): try: name = vol['display_name'] except Exception as exp: name = None if (name is None or len(name) == 0): name = vol['name'] return name def _get_vpool(self, volume): vpool = {} ctxt = context.get_admin_context() type_id = volume['volume_type_id'] if type_id is not None: volume_type = volume_types.get_volume_type(ctxt, type_id) specs = volume_type.get('extra_specs') for key, value in specs.iteritems(): vpool[key] = value return vpool @retry_wrapper def _find_exportgroup(self, initiator_ports): '''Find the export group to which the given initiator ports are the same as the initiators in the group ''' foundgroupname = None grouplist = self.exportgroup_obj.exportgroup_list( self.configuration.vipr_project, self.configuration.vipr_tenant) for groupid in grouplist: groupdetails = self.exportgroup_obj.exportgroup_show( groupid, self.configuration.vipr_project, self.configuration.vipr_tenant) if groupdetails is not None: if (groupdetails['inactive']): continue initiators = groupdetails['initiators'] if initiators is not None: inits_eg = set() for initiator in initiators: inits_eg.add(initiator['initiator_port']) if (inits_eg == set(initiator_ports)): foundgroupname = groupdetails['name'] if foundgroupname is not None: # Check the associated varray if groupdetails['varray']: varray_uri = groupdetails['varray']['id'] varray_details = self.varray_obj.varray_show( varray_uri) if (varray_details['name'] == self.configuration.vipr_varray): LOG.debug("Found exportgroup " + foundgroupname) break # Not the right varray foundgroupname = None return foundgroupname @retry_wrapper def _find_host(self, initiator_port): '''Find the host, if exists, to which the given initiator belong.''' foundhostname = None hosts = self.host_obj.list_by_tenant(self.configuration.vipr_tenant) for host in hosts: initiators = self.host_obj.list_initiators(host['id']) for initiator in initiators: if (initiator_port == initiator['name']): foundhostname = host['name'] break if foundhostname is not None: break return foundhostname @retry_wrapper def _host_exists(self, host_name): '''Check if a Host object with the given hostname already exists in ViPR ''' hosts = self.host_obj.search_by_name(host_name) if (len(hosts) > 0): for host in hosts: hostname = host['match'] if (host_name == hostname): return hostname return hostname LOG.debug("no host found for:" + host_name) return None @retry_wrapper def update_volume_stats(self): """Retrieve stats info.""" LOG.debug(_("Updating volume stats")) self.authenticate_user() import common as vipr_utils from common import SOSError try: vols = self.volume_obj.list_volumes( self.configuration.vipr_tenant + "/" + self.configuration.vipr_project) vpairs = set() if (len(vols) > 0): for vol in vols: if (vol): vpair = (vol["vpool"]["id"], vol["varray"]["id"]) if (vpair not in vpairs): vpairs.add(vpair) if (len(vpairs) > 0): free_gb = 0.0 used_gb = 0.0 provisioned_gb = 0.0 precent_used = 0.0 percent_provisioned = 0.0 for vpair in vpairs: if (vpair): (s, h) = vipr_utils.service_json_request( self.configuration.vipr_hostname, self.configuration.vipr_port, "GET", URI_VPOOL_VARRAY_CAPACITY.format( vpair[0], vpair[1]), body=None) capacity = vipr_utils.json_decode(s) free_gb += float(capacity["free_gb"]) used_gb += float(capacity["used_gb"]) provisioned_gb += float(capacity["provisioned_gb"]) self.stats['free_capacity_gb'] = free_gb self.stats['total_capacity_gb'] = free_gb + used_gb self.stats['reserved_percentage'] = 100 * \ provisioned_gb / (free_gb + used_gb) return self.stats except SOSError as e: raise e
class Openstack(object): ''' The class definition for operations related to 'Openstack'. ''' #Commonly used URIs for the 'Openstack' module URI_HOST_SEARCH = '/compute/hosts/search?name={0}' URI_HOST_BULK = '/compute/hosts/bulk' URI_NETWORK_BULK = '/vdc/networks/bulk' URI_NETWORK_PORTS = '/vdc/networks/{0}/storage-ports' URI_STORAGEPORT_ALL = '/vdc/storage-ports' URI_STORAGEPORT_BULK = '/vdc/storage-ports/bulk' VIPR_CONFIG_FILE = '/etc/cinder/cinder.conf' def __init__(self, ipAddr, port, verbose): ''' Constructor: takes IP address and port of the ViPR instance. These are needed to make http requests for REST API ''' self.__ipAddr = ipAddr self.__port = port self._host = Host(self.__ipAddr, self.__port) self._hostinitiator = HostInitiator(self.__ipAddr, self.__port) self._network = Network(self.__ipAddr, self.__port) self._execute = utils.execute self._vipr_info = ViPRInfo(self.VIPR_CONFIG_FILE) self.set_logging(verbose) def set_logging(self, verbose): self._logger = logging.getLogger(__name__) if (verbose): self._logger.setLevel(logging.DEBUG) else: self._logger.setLevel(logging.INFO) logging.basicConfig(format='%(asctime)s:%(levelname)s: %(message)s') def get_logger(self): return self._logger def get_hostname(self, hostname = None): if (not hostname): return socket.getfqdn() else: return hostname def get_vipr_info(self): return self._vipr_info #@retry_wrapper def add_host(self, host_param, connector, vipr_param): self._vipr_info.authenticate_user() varray = vipr_param['varray'] # Find or create host. host = self.create_host(host_param['hostname'], vipr_param['tenant'], vipr_param['project']) self._logger.info('Created/found host %s', host['name']) self._logger.debug('Details of host %s: %s', host_param['hostname'], host) # Find or create initiator. initiator = self.create_initiator(host, connector) self._logger.info('Added initiator %s to host %s', initiator['initiator_port'], host['name']) self._logger.debug('Details of initiator %s', initiator) # Find network network = self.find_iscsi_network(vipr_param['varray'], vipr_param['network']) if (network): self._logger.info('Found network %s in virtual array %s', network['name'], varray) else: self._logger('Cannot find a network in virtual array %s to place the initiator', varray) exit(1) # add initiator to network if (initiator['initiator_port'] not in network['endpoints']): self.add_initiator_to_network(host, initiator, network, vipr_param['varray']) self._logger.info('Added initiator %s to network %s', initiator['initiator_port'], network['name']) self._logger.debug('Network details %s: ', network) @vipr_retry_wrapper def create_host(self, hostname, tenant, project, ostype='Linux'): # find host host = self.find_host(hostname) if (not host): if (not ostype) : ostype = "Linux" # host not found, create a new one. task_rep = self._host.create(hostname, ostype, hostname, tenant, None, None, None, None, None, None, None, None, None) host = common.show_by_href(self.__ipAddr, self.__port, task_rep['resource']) return host ''' Find host by name of host object in ViPR, normally the hostname of the host. Parameters: name: name of the host Returns: host details in JSON ''' def find_host(self, hostname): shortname = hostname[:hostname.find(".")] (s, h) = common.service_json_request(self.__ipAddr, self.__port, "GET", self.URI_HOST_SEARCH.format(shortname), None) o = common.json_decode(s); ids = [] for host in o['resource'] : ids.append(host['id']) body = json.dumps({'id' : ids}) (s, h) = common.service_json_request(self.__ipAddr, self.__port, "POST", self.URI_HOST_BULK, body) o = common.json_decode(s) for host in o['host']: if (host['inactive']): continue if (hostname in host['host_name'] or host['host_name'] in hostname ): return host def get_localhost_initiator(self, protocol='iSCSI'): if (protocol == 'iSCSI'): wwpn = libvirt_utils.get_iscsi_initiator() initiator = {'wwpn' : wwpn} return initiator def find_initiator(self, host, wwpn): initiators = self._host.list_initiators(host) for initiator in initiators: if (initiator['name'] == wwpn): return initiator return None def create_initiator(self, host, connector): initiator = self.find_initiator(host['name'], connector['wwpn']) if (not initiator): initiator = self._hostinitiator.create(host['name'], 'iSCSI', None, connector['wwpn']) return common.show_by_href(self.__ipAddr, self.__port, initiator) ''' Find network for a given network name. If network name is not specified ''' def find_iscsi_network(self, varray, network_name): if (network_name): try: return self._network.network_query(network_name, varray) except SOSError: # TODO: re-raise the exception with correct name. To be removed raise SOSError(SOSError.NOT_FOUND_ERR, "Network {0} not found".format(network_name)) storage_ports = self.get_varray_iscsi_storageports(varray) for port in storage_ports: port_info = dict() port_info['native_guid'] = port['native_guid'] port_info['port_name'] = port['port_name'] try: ip_address = port['ip_address'] port_info['ip_address'] = ip_address if (self.is_ip_pingable(ip_address)): network = port['network'] network_detail = common.show_by_href(self.__ipAddr, self.__port, network) port_info['network'] = network_detail['name'] self._logger.debug('Select storage port %s: ', port_info) return network_detail else: self._logger.debug('Skip storage port %s: ', port_info) except KeyError: self._logger.debug('Skip storage port %s: ', port_info) continue def is_ip_pingable(self, ip_address): self._logger.debug('ping ip address %s ', ip_address) try: (out, err) = self._execute('ping', '-c', '2', ip_address) self._logger.debug(out) return True except Exception as ex: return False def get_ip_networks(self, varray): networks = self._network.list_networks(varray) ip_networks = [] resources = self.get_bulk_details(networks, self.URI_NETWORK_BULK) for x in resources['network']: if (x['transport_type'] == 'IP'): ip_networks.append(x) return ip_networks def get_bulk_details(self, resources, bulkuri): ids = [] for each in resources : ids.append(each['id']) body = json.dumps({'id' : ids}) (s, h) = common.service_json_request(self.__ipAddr, self.__port, "POST", bulkuri, body) return common.json_decode(s) ''' Attach host initiators to a network Parameters: name: name of the host network: name of the network to be attached Return: network details in JSON ''' def add_initiator_to_network(self, host, initiator, network, varray): if (network['transport_type'] == 'IP' and initiator['protocol'] == 'iSCSI'): return self._network.add_endpoint(varray, network['name'], initiator['initiator_port']) def get_varray_iscsi_storageports(self, varray): iscsi_ports = [] for port in self.get_varray_storageports(varray): if (port['transport_type'] != 'IP'): continue if ('iqn' not in port['port_network_id']): continue if ('Not Available' in port['ip_address'] ): continue iscsi_ports.append(port) return iscsi_ports """ Get all storage ports Returns: Storage ports in JSON """ def get_varray_storageports(self, varray): networks = self._network.list_networks(varray) ids = [] for net in networks: net_id = net['id'] (s, h) = common.service_json_request(self.__ipAddr, self.__port, "GET", self.URI_NETWORK_PORTS.format(net_id) , None) o = common.json_decode(s) for port in o['storage_port']: ids.append(port['id']) body = json.dumps({'id' : ids}) (s, h) = common.service_json_request(self.__ipAddr, self.__port, "POST", self.URI_STORAGEPORT_BULK, body) o = common.json_decode(s) return o['storage_port'] def log_info(self, message): import datetime timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") sys.stdout.write(timestamp + ': ' + message + '\n')