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