##// END OF EJS Templates
integrations: skip executing EE integrations activated from EE but not present in downgrade at CE.
marcink -
r2460:20bf9c61 default
parent child Browse files
Show More
@@ -1,216 +1,222 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 Model for integrations
23 Model for integrations
24 """
24 """
25
25
26
26
27 import logging
27 import logging
28
28
29 from sqlalchemy import or_, and_
29 from sqlalchemy import or_, and_
30
30
31 import rhodecode
31 import rhodecode
32 from rhodecode import events
32 from rhodecode import events
33 from rhodecode.integrations.types.base import EEIntegration
33 from rhodecode.lib.caching_query import FromCache
34 from rhodecode.lib.caching_query import FromCache
34 from rhodecode.model import BaseModel
35 from rhodecode.model import BaseModel
35 from rhodecode.model.db import Integration, Repository, RepoGroup
36 from rhodecode.model.db import Integration, Repository, RepoGroup
36 from rhodecode.integrations import integration_type_registry
37 from rhodecode.integrations import integration_type_registry
37
38
38 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
39
40
40
41
41 class IntegrationModel(BaseModel):
42 class IntegrationModel(BaseModel):
42
43
43 cls = Integration
44 cls = Integration
44
45
45 def __get_integration(self, integration):
46 def __get_integration(self, integration):
46 if isinstance(integration, Integration):
47 if isinstance(integration, Integration):
47 return integration
48 return integration
48 elif isinstance(integration, (int, long)):
49 elif isinstance(integration, (int, long)):
49 return self.sa.query(Integration).get(integration)
50 return self.sa.query(Integration).get(integration)
50 else:
51 else:
51 if integration:
52 if integration:
52 raise Exception('integration must be int, long or Instance'
53 raise Exception('integration must be int, long or Instance'
53 ' of Integration got %s' % type(integration))
54 ' of Integration got %s' % type(integration))
54
55
55 def create(self, IntegrationType, name, enabled, repo, repo_group,
56 def create(self, IntegrationType, name, enabled, repo, repo_group,
56 child_repos_only, settings):
57 child_repos_only, settings):
57 """ Create an IntegrationType integration """
58 """ Create an IntegrationType integration """
58 integration = Integration()
59 integration = Integration()
59 integration.integration_type = IntegrationType.key
60 integration.integration_type = IntegrationType.key
60 self.sa.add(integration)
61 self.sa.add(integration)
61 self.update_integration(integration, name, enabled, repo, repo_group,
62 self.update_integration(integration, name, enabled, repo, repo_group,
62 child_repos_only, settings)
63 child_repos_only, settings)
63 self.sa.commit()
64 self.sa.commit()
64 return integration
65 return integration
65
66
66 def update_integration(self, integration, name, enabled, repo, repo_group,
67 def update_integration(self, integration, name, enabled, repo, repo_group,
67 child_repos_only, settings):
68 child_repos_only, settings):
68 integration = self.__get_integration(integration)
69 integration = self.__get_integration(integration)
69
70
70 integration.repo = repo
71 integration.repo = repo
71 integration.repo_group = repo_group
72 integration.repo_group = repo_group
72 integration.child_repos_only = child_repos_only
73 integration.child_repos_only = child_repos_only
73 integration.name = name
74 integration.name = name
74 integration.enabled = enabled
75 integration.enabled = enabled
75 integration.settings = settings
76 integration.settings = settings
76
77
77 return integration
78 return integration
78
79
79 def delete(self, integration):
80 def delete(self, integration):
80 integration = self.__get_integration(integration)
81 integration = self.__get_integration(integration)
81 if integration:
82 if integration:
82 self.sa.delete(integration)
83 self.sa.delete(integration)
83 return True
84 return True
84 return False
85 return False
85
86
86 def get_integration_handler(self, integration):
87 def get_integration_handler(self, integration):
87 TypeClass = integration_type_registry.get(integration.integration_type)
88 TypeClass = integration_type_registry.get(integration.integration_type)
88 if not TypeClass:
89 if not TypeClass:
89 log.error('No class could be found for integration type: {}'.format(
90 log.error('No class could be found for integration type: {}'.format(
90 integration.integration_type))
91 integration.integration_type))
91 return None
92 return None
93 elif isinstance(TypeClass, EEIntegration) or issubclass(TypeClass, EEIntegration):
94 log.error('EE integration cannot be '
95 'executed for integration type: {}'.format(
96 integration.integration_type))
97 return None
92
98
93 return TypeClass(integration.settings)
99 return TypeClass(integration.settings)
94
100
95 def send_event(self, integration, event):
101 def send_event(self, integration, event):
96 """ Send an event to an integration """
102 """ Send an event to an integration """
97 handler = self.get_integration_handler(integration)
103 handler = self.get_integration_handler(integration)
98 if handler:
104 if handler:
99 log.debug(
105 log.debug(
100 'events: sending event %s on integration %s using handler %s',
106 'events: sending event %s on integration %s using handler %s',
101 event, integration, handler)
107 event, integration, handler)
102 handler.send_event(event)
108 handler.send_event(event)
103
109
104 def get_integrations(self, scope, IntegrationType=None):
110 def get_integrations(self, scope, IntegrationType=None):
105 """
111 """
106 Return integrations for a scope, which must be one of:
112 Return integrations for a scope, which must be one of:
107
113
108 'all' - every integration, global/repogroup/repo
114 'all' - every integration, global/repogroup/repo
109 'global' - global integrations only
115 'global' - global integrations only
110 <Repository> instance - integrations for this repo only
116 <Repository> instance - integrations for this repo only
111 <RepoGroup> instance - integrations for this repogroup only
117 <RepoGroup> instance - integrations for this repogroup only
112 """
118 """
113
119
114 if isinstance(scope, Repository):
120 if isinstance(scope, Repository):
115 query = self.sa.query(Integration).filter(
121 query = self.sa.query(Integration).filter(
116 Integration.repo==scope)
122 Integration.repo==scope)
117 elif isinstance(scope, RepoGroup):
123 elif isinstance(scope, RepoGroup):
118 query = self.sa.query(Integration).filter(
124 query = self.sa.query(Integration).filter(
119 Integration.repo_group==scope)
125 Integration.repo_group==scope)
120 elif scope == 'global':
126 elif scope == 'global':
121 # global integrations
127 # global integrations
122 query = self.sa.query(Integration).filter(
128 query = self.sa.query(Integration).filter(
123 and_(Integration.repo_id==None, Integration.repo_group_id==None)
129 and_(Integration.repo_id==None, Integration.repo_group_id==None)
124 )
130 )
125 elif scope == 'root-repos':
131 elif scope == 'root-repos':
126 query = self.sa.query(Integration).filter(
132 query = self.sa.query(Integration).filter(
127 and_(Integration.repo_id==None,
133 and_(Integration.repo_id==None,
128 Integration.repo_group_id==None,
134 Integration.repo_group_id==None,
129 Integration.child_repos_only==True)
135 Integration.child_repos_only==True)
130 )
136 )
131 elif scope == 'all':
137 elif scope == 'all':
132 query = self.sa.query(Integration)
138 query = self.sa.query(Integration)
133 else:
139 else:
134 raise Exception(
140 raise Exception(
135 "invalid `scope`, must be one of: "
141 "invalid `scope`, must be one of: "
136 "['global', 'all', <Repository>, <RepoGroup>]")
142 "['global', 'all', <Repository>, <RepoGroup>]")
137
143
138 if IntegrationType is not None:
144 if IntegrationType is not None:
139 query = query.filter(
145 query = query.filter(
140 Integration.integration_type==IntegrationType.key)
146 Integration.integration_type==IntegrationType.key)
141
147
142 result = []
148 result = []
143 for integration in query.all():
149 for integration in query.all():
144 IntType = integration_type_registry.get(integration.integration_type)
150 IntType = integration_type_registry.get(integration.integration_type)
145 result.append((IntType, integration))
151 result.append((IntType, integration))
146 return result
152 return result
147
153
148 def get_for_event(self, event, cache=False):
154 def get_for_event(self, event, cache=False):
149 """
155 """
150 Get integrations that match an event
156 Get integrations that match an event
151 """
157 """
152 query = self.sa.query(
158 query = self.sa.query(
153 Integration
159 Integration
154 ).filter(
160 ).filter(
155 Integration.enabled==True
161 Integration.enabled==True
156 )
162 )
157
163
158 global_integrations_filter = and_(
164 global_integrations_filter = and_(
159 Integration.repo_id==None,
165 Integration.repo_id==None,
160 Integration.repo_group_id==None,
166 Integration.repo_group_id==None,
161 Integration.child_repos_only==False,
167 Integration.child_repos_only==False,
162 )
168 )
163
169
164 if isinstance(event, events.RepoEvent):
170 if isinstance(event, events.RepoEvent):
165 root_repos_integrations_filter = and_(
171 root_repos_integrations_filter = and_(
166 Integration.repo_id==None,
172 Integration.repo_id==None,
167 Integration.repo_group_id==None,
173 Integration.repo_group_id==None,
168 Integration.child_repos_only==True,
174 Integration.child_repos_only==True,
169 )
175 )
170
176
171 clauses = [
177 clauses = [
172 global_integrations_filter,
178 global_integrations_filter,
173 ]
179 ]
174
180
175 # repo integrations
181 # repo integrations
176 if event.repo.repo_id: # pre create events dont have a repo_id yet
182 if event.repo.repo_id: # pre create events dont have a repo_id yet
177 clauses.append(
183 clauses.append(
178 Integration.repo_id==event.repo.repo_id
184 Integration.repo_id==event.repo.repo_id
179 )
185 )
180
186
181 if event.repo.group:
187 if event.repo.group:
182 clauses.append(
188 clauses.append(
183 and_(
189 and_(
184 Integration.repo_group_id==event.repo.group.group_id,
190 Integration.repo_group_id==event.repo.group.group_id,
185 Integration.child_repos_only==True
191 Integration.child_repos_only==True
186 )
192 )
187 )
193 )
188 # repo group cascade to kids
194 # repo group cascade to kids
189 clauses.append(
195 clauses.append(
190 and_(
196 and_(
191 Integration.repo_group_id.in_(
197 Integration.repo_group_id.in_(
192 [group.group_id for group in
198 [group.group_id for group in
193 event.repo.groups_with_parents]
199 event.repo.groups_with_parents]
194 ),
200 ),
195 Integration.child_repos_only==False
201 Integration.child_repos_only==False
196 )
202 )
197 )
203 )
198
204
199
205
200 if not event.repo.group: # root repo
206 if not event.repo.group: # root repo
201 clauses.append(root_repos_integrations_filter)
207 clauses.append(root_repos_integrations_filter)
202
208
203 query = query.filter(or_(*clauses))
209 query = query.filter(or_(*clauses))
204
210
205 if cache:
211 if cache:
206 cache_key = "get_enabled_repo_integrations_%i" % event.repo.repo_id
212 cache_key = "get_enabled_repo_integrations_%i" % event.repo.repo_id
207 query = query.options(
213 query = query.options(
208 FromCache("sql_cache_short", cache_key))
214 FromCache("sql_cache_short", cache_key))
209 else: # only global integrations
215 else: # only global integrations
210 query = query.filter(global_integrations_filter)
216 query = query.filter(global_integrations_filter)
211 if cache:
217 if cache:
212 query = query.options(
218 query = query.options(
213 FromCache("sql_cache_short", "get_enabled_global_integrations"))
219 FromCache("sql_cache_short", "get_enabled_global_integrations"))
214
220
215 result = query.all()
221 result = query.all()
216 return result No newline at end of file
222 return result
General Comments 0
You need to be logged in to leave comments. Login now