Code Coverage

Cobertura Coverage Report > osmclient.sol005 >

vim.py

Trend

Classes100%
 
Lines12%
   
Conditionals100%
 

File Coverage summary

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

Coverage Breakdown by Class

NameLinesConditionals
vim.py
12%
19/160
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"]:
66 0                 return vim["uuid"]
67 0         for vim in self.list():
68 0             if name == vim["name"]:
69 0                 return vim["uuid"]
70 0         return ""
71
72 1     def create(
73         self,
74         name,
75         vim_access,
76         config={},
77         sdn_controller=None,
78         sdn_port_mapping=None,
79         wait=False,
80     ):
81 0         vca_id = None
82
83 0         def get_vca_id(vca):
84 0             vca = self._client.vca.get(vca)
85 0             if vca is None:
86 0                 raise NotFound("cannot find vca '{}'".format(vca))
87 0             return vca["_id"]
88
89 0         self._logger.debug("")
90 0         self._client.get_token()
91 0         if "vca" in vim_access:
92 0             vca_id = get_vca_id(vim_access["vca"])
93 0         if "vim-type" not in vim_access:
94             # 'openstack' not in vim_access['vim-type']):
95 0             raise Exception("vim type not provided")
96 0         vim_account = {}
97 0         vim_account["name"] = name
98 0         vim_account = self.update_vim_account_dict(vim_account, vim_access)
99 0         if vca_id:
100 0             vim_account["vca"] = vca_id
101 0         vim_config = config
102 0         if sdn_controller:
103 0             sdnc = self._client.sdnc.get(sdn_controller)
104 0             vim_config["sdn-controller"] = sdnc["_id"]
105 0         if sdn_port_mapping:
106 0             with open(sdn_port_mapping, "r") as f:
107 0                 vim_config["sdn-port-mapping"] = yaml.safe_load(f.read())
108 0         if vim_config:
109 0             vim_account["config"] = vim_config
110             # vim_account['config'] = json.dumps(vim_config)
111
112 0         http_code, resp = self._http.post_cmd(
113             endpoint=self._apiBase, postfields_dict=vim_account
114         )
115         # print('HTTP CODE: {}'.format(http_code))
116         # print('RESP: {}'.format(resp))
117         # if http_code in (200, 201, 202, 204):
118 0         if resp:
119 0             resp = json.loads(resp)
120 0         if not resp or "id" not in resp:
121 0             raise ClientException("unexpected response from server - {}".format(resp))
122 0         if wait:
123             # Wait for status for VIM instance creation
124 0             self._wait(resp.get("id"), wait)
125 0         print(resp["id"])
126         # else:
127         #    msg = ""
128         #    if resp:
129         #        try:
130         #            msg = json.loads(resp)
131         #        except ValueError:
132         #            msg = resp
133         #    raise ClientException("failed to create vim {} - {}".format(name, msg))
134
135 1     def update(
136         self,
137         vim_name,
138         vim_account,
139         config,
140         sdn_controller,
141         sdn_port_mapping,
142         wait=False,
143     ):
144 0         self._logger.debug("")
145 0         self._client.get_token()
146 0         vim = self.get(vim_name)
147 0         vim_id_for_wait = self._get_id_for_wait(vim_name)
148 0         vim_config = {}
149 0         if config is not None:
150 0             if not config and (sdn_controller or sdn_port_mapping):
151                 # If config is empty (clearing config)
152 0                 raise ClientException(
153                     "clearing config is incompatible with updating SDN info"
154                 )
155 0             vim_config = config
156 0         if sdn_controller == "":
157 0             vim_config["sdn-controller"] = None
158 0             vim_config["sdn-port-mapping"] = None
159         else:
160 0             if sdn_controller:
161 0                 sdnc = self._client.sdnc.get(sdn_controller)
162 0                 vim_config["sdn-controller"] = sdnc["_id"]
163 0             if sdn_port_mapping:
164 0                 with open(sdn_port_mapping, "r") as f:
165 0                     vim_config["sdn-port-mapping"] = yaml.safe_load(f.read())
166 0         vim_account["config"] = vim_config
167         # vim_account['config'] = json.dumps(vim_config)
168 0         http_code, resp = self._http.patch_cmd(
169             endpoint="{}/{}".format(self._apiBase, vim["_id"]),
170             postfields_dict=vim_account,
171         )
172         # print('HTTP CODE: {}'.format(http_code))
173         # print('RESP: {}'.format(resp))
174         # if http_code in (200, 201, 202, 204):
175 0         if wait:
176             # In this case, 'resp' always returns None, so 'resp['id']' cannot be used.
177             # Use the previously obtained id instead.
178 0             wait_id = vim_id_for_wait
179             # Wait for status for VI instance update
180 0             self._wait(wait_id, wait)
181         # else:
182         #     pass
183         # else:
184         #    msg = ""
185         #    if resp:
186         #        try:
187         #            msg = json.loads(resp)
188         #        except ValueError:
189         #            msg = resp
190         #    raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
191
192 1     def update_vim_account_dict(self, vim_account, vim_access):
193 0         self._logger.debug("")
194 0         vim_account["vim_type"] = vim_access["vim-type"]
195 0         vim_account["description"] = vim_access["description"]
196 0         vim_account["vim_url"] = vim_access["vim-url"] or "null"
197 0         vim_account["vim_user"] = vim_access["vim-username"] or "null"
198 0         vim_account["vim_password"] = vim_access["vim-password"] or "null"
199 0         vim_account["vim_tenant_name"] = vim_access["vim-tenant-name"] or "null"
200 0         if "prometheus-config" in vim_access:
201 0             vim_account["prometheus-config"] = vim_access["prometheus-config"]
202 0         return vim_account
203
204 1     def get_id(self, name):
205         """Returns a VIM id from a VIM name"""
206 0         self._logger.debug("")
207 0         for vim in self.list():
208 0             if name == vim["name"]:
209 0                 return vim["uuid"]
210 0         raise NotFound("vim {} not found".format(name))
211
212 1     def delete(self, vim_name, force=False, wait=False):
213 0         self._logger.debug("")
214 0         self._client.get_token()
215 0         vim_id = vim_name
216 0         if not utils.validate_uuid4(vim_name):
217 0             vim_id = self.get_id(vim_name)
218 0         querystring = ""
219 0         if force:
220 0             querystring = "?FORCE=True"
221 0         http_code, resp = self._http.delete_cmd(
222             "{}/{}{}".format(self._apiBase, vim_id, querystring)
223         )
224         # print('HTTP CODE: {}'.format(http_code))
225         # print('RESP: {}'.format(resp))
226 0         if http_code == 202:
227 0             if wait:
228                 # When deleting an account, 'resp' may be None.
229                 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
230 0                 wait_id = vim_id
231 0                 if resp:
232 0                     resp = json.loads(resp)
233 0                     wait_id = resp.get("id")
234                 # Wait for status for VIM account deletion
235 0                 self._wait(wait_id, wait, deleteFlag=True)
236             else:
237 0                 print("Deletion in progress")
238 0         elif http_code == 204:
239 0             print("Deleted")
240         else:
241 0             msg = resp or ""
242             # if resp:
243             #     try:
244             #         msg = json.loads(resp)
245             #     except ValueError:
246             #         msg = resp
247 0             raise ClientException("failed to delete vim {} - {}".format(vim_name, msg))
248
249 1     def list(self, filter=None):
250         """Returns a list of VIM accounts"""
251 0         self._logger.debug("")
252 0         self._client.get_token()
253 0         filter_string = ""
254 0         if filter:
255 0             filter_string = "?{}".format(filter)
256 0         _, resp = self._http.get2_cmd("{}{}".format(self._apiBase, filter_string))
257 0         if not resp:
258 0             return list()
259 0         vim_accounts = json.loads(resp)
260 0         for datacenter in vim_accounts:
261 0             datacenter["uuid"] = datacenter.get("_id")  # backward compatibility?
262 0         return vim_accounts
263
264 1     def get(self, name):
265         """Returns a VIM account based on name or id"""
266 0         self._logger.debug("")
267 0         self._client.get_token()
268 0         vim_id = name
269 0         if not utils.validate_uuid4(name):
270 0             vim_id = self.get_id(name)
271 0         try:
272 0             _, resp = self._http.get2_cmd("{}/{}".format(self._apiBase, vim_id))
273 0             if resp:
274 0                 resp = json.loads(resp)
275 0             if not resp or "_id" not in resp:
276 0                 raise ClientException("failed to get vim info: {}".format(resp))
277 0             return resp
278 0         except NotFound:
279 0             raise NotFound("vim '{}' not found".format(name))