2 # Copyright 2016 RIFT.IO Inc
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
20 from gi
.repository
import (
21 RwConfigAgentYang
as rwcfg_agent
,
24 from .riftcm_config_plugin
import DEFAULT_CAP_TYPE
26 from . import jujuconf
27 import rift
.mano
.config_agent
30 class ConfigAgentError(Exception):
34 class ConfigAgentExistsError(ConfigAgentError
):
38 class UnknownAgentTypeError(Exception):
42 class ConfigAgentVnfrAddError(Exception):
46 class ConfigAgentVnfrTypeError(Exception):
50 class ConfigAccountHandler(object):
51 def __init__(self
, dts
, log
, loop
, project
, on_add_config_agent
, on_delete_config_agent
):
55 self
._project
= project
56 self
._on
_add
_config
_agent
= on_add_config_agent
57 self
._on
_delete
_config
_agent
= on_delete_config_agent
59 self
._log
.debug("creating config account handler")
60 self
.cloud_cfg_handler
= rift
.mano
.config_agent
.ConfigAgentSubscriber(
61 self
._dts
, self
._log
, self
._project
,
62 rift
.mano
.config_agent
.ConfigAgentCallbacks(
63 on_add_apply
=self
.on_config_account_added
,
64 on_delete_apply
=self
.on_config_account_deleted
,
68 def on_config_account_deleted(self
, account
):
69 self
._log
.debug("config account deleted: %s", account
.name
)
70 self
._on
_delete
_config
_agent
(account
)
72 def on_config_account_added(self
, account
):
73 self
._log
.debug("config account added")
74 self
._log
.debug(account
.as_dict())
75 self
._on
_add
_config
_agent
(account
)
79 self
.cloud_cfg_handler
.register()
82 self
.cloud_cfg_handler
.deregister()
85 class RiftCMConfigPlugins(object):
86 """ NSM Config Agent Plugins """
88 self
._plugin
_classes
= {
89 "juju": jujuconf
.JujuConfigPlugin
,
90 "riftca": RiftCA
.RiftCAConfigPlugin
,
96 return self
._plugin
_classes
98 def __getitem__(self
, name
):
100 return self
._plugin
_classes
[name
]
102 def register(self
, plugin_name
, plugin_class
, *args
):
103 """ Register a plugin to this Nsm"""
104 self
._plugin
_classes
[plugin_name
] = plugin_class
106 def deregister(self
, plugin_name
, plugin_class
, *args
):
107 """ Deregister a plugin to this Nsm"""
108 if plugin_name
in self
._plugin
_classes
:
109 del self
._plugin
_classes
[plugin_name
]
111 def class_by_plugin_name(self
, name
):
112 """ Get class by plugin name """
113 return self
._plugin
_classes
[name
]
116 class RiftCMConfigAgent(object):
117 def __init__(self
, dts
, log
, loop
, parent
):
121 self
._ConfigManagerConfig
= parent
123 self
._config
_plugins
= RiftCMConfigPlugins()
124 self
._config
_handler
= ConfigAccountHandler(
125 self
._dts
, self
._log
, self
._loop
, parent
._project
,
126 self
._on
_config
_agent
, self
._on
_config
_agent
_delete
)
127 self
._plugin
_instances
= {}
128 self
._default
_account
_added
= False
131 def invoke_config_agent_plugins(self
, method
, nsr
, vnfr
, *args
):
132 # Invoke the methods on all config agent plugins registered
134 for agent
in self
._plugin
_instances
.values():
135 if not agent
.is_vnfr_managed(vnfr
.id):
138 self
._log
.debug("Invoke {} on {}".format(method
, agent
.name
))
139 rc
= yield from agent
.invoke(method
, nsr
, vnfr
, *args
)
141 except Exception as e
:
142 self
._log
.error("Error invoking {} on {} : {}".
143 format(method
, agent
.name
, e
))
146 self
._log
.info("vnfr({}), method={}, return rc={}"
147 .format(vnfr
.name
, method
, rc
))
150 def get_vnfr_config_agent(self
, vnfr
):
151 # if (not vnfr.has_field('netconf') and
152 # not vnfr.has_field('juju') and
153 # not vnfr.has_field('script')):
156 for agent
in self
._plugin
_instances
.values():
158 if agent
.is_vnfr_managed(vnfr
.id):
160 except Exception as e
:
161 self
._log
.debug("Check if VNFR {} is config agent managed: {}".
162 format(vnfr
.name
, e
))
164 def is_vnfr_config_agent_managed(self
, vnfr
):
165 if self
.get_vnfr_config_agent(vnfr
):
169 def _on_config_agent(self
, config_agent
):
170 self
._log
.debug("Got nsm plugin config agent account: %s", config_agent
)
172 cap_name
= config_agent
.name
173 cap_inst
= self
._config
_plugins
.class_by_plugin_name(
174 config_agent
.account_type
)
175 except KeyError as e
:
176 msg
= "Config agent nsm plugin type not found: {}". \
177 format(config_agent
.account_type
)
179 raise UnknownAgentTypeError(msg
)
181 # Check to see if the plugin was already instantiated
182 if cap_name
in self
._plugin
_instances
:
183 self
._log
.debug("Config agent nsm plugin {} already instantiated. " \
184 "Using existing.". format(cap_name
))
186 # Otherwise, instantiate a new plugin using the config agent account
187 self
._log
.debug("Instantiting new config agent using class: %s", cap_inst
)
188 new_instance
= cap_inst(self
._dts
, self
._log
, self
._loop
,
189 self
._ConfigManagerConfig
._project
, config_agent
)
190 self
._plugin
_instances
[cap_name
] = new_instance
192 # TODO (pjoseph): See why this was added, as this deletes the
193 # Rift plugin account when Juju account is added
194 # if self._default_account_added:
195 # # If the user has provided a config account, chuck the default one.
196 # if self.DEFAULT_CAP_TYPE in self._plugin_instances:
197 # del self._plugin_instances[self.DEFAULT_CAP_TYPE]
199 def _on_config_agent_delete(self
, config_agent
):
200 self
._log
.debug("Got nsm plugin config agent delete, account: %s, type: %s",
201 config_agent
.name
, config_agent
.account_type
)
202 cap_name
= config_agent
.account_type
203 if cap_name
in self
._plugin
_instances
:
204 self
._log
.debug("Config agent nsm plugin exists, deleting it.")
205 del self
._plugin
_instances
[cap_name
]
207 self
._log
.error("Error deleting - Config Agent nsm plugin %s does not exist.", cap_name
)
212 self
._log
.debug("Registering for config agent nsm plugin manager")
213 yield from self
._config
_handler
.register()
215 account
= rwcfg_agent
.ConfigAgentAccount()
216 account
.account_type
= DEFAULT_CAP_TYPE
217 account
.name
= "RiftCA"
218 self
._on
_config
_agent
(account
)
219 self
._default
_account
_added
= True
221 # Also grab any account already configured
222 config_agents
= yield from self
._ConfigManagerConfig
.cmdts_obj
.get_config_agents(name
=None)
223 for account
in config_agents
:
224 self
._on
_config
_agent
(account
)
226 def deregister(self
):
227 self
._log
.debug("De-registering config agent nsm plugin manager".
228 format(self
._ConfigManagerConfig
._project
))
229 self
._config
_handler
.deregister()
231 def set_config_agent(self
, nsr
, vnfr
, method
):
234 elif method
in ['netconf', 'script']:
235 agent_type
= DEFAULT_CAP_TYPE
237 msg
= "Unsupported configuration method ({}) for VNF:{}/{}". \
238 format(method
, nsr
.name
, vnfr
.name
)
240 raise UnknownAgentTypeError(msg
)
243 acc_map
= nsr
.nsr_cfg_msg
.vnf_cloud_account_map
244 except AttributeError:
245 self
._log
.debug("Did not find cloud account map for NS {}".
250 if vnfd
.config_agent_account
is not None:
251 if vnfd
.member_vnf_index_ref
== vnfr
.vnfr_msg
.member_index
:
252 for agent
in self
._plugin
_instances
:
253 # Find the plugin with the same name
254 if agent
== vnfd
.config_agent_account
:
255 # Check if the types are same
256 if self
._plugin
_instances
[agent
].agent_type
!= agent_type
:
257 msg
= "VNF {} specified config agent {} is not of type {}". \
258 format(vnfr
.name
, agent
, agent_type
)
260 raise ConfigAgentVnfrTypeError(msg
)
262 self
._plugin
_instances
[agent
].add_vnfr_managed(vnfr
)
263 self
._log
.debug("Added vnfr {} as config plugin {} managed".
264 format(vnfr
.name
, agent
))
267 # If no config agent specified for the VNF, use the
268 # first available of the same type
269 for agent
in self
._plugin
_instances
:
270 if self
._plugin
_instances
[agent
].agent_type
== agent_type
:
271 self
._plugin
_instances
[agent
].add_vnfr_managed(vnfr
)
272 self
._log
.debug("Added vnfr {} as config plugin {} managed".
273 format(vnfr
.name
, agent
))
276 msg
= "Error finding config agent of type {} for VNF {}". \
277 format(agent_type
, vnfr
.name
)
279 raise ConfigAgentVnfrAddError(msg
)