Code Coverage

Cobertura Coverage Report > osmclient.sol005 >

vim.py

Trend

File Coverage summary

NameClassesLinesConditionals
vim.py
100%
1/1
12%
19/157
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
vim.py
12%
19/157
N/A

Source

osmclient/sol005/vim.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
6 #    not use this file except in compliance with the License. You may obtain
7 #    a copy of the License at
8 #
9 #         http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #    Unless required by applicable law or agreed to in writing, software
12 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 #    License for the specific language governing permissions and limitations
15 #    under the License.
16
17 1 """
18 OSM vim API handling
19 """
20
21 1 from osmclient.common import utils
22 1 from osmclient.common import wait as WaitForStatus
23 1 from osmclient.common.exceptions import ClientException
24 1 from osmclient.common.exceptions import NotFound
25 1 import yaml
26 1 import json
27 1 import logging
28
29
30 1 class Vim(object):
31 1     def __init__(self, http=None, client=None):
32 0         self._http = http
33 0         self._client = client
34 0         self._logger = logging.getLogger("osmclient")
35 0         self._apiName = "/admin"
36 0         self._apiVersion = "/v1"
37 0         self._apiResource = "/vim_accounts"
38 0         self._apiBase = "{}{}{}".format(
39             self._apiName, self._apiVersion, self._apiResource
40         )
41
42     # VIM '--wait' option
43 1     def _wait(self, id, wait_time, deleteFlag=False):
44 0         self._logger.debug("")
45 0         self._client.get_token()
46         # Endpoint to get operation status
47 0         apiUrlStatus = "{}{}{}".format(self._apiName, self._apiVersion, "/vim_accounts")
48         # Wait for status for VIM instance creation/deletion
49 0         if isinstance(wait_time, bool):
50 0             wait_time = WaitForStatus.TIMEOUT_VIM_OPERATION
51 0         WaitForStatus.wait_for_status(
52             "VIM",
53             str(id),
54             wait_time,
55             apiUrlStatus,
56             self._http.get2_cmd,
57             deleteFlag=deleteFlag,
58         )
59
60 1     def _get_id_for_wait(self, name):
61         """Returns id of name, or the id itself if given as argument"""
62 0         self._logger.debug("")
63 0         self._client.get_token()
64 0         for vim in self.list():
65 0             if name == vim["uuid"] or name == vim["name"]:
66 0                 return vim["uuid"]
67 0         return ""
68
69 1     def create(
70         self,
71         name,
72         vim_access,
73         config={},
74         sdn_controller=None,
75         sdn_port_mapping=None,
76         wait=False,
77     ):
78 0         vca_id = None
79
80 0         def get_vca_id(vca):
81 0             vca = self._client.vca.get(vca)
82 0             if vca is None:
83 0                 raise NotFound("cannot find vca '{}'".format(vca))
84 0             return vca["_id"]
85
86 0         self._logger.debug("")
87 0         self._client.get_token()
88 0         if "vca" in vim_access:
89 0             vca_id = get_vca_id(vim_access["vca"])
90 0         if "vim-type" not in vim_access:
91             # 'openstack' not in vim_access['vim-type']):
92 0             raise Exception("vim type not provided")
93 0         vim_account = {}
94 0         vim_account["name"] = name
95 0         vim_account = self.update_vim_account_dict(vim_account, vim_access)
96 0         if vca_id:
97 0             vim_account["vca"] = vca_id
98 0         vim_config = config
99 0         if sdn_controller:
100 0             sdnc = self._client.sdnc.get(sdn_controller)
101 0             vim_config["sdn-controller"] = sdnc["_id"]
102 0         if sdn_port_mapping:
103 0             with open(sdn_port_mapping, "r") as f:
104 0                 vim_config["sdn-port-mapping"] = yaml.safe_load(f.read())
105 0         if vim_config:
106 0             vim_account["config"] = vim_config
107             # vim_account['config'] = json.dumps(vim_config)
108
109 0         http_code, resp = self._http.post_cmd(
110             endpoint=self._apiBase, postfields_dict=vim_account
111         )
112         # print('HTTP CODE: {}'.format(http_code))
113         # print('RESP: {}'.format(resp))
114         # if http_code in (200, 201, 202, 204):
115 0         if resp:
116 0             resp = json.loads(resp)
117 0         if not resp or "id" not in resp:
118 0             raise ClientException("unexpected response from server - {}".format(resp))
119 0         if wait:
120             # Wait for status for VIM instance creation
121 0             self._wait(resp.get("id"), wait)
122 0         print(resp["id"])
123         # else:
124         #    msg = ""
125         #    if resp:
126         #        try:
127         #            msg = json.loads(resp)
128         #        except ValueError:
129         #            msg = resp
130         #    raise ClientException("failed to create vim {} - {}".format(name, msg))
131
132 1     def update(
133         self,
134         vim_name,
135         vim_account,
136         config,
137         sdn_controller,
138         sdn_port_mapping,
139         wait=False,
140     ):
141 0         self._logger.debug("")
142 0         self._client.get_token()
143 0         vim = self.get(vim_name)
144 0         vim_id_for_wait = self._get_id_for_wait(vim_name)
145 0         vim_config = {}
146 0         if config is not None:
147 0             if not config and (sdn_controller or sdn_port_mapping):
148                 # If config is empty (clearing config)
149 0                 raise ClientException(
150                     "clearing config is incompatible with updating SDN info"
151                 )
152 0             vim_config = config
153 0         if sdn_controller == "":
154 0             vim_config["sdn-controller"] = None
155 0             vim_config["sdn-port-mapping"] = None
156         else:
157 0             if sdn_controller:
158 0                 sdnc = self._client.sdnc.get(sdn_controller)
159 0                 vim_config["sdn-controller"] = sdnc["_id"]
160 0             if sdn_port_mapping:
161 0                 with open(sdn_port_mapping, "r") as f:
162 0                     vim_config["sdn-port-mapping"] = yaml.safe_load(f.read())
163 0         vim_account["config"] = vim_config
164         # vim_account['config'] = json.dumps(vim_config)
165 0         http_code, resp = self._http.patch_cmd(
166             endpoint="{}/{}".format(self._apiBase, vim["_id"]),
167             postfields_dict=vim_account,
168         )
169         # print('HTTP CODE: {}'.format(http_code))
170         # print('RESP: {}'.format(resp))
171         # if http_code in (200, 201, 202, 204):
172 0         if wait:
173             # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
174             # Use the previously obtained id instead.
175 0             wait_id = vim_id_for_wait
176             # Wait for status for VI instance update
177 0             self._wait(wait_id, wait)
178         # else:
179         #     pass
180         # else:
181         #    msg = ""
182         #    if resp:
183         #        try:
184         #            msg = json.loads(resp)
185         #        except ValueError:
186         #            msg = resp
187         #    raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
188
189 1     def update_vim_account_dict(self, vim_account, vim_access):
190 0         self._logger.debug("")
191 0         vim_account["vim_type"] = vim_access["vim-type"]
192 0         vim_account["description"] = vim_access["description"]
193 0         vim_account["vim_url"] = vim_access["vim-url"] or "null"
194 0         vim_account["vim_user"] = vim_access["vim-username"] or "null"
195 0         vim_account["vim_password"] = vim_access["vim-password"] or "null"
196 0         vim_account["vim_tenant_name"] = vim_access["vim-tenant-name"] or "null"
197 0         if "prometheus-config" in vim_access:
198 0             vim_account["prometheus-config"] = vim_access["prometheus-config"]
199 0         return vim_account
200
201 1     def get_id(self, name):
202         """Returns a VIM id from a VIM name"""
203 0         self._logger.debug("")
204 0         for vim in self.list():
205 0             if name == vim["name"]:
206 0                 return vim["uuid"]
207 0         raise NotFound("vim {} not found".format(name))
208
209 1     def delete(self, vim_name, force=False, wait=False):
210 0         self._logger.debug("")
211 0         self._client.get_token()
212 0         vim_id = vim_name
213 0         if not utils.validate_uuid4(vim_name):
214 0             vim_id = self.get_id(vim_name)
215 0         querystring = ""
216 0         if force:
217 0             querystring = "?FORCE=True"
218 0         http_code, resp = self._http.delete_cmd(
219             "{}/{}{}".format(self._apiBase, vim_id, querystring)
220         )
221         # print('HTTP CODE: {}'.format(http_code))
222         # print('RESP: {}'.format(resp))
223 0         if http_code == 202:
224 0             if wait:
225                 # When deleting an account, 'resp' may be None.
226                 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
227 0                 wait_id = vim_id
228 0                 if resp:
229 0                     resp = json.loads(resp)
230 0                     wait_id = resp.get("id")
231                 # Wait for status for VIM account deletion
232 0                 self._wait(wait_id, wait, deleteFlag=True)
233             else:
234 0                 print("Deletion in progress")
235 0         elif http_code == 204:
236 0             print("Deleted")
237         else:
238 0             msg = resp or ""
239             # if resp:
240             #     try:
241             #         msg = json.loads(resp)
242             #     except ValueError:
243             #         msg = resp
244 0             raise ClientException("failed to delete vim {} - {}".format(vim_name, msg))
245
246 1     def list(self, filter=None):
247         """Returns a list of VIM accounts"""
248 0         self._logger.debug("")
249 0         self._client.get_token()
250 0         filter_string = ""
251 0         if filter:
252 0             filter_string = "?{}".format(filter)
253 0         _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
254 0         if not resp:
255 0             return list()
256 0         vim_accounts = json.loads(resp)
257 0         for datacenter in vim_accounts:
258 0             datacenter["uuid"] = datacenter.get("_id")  # backward compatibility?
259 0         return vim_accounts
260
261 1     def get(self, name):
262         """Returns a VIM account based on name or id"""
263 0         self._logger.debug("")
264 0         self._client.get_token()
265 0         vim_id = name
266 0         if not utils.validate_uuid4(name):
267 0             vim_id = self.get_id(name)
268 0         try:
269 0             _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, vim_id))
270 0             if resp:
271 0                 resp = json.loads(resp)
272 0             if not resp or "_id" not in resp:
273 0                 raise ClientException("failed to get vim info: {}".format(resp))
274 0             return resp
275 0         except NotFound:
276 0             raise NotFound("vim '{}' not found".format(name))