Initial commit
[ta/config-manager.git] / cmframework / src / cmframework / server / cmactivateserverhandler.py
1 # Copyright 2019 Nokia
2
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 import logging
15 import time
16
17 from cmframework.utils import cmpluginmanager
18 from cmframework.utils import cmpluginloader
19 from cmframework.utils import cmactivationwork
20
21 from cmframework.apis import cmactivator
22 from cmframework.server import cmactivatehandler
23
24
25 class CMActivateServerHandler(cmactivatehandler.CMActivateHandler,
26                               cmpluginmanager.CMPluginManager,
27                               cmpluginloader.CMPluginLoader.LoadingFilter):
28
29     def __init__(self, plugins_path, plugin_client, changemonitor, activationstate_handler):
30         cmpluginmanager.CMPluginManager.__init__(self, plugins_path)
31         self.load_plugin()
32         self.plugin_client = plugin_client
33         self.changemonitor = changemonitor
34         self.activationstate_handler = activationstate_handler
35
36     def is_supported(self, activator_plugin):
37         logging.debug('Checking %s', activator_plugin)
38         return isinstance(activator_plugin, cmactivator.CMGlobalActivator)
39
40     def load_plugin(self):
41         plugin_filter = self
42         pl = cmpluginloader.CMPluginLoader(self.plugins_path, plugin_filter)
43         self.pluginlist, self.filterdict = pl.load()
44         logging.info('pluginlist is %r', self.pluginlist)
45
46     def activate_set(self, indata):
47         return self._activate(indata, 'activate_set')
48
49     def activate_delete(self, indata):
50         return self._activate(indata, 'activate_delete')
51
52     def activate_full(self, target_node, startup_activation=False):
53         return self._activate(target_node, 'activate_full', startup_activation)
54
55     def activate_node(self, target_node):
56         return self._activate(target_node, 'activate_full')
57
58     def _activate(self, indata, operation, startup_activation=False):
59         logging.info('%s called with %s', operation, indata)
60         failures = {}
61         for plugin, objectname in self.pluginlist.iteritems():
62             logging.info('Running plugin %s.%s', plugin, operation)
63             func = None
64             try:
65                 class_name = getattr(objectname, plugin)
66                 instance = class_name()
67                 instance.plugin_client = self.plugin_client
68                 func = getattr(instance, operation)
69                 if operation != 'activate_full':
70                     filtername = self.filterdict[plugin]
71                     inputdata = self.build_input(indata, filtername)
72
73                     if not inputdata:
74                         logging.info('Skipping plugin %s as no input data is to be processed by it',
75                                      plugin)
76                         continue
77
78                     start_time = time.time()
79                     func(inputdata)
80                     logging.info('Plugin %s.%s took %s seconds', plugin, operation,
81                                  time.time() - start_time)
82                 else:
83                     if startup_activation:
84                         if plugin not in self.activationstate_handler.get_full_failed():
85                             logging.info('Skipping plugin %s during startup as '
86                                          'it has not failed in last activation', plugin)
87                             continue
88
89                     start_time = time.time()
90                     func(indata)
91                     logging.info('Plugin %s.%s took %s seconds', plugin, operation,
92                                  time.time() - start_time)
93             except AttributeError as exp:
94                 logging.info('Plugin %s does not have %s defined', plugin, operation)
95                 logging.info(str(exp))
96                 failures[str(plugin)] = 'Plugin does not have {} defined'.format(operation)
97                 continue
98             except Exception as exp:  # pylint: disable=broad-except
99                 failures[str(plugin)] = str(exp)
100                 logging.error('Skipping %s, got exception %s', plugin, str(exp))
101                 failures[str(plugin)] = str(exp)
102                 continue
103
104         logging.info('%s done with %s', operation, indata)
105
106         return failures
107
108     def activate(self, work):
109         logging.debug('CMAcivateServerHandler activating %s', work)
110         failures = {}
111         if work.get_operation() == cmactivationwork.CMActivationWork.OPER_SET:
112             failures = self.activate_set(work.get_props())
113         elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_DELETE:
114             failures = self.activate_delete(work.get_props())
115         elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_FULL:
116             startup_activation = work.is_startup_activation()
117             failures = self.activate_full(work.get_target(), startup_activation)
118         elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_NODE:
119             failures = self.activate_node(work.get_target())
120         else:
121             logging.error('Unsupported activation operation %s', work.get_operation())
122
123         if work.uuid_value:
124             if failures:
125                 self.changemonitor.change_nok(work.uuid_value, failures)
126             else:
127                 self.changemonitor.change_ok(work.uuid_value)
128
129         return failures