##// END OF EJS Templates
integrations: add webhook integration
dan -
r444:3db70ed6 default
parent child Browse files
Show More
@@ -0,0 +1,106 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 from __future__ import unicode_literals
22
23 import logging
24 import requests
25 import colander
26 from celery.task import task
27 from mako.template import Template
28
29 from rhodecode import events
30 from rhodecode.translation import lazy_ugettext
31 from rhodecode.integrations.types.base import IntegrationTypeBase
32 from rhodecode.integrations.schema import IntegrationSettingsSchemaBase
33
34 log = logging.getLogger()
35
36
37 class WebhookSettingsSchema(IntegrationSettingsSchemaBase):
38 url = colander.SchemaNode(
39 colander.String(),
40 title=lazy_ugettext('Webhook URL'),
41 description=lazy_ugettext('URL of the webhook to receive POST event.'),
42 default='',
43 validator=colander.url,
44 placeholder='https://www.example.com/webhook',
45 widget='string'
46 )
47 secret_token = colander.SchemaNode(
48 colander.String(),
49 title=lazy_ugettext('Secret Token'),
50 description=lazy_ugettext('String used to validate received payloads.'),
51 default='',
52 placeholder='secret_token',
53 widget='string'
54 )
55
56
57 class WebhookIntegrationType(IntegrationTypeBase):
58 key = 'webhook'
59 display_name = lazy_ugettext('Webhook')
60 valid_events = [
61 events.PullRequestCloseEvent,
62 events.PullRequestMergeEvent,
63 events.PullRequestUpdateEvent,
64 events.PullRequestCommentEvent,
65 events.PullRequestReviewEvent,
66 events.PullRequestCreateEvent,
67 events.RepoPushEvent,
68 events.RepoCreateEvent,
69 ]
70
71 @classmethod
72 def settings_schema(cls):
73 schema = WebhookSettingsSchema()
74 schema.add(colander.SchemaNode(
75 colander.Set(),
76 widget='checkbox_list',
77 choices=sorted([e.name for e in cls.valid_events]),
78 description="Events activated for this integration",
79 name='events'
80 ))
81 return schema
82
83 def send_event(self, event):
84 log.debug('handling event %s with webhook integration %s',
85 event.name, self)
86
87 if event.__class__ not in self.valid_events:
88 log.debug('event not valid: %r' % event)
89 return
90
91 if event.name not in self.settings['events']:
92 log.debug('event ignored: %r' % event)
93 return
94
95 data = event.as_dict()
96 post_to_webhook(data, self.settings)
97
98
99 @task(ignore_result=True)
100 def post_to_webhook(data, settings):
101 log.debug('sending event:%s to webhook %s', data['name'], settings['url'])
102 resp = requests.post(settings['url'], json={
103 'token': settings['secret_token'],
104 'event': data
105 })
106 resp.raise_for_status() # raise exception on a failed request
@@ -1,52 +1,57 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2012-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import logging
22 22 from rhodecode.integrations.registry import IntegrationTypeRegistry
23 from rhodecode.integrations.types import slack
23 from rhodecode.integrations.types import webhook, slack
24 24
25 25 log = logging.getLogger(__name__)
26 26
27 27
28 28 # TODO: dan: This is currently global until we figure out what to do about
29 29 # VCS's not having a pyramid context - move it to pyramid app configuration
30 30 # includeme level later to allow per instance integration setup
31 31 integration_type_registry = IntegrationTypeRegistry()
32 integration_type_registry.register_integration_type(slack.SlackIntegrationType)
32
33 integration_type_registry.register_integration_type(
34 webhook.WebhookIntegrationType)
35 integration_type_registry.register_integration_type(
36 slack.SlackIntegrationType)
37
33 38
34 39 def integrations_event_handler(event):
35 40 """
36 41 Takes an event and passes it to all enabled integrations
37 42 """
38 43 from rhodecode.model.integration import IntegrationModel
39 44
40 45 integration_model = IntegrationModel()
41 46 integrations = integration_model.get_for_event(event)
42 47 for integration in integrations:
43 48 try:
44 49 integration_model.send_event(integration, event)
45 50 except Exception:
46 51 log.exception(
47 52 'failure occured when sending event %s to integration %s' % (
48 53 event, integration))
49 54
50 55
51 56 def includeme(config):
52 57 config.include('rhodecode.integrations.routes')
General Comments 0
You need to be logged in to leave comments. Login now