forked from nsacyber/WALKOFF
-
Notifications
You must be signed in to change notification settings - Fork 0
/
walkoff.py
124 lines (100 loc) · 4.3 KB
/
walkoff.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import argparse
import logging
import os
import sys
import traceback
from gevent import monkey
from gevent import pywsgi
from prometheus_flask_exporter import PrometheusMetrics
import walkoff
import walkoff.config
from tests.util.jsonplaybookloader import JsonPlaybookLoader
from walkoff.executiondb.playbook import Playbook
from walkoff.helpers import compose_api
from walkoff.server.app import create_app
logger = logging.getLogger('walkoff')
def run(args, app, host, port):
print_banner()
if not args.apponly:
from start_workers import spawn_worker_processes
pids = spawn_worker_processes()
else:
pids = None
monkey.patch_all()
app.running_context.inject_app(app)
app.running_context.executor.initialize_threading(app, pids)
# The order of these imports matter for initialization (should probably be fixed)
server = setup_server(app, host, port)
server.serve_forever()
def print_banner():
banner = '***** Running WALKOFF v.{} *****'.format(walkoff.__version__)
header_footer_banner = '*' * len(banner)
logger.info(header_footer_banner)
logger.info(banner)
logger.info(header_footer_banner)
def setup_server(app, host, port):
if os.path.isfile(walkoff.config.Config.CERTIFICATE_PATH) and os.path.isfile(
walkoff.config.Config.PRIVATE_KEY_PATH):
server = pywsgi.WSGIServer((host, port), application=app,
keyfile=walkoff.config.Config.PRIVATE_KEY_PATH,
certfile=walkoff.config.Config.CERTIFICATE_PATH)
protocol = 'https'
else:
logger.warning('Cannot find certificates. Using HTTP')
server = pywsgi.WSGIServer((host, port), application=app)
protocol = 'http'
logger.info('Listening on host {0}://{1}:{2}'.format(protocol, host, port))
return server
def parse_args():
parser = argparse.ArgumentParser(description='Script to the WALKOFF server')
parser.add_argument('-v', '--version', help='Get the version of WALKOFF running', action='store_true')
parser.add_argument('-p', '--port', help='port to run the server on')
parser.add_argument('-H', '--host', help='host address to run the server on')
parser.add_argument('-c', '--config', help='configuration file to use')
parser.add_argument('-a', '--apponly', help='start WALKOFF app only, no workers', action='store_true')
args = parser.parse_args()
if args.version:
print(walkoff.__version__)
exit(0)
return args
def convert_host_port(args):
host = walkoff.config.Config.HOST if args.host is None else args.host
port = walkoff.config.Config.PORT if args.port is None else args.port
try:
port = int(port)
except ValueError:
print('Invalid port {}. Port must be an integer!'.format(port))
exit(1)
return host, port
def import_workflows(app):
playbook_name = [playbook.id for playbook in app.running_context.execution_db.session.query(Playbook).all()]
if os.path.exists(walkoff.config.Config.WORKFLOWS_PATH):
logger.info('Importing any workflows not currently in database')
for p in os.listdir(walkoff.config.Config.WORKFLOWS_PATH):
full_path = os.path.join(walkoff.config.Config.WORKFLOWS_PATH, p)
if os.path.isfile(full_path):
playbook = JsonPlaybookLoader.load_playbook(full_path)
if playbook.name not in playbook_name:
app.running_context.execution_db.session.add(playbook)
app.running_context.execution_db.session.commit()
if __name__ == "__main__":
args = parse_args()
exit_code = 0
walkoff.config.initialize(args.config)
compose_api(walkoff.config.Config)
app = create_app()
if not walkoff.config.Config.SEPARATE_PROMETHEUS:
metrics = PrometheusMetrics(app, path='/prometheus_metrics')
import_workflows(app)
try:
run(args, app, *convert_host_port(args))
except KeyboardInterrupt:
logger.info('Caught KeyboardInterrupt! Please wait a few seconds for WALKOFF to shutdown.')
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exc()
exit_code = 1
finally:
app.running_context.executor.shutdown_pool()
logger.info('Shutting down server')
os._exit(exit_code)