##// END OF EJS Templates
rcextensions: updated examples, and made http_call util use the method parameter....
marcink -
r3407:9bba7a40 stable
parent child Browse files
Show More
@@ -1,36 +1,37 b''
1 # Example to trigger a HTTP call via an HTTP helper via post_push hook
1 # Example to trigger a HTTP call via an HTTP helper via post_push hook
2
2
3
3
4 @has_kwargs({
4 @has_kwargs({
5 'server_url': 'url of instance that triggered this hook',
5 'server_url': 'url of instance that triggered this hook',
6 'config': 'path to .ini config used',
6 'config': 'path to .ini config used',
7 'scm': 'type of version control "git", "hg", "svn"',
7 'scm': 'type of version control "git", "hg", "svn"',
8 'username': 'username of actor who triggered this event',
8 'username': 'username of actor who triggered this event',
9 'ip': 'ip address of actor who triggered this hook',
9 'ip': 'ip address of actor who triggered this hook',
10 'action': '',
10 'action': '',
11 'repository': 'repository name',
11 'repository': 'repository name',
12 'repo_store_path': 'full path to where repositories are stored',
12 'repo_store_path': 'full path to where repositories are stored',
13 'commit_ids': '',
13 'commit_ids': '',
14 'hook_type': '',
14 'hook_type': '',
15 'user_agent': '',
15 'user_agent': '',
16 })
16 })
17 def _push_hook(*args, **kwargs):
17 def _push_hook(*args, **kwargs):
18 """
18 """
19 POST PUSH HOOK, this function will be executed after each push it's
19 POST PUSH HOOK, this function will be executed after each push it's
20 executed after the build-in hook that RhodeCode uses for logging pushes
20 executed after the build-in hook that RhodeCode uses for logging pushes
21 """
21 """
22
22
23 from .helpers import http_call, extra_fields
23 from .helpers import http_call, extra_fields
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26
26
27 if repo_extra_fields.get('endpoint_url'):
27 if repo_extra_fields.get('endpoint_url'):
28 endpoint = repo_extra_fields['endpoint_url']
28 field_metadata = repo_extra_fields['endpoint_url']
29 endpoint = field_metadata['field_value']
29 if endpoint:
30 if endpoint:
30 data = {
31 data = {
31 'some_key': 'val'
32 'project': kwargs['repository'],
32 }
33 }
33 response = http_call.run(url=endpoint, json_data=data)
34 response = http_call.run(url=endpoint, params=data)
34 return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint, response))
35 return HookResponse(0, 'Called endpoint {}, with response {}\n'.format(endpoint, response))
35
36
36 return HookResponse(0, '')
37 return HookResponse(0, '')
@@ -1,36 +1,37 b''
1 # Example to trigger a CI call via an HTTP helper via post_push hook
1 # Example to trigger a CI call via an HTTP helper via post_push hook
2
2
3
3
4 @has_kwargs({
4 @has_kwargs({
5 'server_url': 'url of instance that triggered this hook',
5 'server_url': 'url of instance that triggered this hook',
6 'config': 'path to .ini config used',
6 'config': 'path to .ini config used',
7 'scm': 'type of version control "git", "hg", "svn"',
7 'scm': 'type of version control "git", "hg", "svn"',
8 'username': 'username of actor who triggered this event',
8 'username': 'username of actor who triggered this event',
9 'ip': 'ip address of actor who triggered this hook',
9 'ip': 'ip address of actor who triggered this hook',
10 'action': '',
10 'action': '',
11 'repository': 'repository name',
11 'repository': 'repository name',
12 'repo_store_path': 'full path to where repositories are stored',
12 'repo_store_path': 'full path to where repositories are stored',
13 'commit_ids': '',
13 'commit_ids': '',
14 'hook_type': '',
14 'hook_type': '',
15 'user_agent': '',
15 'user_agent': '',
16 })
16 })
17 def _push_hook(*args, **kwargs):
17 def _push_hook(*args, **kwargs):
18 """
18 """
19 POST PUSH HOOK, this function will be executed after each push it's
19 POST PUSH HOOK, this function will be executed after each push it's
20 executed after the build-in hook that RhodeCode uses for logging pushes
20 executed after the build-in hook that RhodeCode uses for logging pushes
21 """
21 """
22
22
23 from .helpers import http_call, extra_fields
23 from .helpers import http_call, extra_fields
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26
26
27 if repo_extra_fields.get('endpoint_url'):
27 if repo_extra_fields.get('endpoint_url'):
28 endpoint = repo_extra_fields['endpoint_url']
28 field_metadata = repo_extra_fields['endpoint_url']
29 endpoint = field_metadata['field_value']
29 if endpoint:
30 if endpoint:
30 data = {
31 data = {
31 'some_key': 'val'
32 'some_key': 'val'
32 }
33 }
33 response = http_call.run(url=endpoint, json_data=data)
34 response = http_call.run(url=endpoint, json_data=data)
34 return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint, response))
35 return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint, response))
35
36
36 return HookResponse(0, '')
37 return HookResponse(0, '')
@@ -1,91 +1,92 b''
1 # Example to validate commit message or author using some sort of rules
1 # Example to validate commit message or author using some sort of rules
2
2
3
3
4 @has_kwargs({
4 @has_kwargs({
5 'server_url': 'url of instance that triggered this hook',
5 'server_url': 'url of instance that triggered this hook',
6 'config': 'path to .ini config used',
6 'config': 'path to .ini config used',
7 'scm': 'type of version control "git", "hg", "svn"',
7 'scm': 'type of version control "git", "hg", "svn"',
8 'username': 'username of actor who triggered this event',
8 'username': 'username of actor who triggered this event',
9 'ip': 'ip address of actor who triggered this hook',
9 'ip': 'ip address of actor who triggered this hook',
10 'action': '',
10 'action': '',
11 'repository': 'repository name',
11 'repository': 'repository name',
12 'repo_store_path': 'full path to where repositories are stored',
12 'repo_store_path': 'full path to where repositories are stored',
13 'commit_ids': 'pre transaction metadata for commit ids',
13 'commit_ids': 'pre transaction metadata for commit ids',
14 'hook_type': '',
14 'hook_type': '',
15 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
15 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
16 })
16 })
17 @has_kwargs({
17 @has_kwargs({
18 'server_url': 'url of instance that triggered this hook',
18 'server_url': 'url of instance that triggered this hook',
19 'config': 'path to .ini config used',
19 'config': 'path to .ini config used',
20 'scm': 'type of version control "git", "hg", "svn"',
20 'scm': 'type of version control "git", "hg", "svn"',
21 'username': 'username of actor who triggered this event',
21 'username': 'username of actor who triggered this event',
22 'ip': 'ip address of actor who triggered this hook',
22 'ip': 'ip address of actor who triggered this hook',
23 'action': '',
23 'action': '',
24 'repository': 'repository name',
24 'repository': 'repository name',
25 'repo_store_path': 'full path to where repositories are stored',
25 'repo_store_path': 'full path to where repositories are stored',
26 'commit_ids': 'pre transaction metadata for commit ids',
26 'commit_ids': 'pre transaction metadata for commit ids',
27 'hook_type': '',
27 'hook_type': '',
28 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
28 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
29 })
29 })
30 def _pre_push_hook(*args, **kwargs):
30 def _pre_push_hook(*args, **kwargs):
31 """
31 """
32 Post push hook
32 Post push hook
33 To stop version control from storing the transaction and send a message to user
33 To stop version control from storing the transaction and send a message to user
34 use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed')
34 use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed')
35
35
36 This message will be shown back to client during PUSH operation
36 This message will be shown back to client during PUSH operation
37
37
38 Commit ids might look like that::
38 Commit ids might look like that::
39
39
40 [{u'hg_env|git_env': ...,
40 [{u'hg_env|git_env': ...,
41 u'multiple_heads': [],
41 u'multiple_heads': [],
42 u'name': u'default',
42 u'name': u'default',
43 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
43 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
44 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
44 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
45 u'ref': u'',
45 u'ref': u'',
46 u'total_commits': 2,
46 u'total_commits': 2,
47 u'type': u'branch'}]
47 u'type': u'branch'}]
48 """
48 """
49 import re
49 import re
50 from .helpers import extra_fields, extract_pre_commits
50 from .helpers import extra_fields, extract_pre_commits
51 from .utils import str2bool
51 from .utils import str2bool
52
52
53 # returns list of dicts with key-val fetched from extra fields
53 # returns list of dicts with key-val fetched from extra fields
54 repo_extra_fields = extra_fields.run(**kwargs)
54 repo_extra_fields = extra_fields.run(**kwargs)
55
55
56 # optionally use 'extra fields' to control the logic per repo
56 # optionally use 'extra fields' to control the logic per repo
57 should_validate = str2bool(repo_extra_fields.get('validate_author', True))
57 validate_author = repo_extra_fields.get('validate_author', {}).get('field_value')
58 should_validate = str2bool(validate_author)
58
59
59 # optionally store validation regex into extra fields
60 # optionally store validation regex into extra fields
60 validation_regex = repo_extra_fields.get('validation_regex', '')
61 validation_regex = repo_extra_fields.get('validation_regex', {}).get('field_value')
61
62
62 def validate_commit_message(commit_message, message_regex=None):
63 def validate_commit_message(commit_message, message_regex=None):
63 """
64 """
64 This function validates commit_message against some sort of rules.
65 This function validates commit_message against some sort of rules.
65 It should return a valid boolean, and a reason for failure
66 It should return a valid boolean, and a reason for failure
66 """
67 """
67
68
68 if "secret_string" in commit_message:
69 if "secret_string" in commit_message:
69 msg = "!!Push forbidden: secret string found in commit messages"
70 msg = "!!Push forbidden: secret string found in commit messages"
70 return False, msg
71 return False, msg
71
72
72 if validation_regex:
73 if validation_regex:
73 regexp = re.compile(validation_regex)
74 regexp = re.compile(validation_regex)
74 if not regexp.match(message):
75 if not regexp.match(message):
75 msg = "!!Push forbidden: commit message does not match regexp"
76 msg = "!!Push forbidden: commit message does not match regexp"
76 return False, msg
77 return False, msg
77
78
78 return True, ''
79 return True, ''
79
80
80 if should_validate:
81 if should_validate:
81 # returns list of dicts with key-val fetched from extra fields
82 # returns list of dicts with key-val fetched from extra fields
82 commit_list = extract_pre_commits.run(**kwargs)
83 commit_list = extract_pre_commits.run(**kwargs)
83
84
84 for commit_data in commit_list:
85 for commit_data in commit_list:
85 message = commit_data['message']
86 message = commit_data['message']
86
87
87 message_valid, reason = validate_commit_message(message, validation_regex)
88 message_valid, reason = validate_commit_message(message, validation_regex)
88 if not message_valid:
89 if not message_valid:
89 return HookResponse(1, reason)
90 return HookResponse(1, reason)
90
91
91 return HookResponse(0, '')
92 return HookResponse(0, '')
@@ -1,40 +1,55 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2016-2018 RhodeCode GmbH
2 # Copyright (C) 2016-2018 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 example usage in hooks::
22
22
23 from .helpers import extra_fields
23 from .helpers import extra_fields
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26 repo_extra_fields.get('endpoint_url')
27
28 # the field stored the following example values
29 {u'created_on': datetime.datetime(),
30 u'field_key': u'endpoint_url',
31 u'field_label': u'Endpoint URL',
32 u'field_desc': u'Full HTTP endpoint to call if given',
33 u'field_type': u'str',
34 u'field_value': u'http://server.com/post',
35 u'repo_field_id': 1,
36 u'repository_id': 1}
37 # for example to obtain the value:
38 endpoint_field = repo_extra_fields.get('endpoint_url')
39 if endpoint_field:
40 url = endpoint_field['field_value']
26
41
27 """
42 """
28
43
29
44
30 def run(*args, **kwargs):
45 def run(*args, **kwargs):
31 from rhodecode.model.db import Repository
46 from rhodecode.model.db import Repository
32 # use temp name then the main one propagated
47 # use temp name then the main one propagated
33 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
48 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
34 repo = Repository.get_by_repo_name(repo_name)
49 repo = Repository.get_by_repo_name(repo_name)
35
50
36 fields = {}
51 fields = {}
37 for field in repo.extra_fields:
52 for field in repo.extra_fields:
38 fields[field.field_key] = field.get_dict()
53 fields[field.field_key] = field.get_dict()
39
54
40 return fields
55 return fields
@@ -1,36 +1,49 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2016-2018 RhodeCode GmbH
2 # Copyright (C) 2016-2018 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 us in hooks::
22
22
23 from .helpers import http_call
23 from .helpers import http_call
24 # returns response after making a POST call
24 # returns response after making a POST call
25 response = http_call.run(url=url, json_data=data)
25 response = http_call.run(url=url, json_data={"key": "val"})
26
27 # returns response after making a GET call
28 response = http_call.run(url=url, params={"key": "val"}, method='get')
26
29
27 """
30 """
28
31
29 from rhodecode.integrations.types.base import requests_retry_call
32 from rhodecode.integrations.types.base import requests_retry_call
30
33
31
34
32 def run(url, json_data, method='post'):
35 def run(url, json_data=None, params=None, method='post'):
33 requests_session = requests_retry_call()
36 requests_session = requests_retry_call()
34 requests_session.verify = True # Verify SSL
37 requests_session.verify = True # Verify SSL
35 resp = requests_session.post(url, json=json_data, timeout=60)
38 method_caller = getattr(requests_session, method, 'post')
36 return resp.raise_for_status() # raise exception on a failed request
39
40 timeout = 60
41 if json_data:
42 resp = method_caller(url, json=json_data, timeout=timeout)
43 elif params:
44 resp = method_caller(url, params=json_data, timeout=timeout)
45 else:
46 raise AttributeError('Provide json_data= or params= in function call')
47 resp.raise_for_status() # raise exception on a failed request
48 return resp
49
General Comments 0
You need to be logged in to leave comments. Login now