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