6b13f0fdbb934f5cb0f8800854d9909e1d4b092a
[sfa.git] / sfa / managers / aggregate_manager.py
1 # pylint: disable=c0111, c0103, r0201
2
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
10
11
12 class AggregateManager:
13
14     def __init__(self, config):
15         pass
16
17     # essentially a union of the core version, the generic version (this code) and
18     # whatever the driver needs to expose
19
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())
29         return {
30             'geni_request_rspec_versions': request_rspec_versions,
31             'geni_ad_rspec_versions': ad_rspec_versions,
32         }
33
34     def get_rspec_version_string(self, rspec_version, options=None):
35         if options is None:
36             options = {}
37         version_string = "rspec_%s" % (rspec_version)
38
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')
43
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')
48
49         # Adding geni_available to caching key
50         if options.get('geni_available'):
51             version_string = version_string + "_" + \
52                 str(options.get('geni_available'))
53
54         return version_string
55
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()
62         geni_api_versions[
63             '3'] = 'http://%s:%s' % (api.config.sfa_aggregate_host, api.config.sfa_aggregate_port)
64         version_generic = {
65             'testbed': api.driver.testbed_name(),
66             'interface': 'aggregate',
67             'sfa': 3,
68             'hrn': xrn.get_hrn(),
69             'urn': xrn.get_urn(),
70             'geni_api': 3,
71             'geni_api_versions': geni_api_versions,
72             # Accept operations that act on as subset of slivers in a given
73             # state.
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
80         }
81         version.update(version_generic)
82         version.update(self.rspec_versions())
83         testbed_version = api.driver.aggregate_version()
84         version.update(testbed_version)
85         return version
86
87     def ListResources(self, api, creds, options):
88         call_id = options.get('call_id')
89         if Callids().already_handled(call_id):
90             return ""
91
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)
97
98         # look in cache first
99         cached_requested = options.get('cached', True)
100         if cached_requested and api.driver.cache:
101             rspec = api.driver.cache.get(version_string)
102             if rspec:
103                 logger.debug("%s.ListResources returning cached advertisement" % (
104                     api.driver.__module__))
105                 return rspec
106
107         rspec = api.driver.list_resources(rspec_version, options)
108         if api.driver.cache:
109             logger.debug("%s.ListResources stores advertisement in cache" % (
110                 api.driver.__module__))
111             api.driver.cache.add(version_string, rspec)
112         return rspec
113
114     def Describe(self, api, creds, urns, options):
115         call_id = options.get('call_id')
116         if Callids().already_handled(call_id):
117             return ""
118
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)
123
124     def Status(self, api, urns, creds, options):
125         call_id = options.get('call_id')
126         if Callids().already_handled(call_id):
127             return {}
128         return api.driver.status(urns, options=options)
129
130     def Allocate(self, api, xrn, creds, rspec_string, expiration, options):
131         """
132         Allocate resources as described in a request RSpec argument
133         to a slice with the named URN.
134         """
135         call_id = options.get('call_id')
136         if Callids().already_handled(call_id):
137             return ""
138         return api.driver.allocate(xrn, rspec_string, expiration, options)
139
140     def Provision(self, api, xrns, creds, options):
141         """
142         Create the sliver[s] (slice) at this aggregate.
143         Verify HRN and initialize the slice record in PLC if necessary.
144         """
145         call_id = options.get('call_id')
146         if Callids().already_handled(call_id):
147             return ""
148
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'])
159
160         return api.driver.provision(xrns, options)
161
162     def Delete(self, api, xrns, creds, options):
163         call_id = options.get('call_id')
164         if Callids().already_handled(call_id):
165             return True
166         return api.driver.delete(xrns, options)
167
168     def Renew(self, api, xrns, creds, expiration_time, options):
169         call_id = options.get('call_id')
170         if Callids().already_handled(call_id):
171             return True
172
173         return api.driver.renew(xrns, expiration_time, options)
174
175     def PerformOperationalAction(self, api, xrns, creds, action, options=None):
176         if options is None:
177             options = {}
178         call_id = options.get('call_id')
179         if Callids().already_handled(call_id):
180             return True
181         return api.driver.perform_operational_action(xrns, action, options)
182
183     def Shutdown(self, api, xrn, creds, options=None):
184         if options is None:
185             options = {}
186         call_id = options.get('call_id')
187         if Callids().already_handled(call_id):
188             return True
189         return api.driver.shutdown(xrn, options)