##// END OF EJS Templates
integrations: add repo group integrations, fixes #4175
dan -
r667:b9ef2c10 default
parent child Browse files
Show More
@@ -20,7 +20,7 b''
20 20
21 21 import logging
22 22
23 from rhodecode.model.db import Repository, Integration
23 from rhodecode.model.db import Repository, Integration, RepoGroup
24 24 from rhodecode.config.routing import (
25 25 ADMIN_PREFIX, add_route_requirements, URL_NAME_REQUIREMENTS)
26 26 from rhodecode.integrations import integration_type_registry
@@ -29,6 +29,8 b' log = logging.getLogger(__name__)'
29 29
30 30
31 31 def includeme(config):
32
33 # global integrations
32 34 config.add_route('global_integrations_home',
33 35 ADMIN_PREFIX + '/integrations')
34 36 config.add_route('global_integrations_list',
@@ -58,6 +60,8 b' def includeme(config):'
58 60 request_method='POST',
59 61 route_name=route_name)
60 62
63
64 # repo integrations
61 65 config.add_route('repo_integrations_home',
62 66 add_route_requirements(
63 67 '{repo_name}/settings/integrations',
@@ -101,26 +105,87 b' def includeme(config):'
101 105 route_name=route_name)
102 106
103 107
108 # repo group integrations
109 config.add_route('repo_group_integrations_home',
110 add_route_requirements(
111 '{repo_group_name}/settings/integrations',
112 URL_NAME_REQUIREMENTS
113 ),
114 custom_predicates=(valid_repo_group,))
115 config.add_route('repo_group_integrations_list',
116 add_route_requirements(
117 '{repo_group_name}/settings/integrations/{integration}',
118 URL_NAME_REQUIREMENTS
119 ),
120 custom_predicates=(valid_repo_group, valid_integration))
121 for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
122 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
123 attr='index',
124 request_method='GET',
125 route_name=route_name)
126
127 config.add_route('repo_group_integrations_create',
128 add_route_requirements(
129 '{repo_group_name}/settings/integrations/{integration}/new',
130 URL_NAME_REQUIREMENTS
131 ),
132 custom_predicates=(valid_repo_group, valid_integration))
133 config.add_route('repo_group_integrations_edit',
134 add_route_requirements(
135 '{repo_group_name}/settings/integrations/{integration}/{integration_id}',
136 URL_NAME_REQUIREMENTS
137 ),
138 custom_predicates=(valid_repo_group, valid_integration))
139 for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
140 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
141 attr='settings_get',
142 renderer='rhodecode:templates/admin/integrations/edit.html',
143 request_method='GET',
144 route_name=route_name)
145 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
146 attr='settings_post',
147 renderer='rhodecode:templates/admin/integrations/edit.html',
148 request_method='POST',
149 route_name=route_name)
150
151
104 152 def valid_repo(info, request):
105 153 repo = Repository.get_by_repo_name(info['match']['repo_name'])
106 154 if repo:
107 155 return True
108 156
109 157
158 def valid_repo_group(info, request):
159 repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
160 if repo_group:
161 return True
162 return False
163
164
110 165 def valid_integration(info, request):
111 166 integration_type = info['match']['integration']
112 167 integration_id = info['match'].get('integration_id')
113 168 repo_name = info['match'].get('repo_name')
169 repo_group_name = info['match'].get('repo_group_name')
114 170
115 171 if integration_type not in integration_type_registry:
116 172 return False
117 173
118 repo = None
174 repo, repo_group = None, None
119 175 if repo_name:
120 repo = Repository.get_by_repo_name(info['match']['repo_name'])
176 repo = Repository.get_by_repo_name(repo_name)
121 177 if not repo:
122 178 return False
123 179
180 if repo_group_name:
181 repo_group = RepoGroup.get_by_group_name(repo_group_name)
182 if not repo_group:
183 return False
184
185 if repo_name and repo_group:
186 raise Exception('Either repo or repo_group can be set, not both')
187
188
124 189 if integration_id:
125 190 integration = Integration.get(integration_id)
126 191 if not integration:
@@ -129,5 +194,7 b' def valid_integration(info, request):'
129 194 return False
130 195 if repo and repo.repo_id != integration.repo_id:
131 196 return False
197 if repo_group and repo_group.repo_group_id != integration.repo_group_id:
198 return False
132 199
133 200 return True
@@ -29,7 +29,7 b' from pyramid.response import Response'
29 29
30 30 from rhodecode.lib import auth
31 31 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
32 from rhodecode.model.db import Repository, Session, Integration
32 from rhodecode.model.db import Repository, RepoGroup, Session, Integration
33 33 from rhodecode.model.scm import ScmModel
34 34 from rhodecode.model.integration import IntegrationModel
35 35 from rhodecode.admin.navigation import navigation_list
@@ -59,6 +59,7 b' class IntegrationSettingsViewBase(object'
59 59
60 60 self.IntegrationType = None
61 61 self.repo = None
62 self.repo_group = None
62 63 self.integration = None
63 64 self.integrations = {}
64 65
@@ -68,6 +69,10 b' class IntegrationSettingsViewBase(object'
68 69 repo_name = request.matchdict['repo_name']
69 70 self.repo = Repository.get_by_repo_name(repo_name)
70 71
72 if 'repo_group_name' in request.matchdict: # we're in repo_group context
73 repo_group_name = request.matchdict['repo_group_name']
74 self.repo_group = RepoGroup.get_by_group_name(repo_group_name)
75
71 76 if 'integration' in request.matchdict: # we're in integration context
72 77 integration_type = request.matchdict['integration']
73 78 self.IntegrationType = integration_type_registry[integration_type]
@@ -76,7 +81,10 b' class IntegrationSettingsViewBase(object'
76 81 integration_id = request.matchdict['integration_id']
77 82 self.integration = Integration.get(integration_id)
78 83 else: # list integrations context
79 for integration in IntegrationModel().get_integrations(self.repo):
84 integrations = IntegrationModel().get_integrations(
85 repo=self.repo, repo_group=self.repo_group)
86
87 for integration in integrations:
80 88 self.integrations.setdefault(integration.integration_type, []
81 89 ).append(integration)
82 90
@@ -91,7 +99,9 b' class IntegrationSettingsViewBase(object'
91 99 c.active = 'integrations'
92 100 c.rhodecode_user = self.request.user
93 101 c.repo = self.repo
102 c.repo_group = self.repo_group
94 103 c.repo_name = self.repo and self.repo.repo_name or None
104 c.repo_group_name = self.repo_group and self.repo_group.group_name or None
95 105 if self.repo:
96 106 c.repo_info = self.repo
97 107 c.rhodecode_db_repo = self.repo
@@ -121,7 +131,11 b' class IntegrationSettingsViewBase(object'
121 131 defaults['enabled'] = self.integration.enabled
122 132 else:
123 133 if self.repo:
124 scope = self.repo.repo_name
134 scope = _('{repo_name} repository').format(
135 repo_name=self.repo.repo_name)
136 elif self.repo_group:
137 scope = _('{repo_group_name} repo group').format(
138 repo_group_name=self.repo_group.group_name)
125 139 else:
126 140 scope = _('Global')
127 141
@@ -207,6 +221,8 b' class IntegrationSettingsViewBase(object'
207 221 self.integration.integration_type = self.IntegrationType.key
208 222 if self.repo:
209 223 self.integration.repo = self.repo
224 elif self.repo_group:
225 self.integration.repo_group = self.repo_group
210 226 Session().add(self.integration)
211 227
212 228 self.integration.enabled = valid_data.pop('enabled', False)
@@ -226,6 +242,12 b' class IntegrationSettingsViewBase(object'
226 242 'repo_integrations_edit', repo_name=self.repo.repo_name,
227 243 integration=self.integration.integration_type,
228 244 integration_id=self.integration.integration_id)
245 elif self.repo:
246 redirect_to = self.request.route_url(
247 'repo_group_integrations_edit',
248 repo_group_name=self.repo_group.group_name,
249 integration=self.integration.integration_type,
250 integration_id=self.integration.integration_id)
229 251 else:
230 252 redirect_to = self.request.route_url(
231 253 'global_integrations_edit',
@@ -270,3 +292,8 b' class RepoIntegrationsView(IntegrationSe'
270 292 def perm_check(self, user):
271 293 return auth.HasRepoPermissionAll('repository.admin'
272 294 )(repo_name=self.repo.repo_name, user=user)
295
296 class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
297 def perm_check(self, user):
298 return auth.HasRepoGroupPermissionAll('group.admin'
299 )(group_name=self.repo_group.group_name, user=user)
@@ -3490,9 +3490,16 b' class Integration(Base, BaseModel):'
3490 3490 nullable=True, unique=None, default=None)
3491 3491 repo = relationship('Repository', lazy='joined')
3492 3492
3493 repo_group_id = Column(
3494 'repo_group_id', Integer(), ForeignKey('groups.group_id'),
3495 nullable=True, unique=None, default=None)
3496 repo_group = relationship('RepoGroup', lazy='joined')
3497
3493 3498 def __repr__(self):
3494 3499 if self.repo:
3495 3500 scope = 'repo=%r' % self.repo
3501 elif self.repo_group:
3502 scope = 'repo_group=%r' % self.repo_group
3496 3503 else:
3497 3504 scope = 'global'
3498 3505
@@ -100,10 +100,13 b' class IntegrationModel(BaseModel):'
100 100 if handler:
101 101 handler.send_event(event)
102 102
103 def get_integrations(self, repo=None):
103 def get_integrations(self, repo=None, repo_group=None):
104 104 if repo:
105 105 return self.sa.query(Integration).filter(
106 106 Integration.repo_id==repo.repo_id).all()
107 elif repo_group:
108 return self.sa.query(Integration).filter(
109 Integration.repo_group_id==repo_group.group_id).all()
107 110
108 111 # global integrations
109 112 return self.sa.query(Integration).filter(
@@ -116,9 +119,14 b' class IntegrationModel(BaseModel):'
116 119 query = self.sa.query(Integration).filter(Integration.enabled==True)
117 120
118 121 if isinstance(event, events.RepoEvent): # global + repo integrations
122 # + repo_group integrations
123 parent_groups = event.repo.groups_with_parents
119 124 query = query.filter(
120 125 or_(Integration.repo_id==None,
121 Integration.repo_id==event.repo.repo_id))
126 Integration.repo_id==event.repo.repo_id,
127 Integration.repo_group_id.in_(
128 [group.group_id for group in parent_groups]
129 )))
122 130 if cache:
123 131 query = query.options(FromCache(
124 132 "sql_cache_short",
@@ -3,6 +3,8 b''
3 3 def inherit(context):
4 4 if context['c'].repo:
5 5 return "/admin/repos/repo_edit.html"
6 elif context['c'].repo_group:
7 return "/admin/repo_groups/repo_group_edit.html"
6 8 else:
7 9 return "/admin/settings/settings.html"
8 10 %>
@@ -37,11 +37,15 b''
37 37 %for integration in available_integrations:
38 38 <%
39 39 if c.repo:
40 create_url = request.route_url('repo_integrations_create',
40 create_url = request.route_path('repo_integrations_create',
41 41 repo_name=c.repo.repo_name,
42 42 integration=integration)
43 elif c.repo_group:
44 create_url = request.route_path('repo_group_integrations_create',
45 repo_group_name=c.repo_group.group_name,
46 integration=integration)
43 47 else:
44 create_url = request.route_url('global_integrations_create',
48 create_url = request.route_path('global_integrations_create',
45 49 integration=integration)
46 50 %>
47 51 <a href="${create_url}" class="btn">
@@ -90,12 +94,17 b''
90 94 %else:
91 95 <%
92 96 if c.repo:
93 edit_url = request.route_url('repo_integrations_edit',
97 edit_url = request.route_path('repo_integrations_edit',
94 98 repo_name=c.repo.repo_name,
95 99 integration=integration.integration_type,
96 100 integration_id=integration.integration_id)
101 elif c.repo_group:
102 edit_url = request.route_path('repo_group_integrations_edit',
103 repo_group_name=c.repo_group.group_name,
104 integration=integration.integration_type,
105 integration_id=integration.integration_id)
97 106 else:
98 edit_url = request.route_url('global_integrations_edit',
107 edit_url = request.route_path('global_integrations_edit',
99 108 integration=integration.integration_type,
100 109 integration_id=integration.integration_id)
101 110 %>
@@ -30,6 +30,10 b''
30 30 ${self.menu_items(active='admin')}
31 31 </%def>
32 32
33 <%def name="main_content()">
34 <%include file="/admin/repo_groups/repo_group_edit_${c.active}.html"/>
35 </%def>
36
33 37 <%def name="main()">
34 38 <div class="box">
35 39 <div class="title">
@@ -44,11 +48,12 b''
44 48 <li class="${'active' if c.active=='settings' else ''}"><a href="${h.url('edit_repo_group', group_name=c.repo_group.group_name)}">${_('Settings')}</a></li>
45 49 <li class="${'active' if c.active=='perms' else ''}"><a href="${h.url('edit_repo_group_perms', group_name=c.repo_group.group_name)}">${_('Permissions')}</a></li>
46 50 <li class="${'active' if c.active=='advanced' else ''}"><a href="${h.url('edit_repo_group_advanced', group_name=c.repo_group.group_name)}">${_('Advanced')}</a></li>
51 <li class="${'active' if c.active=='integrations' else ''}"><a href="${h.route_path('repo_group_integrations_home', repo_group_name=c.repo_group.group_name)}">${_('Integrations')}</a></li>
47 52 </ul>
48 53 </div>
49 54
50 55 <div class="main-content-full-width">
51 <%include file="/admin/repo_groups/repo_group_edit_${c.active}.html"/>
56 ${self.main_content()}
52 57 </div>
53 58
54 59 </div>
General Comments 0
You need to be logged in to leave comments. Login now