Added progress reporter playbook
[ta/infra-ansible.git] / playbooks / report-installation-progress
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 logging
21
22 import requests
23
24 class ProgressReporter(object):
25     CALLBACK_URL_PATH = '/etc/userconfig/callback_url'
26     DEFAULT_CLIENT_CERT = '/etc/userconfig/clientcert.pem'
27     DEFAULT_CLIENT_KEY = '/etc/userconfig/clientkey.pem'
28
29     def __init__(self):
30         self._prog = 'progress-reporter'
31         self._callback_url = None
32         self._verbose = None
33         self._status = None
34         self._percentage = None
35         self._description = None
36         self._client_cert_path = ProgressReporter.DEFAULT_CLIENT_CERT
37         self._client_key_path = ProgressReporter.DEFAULT_CLIENT_KEY
38
39     def __call__(self, args):
40         parser = argparse.ArgumentParser(description='Progress Reporter',
41                                          prog=self._prog)
42
43         parser.add_argument('--callback-url',
44                             dest='callback_url',
45                             metavar='CALLBACK-URL',
46                             required=False,
47                             help='The URL for the report callback',
48                             action='store')
49
50         parser.add_argument('--client-cert-path',
51                             dest='client_cert_path',
52                             metavar='CLIENT-CERT-PATH',
53                             required=False,
54                             help='The path to client cert file',
55                             action='store')
56
57         parser.add_argument('--client-key-path',
58                             dest='client_key_path',
59                             metavar='CLIENT-KEY-PATH',
60                             required=False,
61                             help='The path to client key file',
62                             action='store')
63
64         parser.add_argument('--status',
65                             dest='status',
66                             metavar='STATUS',
67                             required=True,
68                             help='The status of the progress, should be: ongoing or failed or success',
69                             action='store')
70
71         parser.add_argument('--description',
72                             dest='description',
73                             metavar='DESCRIPTION',
74                             required=True,
75                             help='The description of the progress',
76                             action='store')
77
78         parser.add_argument('--percentage',
79                             dest='percentage',
80                             metavar='PERCENTAGE',
81                             required=False,
82                             help='The percentage of the progress',
83                             action='store')
84
85         parser.add_argument('--verbose',
86                             required=False,
87                             default=False,
88                             action='store_true')
89
90         args = parser.parse_args(args)
91
92         self.process(args)
93
94     def _set_callback_url(self):
95         try:
96             with open(ProgressReporter.CALLBACK_URL_PATH) as cf:
97                 self._callback_url = cf.readline().strip()
98         except IOError:
99             logging.debug('No callback URL found')
100
101     def _send_progress(self):
102         if self._callback_url:
103             request_data = {'status': self._status, 'description': self._description}
104             if self._percentage:
105                 request_data['percentage'] = self._percentage
106
107             cert_tuple = None
108             if self._client_cert_path:
109                 cert_tuple = (self._client_cert_path, self._client_key_path)
110
111             response = None
112             try:
113                 response = requests.post(self._callback_url, json=request_data, cert=cert_tuple, verify=False)
114                 if response.status_code != requests.codes.ok:
115                     logging.debug('Failed to send progress: %s (%s)', str(response.reason), str(response.status_code))
116                     raise Exception('Failed')
117             except Exception as ex:
118                 logging.debug('Failed to send progress: %s', str(ex))
119                 raise Exception('Failed')
120
121         return True
122
123     def process(self, args):
124         log_level = logging.INFO
125         if args.verbose:
126             log_level = logging.DEBUG
127
128         logging.basicConfig(level=log_level, format='%(asctime)s %(message)s')
129
130         self._callback_url = args.callback_url
131         if not self._callback_url:
132             self._set_callback_url()
133
134         if args.client_cert_path:
135             self._client_cert_path = args.client_cert_path
136
137         if args.client_key_path:
138             self._client_key_path = args.client_key_path
139
140         self._verbose = args.verbose
141         self._status = args.status
142         self._percentage = args.percentage
143         self._description = args.description
144
145         logging.debug('callback_url = %s', self._callback_url)
146         logging.debug('client_cert_path = %s', self._client_cert_path)
147         logging.debug('client_key_path = %s', self._client_key_path)
148         logging.info('status=%s, percentage=%s, description=%s', self._status, self._percentage, self._description)
149
150         self._send_progress()
151
152 def main():
153     try:
154         reporter = ProgressReporter()
155         args = sys.argv[1:]
156         reporter(args)
157     except Exception as exp:
158         logging.error('Failed with error: %s', str(exp))
159         return 1
160
161
162 if __name__ == '__main__':
163     sys.exit(main())