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