Merge "Fix INF-351 ocloud serviceUri is wrong about protocol"
[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     profiles = config.get_dms_support_profiles()
146     if profile not in profiles:
147         return ""
148
149     extensions = {
150         'profileName': profile
151     }
152     if ocloud.DeploymentManagerProfileDefault == profile \
153             or ocloud.DeploymentManagerProfileSOL018 == profile:
154         result['serviceUri'] = \
155             profile_data['cluster_api_endpoint']
156         extensions['profileData'] = profile_data
157     elif ocloud.DeploymentManagerProfileSOL018HelmCLI == profile:
158         result['serviceUri'] = \
159             profile_data['cluster_api_endpoint']
160
161         helmcli_profile = dict()
162         helmcli_profile["helmcli_host_with_port"], helmcli_profile[
163             "helmcli_username"], helmcli_profile["helmcli_password"] = \
164             config.get_helmcli_access()
165         helmcli_profile["helmcli_kubeconfig"] = _gen_kube_config(
166             deploymentManagerId, profile_data)
167         extensions['profileData'] = helmcli_profile
168     else:
169         return ""
170
171     result['extensions'] = extensions
172     return result
173
174
175 def _gen_kube_config(dmId: str, kubeconfig: dict) -> dict:
176
177     data = config.gen_k8s_config_dict(
178         kubeconfig.pop('cluster_api_endpoint', None),
179         kubeconfig.pop('cluster_ca_cert', None),
180         kubeconfig.pop('admin_user', None),
181         kubeconfig.pop('admin_client_cert', None),
182         kubeconfig.pop('admin_client_key', None),
183     )
184
185     # Generate a random key for tmp kube config file
186     # letters = string.ascii_uppercase
187     # random_key = ''.join(random.choice(letters) for i in range(10))
188     name_key = dmId[:8]
189
190     # Get datetime of now as tag of the tmp file
191     current_time = datetime.now().strftime("%Y%m%d%H%M%S")
192     tmp_file_name = 'kubeconfig_' + name_key + "_" + current_time
193     kube_config_name = 'kubeconfig_' + name_key + '.config'
194
195     # write down the yaml file of kubectl into tmp folder
196     with open('/tmp/' + tmp_file_name, 'w') as file:
197         yaml.dump(data, file)
198
199     # generate the kube config file if not exist or update the file if it
200     # changes
201     if not os.path.exists('/configs/' + kube_config_name) or not \
202             filecmp.cmp('/tmp/'+tmp_file_name, '/configs/'+kube_config_name):
203         shutil.move(os.path.join('/tmp', tmp_file_name),
204                     os.path.join('/configs', kube_config_name))
205
206     return '/configs/'+kube_config_name
207
208
209 def subscriptions(uow: unit_of_work.AbstractUnitOfWork, **kwargs):
210     pagination = Pagination(**kwargs)
211     query_kwargs = pagination.get_pagination()
212     args = gen_filter(Subscription,
213                       kwargs['filter']) if 'filter' in kwargs else []
214     with uow:
215         li = uow.subscriptions.list_with_count(*args, **query_kwargs)
216     return pagination.get_result(li)
217
218
219 def subscription_one(subscriptionId: str,
220                      uow: unit_of_work.AbstractUnitOfWork):
221     with uow:
222         first = uow.subscriptions.get(subscriptionId)
223         return first.serialize() if first is not None else None
224
225
226 def subscription_create(subscriptionDto: SubscriptionDTO.subscription_create,
227                         uow: unit_of_work.AbstractUnitOfWork):
228     filter = subscriptionDto.get('filter', '')
229     consumer_subs_id = subscriptionDto.get('consumerSubscriptionId', '')
230
231     check_filter(ocloud.Resource, filter)
232
233     sub_uuid = str(uuid.uuid4())
234     subscription = Subscription(
235         sub_uuid, subscriptionDto['callback'],
236         consumer_subs_id, filter)
237     with uow:
238         args = list()
239         args.append(getattr(Subscription, 'callback')
240                     == subscriptionDto['callback'])
241         args.append(getattr(Subscription, 'filter') == filter)
242         args.append(getattr(Subscription,
243                     'consumerSubscriptionId') == consumer_subs_id)
244         count, _ = uow.alarm_subscriptions.list_with_count(*args)
245         if count > 0:
246             raise BadRequestException("The value of parameters is duplicated")
247         uow.subscriptions.add(subscription)
248         uow.commit()
249         first = uow.subscriptions.get(sub_uuid)
250         return first.serialize()
251
252
253 def subscription_delete(subscriptionId: str,
254                         uow: unit_of_work.AbstractUnitOfWork):
255     with uow:
256         uow.subscriptions.delete(subscriptionId)
257         uow.commit()
258     return True