parent
8afb4691a5
commit
f99e74f0a1
3 changed files with 165 additions and 9 deletions
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from jsonschema import validate
|
from jsonschema import validate, ValidationError
|
||||||
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
||||||
TriggerStartException, ValidationRequestException,
|
TriggerStartException, ValidationRequestException,
|
||||||
InvalidPayloadException,
|
InvalidPayloadException,
|
||||||
|
@ -10,11 +10,60 @@ from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivation
|
||||||
|
|
||||||
from buildtrigger.basehandler import BuildTriggerHandler
|
from buildtrigger.basehandler import BuildTriggerHandler
|
||||||
|
|
||||||
|
from buildtrigger.bitbuckethandler import (BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA as bb_schema,
|
||||||
|
get_transformed_webhook_payload as bb_payload)
|
||||||
|
|
||||||
|
from buildtrigger.githubhandler import (GITHUB_WEBHOOK_PAYLOAD_SCHEMA as gh_schema,
|
||||||
|
get_transformed_webhook_payload as gh_payload)
|
||||||
|
|
||||||
|
from buildtrigger.bitbuckethandler import (BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA as bb_schema,
|
||||||
|
get_transformed_webhook_payload as bb_payload)
|
||||||
|
|
||||||
|
from buildtrigger.gitlabhandler import (GITLAB_WEBHOOK_PAYLOAD_SCHEMA as gl_schema,
|
||||||
|
get_transformed_webhook_payload as gl_payload)
|
||||||
|
|
||||||
from util.security.ssh import generate_ssh_keypair
|
from util.security.ssh import generate_ssh_keypair
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Defines an ordered set of tuples of the schemas and associated transformation functions
|
||||||
|
# for incoming webhook payloads.
|
||||||
|
SCHEMA_AND_HANDLERS = [
|
||||||
|
(gh_schema, gh_payload),
|
||||||
|
(bb_schema, bb_payload),
|
||||||
|
(gl_schema, gl_payload),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def custom_trigger_payload(metadata, git_url):
|
||||||
|
# First try the customhandler schema. If it matches, nothing more to do.
|
||||||
|
custom_handler_validation_error = None
|
||||||
|
try:
|
||||||
|
validate(metadata, CustomBuildTrigger.payload_schema)
|
||||||
|
except ValidationError as vex:
|
||||||
|
custom_handler_validation_error = vex
|
||||||
|
|
||||||
|
# Otherwise, try the defined schemas, in order, until we find a match.
|
||||||
|
for schema, handler in SCHEMA_AND_HANDLERS:
|
||||||
|
try:
|
||||||
|
validate(metadata, schema)
|
||||||
|
except ValidationError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
result = handler(metadata)
|
||||||
|
result['git_url'] = git_url
|
||||||
|
return result
|
||||||
|
|
||||||
|
# If we have reached this point and no other schemas validated, then raise the error for the
|
||||||
|
# custom schema.
|
||||||
|
if custom_handler_validation_error is not None:
|
||||||
|
raise InvalidPayloadException(custom_handler_validation_error.message)
|
||||||
|
|
||||||
|
metadata['git_url'] = git_url
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
class CustomBuildTrigger(BuildTriggerHandler):
|
class CustomBuildTrigger(BuildTriggerHandler):
|
||||||
payload_schema = {
|
payload_schema = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
|
@ -101,13 +150,14 @@ class CustomBuildTrigger(BuildTriggerHandler):
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
return self.config.has_key('credentials')
|
return self.config.has_key('credentials')
|
||||||
|
|
||||||
def _metadata_from_payload(self, payload):
|
def _metadata_from_payload(self, payload, git_url):
|
||||||
|
# Parse the JSON payload.
|
||||||
try:
|
try:
|
||||||
metadata = json.loads(payload)
|
metadata = json.loads(payload)
|
||||||
validate(metadata, self.payload_schema)
|
except ValueError as vex:
|
||||||
except Exception as e:
|
raise InvalidPayloadException(vex.message)
|
||||||
raise InvalidPayloadException(e.message)
|
|
||||||
return metadata
|
return custom_trigger_payload(metadata, git_url)
|
||||||
|
|
||||||
def handle_trigger_request(self, request):
|
def handle_trigger_request(self, request):
|
||||||
payload = request.data
|
payload = request.data
|
||||||
|
@ -116,9 +166,7 @@ class CustomBuildTrigger(BuildTriggerHandler):
|
||||||
|
|
||||||
logger.debug('Payload %s', payload)
|
logger.debug('Payload %s', payload)
|
||||||
|
|
||||||
metadata = self._metadata_from_payload(payload)
|
metadata = self._metadata_from_payload(payload, self.config['build_source'])
|
||||||
metadata['git_url'] = self.config['build_source']
|
|
||||||
|
|
||||||
prepared = self.prepare_build(metadata)
|
prepared = self.prepare_build(metadata)
|
||||||
|
|
||||||
# Check if we should skip this build.
|
# Check if we should skip this build.
|
||||||
|
|
|
@ -2,6 +2,7 @@ import unittest
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from jsonschema import validate, ValidationError
|
from jsonschema import validate, ValidationError
|
||||||
|
from buildtrigger.customhandler import custom_trigger_payload
|
||||||
from buildtrigger.basehandler import METADATA_SCHEMA
|
from buildtrigger.basehandler import METADATA_SCHEMA
|
||||||
from buildtrigger.bitbuckethandler import get_transformed_webhook_payload as bb_webhook
|
from buildtrigger.bitbuckethandler import get_transformed_webhook_payload as bb_webhook
|
||||||
from buildtrigger.bitbuckethandler import get_transformed_commit_info as bb_commit
|
from buildtrigger.bitbuckethandler import get_transformed_commit_info as bb_commit
|
||||||
|
@ -21,6 +22,93 @@ class TestPrepareTrigger(unittest.TestCase):
|
||||||
validate(created, METADATA_SCHEMA)
|
validate(created, METADATA_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
def test_custom_custom(self):
|
||||||
|
expected = {
|
||||||
|
u'commit':u'1c002dd',
|
||||||
|
u'commit_info': {
|
||||||
|
u'url': u'gitsoftware.com/repository/commits/1234567',
|
||||||
|
u'date': u'timestamp',
|
||||||
|
u'message': u'initial commit',
|
||||||
|
u'committer': {
|
||||||
|
u'username': u'user',
|
||||||
|
u'url': u'gitsoftware.com/users/user',
|
||||||
|
u'avatar_url': u'gravatar.com/user.png'
|
||||||
|
},
|
||||||
|
u'author': {
|
||||||
|
u'username': u'user',
|
||||||
|
u'url': u'gitsoftware.com/users/user',
|
||||||
|
u'avatar_url': u'gravatar.com/user.png'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
u'ref': u'refs/heads/master',
|
||||||
|
u'default_branch': u'master',
|
||||||
|
u'git_url': u'foobar',
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertSchema('custom_webhook', expected, custom_trigger_payload, git_url='foobar')
|
||||||
|
|
||||||
|
|
||||||
|
def test_custom_gitlab(self):
|
||||||
|
expected = {
|
||||||
|
'commit': u'fb88379ee45de28a0a4590fddcbd8eff8b36026e',
|
||||||
|
'ref': u'refs/heads/master',
|
||||||
|
'git_url': u'git@gitlab.com:jzelinskie/www-gitlab-com.git',
|
||||||
|
'commit_info': {
|
||||||
|
'url': u'https://gitlab.com/jzelinskie/www-gitlab-com/commit/fb88379ee45de28a0a4590fddcbd8eff8b36026e',
|
||||||
|
'date': u'2015-08-13T19:33:18+00:00',
|
||||||
|
'message': u'Fix link\n',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertSchema('gitlab_webhook', expected, custom_trigger_payload, git_url='git@gitlab.com:jzelinskie/www-gitlab-com.git')
|
||||||
|
|
||||||
|
|
||||||
|
def test_custom_github(self):
|
||||||
|
expected = {
|
||||||
|
'commit': u'410f4cdf8ff09b87f245b13845e8497f90b90a4c',
|
||||||
|
'ref': u'refs/heads/master',
|
||||||
|
'git_url': u'git@github.com:josephschorr/anothertest.git',
|
||||||
|
'commit_info': {
|
||||||
|
'url': u'https://github.com/josephschorr/anothertest/commit/410f4cdf8ff09b87f245b13845e8497f90b90a4c',
|
||||||
|
'date': u'2015-09-11T14:26:16-04:00',
|
||||||
|
'message': u'Update Dockerfile',
|
||||||
|
'committer': {
|
||||||
|
'username': u'josephschorr',
|
||||||
|
},
|
||||||
|
'author': {
|
||||||
|
'username': u'josephschorr',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertSchema('github_webhook', expected, custom_trigger_payload, git_url='git@github.com:josephschorr/anothertest.git')
|
||||||
|
|
||||||
|
|
||||||
|
def test_custom_bitbucket(self):
|
||||||
|
expected = {
|
||||||
|
"commit": u"af64ae7188685f8424040b4735ad12941b980d75",
|
||||||
|
"ref": u"refs/heads/master",
|
||||||
|
"git_url": u"git@bitbucket.org:jscoreos/another-repo.git",
|
||||||
|
"commit_info": {
|
||||||
|
"url": u"https://bitbucket.org/jscoreos/another-repo/commits/af64ae7188685f8424040b4735ad12941b980d75",
|
||||||
|
"date": u"2015-09-10T20:40:54+00:00",
|
||||||
|
"message": u"Dockerfile edited online with Bitbucket",
|
||||||
|
"author": {
|
||||||
|
"username": u"jscoreos",
|
||||||
|
"url": u"https://bitbucket.org/jscoreos/",
|
||||||
|
"avatar_url": u"https://bitbucket.org/account/jscoreos/avatar/32/",
|
||||||
|
},
|
||||||
|
"committer": {
|
||||||
|
"username": u"jscoreos",
|
||||||
|
"url": u"https://bitbucket.org/jscoreos/",
|
||||||
|
"avatar_url": u"https://bitbucket.org/account/jscoreos/avatar/32/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertSchema('bitbucket_webhook', expected, custom_trigger_payload, git_url='git@bitbucket.org:jscoreos/another-repo.git')
|
||||||
|
|
||||||
|
|
||||||
def test_bitbucket_customer_payload_noauthor(self):
|
def test_bitbucket_customer_payload_noauthor(self):
|
||||||
expected = {
|
expected = {
|
||||||
"commit": "a0ec139843b2bb281ab21a433266ddc498e605dc",
|
"commit": "a0ec139843b2bb281ab21a433266ddc498e605dc",
|
||||||
|
|
20
test/triggerjson/custom_webhook.json
Normal file
20
test/triggerjson/custom_webhook.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"commit": "1c002dd",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"default_branch": "master",
|
||||||
|
"commit_info": {
|
||||||
|
"url": "gitsoftware.com/repository/commits/1234567",
|
||||||
|
"message": "initial commit",
|
||||||
|
"date": "timestamp",
|
||||||
|
"author": {
|
||||||
|
"username": "user",
|
||||||
|
"avatar_url": "gravatar.com/user.png",
|
||||||
|
"url": "gitsoftware.com/users/user"
|
||||||
|
},
|
||||||
|
"committer": {
|
||||||
|
"username": "user",
|
||||||
|
"avatar_url": "gravatar.com/user.png",
|
||||||
|
"url": "gitsoftware.com/users/user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue