##// END OF EJS Templates
feat(configs): deprecared old hooks protocol and ssh wrapper....
feat(configs): deprecared old hooks protocol and ssh wrapper. New defaults are now set on v2 keys, so previous installation are automatically set to new keys. Fallback mode is still available.

File last commit:

r5200:382130ed default
r5496:cab50adf default
Show More
integration.py
237 lines | 8.6 KiB | text/x-python | PythonLexer
copyrights: updated for 2023
r5088 # Copyright (C) 2011-2023 RhodeCode GmbH
dan
integrations: add integration support...
r411 #
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
"""
Model for integrations
"""
import logging
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 from sqlalchemy import or_, and_
dan
integrations: add integration support...
r411
from rhodecode import events
integrations: skip executing EE integrations activated from EE but not present in downgrade at CE.
r2460 from rhodecode.integrations.types.base import EEIntegration
dan
integrations: add integration support...
r411 from rhodecode.lib.caching_query import FromCache
from rhodecode.model import BaseModel
models: major update for python3,...
r5070 from rhodecode.model.db import Integration, Repository, RepoGroup, true, false, case, null
dan
integrations: add integration support...
r411 from rhodecode.integrations import integration_type_registry
log = logging.getLogger(__name__)
class IntegrationModel(BaseModel):
cls = Integration
def __get_integration(self, integration):
if isinstance(integration, Integration):
return integration
python3: fix usage of int/long
r4935 elif isinstance(integration, int):
dan
integrations: add integration support...
r411 return self.sa.query(Integration).get(integration)
else:
if integration:
python3: fix usage of int/long
r4935 raise Exception('integration must be int or Instance'
dan
integrations: add integration support...
r411 ' of Integration got %s' % type(integration))
models: major update for python3,...
r5070 def create(self, IntegrationType, name, enabled, repo, repo_group, child_repos_only, settings):
dan
integrations: fix bug where deleting a repo did not delete integrations
r427 """ Create an IntegrationType integration """
integrations-db: don't use default contructor to be consisten with other modules...
r448 integration = Integration()
integration.integration_type = IntegrationType.key
dan
integrations: fix bug where deleting a repo did not delete integrations
r427 self.sa.add(integration)
dan
integrations: add recursive repo group scope to allow integrations...
r793 self.update_integration(integration, name, enabled, repo, repo_group,
child_repos_only, settings)
dan
integrations: fix bug where deleting a repo did not delete integrations
r427 self.sa.commit()
return integration
dan
integrations: add recursive repo group scope to allow integrations...
r793 def update_integration(self, integration, name, enabled, repo, repo_group,
child_repos_only, settings):
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 integration = self.__get_integration(integration)
dan
integrations: add recursive repo group scope to allow integrations...
r793 integration.repo = repo
integration.repo_group = repo_group
integration.child_repos_only = child_repos_only
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 integration.name = name
integration.enabled = enabled
integration.settings = settings
return integration
dan
integrations: add integration support...
r411 def delete(self, integration):
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 integration = self.__get_integration(integration)
if integration:
self.sa.delete(integration)
return True
dan
integrations: add integration support...
r411 return False
def get_integration_handler(self, integration):
TypeClass = integration_type_registry.get(integration.integration_type)
if not TypeClass:
log.error('No class could be found for integration type: {}'.format(
integration.integration_type))
return None
integrations: skip executing EE integrations activated from EE but not present in downgrade at CE.
r2460 elif isinstance(TypeClass, EEIntegration) or issubclass(TypeClass, EEIntegration):
log.error('EE integration cannot be '
'executed for integration type: {}'.format(
integration.integration_type))
return None
dan
integrations: add integration support...
r411
return TypeClass(integration.settings)
def send_event(self, integration, event):
""" Send an event to an integration """
handler = self.get_integration_handler(integration)
if handler:
events: re-organizate events handling....
r1789 log.debug(
'events: sending event %s on integration %s using handler %s',
event, integration, handler)
dan
integrations: add integration support...
r411 handler.send_event(event)
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 def get_integrations(self, scope, IntegrationType=None):
"""
Return integrations for a scope, which must be one of:
'all' - every integration, global/repogroup/repo
'global' - global integrations only
<Repository> instance - integrations for this repo only
<RepoGroup> instance - integrations for this repogroup only
"""
dan
integrations: add integration support...
r411
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 if isinstance(scope, Repository):
query = self.sa.query(Integration).filter(
events: cleanup code, pep8, better logging.
r2920 Integration.repo == scope)
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 elif isinstance(scope, RepoGroup):
query = self.sa.query(Integration).filter(
events: cleanup code, pep8, better logging.
r2920 Integration.repo_group == scope)
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 elif scope == 'global':
# global integrations
query = self.sa.query(Integration).filter(
lint: use null() to compare to == None for linters to be happy
r5180 and_(Integration.repo_id == null(), Integration.repo_group_id == null())
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
dan
integrations: add recursive repo group scope to allow integrations...
r793 elif scope == 'root-repos':
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 query = self.sa.query(Integration).filter(
lint: use null() to compare to == None for linters to be happy
r5180 and_(Integration.repo_id == null(),
Integration.repo_group_id == null(),
events: cleanup code, pep8, better logging.
r2920 Integration.child_repos_only == true())
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
elif scope == 'all':
query = self.sa.query(Integration)
else:
raise Exception(
"invalid `scope`, must be one of: "
"['global', 'all', <Repository>, <RepoGroup>]")
if IntegrationType is not None:
query = query.filter(
Integration.integration_type==IntegrationType.key)
result = []
for integration in query.all():
IntType = integration_type_registry.get(integration.integration_type)
result.append((IntType, integration))
return result
dan
integrations: add integration support...
r411
def get_for_event(self, event, cache=False):
"""
Get integrations that match an event
"""
events: ensure stable execution of integrations
r3806 # base query
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 query = self.sa.query(
Integration
).filter(
events: cleanup code, pep8, better logging.
r2920 Integration.enabled == true()
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
global_integrations_filter = and_(
models: major update for python3,...
r5070 Integration.repo_id == null(),
Integration.repo_group_id == null(),
events: ensure stable execution of integrations
r3806 Integration.child_repos_only == false(),
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
if isinstance(event, events.RepoEvent):
root_repos_integrations_filter = and_(
models: major update for python3,...
r5070 Integration.repo_id == null(),
Integration.repo_group_id == null(),
events: cleanup code, pep8, better logging.
r2920 Integration.child_repos_only == true(),
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
clauses = [
global_integrations_filter,
]
events: ensure stable execution of integrations
r3806 cases = [
(global_integrations_filter, 1),
(root_repos_integrations_filter, 2),
]
dan
integrations: add integration support...
r411
events: ensure stable execution of integrations
r3806 # repo group integrations
if event.repo.group:
# repo group with only root level repos
group_child_repos_filter = and_(
Integration.repo_group_id == event.repo.group.group_id,
Integration.child_repos_only == true()
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
events: ensure stable execution of integrations
r3806 clauses.append(group_child_repos_filter)
cases.append(
(group_child_repos_filter, 3),
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 )
events: ensure stable execution of integrations
r3806
dan
integrations: add recursive repo group scope to allow integrations...
r793 # repo group cascade to kids
events: ensure stable execution of integrations
r3806 group_recursive_repos_filter = and_(
Integration.repo_group_id.in_(
[group.group_id for group in event.repo.groups_with_parents]
),
Integration.child_repos_only == false()
)
clauses.append(group_recursive_repos_filter)
cases.append(
(group_recursive_repos_filter, 4),
dan
integrations: add recursive repo group scope to allow integrations...
r793 )
dan
integrations: refactor/cleanup + features, fixes #4181...
r731
events: cleanup code, pep8, better logging.
r2920 if not event.repo.group: # root repo
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 clauses.append(root_repos_integrations_filter)
events: ensure stable execution of integrations
r3806 # repo integrations
if event.repo.repo_id: # pre create events dont have a repo_id yet
specific_repo_filter = Integration.repo_id == event.repo.repo_id
clauses.append(specific_repo_filter)
cases.append(
(specific_repo_filter, 5),
)
chore(warnings): fixed sqlalchemy warning for use of cases syntax
r5200 order_by_criterion = case(*cases)
events: ensure stable execution of integrations
r3806
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 query = query.filter(or_(*clauses))
events: ensure stable execution of integrations
r3806 query = query.order_by(order_by_criterion)
dan
integrations: refactor/cleanup + features, fixes #4181...
r731
dan
integrations: add integration support...
r411 if cache:
models: major update for python3,...
r5070 cache_key = f"get_enabled_repo_integrations_{event.repo.repo_id}"
caches: ensure we don't use non-ascii characters in cache keys....
r1749 query = query.options(
FromCache("sql_cache_short", cache_key))
events: cleanup code, pep8, better logging.
r2920 else: # only global integrations
events: ensure stable execution of integrations
r3806 order_by_criterion = Integration.integration_id
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 query = query.filter(global_integrations_filter)
events: ensure stable execution of integrations
r3806 query = query.order_by(order_by_criterion)
dan
integrations: add integration support...
r411 if cache:
caches: ensure we don't use non-ascii characters in cache keys....
r1749 query = query.options(
FromCache("sql_cache_short", "get_enabled_global_integrations"))
dan
integrations: add integration support...
r411
dan
integrations: refactor/cleanup + features, fixes #4181...
r731 result = query.all()
events: cleanup code, pep8, better logging.
r2920 return result