1 # Copyright 2017 Sandvine
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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
21 from osmclient
.common
.exceptions
import ClientException
22 from osmclient
.common
.exceptions
import NotFound
28 def __init__(self
, http
=None, ro_http
=None, client
=None):
30 self
._ro
_http
= ro_http
33 def _attach(self
, vim_name
, vim_account
):
35 tenant
= self
._get
_ro
_tenant
()
37 raise ClientException("tenant {} not found".format(tenant_name
))
39 datacenter
= self
._get
_ro
_datacenter
(vim_name
)
40 if datacenter
is None:
41 raise Exception("datacenter {} not found".format(vim_name
))
43 return self
._ro
_http
.post_cmd(
44 "openmano/{}/datacenters/{}".format(tenant
["uuid"], datacenter
["uuid"]),
48 def _detach(self
, vim_name
):
50 tenant
= self
._get
_ro
_tenant
()
52 raise ClientException("tenant {} not found".format(tenant_name
))
53 return self
._ro
_http
.delete_cmd(
54 "openmano/{}/datacenters/{}".format(tenant
["uuid"], vim_name
)
57 def create(self
, name
, vim_access
):
59 vim_account
["datacenter"] = {}
61 # currently assumes vim_acc
62 if "vim-type" not in vim_access
:
63 # 'openstack' not in vim_access['vim-type']):
64 raise Exception("vim type not provided")
66 vim_account
["datacenter"]["name"] = name
67 vim_account
["datacenter"]["type"] = vim_access
["vim-type"]
70 if "config" in vim_access
and vim_access
["config"] is not None:
71 vim_config
= yaml
.safe_load(vim_access
["config"])
74 vim_account
["datacenter"]["config"] = vim_config
76 vim_account
= self
.update_vim_account_dict(vim_account
, vim_access
, vim_config
)
78 resp
= self
._ro
_http
.post_cmd("openmano/datacenters", vim_account
)
79 if resp
and "error" in resp
:
80 raise ClientException("failed to create vim")
82 self
._attach
(name
, vim_account
)
83 self
._update
_ro
_accounts
()
85 def _update_ro_accounts(self
):
86 get_ro_accounts
= self
._http
.get_cmd(
87 "api/operational/{}ro-account".format(self
._client
.so_rbac_project_path
)
89 if not get_ro_accounts
or "rw-ro-account:ro-account" not in get_ro_accounts
:
91 for account
in get_ro_accounts
["rw-ro-account:ro-account"]["account"]:
92 if account
["ro-account-type"] == "openmano":
93 # Refresh the Account Status
96 "ro-account": account
["name"],
97 "project-name": self
._client
._so
_project
,
100 refresh_status
= self
._http
.post_cmd(
101 "api/operations/update-ro-account-status", refresh_body
103 if refresh_status
and "error" in refresh_status
:
104 raise ClientException("Failed to refersh RO Account Status")
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
[
112 if "admin_password" in vim_config
:
113 vim_account
["datacenter"]["admin_password"] = vim_config
[
116 if "nsx_manager" in vim_config
:
117 vim_account
["datacenter"]["nsx_manager"] = vim_config
["nsx_manager"]
118 if "nsx_user" in vim_config
:
119 vim_account
["datacenter"]["nsx_user"] = vim_config
["nsx_user"]
120 if "nsx_password" in vim_config
:
121 vim_account
["datacenter"]["nsx_password"] = vim_config
["nsx_password"]
122 if "orgname" in vim_config
:
123 vim_account
["datacenter"]["orgname"] = vim_config
["orgname"]
124 if "vcenter_ip" in vim_config
:
125 vim_account
["datacenter"]["vcenter_ip"] = vim_config
["vcenter_ip"]
126 if "vcenter_user" in vim_config
:
127 vim_account
["datacenter"]["vcenter_user"] = vim_config
["vcenter_user"]
128 if "vcenter_password" in vim_config
:
129 vim_account
["datacenter"]["vcenter_password"] = vim_config
[
132 if "vcenter_port" in vim_config
:
133 vim_account
["datacenter"]["vcenter_port"] = vim_config
["vcenter_port"]
134 vim_account
["datacenter"]["vim_url"] = vim_access
["vim-url"]
135 vim_account
["datacenter"]["vim_url_admin"] = vim_access
["vim-url"]
136 vim_account
["datacenter"]["description"] = vim_access
["description"]
137 vim_account
["datacenter"]["vim_username"] = vim_access
["vim-username"]
138 vim_account
["datacenter"]["vim_password"] = vim_access
["vim-password"]
139 vim_account
["datacenter"]["vim_tenant_name"] = vim_access
["vim-tenant-name"]
141 vim_account
["datacenter"]["vim_url"] = vim_access
["vim-url"]
142 vim_account
["datacenter"]["vim_url_admin"] = vim_access
["vim-url"]
143 vim_account
["datacenter"]["description"] = vim_access
["description"]
144 vim_account
["datacenter"]["vim_username"] = vim_access
["vim-username"]
145 vim_account
["datacenter"]["vim_password"] = vim_access
["vim-password"]
146 vim_account
["datacenter"]["vim_tenant_name"] = vim_access
["vim-tenant-name"]
149 def delete(self
, vim_name
):
151 self
._detach
(vim_name
)
152 # detach. continue if error,
153 # it could be the datacenter is left without attachment
154 resp
= self
._ro
_http
.delete_cmd("openmano/datacenters/{}".format(vim_name
))
155 if "result" not in resp
:
156 raise ClientException("failed to delete vim {} - {}".format(vim_name
, resp
))
157 self
._update
_ro
_accounts
()
159 def list(self
, ro_update
):
161 self
._update
_ro
_accounts
()
162 # the ro_update needs to be made synchronous, for now this works around the issue
163 # and waits a resonable amount of time for the update to finish
166 if self
._client
._so
_version
== "v3":
167 resp
= self
._http
.get_cmd(
168 "v1/api/operational/{}ro-account-state".format(
169 self
._client
.so_rbac_project_path
173 if not resp
or "rw-ro-account:ro-account-state" not in resp
:
176 ro_accounts
= resp
["rw-ro-account:ro-account-state"]
177 for ro_account
in ro_accounts
["account"]:
178 if "datacenters" not in ro_account
:
180 if "datacenters" not in ro_account
["datacenters"]:
182 for datacenter
in ro_account
["datacenters"]["datacenters"]:
185 "name": datacenter
["name"],
186 "uuid": datacenter
["uuid"]
187 if "uuid" in datacenter
192 vim_accounts
= datacenters
195 # Backwards Compatibility
196 resp
= self
._http
.get_cmd("v1/api/operational/datacenters")
197 if not resp
or "rw-launchpad:datacenters" not in resp
:
200 datacenters
= resp
["rw-launchpad:datacenters"]
202 vim_accounts
= list()
203 if "ro-accounts" not in datacenters
:
206 tenant
= self
._get
_ro
_tenant
()
210 for roaccount
in datacenters
["ro-accounts"]:
211 if "datacenters" not in roaccount
:
213 for datacenter
in roaccount
["datacenters"]:
215 self
._get
_ro
_datacenter
(datacenter
["name"], tenant
["uuid"])
219 def _get_ro_tenant(self
, name
="osm"):
220 resp
= self
._ro
_http
.get_cmd("openmano/tenants/{}".format(name
))
225 if "tenant" in resp
and "uuid" in resp
["tenant"]:
226 return resp
["tenant"]
230 def _get_ro_datacenter(self
, name
, tenant_uuid
="any"):
231 resp
= self
._ro
_http
.get_cmd(
232 "openmano/{}/datacenters/{}".format(tenant_uuid
, name
)
235 raise NotFound("datacenter {} not found".format(name
))
237 if "datacenter" in resp
and "uuid" in resp
["datacenter"]:
238 return resp
["datacenter"]
240 raise NotFound("datacenter {} not found".format(name
))
243 tenant
= self
._get
_ro
_tenant
()
245 raise NotFound("no ro tenant found")
247 return self
._get
_ro
_datacenter
(name
, tenant
["uuid"])
249 def get_datacenter(self
, name
):
250 if self
._client
._so
_version
== "v3":
251 resp
= self
._http
.get_cmd(
252 "v1/api/operational/{}ro-account-state".format(
253 self
._client
.so_rbac_project_path
259 if not resp
or "rw-ro-account:ro-account-state" not in resp
:
262 ro_accounts
= resp
["rw-ro-account:ro-account-state"]
263 for ro_account
in ro_accounts
["account"]:
264 if "datacenters" not in ro_account
:
266 if "datacenters" not in ro_account
["datacenters"]:
268 for datacenter
in ro_account
["datacenters"]["datacenters"]:
269 if datacenter
["name"] == name
:
270 return datacenter
, ro_account
["name"]
273 # Backwards Compatibility
274 resp
= self
._http
.get_cmd("v1/api/operational/datacenters")
278 if not resp
or "rw-launchpad:datacenters" not in resp
:
280 if "ro-accounts" not in resp
["rw-launchpad:datacenters"]:
282 for roaccount
in resp
["rw-launchpad:datacenters"]["ro-accounts"]:
283 if "datacenters" not in roaccount
:
285 for datacenter
in roaccount
["datacenters"]:
286 if datacenter
["name"] == name
:
290 def get_resource_orchestrator(self
):
291 resp
= self
._http
.get_cmd(
292 "v1/api/operational/{}resource-orchestrator".format(
293 self
._client
.so_rbac_project_path
297 if not resp
or "rw-launchpad:resource-orchestrator" not in resp
:
299 return resp
["rw-launchpad:resource-orchestrator"]