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
, on_add_config_agent
, on_delete_config_agent
):
55 self
._on
_add
_config
_agent
= on_add_config_agent
56 self
._on
_delete
_config
_agent
= on_delete_config_agent
58 self
._log
.debug("creating config account handler")
59 self
.cloud_cfg_handler
= rift
.mano
.config_agent
.ConfigAgentSubscriber(
61 rift
.mano
.config_agent
.ConfigAgentCallbacks(
62 on_add_apply
=self
.on_config_account_added
,
63 on_delete_apply
=self
.on_config_account_deleted
,
67 def on_config_account_deleted(self
, account
):
68 self
._log
.debug("config account deleted: %s", account
.name
)
69 self
._on
_delete
_config
_agent
(account
)
71 def on_config_account_added(self
, account
):
72 self
._log
.debug("config account added")
73 self
._log
.debug(account
.as_dict())
74 self
._on
_add
_config
_agent
(account
)
78 self
.cloud_cfg_handler
.register()
80 class RiftCMConfigPlugins(object):
81 """ NSM Config Agent Plugins """
83 self
._plugin
_classes
= {
84 "juju": jujuconf
.JujuConfigPlugin
,
85 "riftca": RiftCA
.RiftCAConfigPlugin
,
91 return self
._plugin
_classes
93 def __getitem__(self
, name
):
95 return self
._plugin
_classes
[name
]
97 def register(self
, plugin_name
, plugin_class
, *args
):
98 """ Register a plugin to this Nsm"""
99 self
._plugin
_classes
[plugin_name
] = plugin_class
101 def deregister(self
, plugin_name
, plugin_class
, *args
):
102 """ Deregister a plugin to this Nsm"""
103 if plugin_name
in self
._plugin
_classes
:
104 del self
._plugin
_classes
[plugin_name
]
106 def class_by_plugin_name(self
, name
):
107 """ Get class by plugin name """
108 return self
._plugin
_classes
[name
]
111 class RiftCMConfigAgent(object):
112 def __init__(self
, dts
, log
, loop
, parent
):
116 self
._ConfigManagerConfig
= parent
118 self
._config
_plugins
= RiftCMConfigPlugins()
119 self
._config
_handler
= ConfigAccountHandler(
120 self
._dts
, self
._log
, self
._loop
, self
._on
_config
_agent
, self
._on
_config
_agent
_delete
)
121 self
._plugin
_instances
= {}
122 self
._default
_account
_added
= False
125 def invoke_config_agent_plugins(self
, method
, nsr
, vnfr
, *args
):
126 # Invoke the methods on all config agent plugins registered
128 for agent
in self
._plugin
_instances
.values():
129 if not agent
.is_vnfr_managed(vnfr
.id):
132 self
._log
.debug("Invoke {} on {}".format(method
, agent
.name
))
133 rc
= yield from agent
.invoke(method
, nsr
, vnfr
, *args
)
135 except Exception as e
:
136 self
._log
.error("Error invoking {} on {} : {}".
137 format(method
, agent
.name
, e
))
140 self
._log
.info("vnfr({}), method={}, return rc={}"
141 .format(vnfr
.name
, method
, rc
))
144 def is_vnfr_config_agent_managed(self
, vnfr
):
145 if (not vnfr
.has_field('netconf') and
146 not vnfr
.has_field('juju') and
147 not vnfr
.has_field('script')):
150 for agent
in self
._plugin
_instances
.values():
152 if agent
.is_vnfr_managed(vnfr
.id):
154 except Exception as e
:
155 self
._log
.debug("Check if VNFR {} is config agent managed: {}".
156 format(vnfr
.name
, e
))
159 def _on_config_agent(self
, config_agent
):
160 self
._log
.debug("Got nsm plugin config agent account: %s", config_agent
)
162 cap_name
= config_agent
.name
163 cap_inst
= self
._config
_plugins
.class_by_plugin_name(
164 config_agent
.account_type
)
165 except KeyError as e
:
166 msg
= "Config agent nsm plugin type not found: {}". \
167 format(config_agent
.account_type
)
169 raise UnknownAgentTypeError(msg
)
171 # Check to see if the plugin was already instantiated
172 if cap_name
in self
._plugin
_instances
:
173 self
._log
.debug("Config agent nsm plugin {} already instantiated. " \
174 "Using existing.". format(cap_name
))
176 # Otherwise, instantiate a new plugin using the config agent account
177 self
._log
.debug("Instantiting new config agent using class: %s", cap_inst
)
178 new_instance
= cap_inst(self
._dts
, self
._log
, self
._loop
, config_agent
)
179 self
._plugin
_instances
[cap_name
] = new_instance
181 # TODO (pjoseph): See why this was added, as this deletes the
182 # Rift plugin account when Juju account is added
183 # if self._default_account_added:
184 # # If the user has provided a config account, chuck the default one.
185 # if self.DEFAULT_CAP_TYPE in self._plugin_instances:
186 # del self._plugin_instances[self.DEFAULT_CAP_TYPE]
188 def _on_config_agent_delete(self
, config_agent
):
189 self
._log
.debug("Got nsm plugin config agent delete, account: %s, type: %s",
190 config_agent
.name
, config_agent
.account_type
)
191 cap_name
= config_agent
.account_type
192 if cap_name
in self
._plugin
_instances
:
193 self
._log
.debug("Config agent nsm plugin exists, deleting it.")
194 del self
._plugin
_instances
[cap_name
]
196 self
._log
.error("Error deleting - Config Agent nsm plugin %s does not exist.", cap_name
)
201 self
._log
.debug("Registering for config agent nsm plugin manager")
202 yield from self
._config
_handler
.register()
204 account
= rwcfg_agent
.ConfigAgentAccount()
205 account
.account_type
= DEFAULT_CAP_TYPE
206 account
.name
= "RiftCA"
207 self
._on
_config
_agent
(account
)
208 self
._default
_account
_added
= True
210 # Also grab any account already configured
211 config_agents
= yield from self
._ConfigManagerConfig
.cmdts_obj
.get_config_agents(name
=None)
212 for account
in config_agents
:
213 self
._on
_config
_agent
(account
)
215 def set_config_agent(self
, nsr
, vnfr
, method
):
218 elif method
in ['netconf', 'script']:
219 agent_type
= DEFAULT_CAP_TYPE
221 msg
= "Unsupported configuration method ({}) for VNF:{}/{}". \
222 format(method
, nsr
.name
, vnfr
.name
)
224 raise UnknownAgentTypeError(msg
)
227 acc_map
= nsr
.nsr_cfg_msg
.vnf_cloud_account_map
228 except AttributeError:
229 self
._log
.debug("Did not find cloud account map for NS {}".
234 if vnfd
.config_agent_account
is not None:
235 if vnfd
.member_vnf_index_ref
== vnfr
.vnfr_msg
.member_index
:
236 for agent
in self
._plugin
_instances
:
237 # Find the plugin with the same name
238 if agent
== vnfd
.config_agent_account
:
239 # Check if the types are same
240 if self
._plugin
_instances
[agent
].agent_type
!= agent_type
:
241 msg
= "VNF {} specified config agent {} is not of type {}". \
242 format(vnfr
.name
, agent
, agent_type
)
244 raise ConfigAgentVnfrTypeError(msg
)
246 self
._plugin
_instances
[agent
].add_vnfr_managed(vnfr
)
247 self
._log
.debug("Added vnfr {} as config plugin {} managed".
248 format(vnfr
.name
, agent
))
251 # If no config agent specified for the VNF, use the
252 # first available of the same type
253 for agent
in self
._plugin
_instances
:
254 if self
._plugin
_instances
[agent
].agent_type
== agent_type
:
255 self
._plugin
_instances
[agent
].add_vnfr_managed(vnfr
)
256 self
._log
.debug("Added vnfr {} as config plugin {} managed".
257 format(vnfr
.name
, agent
))
260 msg
= "Error finding config agent of type {} for VNF {}". \
261 format(agent_type
, vnfr
.name
)
263 raise ConfigAgentVnfrAddError(msg
)