コード例 #1
0
    def show(self, full_project_name, name):
        """Retrieves volume details based on volume name.

        :param full_project_name: project path of the volume
        :param name: name of the volume. If the volume is under a project,
                     then full XPath needs to be specified.
                     Example: If VOL1 is a volume under project PROJ1,
                     then the name of volume is PROJ1/VOL1
        :returns: Volume details in JSON response payload
        """
        if common.is_uri(name):
            return name
        if full_project_name is None:
            raise common.CoprHdError(
                common.CoprHdError.NOT_FOUND_ERR,
                (_("Volume %s : not found") % six.text_type(name)))

        uris = self.search_volumes(full_project_name)

        for uri in uris:
            volume = self.show_by_uri(uri)
            if volume and 'name' in volume and volume['name'] == name:
                return volume
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Volume"
                                    " %s : not found") % six.text_type(name)))
コード例 #2
0
    def _get_resource_lun_tuple(self, resources, resType, baseResUri,
                                tenantname, projectname, blockTypeName):
        """Function to validate input volumes and return list of ids and luns.

        """
        copyEntries = []
        volumeObject = volume.Volume(self.ipaddr, self.port)
        for copy in resources:
            copyParam = []
            try:
                copyParam = copy.split(":")
            except Exception:
                raise common.CoprHdError(
                    common.CoprHdError.CMD_LINE_ERR,
                    (_("Please provide valid format volume:"
                       " lun for parameter %s") % resType))
            copy = dict()
            if not len(copyParam):
                raise common.CoprHdError(
                    common.CoprHdError.CMD_LINE_ERR,
                    (_("Please provide at least one volume for parameter %s") %
                     resType))
            if resType == "volumes":
                full_project_name = tenantname + "/" + projectname
                copy['id'] = volumeObject.volume_query(full_project_name,
                                                       copyParam[0])
            if len(copyParam) > 1:
                copy['lun'] = copyParam[1]
            copyEntries.append(copy)
        return copyEntries
コード例 #3
0
    def exportgroup_query(self, name, project, tenant, varrayuri=None):
        """Makes REST API call to query the exportgroup by name.

        :param name: Name/id of the export group
        :param project: Name of the project
        :param tenant: Name of the tenant
        :param varrayuri: URI of the virtual array
        :returns: id of the export group
        """
        if common.is_uri(name):
            return name

        uris = self.exportgroup_list(project, tenant)
        for uri in uris:
            exportgroup = self.exportgroup_show(uri, project, tenant)
            if exportgroup and exportgroup['name'] == name:
                if varrayuri:
                    varrayobj = exportgroup['varray']
                    if varrayobj['id'] == varrayuri:
                        return exportgroup['id']
                    else:
                        continue
                else:
                    return exportgroup['id']
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Export Group %s: not found") % name))
コード例 #4
0
    def tenant_query(self, label):
        """Returns the UID of the tenant specified by the hierarchical name.

        (ex tenant1/tenant2/tenant3)
        """

        if common.is_uri(label):
            return label

        tenant_id = self.tenant_getid()

        if not label:
            return tenant_id

        subtenants = self.tenant_list(tenant_id)
        subtenants.append(self.tenant_show(None))

        for tenant in subtenants:
            if tenant['name'] == label:
                rslt = self.tenant_show_by_uri(tenant['id'])
                if rslt:
                    return tenant['id']

        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Tenant %s: not found") % label))
コード例 #5
0
    def expand(self,
               full_project_name,
               volume_name,
               new_size,
               sync=False,
               synctimeout=0):

        volume_detail = self.show(full_project_name, volume_name)
        from decimal import Decimal
        new_size_in_gb = Decimal(Decimal(new_size) / (units.Gi))
        current_size = Decimal(volume_detail["provisioned_capacity_gb"])
        if new_size_in_gb <= current_size:
            raise common.CoprHdError(
                common.CoprHdError.VALUE_ERR,
                (_("error: Incorrect value of new size: %(new_size_in_gb)s"
                   " GB\nNew size must be greater than current size: "
                   "%(current_size)s GB") % {
                       'new_size_in_gb': new_size_in_gb,
                       'current_size': current_size
                   }))

        body = oslo_serialization.jsonutils.dumps({"new_size": new_size})

        (s, h) = common.service_json_request(
            self.ipaddr, self.port, "POST",
            Volume.URI_EXPAND.format(volume_detail["id"]), body)
        if not s:
            return None
        o = common.json_decode(s)

        if sync:
            return self.check_for_sync(o, sync, synctimeout)
        return o
コード例 #6
0
    def exportgroup_create(self,
                           name,
                           project_name,
                           tenant,
                           varray,
                           exportgrouptype,
                           export_destination=None):
        """This function creates the Export group with given name.

        :param name: Name of the export group
        :param project_name: Name of the project path
        :param tenant: Container tenant name
        :param varray: Name of the virtual array
        :param exportgrouptype: Type of the export group. Ex:Host etc
        :returns: status of creation
        """
        # check for existence of export group.
        try:
            status = self.exportgroup_show(name, project_name, tenant)
        except common.CoprHdError as e:
            if e.err_code == common.CoprHdError.NOT_FOUND_ERR:
                if tenant is None:
                    tenant = ""

                fullproj = tenant + "/" + project_name
                projObject = project.Project(self.ipaddr, self.port)
                projuri = projObject.project_query(fullproj)

                varrayObject = virtualarray.VirtualArray(
                    self.ipaddr, self.port)
                nhuri = varrayObject.varray_query(varray)

                parms = {
                    'name': name,
                    'project': projuri,
                    'varray': nhuri,
                    'type': exportgrouptype
                }

                if exportgrouptype and export_destination:
                    host_obj = host.Host(self.ipaddr, self.port)
                    host_uri = host_obj.query_by_name(export_destination)
                    parms['hosts'] = [host_uri]

                body = oslo_serialization.jsonutils.dumps(parms)
                (s, h) = common.service_json_request(self.ipaddr, self.port,
                                                     "POST",
                                                     self.URI_EXPORT_GROUP,
                                                     body)

                o = common.json_decode(s)
                return o
            else:
                raise

        if status:
            raise common.CoprHdError(
                common.CoprHdError.ENTRY_ALREADY_EXISTS_ERR,
                (_("Export group with name %s"
                   " already exists") % name))
コード例 #7
0
    def vpool_query(self, name, vpooltype):
        """Makes REST API call to query the vpool by name and type.

        This function will take the VPOOL name and type of VPOOL
        as input and get uri of the first occurrence of given VPOOL.

        :param name: Name of the VPOOL
        :param vpooltype: Type of the VPOOL {'block'}
        :returns: uri of the given vpool
        """
        if common.is_uri(name):
            return name

        (s, h) = common.service_json_request(
            self.ipaddr, self.port, "GET",
            self.URI_VPOOL_SEARCH.format(vpooltype, name), None)

        o = common.json_decode(s)
        if len(o['resource']) > 0:
            # Get the Active vpool ID.
            for vpool in o['resource']:
                if self.vpool_show_uri(vpooltype, vpool['id']) is not None:
                    return vpool['id']
        # Raise not found exception. as we did not find any active vpool.
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("VPool %(name)s ( %(vpooltype)s ) :"
                                    " not found") %
                                  {'name': name,
                                   'vpooltype': vpooltype
                                   }))
コード例 #8
0
 def check_for_sync(self, result, sync, synctimeout=0):
     if len(result["resource"]) > 0:
         resource = result["resource"]
         return (common.block_until_complete("consistencygroup",
                                             resource["id"], result["id"],
                                             self.ipaddr, self.port,
                                             synctimeout))
     else:
         raise common.CoprHdError(
             common.CoprHdError.SOS_FAILURE_ERR,
             _("error: task list is empty, no task response found"))
コード例 #9
0
    def volume_query(self, full_project_name, volume_name):
        """Makes REST API call to query the volume by name.

        :param volume_name: name of volume
        :param full_project_name: Full project path
        :returns: Volume details in JSON response payload
        """
        if common.is_uri(volume_name):
            return volume_name

        if not full_project_name:
            raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                     _("Project name not specified"))
        uris = self.search_volumes(full_project_name)
        for uri in uris:
            volume = self.show_by_uri(uri)
            if volume and 'name' in volume and volume['name'] == volume_name:
                return volume['id']
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Volume"
                                    "%s: not found") % volume_name))
コード例 #10
0
 def get_tenant_by_name(self, tenant):
     uri = None
     if not tenant:
         uri = self.tenant_getid()
     else:
         if not common.is_uri(tenant):
             uri = self.tenant_query(tenant)
         else:
             uri = tenant
         if not uri:
             raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                      (_("Tenant %s: not found") % tenant))
     return uri
コード例 #11
0
ファイル: tag.py プロジェクト: linux6200/cinder-driver
    def list_tags(self, resource_uri):
        if resource_uri.__contains__("tag") is False:
            raise common.CoprHdError(common.CoprHdError.VALUE_ERR,
                                     _("URI should end with /tag"))

        (s, h) = common.service_json_request(self.ipaddr, self.port, "GET",
                                             resource_uri, None)

        allTags = []
        o = common.json_decode(s)
        allTags = o['tag']

        return allTags
コード例 #12
0
    def varray_query(self, name):
        """Returns the UID of the varray specified by the name."""
        if common.is_uri(name):
            return name

        uris = self.varray_list()

        for uri in uris:
            varray = self.varray_show(uri)
            if varray and varray['name'] == name:
                return varray['id']

        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("varray %s: not found") % name))
コード例 #13
0
ファイル: snapshot.py プロジェクト: linux6200/cinder-driver
    def snapshot_query(self, storageres_type, storageres_typename, resuri,
                       snapshot_name):
        if resuri is not None:
            uris = self.snapshot_list_uri(storageres_type, storageres_typename,
                                          resuri)
            for uri in uris:
                snapshot = self.snapshot_show_uri(storageres_type, resuri,
                                                  uri['id'])
                if (False == common.get_node_value(snapshot, 'inactive')
                        and snapshot['name'] == snapshot_name):
                    return snapshot['id']

        raise common.CoprHdError(common.CoprHdError.SOS_FAILURE_ERR,
                                 (_("snapshot with the name: "
                                    "%s Not Found") % snapshot_name))
コード例 #14
0
    def query_by_name(self, host_name, tenant_name=None):
        """Search host matching host_name and tenant if tenant_name provided.

        tenant_name is optional
        """
        hostList = self.list_all(tenant_name)
        for host in hostList:
            hostUri = host['id']
            hostDetails = self.show_by_uri(hostUri)
            if hostDetails:
                if hostDetails['name'] == host_name:
                    return hostUri

        raise common.CoprHdError(
            common.CoprHdError.NOT_FOUND_ERR,
            (_("Host with name: %s not found") % host_name))
コード例 #15
0
    def consistencygroup_query(self, name, project, tenant):
        """This function will return consistency group id.

        :param name : Name/id of the consistency group
        :param project: Name of the project
        :param tenant: Name of the tenant
        :returns: id of the consistency group
        """
        if common.is_uri(name):
            return name

        uris = self.list(project, tenant)
        for uri in uris:
            congroup = self.show(uri, project, tenant)
            if congroup and congroup['name'] == name:
                return congroup['id']
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Consistency Group %s: not found") % name))
コード例 #16
0
    def project_query(self, name):
        """Retrieves UUID of project based on its name.

        :param name: name of project
        :returns: UUID of project
        :raises CoprHdError: - when project name is not found
        """
        if common.is_uri(name):
            return name
        (tenant_name, project_name) = common.get_parent_child_from_xpath(name)

        tenant_obj = tenant.Tenant(self.ipaddr, self.port)

        tenant_uri = tenant_obj.tenant_query(tenant_name)
        projects = self.project_list(tenant_uri)
        if projects:
            for project in projects:
                if project:
                    project_detail = self.project_show_by_uri(project['id'])
                    if (project_detail
                            and project_detail['name'] == project_name):
                        return project_detail['id']
        raise common.CoprHdError(common.CoprHdError.NOT_FOUND_ERR,
                                 (_("Project: %s not found") % project_name))
コード例 #17
0
ファイル: snapshot.py プロジェクト: linux6200/cinder-driver
    def snapshot_create(self,
                        otype,
                        typename,
                        ouri,
                        snaplabel,
                        inactive,
                        sync,
                        readonly=False,
                        synctimeout=0):
        """New snapshot is created, for a given volume.

        :param otype       : block type should be provided
        :param typename    : either volume or consistency-groups should
                             be provided
        :param ouri        : uri of volume
        :param snaplabel   : name of the snapshot
        :param inactive    : if true, the snapshot will not activate the
                             synchronization between source and target volumes
        :param sync        : synchronous request
        :param synctimeout : Query for task status for "synctimeout" secs.
                             If the task doesn't complete in synctimeout
                             secs, an exception is thrown
        """

        # check snapshot is already exist
        is_snapshot_exist = True
        try:
            self.snapshot_query(otype, typename, ouri, snaplabel)
        except common.CoprHdError as e:
            if e.err_code == common.CoprHdError.NOT_FOUND_ERR:
                is_snapshot_exist = False
            else:
                raise

        if is_snapshot_exist:
            raise common.CoprHdError(
                common.CoprHdError.ENTRY_ALREADY_EXISTS_ERR,
                (_("Snapshot with name %(snaplabel)s"
                   " already exists under %(typename)s") % {
                       'snaplabel': snaplabel,
                       'typename': typename
                   }))

        parms = {
            'name': snaplabel,
            # if true, the snapshot will not activate the synchronization
            # between source and target volumes
            'create_inactive': inactive
        }
        if readonly is True:
            parms['read_only'] = readonly
        body = oslo_serialization.jsonutils.dumps(parms)

        # REST api call
        (s, h) = common.service_json_request(
            self.ipaddr, self.port, "POST",
            Snapshot.URI_SNAPSHOT_LIST.format(otype, typename, ouri), body)
        o = common.json_decode(s)

        task = o["task"][0]

        if sync:
            return (common.block_until_complete(otype, task['resource']['id'],
                                                task["id"], self.ipaddr,
                                                self.port, synctimeout))
        else:
            return o
コード例 #18
0
    def create(self,
               project_name,
               label,
               size,
               varray,
               vpool,
               sync,
               consistencygroup,
               synctimeout=0):
        """Makes REST API call to create volume under a project.

        :param project_name: name of the project under which the volume
                             will be created
        :param label: name of volume
        :param size: size of volume
        :param varray: name of varray
        :param vpool: name of vpool
        :param sync: synchronous request
        :param consistencygroup: To create volume under a consistencygroup
        :param synctimeout: Query for task status for 'synctimeout' secs.
                            If the task doesn't complete in synctimeout secs,
                            an exception is thrown
        :returns: Created task details in JSON response payload
        """

        proj_obj = project.Project(self.ipaddr, self.port)
        project_uri = proj_obj.project_query(project_name)

        vpool_obj = virtualpool.VirtualPool(self.ipaddr, self.port)
        vpool_uri = vpool_obj.vpool_query(vpool, "block")

        varray_obj = virtualarray.VirtualArray(self.ipaddr, self.port)
        varray_uri = varray_obj.varray_query(varray)

        request = {
            'name': label,
            'size': size,
            'varray': varray_uri,
            'project': project_uri,
            'vpool': vpool_uri,
            'count': 1
        }
        if consistencygroup:
            request['consistency_group'] = consistencygroup

        body = oslo_serialization.jsonutils.dumps(request)
        (s, h) = common.service_json_request(self.ipaddr, self.port, "POST",
                                             Volume.URI_VOLUMES, body)
        o = common.json_decode(s)

        if sync:
            # check task empty
            if len(o["task"]) > 0:
                task = o["task"][0]
                return self.check_for_sync(task, sync, synctimeout)
            else:
                raise common.CoprHdError(
                    common.CoprHdError.SOS_FAILURE_ERR,
                    _("error: task list is empty, no task response found"))
        else:
            return o
コード例 #19
0
    def authenticate_user(self, username, password):
        """Makes REST API call to generate the authentication token.

        Authentication token is generated for the specified user after
        validation

        :param username: Name of the user
        :param password: Password for the user
        :returns: The authtoken
        """

        SEC_REDIRECT = 302
        SEC_AUTHTOKEN_HEADER = 'X-SDS-AUTH-TOKEN'
        LB_API_PORT = 4443
        # Port on which load-balancer/reverse-proxy listens to all incoming
        # requests for CoprHD REST APIs
        APISVC_PORT = 8443  # Port on which apisvc listens to incoming requests

        cookiejar = cookie_lib.LWPCookieJar()

        url = ('https://%(ip)s:%(port)d%(uri)s' % {
            'ip': self.ipaddr,
            'port': self.port,
            'uri': self.URI_AUTHENTICATION
        })

        try:
            if self.port == APISVC_PORT:
                login_response = requests.get(url,
                                              headers=self.HEADERS,
                                              verify=False,
                                              auth=(username, password),
                                              cookies=cookiejar,
                                              allow_redirects=False,
                                              timeout=common.TIMEOUT_SEC)
                if login_response.status_code == SEC_REDIRECT:
                    location = login_response.headers['Location']
                    if not location:
                        raise common.CoprHdError(common.CoprHdError.HTTP_ERR,
                                                 (_("The redirect"
                                                    " location of the"
                                                    " authentication"
                                                    " service is not"
                                                    " provided")))
                    # Make the second request
                    login_response = requests.get(location,
                                                  headers=self.HEADERS,
                                                  verify=False,
                                                  cookies=cookiejar,
                                                  allow_redirects=False,
                                                  timeout=common.TIMEOUT_SEC)
                    if (login_response.status_code !=
                            requests.codes['unauthorized']):
                        raise common.CoprHdError(common.CoprHdError.HTTP_ERR,
                                                 (_("The"
                                                    " authentication"
                                                    " service failed"
                                                    " to reply with"
                                                    " 401")))

                    # Now provide the credentials
                    login_response = requests.get(location,
                                                  headers=self.HEADERS,
                                                  auth=(username, password),
                                                  verify=False,
                                                  cookies=cookiejar,
                                                  allow_redirects=False,
                                                  timeout=common.TIMEOUT_SEC)
                    if login_response.status_code != SEC_REDIRECT:
                        raise common.CoprHdError(
                            common.CoprHdError.HTTP_ERR,
                            (_("Access forbidden: Authentication required")))
                    location = login_response.headers['Location']
                    if not location:
                        raise common.CoprHdError(
                            common.CoprHdError.HTTP_ERR,
                            (_("The"
                               " authentication service failed to provide the"
                               " location of the service URI when redirecting"
                               " back")))
                    authtoken = login_response.headers[SEC_AUTHTOKEN_HEADER]
                    if not authtoken:
                        details_str = self.extract_error_detail(login_response)
                        raise common.CoprHdError(common.CoprHdError.HTTP_ERR,
                                                 (_("The token is not"
                                                    " generated by"
                                                    " authentication service."
                                                    "%s") % details_str))
                    # Make the final call to get the page with the token
                    new_headers = self.HEADERS
                    new_headers[SEC_AUTHTOKEN_HEADER] = authtoken
                    login_response = requests.get(location,
                                                  headers=new_headers,
                                                  verify=False,
                                                  cookies=cookiejar,
                                                  allow_redirects=False,
                                                  timeout=common.TIMEOUT_SEC)
                    if login_response.status_code != requests.codes['ok']:
                        raise common.CoprHdError(
                            common.CoprHdError.HTTP_ERR,
                            (_("Login failure code: "
                               "%(statuscode)s Error: %(responsetext)s") % {
                                   'statuscode':
                                   six.text_type(login_response.status_code),
                                   'responsetext':
                                   login_response.text
                               }))
            elif self.port == LB_API_PORT:
                login_response = requests.get(url,
                                              headers=self.HEADERS,
                                              verify=False,
                                              cookies=cookiejar,
                                              allow_redirects=False)

                if (login_response.status_code ==
                        requests.codes['unauthorized']):
                    # Now provide the credentials
                    login_response = requests.get(url,
                                                  headers=self.HEADERS,
                                                  auth=(username, password),
                                                  verify=False,
                                                  cookies=cookiejar,
                                                  allow_redirects=False)
                authtoken = None
                if SEC_AUTHTOKEN_HEADER in login_response.headers:
                    authtoken = login_response.headers[SEC_AUTHTOKEN_HEADER]
            else:
                raise common.CoprHdError(
                    common.CoprHdError.HTTP_ERR,
                    (_("Incorrect port number. Load balanced port is: "
                       "%(lb_api_port)s, api service port is: "
                       "%(apisvc_port)s") % {
                           'lb_api_port': LB_API_PORT,
                           'apisvc_port': APISVC_PORT
                       }))

            if not authtoken:
                details_str = self.extract_error_detail(login_response)
                raise common.CoprHdError(
                    common.CoprHdError.HTTP_ERR,
                    (_("The token is not generated by authentication service."
                       " %s") % details_str))

            if login_response.status_code != requests.codes['ok']:
                error_msg = None
                if login_response.status_code == 401:
                    error_msg = _("Access forbidden: Authentication required")
                elif login_response.status_code == 403:
                    error_msg = _("Access forbidden: You don't have"
                                  " sufficient privileges to perform"
                                  " this operation")
                elif login_response.status_code == 500:
                    error_msg = _("Bourne internal server error")
                elif login_response.status_code == 404:
                    error_msg = _(
                        "Requested resource is currently unavailable")
                elif login_response.status_code == 405:
                    error_msg = (_("GET method is not supported by resource:"
                                   " %s"), url)
                elif login_response.status_code == 503:
                    error_msg = _("Service temporarily unavailable:"
                                  " The server is temporarily unable"
                                  " to service your request")
                else:
                    error_msg = login_response.text
                raise common.CoprHdError(
                    common.CoprHdError.HTTP_ERR,
                    (_("HTTP code: %(status_code)s"
                       ", response: %(reason)s"
                       " [%(error_msg)s]") % {
                           'status_code': six.text_type(
                               login_response.status_code),
                           'reason': six.text_type(login_response.reason),
                           'error_msg': six.text_type(error_msg)
                       }))
        except (exceptions.SSLError, socket.error, exceptions.ConnectionError,
                exceptions.Timeout) as e:
            raise common.CoprHdError(common.CoprHdError.HTTP_ERR,
                                     six.text_type(e))

        return authtoken