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.
23 from gi
.repository
import(
29 gi
.require_version('RwKeyspec', '1.0')
30 from gi
.repository
.RwKeyspec
import quoted_key
33 class SDNAccountNotFound(Exception):
37 class SDNAccountDtsOperdataHandler(object):
38 def __init__(self
, dts
, log
, loop
, project
):
42 self
._project
= project
44 self
.sdn_accounts
= {}
48 def add_sdn_account(self
, account
):
49 self
.sdn_accounts
[account
.name
] = account
50 account
.start_validate_credentials(self
._loop
)
52 def delete_sdn_account(self
, account_name
):
53 del self
.sdn_accounts
[account_name
]
55 def get_saved_sdn_accounts(self
, sdn_account_name
):
56 ''' Get SDN Account corresponding to passed name, or all saved accounts if name is None'''
57 saved_sdn_accounts
= []
59 if sdn_account_name
is None or sdn_account_name
== "":
60 sdn_accounts
= list(self
.sdn_accounts
.values())
61 saved_sdn_accounts
.extend(sdn_accounts
)
62 elif sdn_account_name
in self
.sdn_accounts
:
63 account
= self
.sdn_accounts
[sdn_account_name
]
64 saved_sdn_accounts
.append(account
)
66 errstr
= "SDN account {} does not exist".format(sdn_account_name
)
67 raise KeyError(errstr
)
69 return saved_sdn_accounts
72 def create_notification(self
, account
):
73 xpath
= "N,/rw-sdn:sdn-notif"
74 ac_status
= RwSdnYang
.YangNotif_RwSdn_SdnNotif()
75 ac_status
.name
= account
.name
76 ac_status
.message
= account
.connection_status
.details
78 yield from self
._dts
.query_create(xpath
, rwdts
.XactFlag
.ADVISE
, ac_status
)
79 self
._log
.info("Notification called by creating dts query: %s", ac_status
)
83 def _register_show_status(self
):
84 self
._log
.debug("Registering for show for project {}".format(self
._project
))
85 def get_xpath(sdn_name
=None):
86 return self
._project
.add_project("D,/rw-sdn:sdn/rw-sdn:account{}/rw-sdn:connection-status".
88 "[rw-sdn:name=%s]" % quoted_key(sdn_name
)
89 if sdn_name
is not None else ''))
92 def on_prepare(xact_info
, action
, ks_path
, msg
):
93 xpath
= ks_path
.to_xpath(RwSdnYang
.get_schema())
94 self
._log
.debug("Got show SDN connection status request: %s", xpath
)
95 path_entry
= RwSdnYang
.YangData_RwProject_Project_Sdn_Account
.schema().keyspec_to_entry(ks_path
)
96 sdn_account_name
= path_entry
.key00
.name
99 saved_accounts
= self
.get_saved_sdn_accounts(sdn_account_name
)
100 for account
in saved_accounts
:
101 connection_status
= account
.connection_status
102 self
._log
.debug("Responding to SDN connection status request: %s",
104 xact_info
.respond_xpath(
105 rwdts
.XactRspCode
.MORE
,
106 xpath
=get_xpath(account
.name
),
107 msg
=account
.connection_status
,
109 except KeyError as e
:
110 self
._log
.warning(str(e
))
111 xact_info
.respond_xpath(rwdts
.XactRspCode
.NA
)
114 xact_info
.respond_xpath(rwdts
.XactRspCode
.ACK
)
116 self
._oper
= yield from self
._dts
.register(
118 handler
=rift
.tasklets
.DTS
.RegistrationHandler(
119 on_prepare
=on_prepare
),
120 flags
=rwdts
.Flag
.PUBLISHER
,
124 def _register_validate_rpc(self
):
125 self
._log
.debug("Registering for rpc for project {}".format(self
._project
))
127 return "/rw-sdn:update-sdn-status"
130 def on_prepare(xact_info
, action
, ks_path
, msg
):
131 if self
._project
and not self
._project
.rpc_check(msg
, xact_info
=xact_info
):
134 self
._log
.debug("Got update SDN connection status request: %s", msg
)
136 if not msg
.has_field("sdn_account"):
137 raise SDNAccountNotFound("SDN account name not provided")
139 sdn_account_name
= msg
.sdn_account
141 account
= self
.sdn_accounts
[sdn_account_name
]
143 errmsg
= "SDN account name %s not found" % sdn_account_name
144 self
._log
.error(errmsg
)
145 xpath
= ks_path
.to_xpath(RwSdnYang
.get_schema())
146 xact_info
.send_error_xpath(RwTypes
.RwStatus
.FAILURE
,
149 xact_info
.respond_xpath(rwdts
.XactRspCode
.NACK
)
152 account
.start_validate_credentials(self
._loop
)
154 yield from self
.create_notification(account
)
156 xact_info
.respond_xpath(rwdts
.XactRspCode
.ACK
)
158 self
._rpc
= yield from self
._dts
.register(
160 handler
=rift
.tasklets
.DTS
.RegistrationHandler(
161 on_prepare
=on_prepare
163 flags
=rwdts
.Flag
.PUBLISHER
,
168 yield from self
._register
_show
_status
()
169 yield from self
._register
_validate
_rpc
()
171 def deregister(self
):
173 self
._oper
.deregister()
177 self
._rpc
.deregister()