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 |
|
|
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, |
|
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 |
|
|
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 |
|
|
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= |
|
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