summaryrefslogtreecommitdiffstats
path: root/samples/services/nginx/docker/grpc/nginx_grpc_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'samples/services/nginx/docker/grpc/nginx_grpc_server.py')
-rw-r--r--samples/services/nginx/docker/grpc/nginx_grpc_server.py236
1 files changed, 236 insertions, 0 deletions
diff --git a/samples/services/nginx/docker/grpc/nginx_grpc_server.py b/samples/services/nginx/docker/grpc/nginx_grpc_server.py
new file mode 100644
index 0000000..5ad64b5
--- /dev/null
+++ b/samples/services/nginx/docker/grpc/nginx_grpc_server.py
@@ -0,0 +1,236 @@
+# Copyright (c) Authors of Clover
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+
+from concurrent import futures
+import time
+import os
+import sys
+import grpc
+import subprocess
+import psutil
+import shutil
+import pickle
+import logging
+import nginx_pb2
+import nginx_pb2_grpc
+
+from jinja2 import Template
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+GRPC_PORT = '[::]:50054'
+
+
+class Controller(nginx_pb2_grpc.ControllerServicer):
+
+ def __init__(self, service_type):
+ logging.basicConfig(filename='nginx.log', level=logging.DEBUG)
+ self.service_type = service_type
+ self.out_file = '/etc/nginx/nginx.conf'
+ self.nginx = 0
+ if service_type == "proxy":
+ self.template_file = '/grpc/templates/proxy.template'
+ self.ModifyProxy(nginx_pb2.ConfigProxy(
+ server_port='9180', server_name='proxy-access-control',
+ location_path='/', proxy_path='http://http-lb:9180',
+ mirror_path='http://snort-ids:80'), "")
+ if service_type == "server":
+ self.template_file = '/grpc/templates/server.template'
+ loc = []
+ val = {}
+ val['uri_match'] = "/test"
+ val['directive'] = "try_files $uri @default1"
+ val['path'] = "/test"
+ loc.append(val)
+ locations = pickle.dumps(loc)
+ files = pickle.dumps([])
+ self.ModifyServer(nginx_pb2.ConfigServer(
+ server_port='9180', server_name='clover-server',
+ site_root='/var/www/html',
+ upload_path_config='/upload',
+ upload_path_test='/upload_test',
+ locations=locations,
+ files=files,
+ site_index='index.html'), "")
+ if service_type == "lb":
+ self.template_file = '/grpc/templates/lb.template'
+ slb_list = pickle.dumps(
+ ['clover-server1:9180', 'clover-server2:9180',
+ 'clover-server3:9180'])
+ self.ModifyLB(nginx_pb2.ConfigLB(
+ server_port='9180', server_name='http-lb',
+ slb_list=slb_list,
+ slb_group='cloverlb', lb_path='/'), "")
+
+ def ModifyProxy(self, r, context):
+ try:
+ with open(self.template_file) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ server_port=r.server_port,
+ server_name=r.server_name,
+ location_path=r.location_path,
+ proxy_path=r.proxy_path,
+ mirror_path=r.mirror_path
+ )
+ with open(self.out_file, "wb") as fh:
+ fh.write(output)
+ msg = "Modified nginx config"
+ self.RestartNginx()
+ except Exception as e:
+ logging.debug(e)
+ msg = "Failed to modify nginx config"
+ return nginx_pb2.NginxReply(message=msg)
+
+ def ModifyServer(self, r, context):
+ try:
+ locations = pickle.loads(r.locations)
+ # Generate nginx config
+ with open(self.template_file) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ server_port=r.server_port,
+ server_name=r.server_name,
+ site_root=r.site_root,
+ site_index=r.site_index,
+ upload_path_config=r.upload_path_config,
+ upload_path_test=r.upload_path_test,
+ locations=locations
+ )
+ with open(self.out_file, "wb") as fh:
+ fh.write(output)
+
+ # Make dirs for locations
+ for l in locations:
+ self.MakeDirs(l['path'])
+
+ # Generate upload form for config
+ template_upload = '/grpc/templates/upload_form.template'
+ out_file = r.site_root + '/' + r.site_index
+ with open(template_upload) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ upload_path=r.upload_path_config
+ )
+ with open(out_file, "wb") as fh:
+ fh.write(output)
+
+ # Generate upload form for test
+ template_upload = '/grpc/templates/upload_form.template'
+ out_file = r.site_root + '/' + 'upload_test.html'
+ with open(template_upload) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ upload_path=r.upload_path_test
+ )
+ with open(out_file, "wb") as fh:
+ fh.write(output)
+
+ msg = "Modified nginx config"
+ self.RestartNginx('custom')
+
+ # Move files that have been uploaded
+ file_ops = pickle.loads(r.files)
+ self.MoveServerFiles(file_ops)
+ except Exception as e:
+ logging.debug(e)
+ msg = "Failed to modify nginx config"
+ return nginx_pb2.NginxReply(message=msg)
+
+ def ModifyLB(self, r, context):
+ try:
+ with open(self.template_file) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ server_port=r.server_port,
+ server_name=r.server_name,
+ slb_list=pickle.loads(r.slb_list),
+ slb_group=r.slb_group,
+ lb_path=r.lb_path
+ )
+ with open(self.out_file, "wb") as fh:
+ fh.write(output)
+ msg = "Modified nginx config"
+ self.RestartNginx()
+ except Exception as e:
+ logging.debug(e)
+ msg = "Failed to modify nginx config"
+ return nginx_pb2.NginxReply(message=msg)
+
+ def DeleteServerFiles(self, upload_folder):
+ for f in os.listdir(upload_folder):
+ file_path = os.path.join(upload_folder, f)
+ try:
+ if os.path.isfile(file_path):
+ os.unlink(file_path)
+ except Exception as e:
+ logging.debug(e)
+
+ def MoveServerFiles(self, file_ops):
+ response = 1
+ try:
+ for fo in file_ops:
+ try:
+ shutil.move(fo['src_file'], fo['dest_file'])
+ except Exception as e:
+ logging.debug(e)
+ response = 0
+ except Exception as e:
+ logging.debug(e)
+ return response
+
+ def RestartNginx(self, package='default'):
+ if package == 'custom':
+ if self.nginx == 0:
+ p = subprocess.Popen(["nginx"],
+ stdout=subprocess.PIPE,
+ shell=True,
+ preexec_fn=os.setsid)
+ else:
+ for proc in psutil.process_iter():
+ if proc.name() == "nginx":
+ proc.kill()
+ p = subprocess.Popen(["nginx"],
+ stdout=subprocess.PIPE,
+ shell=True,
+ preexec_fn=os.setsid)
+ self.nginx = p
+ else:
+ subprocess.Popen(
+ ["service nginx restart"], shell=True)
+
+ def MakeDirs(self, path, prefix='/var/www/html/'):
+ try:
+ path = prefix + path.strip('/')
+ os.makedirs(path)
+ except Exception as e:
+ logging.debug(e)
+
+ def ProcessAlerts(self, request, context):
+ try:
+ msg = "Processed alert"
+ except Exception as e:
+ logging.debug(e)
+ msg = "Failed to process alert"
+ return nginx_pb2.NginxReply(message=msg)
+
+
+def serve(service_type):
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ nginx_pb2_grpc.add_ControllerServicer_to_server(
+ Controller(service_type), server)
+ server.add_insecure_port(GRPC_PORT)
+ server.start()
+ try:
+ while True:
+ time.sleep(_ONE_DAY_IN_SECONDS)
+ except KeyboardInterrupt:
+ server.stop(0)
+
+
+if __name__ == '__main__':
+ serve(sys.argv[1])