1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
#
# ============LICENSE_START==========================================
# org.onap.vvp/engagementmgr
# ===================================================================
# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
# ===================================================================
#
# Unless otherwise specified, all software contained herein is licensed
# under the Apache License, Version 2.0 (the “License”);
# you may not use this software except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
#
# Unless otherwise specified, all documentation contained herein is licensed
# under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
# you may not use this documentation except in compliance with the License.
# You may obtain a copy of the License at
#
# https://creativecommons.org/licenses/by/4.0/
#
# Unless required by applicable law or agreed to in writing, documentation
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ============LICENSE_END============================================
#
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
import json
from django.core.exceptions import ObjectDoesNotExist
from engagementmanager.slack_client.api import SlackClient
from engagementmanager.models import Checklist, VF
from engagementmanager.service.checklist_service import CheckListSvc
from engagementmanager.service.checklist_state_service import set_state
from engagementmanager.utils import dict_path_get
from engagementmanager.utils.constants import CheckListCategory, CheckListState, EngagementStage
from engagementmanager.utils.request_data_mgr import request_data_mgr
from engagementmanager.service.logging_service import LoggingServiceFactory
logger = LoggingServiceFactory.get_logger()
def test_finished_callback(checklist_test_results):
logger.debug(
"test_finished_callback has signaled that a test has finished with test results %r", checklist_test_results)
if not checklist_test_results:
msg = "Couldn't find payload argument inside kwargs array, aborting signal"
logger.error(msg)
raise KeyError(msg)
checklist_test_results['description'] = "Validation manager has indicated that checklist {} tests has been completed with results".format(
checklist_test_results['checklist_uuid'])
checklist = Checklist.objects.get(
uuid=checklist_test_results['checklist_uuid'])
request_data_mgr.set_cl_uuid(checklist.uuid)
data = CheckListSvc().setChecklistDecisionsFromValMgr(
user=checklist.owner,
checklist_uuid=checklist_test_results['checklist_uuid'],
decisions=checklist_test_results['decisions'],
checklist_results_from_jenkins=checklist_test_results
)
return data
def git_push_callback(gitlab_data):
"""
When we are notified that a repo has received a push, we must reject any checklists not in the
closed or archived state whose associated files have been modified.
"""
logger.debug("Validation manager has signaled that a git push has occurred")
msg = "OK"
data = None
# sanity check provided arguments
for key in ['project', 'project/git_ssh_url', 'commits']:
if not dict_path_get(gitlab_data, key):
msg = "{!r} in the git_push signal gitlab_data is missing or empty.".format(
key)
logger.error(msg)
raise KeyError(msg)
# For now, ignore pushes made to any branch other than 'master'.
if gitlab_data['ref'] != u'refs/heads/master':
logger.warn("A non-master ref %r was updated. Ignoring.",
gitlab_data['ref'])
return None
# sanity check payload data
if int(gitlab_data['total_commits_count']) == 0:
logger.debug("total_commits_count = %s",
gitlab_data['total_commits_count'])
msg = "Something is wrong: Number of commits is 0 even after a push event has been invoked from validation manager to engagement manager"
logger.warn(msg)
raise ValueError(msg)
if gitlab_data['before'] == '0000000000000000000000000000000000000000':
logger.debug('This is the first commit pushed to master.')
git_ssh_url = gitlab_data['project']['git_ssh_url']
vf = VF.objects.filter(git_repo_url=git_ssh_url)
if len(vf) == 0:
msg = "Couldn't fetch any VF"
logger.error(msg)
raise ObjectDoesNotExist(msg)
else:
vf = VF.objects.get(git_repo_url=git_ssh_url)
checklists = (Checklist.objects
.filter(engagement=vf.engagement)
# @UndefinedVariable
.exclude(state=CheckListState.archive.name)
.exclude(state=CheckListState.closed.name)) # @UndefinedVariable
committed_files = set(file
for commit in gitlab_data['commits']
for status in ['added', 'modified', 'removed']
for file in commit[status])
logger.debug("Committed files list: [%s]" % ', '.join(committed_files))
# send notifications to reviewers and peer reviewers when the git repo is
# updated
vf_name = vf.name
engagement_manual_id = vf.engagement.engagement_manual_id
reviewer = vf.engagement.reviewer
peer_reviewer = vf.engagement.peer_reviewer
slack_client = SlackClient()
slack_client.send_notifications_on_git_push(
engagement_manual_id, vf_name, reviewer, peer_reviewer, committed_files)
# loop through the checklists and start automation if necessary
for checklist in checklists:
user = checklist.owner
template_category = checklist.template.category
mutual_files = committed_files.intersection(
json.loads(checklist.associated_files))
logger.debug("Mutual files list for checklist %s: [%s]" % (
checklist.uuid, ', '.join(committed_files)))
if not mutual_files and\
template_category == CheckListCategory.heat.name and\
not any(file
for file in committed_files
for extension in ['.yaml', '.yml', '.env']
if file.lower().endswith(extension)):
continue
if checklist.state == CheckListState.pending.name: # @UndefinedVariable
description = "Checklist {checklist.name} (part of VF {vf.name}/{vf.uuid}) in Pending state will transition to Automation due to a push action on files [{mutual_files}]. chosen EL: {user.full_name}".format(
checklist=checklist,
vf=vf,
mutual_files=", ".join(mutual_files),
user=user,
)
else:
description = "Checklist {checklist.uuid} (part of VF {vf.name}/{vf.uuid}) has been rejected due to a push action made on files [{mutual_files}]. chosen EL is: {user.full_name}".format(
checklist=checklist,
vf=vf,
mutual_files=", ".join(mutual_files),
user=user,
)
logger.debug(description)
# FIXME Setting parameters into a global before calling a function that will break without
# them is TERRIBLE. We must fix this before we open-source this code.
request_data_mgr.set_cl_uuid(checklist.uuid)
request_data_mgr.set_user(user)
data = set_state( # means that the checklist will be declined and a cloned one is
# created in PENDING status
decline=True,
checklist_uuid=checklist.uuid,
# means the checklist will be triggered into automation cycle
isMoveToAutomation=True,
description="This change was triggered by an update to the engagement git repository.")
logger.debug("set_state returned (%r)" % data)
return data
|