summaryrefslogtreecommitdiffstats
path: root/gitautodeploy/httpserver.py
diff options
context:
space:
mode:
authorOliver Poignant <oliver@poignant.se>2016-12-09 19:56:11 +0100
committerOliver Poignant <oliver@poignant.se>2016-12-09 19:56:11 +0100
commit1c33c18730af7eb7fdc7bc88eb3c1730c34077c9 (patch)
treed01edb9a28320e53cdc0de1d77821c19ae2b853a /gitautodeploy/httpserver.py
parenteda3e82575e90f9102df2b7a6871e6b48dad889a (diff)
downloadGit-Auto-Deploy-1c33c18730af7eb7fdc7bc88eb3c1730c34077c9.zip
Git-Auto-Deploy-1c33c18730af7eb7fdc7bc88eb3c1730c34077c9.tar.gz
Git-Auto-Deploy-1c33c18730af7eb7fdc7bc88eb3c1730c34077c9.tar.bz2
Support for header filters
Diffstat (limited to 'gitautodeploy/httpserver.py')
-rw-r--r--gitautodeploy/httpserver.py121
1 files changed, 79 insertions, 42 deletions
diff --git a/gitautodeploy/httpserver.py b/gitautodeploy/httpserver.py
index 5313823..654fd83 100644
--- a/gitautodeploy/httpserver.py
+++ b/gitautodeploy/httpserver.py
@@ -66,7 +66,7 @@ class WebhookRequestHandler(BaseHTTPRequestHandler):
return
# Make git pulls and trigger deploy commands
- res = self.process_repositories(repo_configs, ref, action, request_body)
+ res = self.process_repositories(repo_configs, ref, action, request_body, request_headers)
if 'detailed-response' in self._config and self._config['detailed-response']:
self.send_response(200, 'OK')
@@ -161,7 +161,78 @@ class WebhookRequestHandler(BaseHTTPRequestHandler):
logger.error("Unable to recognize request origin. Don't know how to handle the request.")
return
- def process_repositories(self, repo_configs, ref, action, request_body):
+ def passes_payload_filter(self, payload_filters, data, action):
+ import logging
+
+ logger = logging.getLogger()
+
+ # At least one filter must match
+ for filter in payload_filters:
+
+ # All options specified in the filter must match
+ for filter_key, filter_value in filter.iteritems():
+
+ # Ignore filters with value None (let them pass)
+ if filter_value == None:
+ continue
+
+ # Support for earlier version so it's non-breaking functionality
+ if filter_key == 'action' and filter_value == action:
+ continue
+
+ # Interpret dots in filter name as path notations
+ node_value = data
+ for node_key in filter_key.split('.'):
+
+ # If the path is not valid the filter does not match
+ if not node_key in node_value:
+ logger.info("Filter '%s' does not match since the path is invalid" % (filter_key))
+
+ # Filter does not match, do not process this repo config
+ return False
+
+ node_value = node_value[node_key]
+
+ if filter_value == node_value:
+ continue
+
+ # If the filter value is set to True. the filter
+ # will pass regardless of the actual value
+ if filter_value == True:
+ continue
+
+ logger.info("Filter '%s'' does not match ('%s' != '%s')" % (filter_key, filter_value, (str(node_value)[:75] + '..') if len(str(node_value)) > 75 else str(node_value)))
+
+ # Filter does not match, do not process this repo config
+ return False
+
+ # Filter does match, proceed
+ return True
+
+ def passes_header_filter(self, header_filter, request_headers):
+ import logging
+
+ logger = logging.getLogger()
+
+ # At least one filter must match
+ for key in header_filter:
+
+ # Verify that the request has the required header attribute
+ if key.lower() not in request_headers:
+ return False
+
+ # "True" indicates that any header value is accepted
+ if header_filter[key] is True:
+ continue
+
+ # Verify that the request has the required header value
+ if header_filter[key] != request_headers[key.lower()]:
+ return False
+
+ # Filter does match, proceed
+ return True
+
+ def process_repositories(self, repo_configs, ref, action, request_body, request_headers):
"""Verify that the suggested repositories has matching settings and
issue git pull and/or deploy commands."""
import os
@@ -181,48 +252,14 @@ class WebhookRequestHandler(BaseHTTPRequestHandler):
repo_result = {}
- try:
- # Verify that all filters matches the request (if any filters are specified)
- if 'filters' in repo_config:
-
- # At least one filter must match
- for filter in repo_config['filters']:
-
- # All options specified in the filter must match
- for filter_key, filter_value in filter.iteritems():
+ # Verify that all payload filters matches the request (if any payload filters are specified)
+ if 'payload-filter' in repo_config and not self.passes_payload_filter(repo_config['payload-filter'], data, action):
- # Ignore filters with value None (let them pass)
- if filter_value == None:
- continue
-
- # Support for earlier version so it's non-breaking functionality
- if filter_key == 'action' and filter_value == action:
- continue
-
- # Interpret dots in filter name as path notations
- node_value = data
- for node_key in filter_key.split('.'):
-
- # If the path is not valid the filter does not match
- if not node_key in node_value:
- logger.info("Filter '%s' does not match since the path is invalid" % (filter_key))
- raise FilterMatchError()
-
- node_value = node_value[node_key]
-
- if filter_value == node_value:
- continue
-
- # If the filter value is set to True. the filter
- # will pass regardless of the actual value
- if filter_value == True:
- continue
-
- logger.info("Filter '%s'' does not match ('%s' != '%s')" % (filter_key, filter_value, (str(node_value)[:75] + '..') if len(str(node_value)) > 75 else str(node_value)))
-
- raise FilterMatchError()
+ # Filter does not match, do not process this repo config
+ continue
- except FilterMatchError as e:
+ # Verify that all header filters matches the request (if any header filters are specified)
+ if 'header-filter' in repo_config and not self.passes_header_filter(repo_config['header-filter'], request_headers):
# Filter does not match, do not process this repo config
continue