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