3 # Copyright 2017 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('RwTypes', '1.0')
22 require_version('RwsdnalYang', '1.0')
23 require_version('RwSdnYang', '1.0')
25 from gi
.repository
import (
32 if sys
.version_info
< (3, 4, 4):
33 asyncio
.ensure_future
= asyncio
.async
36 class PluginLoadingError(Exception):
40 class SDNAccountCalError(Exception):
44 class SDNAccount(object):
45 def __init__(self
, log
, rwlog_hdl
, account_msg
):
47 self
._account
_msg
= account_msg
.deep_copy()
49 self
._sdn
_plugin
= None
52 self
._sdn
= self
.plugin
.get_interface("Topology")
53 self
._sdn
.init(rwlog_hdl
)
55 self
._status
= RwSdnYang
.YangData_RwProject_Project_Sdn_Account_ConnectionStatus(
57 details
="Connection status lookup not started"
60 self
._validate
_task
= None
64 if self
._sdn
_plugin
is None:
66 self
._sdn
_plugin
= rw_peas
.PeasPlugin(
67 getattr(self
._account
_msg
, self
.account_type
).plugin_name
,
71 except AttributeError as e
:
72 raise PluginLoadingError(str(e
))
74 self
._engine
, _
, _
= self
._sdn
_plugin
()
76 return self
._sdn
_plugin
78 def _wrap_status_fn(self
, fn
, *args
, **kwargs
):
79 ret
= fn(*args
, **kwargs
)
81 if rw_status
!= RwTypes
.RwStatus
.SUCCESS
:
82 msg
= "%s returned %s" % (fn
.__name
__, str(rw_status
))
84 raise SDNAccountCalError(msg
)
86 # If there was only one other return value besides rw_status, then just
87 # return that element. Otherwise return the rest of the return values
89 return ret
[1] if len(ret
) == 2 else ret
[1:]
97 return self
._account
_msg
.name
100 def account_msg(self
):
101 return self
._account
_msg
104 def sdnal_account_msg(self
):
105 return RwsdnalYang
.YangData_RwProject_Project_SdnAccounts_SdnAccountList
.from_dict(
106 self
.account_msg
.as_dict(),
107 ignore_missing_keys
=True,
110 def sdn_account_msg(self
, account_dict
):
111 self
._account
_msg
= RwSdnYang
.YangData_RwProject_Project_SdnAccounts_SdnAccountList
.from_dict(account_dict
)
114 def account_type(self
):
115 return self
._account
_msg
.account_type
118 def connection_status(self
):
121 def update_from_cfg(self
, cfg
):
122 self
._log
.debug("Updating parent SDN Account to %s", cfg
)
124 raise NotImplementedError("Update SDN account not yet supported")
128 def validate_sdn_account_credentials(self
, loop
):
129 self
._log
.debug("Validating SDN Account credentials %s",
131 self
._status
= RwSdnYang
.YangData_RwProject_Project_Sdn_Account_ConnectionStatus(
133 details
="SDN account connection validation in progress"
135 rwstatus
, status
= yield from loop
.run_in_executor(
137 self
._sdn
.validate_sdn_creds
,
138 self
.sdnal_account_msg
,
140 if rwstatus
== RwTypes
.RwStatus
.SUCCESS
:
141 self
._status
= RwSdnYang
.YangData_RwProject_Project_Sdn_Account_ConnectionStatus
.from_dict(status
.as_dict())
143 self
._status
= RwSdnYang
.YangData_RwProject_Project_Sdn_Account_ConnectionStatus(
145 details
="Error when calling SDNAL validate SDN creds"
148 if self
._status
.status
== 'failure':
149 self
._log
.error("SDN account validation failed; Acct: %s status: %s",
150 self
.name
, self
._status
)
152 def start_validate_credentials(self
, loop
):
153 if self
._validate
_task
is not None:
154 self
._validate
_task
.cancel()
155 self
._validate
_task
= None
157 self
._validate
_task
= asyncio
.ensure_future(
158 self
.validate_sdn_account_credentials(loop
),