Fix INF-371 inventoryChange notification of the resourceType, resourcePool, Dms
[pti/o2.git] / o2ims / views / ocloud_view.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 import filecmp
16 import os.path
17 import uuid
18 import yaml
19 from datetime import datetime
20 import shutil
21
22 from o2common.service import unit_of_work
23 from o2common.config import config
24 from o2common.views.view import gen_filter, check_filter
25 from o2common.views.pagination_view import Pagination
26 from o2common.views.route_exception import BadRequestException, \
27     NotFoundException
28
29 from o2ims.domain import ocloud
30 from o2ims.views.ocloud_dto import SubscriptionDTO
31 from o2ims.domain.subscription_obj import Subscription
32
33 from o2common.helper import o2logging
34 logger = o2logging.get_logger(__name__)
35
36
37 def oclouds(uow: unit_of_work.AbstractUnitOfWork):
38     with uow:
39         li = uow.oclouds.list()
40     return [r.serialize() for r in li]
41
42
43 def ocloud_one(ocloudid: str, uow: unit_of_work.AbstractUnitOfWork):
44     with uow:
45         first = uow.oclouds.get(ocloudid)
46         return first.serialize() if first is not None else None
47
48
49 def resource_types(uow: unit_of_work.AbstractUnitOfWork, **kwargs):
50     pagination = Pagination(**kwargs)
51     query_kwargs = pagination.get_pagination()
52     args = gen_filter(ocloud.ResourceType,
53                       kwargs['filter']) if 'filter' in kwargs else []
54     with uow:
55         li = uow.resource_types.list_with_count(*args, **query_kwargs)
56     return pagination.get_result(li)
57
58
59 def resource_type_one(resourceTypeId: str,
60                       uow: unit_of_work.AbstractUnitOfWork):
61     with uow:
62         first = uow.resource_types.get(resourceTypeId)
63         return first.serialize() if first is not None else None
64
65
66 def resource_pools(uow: unit_of_work.AbstractUnitOfWork, **kwargs):
67     pagination = Pagination(**kwargs)
68     query_kwargs = pagination.get_pagination()
69     args = gen_filter(ocloud.ResourcePool,
70                       kwargs['filter']) if 'filter' in kwargs else []
71     with uow:
72         li = uow.resource_pools.list_with_count(*args, **query_kwargs)
73     return pagination.get_result(li)
74
75
76 def resource_pool_one(resourcePoolId: str,
77                       uow: unit_of_work.AbstractUnitOfWork):
78     with uow:
79         first = uow.resource_pools.get(resourcePoolId)
80         return first.serialize() if first else None
81
82
83 def resources(resourcePoolId: str, uow: unit_of_work.AbstractUnitOfWork,
84               **kwargs):
85     with uow:
86         first = uow.resource_pools.get(resourcePoolId)
87     if first is None:
88         raise NotFoundException("ResourcePool {} doesn't exist".format(
89             resourcePoolId))
90     pagination = Pagination(**kwargs)
91     # filter key should be the same with database name
92     query_kwargs = pagination.get_pagination()
93     if 'resourceTypeName' in kwargs:
94         resource_type_name = kwargs['resourceTypeName']
95         with uow:
96             # res_types = uow.resource_types.list()
97             # restype_ids = [
98             #     restype.resourceTypeId for restype in res_types
99             #     if resourceTypeName == restype.name]
100             # restype_id = '' if len(restype_ids) == 0 else restype_ids[0]
101             res_type = uow.resource_types.get_by_name(resource_type_name)
102             restype_id = '' if res_type is None else res_type.resourceTypeId
103         query_kwargs['resourceTypeId'] = restype_id
104     args = gen_filter(
105         ocloud.Resource, kwargs['filter']) if 'filter' in kwargs else []
106
107     if 'parentId' in kwargs:
108         query_kwargs['parentId'] = kwargs['parentId']
109     if 'sort' in kwargs:
110         query_kwargs['sort'] = kwargs['sort']
111
112     with uow:
113         ret = uow.resources.list_with_count(
114             resourcePoolId, *args, **query_kwargs)
115
116     return pagination.get_result(ret)
117
118
119 def resource_one(resourceId: str,
120                  uow: unit_of_work.AbstractUnitOfWork, resourcePoolId: str):
121     with uow:
122         resoucePool = uow.resource_pools.get(resourcePoolId)
123     if resoucePool is None:
124         raise NotFoundException("ResourcePool {} doesn't exist".format(
125             resourcePoolId))
126
127     first = uow.resources.get(resourceId)
128     if first is None:
129         raise NotFoundException("Resource {} doesn't exist".format(
130             resourceId))
131     return first.serialize()
132
133
134 def deployment_managers(uow: unit_of_work.AbstractUnitOfWork, **kwargs):
135     pagination = Pagination(**kwargs)
136     query_kwargs = pagination.get_pagination()
137     args = gen_filter(ocloud.DeploymentManager,
138                       kwargs['filter']) if 'filter' in kwargs else []
139     with uow:
140         li = uow.deployment_managers.list_with_count(*args, **query_kwargs)
141     return pagination.get_result(li)
142
143
144 def deployment_manager_one(deploymentManagerId: str,
145                            uow: unit_of_work.AbstractUnitOfWork,
146                            profile: str =
147                            ocloud.DeploymentManagerProfileDefault):
148     profile = profile.lower()
149     with uow:
150         first = uow.deployment_managers.get(deploymentManagerId)
151         if first is None:
152             return first
153         result = first.serialize()
154         if result is None:
155             return None
156
157     profile_data = result.pop("profile", None)
158     profiles = config.get_dms_support_profiles()
159     if profile not in profiles:
160         return ""
161
162     extensions = {
163         'profileName': profile
164     }
165     if ocloud.DeploymentManagerProfileDefault == profile \
166             or ocloud.DeploymentManagerProfileSOL018 == profile:
167         result['serviceUri'] = \
168             profile_data['cluster_api_endpoint']
169         extensions['profileData'] = profile_data
170     elif ocloud.DeploymentManagerProfileSOL018HelmCLI == profile:
171         result['serviceUri'] = \
172             profile_data['cluster_api_endpoint']
173
174         helmcli_profile = dict()
175         helmcli_profile["helmcli_host_with_port"], helmcli_profile[
176             "helmcli_username"], helmcli_profile["helmcli_password"] = \
177             config.get_helmcli_access()
178         helmcli_profile["helmcli_kubeconfig"] = _gen_kube_config(
179             deploymentManagerId, profile_data)
180         extensions['profileData'] = helmcli_profile
181     else:
182         return ""
183
184     result['extensions'] = extensions
185     return result
186
187
188 def _gen_kube_config(dmId: str, kubeconfig: dict) -> dict:
189
190     data = config.gen_k8s_config_dict(
191         kubeconfig.pop('cluster_api_endpoint', None),
192         kubeconfig.pop('cluster_ca_cert', None),
193         kubeconfig.pop('admin_user', None),
194         kubeconfig.pop('admin_client_cert', None),
195         kubeconfig.pop('admin_client_key', None),
196     )
197
198     # Generate a random key for tmp kube config file
199     # letters = string.ascii_uppercase
200     # random_key = ''.join(random.choice(letters) for i in range(10))
201     name_key = dmId[:8]
202
203     # Get datetime of now as tag of the tmp file
204     current_time = datetime.now().strftime("%Y%m%d%H%M%S")
205     tmp_file_name = 'kubeconfig_' + name_key + "_" + current_time
206     kube_config_name = 'kubeconfig_' + name_key + '.config'
207
208     # write down the yaml file of kubectl into tmp folder
209     with open('/tmp/' + tmp_file_name, 'w') as file:
210         yaml.dump(data, file)
211
212     # generate the kube config file if not exist or update the file if it
213     # changes
214     if not os.path.exists('/configs/' + kube_config_name) or not \
215             filecmp.cmp('/tmp/'+tmp_file_name, '/configs/'+kube_config_name):
216         shutil.move(os.path.join('/tmp', tmp_file_name),
217                     os.path.join('/configs', kube_config_name))
218
219     return '/configs/'+kube_config_name
220
221
222 def subscriptions(uow: unit_of_work.AbstractUnitOfWork, **kwargs):
223     pagination = Pagination(**kwargs)
224     query_kwargs = pagination.get_pagination()
225     args = gen_filter(Subscription,
226                       kwargs['filter']) if 'filter' in kwargs else []
227     with uow:
228         li = uow.subscriptions.list_with_count(*args, **query_kwargs)
229     return pagination.get_result(li)
230
231
232 def subscription_one(subscriptionId: str,
233                      uow: unit_of_work.AbstractUnitOfWork):
234     with uow:
235         first = uow.subscriptions.get(subscriptionId)
236         return first.serialize() if first is not None else None
237
238
239 def subscription_create(subscriptionDto: SubscriptionDTO.subscription_create,
240                         uow: unit_of_work.AbstractUnitOfWork):
241     filter = subscriptionDto.get('filter', '')
242     consumer_subs_id = subscriptionDto.get('consumerSubscriptionId', '')
243
244     check_filter(ocloud.Resource, filter)
245
246     sub_uuid = str(uuid.uuid4())
247     subscription = Subscription(
248         sub_uuid, subscriptionDto['callback'],
249         consumer_subs_id, filter)
250     with uow:
251         args = list()
252         args.append(getattr(Subscription, 'callback')
253                     == subscriptionDto['callback'])
254         args.append(getattr(Subscription, 'filter') == filter)
255         args.append(getattr(Subscription,
256                     'consumerSubscriptionId') == consumer_subs_id)
257         count, _ = uow.subscriptions.list_with_count(*args)
258         if count > 0:
259             raise BadRequestException("The value of parameters is duplicated")
260         uow.subscriptions.add(subscription)
261         uow.commit()
262         first = uow.subscriptions.get(sub_uuid)
263         return first.serialize()
264
265
266 def subscription_delete(subscriptionId: str,
267                         uow: unit_of_work.AbstractUnitOfWork):
268     with uow:
269         first = uow.subscriptions.get(subscriptionId)
270         if not first:
271             raise NotFoundException(
272                 "Subscription {} not found.".format(subscriptionId))
273         uow.subscriptions.delete(subscriptionId)
274         uow.commit()
275     return True