1f5599d381b71ebad04dfbaafd7b0f1b43c1d7bc
[osm/SO.git] / rwlaunchpad / plugins / rwnsm / rift / tasklets / rwnsmtasklet / rwnsm_conman.py
1
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16 #
17
18 import asyncio
19 import ncclient
20 import ncclient.asyncio_manager
21 import re
22 import time
23
24 import gi
25 gi.require_version('RwYang', '1.0')
26 gi.require_version('RwNsmYang', '1.0')
27 gi.require_version('RwDts', '1.0')
28 gi.require_version('RwTypes', '1.0')
29 gi.require_version('RwConmanYang', '1.0')
30 gi.require_version('NsrYang', '1.0')
31
32 from gi.repository import (
33 NsrYang as nsrY,
34 RwYang,
35 RwNsmYang as nsmY,
36 RwDts as rwdts,
37 RwTypes,
38 RwConmanYang as conmanY,
39 )
40
41 import rift.tasklets
42
43 class ROConfigManager(object):
44 def __init__(self, log, loop, dts, parent):
45 self._log = log
46 self._loop = loop
47 self._dts = dts
48 self.nsm = parent
49 self.project = parent._project
50 self._log.debug("Initialized ROConfigManager")
51
52 def is_ready(self):
53 return True
54
55 @property
56 def cm_state_xpath(self):
57 return self.project.add_project("/rw-conman:cm-state/rw-conman:cm-nsr")
58
59 @classmethod
60 def map_config_status(cls, status):
61 cfg_map = {
62 'init': nsrY.ConfigStates.INIT,
63 'received': nsrY.ConfigStates.CONFIGURING,
64 'cfg_delay': nsrY.ConfigStates.CONFIGURING,
65 'cfg_process': nsrY.ConfigStates.CONFIGURING,
66 'cfg_process_failed': nsrY.ConfigStates.CONFIGURING,
67 'cfg_sched': nsrY.ConfigStates.CONFIGURING,
68 'connecting': nsrY.ConfigStates.CONFIGURING,
69 'failed_connection': nsrY.ConfigStates.CONFIGURING,
70 'netconf_connected': nsrY.ConfigStates.CONFIGURING,
71 'netconf_ssh_connected': nsrY.ConfigStates.CONFIGURING,
72 'restconf_connected': nsrY.ConfigStates.CONFIGURING,
73 'cfg_send': nsrY.ConfigStates.CONFIGURING,
74 'cfg_failed': nsrY.ConfigStates.FAILED,
75 'ready_no_cfg': nsrY.ConfigStates.CONFIG_NOT_NEEDED,
76 'ready': nsrY.ConfigStates.CONFIGURED,
77 'terminate': nsrY.ConfigStates.TERMINATE,
78 }
79
80 return cfg_map[status]
81
82 @asyncio.coroutine
83 def update_ns_cfg_state(self, cm_nsr):
84 if cm_nsr is None:
85 return
86
87 try:
88 nsrid = cm_nsr.id
89
90 # Update the VNFRs' config status
91 gen = (vnfr for vnfr in cm_nsr.cm_vnfr
92 if vnfr.id in self.nsm._vnfrs)
93
94 for vnfr in gen:
95 vnfrid = vnfr.id
96 new_status = ROConfigManager.map_config_status(vnfr.state)
97 self._log.debug("Updating config status of VNFR {} " \
98 "in NSR {} to {}({})".
99 format(vnfrid, nsrid, new_status,
100 vnfr.state))
101 yield from \
102 self.nsm.vnfrs[vnfrid].set_config_status(new_status)
103
104 yield from \
105 self.nsm.vnfrs[vnfrid].update_config_primitives(
106 vnfr.vnf_configuration,
107 self.nsm.nsrs[nsrid])
108
109 # Update the NSR's config status
110 new_status = ROConfigManager.map_config_status(cm_nsr.state)
111 self._log.debug("Updating config status of NSR {} to {}({})".
112 format(nsrid, new_status, cm_nsr.state))
113
114 # If terminate nsr request comes when NS instantiation is in
115 # 'Configuring state'; self.nsm.nsrs dict is already empty when
116 # self.nsm.nsrs[nsrid].set_config_status gets executed. So adding a check here.
117 if nsrid in self.nsm.nsrs:
118 yield from self.nsm.nsrs[nsrid].set_config_status(
119 new_status,
120 cm_nsr.state_details)
121
122 except Exception as e:
123 self._log.error("Failed to process cm-state for nsr {}: {}".
124 format(nsrid, e))
125 self._log.exception(e)
126
127 @asyncio.coroutine
128 def register(self):
129 """ Register for cm-state changes """
130
131 @asyncio.coroutine
132 def on_prepare(xact_info, query_action, ks_path, msg):
133 """ cm-state changed """
134
135 self._log.debug("Received cm-state on_prepare (%s:%s:%s)",
136 query_action,
137 ks_path,
138 msg)
139
140 if (query_action == rwdts.QueryAction.UPDATE or
141 query_action == rwdts.QueryAction.CREATE):
142 # Update Each NSR/VNFR state
143 # msg_dict = msg.as_dict()
144 yield from self.update_ns_cfg_state(msg)
145 elif query_action == rwdts.QueryAction.DELETE:
146 self._log.debug("DELETE action in on_prepare for cm-state, "
147 "ignoring")
148 else:
149 raise NotImplementedError(
150 "%s on cm-state is not supported",
151 query_action)
152
153 xact_info.respond_xpath(rwdts.XactRspCode.ACK)
154
155 try:
156 handler = rift.tasklets.DTS.RegistrationHandler(
157 on_prepare=on_prepare)
158 self.dts_reg_hdl = yield from self._dts.register(
159 self.cm_state_xpath,
160 flags=rwdts.Flag.SUBSCRIBER,
161 handler=handler)
162
163 except Exception as e:
164 self._log.error("Failed to register for cm-state changes as %s", str(e))
165
166
167 def deregister(self):
168 if self.dts_reg_hdl:
169 self.dts_reg_hdl.deregister()
170 self.dts_reg_hdl = None