update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwlaunchpad / plugins / rwvns / rift / topmgr / rwtopmgr.py
1 #
2 # Copyright 2016 RIFT.IO Inc
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17 import asyncio
18 import gi
19
20 gi.require_version('RwDts', '1.0')
21 gi.require_version('RwcalYang', '1.0')
22 gi.require_version('RwTypes', '1.0')
23 gi.require_version('RwSdn', '1.0')
24 from gi.repository import (
25 RwDts as rwdts,
26 IetfNetworkYang,
27 IetfNetworkTopologyYang,
28 IetfL2TopologyYang,
29 RwTopologyYang,
30 RwsdnalYang,
31 RwTypes
32 )
33
34 from gi.repository.RwTypes import RwStatus
35 import rift.tasklets
36
37 gi.require_version('RwKeyspec', '1.0')
38 from gi.repository.RwKeyspec import quoted_key
39
40
41 class NwtopDiscoveryDtsHandler(object):
42 """ Handles DTS interactions for the Discovered Topology registration """
43 DISC_XPATH = "D,/nd:network"
44
45 def __init__(self, dts, log, loop, project, acctmgr, nwdatastore):
46 self._dts = dts
47 self._log = log
48 self._loop = loop
49 self._project = project
50 self._acctmgr = acctmgr
51 self._nwdatastore = nwdatastore
52
53 self._regh = None
54
55 @property
56 def regh(self):
57 """ The registration handle associated with this Handler"""
58 return self._regh
59
60 def deregister(self):
61 self._log.debug("De-register Topology discovery handler for project {}".
62 format(self._project.name))
63 if self._regh:
64 self._regh.deregister()
65 self._regh = None
66
67 @asyncio.coroutine
68 def register(self):
69 """ Register for the Discovered Topology path """
70
71 @asyncio.coroutine
72 def on_ready(regh, status):
73 """ On_ready for Discovered Topology registration """
74 self._log.debug("PUB reg ready for Discovered Topology handler regn_hdl(%s) status %s",
75 regh, status)
76
77 @asyncio.coroutine
78 def on_prepare(xact_info, action, ks_path, msg):
79 """ prepare for Discovered Topology registration"""
80 self._log.debug(
81 "Got topology on_prepare callback (xact_info: %s, action: %s): %s",
82 xact_info, action, msg
83 )
84
85 if action == rwdts.QueryAction.READ:
86
87 for name, sdnacct in self._acctstore.items():
88 if sdnacct.account_type != "odl":
89 continue
90 sdnintf = sdnacct.sdn
91
92 rc, nwtop = sdnintf.get_network_list(sdnacct.sdnal_account_msg)
93 #assert rc == RwStatus.SUCCESS
94 if rc != RwStatus.SUCCESS:
95 self._log.error("Fetching get network list for SDN Account %s failed", name)
96 xact_info.respond_xpath(rwdts.XactRspCode.NACK)
97 return
98
99 self._log.debug("Topology: Retrieved network attributes ")
100 for nw in nwtop.network:
101 # Add SDN account name
102 nw.rw_network_attributes.sdn_account_name = name
103 nw.server_provided = False
104 nw.network_id = name + ':' + nw.network_id
105 self._log.debug("...Network id %s", nw.network_id)
106 nw_xpath = ("D,/nd:network[network-id={}]").format(quoted_key(nw.network_id))
107 xact_info.respond_xpath(rwdts.XactRspCode.MORE,
108 nw_xpath, nw)
109
110 xact_info.respond_xpath(rwdts.XactRspCode.ACK)
111 #err = "%s action on discovered Topology not supported" % action
112 #raise NotImplementedError(err)
113
114 self._log.debug("Registering for discovered topology using xpath %s", NwtopDiscoveryDtsHandler.DISC_XPATH)
115
116 handler = rift.tasklets.DTS.RegistrationHandler(
117 on_ready=on_ready,
118 on_prepare=on_prepare,
119 )
120
121 self._regh = yield from self._dts.register(
122 NwtopDiscoveryDtsHandler.DISC_XPATH,
123 flags=rwdts.Flag.PUBLISHER,
124 handler=handler
125 )
126
127
128 class NwtopStaticDtsHandler(object):
129 """ Handles DTS interactions for the Static Topology registration """
130 STATIC_XPATH = "C,/nd:network"
131
132 def __init__(self, dts, log, loop, project, acctmgr, nwdatastore):
133 self._dts = dts
134 self._log = log
135 self._loop = loop
136 self._project = project
137 self._acctmgr = acctmgr
138
139 self._regh = None
140 self.pending = {}
141 self._nwdatastore = nwdatastore
142
143 @property
144 def regh(self):
145 """ The registration handle associated with this Handler"""
146 return self._regh
147
148 def deregister(self):
149 self._log.debug("De-register Topology static handler for project {}".
150 format(self._project.name))
151 if self._regh:
152 self._regh.deregister()
153 self._regh = None
154
155 @asyncio.coroutine
156 def register(self):
157 """ Register for the Static Topology path """
158
159 @asyncio.coroutine
160 def prepare_nw_cfg(dts, acg, xact, xact_info, ksp, msg, scratch):
161 """Prepare for application configuration. Stash the pending
162 configuration object for subsequent transaction phases"""
163 self._log.debug("Prepare Network config received network id %s, msg %s",
164 msg.network_id, msg)
165 self.pending[xact.id] = msg
166 xact_info.respond_xpath(rwdts.XactRspCode.ACK)
167
168 def apply_nw_config(dts, acg, xact, action, scratch):
169 """Apply the pending configuration object"""
170 if action == rwdts.AppconfAction.INSTALL and xact.id is None:
171 self._log.debug("No xact handle. Skipping apply config")
172 return
173
174 if xact.id not in self.pending:
175 raise KeyError("No stashed configuration found with transaction id [{}]".format(xact.id))
176
177 try:
178 if action == rwdts.AppconfAction.INSTALL:
179 self._nwdatastore.create_network(self.pending[xact.id].network_id, self.pending[xact.id])
180 elif action == rwdts.AppconfAction.RECONCILE:
181 self._nwdatastore.update_network(self.pending[xact.id].network_id, self.pending[xact.id])
182 except:
183 raise
184
185 self._log.debug("Create network config done")
186 return RwTypes.RwStatus.SUCCESS
187
188 self._log.debug("Registering for static topology using xpath %s", NwtopStaticDtsHandler.STATIC_XPATH)
189 handler=rift.tasklets.AppConfGroup.Handler(
190 on_apply=apply_nw_config)
191
192 with self._dts.appconf_group_create(handler=handler) as acg:
193 self._regh = acg.register(xpath = NwtopStaticDtsHandler.STATIC_XPATH,
194 flags = rwdts.Flag.SUBSCRIBER,
195 on_prepare=prepare_nw_cfg)