3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain 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,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 from gi
import require_version
21 require_version('RwcalYang', '1.0')
22 require_version('RwTypes', '1.0')
23 require_version('RwCloudYang', '1.0')
24 require_version('RwCal', '1.0')
26 from gi
.repository
import (
33 if sys
.version_info
< (3, 4, 4):
34 asyncio
.ensure_future
= asyncio
.async
37 class PluginLoadingError(Exception):
41 class CloudAccountCalError(Exception):
45 class CloudAccount(object):
46 def __init__(self
, log
, rwlog_hdl
, account_msg
):
48 self
._account
_msg
= account_msg
.deep_copy()
50 self
._cal
_plugin
= None
53 self
._cal
= self
.plugin
.get_interface("Cloud")
54 self
._cal
.init(rwlog_hdl
)
56 self
._status
= RwCloudYang
.CloudAcc_ConnectionStatus(
58 details
="Connection status lookup not started"
61 self
._validate
_task
= None
65 if self
._cal
_plugin
is None:
67 self
._cal
_plugin
= rw_peas
.PeasPlugin(
68 getattr(self
._account
_msg
, self
.account_type
).plugin_name
,
72 except AttributeError as e
:
73 raise PluginLoadingError(str(e
))
75 self
._engine
, _
, _
= self
._cal
_plugin
()
77 return self
._cal
_plugin
79 def _wrap_status_fn(self
, fn
, *args
, **kwargs
):
80 ret
= fn(*args
, **kwargs
)
82 if rw_status
!= RwTypes
.RwStatus
.SUCCESS
:
83 msg
= "%s returned %s" % (fn
.__name
__, str(rw_status
))
85 raise CloudAccountCalError(msg
)
87 # If there was only one other return value besides rw_status, then just
88 # return that element. Otherwise return the rest of the return values
90 return ret
[1] if len(ret
) == 2 else ret
[1:]
98 return self
._account
_msg
.name
101 def account_msg(self
):
102 return self
._account
_msg
105 def cal_account_msg(self
):
106 return RwcalYang
.CloudAccount
.from_dict(
107 self
.account_msg
.as_dict(),
108 ignore_missing_keys
=True,
111 def cloud_account_msg(self
, account_dict
):
112 self
._account
_msg
= RwCloudYang
.CloudAccount
.from_dict(account_dict
)
115 def account_type(self
):
116 return self
._account
_msg
.account_type
119 def connection_status(self
):
122 def update_from_cfg(self
, cfg
):
123 self
._log
.debug("Updating parent CloudAccount to %s", cfg
)
125 # Hack to catch updates triggered from apply_callback when a sdn-account is removed
126 # from a cloud-account. To be fixed properly when updates are handled
127 if (self
.account_msg
.name
== cfg
.name
128 and self
.account_msg
.account_type
== cfg
.account_type
):
131 if cfg
.has_field("sdn_account"):
132 self
.account_msg
.sdn_account
= cfg
.sdn_account
134 raise NotImplementedError("Update cloud account not yet supported")
136 def create_image(self
, image_info_msg
):
137 image_id
= self
._wrap
_status
_fn
(
138 self
.cal
.create_image
, self
.cal_account_msg
, image_info_msg
143 def get_image_list(self
):
144 self
._log
.debug("Getting image list from account: %s", self
.name
)
145 resources
= self
._wrap
_status
_fn
(
146 self
.cal
.get_image_list
, self
.cal_account_msg
149 return resources
.imageinfo_list
152 def validate_cloud_account_credentials(self
, loop
):
153 self
._log
.debug("Validating Cloud Account credentials %s", self
._account
_msg
)
154 self
._status
= RwCloudYang
.CloudAcc_ConnectionStatus(
156 details
="Cloud account connection validation in progress"
158 rwstatus
, status
= yield from loop
.run_in_executor(
160 self
._cal
.validate_cloud_creds
,
161 self
.cal_account_msg
,
163 if rwstatus
== RwTypes
.RwStatus
.SUCCESS
:
164 self
._status
= RwCloudYang
.CloudAcc_ConnectionStatus
.from_dict(status
.as_dict())
166 self
._status
= RwCloudYang
.CloudAcc_ConnectionStatus(
168 details
="Error when calling CAL validate cloud creds"
171 self
._log
.info("Got cloud account validation response: %s", self
._status
)
173 def start_validate_credentials(self
, loop
):
174 if self
._validate
_task
is not None:
175 self
._validate
_task
.cancel()
176 self
._validate
_task
= None
178 self
._validate
_task
= asyncio
.ensure_future(
179 self
.validate_cloud_account_credentials(loop
),