From d8008cde0ff3526153d30cc6cffdd18e718ec458 Mon Sep 17 00:00:00 2001
From: Nicolas Wavrant <nicolas.wavrant@nexedi.com>
Date: Fri, 2 Dec 2016 10:47:29 +0100
Subject: [PATCH] monitor_config_write: CORS apache conf should be rendered
 from a slapos template instead of being hardcoded

---
 slapos/monitor/monitor_config_write.py      | 19 +++++++++++--------
 slapos/test/monitor/test_config_document.py | 14 ++++++++++----
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/slapos/monitor/monitor_config_write.py b/slapos/monitor/monitor_config_write.py
index 5437df1..6ec367b 100644
--- a/slapos/monitor/monitor_config_write.py
+++ b/slapos/monitor/monitor_config_write.py
@@ -3,6 +3,7 @@
 import sys
 import os
 import re
+import jinja2
 import json
 import argparse
 import subprocess
@@ -21,15 +22,18 @@ def parseArguments():
                       help='Path apache htpasswd binary. Needed to write htpasswd file.')
   parser.add_argument('--output_cfg_file',
                       help='Ouput parameters in cfg file.')
+  parser.add_argument('--monitor_https_cors',
+                      help='Path to the CORS httpd template.')
 
   return parser.parse_args()
 
 class MonitorConfigWrite(object):
 
-  def __init__(self, config_json_file, htpasswd_bin, output_cfg_file=""):
+  def __init__(self, config_json_file, htpasswd_bin, output_cfg_file="", monitor_https_cors=""):
     self.config_json_file = config_json_file
     self.output_cfg_file = output_cfg_file
     self.htpasswd_bin = htpasswd_bin
+    self.monitor_https_cors = monitor_https_cors
 
   def _fileWrite(self, file_path, content):
     if os.path.exists(file_path):
@@ -76,14 +80,12 @@ class MonitorConfigWrite(object):
               return True
       except OSError, e:
         print "Failed to open file at %s. \n%s" % (old_httpd_cors_file, str(e))
-    for domain in cors_domain_list:
-      if cors_string:
-        cors_string += '|'
-      cors_string += re.escape(domain)
     try:
+      with open(self.monitor_https_cors, 'r') as cors_template:
+        template = jinja2.Template(cors_template.read())
+        rendered_string = template.render(domain=cors_domain)
       with open(httpd_cors_file, 'w') as file:
-        file.write('SetEnvIf Origin "^http(s)?://(.+\.)?(%s)$" origin_is=$0\n' % cors_string)
-        file.write('Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is')
+        file.write(rendered_string)
     except OSError, e:
       print "ERROR while writing CORS changes to %s.\n %s" % (httpd_cors_file, str(e))
       return False
@@ -176,7 +178,8 @@ def main():
   instance = MonitorConfigWrite(
     parameter_tmp_file,
     parser.htpasswd_bin,
-    parser.output_cfg_file)
+    parser.output_cfg_file,
+    parser.monitor_https_cors)
 
   while True:
     result_dict = instance.applyConfigChanges()
diff --git a/slapos/test/monitor/test_config_document.py b/slapos/test/monitor/test_config_document.py
index df127cf..933a43a 100644
--- a/slapos/test/monitor/test_config_document.py
+++ b/slapos/test/monitor/test_config_document.py
@@ -21,6 +21,7 @@ class MonitorConfigDocument(unittest.TestCase):
     self.httpd_passwd_script = """#!/bin/sh
 echo "htpasswd $@" > %s/monitor-htpasswd
 """ % self.base_dir
+    self.monitor_https_cors = os.path.join(self.base_dir, 'httpd-cors-template.cfg.in')
     self.parameter_dict = {
       "cors-domain": 
         {
@@ -74,6 +75,9 @@ echo "htpasswd $@" > %s/monitor-htpasswd
     self.writeContent("%s/content" % self.base_dir, self.file_content)
     self.writeContent("%s/.httpd_pwd_real" % self.base_dir, self.httpd_passwd)
     self.writeContent(self.httpd_passwd_bin, self.httpd_passwd_script)
+    self.writeContent(self.monitor_https_cors, '{% set allow_domain = "|".join(domain.replace(".", "\.").split()) -%}\n'
+                                               'SetEnvIf Origin "^http(s)?://(.+\.)?({{ allow_domain }})$" ORIGIN_DOMAIN=$0\n'
+                                               'Header always set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN')
     os.chmod(self.httpd_passwd_bin, 0755)
 
   def tearDown(self):
@@ -91,8 +95,8 @@ echo "htpasswd $@" > %s/monitor-htpasswd
         cors_string += '|'
       cors_string += re.escape(domain)
 
-    cors_string = 'SetEnvIf Origin "^http(s)?://(.+\.)?(%s)$" origin_is=$0\n' % cors_string
-    cors_string += 'Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is'
+    cors_string = 'SetEnvIf Origin "^http(s)?://(.+\.)?(%s)$" ORIGIN_DOMAIN=$0\n' % cors_string
+    cors_string += 'Header always set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN'
     return cors_string
 
   def check_config(self):
@@ -140,7 +144,8 @@ echo "htpasswd $@" > %s/monitor-htpasswd
     instance = MonitorConfigWrite(
       self.config_path,
       self.httpd_passwd_bin,
-      cfg_output)
+      cfg_output,
+      self.monitor_https_cors)
 
     result = instance.applyConfigChanges()
     self.assertTrue(os.path.exists(cfg_output))
@@ -179,7 +184,8 @@ echo "htpasswd $@" > %s/monitor-htpasswd
     instance = MonitorConfigWrite(
       self.config_path,
       self.httpd_passwd_bin,
-      cfg_output)
+      cfg_output,
+      self.monitor_https_cors)
 
     result = instance.applyConfigChanges()
     self.assertTrue(os.path.exists(cfg_output))
-- 
2.30.9