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