1 # pylint: disable=c0111, c0103, r0201
3 from sfa.rspecs.version_manager import VersionManager
4 from sfa.util.version import version_core
5 from sfa.util.xrn import Xrn
6 from sfa.util.callids import Callids
7 from sfa.util.sfalogging import logger
8 from sfa.util.faults import SfaInvalidArgument, InvalidRSpecVersion
9 from sfa.server.api_versions import ApiVersions
12 class AggregateManager:
14 def __init__(self, config):
17 # essentially a union of the core version, the generic version (this code) and
18 # whatever the driver needs to expose
20 def rspec_versions(self):
21 version_manager = VersionManager()
22 ad_rspec_versions = []
23 request_rspec_versions = []
24 for rspec_version in version_manager.versions:
25 if rspec_version.content_type in ['*', 'ad']:
26 ad_rspec_versions.append(rspec_version.to_dict())
27 if rspec_version.content_type in ['*', 'request']:
28 request_rspec_versions.append(rspec_version.to_dict())
30 'geni_request_rspec_versions': request_rspec_versions,
31 'geni_ad_rspec_versions': ad_rspec_versions,
34 def get_rspec_version_string(self, rspec_version, options=None):
37 version_string = "rspec_%s" % (rspec_version)
39 # panos adding the info option to the caching key (can be improved)
40 if options.get('info'):
41 version_string = version_string + \
42 "_" + options.get('info', 'default')
44 # Adding the list_leases option to the caching key
45 if options.get('list_leases'):
46 version_string = version_string + "_" + \
47 options.get('list_leases', 'default')
49 # Adding geni_available to caching key
50 if options.get('geni_available'):
51 version_string = version_string + "_" + \
52 str(options.get('geni_available'))
56 def GetVersion(self, api, options):
57 xrn = Xrn(api.hrn, type='authority+am')
58 version = version_core()
59 cred_types = [{'geni_type': 'geni_sfa',
60 'geni_version': str(i)} for i in range(4)[-2:]]
61 geni_api_versions = ApiVersions().get_versions()
63 '3'] = 'http://%s:%s' % (api.config.sfa_aggregate_host, api.config.sfa_aggregate_port)
65 'testbed': api.driver.testbed_name(),
66 'interface': 'aggregate',
71 'geni_api_versions': geni_api_versions,
72 # Accept operations that act on as subset of slivers in a given
74 'geni_single_allocation': 0,
75 # Multiple slivers can exist and be incrementally added, including
76 # those which connect or overlap in some way.
77 'geni_allocate': 'geni_many',
78 'geni_credential_types': cred_types,
79 'geni_handles_speaksfor': True, # supports 'speaks for' credentials
81 version.update(version_generic)
82 version.update(self.rspec_versions())
83 testbed_version = api.driver.aggregate_version()
84 version.update(testbed_version)
87 def ListResources(self, api, creds, options):
88 call_id = options.get('call_id')
89 if Callids().already_handled(call_id):
92 # get the rspec's return format from options
93 version_manager = VersionManager()
94 rspec_version = version_manager.get_version(
95 options.get('geni_rspec_version'))
96 version_string = self.get_rspec_version_string(rspec_version, options)
99 cached_requested = options.get('cached', True)
100 if cached_requested and api.driver.cache:
101 rspec = api.driver.cache.get(version_string)
103 logger.debug("%s.ListResources returning cached advertisement" % (
104 api.driver.__module__))
107 rspec = api.driver.list_resources(rspec_version, options)
109 logger.debug("%s.ListResources stores advertisement in cache" % (
110 api.driver.__module__))
111 api.driver.cache.add(version_string, rspec)
114 def Describe(self, api, creds, urns, options):
115 call_id = options.get('call_id')
116 if Callids().already_handled(call_id):
119 version_manager = VersionManager()
120 rspec_version = version_manager.get_version(
121 options.get('geni_rspec_version'))
122 return api.driver.describe(urns, rspec_version, options)
124 def Status(self, api, urns, creds, options):
125 call_id = options.get('call_id')
126 if Callids().already_handled(call_id):
128 return api.driver.status(urns, options=options)
130 def Allocate(self, api, xrn, creds, rspec_string, expiration, options):
132 Allocate resources as described in a request RSpec argument
133 to a slice with the named URN.
135 call_id = options.get('call_id')
136 if Callids().already_handled(call_id):
138 return api.driver.allocate(xrn, rspec_string, expiration, options)
140 def Provision(self, api, xrns, creds, options):
142 Create the sliver[s] (slice) at this aggregate.
143 Verify HRN and initialize the slice record in PLC if necessary.
145 call_id = options.get('call_id')
146 if Callids().already_handled(call_id):
149 # make sure geni_rspec_version is specified in options
150 if 'geni_rspec_version' not in options:
151 msg = 'geni_rspec_version is required and must be set in options struct'
152 raise SfaInvalidArgument(msg, 'geni_rspec_version')
153 # make sure we support the requested rspec version
154 version_manager = VersionManager()
155 rspec_version = version_manager.get_version(
156 options['geni_rspec_version'])
157 if not rspec_version:
158 raise InvalidRSpecVersion(options['geni_rspec_version'])
160 return api.driver.provision(xrns, options)
162 def Delete(self, api, xrns, creds, options):
163 call_id = options.get('call_id')
164 if Callids().already_handled(call_id):
166 return api.driver.delete(xrns, options)
168 def Renew(self, api, xrns, creds, expiration_time, options):
169 call_id = options.get('call_id')
170 if Callids().already_handled(call_id):
173 return api.driver.renew(xrns, expiration_time, options)
175 def PerformOperationalAction(self, api, xrns, creds, action, options=None):
178 call_id = options.get('call_id')
179 if Callids().already_handled(call_id):
181 return api.driver.perform_operational_action(xrns, action, options)
183 def Shutdown(self, api, xrn, creds, options=None):
186 call_id = options.get('call_id')
187 if Callids().already_handled(call_id):
189 return api.driver.shutdown(xrn, options)