Improved Kubernetes management
[osm/osmclient.git] / osmclient / sol005 / k8scluster.py
1 #
2 # Licensed under the Apache License, Version 2.0 (the "License"); you may
3 # not use this file except in compliance with the License. You may obtain
4 # a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 # License for the specific language governing permissions and limitations
12 # under the License.
13 #
14
15 """
16 OSM K8s cluster API handling
17 """
18
19 from osmclient.common import utils
20 from osmclient.common import wait as WaitForStatus
21 from osmclient.common.exceptions import NotFound
22 from osmclient.common.exceptions import ClientException
23 import json
24 import logging
25
26
27 class K8scluster(object):
28 def __init__(self, http=None, client=None):
29 self._http = http
30 self._client = client
31 self._logger = logging.getLogger("osmclient.k8scluster")
32 self._apiName = "/admin"
33 self._apiVersion = "/v1"
34 self._apiResource = "/k8sclusters"
35 self._apiBase = "{}{}{}".format(
36 self._apiName, self._apiVersion, self._apiResource
37 )
38
39 def _get_vim_account(self, vim_account):
40 vim = self._client.vim.get(vim_account)
41 if vim is None:
42 raise NotFound("cannot find vim account '{}'".format(vim_account))
43 return vim
44
45 # K8S '--wait' option
46 def _wait(self, id, wait_time, deleteFlag=False):
47 self._logger.debug("")
48 self._client.get_token()
49 # Endpoint to get operation status
50 apiUrlStatus = "{}{}{}".format(self._apiName, self._apiVersion, self._apiResource)
51 # Wait for status for VIM instance creation/deletion
52 if isinstance(wait_time, bool):
53 wait_time = WaitForStatus.TIMEOUT_VIM_OPERATION
54 WaitForStatus.wait_for_status(
55 "K8S",
56 str(id),
57 wait_time,
58 apiUrlStatus,
59 self._http.get2_cmd,
60 deleteFlag=deleteFlag,
61 )
62
63 def create(self, name, k8s_cluster, wait=False):
64 self._client.get_token()
65 vim_account = self._get_vim_account(k8s_cluster["vim_account"])
66 k8s_cluster["vim_account"] = vim_account["_id"]
67 if "vca" in vim_account:
68 k8s_cluster["vca_id"] = vim_account["vca"]
69 http_code, resp = self._http.post_cmd(
70 endpoint=self._apiBase, postfields_dict=k8s_cluster
71 )
72
73 self._logger.debug('HTTP CODE: {}'.format(http_code))
74 self._logger.debug('RESP: {}'.format(resp))
75
76 if resp:
77 resp = json.loads(resp)
78 if not resp or "id" not in resp:
79 raise ClientException("unexpected response from server - {}".format(resp))
80 if wait:
81 # Wait for status for VIM instance creation
82 self._wait(resp.get("id"), wait)
83 print(resp["id"])
84 # else:
85 # msg = ""
86 # if resp:
87 # try:
88 # msg = json.loads(resp)
89 # except ValueError:
90 # msg = resp
91 # raise ClientException("failed to add K8s cluster {} - {}".format(name, msg))
92
93 def update(self, name, k8s_cluster, wait=False):
94 self._client.get_token()
95 cluster = self.get(name)
96 if "vim_account" in k8s_cluster:
97 vim_account = self._get_vim_account(k8s_cluster["vim_account"])
98 k8s_cluster["vim_account"] = vim_account["_id"]
99 if "vca" in vim_account:
100 k8s_cluster["vca_id"] = vim_account["vca"]
101 http_code, resp = self._http.patch_cmd(
102 endpoint="{}/{}".format(self._apiBase, cluster["_id"]),
103 postfields_dict=k8s_cluster,
104 )
105
106 if wait:
107 wait_id = cluster["_id"]
108 self._wait(wait_id, wait)
109
110 self._logger.debug('HTTP CODE: {}'.format(http_code))
111 self._logger.debug('RESP: {}'.format(resp))
112
113 if http_code in (200, 201, 202, 204):
114 print("Updated")
115 else:
116 msg = ""
117 if resp:
118 try:
119 msg = json.loads(resp)
120 except ValueError:
121 msg = resp
122 raise ClientException("failed to update K8s cluster {} - {}".format(name, msg))
123
124 def get_id(self, name):
125 """Returns a K8s cluster id from a K8s cluster name"""
126 for cluster in self.list():
127 if name == cluster["name"]:
128 return cluster["_id"]
129 raise NotFound("K8s cluster {} not found".format(name))
130
131 def delete(self, name, force=False, wait=False):
132 self._client.get_token()
133 cluster_id = name
134 if not utils.validate_uuid4(name):
135 cluster_id = self.get_id(name)
136 querystring = ""
137 if force:
138 querystring = "?FORCE=True"
139 http_code, resp = self._http.delete_cmd(
140 "{}/{}{}".format(self._apiBase, cluster_id, querystring)
141 )
142
143 self._logger.debug('HTTP CODE: {}'.format(http_code))
144 self._logger.debug('RESP: {}'.format(resp))
145
146 if http_code == 202:
147 if wait:
148 wait_id = cluster_id
149
150 if resp:
151 resp = json.loads(resp)
152 wait_id = resp.get("id")
153
154 self._wait(wait_id, wait, deleteFlag=True)
155 else:
156 print("Deletion in progress")
157 elif http_code == 204:
158 print("Deleted")
159 else:
160 msg = resp or ""
161 # if resp:
162 # try:
163 # msg = json.loads(resp)
164 # except ValueError:
165 # msg = resp
166 raise ClientException(
167 "failed to delete K8s cluster {} - {}".format(name, msg)
168 )
169
170 def list(self, filter=None):
171 """Returns a list of K8s clusters"""
172 self._client.get_token()
173 filter_string = ""
174 if filter:
175 filter_string = "?{}".format(filter)
176 _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
177 if resp:
178 return json.loads(resp)
179 return list()
180
181 def get(self, name):
182 """Returns a K8s cluster based on name or id"""
183 self._client.get_token()
184 cluster_id = name
185 if not utils.validate_uuid4(name):
186 cluster_id = self.get_id(name)
187 try:
188 _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, cluster_id))
189 if resp:
190 resp = json.loads(resp)
191 if not resp or "_id" not in resp:
192 raise ClientException("failed to get K8s cluster info: {}".format(resp))
193 return resp
194 except NotFound:
195 raise NotFound("K8s cluster {} not found".format(name))