Add INF-320 support attribute-based filter
[pti/o2.git] / o2ims / views / ocloud_route.py
1 # Copyright (C) 2021 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 from flask import request
16 from flask_restx import Resource, reqparse
17
18 from o2common.service.messagebus import MessageBus
19 from o2common.views.pagination_route import link_header, PAGE_PARAM
20 from o2ims.views import ocloud_view
21 from o2ims.views.api_ns import api_ims_inventory_v1
22 from o2ims.views.ocloud_dto import OcloudDTO, ResourceTypeDTO,\
23     ResourcePoolDTO, ResourceDTO, DeploymentManagerDTO, SubscriptionDTO
24
25 from o2common.helper import o2logging
26 logger = o2logging.get_logger(__name__)
27
28
29 def configure_api_route():
30     # Set global bus for resource
31     global bus
32     bus = MessageBus.get_instance()
33
34
35 # ----------  OClouds ---------- #
36 @api_ims_inventory_v1.route("/")
37 @api_ims_inventory_v1.response(404, 'oCloud not found')
38 @api_ims_inventory_v1.param(
39     'all_fields',
40     'Set any value for show all fields. This value will cover "fields" ' +
41     'and "all_fields".',
42     _in='query')
43 @api_ims_inventory_v1.param(
44     'fields',
45     'Set fields to show, split by comma, "/" for parent and children.' +
46     ' Like "name,parent/children". This value will cover "exculde_fields".',
47     _in='query')
48 @api_ims_inventory_v1.param(
49     'exclude_fields',
50     'Set fields to exclude showing, split by comma, "/" for parent and ' +
51     'children. Like "name,parent/children". This value will cover ' +
52     '"exclude_default".',
53     _in='query')
54 @api_ims_inventory_v1.param(
55     'exclude_default',
56     'Exclude showing all default fields, Set "true" to enable.',
57     _in='query')
58 class OcloudsListRouter(Resource):
59     """Ocloud get endpoint
60     O2 interface ocloud endpoint
61     """
62
63     ocloud_get = OcloudDTO.ocloud
64
65     @api_ims_inventory_v1.marshal_with(ocloud_get)
66     def get(self):
67         res = ocloud_view.oclouds(bus.uow)
68         if len(res) > 0:
69             return res[0]
70         api_ims_inventory_v1.abort(
71             404, "oCloud doesn't exist")
72
73
74 # ----------  ResourceTypes ---------- #
75 @api_ims_inventory_v1.route("/resourceTypes")
76 @api_ims_inventory_v1.param(PAGE_PARAM,
77                             'Page number of the results to fetch.' +
78                             ' Default: 1',
79                             _in='query', default=1)
80 @api_ims_inventory_v1.param(
81     'all_fields',
82     'Set any value for show all fields. This value will cover "fields" ' +
83     'and "all_fields".',
84     _in='query')
85 @api_ims_inventory_v1.param(
86     'fields',
87     'Set fields to show, split by comma, "/" for parent and children.' +
88     ' Like "name,parent/children". This value will cover "exculde_fields".',
89     _in='query')
90 @api_ims_inventory_v1.param(
91     'exclude_fields',
92     'Set fields to exclude showing, split by comma, "/" for parent and ' +
93     'children. Like "name,parent/children". This value will cover ' +
94     '"exclude_default".',
95     _in='query')
96 @api_ims_inventory_v1.param(
97     'exclude_default',
98     'Exclude showing all default fields, Set "true" to enable.',
99     _in='query')
100 @api_ims_inventory_v1.param(
101     'filter',
102     'Filter of the query.',
103     _in='query')
104 class ResourceTypesListRouter(Resource):
105
106     model = ResourceTypeDTO.resource_type_get
107
108     @api_ims_inventory_v1.marshal_list_with(model)
109     def get(self):
110         parser = reqparse.RequestParser()
111         parser.add_argument(PAGE_PARAM, location='args')
112         parser.add_argument('filter', location='args')
113         args = parser.parse_args()
114         kwargs = {}
115         if args.nextpage_opaque_marker is not None:
116             kwargs['page'] = args.nextpage_opaque_marker
117         kwargs['filter'] = args.filter if args.filter is not None else ''
118
119         ret = ocloud_view.resource_types(bus.uow, **kwargs)
120         return link_header(request.full_path, ret)
121
122
123 @api_ims_inventory_v1.route("/resourceTypes/<resourceTypeID>")
124 @api_ims_inventory_v1.param('resourceTypeID', 'ID of the resource type')
125 @api_ims_inventory_v1.response(404, 'Resource type not found')
126 @api_ims_inventory_v1.param(
127     'all_fields',
128     'Set any value for show all fields. This value will cover "fields" ' +
129     'and "all_fields".',
130     _in='query')
131 @api_ims_inventory_v1.param(
132     'fields',
133     'Set fields to show, split by comma, "/" for parent and children.' +
134     ' Like "name,parent/children". This value will cover "exculde_fields".',
135     _in='query')
136 @api_ims_inventory_v1.param(
137     'exclude_fields',
138     'Set fields to exclude showing, split by comma, "/" for parent and ' +
139     'children. Like "name,parent/children". This value will cover ' +
140     '"exclude_default".',
141     _in='query')
142 @api_ims_inventory_v1.param(
143     'exclude_default',
144     'Exclude showing all default fields, Set "true" to enable.',
145     _in='query')
146 class ResourceTypeGetRouter(Resource):
147
148     model = ResourceTypeDTO.resource_type_get
149
150     @api_ims_inventory_v1.doc('Get resource type')
151     @api_ims_inventory_v1.marshal_with(model)
152     def get(self, resourceTypeID):
153         result = ocloud_view.resource_type_one(resourceTypeID, bus.uow)
154         if result is not None:
155             return result
156         api_ims_inventory_v1.abort(
157             404, "Resource type {} doesn't exist".format(resourceTypeID))
158
159
160 # ----------  ResourcePools ---------- #
161 @api_ims_inventory_v1.route("/resourcePools")
162 @api_ims_inventory_v1.param(PAGE_PARAM,
163                             'Page number of the results to fetch.' +
164                             ' Default: 1',
165                             _in='query', default=1)
166 @api_ims_inventory_v1.param(
167     'all_fields',
168     'Set any value for show all fields. This value will cover "fields" ' +
169     'and "all_fields".',
170     _in='query')
171 @api_ims_inventory_v1.param(
172     'fields',
173     'Set fields to show, split by comma, "/" for parent and children.' +
174     ' Like "name,parent/children". This value will cover "exculde_fields".',
175     _in='query')
176 @api_ims_inventory_v1.param(
177     'exclude_fields',
178     'Set fields to exclude showing, split by comma, "/" for parent and ' +
179     'children. Like "name,parent/children". This value will cover ' +
180     '"exclude_default".',
181     _in='query')
182 @api_ims_inventory_v1.param(
183     'exclude_default',
184     'Exclude showing all default fields, Set "true" to enable.',
185     _in='query')
186 @api_ims_inventory_v1.param(
187     'filter',
188     'Filter of the query.',
189     _in='query')
190 class ResourcePoolsListRouter(Resource):
191
192     model = ResourcePoolDTO.resource_pool_get
193
194     @api_ims_inventory_v1.marshal_list_with(model)
195     def get(self):
196         parser = reqparse.RequestParser()
197         parser.add_argument(PAGE_PARAM, location='args')
198         parser.add_argument('filter', location='args')
199         args = parser.parse_args()
200         kwargs = {}
201         if args.nextpage_opaque_marker is not None:
202             kwargs['page'] = args.nextpage_opaque_marker
203         kwargs['filter'] = args.filter if args.filter is not None else ''
204
205         ret = ocloud_view.resource_pools(bus.uow, **kwargs)
206         return link_header(request.full_path, ret)
207
208
209 @api_ims_inventory_v1.route("/resourcePools/<resourcePoolID>")
210 @api_ims_inventory_v1.param('resourcePoolID', 'ID of the resource pool')
211 @api_ims_inventory_v1.response(404, 'Resource pool not found')
212 @api_ims_inventory_v1.param(
213     'all_fields',
214     'Set any value for show all fields. This value will cover "fields" ' +
215     'and "all_fields".',
216     _in='query')
217 @api_ims_inventory_v1.param(
218     'fields',
219     'Set fields to show, split by comma, "/" for parent and children.' +
220     ' Like "name,parent/children". This value will cover "exculde_fields".',
221     _in='query')
222 @api_ims_inventory_v1.param(
223     'exclude_fields',
224     'Set fields to exclude showing, split by comma, "/" for parent and ' +
225     'children. Like "name,parent/children". This value will cover ' +
226     '"exclude_default".',
227     _in='query')
228 @api_ims_inventory_v1.param(
229     'exclude_default',
230     'Exclude showing all default fields, Set "true" to enable.',
231     _in='query')
232 class ResourcePoolGetRouter(Resource):
233
234     model = ResourcePoolDTO.resource_pool_get
235
236     @api_ims_inventory_v1.doc('Get resource pool')
237     @api_ims_inventory_v1.marshal_with(model)
238     def get(self, resourcePoolID):
239         result = ocloud_view.resource_pool_one(resourcePoolID, bus.uow)
240         if result is not None:
241             return result
242         api_ims_inventory_v1.abort(
243             404, "Resource pool {} doesn't exist".format(resourcePoolID))
244
245
246 # ----------  Resources ---------- #
247 @api_ims_inventory_v1.route("/resourcePools/<resourcePoolID>/resources")
248 @api_ims_inventory_v1.param('resourcePoolID', 'ID of the resource pool')
249 # @api_ims_inventory_v1.param('sort', 'sort by column name',
250 #                             _in='query')
251 # @api_ims_inventory_v1.param('per_page', 'The number of results per page ' +
252 #                             '(max 100). Default: 30',
253 #                             _in='query', default=30)
254 @api_ims_inventory_v1.param(PAGE_PARAM,
255                             'Page number of the results to fetch.' +
256                             ' Default: 1',
257                             _in='query', default=1)
258 @api_ims_inventory_v1.param(
259     'all_fields',
260     'Set any value for show all fields. This value will cover "fields" ' +
261     'and "all_fields".',
262     _in='query')
263 @api_ims_inventory_v1.param(
264     'fields',
265     'Set fields to show, split by comma, "/" for parent and children.' +
266     ' Like "name,parent/children". This value will cover "exculde_fields".',
267     _in='query')
268 @api_ims_inventory_v1.param(
269     'exclude_fields',
270     'Set fields to exclude showing, split by comma, "/" for parent and ' +
271     'children. Like "name,parent/children". This value will cover ' +
272     '"exclude_default".',
273     _in='query')
274 @api_ims_inventory_v1.param(
275     'exclude_default',
276     'Exclude showing all default fields, Set "true" to enable.',
277     _in='query')
278 @api_ims_inventory_v1.param(
279     'filter',
280     'Filter of the query.',
281     _in='query')
282 class ResourcesListRouter(Resource):
283
284     model = ResourceDTO.resource_list
285
286     @api_ims_inventory_v1.marshal_list_with(model)
287     def get(self, resourcePoolID):
288         parser = reqparse.RequestParser()
289         parser.add_argument(PAGE_PARAM, location='args')
290         parser.add_argument('filter', location='args')
291         args = parser.parse_args()
292         kwargs = {}
293         # if args.per_page is not None:
294         #     kwargs['per_page'] = args.per_page
295         #     base_url = base_url + 'per_page=' + args.per_page + '&'
296         if args.nextpage_opaque_marker is not None:
297             kwargs['page'] = args.nextpage_opaque_marker
298         kwargs['filter'] = args.filter if args.filter is not None else ''
299
300         ret = ocloud_view.resources(resourcePoolID, bus.uow, **kwargs)
301         return link_header(request.full_path, ret)
302
303
304 @api_ims_inventory_v1.route(
305     "/resourcePools/<resourcePoolID>/resources/<resourceID>")
306 @api_ims_inventory_v1.param('resourcePoolID', 'ID of the resource pool')
307 @api_ims_inventory_v1.param('resourceID', 'ID of the resource')
308 @api_ims_inventory_v1.response(404, 'Resource not found')
309 @api_ims_inventory_v1.param(
310     'all_fields',
311     'Set any value for show all fields. This value will cover "fields" ' +
312     'and "all_fields".',
313     _in='query')
314 @api_ims_inventory_v1.param(
315     'fields',
316     'Set fields to show, split by comma, "/" for parent and children.' +
317     ' Like "name,parent/children". This value will cover "exculde_fields".',
318     _in='query')
319 @api_ims_inventory_v1.param(
320     'exclude_fields',
321     'Set fields to exclude showing, split by comma, "/" for parent and ' +
322     'children. Like "name,parent/children". This value will cover ' +
323     '"exclude_default".',
324     _in='query')
325 @api_ims_inventory_v1.param(
326     'exclude_default',
327     'Exclude showing all default fields, Set "true" to enable.',
328     _in='query')
329 class ResourceGetRouter(Resource):
330
331     # dto = ResourceDTO()
332     # model = dto.get_resource_get()
333     model = ResourceDTO.recursive_resource_mapping()
334
335     @api_ims_inventory_v1.doc('Get resource')
336     @api_ims_inventory_v1.marshal_with(model)
337     def get(self, resourcePoolID, resourceID):
338         result = ocloud_view.resource_one(resourceID, bus.uow)
339         if result is not None:
340             return result
341         api_ims_inventory_v1.abort(
342             404, "Resource {} doesn't exist".format(resourceID))
343
344
345 # ----------  DeploymentManagers ---------- #
346 @api_ims_inventory_v1.route("/deploymentManagers")
347 @api_ims_inventory_v1.param(PAGE_PARAM,
348                             'Page number of the results to fetch.' +
349                             ' Default: 1',
350                             _in='query', default=1)
351 @api_ims_inventory_v1.param(
352     'all_fields',
353     'Set any value for show all fields. This value will cover "fields" ' +
354     'and "all_fields".',
355     _in='query')
356 @api_ims_inventory_v1.param(
357     'fields',
358     'Set fields to show, split by comma, "/" for parent and children.' +
359     ' Like "name,parent/children". This value will cover "exculde_fields".',
360     _in='query')
361 @api_ims_inventory_v1.param(
362     'exclude_fields',
363     'Set fields to exclude showing, split by comma, "/" for parent and ' +
364     'children. Like "name,parent/children". This value will cover ' +
365     '"exclude_default".',
366     _in='query')
367 @api_ims_inventory_v1.param(
368     'exclude_default',
369     'Exclude showing all default fields, Set "true" to enable.',
370     _in='query')
371 @api_ims_inventory_v1.param(
372     'filter',
373     'Filter of the query.',
374     _in='query')
375 class DeploymentManagersListRouter(Resource):
376
377     model = DeploymentManagerDTO.deployment_manager_list
378
379     @api_ims_inventory_v1.marshal_list_with(model)
380     def get(self):
381         parser = reqparse.RequestParser()
382         parser.add_argument(PAGE_PARAM, location='args')
383         parser.add_argument('filter', location='args')
384         args = parser.parse_args()
385         kwargs = {}
386         if args.nextpage_opaque_marker is not None:
387             kwargs['page'] = args.nextpage_opaque_marker
388         kwargs['filter'] = args.filter if args.filter is not None else ''
389
390         ret = ocloud_view.deployment_managers(bus.uow, **kwargs)
391         return link_header(request.full_path, ret)
392
393
394 @api_ims_inventory_v1.route("/deploymentManagers/<deploymentManagerID>")
395 @api_ims_inventory_v1.param('deploymentManagerID',
396                             'ID of the deployment manager')
397 @api_ims_inventory_v1.param('profile', 'DMS profile: value supports "sol018"',
398                             _in='query')
399 @api_ims_inventory_v1.response(404, 'Deployment manager not found')
400 @api_ims_inventory_v1.param(
401     'all_fields',
402     'Set any value for show all fields. This value will cover "fields" ' +
403     'and "all_fields".',
404     _in='query')
405 @api_ims_inventory_v1.param(
406     'fields',
407     'Set fields to show, split by comma, "/" for parent and children.' +
408     ' Like "name,parent/children". This value will cover "exculde_fields".',
409     _in='query')
410 @api_ims_inventory_v1.param(
411     'exclude_fields',
412     'Set fields to exclude showing, split by comma, "/" for parent and ' +
413     'children. Like "name,parent/children". This value will cover ' +
414     '"exclude_default".',
415     _in='query')
416 @api_ims_inventory_v1.param(
417     'exclude_default',
418     'Exclude showing all default fields, Set "true" to enable.',
419     _in='query')
420 class DeploymentManagerGetRouter(Resource):
421
422     model = DeploymentManagerDTO.deployment_manager_get
423
424     @api_ims_inventory_v1.doc('Get deployment manager')
425     @api_ims_inventory_v1.marshal_with(model)
426     def get(self, deploymentManagerID):
427         parser = reqparse.RequestParser()
428         parser.add_argument('profile', location='args')
429         args = parser.parse_args()
430         profile = (
431             args.profile if args.profile is not None and args.profile != ''
432             else 'default')
433         result = ocloud_view.deployment_manager_one(
434             deploymentManagerID, bus.uow, profile)
435         if result is not None:
436             return result
437         api_ims_inventory_v1.abort(
438             404,
439             "Deployment manager {} doesn't exist".format(deploymentManagerID))
440
441
442 # ----------  Subscriptions ---------- #
443 @api_ims_inventory_v1.route("/subscriptions")
444 class SubscriptionsListRouter(Resource):
445
446     model = SubscriptionDTO.subscription_get
447     expect = SubscriptionDTO.subscription
448     post_resp = SubscriptionDTO.subscription_post_resp
449
450     @api_ims_inventory_v1.doc('List subscriptions')
451     @api_ims_inventory_v1.marshal_list_with(model)
452     @api_ims_inventory_v1.param(
453         PAGE_PARAM,
454         'Page number of the results to fetch. Default: 1',
455         _in='query', default=1)
456     @api_ims_inventory_v1.param(
457         'all_fields',
458         'Set any value for show all fields. This value will cover "fields" ' +
459         'and "all_fields".',
460         _in='query')
461     @api_ims_inventory_v1.param(
462         'fields',
463         'Set fields to show, split by comma, "/" for parent and children.' +
464         ' Like "name,parent/children". This value will cover' +
465         ' "exculde_fields".',
466         _in='query')
467     @api_ims_inventory_v1.param(
468         'exclude_fields',
469         'Set fields to exclude showing, split by comma, "/" for parent and ' +
470         'children. Like "name,parent/children". This value will cover ' +
471         '"exclude_default".',
472         _in='query')
473     @api_ims_inventory_v1.param(
474         'exclude_default',
475         'Exclude showing all default fields, Set "true" to enable.',
476         _in='query')
477     @api_ims_inventory_v1.param(
478         'filter',
479         'Filter of the query.',
480         _in='query')
481     def get(self):
482         parser = reqparse.RequestParser()
483         parser.add_argument(PAGE_PARAM, location='args')
484         parser.add_argument('filter', location='args')
485         args = parser.parse_args()
486         kwargs = {}
487         if args.nextpage_opaque_marker is not None:
488             kwargs['page'] = args.nextpage_opaque_marker
489         kwargs['filter'] = args.filter if args.filter is not None else ''
490
491         ret = ocloud_view.subscriptions(bus.uow, **kwargs)
492         return link_header(request.full_path, ret)
493
494     @api_ims_inventory_v1.doc('Create a subscription')
495     @api_ims_inventory_v1.expect(expect)
496     @api_ims_inventory_v1.marshal_with(post_resp, code=201)
497     def post(self):
498         data = api_ims_inventory_v1.payload
499         result = ocloud_view.subscription_create(data, bus.uow)
500         return result, 201
501
502
503 @api_ims_inventory_v1.route("/subscriptions/<subscriptionID>")
504 @api_ims_inventory_v1.param('subscriptionID', 'ID of the subscription')
505 @api_ims_inventory_v1.response(404, 'Subscription not found')
506 class SubscriptionGetDelRouter(Resource):
507
508     model = SubscriptionDTO.subscription_get
509
510     @api_ims_inventory_v1.doc('Get subscription by ID')
511     @api_ims_inventory_v1.marshal_with(model)
512     @api_ims_inventory_v1.param(
513         'all_fields',
514         'Set any value for show all fields. This value will cover "fields" ' +
515         'and "all_fields".',
516         _in='query')
517     @api_ims_inventory_v1.param(
518         'fields',
519         'Set fields to show, split by comma, "/" for parent and children.' +
520         ' Like "name,parent/children". This value will cover' +
521         ' "exculde_fields".',
522         _in='query')
523     @api_ims_inventory_v1.param(
524         'exclude_fields',
525         'Set fields to exclude showing, split by comma, "/" for parent and ' +
526         'children. Like "name,parent/children". This value will cover ' +
527         '"exclude_default".',
528         _in='query')
529     @api_ims_inventory_v1.param(
530         'exclude_default',
531         'Exclude showing all default fields, Set "true" to enable.',
532         _in='query')
533     def get(self, subscriptionID):
534         result = ocloud_view.subscription_one(
535             subscriptionID, bus.uow)
536         if result is not None:
537             return result
538         api_ims_inventory_v1.abort(404, "Subscription {} doesn't exist".format(
539             subscriptionID))
540
541     @api_ims_inventory_v1.doc('Delete subscription by ID')
542     @api_ims_inventory_v1.response(204, 'Subscription deleted')
543     def delete(self, subscriptionID):
544         result = ocloud_view.subscription_delete(subscriptionID, bus.uow)
545         return result, 204