summaryrefslogtreecommitdiffstats
path: root/django/engagementmanager/vm_integration
diff options
context:
space:
mode:
Diffstat (limited to 'django/engagementmanager/vm_integration')
-rwxr-xr-xdjango/engagementmanager/vm_integration/__init__.py38
-rwxr-xr-xdjango/engagementmanager/vm_integration/em_api.py188
-rwxr-xr-xdjango/engagementmanager/vm_integration/vm_client.py152
3 files changed, 378 insertions, 0 deletions
diff --git a/django/engagementmanager/vm_integration/__init__.py b/django/engagementmanager/vm_integration/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/vm_integration/__init__.py
@@ -0,0 +1,38 @@
+#
+# ============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.
diff --git a/django/engagementmanager/vm_integration/em_api.py b/django/engagementmanager/vm_integration/em_api.py
new file mode 100755
index 0000000..b41a3ff
--- /dev/null
+++ b/django/engagementmanager/vm_integration/em_api.py
@@ -0,0 +1,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
diff --git a/django/engagementmanager/vm_integration/vm_client.py b/django/engagementmanager/vm_integration/vm_client.py
new file mode 100755
index 0000000..04d77c5
--- /dev/null
+++ b/django/engagementmanager/vm_integration/vm_client.py
@@ -0,0 +1,152 @@
+#
+# ============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.
+from django.conf import settings
+from django.db.models import Q
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.activity_event_message import \
+ ActivityEventMessage
+from engagementmanager.models import VF, Role, IceUserProfile
+from engagementmanager.utils.constants import Roles
+from engagementmanager.utils.activities_data import \
+ VFProvisioningActivityData
+import concurrent.futures
+import validationmanager.em_integration.vm_api as vm_api
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
+
+
+def send_jenkins_job_and_gitlab_repo_exists(vf):
+ # A signal which check if jenkins job was created and also if gitlab repo
+ logger.debug(
+ "Sending a call to validation manager. Call=jenkins_job_and_gitlab_repo_exists_callback. vf=%s", vf.uuid)
+ is_ready = vm_api.jenkins_job_and_gitlab_repo_exists_callback(vf=vf)
+ return is_ready
+
+
+def send_cl_from_pending_to_automation_event(checkListObj):
+ # A signal that is sent when Engagement MAnager moves CL from Pending to
+ # Automation (for example when a CL is rejected by other signal from
+ # validation manager)
+ vf = VF.objects.get(engagement=checkListObj.engagement)
+ logger.debug(
+ "Sending a call to validation manager. Call=send_cl_from_pending_to_automation_event. checklistUuid=%s", checkListObj.uuid)
+ vm_api.cl_from_pending_to_automation_callback(vf=vf, checklist=checkListObj)
+
+
+def send_ssh_key_created_or_updated_event(user):
+ # A signal which is sent from the EM to the VM when a user is adding or
+ # updating their ssh key
+ logger.debug(
+ "Sending a call to validation manager. Call=send_ssh_key_created_or_updated_event. user=%s", user.uuid)
+ vm_api.ssh_key_created_or_updated_callback(user=user)
+
+def send_create_user_in_rgwa_event(user):
+ # A signal which is sent from the EM to the VM when a user is adding or
+ # updating their ssh key
+ logger.debug(
+ "Sending a call to validation manager. Call=send_create_user_in_rgwa_event. user=%s", user.full_name)
+ vm_api.create_user_rgwa(user=user)
+
+
+def send_remove_all_standard_users_from_project_event(gitlab, project_id, formatted_vf):
+ logger.debug(
+ "Sending a call to validation manager. Call=send_remove_all_standard_users_from_project_event.")
+ vm_api.remove_all_standard_users_from_project(
+ gitlab, project_id, formatted_vf)
+
+
+def send_get_project_by_vf_event(vf, gitlab):
+ if not settings.IS_SIGNAL_ENABLED:
+ return None
+ logger.debug(
+ "Sending a call to validation manager. Call=send_get_project_by_vf_event.")
+ vm_api.get_project_by_vf(vf, gitlab)
+
+
+def send_provision_new_vf_event(vf):
+ # A signal which is sent from the EM to the VM when a new VF is created. VM will than create a
+ # gitlab repo for that new VF.
+ #
+ # Note: despite its name, this signal is not used only for new vfs, but to update existing gitlab
+ # and jenkins provisioning when a vf changes e.g. when team members are
+ # added or removed.
+ try:
+ vm_api.provision_new_vf_callback(vf=vf)
+ logger.debug(
+ "Sending a call to validation manager. Call=send_provision_new_vf_event. vf=%s", vf.uuid)
+ except Exception as e:
+ el_role = Role.objects.get(name=Roles.el.name) # @UndefinedVariable
+ admin_role = Role.objects.get(
+ name=Roles.admin.name) # @UndefinedVariable
+ el_admin_list = IceUserProfile.objects.all().filter(
+ Q(role=el_role) | Q(role=admin_role))
+ activity_data = VFProvisioningActivityData(
+ vf, el_admin_list, vf.engagement, e)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+
+def send_get_list_of_repo_files_event(vf):
+ # A signal which is sent from the EM to the VM when a NextStep is created
+ # and we need the VF associated files in the git repository
+ files = vm_api.get_list_of_repo_files_callback(vf=vf)
+ logger.debug(
+ "Sending a call to validation manager. Call=send_get_list_of_repo_files_event. vf=%s", vf.uuid)
+
+ formatted_repo_files = []
+
+ for file in files:
+ formatted_repo_files.append(file['name'])
+ logger.debug(file['name'])
+
+ return formatted_repo_files
+
+
+'''''''''''''''''''''''''''
+ UTIL FUNCTIONS FOR SIGNALS
+'''''''''''''''''''''''''''
+
+
+def fire_event_in_bg(function_name, obj):
+ event_function = globals()[function_name]
+ logger.debug(
+ " . . . . . . . . . . . . Fire event in background started: %s . . . . . . . . . . . . ", function_name)
+ future = executor.submit(event_function, obj)
+ logger.debug("Main thread continue without blocking...")