bd95d6611256905c7925757afe5e3b9cb84bcc89
[osm/osmclient.git] / 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 """
18 OSM vim API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common import wait as WaitForStatus
23 from osmclient.common.exceptions import ClientException
24 from osmclient.common.exceptions import NotFound
25 import yaml
26 import json
27
28
29 class Vim(object):
30 def __init__(self, http=None, client=None):
31 self._http = http
32 self._client = client
33 self._apiName = '/admin'
34 self._apiVersion = '/v1'
35 self._apiResource = '/vim_accounts'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38 # VIM '--wait' option
39 def _wait(self, id, deleteFlag=False):
40 # Endpoint to get operation status
41 apiUrlStatus = '{}{}{}'.format(self._apiName, self._apiVersion, '/vim_accounts')
42 # Wait for status for VIM instance creation/deletion
43 WaitForStatus.wait_for_status(
44 'VIM',
45 str(id),
46 WaitForStatus.TIMEOUT_VIM_OPERATION,
47 apiUrlStatus,
48 self._http.get2_cmd,
49 deleteFlag=deleteFlag)
50
51 def create(self, name, vim_access, sdn_controller=None, sdn_port_mapping=None, wait=False):
52 if 'vim-type' not in vim_access:
53 #'openstack' not in vim_access['vim-type']):
54 raise Exception("vim type not provided")
55
56 vim_account = {}
57 vim_account['name'] = name
58 vim_account = self.update_vim_account_dict(vim_account, vim_access)
59
60 vim_config = {}
61 if 'config' in vim_access and vim_access['config'] is not None:
62 vim_config = yaml.safe_load(vim_access['config'])
63 if sdn_controller:
64 sdnc = self._client.sdnc.get(sdn_controller)
65 vim_config['sdn-controller'] = sdnc['_id']
66 if sdn_port_mapping:
67 with open(sdn_port_mapping, 'r') as f:
68 vim_config['sdn-port-mapping'] = yaml.safe_load(f.read())
69 if vim_config:
70 vim_account['config'] = vim_config
71 #vim_account['config'] = json.dumps(vim_config)
72
73 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
74 postfields_dict=vim_account)
75 #print 'HTTP CODE: {}'.format(http_code)
76 #print 'RESP: {}'.format(resp)
77 if http_code in (200, 201, 202, 204):
78 if resp:
79 resp = json.loads(resp)
80 if not resp or 'id' not in resp:
81 raise ClientException('unexpected response from server - {}'.format(
82 resp))
83 if wait:
84 # Wait for status for VIM instance creation
85 self._wait(resp.get('id'))
86 print(resp['id'])
87 else:
88 msg = ""
89 if resp:
90 try:
91 msg = json.loads(resp)
92 except ValueError:
93 msg = resp
94 raise ClientException("failed to create vim {} - {}".format(name, msg))
95
96 def update(self, vim_name, vim_account, sdn_controller, sdn_port_mapping, wait=False):
97 vim = self.get(vim_name)
98
99 vim_config = {}
100 if 'config' in vim_account:
101 if vim_account.get('config')=="" and (sdn_controller or sdn_port_mapping):
102 raise ClientException("clearing config is incompatible with updating SDN info")
103 if vim_account.get('config')=="":
104 vim_config = None
105 else:
106 vim_config = yaml.safe_load(vim_account['config'])
107 if sdn_controller:
108 sdnc = self._client.sdnc.get(sdn_controller)
109 vim_config['sdn-controller'] = sdnc['_id']
110 if sdn_port_mapping:
111 with open(sdn_port_mapping, 'r') as f:
112 vim_config['sdn-port-mapping'] = yaml.safe_load(f.read())
113 vim_account['config'] = vim_config
114 #vim_account['config'] = json.dumps(vim_config)
115 http_code, resp = self._http.put_cmd(endpoint='{}/{}'.format(self._apiBase,vim['_id']),
116 postfields_dict=vim_account)
117 #print 'HTTP CODE: {}'.format(http_code)
118 #print 'RESP: {}'.format(resp)
119 if http_code in (200, 201, 202, 204):
120 if resp:
121 resp = json.loads(resp)
122 if not resp or 'id' not in resp:
123 raise ClientException('unexpected response from server - {}'.format(
124 resp))
125 if wait:
126 # Wait for status for VIM instance update
127 self._wait(resp.get('id'))
128 print(resp['id'])
129 else:
130 msg = ""
131 if resp:
132 try:
133 msg = json.loads(resp)
134 except ValueError:
135 msg = resp
136 raise ClientException("failed to update vim {} - {}".format(vim_name, msg))
137
138 def update_vim_account_dict(self, vim_account, vim_access):
139 vim_account['vim_type'] = vim_access['vim-type']
140 vim_account['description'] = vim_access['description']
141 vim_account['vim_url'] = vim_access['vim-url']
142 vim_account['vim_user'] = vim_access['vim-username']
143 vim_account['vim_password'] = vim_access['vim-password']
144 vim_account['vim_tenant_name'] = vim_access['vim-tenant-name']
145 return vim_account
146
147 def get_id(self, name):
148 """Returns a VIM id from a VIM name
149 """
150 for vim in self.list():
151 if name == vim['name']:
152 return vim['uuid']
153 raise NotFound("vim {} not found".format(name))
154
155 def delete(self, vim_name, force=False, wait=False):
156 vim_id = vim_name
157 if not utils.validate_uuid4(vim_name):
158 vim_id = self.get_id(vim_name)
159 querystring = ''
160 if force:
161 querystring = '?FORCE=True'
162 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
163 vim_id, querystring))
164 #print 'HTTP CODE: {}'.format(http_code)
165 #print 'RESP: {}'.format(resp)
166 if http_code == 202:
167 if wait:
168 # When deleting an account, 'resp' may be None.
169 # In such a case, the 'id' from 'resp' cannot be used, so use 'vim_id' instead
170 wait_id = vim_id
171 if resp:
172 resp = json.loads(resp)
173 wait_id = resp.get('id')
174 # Wait for status for VIM account deletion
175 self._wait(wait_id, deleteFlag=True)
176 else:
177 print('Deletion in progress')
178 elif http_code == 204:
179 print('Deleted')
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 delete vim {} - {}".format(vim_name, msg))
188
189 def list(self, filter=None):
190 """Returns a list of VIM accounts
191 """
192 filter_string = ''
193 if filter:
194 filter_string = '?{}'.format(filter)
195 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
196 if not resp:
197 return list()
198 vim_accounts = []
199 for datacenter in resp:
200 vim_accounts.append({"name": datacenter['name'], "uuid": datacenter['_id']
201 if '_id' in datacenter else None})
202 return vim_accounts
203
204 def get(self, name):
205 """Returns a VIM account based on name or id
206 """
207 vim_id = name
208 if not utils.validate_uuid4(name):
209 vim_id = self.get_id(name)
210 resp = self._http.get_cmd('{}/{}'.format(self._apiBase,vim_id))
211 if not resp or '_id' not in resp:
212 raise ClientException('failed to get vim info: '.format(
213 resp))
214 else:
215 return resp
216 raise NotFound("vim {} not found".format(name))
217