Code Coverage

Cobertura Coverage Report > osmclient.sol005 >

vim.py

Trend

Classes100%
 
Lines12%
   
Conditionals100%
 

File Coverage summary

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

Coverage Breakdown by Class

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