Example #1
0
    def ListComponents(self, client_cert, args):
        """Get the list of CMs (AMs).

        Return a list of dicts. Each dict has keys gid, urn, hrn, url.
        """
        self.logger.info("Called ListComponents")
        filter = ['SERVICE_CERT', 'SERVICE_URN', 'SERVICE_URL']
        options = dict(filter=filter)
        get_aggregates_result = \
            self._ch_handler.lookup_aggregates(options)
        if get_aggregates_result['code'] != NO_ERROR:
            return get_aggregates_result
        aggregates = get_aggregates_result['value']
        components = []
        for aggregate in aggregates:
            gid_file = aggregate['SERVICE_CERT']
            urn = aggregate['SERVICE_URN']
            url = aggregate['SERVICE_URL']
            sfa_hrn,sfa_type = gcf.sfa.util.xrn.urn_to_hrn(urn)
            # Clean up the HRN
            hrn = sfa_hrn.replace('\\', '')
            # Load the certificate from file
            try:
                with open(gid_file, 'r') as f:
                    gid = f.read()
            except:
                msg = 'ListComponents: gid file %r cannot be read.'
                msg = msg % (gid_file)
                user_email = get_email_from_cert(client_cert)
                chapi_error(PGCH_LOG_PREFIX, msg, {'user': user_email})
                gid = ''
            component = {'gid' : gid, 'urn' : urn, 'hrn' : hrn, 'url' : url}
            components.append(component)
        return self._successReturn(components)
Example #2
0
    def ListComponents(self, client_cert, args):
        """Get the list of CMs (AMs).

        Return a list of dicts. Each dict has keys gid, urn, hrn, url.
        """
        self.logger.info("Called ListComponents")
        filter = ['SERVICE_CERT', 'SERVICE_URN', 'SERVICE_URL']
        options = dict(filter=filter)
        get_aggregates_result = \
            self._ch_handler.lookup_aggregates(options)
        if get_aggregates_result['code'] != NO_ERROR:
            return get_aggregates_result
        aggregates = get_aggregates_result['value']
        components = []
        for aggregate in aggregates:
            gid_file = aggregate['SERVICE_CERT']
            urn = aggregate['SERVICE_URN']
            url = aggregate['SERVICE_URL']
            sfa_hrn, sfa_type = gcf.sfa.util.xrn.urn_to_hrn(urn)
            # Clean up the HRN
            hrn = sfa_hrn.replace('\\', '')
            # Load the certificate from file
            try:
                with open(gid_file, 'r') as f:
                    gid = f.read()
            except:
                msg = 'ListComponents: gid file %r cannot be read.'
                msg = msg % (gid_file)
                user_email = get_email_from_cert(client_cert)
                chapi_error(PGCH_LOG_PREFIX, msg, {'user': user_email})
                gid = ''
            component = {'gid': gid, 'urn': urn, 'hrn': hrn, 'url': url}
            components.append(component)
        return self._successReturn(components)
Example #3
0
    def GetVersion(self, client_cert):
        self.logger.info("Called GetVersion")

        user_email = get_email_from_cert(client_cert)
        # Load the authority from the config
        config = pm.getService('config')
        authority = config.get('chrm.authority')

        # Which API? What is the right value?
        API_VERSION = 1
        CH_HOSTNAME = authority

        # Read code tag from a file
        code_tag = get_code_tag(PGCH_LOG_PREFIX)

        # Templated URN. Should we get this from
        # the authority certificate?
        urn = 'urn:publicid:IDN+' + CH_HOSTNAME + '+authority+ch'

        # At present there are no peers
        peers = dict()
        version = dict(peers=peers,
                       api=API_VERSION,
                       urn=urn,
                       hrn=CH_HOSTNAME,
                       url='https://' + CH_HOSTNAME + '/PGCH',
                       interface='registry',
                       code_tag=code_tag,
                       hostname=CH_HOSTNAME)
        return self._successReturn(version)
Example #4
0
    def GetVersion(self, client_cert):
        self.logger.info("Called GetVersion")

        user_email = get_email_from_cert(client_cert)
        # Load the authority from the config
        config = pm.getService('config')
        authority = config.get('chrm.authority')

        # Which API? What is the right value?
        API_VERSION = 1
        CH_HOSTNAME = authority

        # Read code tag from a file
        code_tag = get_code_tag(PGCH_LOG_PREFIX)

        # Templated URN. Should we get this from
        # the authority certificate?
        urn = 'urn:publicid:IDN+' + CH_HOSTNAME + '+authority+ch'

        # At present there are no peers
        peers = dict()
        version = dict(peers=peers,
                       api=API_VERSION,
                       urn=urn,
                       hrn=CH_HOSTNAME,
                       url='https://' + CH_HOSTNAME + '/PGCH',
                       interface='registry',
                       code_tag=code_tag,
                       hostname=CH_HOSTNAME)
        return self._successReturn(version)
Example #5
0
    def GetKeys(self, client_cert, args):
        # cred is user cred
        # return list( of dict(type='ssh', key=$key))
        # args: credential, optional: member_urn

        self.logger.info("Called GetKeys")

        creds = []
        if 'credential' in args:
            credential = args['credential']
            creds = [credential]
            if isinstance(credential, str) or isinstance(credential, unicode):
                creds = [{'geni_type': 'geni_sfa', 'geni_value': credential}]

        if 'member_urn' in args and args[
                'member_urn'] is not None and args['member_urn'].strip() != "":
            member_urn = args['member_urn']
            self.logger.debug("Got member_urn arg %s", member_urn)
        else:
            member_urn = get_urn_from_cert(client_cert)

        options = {
            'match': {
                'KEY_MEMBER': member_urn
            },
            "filter": ['KEY_PUBLIC']
        }
        ssh_keys_result = \
            self._ma_handler.lookup_keys(creds, options)
        #        print "SSH_KEYS_RESULT = " + str(ssh_keys_result)
        if ssh_keys_result['code'] != NO_ERROR:
            return ssh_keys_result

        ssh_keys_value = ssh_keys_result['value']
        if not ssh_keys_value or \
                not ssh_keys_value.has_key(member_urn):
            user_email = get_email_from_cert(client_cert)
            msg = "GetKeys: No entry or keys found for member %s from lookup_keys" % member_urn
            chapi_warn(PGCH_LOG_PREFIX, msg, {'user': user_email})
            keys = []
#            raise CHAPIv1ServerError(msg)
        else:
            keys = [{'type' : 'ssh' , 'key' : ssh_key['KEY_PUBLIC']} \
                        for ssh_key in ssh_keys_value[member_urn]]

        return self._successReturn(keys)
Example #6
0
    def GetKeys(self, client_cert, args):
        # cred is user cred
        # return list( of dict(type='ssh', key=$key))
        # args: credential, optional: member_urn

        self.logger.info("Called GetKeys")

        creds = []
        if 'credential' in args:
            credential = args['credential']
            creds = [credential]
            if isinstance(credential, str) or isinstance(credential, unicode):
                creds = [{'geni_type': 'geni_sfa', 'geni_value': credential}] 

        if 'member_urn' in args and args['member_urn'] is not None and args['member_urn'].strip() != "":
            member_urn = args['member_urn']
            self.logger.debug("Got member_urn arg %s", member_urn)
        else:
            member_urn = get_urn_from_cert(client_cert)

        options = {'match' : {'KEY_MEMBER' : member_urn},
                   "filter" : ['KEY_PUBLIC']
                   }
        ssh_keys_result = \
            self._ma_handler.lookup_keys(creds, options)
#        print "SSH_KEYS_RESULT = " + str(ssh_keys_result)
        if ssh_keys_result['code'] != NO_ERROR:
            return ssh_keys_result

        ssh_keys_value = ssh_keys_result['value']
        if not ssh_keys_value or \
                not ssh_keys_value.has_key(member_urn):
            user_email = get_email_from_cert(client_cert)
            msg = "GetKeys: No entry or keys found for member %s from lookup_keys" % member_urn
            chapi_warn(PGCH_LOG_PREFIX, msg, {'user': user_email})
            keys = []
#            raise CHAPIv1ServerError(msg)
        else:
            keys = [{'type' : 'ssh' , 'key' : ssh_key['KEY_PUBLIC']} \
                        for ssh_key in ssh_keys_value[member_urn]]
        
        return self._successReturn(keys)
Example #7
0
    def Register(self, client_cert, args):
        # Omni uses this, Flack should not for our purposes
        # args are credential, hrn, urn, type
        # cred is user cred, type must be Slice
        # returns slice cred

        user_email = get_email_from_cert(client_cert)
        type = None
        if 'type' in args:
            type = args['type']
        if type and type.lower() != 'slice':
            raise CHAPIv1ArgumentError("PGCH.Register called with non-slice type : %s" % type)

        cred = None
        creds = []
        if 'credential' in args:
            cred = args['credential']
            creds =[{'geni_type' : 'geni_sfa', 'geni_value' : cred} ]

        hrn = None
        if 'hrn' in args: 
            hrn = args['hrn']

        urn = None
        if 'urn' in args:
            urn = args['urn']

        if not urn and not hrn:
            raise CHAPIv1ArgumentError("URN or HRN required for PGCH.Register")

        if hrn and not urn:
            urn = gcf.sfa.util.xrn.hrn_to_urn(hrn, type)

        # Pull out slice name and project_name
        urn_parts = urn.split('+')
        slice_name = urn_parts[len(urn_parts)-1]
        authority = urn_parts[1]
        authority_parts = authority.split(':')
        if len(authority_parts) != 2:
            raise Exception("No project specified in slice urn: " + urn)
        authority = authority_parts[0]
        project_name = authority_parts[1]

        # Get the project_urn
        project_urn = \
            urn_util.URN(authority = authority, type = 'project', \
                             name = project_name).urn_string()

        # Set the slice email name (Bogus but consistent with current CH)
        slice_email = '*****@*****.**' % slice_name

        options = {'fields': {'SLICE_PROJECT_URN' : project_urn,
                              'SLICE_NAME' : slice_name,
                              '_GENI_SLICE_EMAIL' : slice_email }}

        sa = self._sa_handler
        create_slice_return = sa.create_slice(creds, options)
        if create_slice_return['code'] != NO_ERROR:
            return create_slice_return

        # Now get the slice credential so it can be returned
        slice_urn = create_slice_return['value']['SLICE_URN']
        creds_return = sa.get_credentials(slice_urn, creds, {})
        if creds_return['code'] != NO_ERROR:
            return creds_return

        # Locate the SFA credential
        slice_cred = None
        for cred in creds_return['value']:
            if cred['geni_type'] == 'geni_sfa':
                slice_cred = cred['geni_value']
                break
        if slice_cred is None:
            # No SFA credential found!
            raise CHAPIv1ArgumentError('No slice credential available')
        return self._successReturn(slice_cred)
Example #8
0
    def Resolve(self, client_cert, args):
        # Omni uses this, Flack may not need it

        # ID may be a uuid, hrn, or urn
        #   Omni uses hrn for type=User, urn for type=Slice
        # type is Slice or User
        # args: credential, hrn, urn, uuid, type
        # Return is dict:
#When the type is Slice:
#
#{
#  "urn"  : "URN of the slice",
#  "uuid" : "rfc4122 universally unique identifier",
#  "creator_uuid" : "UUID of the user who created the slice",
#  "creator_urn" : "URN of the user who created the slice",
#  "gid"  : "ProtoGENI Identifier (an x509 certificate)",
#  "component_managers" : "List of CM URNs which are known to contain slivers or tickets in this slice. May be stale"
#}
#When the type is User:
#
#{
#  "uid"  : "login (Emulab) ID of the user.",
#  "hrn"  : "Human Readable Name (HRN)",
#  "uuid" : "rfc4122 universally unique identifier",
#  "email": "registered email address",
#  "gid"  : "ProtoGENI Identifier (an x509 certificate)",
#  "name" : "common name",
#}

        user_email = get_email_from_cert(client_cert)
        type = None
        if 'type' in args:
            type = args['type'].lower()
        if type not in ('slice', 'user'):
            raise CHAPIv1ArgumentError("Unknown type for PGH.Resolve: %s" % str(type))

        uuid = None
        if 'uuid' in args:
            uuid = args['uuid']

        urn = None
        if 'urn' in args:
            urn = args['urn']

        hrn = None
        if 'hrn' in args:
            hrn = args['hrn']

        if not hrn and not urn and not uuid:
            raise CHAPIv1ArgumentError("No UUID, URN or HRN identifier provided")

        if hrn and not urn:
            urn = gcf.sfa.util.xrn.hrn_to_urn(hrn, type)

        if type == 'user':
            # User
            ma = self._ma_handler
            match_clause = {'MEMBER_URN' : urn}
            if not urn:
                match_clause = {'MEMBER_UID' : uuid}
            public_filter_clause = ['MEMBER_UID', 'MEMBER_URN',
                                    'MEMBER_USERNAME',
                                    '_GENI_MEMBER_SSL_CERTIFICATE']
            public_options = {"match" : match_clause,
                              "filter" : public_filter_clause}
            creds = []
            lookup_public_return = \
                ma.lookup_public_member_info(creds, public_options)
            if lookup_public_return['code'] != NO_ERROR:
                return lookup_public_return
            public_info = lookup_public_return['value']
            if not public_info or len(public_info.keys()) == 0 or \
                    (urn and not public_info.has_key(urn)):
                # no user by that urn or uuid
                msg = ""
                if urn:
                    msg = "User requested not found: %s" % urn
                else:
                    msg = "User requested not found: %s" % uuid

                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return { 'code' :  ARGUMENT_ERROR , 'value' : {}, 'output' : msg }

            this_urn = public_info.keys()[0]
            public_info = public_info[this_urn]

            # to get a proper display name we need the following
            identifying_filter_clause = ['MEMBER_EMAIL', '_GENI_MEMBER_DISPLAYNAME', 'MEMBER_FIRSTNAME', 'MEMBER_LASTNAME']
            identifying_options = {'match' : match_clause,
                                   'filter' : identifying_filter_clause }
            lookup_identifying_return = \
                ma.lookup_identifying_member_info(creds,
                                                  identifying_options)
            if lookup_identifying_return['code'] != NO_ERROR:
                return lookup_identifying_return
            identifying_info = lookup_identifying_return['value']
            identifying_info = identifying_info[this_urn]

            member_uid = public_info['MEMBER_USERNAME']
            member_hrn = gcf.sfa.util.xrn.urn_to_hrn(public_info['MEMBER_URN'])[0]
            member_uuid = public_info['MEMBER_UID']
            member_email = identifying_info['MEMBER_EMAIL']
            member_gid = None
            if public_info.has_key('_GENI_MEMBER_SSL_CERTIFICATE'):
                member_gid = public_info['_GENI_MEMBER_SSL_CERTIFICATE']
            member_name = get_member_display_name(identifying_info, public_info['MEMBER_URN'])

            # Slices
            sa = self._sa_handler
            lookup_slices_return = sa.lookup_slices_for_member(
                                                               urn, [], {})
            if lookup_slices_return['code'] != NO_ERROR:
                return lookup_slices_return
            slice_info = lookup_slices_return['value']
            slices = []
            for s in slice_info:
                if s['EXPIRED'] == True:
                    continue
                slices.append(s['SLICE_URN'])

            resolve = {'uid' : member_uid,  # login(Emulab) ID of user \
                           'hrn' : member_hrn, \
                           'uuid' : member_uuid, \
                           'email' : member_email, \
                           'gid' : member_gid,
                       'name' : member_name,  # Common Name
                       'slices' : slices
                       }
        else:
            # Slice
            match_clause = {'SLICE_URN' : urn, 'SLICE_EXPIRED' : 'f'} 
            if not urn:
                match_clause = {'SLICE_UID' : uuid}
            filter_clause = ["SLICE_UID", "SLICE_URN", "SLICE_NAME", \
                                 "_GENI_SLICE_OWNER"]
            options = {'match' : match_clause, 'filter' : filter_clause}
            creds = []
            lookup_slices_return = \
                self._sa_handler.lookup_slices(creds, options)

            if lookup_slices_return['code'] != NO_ERROR:
                if lookup_slices_return['code'] == AUTHORIZATION_ERROR:
                    # Only slice members or operators can look up a
                    # slice
                    # So this might mean you are not in the slice, or
                    # not in the project, or the slice does not exist
                    msg = ""
                    if urn:
                        msg = "No slice found or authorization failed (URN %s)" % str(urn)
                    else:
                        msg = "No slice found or authorization failed (UID %s)" % str(uuid)
                    chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                    return { 'code': 12, 'value': {}, 'output': msg} # 12 is what Flack expects for a nonexistent slice
                return lookup_slices_return
            slice_info_dict = lookup_slices_return['value']
            
            if len(slice_info_dict.keys()) == 0:
                msg = ""
                if urn:
                    msg = "No slice found URN %s" % str(urn)
                else:
                    msg = "No slice found UID %s" % str(uuid)
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                return { 'code' : ARGUMENT_ERROR, 'value': {}, 'output': msg}

            slice_key = slice_info_dict.keys()[0]
            slice_info = slice_info_dict[slice_key]
            slice_name = slice_info['SLICE_NAME']
            slice_urn = slice_info['SLICE_URN']
            slice_uuid = slice_info['SLICE_UID']
            creator_uuid = slice_info['_GENI_SLICE_OWNER']

            match_clause = {'MEMBER_UID' : creator_uuid}
            filter_clause = ['MEMBER_URN']
            options = {'match' : match_clause, 'filter' : filter_clause}
            lookup_member_return = \
                self._ma_handler.lookup_public_member_info(creds, options)

            if lookup_member_return['code'] != NO_ERROR:
                return lookup_member_return
            # If the slice owner listed is not in the DB this will
            # give an error, but that is also a DB error
            creator_urn = lookup_member_return['value'].keys()[0]

            options = {}
            get_credentials_return = \
                self._sa_handler.get_credentials(slice_urn, \
                                                     [], options)
            if get_credentials_return['code'] == AUTHORIZATION_ERROR:
                msg = "No slice found for urn %s" % slice_urn
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
            # Return an error with this message
                return { 'code' :  ARGUMENT_ERROR , 'value' : "", 'output' : msg }

            if get_credentials_return['code'] != NO_ERROR:
                return get_credentials_return

            if not get_credentials_return['value'] or \
                    len(get_credentials_return['value']) == 0:
                msg = "No slice found for urn %s" % slice_urn
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return { 'code' :  ARGUMENT_ERROR , 'value' : "", 'output' : msg }

            slice_cred = get_credentials_return['value'][0]['geni_value']
            slice_gid = gid.GID(slice_cred)

            resolve = {'urn' : slice_urn, \
                           'uuid' : slice_uuid, \
                           'creator_uuid' : creator_uuid, \
                           'creator_urn' : creator_urn,  \
                           # PG Identifier (an x509 cert) 
                           'gid' : slice_gid.save_to_string(),   \
                           'component_managers' : []
                       }
                             

        return self._successReturn(resolve)
Example #9
0
    def GetCredential(self, client_cert, args):
        # all none means return user cred
        # else cred is user cred, id is uuid or urn of object, type=Slice
        #    where omni always uses the urn
        # return is slice credential
        #args: credential, type, uuid, urn

        user_email = get_email_from_cert(client_cert)
        # If no args, get a user credential
        if not args:
#             client_uuid = get_uuid_from_cert(client_cert)
#             creds = []
#             options = {"match" : {"MEMBER_UID" : client_uuid},
#                        "fields" : ["_GENI_USER_CREDENTIAL"]}
#             public_info = \
#                 self._ma_handler._delegate.lookup_public_member_info(client_cert, creds, 
#                                                                      options)
#             client_urn = public_info['value'].keys()[0]
#             user_credential = \
#                 public_info['value'][client_urn]['_GENI_USER_CREDENTIAL']

            client_urn = get_urn_from_cert(client_cert)
            creds = self._ma_handler.get_credentials(client_urn, [], {})
            if creds['code'] != NO_ERROR: return creds

            # Extract the SFA user credential from the returned set
            user_credential = None
            for cred in creds['value']:
                if cred is None:
                    continue
                if cred['geni_type'] == 'geni_sfa':
                    user_credential = cred['geni_value']
                    break

            if user_credential is None:
                msg = "User %s got no user credential - try re-downloading your certificate. Used cert: '%s...'" % (client_urn, client_cert[:250])
                chapi_warn(PGCH_LOG_PREFIX, msg,
                          {'user': user_email})
                raise CHAPIv1ServerError(msg)

            return self._successReturn(user_credential)

#        if not args:
#            raise Exception("PGCH.Credential called with args=None")

        cred_type = None
        if 'type' in args:
            cred_type = args['type']
        if cred_type and cred_type.lower() != 'slice':
            raise CHAPIv1ArgumentError("PGCH.GetCredential called with type that isn't slice: %s" % \
                                cred_type)

        slice_uuid = None
        if 'uuid' in args:
            slice_uuid = args['uuid']

        slice_urn = None
        if 'urn' in args:
            slice_urn = args['urn']
            
        credentials = []
        if 'credential' in args:
            credential = args['credential']
            credentials = [{'geni_type' : 'geni_sfa', 'geni_value' : credential}]

        if slice_uuid and not slice_urn:
            # Lookup slice_urn from slice_uuid
            match_clause = {'SLICE_UID' : slice_uuid}
            filter_clause = ["SLICE_URN"]
            creds = []
            options = {'match' : match_clause, 'filter' : filter_clause}
            lookup_slices_return = \
                self._sa_handler.lookup_slices(creds, options)
            if lookup_slices_return['code'] != NO_ERROR:
                return lookup_slices_return
            if not lookup_slices_return or \
                    not lookup_slices_return['value'] or \
                    len(lookup_slices_return['value'].keys()) == 0:
                msg = "No slice found for uid %s" % slice_uuid
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return { 'code' :  ARGUMENT_ERROR , 'value' : "", 'output' : msg }

            slice_urn = lookup_slices_return ['value'].keys()[0]

        if not slice_uuid and not slice_urn:
            raise CHAPIv1ArgumentError("SLICE URN or UUID not provided to PGCH.GetCredential");

        options = {}
        get_credentials_return = \
            self._sa_handler.get_credentials(slice_urn, 
                                             credentials, 
                                             options)
        if get_credentials_return['code'] != NO_ERROR:
            return get_credentials_return

        if not get_credentials_return['value'] or \
                len(get_credentials_return['value']) == 0:
            msg = "No slice found for urn %s" % slice_urn
            chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
            # Return an error with this message
            return { 'code' :  ARGUMENT_ERROR , 'value' : "", 'output' : msg }
        slice_credential = get_credentials_return['value'][0]['geni_value']
        return self._successReturn(slice_credential)
Example #10
0
    def Register(self, client_cert, args):
        # Omni uses this, Flack should not for our purposes
        # args are credential, hrn, urn, type
        # cred is user cred, type must be Slice
        # returns slice cred

        user_email = get_email_from_cert(client_cert)
        type = None
        if 'type' in args:
            type = args['type']
        if type and type.lower() != 'slice':
            raise CHAPIv1ArgumentError(
                "PGCH.Register called with non-slice type : %s" % type)

        cred = None
        creds = []
        if 'credential' in args:
            cred = args['credential']
            creds = [{'geni_type': 'geni_sfa', 'geni_value': cred}]

        hrn = None
        if 'hrn' in args:
            hrn = args['hrn']

        urn = None
        if 'urn' in args:
            urn = args['urn']

        if not urn and not hrn:
            raise CHAPIv1ArgumentError("URN or HRN required for PGCH.Register")

        if hrn and not urn:
            urn = gcf.sfa.util.xrn.hrn_to_urn(hrn, type)

        # Pull out slice name and project_name
        urn_parts = urn.split('+')
        slice_name = urn_parts[len(urn_parts) - 1]
        authority = urn_parts[1]
        authority_parts = authority.split(':')
        if len(authority_parts) != 2:
            raise Exception("No project specified in slice urn: " + urn)
        authority = authority_parts[0]
        project_name = authority_parts[1]

        # Get the project_urn
        project_urn = \
            urn_util.URN(authority = authority, type = 'project', \
                             name = project_name).urn_string()

        # Set the slice email name (Bogus but consistent with current CH)
        slice_email = '*****@*****.**' % slice_name

        options = {
            'fields': {
                'SLICE_PROJECT_URN': project_urn,
                'SLICE_NAME': slice_name,
                '_GENI_SLICE_EMAIL': slice_email
            }
        }

        sa = self._sa_handler
        create_slice_return = sa.create_slice(creds, options)
        if create_slice_return['code'] != NO_ERROR:
            return create_slice_return

        # Now get the slice credential so it can be returned
        slice_urn = create_slice_return['value']['SLICE_URN']
        creds_return = sa.get_credentials(slice_urn, creds, {})
        if creds_return['code'] != NO_ERROR:
            return creds_return

        # Locate the SFA credential
        slice_cred = None
        for cred in creds_return['value']:
            if cred['geni_type'] == 'geni_sfa':
                slice_cred = cred['geni_value']
                break
        if slice_cred is None:
            # No SFA credential found!
            raise CHAPIv1ArgumentError('No slice credential available')
        return self._successReturn(slice_cred)
Example #11
0
    def Resolve(self, client_cert, args):
        # Omni uses this, Flack may not need it

        # ID may be a uuid, hrn, or urn
        #   Omni uses hrn for type=User, urn for type=Slice
        # type is Slice or User
        # args: credential, hrn, urn, uuid, type
        # Return is dict:
        #When the type is Slice:
        #
        #{
        #  "urn"  : "URN of the slice",
        #  "uuid" : "rfc4122 universally unique identifier",
        #  "creator_uuid" : "UUID of the user who created the slice",
        #  "creator_urn" : "URN of the user who created the slice",
        #  "gid"  : "ProtoGENI Identifier (an x509 certificate)",
        #  "component_managers" : "List of CM URNs which are known to contain slivers or tickets in this slice. May be stale"
        #}
        #When the type is User:
        #
        #{
        #  "uid"  : "login (Emulab) ID of the user.",
        #  "hrn"  : "Human Readable Name (HRN)",
        #  "uuid" : "rfc4122 universally unique identifier",
        #  "email": "registered email address",
        #  "gid"  : "ProtoGENI Identifier (an x509 certificate)",
        #  "name" : "common name",
        #}

        user_email = get_email_from_cert(client_cert)
        type = None
        if 'type' in args:
            type = args['type'].lower()
        if type not in ('slice', 'user'):
            raise CHAPIv1ArgumentError("Unknown type for PGH.Resolve: %s" %
                                       str(type))

        uuid = None
        if 'uuid' in args:
            uuid = args['uuid']

        urn = None
        if 'urn' in args:
            urn = args['urn']

        hrn = None
        if 'hrn' in args:
            hrn = args['hrn']

        if not hrn and not urn and not uuid:
            raise CHAPIv1ArgumentError(
                "No UUID, URN or HRN identifier provided")

        if hrn and not urn:
            urn = gcf.sfa.util.xrn.hrn_to_urn(hrn, type)

        if type == 'user':
            # User
            ma = self._ma_handler
            match_clause = {'MEMBER_URN': urn}
            if not urn:
                match_clause = {'MEMBER_UID': uuid}
            public_filter_clause = [
                'MEMBER_UID', 'MEMBER_URN', 'MEMBER_USERNAME',
                '_GENI_MEMBER_SSL_CERTIFICATE'
            ]
            public_options = {
                "match": match_clause,
                "filter": public_filter_clause
            }
            creds = []
            lookup_public_return = \
                ma.lookup_public_member_info(creds, public_options)
            if lookup_public_return['code'] != NO_ERROR:
                return lookup_public_return
            public_info = lookup_public_return['value']
            if not public_info or len(public_info.keys()) == 0 or \
                    (urn and not public_info.has_key(urn)):
                # no user by that urn or uuid
                msg = ""
                if urn:
                    msg = "User requested not found: %s" % urn
                else:
                    msg = "User requested not found: %s" % uuid

                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return {'code': ARGUMENT_ERROR, 'value': {}, 'output': msg}

            this_urn = public_info.keys()[0]
            public_info = public_info[this_urn]

            # to get a proper display name we need the following
            identifying_filter_clause = [
                'MEMBER_EMAIL', '_GENI_MEMBER_DISPLAYNAME', 'MEMBER_FIRSTNAME',
                'MEMBER_LASTNAME'
            ]
            identifying_options = {
                'match': match_clause,
                'filter': identifying_filter_clause
            }
            lookup_identifying_return = \
                ma.lookup_identifying_member_info(creds,
                                                  identifying_options)
            if lookup_identifying_return['code'] != NO_ERROR:
                return lookup_identifying_return
            identifying_info = lookup_identifying_return['value']
            identifying_info = identifying_info[this_urn]

            member_uid = public_info['MEMBER_USERNAME']
            member_hrn = gcf.sfa.util.xrn.urn_to_hrn(
                public_info['MEMBER_URN'])[0]
            member_uuid = public_info['MEMBER_UID']
            member_email = identifying_info['MEMBER_EMAIL']
            member_gid = None
            if public_info.has_key('_GENI_MEMBER_SSL_CERTIFICATE'):
                member_gid = public_info['_GENI_MEMBER_SSL_CERTIFICATE']
            member_name = get_member_display_name(identifying_info,
                                                  public_info['MEMBER_URN'])

            # Slices
            sa = self._sa_handler
            lookup_slices_return = sa.lookup_slices_for_member(urn, [], {})
            if lookup_slices_return['code'] != NO_ERROR:
                return lookup_slices_return
            slice_info = lookup_slices_return['value']
            slices = []
            for s in slice_info:
                if s['EXPIRED'] == True:
                    continue
                slices.append(s['SLICE_URN'])

            resolve = {'uid' : member_uid,  # login(Emulab) ID of user \
                           'hrn' : member_hrn, \
                           'uuid' : member_uuid, \
                           'email' : member_email, \
                           'gid' : member_gid,
                       'name' : member_name,  # Common Name
                       'slices' : slices
                       }
        else:
            # Slice
            match_clause = {'SLICE_URN': urn, 'SLICE_EXPIRED': 'f'}
            if not urn:
                match_clause = {'SLICE_UID': uuid}
            filter_clause = ["SLICE_UID", "SLICE_URN", "SLICE_NAME", \
                                 "_GENI_SLICE_OWNER"]
            options = {'match': match_clause, 'filter': filter_clause}
            creds = []
            lookup_slices_return = \
                self._sa_handler.lookup_slices(creds, options)

            if lookup_slices_return['code'] != NO_ERROR:
                if lookup_slices_return['code'] == AUTHORIZATION_ERROR:
                    # Only slice members or operators can look up a
                    # slice
                    # So this might mean you are not in the slice, or
                    # not in the project, or the slice does not exist
                    msg = ""
                    if urn:
                        msg = "No slice found or authorization failed (URN %s)" % str(
                            urn)
                    else:
                        msg = "No slice found or authorization failed (UID %s)" % str(
                            uuid)
                    chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                    return {
                        'code': 12,
                        'value': {},
                        'output': msg
                    }  # 12 is what Flack expects for a nonexistent slice
                return lookup_slices_return
            slice_info_dict = lookup_slices_return['value']

            if len(slice_info_dict.keys()) == 0:
                msg = ""
                if urn:
                    msg = "No slice found URN %s" % str(urn)
                else:
                    msg = "No slice found UID %s" % str(uuid)
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                return {'code': ARGUMENT_ERROR, 'value': {}, 'output': msg}

            slice_key = slice_info_dict.keys()[0]
            slice_info = slice_info_dict[slice_key]
            slice_name = slice_info['SLICE_NAME']
            slice_urn = slice_info['SLICE_URN']
            slice_uuid = slice_info['SLICE_UID']
            creator_uuid = slice_info['_GENI_SLICE_OWNER']

            match_clause = {'MEMBER_UID': creator_uuid}
            filter_clause = ['MEMBER_URN']
            options = {'match': match_clause, 'filter': filter_clause}
            lookup_member_return = \
                self._ma_handler.lookup_public_member_info(creds, options)

            if lookup_member_return['code'] != NO_ERROR:
                return lookup_member_return
            # If the slice owner listed is not in the DB this will
            # give an error, but that is also a DB error
            creator_urn = lookup_member_return['value'].keys()[0]

            options = {}
            get_credentials_return = \
                self._sa_handler.get_credentials(slice_urn, \
                                                     [], options)
            if get_credentials_return['code'] == AUTHORIZATION_ERROR:
                msg = "No slice found for urn %s" % slice_urn
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return {'code': ARGUMENT_ERROR, 'value': "", 'output': msg}

            if get_credentials_return['code'] != NO_ERROR:
                return get_credentials_return

            if not get_credentials_return['value'] or \
                    len(get_credentials_return['value']) == 0:
                msg = "No slice found for urn %s" % slice_urn
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return {'code': ARGUMENT_ERROR, 'value': "", 'output': msg}

            slice_cred = get_credentials_return['value'][0]['geni_value']
            slice_gid = gid.GID(slice_cred)

            resolve = {'urn' : slice_urn, \
                           'uuid' : slice_uuid, \
                           'creator_uuid' : creator_uuid, \
                           'creator_urn' : creator_urn,  \
                           # PG Identifier (an x509 cert)

                           'gid' : slice_gid.save_to_string(),   \
                           'component_managers' : []
                       }

        return self._successReturn(resolve)
Example #12
0
    def GetCredential(self, client_cert, args):
        # all none means return user cred
        # else cred is user cred, id is uuid or urn of object, type=Slice
        #    where omni always uses the urn
        # return is slice credential
        #args: credential, type, uuid, urn

        user_email = get_email_from_cert(client_cert)
        # If no args, get a user credential
        if not args:
            #             client_uuid = get_uuid_from_cert(client_cert)
            #             creds = []
            #             options = {"match" : {"MEMBER_UID" : client_uuid},
            #                        "fields" : ["_GENI_USER_CREDENTIAL"]}
            #             public_info = \
            #                 self._ma_handler._delegate.lookup_public_member_info(client_cert, creds,
            #                                                                      options)
            #             client_urn = public_info['value'].keys()[0]
            #             user_credential = \
            #                 public_info['value'][client_urn]['_GENI_USER_CREDENTIAL']

            client_urn = get_urn_from_cert(client_cert)
            creds = self._ma_handler.get_credentials(client_urn, [], {})
            if creds['code'] != NO_ERROR: return creds

            # Extract the SFA user credential from the returned set
            user_credential = None
            for cred in creds['value']:
                if cred is None:
                    continue
                if cred['geni_type'] == 'geni_sfa':
                    user_credential = cred['geni_value']
                    break

            if user_credential is None:
                msg = "User %s got no user credential - try re-downloading your certificate. Used cert: '%s...'" % (
                    client_urn, client_cert[:250])
                chapi_warn(PGCH_LOG_PREFIX, msg, {'user': user_email})
                raise CHAPIv1ServerError(msg)

            return self._successReturn(user_credential)

#        if not args:
#            raise Exception("PGCH.Credential called with args=None")

        cred_type = None
        if 'type' in args:
            cred_type = args['type']
        if cred_type and cred_type.lower() != 'slice':
            raise CHAPIv1ArgumentError("PGCH.GetCredential called with type that isn't slice: %s" % \
                                cred_type)

        slice_uuid = None
        if 'uuid' in args:
            slice_uuid = args['uuid']

        slice_urn = None
        if 'urn' in args:
            slice_urn = args['urn']

        credentials = []
        if 'credential' in args:
            credential = args['credential']
            credentials = [{'geni_type': 'geni_sfa', 'geni_value': credential}]

        if slice_uuid and not slice_urn:
            # Lookup slice_urn from slice_uuid
            match_clause = {'SLICE_UID': slice_uuid}
            filter_clause = ["SLICE_URN"]
            creds = []
            options = {'match': match_clause, 'filter': filter_clause}
            lookup_slices_return = \
                self._sa_handler.lookup_slices(creds, options)
            if lookup_slices_return['code'] != NO_ERROR:
                return lookup_slices_return
            if not lookup_slices_return or \
                    not lookup_slices_return['value'] or \
                    len(lookup_slices_return['value'].keys()) == 0:
                msg = "No slice found for uid %s" % slice_uuid
                chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
                # Return an error with this message
                return {'code': ARGUMENT_ERROR, 'value': "", 'output': msg}

            slice_urn = lookup_slices_return['value'].keys()[0]

        if not slice_uuid and not slice_urn:
            raise CHAPIv1ArgumentError(
                "SLICE URN or UUID not provided to PGCH.GetCredential")

        options = {}
        get_credentials_return = \
            self._sa_handler.get_credentials(slice_urn,
                                             credentials,
                                             options)
        if get_credentials_return['code'] != NO_ERROR:
            return get_credentials_return

        if not get_credentials_return['value'] or \
                len(get_credentials_return['value']) == 0:
            msg = "No slice found for urn %s" % slice_urn
            chapi_info(PGCH_LOG_PREFIX, msg, {'user': user_email})
            # Return an error with this message
            return {'code': ARGUMENT_ERROR, 'value': "", 'output': msg}
        slice_credential = get_credentials_return['value'][0]['geni_value']
        return self._successReturn(slice_credential)