integrations: add repo group integrations, fixes #4175
This commit is contained in:
parent
2a0ed7c3dc
commit
2e3256ff49
7 changed files with 138 additions and 13 deletions
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
from rhodecode.model.db import Repository, Integration
|
||||
from rhodecode.model.db import Repository, Integration, RepoGroup
|
||||
from rhodecode.config.routing import (
|
||||
ADMIN_PREFIX, add_route_requirements, URL_NAME_REQUIREMENTS)
|
||||
from rhodecode.integrations import integration_type_registry
|
||||
|
|
@ -29,6 +29,8 @@ log = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
# global integrations
|
||||
config.add_route('global_integrations_home',
|
||||
ADMIN_PREFIX + '/integrations')
|
||||
config.add_route('global_integrations_list',
|
||||
|
|
@ -58,6 +60,8 @@ def includeme(config):
|
|||
request_method='POST',
|
||||
route_name=route_name)
|
||||
|
||||
|
||||
# repo integrations
|
||||
config.add_route('repo_integrations_home',
|
||||
add_route_requirements(
|
||||
'{repo_name}/settings/integrations',
|
||||
|
|
@ -101,26 +105,87 @@ def includeme(config):
|
|||
route_name=route_name)
|
||||
|
||||
|
||||
# repo group integrations
|
||||
config.add_route('repo_group_integrations_home',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations',
|
||||
URL_NAME_REQUIREMENTS
|
||||
),
|
||||
custom_predicates=(valid_repo_group,))
|
||||
config.add_route('repo_group_integrations_list',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}',
|
||||
URL_NAME_REQUIREMENTS
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='index',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
|
||||
config.add_route('repo_group_integrations_create',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}/new',
|
||||
URL_NAME_REQUIREMENTS
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
config.add_route('repo_group_integrations_edit',
|
||||
add_route_requirements(
|
||||
'{repo_group_name}/settings/integrations/{integration}/{integration_id}',
|
||||
URL_NAME_REQUIREMENTS
|
||||
),
|
||||
custom_predicates=(valid_repo_group, valid_integration))
|
||||
for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_get',
|
||||
renderer='rhodecode:templates/admin/integrations/edit.html',
|
||||
request_method='GET',
|
||||
route_name=route_name)
|
||||
config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
|
||||
attr='settings_post',
|
||||
renderer='rhodecode:templates/admin/integrations/edit.html',
|
||||
request_method='POST',
|
||||
route_name=route_name)
|
||||
|
||||
|
||||
def valid_repo(info, request):
|
||||
repo = Repository.get_by_repo_name(info['match']['repo_name'])
|
||||
if repo:
|
||||
return True
|
||||
|
||||
|
||||
def valid_repo_group(info, request):
|
||||
repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
|
||||
if repo_group:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def valid_integration(info, request):
|
||||
integration_type = info['match']['integration']
|
||||
integration_id = info['match'].get('integration_id')
|
||||
repo_name = info['match'].get('repo_name')
|
||||
repo_group_name = info['match'].get('repo_group_name')
|
||||
|
||||
if integration_type not in integration_type_registry:
|
||||
return False
|
||||
|
||||
repo = None
|
||||
repo, repo_group = None, None
|
||||
if repo_name:
|
||||
repo = Repository.get_by_repo_name(info['match']['repo_name'])
|
||||
repo = Repository.get_by_repo_name(repo_name)
|
||||
if not repo:
|
||||
return False
|
||||
|
||||
if repo_group_name:
|
||||
repo_group = RepoGroup.get_by_group_name(repo_group_name)
|
||||
if not repo_group:
|
||||
return False
|
||||
|
||||
if repo_name and repo_group:
|
||||
raise Exception('Either repo or repo_group can be set, not both')
|
||||
|
||||
|
||||
if integration_id:
|
||||
integration = Integration.get(integration_id)
|
||||
if not integration:
|
||||
|
|
@ -129,5 +194,7 @@ def valid_integration(info, request):
|
|||
return False
|
||||
if repo and repo.repo_id != integration.repo_id:
|
||||
return False
|
||||
if repo_group and repo_group.repo_group_id != integration.repo_group_id:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from pyramid.response import Response
|
|||
|
||||
from rhodecode.lib import auth
|
||||
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
|
||||
from rhodecode.model.db import Repository, Session, Integration
|
||||
from rhodecode.model.db import Repository, RepoGroup, Session, Integration
|
||||
from rhodecode.model.scm import ScmModel
|
||||
from rhodecode.model.integration import IntegrationModel
|
||||
from rhodecode.admin.navigation import navigation_list
|
||||
|
|
@ -59,6 +59,7 @@ class IntegrationSettingsViewBase(object):
|
|||
|
||||
self.IntegrationType = None
|
||||
self.repo = None
|
||||
self.repo_group = None
|
||||
self.integration = None
|
||||
self.integrations = {}
|
||||
|
||||
|
|
@ -68,6 +69,10 @@ class IntegrationSettingsViewBase(object):
|
|||
repo_name = request.matchdict['repo_name']
|
||||
self.repo = Repository.get_by_repo_name(repo_name)
|
||||
|
||||
if 'repo_group_name' in request.matchdict: # we're in repo_group context
|
||||
repo_group_name = request.matchdict['repo_group_name']
|
||||
self.repo_group = RepoGroup.get_by_group_name(repo_group_name)
|
||||
|
||||
if 'integration' in request.matchdict: # we're in integration context
|
||||
integration_type = request.matchdict['integration']
|
||||
self.IntegrationType = integration_type_registry[integration_type]
|
||||
|
|
@ -76,7 +81,10 @@ class IntegrationSettingsViewBase(object):
|
|||
integration_id = request.matchdict['integration_id']
|
||||
self.integration = Integration.get(integration_id)
|
||||
else: # list integrations context
|
||||
for integration in IntegrationModel().get_integrations(self.repo):
|
||||
integrations = IntegrationModel().get_integrations(
|
||||
repo=self.repo, repo_group=self.repo_group)
|
||||
|
||||
for integration in integrations:
|
||||
self.integrations.setdefault(integration.integration_type, []
|
||||
).append(integration)
|
||||
|
||||
|
|
@ -91,7 +99,9 @@ class IntegrationSettingsViewBase(object):
|
|||
c.active = 'integrations'
|
||||
c.rhodecode_user = self.request.user
|
||||
c.repo = self.repo
|
||||
c.repo_group = self.repo_group
|
||||
c.repo_name = self.repo and self.repo.repo_name or None
|
||||
c.repo_group_name = self.repo_group and self.repo_group.group_name or None
|
||||
if self.repo:
|
||||
c.repo_info = self.repo
|
||||
c.rhodecode_db_repo = self.repo
|
||||
|
|
@ -121,7 +131,11 @@ class IntegrationSettingsViewBase(object):
|
|||
defaults['enabled'] = self.integration.enabled
|
||||
else:
|
||||
if self.repo:
|
||||
scope = self.repo.repo_name
|
||||
scope = _('{repo_name} repository').format(
|
||||
repo_name=self.repo.repo_name)
|
||||
elif self.repo_group:
|
||||
scope = _('{repo_group_name} repo group').format(
|
||||
repo_group_name=self.repo_group.group_name)
|
||||
else:
|
||||
scope = _('Global')
|
||||
|
||||
|
|
@ -207,6 +221,8 @@ class IntegrationSettingsViewBase(object):
|
|||
self.integration.integration_type = self.IntegrationType.key
|
||||
if self.repo:
|
||||
self.integration.repo = self.repo
|
||||
elif self.repo_group:
|
||||
self.integration.repo_group = self.repo_group
|
||||
Session().add(self.integration)
|
||||
|
||||
self.integration.enabled = valid_data.pop('enabled', False)
|
||||
|
|
@ -226,6 +242,12 @@ class IntegrationSettingsViewBase(object):
|
|||
'repo_integrations_edit', repo_name=self.repo.repo_name,
|
||||
integration=self.integration.integration_type,
|
||||
integration_id=self.integration.integration_id)
|
||||
elif self.repo:
|
||||
redirect_to = self.request.route_url(
|
||||
'repo_group_integrations_edit',
|
||||
repo_group_name=self.repo_group.group_name,
|
||||
integration=self.integration.integration_type,
|
||||
integration_id=self.integration.integration_id)
|
||||
else:
|
||||
redirect_to = self.request.route_url(
|
||||
'global_integrations_edit',
|
||||
|
|
@ -270,3 +292,8 @@ class RepoIntegrationsView(IntegrationSettingsViewBase):
|
|||
def perm_check(self, user):
|
||||
return auth.HasRepoPermissionAll('repository.admin'
|
||||
)(repo_name=self.repo.repo_name, user=user)
|
||||
|
||||
class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
|
||||
def perm_check(self, user):
|
||||
return auth.HasRepoGroupPermissionAll('group.admin'
|
||||
)(group_name=self.repo_group.group_name, user=user)
|
||||
|
|
|
|||
|
|
@ -3490,9 +3490,16 @@ class Integration(Base, BaseModel):
|
|||
nullable=True, unique=None, default=None)
|
||||
repo = relationship('Repository', lazy='joined')
|
||||
|
||||
repo_group_id = Column(
|
||||
'repo_group_id', Integer(), ForeignKey('groups.group_id'),
|
||||
nullable=True, unique=None, default=None)
|
||||
repo_group = relationship('RepoGroup', lazy='joined')
|
||||
|
||||
def __repr__(self):
|
||||
if self.repo:
|
||||
scope = 'repo=%r' % self.repo
|
||||
elif self.repo_group:
|
||||
scope = 'repo_group=%r' % self.repo_group
|
||||
else:
|
||||
scope = 'global'
|
||||
|
||||
|
|
|
|||
|
|
@ -100,10 +100,13 @@ class IntegrationModel(BaseModel):
|
|||
if handler:
|
||||
handler.send_event(event)
|
||||
|
||||
def get_integrations(self, repo=None):
|
||||
def get_integrations(self, repo=None, repo_group=None):
|
||||
if repo:
|
||||
return self.sa.query(Integration).filter(
|
||||
Integration.repo_id==repo.repo_id).all()
|
||||
elif repo_group:
|
||||
return self.sa.query(Integration).filter(
|
||||
Integration.repo_group_id==repo_group.group_id).all()
|
||||
|
||||
# global integrations
|
||||
return self.sa.query(Integration).filter(
|
||||
|
|
@ -116,9 +119,14 @@ class IntegrationModel(BaseModel):
|
|||
query = self.sa.query(Integration).filter(Integration.enabled==True)
|
||||
|
||||
if isinstance(event, events.RepoEvent): # global + repo integrations
|
||||
# + repo_group integrations
|
||||
parent_groups = event.repo.groups_with_parents
|
||||
query = query.filter(
|
||||
or_(Integration.repo_id==None,
|
||||
Integration.repo_id==event.repo.repo_id))
|
||||
Integration.repo_id==event.repo.repo_id,
|
||||
Integration.repo_group_id.in_(
|
||||
[group.group_id for group in parent_groups]
|
||||
)))
|
||||
if cache:
|
||||
query = query.options(FromCache(
|
||||
"sql_cache_short",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
def inherit(context):
|
||||
if context['c'].repo:
|
||||
return "/admin/repos/repo_edit.html"
|
||||
elif context['c'].repo_group:
|
||||
return "/admin/repo_groups/repo_group_edit.html"
|
||||
else:
|
||||
return "/admin/settings/settings.html"
|
||||
%>
|
||||
|
|
|
|||
|
|
@ -37,11 +37,15 @@
|
|||
%for integration in available_integrations:
|
||||
<%
|
||||
if c.repo:
|
||||
create_url = request.route_url('repo_integrations_create',
|
||||
create_url = request.route_path('repo_integrations_create',
|
||||
repo_name=c.repo.repo_name,
|
||||
integration=integration)
|
||||
elif c.repo_group:
|
||||
create_url = request.route_path('repo_group_integrations_create',
|
||||
repo_group_name=c.repo_group.group_name,
|
||||
integration=integration)
|
||||
else:
|
||||
create_url = request.route_url('global_integrations_create',
|
||||
create_url = request.route_path('global_integrations_create',
|
||||
integration=integration)
|
||||
%>
|
||||
<a href="${create_url}" class="btn">
|
||||
|
|
@ -90,12 +94,17 @@
|
|||
%else:
|
||||
<%
|
||||
if c.repo:
|
||||
edit_url = request.route_url('repo_integrations_edit',
|
||||
edit_url = request.route_path('repo_integrations_edit',
|
||||
repo_name=c.repo.repo_name,
|
||||
integration=integration.integration_type,
|
||||
integration_id=integration.integration_id)
|
||||
elif c.repo_group:
|
||||
edit_url = request.route_path('repo_group_integrations_edit',
|
||||
repo_group_name=c.repo_group.group_name,
|
||||
integration=integration.integration_type,
|
||||
integration_id=integration.integration_id)
|
||||
else:
|
||||
edit_url = request.route_url('global_integrations_edit',
|
||||
edit_url = request.route_path('global_integrations_edit',
|
||||
integration=integration.integration_type,
|
||||
integration_id=integration.integration_id)
|
||||
%>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
${self.menu_items(active='admin')}
|
||||
</%def>
|
||||
|
||||
<%def name="main_content()">
|
||||
<%include file="/admin/repo_groups/repo_group_edit_${c.active}.html"/>
|
||||
</%def>
|
||||
|
||||
<%def name="main()">
|
||||
<div class="box">
|
||||
<div class="title">
|
||||
|
|
@ -44,11 +48,12 @@
|
|||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main-content-full-width">
|
||||
<%include file="/admin/repo_groups/repo_group_edit_${c.active}.html"/>
|
||||
${self.main_content()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue