From 4d17883d9210a0bee2572d7c237e2e40d1e66b5c Mon Sep 17 00:00:00 2001 From: Andy Bavier Date: Fri, 3 Sep 2010 17:53:29 +0000 Subject: [PATCH] Make PLCAPI calls as user in Aggregate Manager --- sfa/managers/aggregate_manager_pl.py | 62 ++++++++++++++++++++---- sfa/plc/network.py | 71 ++++++++++++---------------- 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/sfa/managers/aggregate_manager_pl.py b/sfa/managers/aggregate_manager_pl.py index fecc3d77..c80e02bc 100644 --- a/sfa/managers/aggregate_manager_pl.py +++ b/sfa/managers/aggregate_manager_pl.py @@ -23,6 +23,41 @@ from sfa.plc.network import * from sfa.plc.api import SfaAPI from sfa.plc.slices import * +""" +Create a new plauth object that the Aggregate Manager can use to execute +plshell commands as the authenticated user. +""" +def __get_user_plauth(api, registry, credential, creds, operation, hrn): + plauth = None + + user_creds = api.auth.checkCredentials(creds, operation, hrn) + user_cred_obj = Credential(string=user_creds[0]) + + # If user cred has a parent then the caller is the parent's cred. + # This is true for delegated creds. + if user_cred_obj.parent: + user_hrn = user_cred_obj.parent.get_gid_caller().get_hrn() + else: + user_hrn = user_cred_obj.get_gid_caller().get_hrn() + + user_record = registry.Resolve(user_hrn, [credential])[0] + email = user_record['email'] + + person = api.plshell.GetPersons(api.plauth, email) + if person: + person_id = person[0]['person_id'] + # Get the user's session if one exists, create one otherwise + session = api.plshell.GetSessions(api.plauth, {'person_id': person_id}) + if not session: + session = api.plshell.AddSession(api.plauth, person_id) + else: + session = session[0]['session_id'] + + # Create new authentication token + plauth = {'Username':email, 'AuthMethod':'session', 'session':session} + + return plauth + def __get_registry_objects(slice_xrn, creds, users): """ @@ -97,7 +132,6 @@ def create_slice(api, slice_xrn, creds, rspec, users): Create the sliver[s] (slice) at this aggregate. Verify HRN and initialize the slice record in PLC if necessary. """ - reg_objects = __get_registry_objects(slice_xrn, creds, users) hrn, type = urn_to_hrn(slice_xrn) @@ -112,8 +146,12 @@ def create_slice(api, slice_xrn, creds, rspec, users): slice_record = slices.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer, reg_objects) - - network = Network(api) + + user_plauth = __get_user_plauth(api, registry, credential, creds, + "createsliver", hrn) + + # The Network instance will use user_plauth to call the PLCAPI + network = Network(api, user_plauth) slice = network.get_slice(api, hrn) slice.peer_id = slice_record['peer_slice_id'] @@ -131,8 +169,8 @@ def create_slice(api, slice_xrn, creds, rspec, users): if peer: api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice.id, peer) - api.plshell.AddSliceToNodes(api.plauth, slice.name, added_nodes) - api.plshell.DeleteSliceFromNodes(api.plauth, slice.name, deleted_nodes) + api.plshell.AddSliceToNodes(user_plauth, slice.name, added_nodes) + api.plshell.DeleteSliceFromNodes(user_plauth, slice.name, deleted_nodes) network.updateSliceTags() @@ -141,7 +179,6 @@ def create_slice(api, slice_xrn, creds, rspec, users): slice.peer_id) # print network.toxml() - return True @@ -229,23 +266,32 @@ def get_rspec(api, creds, options): xrn = options.get('geni_slice_urn', None) hrn, type = urn_to_hrn(xrn) + """ # look in cache first if api.cache and not xrn: rspec = api.cache.get('nodes') if rspec: return rspec + """ - network = Network(api) + registry = api.registries[api.hrn] + credential = api.getCredential() + user_plauth = __get_user_plauth(api, registry, credential, creds, + "listnodes", hrn) + + # The Network instance will use user_plauth to call the PLCAPI + network = Network(api, user_plauth) if (hrn): if network.get_slice(api, hrn): network.addSlice() rspec = network.toxml() + """ # cache the result if api.cache and not xrn: api.cache.add('nodes', rspec) - + """ return rspec diff --git a/sfa/plc/network.py b/sfa/plc/network.py index d1345bc6..3b16226f 100644 --- a/sfa/plc/network.py +++ b/sfa/plc/network.py @@ -150,10 +150,8 @@ class Slice: return n # Add a new slice tag - def add_tag(self, tagname, value, node = None, role_id = 40): + def add_tag(self, tagname, value, node = None): tt = self.network.lookupTagType(tagname) - if not tt.permit_update(role_id): - raise InvalidRSpec("permission denied to modify '%s' tag" % tagname) tag = Slicetag() tag.initialize(tagname, value, node, self.network) self.network.tags[tag.id] = tag @@ -161,23 +159,21 @@ class Slice: return tag # Update a slice tag if it exists, else add it - def update_tag(self, tagname, value, node = None, role_id = 40): + def update_tag(self, tagname, value, node = None): tag = self.get_tag(tagname, node) if tag: - if not tag.permit_update(role_id, value): - raise InvalidRSpec("permission denied to modify '%s' tag" % tagname) tag.change(value) else: - tag = self.add_tag(tagname, value, node, role_id) + tag = self.add_tag(tagname, value, node) return tag - def update_multi_tag(self, tagname, value, node = None, role_id = 40): + def update_multi_tag(self, tagname, value, node = None): tags = self.get_multi_tag(tagname, node) for tag in tags: if tag and tag.value == value: break else: - tag = self.add_tag(tagname, value, node, role_id) + tag = self.add_tag(tagname, value, node) return tag def tags_to_xml(self, xml, node = None): @@ -211,7 +207,6 @@ class Slicetag: self.value = tag['value'] self.node_id = tag['node_id'] self.category = tag['category'] - self.min_role_id = tag['min_role_id'] self.status = None # Create a new slicetag that will be written to the DB later @@ -227,16 +222,8 @@ class Slicetag: else: self.node_id = None self.category = tt.category - self.min_role_id = tt.min_role_id self.status = "new" - def permit_update(self, role_id, value = None): - if value and self.value == value: - return True - if role_id > self.min_role_id: - return False - return True - def change(self, value): if self.value != value: self.value = value @@ -260,14 +247,18 @@ class Slicetag: def was_updated(self): return (self.status != None) - def write(self, api): - if self.was_added(): - api.plshell.AddSliceTag(api.plauth, self.slice_id, - self.tagname, self.value, self.node_id) - elif self.was_changed(): - api.plshell.UpdateSliceTag(api.plauth, self.id, self.value) - elif self.was_deleted(): - api.plshell.DeleteSliceTag(api.plauth, self.id) + def write(self, api, user_plauth): + try: + if self.was_added(): + api.plshell.AddSliceTag(user_plauth, self.slice_id, + self.tagname, self.value, self.node_id) + elif self.was_changed(): + api.plshell.UpdateSliceTag(user_plauth, self.id, self.value) + elif self.was_deleted(): + api.plshell.DeleteSliceTag(user_plauth, self.id) + except: + raise InvalidRSpec("user cannot modify '%s' tag" % self.tagname) + class TagType: @@ -275,7 +266,6 @@ class TagType: self.id = tagtype['tag_type_id'] self.category = tagtype['category'] self.tagname = tagtype['tagname'] - self.min_role_id = tagtype['min_role_id'] self.multi = False self.in_rspec = False if self.category == 'slice/rspec': @@ -283,11 +273,6 @@ class TagType: if self.tagname in ['codemux', 'ip_addresses', 'vsys']: self.multi = True - def permit_update(self, role_id): - if role_id > self.min_role_id: - return False - return True - class Network: """ @@ -296,8 +281,9 @@ class Network: * a dictionary mapping node IDs to Node objects * a dictionary mapping interface IDs to Iface objects """ - def __init__(self, api, type = "SFA"): + def __init__(self, api, user_plauth, type = "SFA"): self.api = api + self.user_plauth = user_plauth self.type = type self.sites = self.get_sites(api) self.nodes = self.get_nodes(api) @@ -399,7 +385,7 @@ class Network: """ if element is None: return - + tagtypes = self.getTagTypes() for tt in tagtypes: if tt.in_rspec: @@ -486,14 +472,14 @@ class Network: Write any slice tags that have been added or modified back to the DB """ for tag in self.getSliceTags(): - if tag.category == 'slice/rspec' and not tag.was_updated() and tag.permit_update(None, 40): + if tag.category == 'slice/rspec' and not tag.was_updated(): # The user wants to delete this tag tag.delete() # Update slice tags in database for tag in self.getSliceTags(): if tag.slice_id == self.slice.id: - tag.write(self.api) + tag.write(self.api, self.user_plauth) def toxml(self): """ @@ -520,9 +506,10 @@ class Network: Create a dictionary of site objects keyed by site ID """ tmp = [] - for site in api.plshell.GetSites(api.plauth, {'peer_id': None}): + for site in api.plshell.GetSites(self.user_plauth, {'peer_id': None}): t = site['site_id'], Site(self, site) tmp.append(t) + return dict(tmp) @@ -531,7 +518,7 @@ class Network: Create a dictionary of node objects keyed by node ID """ tmp = [] - for node in api.plshell.GetNodes(api.plauth, {'peer_id': None}): + for node in api.plshell.GetNodes(self.user_plauth, {'peer_id': None}): t = node['node_id'], Node(self, node) tmp.append(t) return dict(tmp) @@ -541,7 +528,7 @@ class Network: Create a dictionary of node objects keyed by node ID """ tmp = [] - for iface in api.plshell.GetInterfaces(api.plauth): + for iface in api.plshell.GetInterfaces(self.user_plauth): t = iface['interface_id'], Iface(self, iface) tmp.append(t) return dict(tmp) @@ -551,7 +538,7 @@ class Network: Create a dictionary of slicetag objects keyed by slice tag ID """ tmp = [] - for tag in api.plshell.GetSliceTags(api.plauth): + for tag in api.plshell.GetSliceTags(self.user_plauth): t = tag['slice_tag_id'], Slicetag(tag) tmp.append(t) return dict(tmp) @@ -561,7 +548,7 @@ class Network: Create a list of tagtype obects keyed by tag name """ tmp = [] - for tag in api.plshell.GetTagTypes(api.plauth): + for tag in api.plshell.GetTagTypes(self.user_plauth): t = tag['tagname'], TagType(tag) tmp.append(t) return dict(tmp) @@ -571,7 +558,7 @@ class Network: Return a Slice object for a single slice """ slicename = hrn_to_pl_slicename(hrn) - slice = api.plshell.GetSlices(api.plauth, [slicename]) + slice = api.plshell.GetSlices(self.user_plauth, [slicename]) if len(slice): self.slice = Slice(self, slicename, slice[0]) return self.slice -- 2.43.0