c2abaa17c492a82591e69e947c259e84e23cf6a6
[ta/config-manager.git] / cmframework / src / cmframework / agent / cmagent.py
1 #! /usr/bin/python
2
3 # Copyright 2019 Nokia
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 from __future__ import print_function
18 import sys
19 import argparse
20 import socket
21 import logging
22 import subprocess
23
24 from cmframework.apis import cmmanage
25 from cmframework.apis import cmerror
26 from cmframework.utils import cmlogger
27 from cmframework.utils import cmalarm
28
29
30 class VerboseLogger(object):
31     def __call__(self, msg):
32         print (msg)
33
34
35 class CMAgent(object):
36     def __init__(self):
37         self.prog = 'cmagent'
38         self.ip = None
39         self.port = None
40         self.verbose = False
41         self.log_level = cmlogger.CMLogger.str_to_level('debug')
42         self.log_dest = cmlogger.CMLogger.str_to_dest('syslog')
43         self.api = None
44         self.verbose_logger = VerboseLogger()
45
46     @staticmethod
47     def log_level_parser(level):
48         try:
49             return cmlogger.CMLogger.str_to_level(level)
50         except cmerror.CMError as exp:
51             raise argparse.ArgumentTypeError(str(exp))
52
53     @staticmethod
54     def log_dest_parser(dest):
55         try:
56             return cmlogger.CMLogger.str_to_dest(dest)
57         except cmerror.CMError as exp:
58             raise argparse.ArgumentTypeError(str(exp))
59
60     def __call__(self, args):
61         parser = argparse.ArgumentParser(description='Configuration Management Agent',
62                                          prog=self.prog)
63         parser.add_argument('--ip',
64                             dest='ip',
65                             metavar='SERVER-IP',
66                             default='config-manager',
67                             type=str,
68                             action='store')
69
70         parser.add_argument('--port',
71                             dest='port',
72                             metavar='SERVER-PORT',
73                             default=61100,
74                             type=int,
75                             action='store')
76
77         parser.add_argument('--client-lib',
78                             dest='client_lib',
79                             metavar='CLIENT-LIB',
80                             default='cmframework.lib.CMClientImpl',
81                             type=str,
82                             action='store')
83
84         parser.add_argument('--log-level',
85                             dest='log_level',
86                             metavar='LOG-LEVEL',
87                             required=False,
88                             help=('The enabled logging level, possible values are '
89                                   '{debug, info, warn, error}'),
90                             type=CMAgent.log_level_parser,
91                             default=self.log_level,
92                             action='store')
93
94         parser.add_argument('--log-dest',
95                             dest='log_dest',
96                             metavar='LOG-DEST',
97                             required=False,
98                             help='The logs destination, possible values are {console, syslog}',
99                             type=CMAgent.log_dest_parser,
100                             default=self.log_dest,
101                             action='store')
102
103         parser.add_argument('--verbose',
104                             required=False,
105                             default=False,
106                             action='store_true')
107
108         args = parser.parse_args(args)
109
110         self.process(args)
111
112     def _init_api(self, ip, port, client_lib):
113         try:
114             serverip = socket.gethostbyname(ip)
115         except socket.gaierror:
116             # use localhost in-case we cannot resolve the provided hostname
117             serverip = '127.0.0.1'
118
119         self.api = cmmanage.CMManage(serverip, port, client_lib, self.verbose_logger)
120
121     @staticmethod
122     def _reboot_node():
123         cmd = 'systemctl reboot'
124         args = cmd.split()
125         process = subprocess.Popen(args)
126         return process.wait()
127
128     def process(self, args):
129         cmlogger.CMLogger(args.log_dest, args.verbose, args.log_level)
130
131         self._init_api(args.ip, args.port, args.client_lib)
132
133         node_name = socket.gethostname()
134
135         reboot_request_alarm = cmalarm.CMRebootRequestAlarm()
136         reboot_request_alarm.cancel_alarm_for_node(node_name)
137
138         reboot = self.api.activate_node(node_name)
139         if reboot:
140             logging.warn('Going to reboot this node')
141             res = self._reboot_node()
142             if res != 0:
143                 logging.error('Reboot failed')
144
145
146 def main():
147     try:
148         agent = CMAgent()
149         args = sys.argv[1:]
150         agent(args)
151     except cmerror.CMError as exp:
152         print ('Failed with error: %s' % str(exp))
153         return 1
154     # TODO: catch all exceptions?
155
156
157 if __name__ == '__main__':
158     sys.exit(main())