def verify_users(self, slice_hrn, slice_record, users, options={}): slice_name = hrn_to_unigetestbed_slicename(slice_hrn) users_by_email = {} for user in users: user['urn'] = user['urn'].lower() hrn, type = urn_to_hrn(user['urn']) username = get_leaf(hrn) user['username'] = username if 'email' in user: user['email'] = user['email'].lower() users_by_email[user['email']] = user # start building a list of existing users existing_users_by_email = {} existing_slice_users_by_email = {} existing_users = self.driver.shell.GetUsers() existing_slice_users_ids = self.driver.shell.GetSlices( {'slice_name': slice_name})[0]['user_ids'] for user in existing_users: existing_users_by_email[user['email']] = user if user['user_id'] in existing_slice_users_ids: existing_slice_users_by_email[user['email']] = user add_users_by_email = set(users_by_email).difference( existing_slice_user_by_email) delete_users_by_email = set(existing_slice_user_by_email).difference( users_by_email) try: for user in add_users_by_email: self.driver.shell.AddUser() except: pass
def verify_users(self, slice_hrn, slice_record, users, options={}): slice_name = hrn_to_dummy_slicename(slice_hrn) users_by_email = {} for user in users: user['urn'] = user['urn'].lower() hrn, type = urn_to_hrn(user['urn']) username = get_leaf(hrn) user['username'] = username if 'email' in user: user['email'] = user['email'].lower() users_by_email[user['email']] = user # start building a list of existing users existing_users_by_email = {} existing_slice_users_by_email = {} existing_users = self.driver.shell.GetUsers() existing_slice_users_ids = self.driver.shell.GetSlices({'slice_name': slice_name})[0]['user_ids'] for user in existing_users: existing_users_by_email[user['email']] = user if user['user_id'] in existing_slice_users_ids: existing_slice_users_by_email[user['email']] = user add_users_by_email = set(users_by_email).difference(existing_slice_user_by_email) delete_users_by_email = set(existing_slice_user_by_email).difference(users_by_email) try: for user in add_users_by_email: self.driver.shell.AddUser() except: pass
def add_nodes(xml, nodes, rspec_content_type=None): node_elems = [] for node in nodes: node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive'] node_elem = xml.add_instance('node', node, node_fields) node_elems.append(node_elem) # set component name if node.get('component_id'): component_name = Xrn.unescape(get_leaf(Xrn(node['component_id']).get_hrn())) node_elem.set('component_name', component_name) # set hardware types if node.get('hardware_types'): for hardware_type in node.get('hardware_types', []): node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields) # set location if node.get('location'): node_elem.add_instance('location', node['location'], Location.fields) # set granularity if node.get('exclusive') == "true": granularity = node.get('granularity') node_elem.add_instance('granularity', granularity, granularity.fields) # set interfaces PGv2Interface.add_interfaces(node_elem, node.get('interfaces')) #if node.get('interfaces'): # for interface in node.get('interfaces', []): # node_elem.add_instance('interface', interface, ['component_id', 'client_id']) # set available element if node.get('available'): available_elem = node_elem.add_element('available', now=node['available']) # add services PGv2Services.add_services(node_elem, node.get('services', [])) # add slivers slivers = node.get('slivers', []) if not slivers: # we must still advertise the available sliver types if node.get('sliver_type'): slivers = Sliver({'type': node['sliver_type']}) else: # Planet lab slivers = Sliver({'type': 'plab-vserver'}) # we must also advertise the available initscripts slivers['tags'] = [] if node.get('pl_initscripts'): for initscript in node.get('pl_initscripts', []): slivers['tags'].append({'name': 'initscript', 'value': initscript['name']}) PGv2SliverType.add_slivers(node_elem, slivers) # advertise the node tags tags = node.get('tags', []) if tags: for tag in tags: tag['name'] = tag.pop('tagname') node_elem.add_instance('{%s}attribute' % xml.namespaces['planetlab'], tag, ['name', 'value']) # add sliver tag in Request Rspec #if rspec_content_type == "request": # node_elem.add_instance('sliver', '', []) return node_elems
def get_auth_filenames(self, xrn): hrn, type = urn_to_hrn(xrn) leaf = get_leaf(hrn) parent_hrn = get_authority(hrn) directory = os.path.join(self.basedir, hrn.replace(".", "/")) gid_filename = os.path.join(directory, leaf+".gid") privkey_filename = os.path.join(directory, leaf+".pkey") return (directory, gid_filename, privkey_filename)
def get_auth_filenames(self, xrn): hrn, type = urn_to_hrn(xrn) if '\\' in hrn: hrn = hrn.replace('\\', '') leaf = hrn else: leaf = get_leaf(hrn) parent_hrn = get_authority(hrn) directory = os.path.join(self.basedir, hrn.replace(".", "/")) gid_filename = os.path.join(directory, leaf+".gid") privkey_filename = os.path.join(directory, leaf+".pkey") return (directory, gid_filename, privkey_filename)
def register (self, sfa_record, hrn, pub_key=None): ''' Register a new object (record) within the registry. In addition to being stored at the SFA level, the appropriate records will also be created at the testbed level. The supported object types are: node, slice, user :param sfa_record: SFA record of the entity being registered. It must contain at least: { 'name':'name_of_the_entity', 'type':'type_of_the_entity' 'group':'group_entity_belongs_to' } :type dict :param hrn: hrn of the resource being registered :type string :param pub_key: public key of the user (if apply) :type string :returns C-Lab identifier (id) of the created entity :rtype int ''' print "Register method in ClabRegistry" # Get name of the entity being registered entity_name = sfa_record.get('name', get_leaf(hrn)) if sfa_record['type'] == 'node': try: node_id = self.driver.testbed_shell.get_node_by(node_name=entity_name).get('id', None) except Exception: # Create the node if does not exist node_id = self.driver.testbed_shell.create_node(entity_name, sfa_record).get('id', None) return node_id elif sfa_record['type'] == 'slice': try: slice_id = self.driver.testbed_shell.get_slice_by(slice_name=entity_name).get('id', None) except Exception: # Create the slice if does not exist print "Calling shell.create_slice with name %s"%(entity_name) print sfa_record slice_id = self.driver.testbed_shell.create_slice(entity_name, fields=sfa_record).get('id', None) return slice_id elif sfa_record['type'] == 'user': try: user_id = self.driver.testbed_shell.get_users({'name':entity_name})[0].get('id', None) except Exception: # Create the user if does not exist print "Calling shell.create_user with name %s"%(entity_name) print sfa_record user_id = self.driver.testbed_shell.create_user(entity_name).get('id', None) return user_id
def delegate(self, opts, args): delegee_hrn = args[0] if opts.delegate_user: user_cred = self.get_user_cred() cred = self.delegate_cred(user_cred, delegee_hrn) elif opts.delegate_slice: slice_cred = self.get_slice_cred(opts.delegate_slice) cred = self.delegate_cred(slice_cred, delegee_hrn) else: self.logger.warning("Must specify either --user or --slice <hrn>") return delegated_cred = Credential(string=cred) object_hrn = delegated_cred.get_gid_object().get_hrn() if opts.delegate_user: dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_" + get_leaf(object_hrn) + ".cred") elif opts.delegate_slice: dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_" + get_leaf(object_hrn) + ".cred") delegated_cred.save_to_file(dest_fn, save_parents=True) self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
def rspec_add_network(self, slice_id, rspec, network): rspec.append(' <network name="%s">' % network) if network in self.resources_by_network: for r in self.resources_by_network[network]: rspec.append(' <node component_id="%s">' % r) rspec.append(' <sliver/>') rspec.append(' </node>') if network in self.leases_by_network: # Group leases by (start_time, duration) lease_groups = {} for l in self.leases_by_network[network]: # Do we need to group ? if isinstance(l, list): print "W: list to dict for lease" l = { 'urn': l[0], 'slice_id': slice_id, 'start_time': l[1], 'duration': l[2] } lease_tuple = (l['start_time'], l['duration']) if lease_tuple in lease_groups: lease_groups[lease_tuple].append(l) else: lease_groups[lease_tuple] = [l] # Create RSpec content for lease_tuple, leases in lease_groups.items(): rspec.append( ' <lease slice_id="%s" start_time="%s" duration="%s">' % (slice_id, lease_tuple[0], lease_tuple[1])) for l in leases: type = Xrn(l['urn']).type if type == 'node': rspec.append(' <node component_id="%s"/>' % l['urn']) elif type == 'channel': rspec.append(' <channel channel_num="%s"/>' % get_leaf(l['urn'])) else: print "W: Ignore element while building rspec" continue rspec.append(' </lease>') rspec.append(' </network>')
def get_ticket(self, opts, args): slice_hrn, rspec_path = args[0], args[1] slice_urn = hrn_to_urn(slice_hrn, 'slice') user_cred = self.get_user_cred() slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True) creds = [slice_cred] if opts.delegate: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) rspec_file = self.get_rspec_file(rspec_path) rspec = open(rspec_file).read() server = self.get_server_from_opts(opts) ticket_string = server.GetTicket(slice_urn, creds, rspec, []) file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket") self.logger.info("writing ticket to %s"%file) ticket = SfaTicket(string=ticket_string) ticket.save_to_file(filename=file, save_parents=True)
def verify_persons(self, slice_hrn, slice_record, users, peer, sfa_peer, append=True): users_by_email = {} users_by_site = defaultdict(list) users_dict = {} for user in users: if 'append' in user and user['append'] == False: append = False if 'email' in user: users_by_email[user['email']] = user users_dict[user['email']] = user elif 'urn' in user: hrn, type = urn_to_hrn(user['urn']) username = get_leaf(hrn) login_base = get_leaf(get_authority(user['urn'])) user['username'] = username users_by_site[login_base].append(user) existing_user_ids = [] if users_by_email: # get existing users by email existing_users = self.api.plshell.GetPersons(self.api.plauth, \ {'email': users_by_email.keys()}, ['person_id', 'key_ids', 'email']) existing_user_ids.extend([user['email'] for user in existing_users]) if users_by_site: # get a list of user sites (based on requeste user urns site_list = self.api.plshell.GetSites(self.api.plauth, users_by_site.keys(), \ ['site_id', 'login_base', 'person_ids']) sites = {} site_user_ids = [] # get all existing users at these sites for site in site_list: sites[site['site_id']] = site site_user_ids.extend(site['person_ids']) existing_site_persons_list = self.api.plshell.GetPersons(self.api.plauth, \ site_user_ids, ['person_id', 'key_ids', 'email', 'site_ids']) # all requested users are either existing users or new (added) users for login_base in users_by_site: requested_site_users = users_by_site[login_base] for requested_user in requested_site_users: user_found = False for existing_user in existing_site_persons_list: for site_id in existing_user['site_ids']: site = sites[site_id] if login_base == site['login_base'] and \ existing_user['email'].startswith(requested_user['username']): existing_user_ids.append(existing_user['email']) users_dict[existing_user['email']] = requested_user user_found = True break if user_found: break if user_found == False: fake_email = requested_user['username'] + '@geni.net' users_dict[fake_email] = requested_user # requested slice users requested_user_ids = users_dict.keys() # existing slice users existing_slice_users_filter = {'person_id': slice_record.get('person_ids', [])} existing_slice_users = self.api.plshell.GetPersons(self.api.plauth, \ existing_slice_users_filter, ['person_id', 'key_ids', 'email']) existing_slice_user_ids = [user['email'] for user in existing_slice_users] # users to be added, removed or updated added_user_ids = set(requested_user_ids).difference(existing_user_ids) added_slice_user_ids = set(requested_user_ids).difference(existing_slice_user_ids) removed_user_ids = set(existing_slice_user_ids).difference(requested_user_ids) updated_user_ids = set(existing_slice_user_ids).intersection(requested_user_ids) # Remove stale users (only if we are not appending). if append == False: for removed_user_id in removed_user_ids: self.api.plshell.DeletePersonFromSlice(self.api.plauth, removed_user_id, slice_record['name']) # update_existing users updated_users_list = [user for user in existing_slice_users if user['email'] in \ updated_user_ids] self.verify_keys(existing_slice_users, updated_users_list, peer, append) added_persons = [] # add new users for added_user_id in added_user_ids: added_user = users_dict[added_user_id] hrn, type = urn_to_hrn(added_user['urn']) person = { 'first_name': added_user.get('first_name', hrn), 'last_name': added_user.get('last_name', hrn), 'email': added_user_id, 'peer_person_id': None, 'keys': [], 'key_ids': added_user.get('key_ids', []), } person['person_id'] = self.api.plshell.AddPerson(self.api.plauth, person) if peer: person['peer_person_id'] = added_user['person_id'] added_persons.append(person) # enable the account self.api.plshell.UpdatePerson(self.api.plauth, person['person_id'], {'enabled': True}) # add person to site self.api.plshell.AddPersonToSite(self.api.plauth, added_user_id, login_base) for key_string in added_user.get('keys', []): key = {'key':key_string, 'key_type':'ssh'} key['key_id'] = self.api.plshell.AddPersonKey(self.api.plauth, person['person_id'], key) person['keys'].append(key) # add the registry record if sfa_peer: peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': sfa_peer, \ 'pointer': person['person_id']} self.registry.register_peer_object(self.credential, peer_dict) for added_slice_user_id in added_slice_user_ids.union(added_user_ids): # add person to the slice self.api.plshell.AddPersonToSlice(self.api.plauth, added_slice_user_id, slice_record['name']) # if this is a peer record then it should already be bound to a peer. # no need to return worry about it getting bound later return added_persons
def get_slice_cred(self, name): file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred") return self.get_cred(file, 'slice', name)
def add_nodes(xml, nodes, rspec_content_type=None): node_elems = [] for node in nodes: node_fields = [ 'component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive' ] node_elem = xml.add_instance('node', node, node_fields) node_elems.append(node_elem) # set component name if node.get('component_id'): component_name = Xrn.unescape( get_leaf(Xrn(node['component_id']).get_hrn())) node_elem.set('component_name', component_name) # set hardware types if node.get('hardware_types'): for hardware_type in node.get('hardware_types', []): node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields) # set location if node.get('location'): node_elem.add_instance('location', node['location'], Location.fields) # set granularity if node.get('exclusive') == "true": granularity = node.get('granularity') node_elem.add_instance('granularity', granularity, granularity.fields) # set interfaces Clabv1Interface.add_interfaces(node_elem, node.get('nodeInterfaces')) # set available element if node.get('available'): available_elem = node_elem.add_element('available', now=node['available']) # add services PGv2Services.add_services(node_elem, node.get('services', [])) # add slivers slivers = node.get('slivers', []) if not slivers: # we must still advertise the available sliver types if node.get('sliver_type'): sliver_elem = node_elem.add_element('sliver_type') sliver_elem.set('name', node['sliver_type']) else: # Add the slivers of the node Clabv1Sliver.add_slivers(node_elem, slivers) # EXTENSION for C-Lab v1 RSpec Nodes # Add group group = node.get('group') if group: group_elem = node_elem.add_element('{%s}group' % xml.namespaces['clab'], name=group['name'], id=group['id']) island = node.get('island') if island: island_elem = node_elem.add_element('{%s}island' % xml.namespaces['clab'], name=island['name'], id=island['id']) # Add Node Network Interfaces #node_ifaces = node.get('nodeInterfaces') #if node_ifaces: # node_ifaces_elem = node_elem.add_element('node_interfaces') # for node_iface in node_ifaces: # node_ifaces_elem.add_element('node_interface', name=node_iface['name'], type=node_iface['type']) # Add Management Network Information mgmt_net = node.get('mgmt_net') if mgmt_net: mgmt_net_elem = node_elem.add_element( '{%s}management_network' % xml.namespaces['clab'], addr=mgmt_net['addr']) return node_elems
def register(self, sfa_record, hrn, pub_key): type = sfa_record['type'] pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record) if type == 'authority': sites = self.shell.GetSites({ 'peer_id': None, 'login_base': pl_record['login_base'] }) if not sites: # xxx when a site gets registered through SFA we need to set its max_slices if 'max_slices' not in pl_record: pl_record['max_slices'] = 2 pointer = self.shell.AddSite(pl_record) self.shell.SetSiteHrn(int(pointer), hrn) else: pointer = sites[0]['site_id'] elif type == 'slice': acceptable_fields = ['url', 'instantiation', 'name', 'description'] for key in pl_record.keys(): if key not in acceptable_fields: pl_record.pop(key) slices = self.shell.GetSlices({ 'peer_id': None, 'name': pl_record['name'] }) if not slices: if not pl_record.get('url', None) or not pl_record.get( 'description', None): pl_record['url'] = hrn pl_record['description'] = hrn pointer = self.shell.AddSlice(pl_record) self.shell.SetSliceHrn(int(pointer), hrn) else: pointer = slices[0]['slice_id'] elif type == 'user': persons = self.shell.GetPersons({ 'peer_id': None, 'email': sfa_record['email'] }) if not persons: for key in ['first_name', 'last_name']: if key not in sfa_record: sfa_record[key] = '*from*sfa*' # AddPerson does not allow everything to be set can_add = [ 'first_name', 'last_name', 'title', 'email', 'password', 'phone', 'url', 'bio' ] add_person_dict = dict([(k, sfa_record[k]) for k in sfa_record if k in can_add]) pointer = self.shell.AddPerson(add_person_dict) self.shell.SetPersonHrn(int(pointer), hrn) else: pointer = persons[0]['person_id'] # enable the person's account self.shell.UpdatePerson(pointer, {'enabled': True}) # add this person to the site login_base = get_leaf(sfa_record['authority']) self.shell.AddPersonToSite(pointer, login_base) # What roles should this user have? roles = [] if 'roles' in sfa_record: # if specified in xml, but only low-level roles roles = [ role for role in sfa_record['roles'] if role in ['user', 'tech'] ] # at least user if no other cluse could be found if not roles: roles = ['user'] for role in roles: self.shell.AddRoleToPerson(role, pointer) # Add the user's key if pub_key: self.shell.AddPersonKey(pointer, { 'key_type': 'ssh', 'key': pub_key }) elif type == 'node': login_base = PlXrn(xrn=sfa_record['authority'], type='authority').pl_login_base() nodes = self.shell.GetNodes({ 'peer_id': None, 'hostname': pl_record['hostname'] }) if not nodes: pointer = self.shell.AddNode(login_base, pl_record) self.shell.SetNodeHrn(int(pointer), hrn) else: pointer = nodes[0]['node_id'] return pointer
def add_nodes(xml, nodes, rspec_content_type=None): network_elems = xml.xpath('//network') if len(network_elems) > 0: network_elem = network_elems[0] elif len(nodes) > 0 and nodes[0].get('component_manager_id'): network_urn = nodes[0]['component_manager_id'] network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn()) else: network_elem = xml node_elems = [] for node in nodes: node_fields = ['component_manager_id', 'component_id', 'boot_state'] node_elem = network_elem.add_instance('node', node, node_fields) node_elems.append(node_elem) # determine network hrn network_hrn = None if 'component_manager_id' in node and node['component_manager_id']: network_hrn = Xrn(node['component_manager_id']).get_hrn() # set component_name attribute and hostname element if 'component_id' in node and node['component_id']: component_name = Xrn.unescape(get_leaf(Xrn(node['component_id']).get_hrn())) node_elem.set('component_name', component_name) hostname_elem = node_elem.add_element('hostname') hostname_elem.set_text(component_name) # set site id if 'authority_id' in node and node['authority_id']: node_elem.set('site_id', node['authority_id']) # add locaiton location = node.get('location') if location: node_elem.add_instance('location', location, Location.fields) # add exclusive tag to distinguish between Reservable and Shared nodes exclusive_elem = node_elem.add_element('exclusive') if node.get('exclusive') and node.get('exclusive') == 'true': exclusive_elem.set_text('TRUE') # add granularity of the reservation system granularity = node.get('granularity') if granularity: node_elem.add_instance('granularity', granularity, granularity.fields) else: exclusive_elem.set_text('FALSE') if isinstance(node.get('interfaces'), list): for interface in node.get('interfaces', []): node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) #if 'bw_unallocated' in node and node['bw_unallocated']: # bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000) PGv2Services.add_services(node_elem, node.get('services', [])) tags = node.get('tags', []) if tags: for tag in tags: # backdoor for FITeagle # Alexander Willner <*****@*****.**> if tag['tagname']=="fiteagle_settings": tag_elem = node_elem.add_element(tag['tagname']) for subtag in tag['value']: subtag_elem = tag_elem.add_element('setting') subtag_elem.set('name', str(subtag['tagname'])) subtag_elem.set('description', str(subtag['description'])) subtag_elem.set_text(subtag['value']) else: tag_elem = node_elem.add_element(tag['tagname']) tag_elem.set_text(tag['value']) SFAv1Sliver.add_slivers(node_elem, node.get('slivers', [])) # add sliver tag in Request Rspec if rspec_content_type == "request": node_elem.add_instance('sliver', '', [])
def register(api, record): hrn, type = record['hrn'], record['type'] urn = hrn_to_urn(hrn,type) # validate the type if type not in ['authority', 'slice', 'node', 'user']: raise UnknownSfaType(type) # check if record already exists table = SfaTable() existing_records = table.find({'type': type, 'hrn': hrn}) if existing_records: raise ExistingRecord(hrn) record = SfaRecord(dict = record) record['authority'] = get_authority(record['hrn']) type = record['type'] hrn = record['hrn'] auth_info = api.auth.get_auth_info(record['authority']) pub_key = None # make sure record has a gid if 'gid' not in record: uuid = create_uuid() pkey = Keypair(create=True) if 'key' in record and record['key']: if isinstance(record['key'], types.ListType): pub_key = record['key'][0] else: pub_key = record['key'] pkey = convert_public_key(pub_key) gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey) gid = gid_object.save_to_string(save_parents=True) record['gid'] = gid record.set_gid(gid) if type in ["authority"]: # update the tree if not api.auth.hierarchy.auth_exists(hrn): api.auth.hierarchy.create_auth(hrn_to_urn(hrn,'authority')) # get the GID from the newly created authority gid = auth_info.get_gid_object() record.set_gid(gid.save_to_string(save_parents=True)) pl_record = api.sfa_fields_to_pl_fields(type, hrn, record) sites = api.plshell.GetSites(api.plauth, [pl_record['login_base']]) if not sites: pointer = api.plshell.AddSite(api.plauth, pl_record) else: pointer = sites[0]['site_id'] record.set_pointer(pointer) record['pointer'] = pointer elif (type == "slice"): acceptable_fields=['url', 'instantiation', 'name', 'description'] pl_record = api.sfa_fields_to_pl_fields(type, hrn, record) for key in pl_record.keys(): if key not in acceptable_fields: pl_record.pop(key) slices = api.plshell.GetSlices(api.plauth, [pl_record['name']]) if not slices: pointer = api.plshell.AddSlice(api.plauth, pl_record) else: pointer = slices[0]['slice_id'] record.set_pointer(pointer) record['pointer'] = pointer elif (type == "user"): persons = api.plshell.GetPersons(api.plauth, [record['email']]) if not persons: pointer = api.plshell.AddPerson(api.plauth, dict(record)) else: pointer = persons[0]['person_id'] if 'enabled' in record and record['enabled']: api.plshell.UpdatePerson(api.plauth, pointer, {'enabled': record['enabled']}) # add this persons to the site only if he is being added for the first # time by sfa and doesont already exist in plc if not persons or not persons[0]['site_ids']: login_base = get_leaf(record['authority']) api.plshell.AddPersonToSite(api.plauth, pointer, login_base) # What roles should this user have? api.plshell.AddRoleToPerson(api.plauth, 'user', pointer) # Add the user's key if pub_key: api.plshell.AddPersonKey(api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key}) elif (type == "node"): pl_record = api.sfa_fields_to_pl_fields(type, hrn, record) login_base = hrn_to_pl_login_base(record['authority']) nodes = api.plshell.GetNodes(api.plauth, [pl_record['hostname']]) if not nodes: pointer = api.plshell.AddNode(api.plauth, login_base, pl_record) else: pointer = nodes[0]['node_id'] record['pointer'] = pointer record.set_pointer(pointer) record_id = table.insert(record) record['record_id'] = record_id # update membership for researchers, pis, owners, operators api.update_membership(None, record) return record.get_gid_object().save_to_string(save_parents=True)
def main(): process_options() config = Config() if not config.SFA_REGISTRY_ENABLED: sys.exit(0) root_auth = config.SFA_REGISTRY_ROOT_AUTH interface_hrn = config.SFA_INTERFACE_HRN keys_filename = config.config_path + os.sep + 'person_keys.py' sfaImporter = sfaImport() if config.SFA_API_DEBUG: sfaImporter.logger.setLevelDebug() shell = sfaImporter.shell plc_auth = sfaImporter.plc_auth # initialize registry db table table = SfaTable() if not table.exists(): table.create() # create root authority sfaImporter.create_top_level_auth_records(root_auth) if not root_auth == interface_hrn: sfaImporter.create_top_level_auth_records(interface_hrn) # create s user record for the slice manager sfaImporter.create_sm_client_record() # create interface records sfaImporter.logger.info("Import: creating interface records") sfaImporter.create_interface_records() # add local root authority's cert to trusted list sfaImporter.logger.info("Import: adding " + interface_hrn + " to trusted list") authority = sfaImporter.AuthHierarchy.get_auth_info(interface_hrn) sfaImporter.TrustedRoots.add_gid(authority.get_gid_object()) # special case for vini if ".vini" in interface_hrn and interface_hrn.endswith('vini'): # create a fake internet2 site first i2site = {'name': 'Internet2', 'abbreviated_name': 'I2', 'login_base': 'internet2', 'site_id': -1} sfaImporter.import_site(interface_hrn, i2site) # create dict of all existing sfa records existing_records = {} existing_hrns = [] key_ids = [] person_keys = {} results = table.find() for result in results: existing_records[(result['hrn'], result['type'])] = result existing_hrns.append(result['hrn']) # Get all plc sites sites = shell.GetSites(plc_auth, {'peer_id': None}) sites_dict = {} for site in sites: sites_dict[site['login_base']] = site # Get all plc users persons = shell.GetPersons(plc_auth, {'peer_id': None, 'enabled': True}, ['person_id', 'email', 'key_ids', 'site_ids']) persons_dict = {} for person in persons: persons_dict[person['person_id']] = person key_ids.extend(person['key_ids']) # Get all public keys keys = shell.GetKeys(plc_auth, {'peer_id': None, 'key_id': key_ids}) keys_dict = {} for key in keys: keys_dict[key['key_id']] = key['key'] # create a dict of person keys keyed on key_id old_person_keys = load_keys(keys_filename) for person in persons: pubkeys = [] for key_id in person['key_ids']: pubkeys.append(keys_dict[key_id]) person_keys[person['person_id']] = pubkeys # Get all plc nodes nodes = shell.GetNodes(plc_auth, {'peer_id': None}, ['node_id', 'hostname', 'site_id']) nodes_dict = {} for node in nodes: nodes_dict[node['node_id']] = node # Get all plc slices slices = shell.GetSlices(plc_auth, {'peer_id': None}, ['slice_id', 'name']) slices_dict = {} for slice in slices: slices_dict[slice['slice_id']] = slice # start importing for site in sites: site_hrn = _get_site_hrn(interface_hrn, site) sfaImporter.logger.info("Importing site: %s" % site_hrn) # import if hrn is not in list of existing hrns or if the hrn exists # but its not a site record if site_hrn not in existing_hrns or \ (site_hrn, 'authority') not in existing_records: sfaImporter.import_site(site_hrn, site) # import node records for node_id in site['node_ids']: if node_id not in nodes_dict: continue node = nodes_dict[node_id] site_auth = get_authority(site_hrn) site_name = get_leaf(site_hrn) hrn = hostname_to_hrn(site_auth, site_name, node['hostname']) if hrn not in existing_hrns or \ (hrn, 'node') not in existing_records: sfaImporter.import_node(hrn, node) # import slices for slice_id in site['slice_ids']: if slice_id not in slices_dict: continue slice = slices_dict[slice_id] hrn = slicename_to_hrn(interface_hrn, slice['name']) if hrn not in existing_hrns or \ (hrn, 'slice') not in existing_records: sfaImporter.import_slice(site_hrn, slice) # import persons for person_id in site['person_ids']: if person_id not in persons_dict: continue person = persons_dict[person_id] hrn = email_to_hrn(site_hrn, person['email']) old_keys = [] new_keys = [] if person_id in old_person_keys: old_keys = old_person_keys[person_id] if person_id in person_keys: new_keys = person_keys[person_id] update_record = False for key in new_keys: if key not in old_keys: update_record = True if hrn not in existing_hrns or \ (hrn, 'user') not in existing_records or update_record: sfaImporter.import_person(site_hrn, person) # remove stale records system_records = [interface_hrn, root_auth, interface_hrn + '.slicemanager'] for (record_hrn, type) in existing_records.keys(): if record_hrn in system_records: continue record = existing_records[(record_hrn, type)] if record['peer_authority']: continue # dont delete vini's internet2 placeholdder record # normally this would be deleted becuase it does not have a plc record if ".vini" in interface_hrn and interface_hrn.endswith('vini') and \ record_hrn.endswith("internet2"): continue found = False if type == 'authority': for site in sites: site_hrn = interface_hrn + "." + site['login_base'] if site_hrn == record_hrn and site['site_id'] == record['pointer']: found = True break elif type == 'user': login_base = get_leaf(get_authority(record_hrn)) username = get_leaf(record_hrn) if login_base in sites_dict: site = sites_dict[login_base] for person in persons: tmp_username = person['email'].split("@")[0] alt_username = person['email'].split("@")[0].replace(".", "_").replace("+", "_") if username in [tmp_username, alt_username] and \ site['site_id'] in person['site_ids'] and \ person['person_id'] == record['pointer']: found = True break elif type == 'slice': slicename = hrn_to_pl_slicename(record_hrn) for slice in slices: if slicename == slice['name'] and \ slice['slice_id'] == record['pointer']: found = True break elif type == 'node': login_base = get_leaf(get_authority(record_hrn)) nodename = Xrn.unescape(get_leaf(record_hrn)) if login_base in sites_dict: site = sites_dict[login_base] for node in nodes: tmp_nodename = node['hostname'] if tmp_nodename == nodename and \ node['site_id'] == site['site_id'] and \ node['node_id'] == record['pointer']: found = True break else: continue if not found: record_object = existing_records[(record_hrn, type)] sfaImporter.delete_record(record_hrn, type) # save pub keys sfaImporter.logger.info('Import: saving current pub keys') save_keys(keys_filename, person_keys)
def register (self, sfa_record, hrn, pub_key): type = sfa_record['type'] pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record) if type == 'authority': sites = self.shell.GetSites([pl_record['login_base']]) if not sites: # xxx when a site gets registered through SFA we need to set its max_slices if 'max_slices' not in pl_record: pl_record['max_slices']=2 pointer = self.shell.AddSite(pl_record) else: pointer = sites[0]['site_id'] elif type == 'slice': acceptable_fields=['url', 'instantiation', 'name', 'description'] for key in pl_record.keys(): if key not in acceptable_fields: pl_record.pop(key) slices = self.shell.GetSlices([pl_record['name']]) if not slices: pointer = self.shell.AddSlice(pl_record) else: pointer = slices[0]['slice_id'] elif type == 'user': persons = self.shell.GetPersons({'email':sfa_record['email']}) if not persons: for key in ['first_name','last_name']: if key not in sfa_record: sfa_record[key]='*from*sfa*' # AddPerson does not allow everything to be set can_add = ['first_name', 'last_name', 'title','email', 'password', 'phone', 'url', 'bio'] add_person_dict=dict ( [ (k,sfa_record[k]) for k in sfa_record if k in can_add ] ) pointer = self.shell.AddPerson(add_person_dict) else: pointer = persons[0]['person_id'] if 'enabled' in sfa_record and sfa_record['enabled']: self.shell.UpdatePerson(pointer, {'enabled': sfa_record['enabled']}) # add this person to the site only if she is being added for the first # time by sfa and doesont already exist in plc if not persons or not persons[0]['site_ids']: login_base = get_leaf(sfa_record['authority']) self.shell.AddPersonToSite(pointer, login_base) # What roles should this user have? roles=[] if 'roles' in sfa_record: # if specified in xml, but only low-level roles roles = [ role for role in sfa_record['roles'] if role in ['user','tech'] ] # at least user if no other cluse could be found if not roles: roles=['user'] for role in roles: self.shell.AddRoleToPerson(role, pointer) # Add the user's key if pub_key: self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key}) elif type == 'node': login_base = PlXrn(xrn=sfa_record['authority'],type='authority').pl_login_base() nodes = self.shell.GetNodes([pl_record['hostname']]) if not nodes: pointer = self.shell.AddNode(login_base, pl_record) else: pointer = nodes[0]['node_id'] return pointer
def add_nodes(xml, nodes, rspec_content_type=None): node_elems = [] for node in nodes: node_fields = [ 'component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive' ] node_elem = xml.add_instance('node', node, node_fields) node_elems.append(node_elem) # set component name if node.get('component_id'): component_name = Xrn.unescape( get_leaf(Xrn(node['component_id']).get_hrn())) node_elem.set('component_name', component_name) # set hardware types if node.get('hardware_types'): for hardware_type in node.get('hardware_types', []): node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields) # set location if node.get('location'): node_elem.add_instance('location', node['location'], Location.fields) # set granularity if node.get('exclusive') == "true": granularity = node.get('granularity') node_elem.add_instance('granularity', granularity, granularity.fields) # set interfaces PGv2Interface.add_interfaces(node_elem, node.get('interfaces')) #if node.get('interfaces'): # for interface in node.get('interfaces', []): # node_elem.add_instance('interface', interface, ['component_id', 'client_id']) # set available element if node.get('available'): available_elem = node_elem.add_element('available', now=node['available']) # add services PGv2Services.add_services(node_elem, node.get('services', [])) # add slivers slivers = node.get('slivers', []) if not slivers: # we must still advertise the available sliver types if node.get('sliver_type'): slivers = Sliver({'type': node['sliver_type']}) else: # Planet lab slivers = Sliver({'type': 'plab-vserver'}) # we must also advertise the available initscripts slivers['tags'] = [] if node.get('pl_initscripts'): for initscript in node.get('pl_initscripts', []): slivers['tags'].append({ 'name': 'initscript', 'value': initscript['name'] }) PGv2SliverType.add_slivers(node_elem, slivers) # advertise the node tags tags = node.get('tags', []) if tags: for tag in tags: tag['name'] = tag.pop('tagname') node_elem.add_instance( '{%s}attribute' % xml.namespaces['planetlab'], tag, ['name', 'value']) # add sliver tag in Request Rspec #if rspec_content_type == "request": # node_elem.add_instance('sliver', '', []) return node_elems