summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Poignant <oliver@poignant.se>2017-01-08 17:15:58 +0100
committerOliver Poignant <oliver@poignant.se>2017-01-08 17:15:58 +0100
commit465cb9263fb1ffc9ba2d4a912847322920180caa (patch)
tree59932075b5f6426088704abac7c53f8c476da2a4
parent324c3518d4b98da5bb660c62fa1503c47139c088 (diff)
downloadGit-Auto-Deploy-origin/master.zip
Git-Auto-Deploy-origin/master.tar.gz
Git-Auto-Deploy-origin/master.tar.bz2
-rw-r--r--gitautodeploy/__init__.py5
-rw-r--r--gitautodeploy/cli/__init__.py1
-rw-r--r--gitautodeploy/cli/config.py8
-rw-r--r--gitautodeploy/events.py9
-rw-r--r--gitautodeploy/gitautodeploy.py15
-rw-r--r--gitautodeploy/httpserver.py43
-rw-r--r--gitautodeploy/models/__init__.py1
-rw-r--r--gitautodeploy/models/project.py (renamed from gitautodeploy/webhook.py)272
-rw-r--r--gitautodeploy/parsers/__init__.py49
-rw-r--r--gitautodeploy/parsers/base.py (renamed from gitautodeploy/parsers/common.py)5
-rw-r--r--gitautodeploy/parsers/bitbucket.py7
-rw-r--r--gitautodeploy/parsers/coding.py8
-rw-r--r--gitautodeploy/parsers/generic.py7
-rw-r--r--gitautodeploy/parsers/github.py7
-rw-r--r--gitautodeploy/parsers/gitlab.py7
-rw-r--r--gitautodeploy/parsers/gitlabci.py7
-rw-r--r--test/test_parsers.py6
-rw-r--r--test/utils.py9
-rw-r--r--webui/src/Components/WebSocketStatus.scss2
-rw-r--r--webui/src/Event.js3
20 files changed, 258 insertions, 213 deletions
diff --git a/gitautodeploy/__init__.py b/gitautodeploy/__init__.py
index 8f762c3..81e2119 100644
--- a/gitautodeploy/__init__.py
+++ b/gitautodeploy/__init__.py
@@ -1,2 +1,5 @@
+from __future__ import absolute_import
+
from .gitautodeploy import *
-from .cli import * \ No newline at end of file
+from .cli import *
+from .parsers import *
diff --git a/gitautodeploy/cli/__init__.py b/gitautodeploy/cli/__init__.py
index 27c9ec6..ae8757c 100644
--- a/gitautodeploy/cli/__init__.py
+++ b/gitautodeploy/cli/__init__.py
@@ -1 +1,2 @@
from .config import *
+from .models import *
diff --git a/gitautodeploy/cli/config.py b/gitautodeploy/cli/config.py
index 3af4e3d..5c5cd06 100644
--- a/gitautodeploy/cli/config.py
+++ b/gitautodeploy/cli/config.py
@@ -342,6 +342,7 @@ def init_config(config):
import os
import re
import logging
+ from .models import Project
logger = logging.getLogger()
# Translate any ~ in the path into /home/<user>
@@ -360,6 +361,8 @@ def init_config(config):
if 'repositories' not in config:
config['repositories'] = []
+ deserialized = []
+
for repo_config in config['repositories']:
# Setup branch if missing
@@ -425,6 +428,11 @@ def init_config(config):
filter['pull_request'] = True
+ project = Project(repo_config)
+ deserialized.append(project)
+
+ config['repositories'] = deserialized
+
return config
diff --git a/gitautodeploy/events.py b/gitautodeploy/events.py
index 5a4cef5..ab3cdec 100644
--- a/gitautodeploy/events.py
+++ b/gitautodeploy/events.py
@@ -97,8 +97,8 @@ class WebhookAction(SystemEvent):
class DeployEvent(SystemEvent):
- def __init__(self, repo_config):
- self.repo_config = repo_config
+ def __init__(self, project):
+ self.project = project
super(DeployEvent, self).__init__()
def __repr__(self):
@@ -106,12 +106,9 @@ class DeployEvent(SystemEvent):
def dict_repr(self):
data = super(DeployEvent, self).dict_repr()
- data['name'] = self.get_name()
+ data['name'] = self.project.get_name()
return data
- def get_name(self):
- return self.repo_config['url'].split('/')[-1].split('.git')[0]
-
class StartupEvent(SystemEvent):
diff --git a/gitautodeploy/gitautodeploy.py b/gitautodeploy/gitautodeploy.py
index 31e1696..eaca8b0 100644
--- a/gitautodeploy/gitautodeploy.py
+++ b/gitautodeploy/gitautodeploy.py
@@ -30,6 +30,7 @@ class GitAutoDeploy(object):
_default_stderr = None
_startup_event = None
_ws_clients = []
+ _http_port = None
def __new__(cls, *args, **kwargs):
"""Overload constructor to enable singleton access"""
@@ -260,7 +261,7 @@ class GitAutoDeploy(object):
#if 'daemon-mode' not in self._config or not self._config['daemon-mode']:
# self._startup_event.log_info('Git Auto Deploy started')
- def serve_http(self):
+ def serve_http(self, serve_forever=True):
"""Starts a HTTP server that listens for webhook requests and serves the web ui."""
import sys
import socket
@@ -288,8 +289,8 @@ class GitAutoDeploy(object):
# Setup SSL for HTTP server
sa = self._http_server.socket.getsockname()
- self._server_status['http-uri'] = "http://%s:%s" % (self._config['http-host'], self._config['http-port'])
-
+ self._http_port = sa[1]
+ self._server_status['http-uri'] = "http://%s:%s" % (self._config['http-host'], sa[1])
self._startup_event.log_info("Listening for connections on %s" % self._server_status['http-uri'])
self._startup_event.http_address = sa[0]
self._startup_event.http_port = sa[1]
@@ -299,17 +300,22 @@ class GitAutoDeploy(object):
self._startup_event.log_critical("Unable to start HTTP server: %s" % e)
return
+ if not serve_forever:
+ return
+
# Run forever
try:
self._http_server.serve_forever()
except socket.error as e:
+ print e
event = SystemEvent()
self._event_store.register_action(event)
event.log_critical("Error on socket: %s" % e)
sys.exit(1)
except KeyboardInterrupt as e:
+ print e
event = SystemEvent()
self._event_store.register_action(event)
event.log_info('Requested close by keyboard interrupt signal')
@@ -359,7 +365,8 @@ class GitAutoDeploy(object):
server_side=True)
sa = self._https_server.socket.getsockname()
- self._server_status['https-uri'] = "https://%s:%s" % (self._config['https-host'], self._config['https-port'])
+ self._http_port = sa[1]
+ self._server_status['https-uri'] = "https://%s:%s" % (self._config['https-host'], sa[1])
self._startup_event.log_info("Listening for connections on %s" % self._server_status['https-uri'])
self._startup_event.http_address = sa[0]
diff --git a/gitautodeploy/httpserver.py b/gitautodeploy/httpserver.py
index 857f5f3..4377078 100644
--- a/gitautodeploy/httpserver.py
+++ b/gitautodeploy/httpserver.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
-from .webhook import WebhookRequestFilter, WebbhookRequestProcessor
from .events import WebhookAction
+from .parsers import get_service_handler
+
def WebhookRequestHandlerFactory(config, event_store, server_status, is_https=False):
"""Factory method for webhook request handler class"""
@@ -119,10 +120,8 @@ def WebhookRequestHandlerFactory(config, event_store, server_status, is_https=Fa
try:
- request_processor = WebbhookRequestProcessor()
-
# Will raise a ValueError exception if it fails
- ServiceRequestHandler = request_processor.get_service_handler(request_headers, request_body, action)
+ ServiceRequestHandler = get_service_handler(request_headers, request_body, action)
# Unable to identify the source of the request
if not ServiceRequestHandler:
@@ -138,26 +137,32 @@ def WebhookRequestHandlerFactory(config, event_store, server_status, is_https=Fa
action.log_info("Handling the request with %s" % ServiceRequestHandler.__name__)
# Could be GitHubParser, GitLabParser or other
- repo_configs = service_handler.get_repo_configs(request_headers, request_body, action)
+ projects = service_handler.get_matching_projects(request_headers, request_body, action)
- action.log_info("%s candidates found" % len(repo_configs))
+ action.log_info("%s candidates matches the request" % len(projects))
- request_filter = WebhookRequestFilter()
+ # request_filter = WebhookRequestFilter()
- if len(repo_configs) == 0:
+ if len(projects) == 0:
self.send_error(400, 'Bad request')
test_case['expected']['status'] = 400
- action.log_error("No matching repository config")
+ action.log_error("No matching projects")
action.set_waiting(False)
action.set_success(False)
return
# Apply filters
- repo_configs = request_filter.apply_filters(repo_configs, request_headers, request_body, action)
+ matching_projects = []
+ for project in projects:
+ if project.apply_filters(request_headers, request_body, action):
+ matching_projects.append(project)
+
+ # Only keep projects that matches
+ projects = matching_projects
- action.log_info("%s candidates matches the filters" % len(repo_configs))
+ action.log_info("%s candidates matches after applying filters" % len(projects))
- if not service_handler.validate_request(request_headers, repo_configs, action):
+ if not service_handler.validate_request(request_headers, projects, action):
self.send_error(400, 'Bad request')
test_case['expected']['status'] = 400
action.log_warning("Request is not valid")
@@ -171,26 +176,26 @@ def WebhookRequestHandlerFactory(config, event_store, server_status, is_https=Fa
self.send_header('Content-type', 'text/plain')
self.end_headers()
- if len(repo_configs) == 0:
+ if len(projects) == 0:
action.set_waiting(False)
action.set_success(False)
return
- action.log_info("Proceeding with %s candidates" % len(repo_configs))
+ action.log_info("Proceeding with %s candidates" % len(projects))
action.set_waiting(False)
action.set_success(True)
- for repo_config in repo_configs:
+ for project in projects:
# Schedule the execution of the webhook (git pull and trigger deploy etc)
- thread = threading.Thread(target=request_processor.execute_webhook, args=[repo_config, self._event_store])
+ thread = threading.Thread(target=project.execute_webhook, args=[self._event_store])
thread.start()
# Add additional test case data
test_case['config'] = {
- 'url': 'url' in repo_config and repo_config['url'],
- 'branch': 'branch' in repo_config and repo_config['branch'],
- 'remote': 'remote' in repo_config and repo_config['remote'],
+ 'url': 'url' in project and project['url'],
+ 'branch': 'branch' in project and project['branch'],
+ 'remote': 'remote' in project and project['remote'],
'deploy': 'echo test!'
}
diff --git a/gitautodeploy/models/__init__.py b/gitautodeploy/models/__init__.py
new file mode 100644
index 0000000..e2ebdf8
--- /dev/null
+++ b/gitautodeploy/models/__init__.py
@@ -0,0 +1 @@
+from .project import * \ No newline at end of file
diff --git a/gitautodeploy/webhook.py b/gitautodeploy/models/project.py
index 752717e..954da99 100644
--- a/gitautodeploy/webhook.py
+++ b/gitautodeploy/models/project.py
@@ -1,75 +1,140 @@
-from .parsers import CodingRequestParser, GitLabCIRequestParser
-from .parsers import GitLabRequestParser, GitHubRequestParser
-from .parsers import BitBucketRequestParser, GenericRequestParser
+import collections
+from ..wrappers import GitWrapper
+from ..lock import Lock
+from ..wrappers import GitWrapper
+from ..events import DeployEvent
-class WebbhookRequestProcessor(object):
+class Project(collections.MutableMapping):
- def get_service_handler(self, request_headers, request_body, action):
- """Parses the incoming request and attempts to determine whether
- it originates from GitHub, GitLab or any other known service."""
- import json
+ """A dictionary that applies an arbitrary key-altering
+ function before accessing the keys"""
- payload = json.loads(request_body)
+ def __init__(self, *args, **kwargs):
+ self.store = dict()
+ self.update(dict(*args, **kwargs)) # use the free update to set keys
+
+ def __getitem__(self, key):
+ return self.store[self.__keytransform__(key)]
+
+ def __setitem__(self, key, value):
+ self.store[self.__keytransform__(key)] = value
+
+ def __delitem__(self, key):
+ del self.store[self.__keytransform__(key)]
+
+ def __iter__(self):
+ return iter(self.store)
+
+ def __len__(self):
+ return len(self.store)
+
+ def __keytransform__(self, key):
+ return key
+
+ def get_name(self):
+ return self['url'].split('/')[-1].split('.git')[0]
+
+ def passes_payload_filter(self, payload, action):
+
+ # At least one filter must match
+ for filter in self['payload-filter']:
+
+ # All options specified in the filter must match
+ for filter_key, filter_value in filter.items():
+
+ # Ignore filters with value None (let them pass)
+ if filter_value == None:
+ continue
+
+ # Interpret dots in filter name as path notations
+ node_value = payload
+ 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:
+ action.log_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
+
+ action.log_debug("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
- if not isinstance(payload, dict):
- raise ValueError("Invalid JSON object")
+ # Filter does match, proceed
+ return True
- user_agent = 'user-agent' in request_headers and request_headers['user-agent']
- content_type = 'content-type' in request_headers and request_headers['content-type']
+ def passes_header_filter(self, request_headers):
- # Assume Coding if the X-Coding-Event HTTP header is set
- if 'x-coding-event' in request_headers:
- return CodingRequestParser
+ # At least one filter must match
+ for key in self['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 self['header-filter'][key] is True:
+ continue
- # Assume GitLab if the X-Gitlab-Event HTTP header is set
- elif 'x-gitlab-event' in request_headers:
+ # Verify that the request has the required header value
+ if self['header-filter'][key] != request_headers[key.lower()]:
+ return False
- # Special Case for Gitlab CI
- if content_type == "application/json" and "build_status" in payload:
- return GitLabCIRequestParser
- else:
- return GitLabRequestParser
+ # Filter does match, proceed
+ return True
- # Assume GitHub if the X-GitHub-Event HTTP header is set
- elif 'x-github-event' in request_headers:
+ def apply_filters(self, request_headers, request_body, action):
+ """Verify that the suggested repositories has matching settings and
+ issue git pull and/or deploy commands."""
+ import os
+ import time
+ import json
- return GitHubRequestParser
+ payload = json.loads(request_body)
- # Assume BitBucket if the User-Agent HTTP header is set to
- # 'Bitbucket-Webhooks/2.0' (or something similar)
- elif user_agent and user_agent.lower().find('bitbucket') != -1:
+ # Verify that all payload filters matches the request (if any payload filters are specified)
+ if 'payload-filter' in self and not self.passes_payload_filter(payload, action):
- return BitBucketRequestParser
+ # Filter does not match, do not process this repo config
+ return False
- # This handles old GitLab requests and Gogs requests for example.
- elif content_type == "application/json":
+ # Verify that all header filters matches the request (if any header filters are specified)
+ if 'header-filter' in self and not self.passes_header_filter(request_headers):
- action.log_info("Received event from unknown origin.")
- return GenericRequestParser
+ # Filter does not match, do not process this repo config
+ return False
- action.log_error("Unable to recognize request origin. Don't know how to handle the request.")
- return
+ return True
- def execute_webhook(self, repo_config, event_store):
+ def execute_webhook(self, event_store):
"""Verify that the suggested repositories has matching settings and
issue git pull and/or deploy commands."""
import os
import time
- from .wrappers import GitWrapper
- from .events import DeployEvent
- from .lock import Lock
import json
- event = DeployEvent(repo_config)
+ event = DeployEvent(self)
event_store.register_action(event)
event.set_waiting(True)
event.log_info("Running deploy commands")
# In case there is no path configured for the repository, no pull will
# be made.
- if 'path' not in repo_config:
- res = GitWrapper.deploy(repo_config)
+ if 'path' not in self:
+ res = GitWrapper.deploy(self)
event.log_info("%s" % res)
event.set_waiting(False)
event.set_success(True)
@@ -77,22 +142,22 @@ class WebbhookRequestProcessor(object):
# If the path does not exist, a warning will be raised and no pull or
# deploy will be made.
- if not os.path.isdir(repo_config['path']):
- event.log_error("The repository '%s' does not exist locally. Make sure it was pulled properly without errors by reviewing the log." % repo_config['path'])
+ if not os.path.isdir(self['path']):
+ event.log_error("The repository '%s' does not exist locally. Make sure it was pulled properly without errors by reviewing the log." % self['path'])
event.set_waiting(False)
event.set_success(False)
return
# If the path is not writable, a warning will be raised and no pull or
# deploy will be made.
- if not os.access(repo_config['path'], os.W_OK):
- event.log_error("The path '%s' is not writable. Make sure that GAD has write access to that path." % repo_config['path'])
+ if not os.access(self['path'], os.W_OK):
+ event.log_error("The path '%s' is not writable. Make sure that GAD has write access to that path." % self['path'])
event.set_waiting(False)
event.set_success(False)
return
- running_lock = Lock(os.path.join(repo_config['path'], 'status_running'))
- waiting_lock = Lock(os.path.join(repo_config['path'], 'status_waiting'))
+ running_lock = Lock(os.path.join(self['path'], 'status_running'))
+ waiting_lock = Lock(os.path.join(self['path'], 'status_waiting'))
try:
# Attempt to obtain the status_running lock
@@ -113,7 +178,7 @@ class WebbhookRequestProcessor(object):
while n > 0:
# Attempt to pull up a maximum of 4 times
- res = GitWrapper.pull(repo_config)
+ res = GitWrapper.pull(self)
# Return code indicating success?
if res == 0:
@@ -122,10 +187,10 @@ class WebbhookRequestProcessor(object):
n -= 1
if 0 < n:
- res = GitWrapper.deploy(repo_config)
+ res = GitWrapper.deploy(self)
#except Exception as e:
- # logger.error('Error during \'pull\' or \'deploy\' operation on path: %s' % repo_config['path'])
+ # logger.error('Error during \'pull\' or \'deploy\' operation on path: %s' % self['path'])
# logger.error(e)
# raise e
@@ -143,106 +208,3 @@ class WebbhookRequestProcessor(object):
event.set_waiting(False)
event.set_success(True)
-
-class WebhookRequestFilter(object):
-
- def passes_payload_filter(self, payload_filters, payload, 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.items():
-
- # Ignore filters with value None (let them pass)
- if filter_value == None:
- continue
-
- # Interpret dots in filter name as path notations
- node_value = payload
- 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:
- action.log_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
-
- action.log_debug("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 apply_filters(self, repo_configs, request_headers, request_body, action):
- """Verify that the suggested repositories has matching settings and
- issue git pull and/or deploy commands."""
- import os
- import time
- import logging
- from .wrappers import GitWrapper
- from .lock import Lock
- import json
-
- logger = logging.getLogger()
- payload = json.loads(request_body)
-
- matches = []
-
- # Process each matching repository
- for repo_config in repo_configs:
-
- # 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'], payload, action):
-
- # Filter does not match, do not process this repo config
- continue
-
- # 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
-
- matches.append(repo_config)
-
- return matches \ No newline at end of file
diff --git a/gitautodeploy/parsers/__init__.py b/gitautodeploy/parsers/__init__.py
index cecd1c7..f213339 100644
--- a/gitautodeploy/parsers/__init__.py
+++ b/gitautodeploy/parsers/__init__.py
@@ -3,4 +3,51 @@ from .github import GitHubRequestParser
from .gitlab import GitLabRequestParser
from .gitlabci import GitLabCIRequestParser
from .generic import GenericRequestParser
-from .coding import CodingRequestParser \ No newline at end of file
+from .coding import CodingRequestParser
+
+
+def get_service_handler(request_headers, request_body, action):
+ """Parses the incoming request and attempts to determine whether
+ it originates from GitHub, GitLab or any other known service."""
+ import json
+
+ payload = json.loads(request_body)
+
+ if not isinstance(payload, dict):
+ raise ValueError("Invalid JSON object")
+
+ user_agent = 'user-agent' in request_headers and request_headers['user-agent']
+ content_type = 'content-type' in request_headers and request_headers['content-type']
+
+ # Assume Coding if the X-Coding-Event HTTP header is set
+ if 'x-coding-event' in request_headers:
+ return CodingRequestParser
+
+ # Assume GitLab if the X-Gitlab-Event HTTP header is set
+ elif 'x-gitlab-event' in request_headers:
+
+ # Special Case for Gitlab CI
+ if content_type == "application/json" and "build_status" in payload:
+ return GitLabCIRequestParser
+ else:
+ return GitLabRequestParser
+
+ # Assume GitHub if the X-GitHub-Event HTTP header is set
+ elif 'x-github-event' in request_headers:
+
+ return GitHubRequestParser
+
+ # Assume BitBucket if the User-Agent HTTP header is set to
+ # 'Bitbucket-Webhooks/2.0' (or something similar)
+ elif user_agent and user_agent.lower().find('bitbucket') != -1:
+
+ return BitBucketRequestParser
+
+ # This handles old GitLab requests and Gogs requests for example.
+ elif content_type == "application/json":
+
+ action.log_info("Received event from unknown origin.")
+ return GenericRequestParser
+
+ action.log_error("Unable to recognize request origin. Don't know how to handle the request.")
+ return \ No newline at end of file
diff --git a/gitautodeploy/parsers/common.py b/gitautodeploy/parsers/base.py
index b194062..f641d4c 100644
--- a/gitautodeploy/parsers/common.py
+++ b/gitautodeploy/parsers/base.py
@@ -1,5 +1,4 @@
-
-class WebhookRequestParser(object):
+class WebhookRequestParserBase(object):
"""Abstract parent class for git service parsers. Contains helper
methods."""
@@ -27,4 +26,4 @@ class WebhookRequestParser(object):
return configs
def validate_request(self, request_headers, repo_configs, action):
- return True \ No newline at end of file
+ return True
diff --git a/gitautodeploy/parsers/bitbucket.py b/gitautodeploy/parsers/bitbucket.py
index b80f6aa..8905bfc 100644
--- a/gitautodeploy/parsers/bitbucket.py
+++ b/gitautodeploy/parsers/bitbucket.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class BitBucketRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class BitBucketRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
diff --git a/gitautodeploy/parsers/coding.py b/gitautodeploy/parsers/coding.py
index 3d114d4..588ea22 100644
--- a/gitautodeploy/parsers/coding.py
+++ b/gitautodeploy/parsers/coding.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class CodingRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class CodingRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
@@ -35,6 +36,5 @@ class CodingRequestParser(WebhookRequestParser):
return repo_configs
-
def verify_token(self, secret_token, request_token):
return secret_token == request_token
diff --git a/gitautodeploy/parsers/generic.py b/gitautodeploy/parsers/generic.py
index c71bced..f8e8f31 100644
--- a/gitautodeploy/parsers/generic.py
+++ b/gitautodeploy/parsers/generic.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class GenericRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class GenericRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
diff --git a/gitautodeploy/parsers/github.py b/gitautodeploy/parsers/github.py
index 5f2ba5d..a6659bd 100644
--- a/gitautodeploy/parsers/github.py
+++ b/gitautodeploy/parsers/github.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class GitHubRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class GitHubRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
diff --git a/gitautodeploy/parsers/gitlab.py b/gitautodeploy/parsers/gitlab.py
index 6767907..6c6ca90 100644
--- a/gitautodeploy/parsers/gitlab.py
+++ b/gitautodeploy/parsers/gitlab.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class GitLabRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class GitLabRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
diff --git a/gitautodeploy/parsers/gitlabci.py b/gitautodeploy/parsers/gitlabci.py
index eebf2bd..35d5ed4 100644
--- a/gitautodeploy/parsers/gitlabci.py
+++ b/gitautodeploy/parsers/gitlabci.py
@@ -1,8 +1,9 @@
-from .common import WebhookRequestParser
+from .base import WebhookRequestParserBase
-class GitLabCIRequestParser(WebhookRequestParser):
- def get_repo_configs(self, request_headers, request_body, action):
+class GitLabCIRequestParser(WebhookRequestParserBase):
+
+ def get_matching_projects(self, request_headers, request_body, action):
import json
data = json.loads(request_body)
diff --git a/test/test_parsers.py b/test/test_parsers.py
index 420f9ff..7a30f2e 100644
--- a/test/test_parsers.py
+++ b/test/test_parsers.py
@@ -1,6 +1,7 @@
import unittest
from utils import WebhookTestCaseBase
+
class WebhookTestCase(WebhookTestCaseBase):
test_case = None
@@ -19,7 +20,10 @@ class WebhookTestCase(WebhookTestCaseBase):
# GAD configuration for this test case
config = {
- 'port': 0,
+ 'http-port': 0,
+ 'https-enabled': False,
+ 'wss-enabled': False,
+ 'web-ui-require-https': False,
'intercept-stdout': False,
'detailed-response': True,
'log-level': 'ERROR',
diff --git a/test/utils.py b/test/utils.py
index 30eeff6..551f809 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -48,7 +48,7 @@ class WebhookTestCaseBase(unittest.TestCase):
for current_thread in threading.enumerate():
if current_thread == main_thread:
continue
- #print "Waiting for thread %s to finish" % current_thread
+ # print "Waiting for thread %s to finish" % current_thread
current_thread.join()
def tearDown(self):
@@ -103,12 +103,15 @@ class GADRunnerThread(threading.Thread):
self._app = GitAutoDeploy()
self._app.setup(config)
+ # Setup HTTP server, but do not start serving
+ self._app.serve_http(serve_forever=False)
+
# Store PID and port in thread instance
self.pid = self._app._pid
- self.port = self._app._port
+ self.port = self._app._http_port
def run(self):
- self._app.handle_request()
+ self._app._http_server.handle_request()
def exit(self):
self._app.stop()
diff --git a/webui/src/Components/WebSocketStatus.scss b/webui/src/Components/WebSocketStatus.scss
index d287c72..8cb8997 100644
--- a/webui/src/Components/WebSocketStatus.scss
+++ b/webui/src/Components/WebSocketStatus.scss
@@ -2,7 +2,7 @@
.WebSocketStatus {
- position: absolute;
+ position: fixed;
bottom: 4rem;
right: .3rem;
z-index: 1010;
diff --git a/webui/src/Event.js b/webui/src/Event.js
index e5c8394..f5a2dd2 100644
--- a/webui/src/Event.js
+++ b/webui/src/Event.js
@@ -21,6 +21,9 @@ class Event {
if(this.event.type === "WebhookAction")
return "blue";
+ if(this.event.type === "DeployEvent")
+ return "blue";
+
return "blue";
// return "purple";
}