From c15c2b3202c7a796dc3bd583996b2d7ebb8995af Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Thu, 23 Aug 2012 15:36:34 -0400 Subject: [PATCH] updated renew(), delete(), allocate(), provision() --- sfa/managers/aggregate_manager.py | 62 ++++++++++--------------------- sfa/managers/slice_manager.py | 8 ++-- sfa/methods/DeleteSliver.py | 19 +++++----- sfa/methods/RenewSliver.py | 20 +++++----- sfa/openstack/nova_driver.py | 50 ++++++++++--------------- sfa/openstack/osaggregate.py | 7 +++- sfa/planetlab/pldriver.py | 62 +++++++++++++++++++------------ sfa/util/faults.py | 15 +++++++- 8 files changed, 120 insertions(+), 123 deletions(-) diff --git a/sfa/managers/aggregate_manager.py b/sfa/managers/aggregate_manager.py index 20c3d730..f8948fd3 100644 --- a/sfa/managers/aggregate_manager.py +++ b/sfa/managers/aggregate_manager.py @@ -105,7 +105,7 @@ class AggregateManager: logger.debug("%s.ListResources returning cached advertisement" % (self.driver.__module__)) return rspec - rspec = self.driver.list_resources (creds, version, options) + rspec = self.driver.list_resources (version, options) if self.driver.cache: logger.debug("%s.ListResources stores advertisement in cache" % (self.driver.__module__)) self.driver.cache.add(version_string, rspec) @@ -117,65 +117,43 @@ class AggregateManager: version_manager = VersionManager() rspec_version = version_manager.get_version(options.get('geni_rspec_version')) - return self.driver.describe(creds, urns, rspec_version, options) + return self.driver.describe(urns, rspec_version, options) - def Status (self, api, urns, creds, options): + def Status (self, api, urns, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return {} return self.driver.status (urns, options=options) - - def CreateSliver(self, api, xrn, creds, rspec_string, users, options): + + + def Allocate(self, api, xrn, creds, rspec_string, options): + """ + Allocate resources as described in a request RSpec argument + to a slice with the named URN. + """ + call_id = options.get('call_id') + if Callids().already_handled(call_id): return "" + return self.driver.allocate(xrn, creds, rspec_string, options) + + def Provision(self, api, xrns, options): """ Create the sliver[s] (slice) at this aggregate. Verify HRN and initialize the slice record in PLC if necessary. """ call_id = options.get('call_id') if Callids().already_handled(call_id): return "" + return self.driver.provision(xrns, creds, options) - xrn = Xrn(xrn, 'slice') - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - - return self.driver.create_sliver (slice_urn, slice_hrn, creds, rspec_string, users, options) - - def DeleteSliver(self, api, xrn, creds, options): + def Delete(self, api, xrns, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return True + return self.driver.delete_sliver (xrns, options) - xrn = Xrn(xrn, 'slice') - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - return self.driver.delete_sliver (slice_urn, slice_hrn, creds, options) - - def RenewSliver(self, api, xrn, creds, expiration_time, options): + def Renew(self, api, xrns, expiration_time, options): call_id = options.get('call_id') if Callids().already_handled(call_id): return True - - xrn = Xrn(xrn, 'slice') - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - return self.driver.renew_sliver (slice_urn, slice_hrn, creds, expiration_time, options) + return self.driver.renew(xrns, expiration_time, options) - ### these methods could use an options extension for at least call_id - def start_slice(self, api, xrn, creds): - xrn = Xrn(xrn) - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - return self.driver.start_slice (slice_urn, slice_hrn, creds) - - def stop_slice(self, api, xrn, creds): - xrn = Xrn(xrn) - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - return self.driver.stop_slice (slice_urn, slice_hrn, creds) - - def reset_slice(self, api, xrn): - xrn = Xrn(xrn) - slice_urn=xrn.get_urn() - slice_hrn=xrn.get_hrn() - return self.driver.reset_slice (slice_urn, slice_hrn) - def GetTicket(self, api, xrn, creds, rspec, users, options): xrn = Xrn(xrn) diff --git a/sfa/managers/slice_manager.py b/sfa/managers/slice_manager.py index 02729b00..dcd5e5e0 100644 --- a/sfa/managers/slice_manager.py +++ b/sfa/managers/slice_manager.py @@ -337,9 +337,9 @@ class SliceManager: # first draft at a merging SliverStatus - def SliverStatus(self, api, slice_xrn, creds, options): - def _SliverStatus(server, xrn, creds, options): - return server.SliverStatus(xrn, creds, options) + def Status(self, api, slice_xrn, creds, options): + def _Status(server, xrn, creds, options): + return server.Status(xrn, creds, options) call_id = options.get('call_id') if Callids().already_handled(call_id): return {} @@ -351,7 +351,7 @@ class SliceManager: for aggregate in api.aggregates: interface = api.aggregates[aggregate] server = api.server_proxy(interface, cred) - threads.run (_SliverStatus, server, slice_xrn, [cred], options) + threads.run (_Status, server, slice_xrn, [cred], options) results = [ReturnValue.get_value(result) for result in threads.get_results()] # get rid of any void result - e.g. when call_id was hit, where by convention we return {} diff --git a/sfa/methods/DeleteSliver.py b/sfa/methods/DeleteSliver.py index 697b6d3e..9dfebda6 100644 --- a/sfa/methods/DeleteSliver.py +++ b/sfa/methods/DeleteSliver.py @@ -4,19 +4,19 @@ from sfa.storage.parameter import Parameter, Mixed from sfa.trust.auth import Auth from sfa.trust.credential import Credential -class DeleteSliver(Method): +class Delete(Method): """ - Remove the slice from all nodes and free the allocated resources + Remove the slice or slivers and free the allocated resources - @param xrn human readable name of slice to instantiate (hrn or urn) - @param cred credential string specifying the rights of the caller + @param xrns human readable name of slice to instantiate (hrn or urn) + @param creds credential string specifying the rights of the caller @return 1 is successful, faults otherwise """ interfaces = ['aggregate', 'slicemgr', 'component'] accepts = [ - Parameter(str, "Human readable name of slice to delete (hrn or urn)"), + Parameter([str], "Human readable name of slice to delete (hrn or urn)"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(dict, "options"), @@ -24,14 +24,13 @@ class DeleteSliver(Method): returns = Parameter(int, "1 if successful") - def call(self, xrn, creds, options): - (hrn, type) = urn_to_hrn(xrn) - valid_creds = self.api.auth.checkCredentials(creds, 'deletesliver', hrn) + def call(self, xrns, creds, options): + valid_creds = self.api.auth.checkCredentials(creds, 'deletesliver', xrns) #log the call origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() - self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name)) + self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, xrns, self.name)) - self.api.manager.DeleteSliver(self.api, xrn, creds, options) + self.api.manager.Delete(self.api, xrns, options) return 1 diff --git a/sfa/methods/RenewSliver.py b/sfa/methods/RenewSliver.py index c64b8841..ee951c0c 100644 --- a/sfa/methods/RenewSliver.py +++ b/sfa/methods/RenewSliver.py @@ -9,13 +9,15 @@ from sfa.trust.credential import Credential from sfa.storage.parameter import Parameter -class RenewSliver(Method): +class Renew(Method): """ - Renews the resources in a sliver, extending the lifetime of the slice. - @param slice_urn (string) URN of slice to renew + Renews the resources in the specified slice or slivers by + extending the lifetime. + + @param surn ([string]) List of URNs of to renew @param credentials ([string]) of credentials @param expiration_time (string) requested time of expiration - + @param options (dict) options """ interfaces = ['aggregate', 'slicemgr'] accepts = [ @@ -26,14 +28,12 @@ class RenewSliver(Method): ] returns = Parameter(bool, "Success or Failure") - def call(self, slice_xrn, creds, expiration_time, options): - - (hrn, type) = urn_to_hrn(slice_xrn) + def call(self, urns, creds, expiration_time, options): - self.api.logger.info("interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"%(self.api.interface, hrn, creds, self.name)) + self.api.logger.info("interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"%(self.api.interface, urns, creds, self.name)) # Find the valid credentials - valid_creds = self.api.auth.checkCredentials(creds, 'renewsliver', hrn) + valid_creds = self.api.auth.checkCredentials(creds, 'renewsliver', urns) # Validate that the time does not go beyond the credential's expiration time requested_time = utcparse(expiration_time) @@ -42,5 +42,5 @@ class RenewSliver(Method): raise InsufficientRights('Renewsliver: Credential expires before requested expiration time') if requested_time > datetime.datetime.utcnow() + datetime.timedelta(days=max_renew_days): raise Exception('Cannot renew > %s days from now' % max_renew_days) - return self.api.manager.RenewSliver(self.api, slice_xrn, valid_creds, expiration_time, options) + return self.api.manager.Renew(self.api, urns, expiration_time, options) diff --git a/sfa/openstack/nova_driver.py b/sfa/openstack/nova_driver.py index af9ce4df..7a84c2e6 100644 --- a/sfa/openstack/nova_driver.py +++ b/sfa/openstack/nova_driver.py @@ -318,22 +318,13 @@ class NovaDriver(Driver): def aggregate_version (self): return {} - def list_slices (self, creds, options): - # get data from db - instance_urns = [] - instances = self.shell.nova_manager.servers.findall() - for instance in instances: - if instance.name not in instance_urns: - instance_urns.append(OSXrn(instance.name, type='slice').urn) - return instance_urns - # first 2 args are None in case of resource discovery - def list_resources (self, creds, version, options): + def list_resources (self, version, options): aggregate = OSAggregate(self) rspec = aggregate.list_resources(version=version, options=options) return rspec - def describe(self, creds, urns, version, options): + def describe(self, urns, version, options): aggregate = OSAggregate(self) return aggregate.describe(urns, version=version, options=options) @@ -342,8 +333,8 @@ class NovaDriver(Driver): desc = aggregate.describe(urns) return desc['geni_slivers'] - def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options): - + def allocate (self, urn, rspec_string, options): + xrn = Xrn(urn) aggregate = OSAggregate(self) # assume first user is the caller and use their context @@ -351,9 +342,10 @@ class NovaDriver(Driver): # key as the project key. key_name = None if len(users) > 1: - key_name = aggregate.create_instance_key(slice_hrn, users[0]) + key_name = aggregate.create_instance_key(xrn.get_hrn(), users[0]) # collect public keys + users = options.get('geni_users', []) pubkeys = [] for user in users: pubkeys.extend(user['keys']) @@ -365,33 +357,29 @@ class NovaDriver(Driver): return aggregate.describe(slice_xrn=slice_urn, version=rspec.version) - def delete_sliver (self, slice_urn, slice_hrn, creds, options): + def provision(self, urns, version, options): aggregate = OSAggregate(self) - tenant_name = OSXrn(xrn=slice_hrn, type='slice').get_tenant_name() - project_name = hrn_to_os_slicename(slice_hrn) - return aggregate.delete_instances(project_name, tenant_name) + return aggregate.describe(urns, version=version, options=options) - def update_sliver(self, slice_urn, slice_hrn, rspec, creds, options): - name = hrn_to_os_slicename(slice_hrn) - tenant_name = OSXrn(xrn=slice_hrn, type='slice').get_tenant_name() + def delete (self, urns, options): aggregate = OSAggregate(self) - return aggregate.update_instances(name) - - def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options): - return True - - def start_slice (self, slice_urn, slice_hrn, creds): + for urn in urns: + xrn = OSXrn(xrn=urn, type='slice') + tenant_name = xrn.get_tenant_name() + project_name = xrn.get_slicename() + id = xrn.id + aggregate.delete_instance(tenant_name, project_name, id) return 1 - def stop_slice (self, slice_urn, slice_hrn, creds): + def renew (self, urns, expiration_time, options): + return True + + def perform_operational_action (self, urns, action, options): tenant_name = OSXrn(xrn=slice_hrn, type='slice').get_tenant_name() name = OSXrn(xrn=slice_urn).name aggregate = OSAggregate(self) return aggregate.stop_instances(name, tenant_name) - def reset_slice (self, slice_urn, slice_hrn, creds): - raise SfaNotImplemented ("reset_slice not available at this interface") - # xxx this code is quite old and has not run for ages # it is obviously totally broken and needs a rewrite def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options): diff --git a/sfa/openstack/osaggregate.py b/sfa/openstack/osaggregate.py index 032fd177..0e4be844 100644 --- a/sfa/openstack/osaggregate.py +++ b/sfa/openstack/osaggregate.py @@ -351,9 +351,12 @@ class OSAggregate: - def delete_instances(self, instance_name, tenant_name): + def delete_instance(self, tenant_name, instance_name, id=None): self.driver.shell.nova_manager.connect(tenant=tenant_name) - instances = self.driver.shell.nova_manager.servers.findall(name=instance_name) + args = {'name': instance_name} + if id: + args['id'] = id + instances = self.driver.shell.nova_manager.servers.findall(**args) security_group_manager = SecurityGroup(self.driver) for instance in instances: # deleate this instance's security groups diff --git a/sfa/planetlab/pldriver.py b/sfa/planetlab/pldriver.py index f73410e3..d4f12438 100644 --- a/sfa/planetlab/pldriver.py +++ b/sfa/planetlab/pldriver.py @@ -2,7 +2,7 @@ import time import datetime # from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \ - RecordNotFound, SfaNotImplemented, SliverDoesNotExist + RecordNotFound, SfaNotImplemented, SliverDoesNotExist, SearchFailed from sfa.util.sfalogging import logger from sfa.util.defaultdict import defaultdict from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch @@ -571,12 +571,12 @@ class PlDriver (Driver): return slice_urns # first 2 args are None in case of resource discovery - def list_resources (self, creds, options): + def list_resources (self, version, options): aggregate = PlAggregate(self) - rspec = aggregate.list_resources(version=rspec_version, options=options) + rspec = aggregate.list_resources(version=version, options=options) return rspec - def describe(self, creds, urns, version, options): + def describe(self, urns, version, options): aggregate = PlAggregate(self) return aggregate.describe(urns, version=version, options=options) @@ -649,13 +649,14 @@ class PlDriver (Driver): result['geni_resources'] = resources return result - def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options): - + def allocate (self, urn, rspec_string, options): + xrn = Xrn(urn) aggregate = PlAggregate(self) slices = PlSlices(self) - peer = slices.get_peer(slice_hrn) - sfa_peer = slices.get_sfa_peer(slice_hrn) + peer = slices.get_peer(xrn.get_hrn()) + sfa_peer = slices.get_sfa_peer(xrn.get_hrn()) slice_record=None + users = options.get('geni_users', []) if users: slice_record = users[0].get('slice_record', {}) @@ -664,11 +665,11 @@ class PlDriver (Driver): requested_attributes = rspec.version.get_slice_attributes() # ensure site record exists - site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options) + site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options) # ensure slice record exists - slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options) + slice = slices.verify_slice(xrn.hrn, slice_record, peer, sfa_peer, options=options) # ensure person records exists - persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options) + persons = slices.verify_persons(xrn.hrn, slice, users, peer, sfa_peer, options=options) # ensure slice attributes exists slices.verify_slice_attributes(slice, requested_attributes, options=options) @@ -707,15 +708,25 @@ class PlDriver (Driver): # only used by plc and ple. slices.handle_peer(site, slice, persons, peer) - return aggregate.describe_rspec(slice_xrn=slice_urn, version=rspec.version) - - def delete_sliver (self, slice_urn, slice_hrn, creds, options): - slicename = hrn_to_pl_slicename(slice_hrn) - slices = self.shell.GetSlices({'name': slicename}) + return aggregate.describe(slice_xrn=xrn.get_urn(), version=rspec.version) + + def delete(self, urns, options): + names = [] + ids = [] + for urn in urns: + xrn = PlXrn(xrn=urn, type='slice') + names.append(xrn.pl_slicename()) + if xrn.id: + ids.append(xrn.id) + slices = self.shell.GetSlices({'name': names}) if not slices: - return 1 + raise SearchFailed(urns) slice = slices[0] - + if ids: + node_ids = ids + else: + node_ids = slice['node_ids'] + # determine if this is a peer slice # xxx I wonder if this would not need to use PlSlices.get_peer instead # in which case plc.peers could be deprecated as this here @@ -724,17 +735,22 @@ class PlDriver (Driver): try: if peer: self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer) - self.shell.DeleteSliceFromNodes(slicename, slice['node_ids']) + self.shell.DeleteSliceFromNodes(slice['slice_id'], node_ids) finally: if peer: self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id']) return 1 - def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options): - slicename = hrn_to_pl_slicename(slice_hrn) - slices = self.shell.GetSlices({'name': slicename}, ['slice_id']) + def renew (self, urns, expiration_time, options): + # we can only renew slices, not individual slivers. ignore sliver + # ids in the urn + names = [] + for urn in urns: + xrn = PlXrn(urn=urn, type='slice') + names.append(xrn.pl_slicename()) + slices = self.shell.GetSlices(names, ['slice_id']) if not slices: - raise RecordNotFound(slice_hrn) + raise SearchFailed(urns) slice = slices[0] requested_time = utcparse(expiration_time) record = {'expires': int(datetime_to_epoch(requested_time))} diff --git a/sfa/util/faults.py b/sfa/util/faults.py index 848d8182..df192643 100644 --- a/sfa/util/faults.py +++ b/sfa/util/faults.py @@ -101,6 +101,14 @@ class TreeException(SfaFault): def __str__(self): return repr(self.value) +class SearchFailed(SfaFault): + def __init__(self, value, extra = None): + self.value = value + faultString = "%s does not exist here " % self.value + SfaFault.__init__(self, GENICODE.SEARCHFAILED, faultString, extra) + def __str__(self): + return repr(self.value) + class NonExistingRecord(SfaFault): def __init__(self, value, extra = None): self.value = value @@ -329,4 +337,9 @@ class CertExpired(SfaFault): self.value = value faultString = "%s cert is expired" % value SfaFault.__init__(self, GENICODE.ERROR, faultString, extra) - + +class SfatablesRejected(SfaFault): + def __init__(self, value, extra=None): + self.value =value + faultString = "%s rejected by sfatables" + SfaFault.__init__(self, GENICODE.FORBIDDEN, faultString, extra) -- 2.43.0