vim-list Fixed. SO needed refresh of the RO Accounts Change 5516
[osm/osmclient.git] / osmclient / v1 / vim.py
1 # Copyright 2017 Sandvine
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.exceptions import ClientException
22 from osmclient.common.exceptions import NotFound
23 import json
24
25
26 class Vim(object):
27 def __init__(self, http=None, ro_http=None, client=None):
28 self._client = client
29 self._ro_http = ro_http
30 self._http = http
31
32 def _attach(self, vim_name, vim_account):
33 tenant_name = 'osm'
34 tenant = self._get_ro_tenant()
35 if tenant is None:
36 raise ClientException("tenant {} not found".format(tenant_name))
37
38 datacenter = self._get_ro_datacenter(vim_name)
39 if datacenter is None:
40 raise Exception('datacenter {} not found'.format(vim_name))
41
42 return self._ro_http.post_cmd('openmano/{}/datacenters/{}'
43 .format(tenant['uuid'],
44 datacenter['uuid']), vim_account)
45
46 def _detach(self, vim_name):
47 return self._ro_http.delete_cmd('openmano/{}/datacenters/{}'
48 .format('osm', vim_name))
49
50 def create(self, name, vim_access):
51 vim_account = {}
52 vim_account['datacenter'] = {}
53
54 # currently assumes vim_acc
55 if ('vim-type' not in vim_access):
56 #'openstack' not in vim_access['vim-type']):
57 raise Exception("vim type not provided")
58
59 vim_account['datacenter']['name'] = name
60 vim_account['datacenter']['type'] = vim_access['vim-type']
61
62 vim_config = {}
63 vim_config['use_floating_ip'] = False
64
65 if ('floating_ip_pool' in vim_access and
66 vim_access['floating_ip_pool'] is not None):
67 vim_config['use_floating_ip'] = True
68
69 if 'keypair' in vim_access and vim_access['keypair'] is not None:
70 vim_config['keypair'] = vim_access['keypair']
71 elif 'config' in vim_access and vim_access['config'] is not None:
72 if any(var in vim_access['config'] for var in ["admin_password","admin_username","orgname","nsx_user","nsx_password","nsx_manager","vcenter_ip","vcenter_port","vcenter_user","vcenter_password"]):
73 vim_config = json.loads(vim_access['config'])
74
75 vim_account['datacenter']['config'] = vim_config
76
77 vim_account = self.update_vim_account_dict(vim_account, vim_access, vim_config)
78
79 resp = self._ro_http.post_cmd('openmano/datacenters', vim_account)
80 if resp and 'error' in resp:
81 raise ClientException("failed to create vim")
82 else:
83 self._attach(name, vim_account)
84 self._update_ro_accounts()
85
86
87 def _update_ro_accounts(self):
88 get_ro_accounts = self._http.get_cmd('api/operational/{}ro-account'
89 .format(self._client.so_rbac_project_path))
90 if not get_ro_accounts or 'rw-ro-account:ro-account' not in get_ro_accounts:
91 return
92 for account in get_ro_accounts['rw-ro-account:ro-account']['account']:
93 if account['ro-account-type'] == 'openmano':
94 # Refresh the Account Status
95 refresh_body = {"input": {
96 "ro-account": account['name'],
97 "project-name": self._client._so_project
98 }
99 }
100 refresh_status = self._http.post_cmd('api/operations/update-ro-account-status',
101 refresh_body)
102 if refresh_status and 'error' in refresh_status:
103 raise ClientException("Failed to refersh RO Account Status")
104
105
106 def update_vim_account_dict(self, vim_account, vim_access, vim_config):
107 if vim_access['vim-type'] == 'vmware':
108 if 'admin_username' in vim_config:
109 vim_account['datacenter']['admin_username'] = vim_config['admin_username']
110 if 'admin_password' in vim_config:
111 vim_account['datacenter']['admin_password'] = vim_config['admin_password']
112 if 'nsx_manager' in vim_config:
113 vim_account['datacenter']['nsx_manager'] = vim_config['nsx_manager']
114 if 'nsx_user' in vim_config:
115 vim_account['datacenter']['nsx_user'] = vim_config['nsx_user']
116 if 'nsx_password' in vim_config:
117 vim_account['datacenter']['nsx_password'] = vim_config['nsx_password']
118 if 'orgname' in vim_config:
119 vim_account['datacenter']['orgname'] = vim_config['orgname']
120 if 'vcenter_ip' in vim_config:
121 vim_account['datacenter']['vcenter_ip'] = vim_config['vcenter_ip']
122 if 'vcenter_user' in vim_config:
123 vim_account['datacenter']['vcenter_user'] = vim_config['vcenter_user']
124 if 'vcenter_password' in vim_config:
125 vim_account['datacenter']['vcenter_password'] = vim_config['vcenter_password']
126 if 'vcenter_port' in vim_config:
127 vim_account['datacenter']['vcenter_port'] = vim_config['vcenter_port']
128 vim_account['datacenter']['vim_url'] = vim_access['vim-url']
129 vim_account['datacenter']['vim_url_admin'] = vim_access['vim-url']
130 vim_account['datacenter']['description'] = vim_access['description']
131 vim_account['datacenter']['vim_username'] = vim_access['vim-username']
132 vim_account['datacenter']['vim_password'] = vim_access['vim-password']
133 vim_account['datacenter']['vim_tenant_name'] = vim_access['vim-tenant-name']
134 else:
135 vim_account['datacenter']['vim_url'] = vim_access['vim-url']
136 vim_account['datacenter']['vim_url_admin'] = vim_access['vim-url']
137 vim_account['datacenter']['description'] = vim_access['description']
138 vim_account['datacenter']['vim_username'] = vim_access['vim-username']
139 vim_account['datacenter']['vim_password'] = vim_access['vim-password']
140 vim_account['datacenter']['vim_tenant_name'] = vim_access['vim-tenant-name']
141 return vim_account
142
143 def delete(self, vim_name):
144 # first detach
145 self._detach(vim_name)
146 # detach. continue if error,
147 # it could be the datacenter is left without attachment
148 resp = self._ro_http.delete_cmd('openmano/datacenters/{}'
149 .format(vim_name))
150 if 'result' not in resp:
151 raise ClientException("failed to delete vim {} - {}".format(vim_name, resp))
152 self._update_ro_accounts()
153
154 def list(self):
155 if self._client._so_version == 'v3':
156 resp = self._http.get_cmd('v1/api/operational/{}ro-account-state'
157 .format(self._client.so_rbac_project_path))
158 datacenters = []
159 if not resp or 'rw-ro-account:ro-account-state' not in resp:
160 return list()
161
162 ro_accounts = resp['rw-ro-account:ro-account-state']
163 for ro_account in ro_accounts['account']:
164 if 'datacenters' not in ro_account:
165 continue
166 if 'datacenters' not in ro_account['datacenters']:
167 continue
168 for datacenter in ro_account['datacenters']['datacenters']:
169 datacenters.append({"name": datacenter['name'], "uuid": datacenter['uuid']
170 if 'uuid' in datacenter else None})
171
172 vim_accounts = datacenters
173 return vim_accounts
174 else:
175 # Backwards Compatibility
176 resp = self._http.get_cmd('v1/api/operational/datacenters')
177 if not resp or 'rw-launchpad:datacenters' not in resp:
178 return list()
179
180 datacenters = resp['rw-launchpad:datacenters']
181
182 vim_accounts = list()
183 if 'ro-accounts' not in datacenters:
184 return vim_accounts
185
186 tenant = self._get_ro_tenant()
187 if tenant is None:
188 return vim_accounts
189
190 for roaccount in datacenters['ro-accounts']:
191 if 'datacenters' not in roaccount:
192 continue
193 for datacenter in roaccount['datacenters']:
194 vim_accounts.append(self._get_ro_datacenter(datacenter['name'],
195 tenant['uuid']))
196 return vim_accounts
197
198 def _get_ro_tenant(self, name='osm'):
199 resp = self._ro_http.get_cmd('openmano/tenants/{}'.format(name))
200
201 if not resp:
202 return None
203
204 if 'tenant' in resp and 'uuid' in resp['tenant']:
205 return resp['tenant']
206 else:
207 return None
208
209 def _get_ro_datacenter(self, name, tenant_uuid='any'):
210 resp = self._ro_http.get_cmd('openmano/{}/datacenters/{}'
211 .format(tenant_uuid, name))
212 if not resp:
213 raise NotFound("datacenter {} not found".format(name))
214
215 if 'datacenter' in resp and 'uuid' in resp['datacenter']:
216 return resp['datacenter']
217 else:
218 raise NotFound("datacenter {} not found".format(name))
219
220 def get(self, name):
221 tenant = self._get_ro_tenant()
222 if tenant is None:
223 raise NotFound("no ro tenant found")
224
225 return self._get_ro_datacenter(name, tenant['uuid'])
226
227 def get_datacenter(self, name):
228 if self._client._so_version == 'v3':
229 resp = self._http.get_cmd('v1/api/operational/{}ro-account-state'
230 .format(self._client.so_rbac_project_path))
231 if not resp:
232 return None, None
233
234 if not resp or 'rw-ro-account:ro-account-state' not in resp:
235 return None, None
236
237 ro_accounts = resp['rw-ro-account:ro-account-state']
238 for ro_account in ro_accounts['account']:
239 if 'datacenters' not in ro_account:
240 continue
241 if 'datacenters' not in ro_account['datacenters']:
242 continue
243 for datacenter in ro_account['datacenters']['datacenters']:
244 if datacenter['name'] == name:
245 return datacenter, ro_account['name']
246 return None, None
247 else:
248 # Backwards Compatibility
249 resp = self._http.get_cmd('v1/api/operational/datacenters')
250 if not resp:
251 return None
252
253 if not resp or 'rw-launchpad:datacenters' not in resp:
254 return None
255 if 'ro-accounts' not in resp['rw-launchpad:datacenters']:
256 return None
257 for roaccount in resp['rw-launchpad:datacenters']['ro-accounts']:
258 if 'datacenters' not in roaccount:
259 continue
260 for datacenter in roaccount['datacenters']:
261 if datacenter['name'] == name:
262 return datacenter
263 return None
264
265 def get_resource_orchestrator(self):
266 resp = self._http.get_cmd('v1/api/operational/{}resource-orchestrator'
267 .format(self._client.so_rbac_project_path))
268
269 if not resp or 'rw-launchpad:resource-orchestrator' not in resp:
270 return None
271 return resp['rw-launchpad:resource-orchestrator']