Beispiel #1
0
    def shutdown(self, xrn, options={}):
        hrn, _ = urn_to_hrn(xrn)
        top_auth_hrn = top_auth(hrn)
        site_hrn = '.'.join(hrn.split('.')[:-1])
        slice_part = hrn.split('.')[-1]
        if top_auth_hrn == self.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)

        slicename = '_'.join([login_base, slice_part])

        slices = self.shell.GetSlices({
            'peer_id': None,
            'name': slicename
        }, ['slice_id'])
        if not slices:
            raise RecordNotFound(slice_hrn)
        slice_id = slices[0]['slice_id']
        slice_tags = self.shell.GetSliceTags({
            'slice_id': slice_id,
            'tagname': 'enabled'
        })
        if not slice_tags:
            self.shell.AddSliceTag(slice_id, 'enabled', '0')
        elif slice_tags[0]['value'] != "0":
            tag_id = slice_tags[0]['slice_tag_id']
            self.shell.UpdateSliceTag(tag_id, '0')
        return 1
Beispiel #2
0
    def verify_slice(self, slice_hrn, slice_record, sfa_peer, expiration, options=None):
        if options is None: options={}
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        slice_part = slice_hrn.split('.')[-1]
        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)
        slice_name = '_'.join([login_base, slice_part])

        expires = int(datetime_to_epoch(utcparse(expiration)))
        # Filter slices by HRN
        slices = self.driver.shell.GetSlices({'peer_id': None, 'hrn':slice_hrn},
                                             ['slice_id','name','hrn','expires'])
        
        if slices:
            slice = slices[0]
            slice_id = slice['slice_id']
            #Update expiration if necessary
            if slice.get('expires', None) != expires:
                self.driver.shell.UpdateSlice( slice_id, {'expires' : expires})
        else:
            if slice_record:
                url = slice_record.get('url', slice_hrn)
                description = slice_record.get('description', slice_hrn)
            else:
                url = slice_hrn
                description = slice_hrn
            slice = {'name': slice_name,
                     'url': url,
                     'description': description,
                     'hrn': slice_hrn,
                     'sfa_created': 'True',
                     #'expires': expires,
            }
            # add the slice
            slice_id = self.driver.shell.AddSlice(slice)
            # plcapi tends to mess with the incoming hrn so let's make sure
            self.driver.shell.SetSliceHrn (slice_id, slice_hrn)
            # cannot be set with AddSlice
            # set the expiration
            self.driver.shell.UpdateSlice(slice_id, {'expires': expires})

        return self.driver.shell.GetSlices(slice_id)[0]
Beispiel #3
0
    def verify_site(self, slice_xrn, slice_record=None, sfa_peer=None, options=None):
        if slice_record is None: slice_record={}
        if options is None: options={}
        (slice_hrn, type) = urn_to_hrn(slice_xrn)
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)

        # filter sites by hrn
        sites = self.driver.shell.GetSites({'peer_id': None, 'hrn':site_hrn},
                                           ['site_id','name','abbreviated_name','login_base','hrn'])

        # alredy exists
        if sites:
            site = sites[0]
        else:
            # create new site record
            site = {'name': 'sfa:%s' % site_hrn,
                    'abbreviated_name': site_hrn,
                    'login_base': login_base,
                    'max_slices': 100,
                    'max_slivers': 1000,
                    'enabled': True,
                    'peer_site_id': None,
                    'hrn':site_hrn,
                    'sfa_created': 'True',
            }
            site_id = self.driver.shell.AddSite(site)
            # plcapi tends to mess with the incoming hrn so let's make sure
            self.driver.shell.SetSiteHrn (site_id, site_hrn)
            site['site_id'] = site_id
            # exempt federated sites from monitor policies
            self.driver.shell.AddSiteTag(site_id, 'exempt_site_until', "20200101")

        return site
Beispiel #4
0
    def shutdown (self, xrn, options={}):
        hrn, _ = urn_to_hrn(xrn)
        top_auth_hrn = top_auth(hrn)
        site_hrn = '.'.join(hrn.split('.')[:-1])
        slice_part = hrn.split('.')[-1]
        if top_auth_hrn == self.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)

        slicename = '_'.join([login_base, slice_part])

        slices = self.shell.GetSlices({'peer_id': None, 'name': slicename}, ['slice_id'])
        if not slices:
            raise RecordNotFound(slice_hrn)
        slice_id = slices[0]['slice_id']
        slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
        if not slice_tags:
            self.shell.AddSliceTag(slice_id, 'enabled', '0')
        elif slice_tags[0]['value'] != "0":
            tag_id = slice_tags[0]['slice_tag_id']
            self.shell.UpdateSliceTag(tag_id, '0')
        return 1
Beispiel #5
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn() 
            top_auth_hrn = top_auth(slice_cred_hrn)
            site_hrn = '.'.join(slice_cred_hrn.split('.')[:-1])
            slice_part = slice_cred_hrn.split('.')[-1]
            if top_auth_hrn == self.hrn:
                login_base = slice_cred_hrn.split('.')[-2][:12]
            else:
                login_base = hash_loginbase(site_hrn)

            slicename = '_'.join([login_base, slice_part])   
            slice_cred_names.append(slicename) 

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            try:
                slice_ids.append(int(sliver_id_parts[0]))
            except ValueError: 
                pass

        if not slice_ids:
             raise Forbidden("sliver urn not provided")

        slices = self.shell.GetSlices(slice_ids)
        sliver_names = [slice['name'] for slice in slices]

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Beispiel #6
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
            top_auth_hrn = top_auth(slice_cred_hrn)
            site_hrn = '.'.join(slice_cred_hrn.split('.')[:-1])
            slice_part = slice_cred_hrn.split('.')[-1]
            if top_auth_hrn == self.hrn:
                login_base = slice_cred_hrn.split('.')[-2][:12]
            else:
                login_base = hash_loginbase(site_hrn)

            slicename = '_'.join([login_base, slice_part])
            slice_cred_names.append(slicename)

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            try:
                slice_ids.append(int(sliver_id_parts[0]))
            except ValueError:
                pass

        if not slice_ids:
            raise Forbidden("sliver urn not provided")

        slices = self.shell.GetSlices(slice_ids)
        sliver_names = [slice['name'] for slice in slices]

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Beispiel #7
0
    def verify_persons(self, slice_hrn, slice_record, users, sfa_peer, options=None):
        if options is None: options={}

        # first we annotate the incoming users arg with a 'hrn' key
        for user in users:
           user['hrn'], _ = urn_to_hrn(user['urn'])
        # this is for retrieving users from a hrn
        users_by_hrn = { user['hrn'] : user for user in users }

        for user in users: logger.debug("incoming user %s"%user)

        # compute the hrn's for the authority and site
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        slice_part = slice_hrn.split('.')[-1]
        # deduce login_base and slice_name
        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)
        slice_name = '_'.join([login_base, slice_part])

        # locate the site object
        # due to a limitation in PLCAPI, we have to specify 'hrn' as part of the return fields
        site = self.driver.shell.GetSites ({'peer_id':None, 'hrn':site_hrn}, ['site_id','hrn'])[0]
        site_id = site['site_id']

        # locate the slice object
        slice = self.driver.shell.GetSlices ({'peer_id':None, 'hrn':slice_hrn}, ['slice_id','hrn','person_ids'])[0]
        slice_id = slice['slice_id']
        slice_person_ids = slice['person_ids']

        # the common set of attributes for our calls to GetPersons
        person_fields = ['person_id','email','hrn']

        # for the intended set of hrns, locate existing persons
        target_hrns = [ user['hrn'] for user in users ]
        target_existing_persons = self.driver.shell.GetPersons ({'peer_id':None, 'hrn': target_hrns}, person_fields)
        target_existing_person_ids = [ person ['person_id'] for person in target_existing_persons ]
        # find out the hrns that *do not* have a corresponding person
        existing_hrns = [ person['hrn'] for person in target_existing_persons ]
        tocreate_hrns = set (target_hrns) - set (existing_hrns)
        # create these
        target_created_person_ids = [ self.create_person_from_user (users_by_hrn[hrn], site_id) for hrn in tocreate_hrns ]

        # we can partition the persons of interest into one of these 3 classes
        add_person_ids  = set(target_created_person_ids) | set(target_existing_person_ids) - set(slice_person_ids)
        keep_person_ids = set(target_existing_person_ids) & set(slice_person_ids)
        del_person_ids  = set(slice_person_ids) - set(target_existing_person_ids)

        # delete 
        for person_id in del_person_ids:
            self.driver.shell.DeletePersonFromSlice (person_id, slice_id)

        # about the last 2 sets, for managing keys, we need to trace back person_id -> user
        # and for this we need all the Person objects; we already have the target_existing ones
        # also we avoid issuing a call if possible
        target_created_persons = [] if not target_created_person_ids \
                                 else self.driver.shell.GetPersons \
                                      ({'peer_id':None, 'person_id':target_created_person_ids}, person_fields)
        persons_by_person_id = { person['person_id'] : person \
                                 for person in target_existing_persons + target_created_persons }

        def user_by_person_id (person_id):
            person = persons_by_person_id [person_id]
            hrn = person ['hrn']
            return users_by_hrn [hrn]
        
        persons_to_verify_keys = {}
        # add 
        for person_id in add_person_ids:
            self.driver.shell.AddPersonToSlice(person_id, slice_id)
            persons_to_verify_keys[person_id] = user_by_person_id(person_id)
        # Update kept persons
        for person_id in keep_person_ids:
            persons_to_verify_keys[person_id] = user_by_person_id(person_id)
        self.verify_keys(persons_to_verify_keys, options)

        # return hrns of the newly added persons

        return [ persons_by_person_id[person_id]['hrn'] for person_id in add_person_ids ]
Beispiel #8
0
    def verify_slice_leases(self, slice, rspec_requested_leases):

        leases = self.driver.shell.GetLeases({'name':slice['name'], 'clip':int(time.time())}, 
                                             ['lease_id','name', 'hostname', 't_from', 't_until'])
        grain = self.driver.shell.GetLeaseGranularity()

        requested_leases = []
        for lease in rspec_requested_leases:
             requested_lease = {}
             slice_hrn, _ = urn_to_hrn(lease['slice_id'])

             top_auth_hrn = top_auth(slice_hrn)
             site_hrn = '.'.join(slice_hrn.split('.')[:-1])
             slice_part = slice_hrn.split('.')[-1]
             if top_auth_hrn == self.driver.hrn:
                 login_base = slice_hrn.split('.')[-2][:12]
             else:
                 login_base = hash_loginbase(site_hrn)

             slice_name = '_'.join([login_base, slice_part])

             if slice_name != slice['name']:
                 continue
             elif Xrn(lease['component_id']).get_authority_urn().split(':')[0] != self.driver.hrn:
                 continue

             hostname = xrn_to_hostname(lease['component_id'])
             # fill the requested node with nitos ids
             requested_lease['name'] = slice['name']
             requested_lease['hostname'] = hostname
             requested_lease['t_from'] = int(lease['start_time'])
             requested_lease['t_until'] = int(lease['duration']) * grain + int(lease['start_time'])
             requested_leases.append(requested_lease)



        # prepare actual slice leases by lease_id  
        leases_by_id = {}
        for lease in leases:
             leases_by_id[lease['lease_id']] = {'name': lease['name'], 'hostname': lease['hostname'], \
                                                't_from': lease['t_from'], 't_until': lease['t_until']}
        
        added_leases = []
        kept_leases_id = []
        deleted_leases_id = []
        for lease_id in leases_by_id:
             if leases_by_id[lease_id] not in requested_leases:
                 deleted_leases_id.append(lease_id)
             else:
                 kept_leases_id.append(lease_id)
                 requested_leases.remove(leases_by_id[lease_id])
        added_leases = requested_leases
   

        try:
            self.driver.shell.DeleteLeases(deleted_leases_id)
            for lease in added_leases:
                self.driver.shell.AddLeases(lease['hostname'], slice['name'], lease['t_from'], lease['t_until'])

        except: 
            logger.log_exc('Failed to add/remove slice leases')

        return leases
Beispiel #9
0
    def verify_persons(self,
                       slice_hrn,
                       slice_record,
                       users,
                       sfa_peer,
                       options={}):
        top_auth_hrn = top_auth(slice_hrn)
        site_hrn = '.'.join(slice_hrn.split('.')[:-1])
        slice_part = slice_hrn.split('.')[-1]
        users_by_hrn = {}
        for user in users:
            user['hrn'], _ = urn_to_hrn(user['urn'])
            users_by_hrn[user['hrn']] = user

        if top_auth_hrn == self.driver.hrn:
            login_base = slice_hrn.split('.')[-2][:12]
        else:
            login_base = hash_loginbase(site_hrn)

        slice_name = '_'.join([login_base, slice_part])

        persons = self.driver.shell.GetPersons({'peer_id': None},
                                               ['person_id', 'email', 'hrn'])
        sites = self.driver.shell.GetSites({'peer_id': None}, [
            'node_ids', 'site_id', 'name', 'person_ids', 'slice_ids',
            'login_base', 'hrn'
        ])
        site = [site for site in sites if site['hrn'] == site_hrn][0]
        slices = self.driver.shell.GetSlices({'peer_id': None}, [
            'slice_id', 'node_ids', 'person_ids', 'expires', 'site_id', 'name',
            'hrn'
        ])
        slice = [slice for slice in slices if slice['hrn'] == slice_hrn][0]
        slice_persons = self.driver.shell.GetPersons(
            {
                'peer_id': None,
                'person_id': slice['person_ids']
            }, ['person_id', 'email', 'hrn'])

        persons_by_hrn = {}
        persons_by_email = {}
        for person in persons:
            persons_by_hrn[person['hrn']] = person
            persons_by_email[person['email']] = person
        slice_persons_by_hrn = {}
        for slice_person in slice_persons:
            slice_persons_by_hrn[slice_person['hrn']] = slice_person

        # sort persons by HRN
        persons_to_add = set(users_by_hrn.keys()).difference(
            slice_persons_by_hrn.keys())
        persons_to_delete = set(slice_persons_by_hrn.keys()).difference(
            users_by_hrn.keys())
        persons_to_keep = set(users_by_hrn.keys()).intersection(
            slice_persons_by_hrn.keys())

        persons_to_verify_keys = {}

        # Add persons or add persons to slice
        for person_hrn in persons_to_add:
            person_email = users_by_hrn[person_hrn].get(
                'email', "*****@*****.**" % person_hrn.split('.')[-1])
            if person_email and person_email in persons_by_email.keys():
                # check if the user already exist in PL
                person_id = persons_by_email[person_email]['person_id']
                self.driver.shell.AddPersonToSlice(person_id,
                                                   slice['slice_id'])
                persons_to_verify_keys[person_id] = users_by_hrn[person_hrn]

            else:
                person = {
                    'first_name':
                    person_hrn,
                    'last_name':
                    person_hrn,
                    'email':
                    users_by_hrn[person_hrn].get(
                        'email', "*****@*****.**" % person_hrn.split('.')[-1]),
                }

                person_id = self.driver.shell.AddPerson(person)
                self.driver.shell.AddRoleToPerson('user', int(person_id))
                # enable the account
                self.driver.shell.UpdatePerson(int(person_id),
                                               {'enabled': True})
                self.driver.shell.SetPersonSfaCreated(int(person_id), 'True')
                self.driver.shell.AddPersonToSite(int(person_id),
                                                  site['site_id'])
                self.driver.shell.AddPersonToSlice(int(person_id),
                                                   slice['slice_id'])
                self.driver.shell.SetPersonHrn(int(person_id), person_hrn)

                # Add keys
                for key in users_by_hrn[person_hrn].get('keys', []):
                    key = {'key': key, 'key_type': 'ssh'}
                    self.driver.shell.AddPersonKey(person_id, key)

        # Delete persons from slice
        for person_hrn in persons_to_delete:
            person_id = slice_persons_by_hrn[person_hrn].get('person_id')
            slice_id = slice['slice_id']
            self.driver.shell.DeletePersonFromSlice(person_id, slice_id)

        # Update kept persons
        for person_hrn in persons_to_keep:
            person_id = slice_persons_by_hrn[person_hrn].get('person_id')
            persons_to_verify_keys[person_id] = users_by_hrn[person_hrn]

        self.verify_keys(persons_to_verify_keys, options)

        return persons_to_add
Beispiel #10
0
    def verify_slice_leases(self, slice, rspec_requested_leases):

        leases = self.driver.shell.GetLeases(
            {
                'name': slice['name'],
                'clip': int(time.time())
            }, ['lease_id', 'name', 'hostname', 't_from', 't_until'])
        grain = self.driver.shell.GetLeaseGranularity()

        requested_leases = []
        for lease in rspec_requested_leases:
            requested_lease = {}
            slice_hrn, _ = urn_to_hrn(lease['slice_id'])

            top_auth_hrn = top_auth(slice_hrn)
            site_hrn = '.'.join(slice_hrn.split('.')[:-1])
            slice_part = slice_hrn.split('.')[-1]
            if top_auth_hrn == self.driver.hrn:
                login_base = slice_hrn.split('.')[-2][:12]
            else:
                login_base = hash_loginbase(site_hrn)

            slice_name = '_'.join([login_base, slice_part])

            if slice_name != slice['name']:
                continue
            elif Xrn(lease['component_id']).get_authority_urn().split(
                    ':')[0] != self.driver.hrn:
                continue

            hostname = xrn_to_hostname(lease['component_id'])
            # fill the requested node with nitos ids
            requested_lease['name'] = slice['name']
            requested_lease['hostname'] = hostname
            requested_lease['t_from'] = int(lease['start_time'])
            requested_lease['t_until'] = int(lease['duration']) * grain + int(
                lease['start_time'])
            requested_leases.append(requested_lease)

        # prepare actual slice leases by lease_id
        leases_by_id = {}
        for lease in leases:
            leases_by_id[lease['lease_id']] = {'name': lease['name'], 'hostname': lease['hostname'], \
                                               't_from': lease['t_from'], 't_until': lease['t_until']}

        added_leases = []
        kept_leases_id = []
        deleted_leases_id = []
        for lease_id in leases_by_id:
            if leases_by_id[lease_id] not in requested_leases:
                deleted_leases_id.append(lease_id)
            else:
                kept_leases_id.append(lease_id)
                requested_leases.remove(leases_by_id[lease_id])
        added_leases = requested_leases

        try:
            self.driver.shell.DeleteLeases(deleted_leases_id)
            for lease in added_leases:
                self.driver.shell.AddLeases(lease['hostname'], slice['name'],
                                            lease['t_from'], lease['t_until'])

        except:
            logger.log_exc('Failed to add/remove slice leases')

        return leases