From 40971b94986fbc73719d7be19b0bb81fe673a170 Mon Sep 17 00:00:00 2001 From: Josh Karlin <jkarlin@bbn.com> Date: Mon, 19 Apr 2010 21:25:29 +0000 Subject: [PATCH] Full API implemented. --- sfa/client/sfi.py | 24 ++++++++++++++++++++---- sfa/managers/aggregate_manager_pl.py | 2 +- sfa/managers/registry_manager_pl.py | 23 +++++++++++++++++++++++ sfa/managers/slice_manager_pl.py | 1 + sfa/methods/CreateSliver.py | 22 ++++++++++++++++++++-- sfa/methods/GetVersion.py | 8 +++++++- sfa/methods/ListResources.py | 27 ++++++++++++++++++++++----- sfa/methods/__init__.py | 1 + sfa/plc/network.py | 1 + sfa/trust/certificate.py | 28 ++++++++++++++++------------ sfa/trust/credential.py | 20 ++++++++++---------- sfa/trust/rights.py | 2 +- 12 files changed, 123 insertions(+), 36 deletions(-) diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 45635d0e..550edcfb 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -947,17 +947,15 @@ class Sfi: if args: xrn = args[0] cred = self.get_slice_cred(xrn).save_to_string(save_parents=True) - if xrn: call_options['geni_slice_urn'] = xrn - rspec = server.ListResources([user_cred], call_options) + rspec = server.ListResources([cred], call_options) rspec = zlib.decompress(rspec.decode('base64')) print rspec def CreateSliver(self, opts, args): slice_xrn = args[0] - user_cred = self.get_user_cred() slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True) rspec_file = self.get_rspec_file(args[1]) rspec = open(rspec_file).read() @@ -966,10 +964,28 @@ class Sfi: def DeleteSliver(self, opts, args): slice_xrn = args[0] - user_cred = self.get_user_cred() slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True) server = self.geni_am return server.DeleteSliver(slice_xrn, [slice_cred]) + + def SliverStatus(self, opts, args): + slice_xrn = args[0] + slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True) + server = self.geni_am + return server.SliverStatus(slice_xrn, [slice_cred]) + + def RenewSliver(self, opts, args): + slice_xrn = args[0] + slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True) + time = args[1] + server = self.geni_am + return server.RenewSliver(slice_xrn, [slice_cred], time) + + def Shutdown(self, opts, args): + slice_xrn = args[0] + slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True) + server = self.geni_am + return server.Shutdown(slice_xrn, [slice_cred]) # # Main: parse arguments and dispatch to command diff --git a/sfa/managers/aggregate_manager_pl.py b/sfa/managers/aggregate_manager_pl.py index 2ca9db4f..12b170b9 100644 --- a/sfa/managers/aggregate_manager_pl.py +++ b/sfa/managers/aggregate_manager_pl.py @@ -146,7 +146,7 @@ def start_slice(api, xrn): raise RecordNotFound(hrn) slice_id = slices[0] attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id']) - attribute_id = attreibutes[0]['slice_attribute_id'] + attribute_id = attributes[0]['slice_attribute_id'] api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" ) return 1 diff --git a/sfa/managers/registry_manager_pl.py b/sfa/managers/registry_manager_pl.py index 18181aec..6ed5da8d 100644 --- a/sfa/managers/registry_manager_pl.py +++ b/sfa/managers/registry_manager_pl.py @@ -10,6 +10,14 @@ from sfa.trust.credential import * from sfa.trust.certificate import * from sfa.util.faults import * +def GetVersion(): + version = {} + version['geni_api'] = 1 + return version + + + + def get_credential(api, xrn, type, is_self=False): # convert xrn to hrn if type: @@ -66,6 +74,21 @@ def get_credential(api, xrn, type, is_self=False): return new_cred.save_to_string(save_parents=True) +# The GENI resolve call +def Resolve(api, xrn, creds): + records = resolve(api, xrn) + + if len(records) == 0: + return {} + + record = records[0] + if record.type == 'slice': + return {'geni_urn': xrn, 'geni_creator': record.gid} + if record.type == 'user': + return {'geni_urn': xrn, 'geni_certificate': record.gid} + + + def resolve(api, xrns, type=None, origin_hrn=None, full=True): # load all know registry names into a prefix tree and attempt to find diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py index 2c824cfd..3a15b68c 100644 --- a/sfa/managers/slice_manager_pl.py +++ b/sfa/managers/slice_manager_pl.py @@ -23,6 +23,7 @@ from sfa.util.debug import log from sfa.util.sfalogging import logger import sfa.plc.peers as peers + def delete_slice(api, xrn, origin_hrn=None): credential = api.getCredential() aggregates = api.aggregates diff --git a/sfa/methods/CreateSliver.py b/sfa/methods/CreateSliver.py index 48cf9803..e8738018 100644 --- a/sfa/methods/CreateSliver.py +++ b/sfa/methods/CreateSliver.py @@ -2,6 +2,9 @@ from sfa.util.faults import * from sfa.util.namespace import * from sfa.util.method import Method from sfa.util.parameter import Parameter +from sfatables.runtime import SFATablesRules +import sys +from sfa.trust.credential import Credential class CreateSliver(Method): """ @@ -23,6 +26,17 @@ class CreateSliver(Method): ] returns = Parameter(str, "Allocated RSpec") + def __run_sfatables(self, manager, rules, hrn, origin_hrn, rspec): + if rules.sorted_rule_list: + contexts = rules.contexts + request_context = manager.fetch_context(hrn, origin_hrn, contexts) + rules.set_context(request_context) + newrspec = rules.apply(rspec) + else: + newrspec = rspec + return newrspec + + def call(self, slice_xrn, creds, rspec): hrn, type = urn_to_hrn(slice_xrn) @@ -33,14 +47,16 @@ class CreateSliver(Method): for cred in creds: try: self.api.auth.check(cred, 'createslice') + origin_hrn = Credential(string=cred).get_gid_caller().get_hrn() found = True break except: + error = sys.exc_info()[:2] continue if not found: - raise InsufficientRights('CreateSliver: Credentials either did not verify, were no longer valid, or did not have appropriate privileges') - + raise InsufficientRights('CreateSliver: Access denied: %s -- %s' % (error[0],error[1])) + manager_base = 'sfa.managers' @@ -48,6 +64,8 @@ class CreateSliver(Method): mgr_type = self.api.config.SFA_GENI_AGGREGATE_TYPE manager_module = manager_base + ".geni_am_%s" % mgr_type manager = __import__(manager_module, fromlist=[manager_base]) + rspec = self.__run_sfatables(manager, SFATablesRules('INCOMING'), + hrn, origin_hrn, rspec) return manager.CreateSliver(self.api, slice_xrn, creds, rspec) return '' diff --git a/sfa/methods/GetVersion.py b/sfa/methods/GetVersion.py index f419d5a8..e1ca8b3b 100644 --- a/sfa/methods/GetVersion.py +++ b/sfa/methods/GetVersion.py @@ -9,7 +9,7 @@ class GetVersion(Method): Returns this GENI Aggregate Manager's Version Information @return version """ - interfaces = ['geni_am'] + interfaces = ['geni_am','registry'] accepts = [] returns = Parameter(dict, "Version information") @@ -23,5 +23,11 @@ class GetVersion(Method): manager_module = manager_base + ".geni_am_%s" % mgr_type manager = __import__(manager_module, fromlist=[manager_base]) return manager.GetVersion() + if self.api.interface in ['registry']: + mgr_type = self.api.config.SFA_REGISTRY_TYPE + manager_module = manager_base + ".slice_manager_%s" % mgr_type + manager = __import__(manager_module, fromlist=[manager_base]) + return manager.GetVersion() + return {} diff --git a/sfa/methods/ListResources.py b/sfa/methods/ListResources.py index a28fb0e1..0007c255 100644 --- a/sfa/methods/ListResources.py +++ b/sfa/methods/ListResources.py @@ -2,6 +2,10 @@ from sfa.util.faults import * from sfa.util.namespace import * from sfa.util.method import Method from sfa.util.parameter import Parameter, Mixed +from sfa.trust.credential import Credential +from sfatables.runtime import SFATablesRules +import sys + class ListResources(Method): """ @@ -19,27 +23,40 @@ class ListResources(Method): def call(self, creds, options): self.api.logger.info("interface: %s\tmethod-name: %s" % (self.api.interface, self.name)) - + # Validate that at least one of the credentials is good enough found = False for cred in creds: try: - self.api.auth.check(cred, 'ListResources') + self.api.auth.check(cred, 'listnodes') found = True + user_cred = Credential(string=cred) break except: + error = sys.exc_info()[:2] continue if not found: - raise InsufficientRights('ListResources: Credentials either did not verify, were no longer valid, or did not have appropriate privileges') + raise InsufficientRights('ListResources: Access denied: %s -- %s' % (error[0],error[1])) + origin_hrn = user_cred.get_gid_caller().get_hrn() + manager_base = 'sfa.managers' if self.api.interface in ['geni_am']: mgr_type = self.api.config.SFA_GENI_AGGREGATE_TYPE manager_module = manager_base + ".geni_am_%s" % mgr_type manager = __import__(manager_module, fromlist=[manager_base]) - return manager.ListResources(self.api, creds, options) + rspec = manager.ListResources(self.api, creds, options) + outgoing_rules = SFATablesRules('OUTGOING') + + + filtered_rspec = rspec + if outgoing_rules.sorted_rule_list: + context = {'sfa':{'user':{'hrn':origin_hrn}, 'slice':{'hrn':None}}} + outgoing_rules.set_context(context) + filtered_rspec = outgoing_rules.apply(rspec) - return '' + return filtered_rspec + diff --git a/sfa/methods/__init__.py b/sfa/methods/__init__.py index 243db987..dd35e3e4 100644 --- a/sfa/methods/__init__.py +++ b/sfa/methods/__init__.py @@ -34,4 +34,5 @@ DeleteSliver SliverStatus RenewSliver Shutdown +Resolve """.split() diff --git a/sfa/plc/network.py b/sfa/plc/network.py index 955036c5..01ed4f77 100644 --- a/sfa/plc/network.py +++ b/sfa/plc/network.py @@ -102,6 +102,7 @@ class Site: def toxml(self, xml): if not (self.public and self.enabled and self.node_ids): return + with xml.site(id = self.idtag): with xml.name: xml << self.name diff --git a/sfa/trust/certificate.py b/sfa/trust/certificate.py index c49c50cc..f7dec97c 100644 --- a/sfa/trust/certificate.py +++ b/sfa/trust/certificate.py @@ -22,8 +22,7 @@ import traceback from OpenSSL import crypto import M2Crypto from M2Crypto import X509 -from M2Crypto import EVP -from random import randint +from tempfile import mkstemp from sfa.util.faults import * @@ -315,19 +314,24 @@ class Certificate: # Save the certificate to a file. # @param save_parents If save_parents==True, then also save the parent certificates. - def save_to_file(self, filename, save_parents=True): + def save_to_file(self, filename, save_parents=True, filep=None): string = self.save_to_string(save_parents=save_parents) - open(filename, 'w').write(string) + if filep: + f = filep + else: + f = open(filename, 'w') + f.write(string) + f.close() + ## # Save the certificate to a random file in /tmp/ - # @param save_parents If save_parents==True, then also save the parent certificates. - def save_to_random_tmp_file(self, save_parents=True): - while True: - filename = "/tmp/cred_%d" % randint(0,999999999) - if not os.path.isfile(filename): - break - self.save_to_file(filename, save_parents) - return filename + # @param save_parents If save_parents==True, then also save the parent certificates. + def save_to_random_tmp_file(self, save_parents=True): + fp, filename = mkstemp(suffix='cert', text=True) + fp = os.fdopen(fp, "w") + self.save_to_file(filename, save_parents=True, filep=fp) + return filename + ## # Sets the issuer private key and name # @param key Keypair object containing the private key of the issuer diff --git a/sfa/trust/credential.py b/sfa/trust/credential.py index c72817b5..bb58407e 100644 --- a/sfa/trust/credential.py +++ b/sfa/trust/credential.py @@ -9,8 +9,8 @@ import os import datetime -from random import randint from xml.dom.minidom import Document, parseString +from tempfile import mkstemp from sfa.trust.credential_legacy import CredentialLegacy from sfa.trust.rights import * @@ -411,19 +411,19 @@ class Credential(object): self.xml = doc.toxml() - def save_to_random_tmp_file(self): - while True: - filename = "/tmp/cred_%d" % randint(0,999999999) - if not os.path.isfile(filename): - break - - self.save_to_file(filename) + def save_to_random_tmp_file(self): + fp, filename = mkstemp(suffix='cred', text=True) + fp = os.fdopen(fp, "w") + self.save_to_file(filename, save_parents=True, filep=fp) return filename - def save_to_file(self, filename, save_parents=True): + def save_to_file(self, filename, save_parents=True, filep=None): if not self.xml: self.encode() - f = open(filename, "w") + if filep: + f = filep + else: + f = open(filename, "w") f.write(self.xml) f.close() diff --git a/sfa/trust/rights.py b/sfa/trust/rights.py index bef63824..fa5c043c 100644 --- a/sfa/trust/rights.py +++ b/sfa/trust/rights.py @@ -18,7 +18,7 @@ privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential", "*"], "refresh": ["remove", "update"], - "resolve": ["resolve", "list", "getcredential", "listresources", "getversion"], + "resolve": ["resolve", "list", "getcredential", "getversion"], "sa": ["getticket", "redeemslice", "redeemticket", "createslice", "deleteslice", "updateslice", "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", "renewsliver", "deleteslice", "resetslice", "listslices", "listnodes", "getpolicy", "createsliver", "sliverestatus"], -- 2.47.0