##// END OF EJS Templates
docs: document email integration
dan -
r641:fe7c372b default
parent child Browse files
Show More
@@ -0,0 +1,23 b''
1 .. _integrations-email:
2
3 Email integration
4 =================
5
6 The email integration allows you to send the summary of repo pushes to a
7 list of email recipients in the format:
8
9 An example::
10
11 User: johndoe
12 Branches: default
13 Repository: http://rhodecode.company.com/repo
14 Commit: 8eab60a44a612e331edfcd59b8d96b2f6a935cd9
15 URL: http://rhodecode.company.com/repo/changeset/8eab60a44a612e331edfcd59b8d96b2f6a935cd9
16 Author: John Doe
17 Date: 2016-03-01 11:20:44
18 Commit Message:
19
20 fixed bug with thing
21
22
23 To create one, create a ``email`` integration in `creating-integrations`.
@@ -1,49 +1,50 b''
1 1 .. _integrations:
2 2
3 3 Integrations
4 4 ------------
5 5
6 6 Rhodecode supports integrations with external services for various events
7 7 such as commit pushes and pull requests. Multiple integrations of the same type
8 8 (eg. slack) can be added at the same time which is useful for example to post
9 9 different events to different slack channels.
10 10
11 11 Supported integrations
12 12 ^^^^^^^^^^^^^^^^^^^^^^
13 13
14 14 ============================ ============ =====================================
15 15 Type/Name |RC| Edition Description
16 16 ============================ ============ =====================================
17 17 :ref:`integrations-slack` |RCCEshort| https://slack.com/
18 18 :ref:`integrations-hipchat` |RCCEshort| https://www.hipchat.com/
19 19 :ref:`integrations-webhook` |RCCEshort| POST events as `json` to a custom url
20 :ref:`integrations-email` |RCEEshort| Send repo push commits by email
20 21 :ref:`integrations-redmine` |RCEEshort| Close/Resolve/Reference redmine issues
21 22 :ref:`integrations-jira` |RCEEshort| Close/Resolve/Reference JIRA issues
22 23 ============================ ============ =====================================
23 24
24 25 .. _creating-integrations:
25 26
26 27 Creating an integration
27 28 ^^^^^^^^^^^^^^^^^^^^^^^
28 29
29 30 Integrations can be added globally via the admin UI:
30 31
31 32 :menuselection:`Admin --> Integrations`
32 33
33 34 or per repository in the repository settings:
34 35
35 36 :menuselection:`Admin --> Repositories --> Edit --> Integrations`
36 37
37 38 To create an integration, select the type from the list of types in the
38 39 `Create an integration` section.
39 40
40 41 The `Current integrations` section shows existing integrations that have been
41 42 created along with their type (eg. slack) and enabled status.
42 43
43 44 .. toctree::
44 45
45 46 slack
46 47 hipchat
47 48 redmine
48 49 jira
49 50 webhook
@@ -1,284 +1,285 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 """
22 22 RhodeCode task modules, containing all task that suppose to be run
23 23 by celery daemon
24 24 """
25 25
26 26
27 27 import os
28 28 import logging
29 29
30 30 from celery.task import task
31 31 from pylons import config
32 32
33 33 import rhodecode
34 34 from rhodecode.lib.celerylib import (
35 35 run_task, dbsession, __get_lockkey, LockHeld, DaemonLock,
36 36 get_session, vcsconnection, RhodecodeCeleryTask)
37 37 from rhodecode.lib.hooks_base import log_create_repository
38 38 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
39 39 from rhodecode.lib.utils import add_cache, action_logger
40 40 from rhodecode.lib.utils2 import safe_int, str2bool
41 41 from rhodecode.model.db import Repository, User
42 42
43 43
44 44 add_cache(config) # pragma: no cover
45 45
46 46
47 47 def get_logger(cls):
48 48 if rhodecode.CELERY_ENABLED:
49 49 try:
50 50 log = cls.get_logger()
51 51 except Exception:
52 52 log = logging.getLogger(__name__)
53 53 else:
54 54 log = logging.getLogger(__name__)
55 55
56 56 return log
57 57
58 58
59 59 @task(ignore_result=True, base=RhodecodeCeleryTask)
60 60 @dbsession
61 61 def send_email(recipients, subject, body='', html_body='', email_config=None):
62 62 """
63 63 Sends an email with defined parameters from the .ini files.
64 64
65 65 :param recipients: list of recipients, it this is empty the defined email
66 66 address from field 'email_to' is used instead
67 67 :param subject: subject of the mail
68 68 :param body: body of the mail
69 69 :param html_body: html version of body
70 70 """
71 71 log = get_logger(send_email)
72 72
73 73 email_config = email_config or rhodecode.CONFIG
74 print email_config
74 75 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
75 76 if not recipients:
76 77 # if recipients are not defined we send to email_config + all admins
77 78 admins = [
78 79 u.email for u in User.query().filter(User.admin == True).all()]
79 80 recipients = [email_config.get('email_to')] + admins
80 81
81 82 mail_server = email_config.get('smtp_server') or None
82 83 if mail_server is None:
83 84 log.error("SMTP server information missing. Sending email failed. "
84 85 "Make sure that `smtp_server` variable is configured "
85 86 "inside the .ini file")
86 87 return False
87 88
88 89 mail_from = email_config.get('app_email_from', 'RhodeCode')
89 90 user = email_config.get('smtp_username')
90 91 passwd = email_config.get('smtp_password')
91 92 mail_port = email_config.get('smtp_port')
92 93 tls = str2bool(email_config.get('smtp_use_tls'))
93 94 ssl = str2bool(email_config.get('smtp_use_ssl'))
94 95 debug = str2bool(email_config.get('debug'))
95 96 smtp_auth = email_config.get('smtp_auth')
96 97
97 98 try:
98 99 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
99 100 mail_port, ssl, tls, debug=debug)
100 101 m.send(recipients, subject, body, html_body)
101 102 except Exception:
102 103 log.exception('Mail sending failed')
103 104 return False
104 105 return True
105 106
106 107
107 108 @task(ignore_result=True, base=RhodecodeCeleryTask)
108 109 @dbsession
109 110 @vcsconnection
110 111 def create_repo(form_data, cur_user):
111 112 from rhodecode.model.repo import RepoModel
112 113 from rhodecode.model.user import UserModel
113 114 from rhodecode.model.settings import SettingsModel
114 115
115 116 log = get_logger(create_repo)
116 117 DBS = get_session()
117 118
118 119 cur_user = UserModel(DBS)._get_user(cur_user)
119 120 owner = cur_user
120 121
121 122 repo_name = form_data['repo_name']
122 123 repo_name_full = form_data['repo_name_full']
123 124 repo_type = form_data['repo_type']
124 125 description = form_data['repo_description']
125 126 private = form_data['repo_private']
126 127 clone_uri = form_data.get('clone_uri')
127 128 repo_group = safe_int(form_data['repo_group'])
128 129 landing_rev = form_data['repo_landing_rev']
129 130 copy_fork_permissions = form_data.get('copy_permissions')
130 131 copy_group_permissions = form_data.get('repo_copy_permissions')
131 132 fork_of = form_data.get('fork_parent_id')
132 133 state = form_data.get('repo_state', Repository.STATE_PENDING)
133 134
134 135 # repo creation defaults, private and repo_type are filled in form
135 136 defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
136 137 enable_statistics = form_data.get(
137 138 'enable_statistics', defs.get('repo_enable_statistics'))
138 139 enable_locking = form_data.get(
139 140 'enable_locking', defs.get('repo_enable_locking'))
140 141 enable_downloads = form_data.get(
141 142 'enable_downloads', defs.get('repo_enable_downloads'))
142 143
143 144 try:
144 145 RepoModel(DBS)._create_repo(
145 146 repo_name=repo_name_full,
146 147 repo_type=repo_type,
147 148 description=description,
148 149 owner=owner,
149 150 private=private,
150 151 clone_uri=clone_uri,
151 152 repo_group=repo_group,
152 153 landing_rev=landing_rev,
153 154 fork_of=fork_of,
154 155 copy_fork_permissions=copy_fork_permissions,
155 156 copy_group_permissions=copy_group_permissions,
156 157 enable_statistics=enable_statistics,
157 158 enable_locking=enable_locking,
158 159 enable_downloads=enable_downloads,
159 160 state=state
160 161 )
161 162
162 163 action_logger(cur_user, 'user_created_repo',
163 164 repo_name_full, '', DBS)
164 165 DBS.commit()
165 166
166 167 # now create this repo on Filesystem
167 168 RepoModel(DBS)._create_filesystem_repo(
168 169 repo_name=repo_name,
169 170 repo_type=repo_type,
170 171 repo_group=RepoModel(DBS)._get_repo_group(repo_group),
171 172 clone_uri=clone_uri,
172 173 )
173 174 repo = Repository.get_by_repo_name(repo_name_full)
174 175 log_create_repository(created_by=owner.username, **repo.get_dict())
175 176
176 177 # update repo commit caches initially
177 178 repo.update_commit_cache()
178 179
179 180 # set new created state
180 181 repo.set_state(Repository.STATE_CREATED)
181 182 DBS.commit()
182 183 except Exception as e:
183 184 log.warning('Exception %s occurred when creating repository, '
184 185 'doing cleanup...', e)
185 186 # rollback things manually !
186 187 repo = Repository.get_by_repo_name(repo_name_full)
187 188 if repo:
188 189 Repository.delete(repo.repo_id)
189 190 DBS.commit()
190 191 RepoModel(DBS)._delete_filesystem_repo(repo)
191 192 raise
192 193
193 194 # it's an odd fix to make celery fail task when exception occurs
194 195 def on_failure(self, *args, **kwargs):
195 196 pass
196 197
197 198 return True
198 199
199 200
200 201 @task(ignore_result=True, base=RhodecodeCeleryTask)
201 202 @dbsession
202 203 @vcsconnection
203 204 def create_repo_fork(form_data, cur_user):
204 205 """
205 206 Creates a fork of repository using internal VCS methods
206 207
207 208 :param form_data:
208 209 :param cur_user:
209 210 """
210 211 from rhodecode.model.repo import RepoModel
211 212 from rhodecode.model.user import UserModel
212 213
213 214 log = get_logger(create_repo_fork)
214 215 DBS = get_session()
215 216
216 217 cur_user = UserModel(DBS)._get_user(cur_user)
217 218 owner = cur_user
218 219
219 220 repo_name = form_data['repo_name'] # fork in this case
220 221 repo_name_full = form_data['repo_name_full']
221 222 repo_type = form_data['repo_type']
222 223 description = form_data['description']
223 224 private = form_data['private']
224 225 clone_uri = form_data.get('clone_uri')
225 226 repo_group = safe_int(form_data['repo_group'])
226 227 landing_rev = form_data['landing_rev']
227 228 copy_fork_permissions = form_data.get('copy_permissions')
228 229 fork_id = safe_int(form_data.get('fork_parent_id'))
229 230
230 231 try:
231 232 fork_of = RepoModel(DBS)._get_repo(fork_id)
232 233 RepoModel(DBS)._create_repo(
233 234 repo_name=repo_name_full,
234 235 repo_type=repo_type,
235 236 description=description,
236 237 owner=owner,
237 238 private=private,
238 239 clone_uri=clone_uri,
239 240 repo_group=repo_group,
240 241 landing_rev=landing_rev,
241 242 fork_of=fork_of,
242 243 copy_fork_permissions=copy_fork_permissions
243 244 )
244 245 action_logger(cur_user, 'user_forked_repo:%s' % repo_name_full,
245 246 fork_of.repo_name, '', DBS)
246 247 DBS.commit()
247 248
248 249 base_path = Repository.base_path()
249 250 source_repo_path = os.path.join(base_path, fork_of.repo_name)
250 251
251 252 # now create this repo on Filesystem
252 253 RepoModel(DBS)._create_filesystem_repo(
253 254 repo_name=repo_name,
254 255 repo_type=repo_type,
255 256 repo_group=RepoModel(DBS)._get_repo_group(repo_group),
256 257 clone_uri=source_repo_path,
257 258 )
258 259 repo = Repository.get_by_repo_name(repo_name_full)
259 260 log_create_repository(created_by=owner.username, **repo.get_dict())
260 261
261 262 # update repo commit caches initially
262 263 config = repo._config
263 264 config.set('extensions', 'largefiles', '')
264 265 repo.update_commit_cache(config=config)
265 266
266 267 # set new created state
267 268 repo.set_state(Repository.STATE_CREATED)
268 269 DBS.commit()
269 270 except Exception as e:
270 271 log.warning('Exception %s occurred when forking repository, '
271 272 'doing cleanup...', e)
272 273 # rollback things manually !
273 274 repo = Repository.get_by_repo_name(repo_name_full)
274 275 if repo:
275 276 Repository.delete(repo.repo_id)
276 277 DBS.commit()
277 278 RepoModel(DBS)._delete_filesystem_repo(repo)
278 279 raise
279 280
280 281 # it's an odd fix to make celery fail task when exception occurs
281 282 def on_failure(self, *args, **kwargs):
282 283 pass
283 284
284 285 return True
General Comments 0
You need to be logged in to leave comments. Login now