summaryrefslogtreecommitdiffstats
path: root/django/engagementmanager
diff options
context:
space:
mode:
authorPaul McGoldrick <paul.mcgoldrick@att.com>2017-09-28 10:03:40 -0700
committerPaul McGoldrick <paul.mcgoldrick@att.com>2017-09-28 10:14:55 -0700
commitbd886d918ef2adbabd16c61fdd2e47984e21dfd7 (patch)
treed41683dffa58fd698df450d148fab3cc2521b0c5 /django/engagementmanager
parent474554adad912f3edb7ddc3ad14406abb369fb3c (diff)
initial seed code commit VVP-5
Change-Id: I6560c87ef48a6d0d1fe8197c7c6439c7e6ad653f Signed-off-by: Paul McGoldrick <paul.mcgoldrick@att.com>
Diffstat (limited to 'django/engagementmanager')
-rwxr-xr-xdjango/engagementmanager/__init__.py38
-rwxr-xr-xdjango/engagementmanager/admin.py380
-rwxr-xr-xdjango/engagementmanager/apps.py96
-rwxr-xr-xdjango/engagementmanager/bus/__init__.py38
-rwxr-xr-xdjango/engagementmanager/bus/handlers/__init__.py38
-rwxr-xr-xdjango/engagementmanager/bus/handlers/activity_event_handler.py52
-rwxr-xr-xdjango/engagementmanager/bus/handlers/check_news_and_announcements_handler.py49
-rwxr-xr-xdjango/engagementmanager/bus/handlers/daily_notify_inactive_engagements.py93
-rwxr-xr-xdjango/engagementmanager/bus/handlers/daily_notify_inactive_engagements_handler.py90
-rwxr-xr-xdjango/engagementmanager/bus/handlers/daily_resend_notifications_handler.py75
-rwxr-xr-xdjango/engagementmanager/bus/handlers/digest_email_notification_handler.py74
-rwxr-xr-xdjango/engagementmanager/bus/handlers/new_notification_handler.py74
-rwxr-xr-xdjango/engagementmanager/bus/handlers/service_bus_base_handler.py54
-rwxr-xr-xdjango/engagementmanager/bus/messages/__init__.py38
-rwxr-xr-xdjango/engagementmanager/bus/messages/activity_event_message.py49
-rwxr-xr-xdjango/engagementmanager/bus/messages/daily_scheduled_message.py44
-rwxr-xr-xdjango/engagementmanager/bus/messages/hourly_scheduled_message.py44
-rwxr-xr-xdjango/engagementmanager/bus/messages/new_notification_message.py49
-rwxr-xr-xdjango/engagementmanager/bus/messages/service_bus_base_message.py46
-rwxr-xr-xdjango/engagementmanager/cms_client/__init__.py38
-rwxr-xr-xdjango/engagementmanager/cms_client/api.py159
-rwxr-xr-xdjango/engagementmanager/decorator/__init__.py38
-rwxr-xr-xdjango/engagementmanager/decorator/auth.py103
-rwxr-xr-xdjango/engagementmanager/decorator/class_decorator.py47
-rwxr-xr-xdjango/engagementmanager/decorator/log_func_entry.py50
-rwxr-xr-xdjango/engagementmanager/decorator/retry.py52
-rwxr-xr-xdjango/engagementmanager/git/__init__.py38
-rwxr-xr-xdjango/engagementmanager/git/git_manager.py52
-rwxr-xr-xdjango/engagementmanager/http_client.py54
-rwxr-xr-xdjango/engagementmanager/mail.py71
-rwxr-xr-xdjango/engagementmanager/management/__init__.py39
-rwxr-xr-xdjango/engagementmanager/management/commands/__init__.py38
-rwxr-xr-xdjango/engagementmanager/management/commands/clean_gitlab_content.py103
-rwxr-xr-xdjango/engagementmanager/management/commands/clean_jenkins_jobs.py73
-rwxr-xr-xdjango/engagementmanager/management/commands/clean_vvp_db.py96
-rwxr-xr-xdjango/engagementmanager/management/commands/clean_vvp_system.py93
-rwxr-xr-xdjango/engagementmanager/management/commands/initial_populate_db.py912
-rwxr-xr-xdjango/engagementmanager/management/commands/populate_all_gitlab_repo_and_user_and_jenkins.py78
-rwxr-xr-xdjango/engagementmanager/management/commands/render_rgwa_credentials.py61
-rwxr-xr-xdjango/engagementmanager/migrations/0001_initial.py396
-rwxr-xr-xdjango/engagementmanager/migrations/0001_squashed_initial.py639
-rwxr-xr-xdjango/engagementmanager/migrations/0002_auto_20160704_1028.py176
-rwxr-xr-xdjango/engagementmanager/migrations/0003_auto_20160713_0929.py85
-rwxr-xr-xdjango/engagementmanager/migrations/0004_auto_20160720_2143.py68
-rwxr-xr-xdjango/engagementmanager/migrations/0005_auto_20160815_1248.py95
-rwxr-xr-xdjango/engagementmanager/migrations/0006_auto_20160825_0644.py237
-rwxr-xr-xdjango/engagementmanager/migrations/0007_auto_20160922_0421.py70
-rwxr-xr-xdjango/engagementmanager/migrations/0008_auto_20161009_1210.py74
-rwxr-xr-xdjango/engagementmanager/migrations/0009_auto_20161018_0740.py65
-rwxr-xr-xdjango/engagementmanager/migrations/0010_auto_20161025_0838.py106
-rwxr-xr-xdjango/engagementmanager/migrations/0011_auto_20161109_0811.py81
-rwxr-xr-xdjango/engagementmanager/migrations/0012_auto_20161109_0822.py82
-rwxr-xr-xdjango/engagementmanager/migrations/0013_auto_20161128_1159.py99
-rwxr-xr-xdjango/engagementmanager/migrations/0014_auto_20161129_1145.py104
-rwxr-xr-xdjango/engagementmanager/migrations/0015_engagementstatus.py71
-rwxr-xr-xdjango/engagementmanager/migrations/0016_auto_20161208_0842.py59
-rwxr-xr-xdjango/engagementmanager/migrations/0017_auto_20161215_1535.py74
-rwxr-xr-xdjango/engagementmanager/migrations/0018_set_old_notif_true.py54
-rwxr-xr-xdjango/engagementmanager/migrations/0019_auto_20170104_1715.py59
-rwxr-xr-xdjango/engagementmanager/migrations/0020_add_indexes_20170108.py109
-rwxr-xr-xdjango/engagementmanager/migrations/0021_generate_excel_overview_sheet_procedure_20170110.py65
-rwxr-xr-xdjango/engagementmanager/migrations/0022_auto_20170118_1520.py275
-rwxr-xr-xdjango/engagementmanager/migrations/0023_auto_20170123_1445.py108
-rwxr-xr-xdjango/engagementmanager/migrations/0024_auto_20170227_1224.py64
-rwxr-xr-xdjango/engagementmanager/migrations/0025_change_nextsteps_to_new_state.py54
-rwxr-xr-xdjango/engagementmanager/migrations/0026_add_slack_handle_to_ice_user_profile.py57
-rwxr-xr-xdjango/engagementmanager/migrations/0027_add_version_to_vf.py58
-rwxr-xr-xdjango/engagementmanager/migrations/0028_auto_20170425_1310.py111
-rwxr-xr-xdjango/engagementmanager/migrations/0029_auto_20170504_0749.py73
-rwxr-xr-xdjango/engagementmanager/migrations/0030_engagement_archived_time.py58
-rwxr-xr-xdjango/engagementmanager/migrations/0031_auto_20170620_1312.py64
-rwxr-xr-xdjango/engagementmanager/migrations/0032_auto_20170702_1435.py71
-rwxr-xr-xdjango/engagementmanager/migrations/0033_auto_20170704_0635.py169
-rwxr-xr-xdjango/engagementmanager/migrations/0034_engagement_is_with_files.py58
-rwxr-xr-xdjango/engagementmanager/migrations/0035_rgwa_fields.py68
-rwxr-xr-xdjango/engagementmanager/migrations/0036_auto_20170906_0935.py63
-rwxr-xr-xdjango/engagementmanager/migrations/__init__.py38
-rwxr-xr-xdjango/engagementmanager/models.py615
-rwxr-xr-xdjango/engagementmanager/nextsteps.py114
-rwxr-xr-xdjango/engagementmanager/notifications.py71
-rwxr-xr-xdjango/engagementmanager/rest/__init__.py38
-rwxr-xr-xdjango/engagementmanager/rest/activation.py123
-rwxr-xr-xdjango/engagementmanager/rest/activity.py65
-rwxr-xr-xdjango/engagementmanager/rest/checklist.py139
-rwxr-xr-xdjango/engagementmanager/rest/checklist_audit_log.py103
-rwxr-xr-xdjango/engagementmanager/rest/checklist_decision.py76
-rwxr-xr-xdjango/engagementmanager/rest/checklist_set_state.py67
-rwxr-xr-xdjango/engagementmanager/rest/cms/__init__.py38
-rwxr-xr-xdjango/engagementmanager/rest/cms/pages.py80
-rwxr-xr-xdjango/engagementmanager/rest/cms/posts.py57
-rwxr-xr-xdjango/engagementmanager/rest/csrf_exempt_session_authentication.py47
-rwxr-xr-xdjango/engagementmanager/rest/data_loader.py82
-rwxr-xr-xdjango/engagementmanager/rest/deployment_target.py69
-rwxr-xr-xdjango/engagementmanager/rest/deployment_target_site.py103
-rwxr-xr-xdjango/engagementmanager/rest/ecomp.py69
-rwxr-xr-xdjango/engagementmanager/rest/engagement.py665
-rwxr-xr-xdjango/engagementmanager/rest/feedback.py70
-rwxr-xr-xdjango/engagementmanager/rest/invite.py97
-rwxr-xr-xdjango/engagementmanager/rest/login.py88
-rwxr-xr-xdjango/engagementmanager/rest/nextsteps.py163
-rwxr-xr-xdjango/engagementmanager/rest/notification.py89
-rwxr-xr-xdjango/engagementmanager/rest/parsers.py118
-rwxr-xr-xdjango/engagementmanager/rest/signup.py188
-rwxr-xr-xdjango/engagementmanager/rest/user.py241
-rwxr-xr-xdjango/engagementmanager/rest/validation_details.py55
-rwxr-xr-xdjango/engagementmanager/rest/vendor.py95
-rwxr-xr-xdjango/engagementmanager/rest/vf.py74
-rwxr-xr-xdjango/engagementmanager/rest/vfc.py86
-rwxr-xr-xdjango/engagementmanager/rest/vvp_api_view.py64
-rwxr-xr-xdjango/engagementmanager/scheduled_jobs.py67
-rwxr-xr-xdjango/engagementmanager/serializers.py423
-rwxr-xr-xdjango/engagementmanager/service/__init__.py38
-rwxr-xr-xdjango/engagementmanager/service/activities_service.py238
-rwxr-xr-xdjango/engagementmanager/service/authorization_service.py605
-rwxr-xr-xdjango/engagementmanager/service/base_service.py52
-rwxr-xr-xdjango/engagementmanager/service/bus_service.py75
-rwxr-xr-xdjango/engagementmanager/service/checklist_audit_log_service.py105
-rwxr-xr-xdjango/engagementmanager/service/checklist_decision_service.py122
-rwxr-xr-xdjango/engagementmanager/service/checklist_service.py509
-rwxr-xr-xdjango/engagementmanager/service/checklist_state_service.py434
-rwxr-xr-xdjango/engagementmanager/service/cms/__init__.py38
-rwxr-xr-xdjango/engagementmanager/service/cms/base_cms.py51
-rwxr-xr-xdjango/engagementmanager/service/cms/pages_service.py68
-rwxr-xr-xdjango/engagementmanager/service/cms/posts_service.py58
-rwxr-xr-xdjango/engagementmanager/service/deploment_target_service.py47
-rwxr-xr-xdjango/engagementmanager/service/ecomp_service.py46
-rwxr-xr-xdjango/engagementmanager/service/engagement_service.py689
-rwxr-xr-xdjango/engagementmanager/service/invite_service.py179
-rwxr-xr-xdjango/engagementmanager/service/logging_service.py58
-rwxr-xr-xdjango/engagementmanager/service/login_service.py136
-rwxr-xr-xdjango/engagementmanager/service/nextstep_service.py280
-rwxr-xr-xdjango/engagementmanager/service/user_service.py121
-rwxr-xr-xdjango/engagementmanager/service/vf_service.py47
-rwxr-xr-xdjango/engagementmanager/service/vfc_service.py112
-rwxr-xr-xdjango/engagementmanager/slack_client/__init__.py38
-rwxr-xr-xdjango/engagementmanager/slack_client/api.py212
-rwxr-xr-xdjango/engagementmanager/sql-scripts/generate_excel_overview_sheet_procedure.sql203
-rwxr-xr-xdjango/engagementmanager/templatetags/__init__.py38
-rwxr-xr-xdjango/engagementmanager/templatetags/vvptags.py48
-rwxr-xr-xdjango/engagementmanager/tests/__init__.py38
-rwxr-xr-xdjango/engagementmanager/tests/test_access_credentials.py175
-rwxr-xr-xdjango/engagementmanager/tests/test_activation.py173
-rwxr-xr-xdjango/engagementmanager/tests/test_activities.py125
-rwxr-xr-xdjango/engagementmanager/tests/test_add_contact.py141
-rwxr-xr-xdjango/engagementmanager/tests/test_add_feedback.py105
-rwxr-xr-xdjango/engagementmanager/tests/test_add_next_step_to_checklist.py157
-rwxr-xr-xdjango/engagementmanager/tests/test_audit_log_and_decision_api.py375
-rwxr-xr-xdjango/engagementmanager/tests/test_auth_service.py244
-rwxr-xr-xdjango/engagementmanager/tests/test_base_entity.py319
-rwxr-xr-xdjango/engagementmanager/tests/test_base_transaction_entity.py76
-rwxr-xr-xdjango/engagementmanager/tests/test_checklist.py177
-rwxr-xr-xdjango/engagementmanager/tests/test_checklist_template.py168
-rwxr-xr-xdjango/engagementmanager/tests/test_cms_documentation_search.py103
-rwxr-xr-xdjango/engagementmanager/tests/test_cms_pages.py135
-rwxr-xr-xdjango/engagementmanager/tests/test_cms_posts.py137
-rwxr-xr-xdjango/engagementmanager/tests/test_deployment_target_sites.py163
-rwxr-xr-xdjango/engagementmanager/tests/test_digest_email_notifications.py128
-rwxr-xr-xdjango/engagementmanager/tests/test_eng_progress.py99
-rwxr-xr-xdjango/engagementmanager/tests/test_eng_status.py161
-rwxr-xr-xdjango/engagementmanager/tests/test_engagement_admin_operations.py306
-rwxr-xr-xdjango/engagementmanager/tests/test_engagement_export.py161
-rwxr-xr-xdjango/engagementmanager/tests/test_expanded_eng.py325
-rwxr-xr-xdjango/engagementmanager/tests/test_import_engagement_xls.py72
-rwxr-xr-xdjango/engagementmanager/tests/test_invite_members.py164
-rwxr-xr-xdjango/engagementmanager/tests/test_next_steps.py80
-rwxr-xr-xdjango/engagementmanager/tests/test_next_steps_api.py367
-rwxr-xr-xdjango/engagementmanager/tests/test_notify_inactive_engagements.py232
-rwxr-xr-xdjango/engagementmanager/tests/test_pull_notifications.py134
-rwxr-xr-xdjango/engagementmanager/tests/test_rados_gateway.py178
-rwxr-xr-xdjango/engagementmanager/tests/test_remove_user_from_eng_team.py210
-rwxr-xr-xdjango/engagementmanager/tests/test_request_data_manager.py205
-rwxr-xr-xdjango/engagementmanager/tests/test_resend_activation_email.py62
-rwxr-xr-xdjango/engagementmanager/tests/test_reset_password.py75
-rwxr-xr-xdjango/engagementmanager/tests/test_rgwa_client.py214
-rwxr-xr-xdjango/engagementmanager/tests/test_set_checklist_state.py236
-rwxr-xr-xdjango/engagementmanager/tests/test_set_eng_stage.py207
-rwxr-xr-xdjango/engagementmanager/tests/test_update_password.py99
-rwxr-xr-xdjango/engagementmanager/tests/test_update_user_account.py119
-rwxr-xr-xdjango/engagementmanager/tests/test_vfc.py180
-rwxr-xr-xdjango/engagementmanager/tests/vvpEntitiesCreator.py290
-rwxr-xr-xdjango/engagementmanager/urls.py227
-rwxr-xr-xdjango/engagementmanager/utils/__init__.py65
-rwxr-xr-xdjango/engagementmanager/utils/activities_data.py116
-rwxr-xr-xdjango/engagementmanager/utils/authentication.py91
-rwxr-xr-xdjango/engagementmanager/utils/choice_enum.py56
-rwxr-xr-xdjango/engagementmanager/utils/constants.py211
-rwxr-xr-xdjango/engagementmanager/utils/cryptography.py61
-rwxr-xr-xdjango/engagementmanager/utils/dates.py51
-rwxr-xr-xdjango/engagementmanager/utils/exception_handler.py73
-rwxr-xr-xdjango/engagementmanager/utils/exception_message_factory.py92
-rwxr-xr-xdjango/engagementmanager/utils/request_data_mgr.py128
-rwxr-xr-xdjango/engagementmanager/utils/validator.py90
-rwxr-xr-xdjango/engagementmanager/utils/vvp_exceptions.py66
-rwxr-xr-xdjango/engagementmanager/views_helper.py347
-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
197 files changed, 26226 insertions, 0 deletions
diff --git a/django/engagementmanager/__init__.py b/django/engagementmanager/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/__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/admin.py b/django/engagementmanager/admin.py
new file mode 100755
index 0000000..38a63f8
--- /dev/null
+++ b/django/engagementmanager/admin.py
@@ -0,0 +1,380 @@
+#
+# ============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.contrib import admin
+
+from engagementmanager import models
+
+
+@admin.register(models.Activity)
+class ActivityModelAdmin(admin.ModelAdmin):
+
+ list_display = ["engagement_manual_id", "vf_name", "description",
+ "activity_type", "activity_owner", "create_time", "is_notification"]
+ list_filter = ["activity_type", "is_notification"]
+
+ def engagement_manual_id(self, obj):
+ if obj.engagement:
+ return obj.engagement.engagement_manual_id
+ else:
+ return ""
+
+ def vf_name(self, obj):
+ if obj.engagement:
+ return models.VF.objects.get(engagement=obj.engagement).name
+ else:
+ return ""
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj: # editing an existing object
+ return self.readonly_fields + ('create_time',)
+ return self.readonly_fields
+
+
+@admin.register(models.Checklist)
+class ChecklistModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "state", "engagement_manual_id", "vf_name", "validation_cycle",
+ "weight", "template", "owner", "creator", "associated_files", "create_time", "update_time"]
+ list_filter = ["template", "state"]
+ search_fields = ["name", "associated_files"]
+
+ def engagement_manual_id(self, obj):
+ return obj.engagement.engagement_manual_id
+
+ def vf_name(self, obj):
+ return models.VF.objects.get(engagement=obj.engagement).name
+
+
+@admin.register(models.ChecklistAuditLog)
+class ChecklistAuditLogModelAdmin(admin.ModelAdmin):
+
+ list_display = ["description", "creator", "checklist", "create_time", "update_time"]
+ list_filter = ["category"]
+ search_fields = ["description"]
+
+
+@admin.register(models.ChecklistDecision)
+class ChecklistDecisionModelAdmin(admin.ModelAdmin):
+
+ list_display = ["checklist", "lineitem", "review_value", "peer_review_value", "create_time", "update_time"]
+ list_filter = ["template"]
+ search_fields = ["name"]
+
+
+@admin.register(models.ChecklistLineItem)
+class ChecklistLineItemModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "weight", "template", "section", "create_time", "update_time"]
+ list_filter = ["template", "section"]
+ search_fields = ["name"]
+
+
+@admin.register(models.ChecklistSection)
+class ChecklistSectionModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "weight", "template", "parent_section", "create_time", "update_time"]
+ list_filter = ["template"]
+
+
+@admin.register(models.ChecklistTemplate)
+class ChecklistTemplateModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "category", "version", "create_time", "update_time"]
+ list_filter = ["category", "version"]
+ search_fields = ["name"]
+ search_fields = ["name"]
+
+
+@admin.register(models.DeploymentTarget)
+class DeploymentTargetModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "version"]
+ list_filter = ["version"]
+
+
+@admin.register(models.DeploymentTargetSite)
+class DeploymentTargetSiteModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name"]
+
+
+@admin.register(models.Engagement)
+class EngagementModelAdmin(admin.ModelAdmin):
+
+ list_display = ["engagement_manual_id", "vf_name", "deployment_target_name", "ecomp_release", "progress", "target_completion_date",
+ "target_lab_entry_date", "engagement_stage", "create_time"]
+ list_editable = ["progress", "target_completion_date", "engagement_stage"]
+ list_filter = ["engagement_stage"]
+ search_fields = ["engagement_stage", "engagement_manual_id"]
+
+ def vf_name(self, obj):
+ return models.VF.objects.get(engagement=obj).name
+
+ def target_lab_entry_date(self, obj):
+ return models.VF.objects.get(engagement=obj).target_lab_entry_date
+
+ def ecomp_release(self, obj):
+ return models.VF.objects.get(engagement=obj).ecomp_release
+
+ def deployment_target_name(self, obj):
+ e = models.VF.objects.get(engagement=obj)
+ return e.deployment_target.name + " " + e.deployment_target.version
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj: # editing an existing object
+ return self.readonly_fields + ('create_time',)
+ return self.readonly_fields
+
+
+@admin.register(models.EngagementStatus)
+class EngagementStatusModelAdmin(admin.ModelAdmin):
+
+ list_display = ["engagement_manual_id", "vf_name", "description", "creator_full_name", "create_time", "update_time"]
+ list_filter = ["creator"]
+ search_fields = ["description"]
+
+ def engagement_manual_id(self, obj):
+ return obj.engagement.engagement_manual_id
+
+ def vf_name(self, obj):
+ return models.VF.objects.get(engagement=obj.engagement).name
+
+ def creator_full_name(self, obj):
+ return obj.creator.full_name
+
+
+@admin.register(models.ECOMPRelease)
+class ECOMPReleaseModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name"]
+ search_fields = ["name"]
+
+
+@admin.register(models.IceUserProfile)
+class IceUserProfileModelAdmin(admin.ModelAdmin):
+
+ list_display = ["full_name", "email", "phone_number", "company_name", "role_name", "is_service_provider_contact", "has_ssh_key",
+ "create_time", "role"]
+ list_editable = ["phone_number", "is_service_provider_contact", "role"]
+ list_filter = ["is_service_provider_contact", "role", "company"]
+ search_fields = ["full_name", "email", "phone_number"]
+
+ def company_name(self, obj):
+ return obj.company.name
+
+ def role_name(self, obj):
+ return obj.role.name
+
+ def has_ssh_key(self, obj):
+ if obj.ssh_public_key:
+ return True
+ else:
+ return False
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj: # editing an existing object
+ return self.readonly_fields + ('create_time',)
+ return self.readonly_fields
+
+
+@admin.register(models.Invitation)
+class InvitationModelAdmin(admin.ModelAdmin):
+
+ list_display = ["email", "engagement_manual_id", "vf_name",
+ "invited_by_user", "accepted", "create_time", "invitation_token"]
+ list_filter = ["accepted"]
+ search_fields = ["email", "invitation_token"]
+
+ def invited_by_user(self, obj):
+ return models.IceUserProfile.objects.get(uuid=obj.invited_by_user_uuid).full_name
+
+ def engagement_manual_id(self, obj):
+ return models.Engagement.objects.get(uuid=obj.engagement_uuid).engagement_manual_id
+
+ def vf_name(self, obj):
+ e = models.Engagement.objects.get(uuid=obj.engagement_uuid)
+ return models.VF.objects.get(engagement=e).name
+
+
+@admin.register(models.NextStep)
+class NextStepModelAdmin(admin.ModelAdmin):
+
+ list_display = ["engagement_manual_id", "vf_name", "description", "files", "due_date", "last_updater_full_name", "last_update_time",
+ "last_update_type", "creator_full_name", "create_time", "state", "next_step_type", "owner_full_name"]
+ list_filter = ["next_step_type", "state"]
+ search_fields = ["description", "files"]
+
+ def engagement_manual_id(self, obj):
+ e = obj.engagement
+ if e:
+ return e.engagement_manual_id
+ else:
+ return ""
+
+ def vf_name(self, obj):
+ e = obj.engagement
+ if e:
+ return models.VF.objects.get(engagement=e).name
+ else:
+ return ""
+
+ def creator_full_name(self, obj):
+ c = obj.creator
+ if c:
+ return c.full_name
+ else:
+ return ""
+
+ def last_updater_full_name(self, obj):
+ lu = obj.last_updater
+ if lu:
+ return lu.full_name
+ else:
+ return ""
+
+ def owner_full_name(self, obj):
+ o = obj.owner
+ if o:
+ return o.full_name
+ else:
+ return ""
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj: # editing an existing object
+ return self.readonly_fields + ('state',)
+ return self.readonly_fields
+
+
+@admin.register(models.Notification)
+class NotificationModelAdmin(admin.ModelAdmin):
+
+ list_display = ["activity_description", "activity_type", "engagement_manual_id",
+ "vf_name", "is_sent", "is_read", "activity_create_time"]
+ list_filter = ["is_sent", "is_read"]
+
+ def activity_description(self, obj):
+ return obj.activity.description
+
+ def activity_type(self, obj):
+ return obj.activity.activity_type
+
+ def activity_create_time(self, obj):
+ return obj.activity.create_time
+
+ def engagement_manual_id(self, obj):
+ if obj.activity.engagement:
+ return obj.activity.engagement.engagement_manual_id
+ else:
+ return ""
+
+ def vf_name(self, obj):
+ if obj.activity.engagement:
+ return models.VF.objects.get(engagement=obj.activity.engagement).name
+ else:
+ return ""
+
+
+@admin.register(models.RecentEngagement)
+class RecentEngagementModelAdmin(admin.ModelAdmin):
+
+ list_display = ["engagement_manual_id", "vf_name", "ice_user", "action_type", "last_update"]
+ list_filter = ["action_type"]
+
+ def vf_name(self, obj):
+ return obj.vf.name
+
+ def engagement_manual_id(self, obj):
+ return obj.vf.engagement.engagement_manual_id
+
+ def ice_user(self, obj):
+ return models.IceUserProfile.objects.get(uuid=obj.user_uuid).full_name
+
+
+@admin.register(models.Role)
+class RoleModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name"]
+
+
+@admin.register(models.Vendor)
+class VendorModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "public"]
+ list_editable = ["public"]
+ search_fields = ["name"]
+
+
+@admin.register(models.VF)
+class VFModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "deployment_target", "ecomp_release", "progress", "target_completion_date",
+ "target_lab_entry_date", "is_service_provider_internal", "git_repo_url", "engagement_stage", "engagement_manual_id"]
+ list_filter = ["deployment_target", "ecomp_release", "is_service_provider_internal", "vendor"]
+ list_editable = ["is_service_provider_internal"]
+ search_fields = ["name", "git_repo_url"]
+
+ def engagement_manual_id(self, obj):
+ return obj.engagement.engagement_manual_id
+
+ def progress(self, obj):
+ return obj.engagement.progress
+
+ def target_completion_date(self, obj):
+ return obj.engagement.target_completion_date
+
+ def engagement_stage(self, obj):
+ return obj.engagement.engagement_stage
+
+
+@admin.register(models.VFC)
+class VFCModelAdmin(admin.ModelAdmin):
+
+ list_display = ["name", "external_ref_id", "ice_mandated", "vf_name", "company_name", "engagement_manual_id"]
+ list_filter = ["ice_mandated", "company"]
+ list_editable = ["external_ref_id", "ice_mandated"]
+ search_fields = ["name", "external_ref_id"]
+
+ def vf_name(self, obj):
+ return obj.vf.name
+
+ def engagement_manual_id(self, obj):
+ return obj.vf.engagement.engagement_manual_id
+
+ def company_name(self, obj):
+ return obj.company.name
diff --git a/django/engagementmanager/apps.py b/django/engagementmanager/apps.py
new file mode 100755
index 0000000..e4a967d
--- /dev/null
+++ b/django/engagementmanager/apps.py
@@ -0,0 +1,96 @@
+#
+# ============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.apps import AppConfig
+from django.conf import settings
+from engagementmanager.scheduled_jobs import ScheduledJobs
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+cms_client = None
+bus_service = None
+
+
+class EngagementmanagerConfig(AppConfig):
+ name = 'engagementmanager'
+ verbose_name = "engagementmanager"
+
+ def ready(self):
+ # This otherwise unused import causes the signal receivers
+ # to register themselves at the appropriate time. Do not remove.
+ import engagementmanager.vm_integration.em_api
+ ###############################
+ # Bootstrap Actions #
+ ###############################
+ from engagementmanager.utils.constants import Constants
+ logger = LoggingServiceFactory.get_logger()
+
+ if (settings.DOMAIN == Constants.prodDomain):
+ logger.info("--Production Mode--")
+ else:
+ logger.info("--Development Mode--")
+
+ from engagementmanager.cms_client.api import CMSClient
+ global cms_client
+ cms_client = CMSClient()
+ global bus_service
+ from engagementmanager.service.bus_service import BusService
+ bus_service = BusService()
+ self.__register_bus_service_handlers()
+
+ ice_scheduler = ScheduledJobs(bus_service)
+ ice_scheduler.setup_daily_job()
+ ice_scheduler.setup_hourly_job()
+
+ def __register_bus_service_handlers(self):
+ from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+ from engagementmanager.bus.messages.daily_scheduled_message import DailyScheduledMessage
+ from engagementmanager.bus.messages.new_notification_message import NewNotificationMessage
+ from engagementmanager.bus.handlers.activity_event_handler import ActivityEventHandler
+ from engagementmanager.bus.handlers.daily_resend_notifications_handler import DailyResendNotificationsHandler
+ from engagementmanager.bus.handlers.digest_email_notification_handler import DigestEmailNotificationHandler
+ from engagementmanager.bus.handlers.new_notification_handler import NewNotificationHandler
+ from engagementmanager.bus.messages.hourly_scheduled_message import HourlyScheduledMessage
+ from engagementmanager.bus.handlers.check_news_and_announcements_handler import CheckNewsAndAnnouncementsHandler
+ from engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler import DailyNotifyInactiveEngagementsHandler
+
+ bus_service.register(ActivityEventHandler(), ActivityEventMessage)
+ bus_service.register(NewNotificationHandler(), NewNotificationMessage)
+ bus_service.register(DigestEmailNotificationHandler(), DailyScheduledMessage)
+ bus_service.register(DailyResendNotificationsHandler(), DailyScheduledMessage)
+ bus_service.register(DailyNotifyInactiveEngagementsHandler(), DailyScheduledMessage)
+ bus_service.register(CheckNewsAndAnnouncementsHandler(), HourlyScheduledMessage)
diff --git a/django/engagementmanager/bus/__init__.py b/django/engagementmanager/bus/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/bus/__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/bus/handlers/__init__.py b/django/engagementmanager/bus/handlers/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/__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/bus/handlers/activity_event_handler.py b/django/engagementmanager/bus/handlers/activity_event_handler.py
new file mode 100755
index 0000000..d5ef819
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/activity_event_handler.py
@@ -0,0 +1,52 @@
+#
+# ============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 engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.service.activities_service import ActivitiesSvc
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class ActivityEventHandler(ServiceBusBaseHandler):
+ activities_service = ActivitiesSvc()
+
+ def handle_message(self, bus_message):
+ logger.info("New ICE event from type '%s' arrived, activity will be generated." %
+ bus_message.activity_data.activity_type.name)
+ self.activities_service.generate_activity(bus_message.activity_data)
diff --git a/django/engagementmanager/bus/handlers/check_news_and_announcements_handler.py b/django/engagementmanager/bus/handlers/check_news_and_announcements_handler.py
new file mode 100755
index 0000000..6ef4fdb
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/check_news_and_announcements_handler.py
@@ -0,0 +1,49 @@
+#
+# ============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 engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class CheckNewsAndAnnouncementsHandler(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.debug("New hourly scheduled message arrived, will check for news and announcements and send notification"
+ " if needed.")
+ pass
diff --git a/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements.py b/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements.py
new file mode 100755
index 0000000..598b977
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements.py
@@ -0,0 +1,93 @@
+#
+# ============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.db.models.query_utils import Q
+from django.utils import timezone
+from django.utils.timezone import timedelta
+from engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.models import Engagement, VF
+from engagementmanager.service.activities_service import ActivitiesSvc
+from engagementmanager.service.checklist_service import CheckListSvc
+from engagementmanager.service.engagement_service import archive_engagement
+from engagementmanager.utils.constants import EngagementStage
+from engagementmanager.utils.activities_data import NoticeEmptyEngagementData
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class DailyNotifyInactiveEngagements(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.debug("New digest bus message arrived - email is about to sent")
+ checklist_service = CheckListSvc()
+ engagements_list = Engagement.objects.filter(is_with_files=False, Q(engagement_stage=EngagementStage.Active.name) | Q(engagement_stage=EngagementStage.Intake.name))
+
+ for engagement in engagements_list:
+ files_found = checklist_service.getEngagementFiles(engagement.uuid)
+ if files_found:
+ engagement.is_with_files = True
+ engagement.save()
+ continue
+
+ max_empty_time = self.get_max_empty_date(engagement.create_time)
+
+ if max_empty_time < timezone.now():
+ archive_engagement(engagement.uuid, "More than 30 days passed and no files added to gitlab yet")
+ else:
+ self.send_emails_logic(engagement)
+
+ @staticmethod
+ def get_max_empty_date(creation_time):
+ return creation_time + timedelta(days=30)
+
+ @staticmethod
+ def get_days_delta(start_time, end_time):
+ return (end_time - start_time).days
+
+ def send_emails_logic(self, engagement):
+
+ delta_days_from_creation = self.get_days_delta(engagement.create_time, timezone.now())
+ alert_days = [7, 14, 21]
+ if (delta_days_from_creation in alert_days) or (delta_days_from_creation >= 23 and delta_days_from_creation < 30):
+ vf = VF.objects.get(engagement=engagement)
+ vf_name = vf.name
+ max_empty_time = self.get_max_empty_date(engagement.create_time).strftime('%b %d, %Y')
+ git_repo_url = vf.git_repo_url
+ activity_data = NoticeEmptyEngagementData(
+ vf_name, max_empty_time, git_repo_url, str(delta_days_from_creation), engagement)
+ ActivitiesSvc().generate_activity(activity_data)
diff --git a/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements_handler.py b/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements_handler.py
new file mode 100755
index 0000000..12acea1
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/daily_notify_inactive_engagements_handler.py
@@ -0,0 +1,90 @@
+#
+# ============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.utils import timezone
+from django.utils.timezone import timedelta
+from engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.models import Engagement, VF
+from engagementmanager.service.activities_service import ActivitiesSvc
+from engagementmanager.service.checklist_service import CheckListSvc
+from engagementmanager.service.engagement_service import archive_engagement
+from engagementmanager.utils.constants import EngagementStage
+from engagementmanager.utils.activities_data import NoticeEmptyEngagementData
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class DailyNotifyInactiveEngagementsHandler(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.debug("New digest bus message arrived - email is about to sent")
+ checklist_service = CheckListSvc()
+ engagements_list = Engagement.objects.filter(is_with_files=False, engagement_stage=EngagementStage.Active.name)
+
+ for engagement in engagements_list:
+ files_found = checklist_service.getEngagementFiles(engagement.uuid)
+ if files_found:
+ engagement.is_with_files = True
+ engagement.save()
+ continue
+
+ max_empty_time = self.get_max_empty_date(engagement.create_time)
+
+ if max_empty_time < timezone.now():
+ archive_engagement(engagement.uuid, "More than 30 days passed and no files added to gitlab yet")
+ else:
+ self.send_emails_logic(engagement)
+
+ def get_max_empty_date(self, creation_time):
+ return creation_time + timedelta(days=30)
+
+ def get_days_delta(self, start_time, end_time):
+ return (end_time - start_time).days
+
+ def send_emails_logic(self, engagement):
+
+ delta_days_from_creation = self.get_days_delta(engagement.create_time, timezone.now())
+ alert_days = [7, 14, 21]
+ if (delta_days_from_creation in alert_days) or (delta_days_from_creation >= 23 and delta_days_from_creation < 30):
+ vf = VF.objects.get(engagement=engagement)
+ vf_name = vf.name
+ max_empty_time = self.get_max_empty_date(engagement.create_time).strftime('%b %d, %Y')
+ git_repo_url = vf.git_repo_url
+ activity_data = NoticeEmptyEngagementData(
+ vf_name, max_empty_time, git_repo_url, str(delta_days_from_creation), engagement)
+ ActivitiesSvc().generate_activity(activity_data)
diff --git a/django/engagementmanager/bus/handlers/daily_resend_notifications_handler.py b/django/engagementmanager/bus/handlers/daily_resend_notifications_handler.py
new file mode 100755
index 0000000..9919cad
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/daily_resend_notifications_handler.py
@@ -0,0 +1,75 @@
+#
+# ============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.template.loader import get_template
+from engagementmanager import mail
+from engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.mail import sendMail
+from engagementmanager.models import Notification
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class DailyResendNotificationsHandler(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.debug("New resend notifications message arrived - emails is about to sent to the "
+ "all unsent notifications")
+ unsent_notifications = Notification.objects.filter(is_sent=False)
+ for notification in unsent_notifications:
+ if notification.user.email_updates_on_every_notification:
+ try:
+ subject_template = get_template("{notification_template_dir}notification_mail_subject.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+ msg_template = get_template("{notification_template_dir}notification_mail_body.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+
+ sendMail(notification.user.email, json.loads(notification.activity.metadata),
+ msg_template, subject_template, mail_from=mail.ice_admin_mail_from)
+ notification.is_sent = True
+ notification.save()
+ except Exception as e:
+ msg = "Something went wrong while trying to resend bulk mail " \
+ "as part of the notifications daily resend"
+ logger.error(msg + " " + e)
+ else:
+ notification.is_sent = True
+ notification.save()
+ logger.info("User choose not to get email on every notification, set it as sent.")
diff --git a/django/engagementmanager/bus/handlers/digest_email_notification_handler.py b/django/engagementmanager/bus/handlers/digest_email_notification_handler.py
new file mode 100755
index 0000000..7f5cb6b
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/digest_email_notification_handler.py
@@ -0,0 +1,74 @@
+#
+# ============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 datetime import datetime
+from django.template.loader import get_template
+from engagementmanager import mail
+from engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from engagementmanager.mail import sendMail
+from engagementmanager.models import Notification, IceUserProfile
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class DigestEmailNotificationHandler(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.debug("New digest bus message arrived - email is about to sent")
+ today = datetime.now().date()
+ users = Notification.objects.filter(activity__create_time__gte=today).values("user").distinct()
+
+ for user in users:
+ user = IceUserProfile.objects.get(id=user['user'])
+
+ if user.email_updates_daily_digest:
+ notifications = Notification.objects.filter(activity__create_time__gte=today, user=user)
+ try:
+ subject_template = get_template("{notification_template_dir}"
+ "notification_digest_mail_subject.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+ msg_template = get_template("{notification_template_dir}"
+ "notification_digest_mail_body.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+
+ sendMail(user.email, notifications.values(),
+ msg_template, subject_template, mail_from=mail.ice_admin_mail_from)
+ except Exception as e:
+ msg = "Something went wrong while trying to send bulk mail as part of the digest notifications"
+ logger.error(msg)
diff --git a/django/engagementmanager/bus/handlers/new_notification_handler.py b/django/engagementmanager/bus/handlers/new_notification_handler.py
new file mode 100755
index 0000000..00491fa
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/new_notification_handler.py
@@ -0,0 +1,74 @@
+#
+# ============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 engagementmanager import mail
+from engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+from django.template.loader import get_template
+from engagementmanager.mail import sendMail
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class NewNotificationHandler(ServiceBusBaseHandler):
+ def handle_message(self, bus_message):
+ logger.info("New notification (%s) arrived - email will sent" %
+ bus_message.notification.uuid)
+
+ user = bus_message.notification.user
+ if user.email_updates_on_every_notification:
+ try:
+ subject_template = get_template("{notification_template_dir}notification_mail_subject.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+ msg_template = get_template("{notification_template_dir}notification_mail_body.html".format(
+ notification_template_dir=Constants.notification_template_dir))
+
+ sendMail(user.email, json.loads(bus_message.notification.activity.metadata),
+ msg_template, subject_template, mail_from=mail.ice_admin_mail_from)
+ bus_message.notification.is_sent = True
+ bus_message.notification.save()
+ except Exception as e:
+ msg = "Something went wrong while trying to send bulk mail as part of the notification"
+ logger.error(msg + " " + str(e))
+ else:
+ bus_message.notification.is_sent = True
+ bus_message.notification.save()
+ logger.info("User choose not to get email on every notification, set it as sent.")
diff --git a/django/engagementmanager/bus/handlers/service_bus_base_handler.py b/django/engagementmanager/bus/handlers/service_bus_base_handler.py
new file mode 100755
index 0000000..7b4a83b
--- /dev/null
+++ b/django/engagementmanager/bus/handlers/service_bus_base_handler.py
@@ -0,0 +1,54 @@
+#
+# ============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 abc import ABCMeta, abstractmethod
+
+from engagementmanager.bus.messages.service_bus_base_message import ServiceBusBaseMessage
+from engagementmanager.utils.vvp_exceptions import VvpGeneralException
+
+
+class ServiceBusBaseHandler:
+ __metaclass__ = ABCMeta
+
+ def validate_message(self, bus_message):
+ if not issubclass(type(bus_message), ServiceBusBaseMessage):
+ raise VvpGeneralException("You can't handle message which is not from type of ServiceBusBaseMessage")
+
+ @abstractmethod
+ def handle_message(self, bus_message):
+ pass
diff --git a/django/engagementmanager/bus/messages/__init__.py b/django/engagementmanager/bus/messages/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/bus/messages/__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/bus/messages/activity_event_message.py b/django/engagementmanager/bus/messages/activity_event_message.py
new file mode 100755
index 0000000..67bf319
--- /dev/null
+++ b/django/engagementmanager/bus/messages/activity_event_message.py
@@ -0,0 +1,49 @@
+#
+# ============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 engagementmanager.bus.messages.service_bus_base_message import ServiceBusBaseMessage
+from engagementmanager.utils.activities_data import ActivityData
+from engagementmanager.utils.vvp_exceptions import VvpGeneralException
+
+
+class ActivityEventMessage(ServiceBusBaseMessage):
+ def __init__(self, activity_data):
+ if not issubclass(type(activity_data), ActivityData):
+ raise VvpGeneralException("Activity data can be from type ActivityData only.")
+
+ self.activity_data = activity_data
diff --git a/django/engagementmanager/bus/messages/daily_scheduled_message.py b/django/engagementmanager/bus/messages/daily_scheduled_message.py
new file mode 100755
index 0000000..41941e8
--- /dev/null
+++ b/django/engagementmanager/bus/messages/daily_scheduled_message.py
@@ -0,0 +1,44 @@
+#
+# ============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 engagementmanager.bus.messages.service_bus_base_message import ServiceBusBaseMessage
+
+
+class DailyScheduledMessage(ServiceBusBaseMessage):
+ def __init__(self):
+ pass
diff --git a/django/engagementmanager/bus/messages/hourly_scheduled_message.py b/django/engagementmanager/bus/messages/hourly_scheduled_message.py
new file mode 100755
index 0000000..8c733bf
--- /dev/null
+++ b/django/engagementmanager/bus/messages/hourly_scheduled_message.py
@@ -0,0 +1,44 @@
+#
+# ============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 engagementmanager.bus.messages.service_bus_base_message import ServiceBusBaseMessage
+
+
+class HourlyScheduledMessage(ServiceBusBaseMessage):
+ def __init__(self):
+ pass
diff --git a/django/engagementmanager/bus/messages/new_notification_message.py b/django/engagementmanager/bus/messages/new_notification_message.py
new file mode 100755
index 0000000..ce4ce06
--- /dev/null
+++ b/django/engagementmanager/bus/messages/new_notification_message.py
@@ -0,0 +1,49 @@
+#
+# ============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 engagementmanager.bus.messages.service_bus_base_message import ServiceBusBaseMessage
+from engagementmanager.models import Notification
+from engagementmanager.utils.vvp_exceptions import VvpGeneralException
+
+
+class NewNotificationMessage(ServiceBusBaseMessage):
+ def __init__(self, notification):
+ if type(notification) is not Notification:
+ raise VvpGeneralException("New notification event can be from type Notification only.")
+
+ self.notification = notification
diff --git a/django/engagementmanager/bus/messages/service_bus_base_message.py b/django/engagementmanager/bus/messages/service_bus_base_message.py
new file mode 100755
index 0000000..3f97a0d
--- /dev/null
+++ b/django/engagementmanager/bus/messages/service_bus_base_message.py
@@ -0,0 +1,46 @@
+#
+# ============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 abc import ABCMeta
+
+
+class ServiceBusBaseMessage:
+ __metaclass__ = ABCMeta
+
+ def __init__(self):
+ pass
diff --git a/django/engagementmanager/cms_client/__init__.py b/django/engagementmanager/cms_client/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/cms_client/__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/cms_client/api.py b/django/engagementmanager/cms_client/api.py
new file mode 100755
index 0000000..a0ca5b1
--- /dev/null
+++ b/django/engagementmanager/cms_client/api.py
@@ -0,0 +1,159 @@
+#
+# ============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.conf import settings
+from oauthlib.oauth2 import BackendApplicationClient, TokenExpiredError
+from requests_oauthlib import OAuth2Session
+from rest_framework.status import HTTP_401_UNAUTHORIZED
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class CMSClient(object):
+ """
+ ICE CMS (Mezzanine) API Client SDK
+ """
+
+ def __init__(self):
+ """
+ Ice CMS client constructor ->
+ :param MZN_ID: from env vars.
+ :param MZN_Secret: from env vars.
+ """
+ super(CMSClient, self).__init__()
+
+ self.client_id = settings.CMS_APP_CLIENT_ID
+ self.client_secret = settings.CMS_APP_CLIENT_SECRET
+ self.api_url = settings.CMS_URL
+ self.token = self.generateToken(self.client_id, self.client_secret)
+ self.session = OAuth2Session(self.client_id, token=self.token)
+
+ # PROBLEM TO REMOVE TRY AND CATCH
+ def generateToken(self, client_id, client_secret):
+ """
+ Create oauth2 token by id and secret (via cms server)
+ :param client_id: client id (from env vars)
+ :param client_secret: client secret (from env vars)
+ :return: return the result token.
+ """
+ token = None
+
+ try:
+ client = BackendApplicationClient(client_id=client_id)
+ oatuh = OAuth2Session(client=client)
+ token = oatuh.fetch_token(token_url=self.api_url + 'oauth2/token/', client_id=client_id,
+ client_secret=client_secret)
+ except Exception as exception:
+ logger.error(
+ 'Could not create CMS token, error message: ' + str(exception))
+
+ return token
+
+ @staticmethod
+ def json_serialize(obj):
+ """
+ Returns JSON serialization of object
+ """
+ return json.dumps(obj)
+
+ @staticmethod
+ def json_deserialize(string):
+ """
+ Returns deserialization of JSON
+ """
+ return json.loads(string)
+
+ def get(self, resource, params=None):
+ """
+ Make a GET HTTP request
+ """
+ response = None
+ try:
+ response = self.session.get(self.api_url + resource, params=params)
+ if response.status_code == HTTP_401_UNAUTHORIZED:
+ logger.error('Token expired (401 status excepted), will renew cms token now')
+ self.__init__()
+ response = self.session.get(self.api_url + resource, params=params)
+ except TokenExpiredError as exception:
+ logger.error('Token expired (TokenExpiredError exception excepted),'
+ ' will renew cms token now: ' + str(exception))
+ self.__init__()
+ response = self.session.get(self.api_url + resource, params=params)
+ item = self.json_deserialize(response.content.decode('utf-8'))
+ return item
+
+ def get_posts(self, offset=0, limit=10, category="", date_min=""):
+ """
+ Get published blog posts
+ :param date_min: all the posts returned will be after this date
+ :param offset: pagination offset
+ :param limit: pagination limit
+ :param category: the category which the post related to
+ :param limit: date_min of posts to return
+ :return: list of dicts for most recently published blog posts
+ """
+ return self.get('posts?offset={}&limit={}&category_name={}&date_min={}'.format(int(offset), int(limit),
+ category, date_min))['results']
+
+ def get_pages(self, title=""):
+ """
+ Get all pages and it's children.
+ :param title: The title of the page we want
+ :return: list of pages by out filters declaration
+ """
+ return self.get('pages?title={}'.format(title))['results']
+
+ def get_page(self, id):
+ """
+ Return specific page by id
+ :param id: The id of the page we want to require
+ :return: the page result
+ """
+ return self.get('pages/{}'.format(int(id)))
+
+ def search_pages(self, keyword):
+ """
+ Return pages by keyword contained in title or content
+ :param keyword: The keyword which will be searched in title and content
+ :return: the pages as result
+ """
+
+ return self.get('pages/search/?keyword={}'.format(keyword))
diff --git a/django/engagementmanager/decorator/__init__.py b/django/engagementmanager/decorator/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/decorator/__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/decorator/auth.py b/django/engagementmanager/decorator/auth.py
new file mode 100755
index 0000000..686a8cc
--- /dev/null
+++ b/django/engagementmanager/decorator/auth.py
@@ -0,0 +1,103 @@
+#
+# ============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 traceback
+import bleach
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.status import HTTP_401_UNAUTHORIZED, \
+ HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR
+from engagementmanager.service.authorization_service import AuthorizationService
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def auth(action, is_internal=False):
+ """
+ Check that given action is permitted by the user
+ """
+ def _dec(func):
+ def _new_func(*args, **kwargs):
+ auth_service = AuthorizationService()
+
+ # Extract USER - A MUST Have in KWARGS #
+ user = request_data_mgr.get_user()
+ if user == None:
+ msg = "user couldn't be identified in the request"
+ logger.error(msg)
+ if (is_internal == True):
+ return msg, HTTP_400_BAD_REQUEST
+ return Response(msg, status=status.HTTP_400_BAD_REQUEST)
+
+ checklist_uuid = request_data_mgr.get_cl_uuid()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+
+ try:
+ result = None
+ message = None
+ result, message = auth_service.is_user_able_to(user, action, eng_uuid, checklist_uuid)
+ logger.debug('Authorization Service : ' + action.name +
+ '. Result=' + str(result) + '. message=' + str(message))
+ if result == False:
+ msg = "User not authorized: " + \
+ str(user.uuid) + ". eng_uuid=" + str(eng_uuid) + ". checklist_uuid=" + str(checklist_uuid)
+ if (is_internal == True):
+ return msg, HTTP_401_UNAUTHORIZED
+ msg = bleach.clean(msg, tags=['a', 'b'])
+ return Response(msg, status=status.HTTP_401_UNAUTHORIZED)
+
+ except Exception as e:
+ logger.error("=====================Exception=====================")
+ msg = "A problem occurred while trying to authorize user.uuid= " + \
+ str(user.uuid) + ". eng_uuid=" + str(eng_uuid) + \
+ ". checklist_uuid=" + str(checklist_uuid) + "action=" + str(action)
+ logger.error(str(e) + " Message: " + msg)
+ logger.error(traceback.format_exc())
+ logger.error("===================================================")
+
+ if (is_internal == True):
+ return msg, HTTP_500_INTERNAL_SERVER_ERROR
+ msg = "Action was failed to be performed"
+ return Response(msg, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return func(*args, **kwargs)
+
+ return _new_func
+
+ return _dec
diff --git a/django/engagementmanager/decorator/class_decorator.py b/django/engagementmanager/decorator/class_decorator.py
new file mode 100755
index 0000000..362e473
--- /dev/null
+++ b/django/engagementmanager/decorator/class_decorator.py
@@ -0,0 +1,47 @@
+#
+# ============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.
+def classDecorator(decorators):
+ def decorate(cls):
+ for attr in cls.__dict__:
+ if callable(getattr(cls, attr)):
+ for ice_decorator in decorators:
+ if (attr in ["get", "put", "post", "delete", "entity_list", "entity_detail", "set_attr"]):
+ setattr(cls, attr, ice_decorator(getattr(cls, attr)))
+ return cls
+ return decorate
diff --git a/django/engagementmanager/decorator/log_func_entry.py b/django/engagementmanager/decorator/log_func_entry.py
new file mode 100755
index 0000000..1e7d840
--- /dev/null
+++ b/django/engagementmanager/decorator/log_func_entry.py
@@ -0,0 +1,50 @@
+#
+# ============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 functools import wraps
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def logFuncEntry(func):
+ @wraps(func)
+ def log(*args, **kwargs):
+ logger.debug('calling {}'.format(func.__name__) + " | " + str(args) + " | " + str(kwargs))
+ return func(*args, **kwargs)
+ return log
diff --git a/django/engagementmanager/decorator/retry.py b/django/engagementmanager/decorator/retry.py
new file mode 100755
index 0000000..d0c15c1
--- /dev/null
+++ b/django/engagementmanager/decorator/retry.py
@@ -0,0 +1,52 @@
+#
+# ============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.
+"""This module provides retry_connection, a simple wrapper around retrying.retry, for our most
+common use case.
+
+"""
+
+from requests.exceptions import Timeout, ConnectionError
+from retrying import retry
+
+
+def is_connection_exception(exception):
+ return isinstance(exception, (ConnectionError, Timeout))
+
+
+retry_connection = retry(stop_max_attempt_number=2, retry_on_exception=is_connection_exception)
diff --git a/django/engagementmanager/git/__init__.py b/django/engagementmanager/git/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/git/__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/git/git_manager.py b/django/engagementmanager/git/git_manager.py
new file mode 100755
index 0000000..4bc8de0
--- /dev/null
+++ b/django/engagementmanager/git/git_manager.py
@@ -0,0 +1,52 @@
+#
+# ============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 engagementmanager.models import VF
+from engagementmanager.vm_integration.vm_client import \
+ send_get_list_of_repo_files_event
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+class GitManager(object):
+ def getRepoAssociatedFilesForUser(self, eng_uuid):
+ logger.debug("Fetching the repo associated files for engagement " +
+ eng_uuid)
+ vf = VF.objects.get(engagement__uuid=eng_uuid)
+ fileList = send_get_list_of_repo_files_event(vf)
+ return fileList
diff --git a/django/engagementmanager/http_client.py b/django/engagementmanager/http_client.py
new file mode 100755
index 0000000..c4c8afd
--- /dev/null
+++ b/django/engagementmanager/http_client.py
@@ -0,0 +1,54 @@
+#
+# ============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 http.client import HTTPSConnection
+
+
+class HttpClient(HTTPSConnection):
+ '''
+ classdocs
+ '''
+
+ def __init__(self, protocol, host, port, params=None):
+ if (protocol == 'HTTP'):
+ self.conn = self.HTTPConnection(host, port)
+ else: # SSL
+ self.conn = HTTPSConnection(host, port)
+
+ def getConn(self):
+ return self.conn
diff --git a/django/engagementmanager/mail.py b/django/engagementmanager/mail.py
new file mode 100755
index 0000000..10279b9
--- /dev/null
+++ b/django/engagementmanager/mail.py
@@ -0,0 +1,71 @@
+#
+# ============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.core.mail import send_mail, send_mass_mail
+
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.constants import TemplatesConstants
+
+ice_admin_mail_from = settings.CONTACT_FROM_ADDRESS
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def sendMail(email, data, mail_body_template, mail_subject_template, mail_from=ice_admin_mail_from):
+ logger.debug("about to send mail to " + email)
+ if data is None:
+ data = {}
+ data.update(TemplatesConstants.context)
+ html_msg = mail_body_template.render(context=data)
+ mail_subject = mail_subject_template.render(context=data)
+ # send mail with template
+ send_mail(mail_subject, '', "D2 ICE Team <" + mail_from + ">", [email], fail_silently=False, html_message=html_msg)
+ logger.debug("Looks like email delivery to " + email + " has succeeded")
+
+
+def sendBulkMail(datatuple):
+ logger.debug("about to send mail")
+
+ try:
+ num_sent = send_mass_mail(datatuple)
+ logger.debug("Looks like email delivery has succeeded. Number of sent mails is " + str(num_sent))
+ return num_sent
+ except Exception as e: # Dont remove try-except since it is invoked from Notification Bot
+ logger.error("Email delivery has failed. Error is: " + str(e))
+ raise e
diff --git a/django/engagementmanager/management/__init__.py b/django/engagementmanager/management/__init__.py
new file mode 100755
index 0000000..36beacd
--- /dev/null
+++ b/django/engagementmanager/management/__init__.py
@@ -0,0 +1,39 @@
+#
+# ============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/management/commands/__init__.py b/django/engagementmanager/management/commands/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/management/commands/__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/management/commands/clean_gitlab_content.py b/django/engagementmanager/management/commands/clean_gitlab_content.py
new file mode 100755
index 0000000..5299367
--- /dev/null
+++ b/django/engagementmanager/management/commands/clean_gitlab_content.py
@@ -0,0 +1,103 @@
+#
+# ============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.
+""" clean_gitlab_content
+Will delete content from gitlab to create initial environment:
+1.Projects
+2.Groups
+3.Users
+
+This command uses gitlab client rest api to remove data.
+This command is part of clean_vvp_system command but can be used separately as well.
+
+WARNING: It will delete almost everything, if you have necessary data DO NOT USE THIS COMMAND!
+"""
+from django.conf import settings
+from django.core.management.base import BaseCommand
+import requests
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ logger.info("***************************************")
+ logger.info(">>git-lab is about to be cleaned up!")
+ logger.info("***************************************")
+
+ entities = ['projects', 'groups', 'users', ]
+ headers = dict()
+ headers['Content-type'] = 'application/json'
+ headers['PRIVATE-TOKEN'] = settings.GITLAB_TOKEN
+
+ for entity in entities:
+ entities_deleted = []
+ gitlab_entity_url = settings.GITLAB_URL + "api/v3/%s/" % entity
+ r1 = requests.get(gitlab_entity_url, headers=headers, verify=False)
+ data = r1.json()
+
+ while len(data) > 1:
+ for record in data:
+ try:
+ if record['id'] not in entities_deleted \
+ and record['name'] != 'Administrator':
+ r2 = requests.delete(gitlab_entity_url +
+ str(record['id']),
+ headers=headers, verify=False)
+ logger.info("Entity '%s' with id %s Will be deleted"
+ " in a bit (type: %s)" % (
+ record['name'],
+ record['id'], entity,))
+
+ entities_deleted.append(record['id'])
+ except Exception as e:
+ logger.error("Some problem occurred... We give it "
+ "another shot...", e)
+
+ r1 = requests.get(gitlab_entity_url, headers=headers,
+ verify=False)
+ data = r1.json()
+
+ logger.info("***************************************")
+ logger.info(">>>>All %s deleted from git-lab" % entity)
+ logger.info("***************************************")
+
+ logger.info("***************************************")
+ logger.info(">>git-lab is now clean!")
+ logger.info("***************************************")
diff --git a/django/engagementmanager/management/commands/clean_jenkins_jobs.py b/django/engagementmanager/management/commands/clean_jenkins_jobs.py
new file mode 100755
index 0000000..c19f28d
--- /dev/null
+++ b/django/engagementmanager/management/commands/clean_jenkins_jobs.py
@@ -0,0 +1,73 @@
+#
+# ============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.
+""" clean_jenkins_jobs
+Will delete content(jobs) from jenkins to create initial environment.
+
+This command uses jenkins_client api to remove data.
+This command is part of clean_vvp_system command but can be used separately as well.
+
+WARNING: It will delete almost everything, if you have necessary data DO NOT USE THIS COMMAND!
+"""
+from validationmanager.utils.clients import get_jenkins_client
+from django.core.management.base import BaseCommand
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ logger.info("***************************************")
+ logger.info(">>Jenkins is about to be cleaned up!")
+ logger.info("***************************************")
+
+ try:
+ jenkins_client = get_jenkins_client()
+ job_names = jenkins_client.get_jobs_names()
+
+ for job_name in job_names:
+ jenkins_client.delete_job(job_name)
+ logger.info("Jenkins job '%s' deleted successfully." % job_name)
+ except Exception as e:
+ logger.error("Some problem occurred while trying "
+ "cleaning Jenkins...", e)
+
+ logger.info("***************************************")
+ logger.info(">>Jenkins is now clean!")
+ logger.info("***************************************")
diff --git a/django/engagementmanager/management/commands/clean_vvp_db.py b/django/engagementmanager/management/commands/clean_vvp_db.py
new file mode 100755
index 0000000..931f684
--- /dev/null
+++ b/django/engagementmanager/management/commands/clean_vvp_db.py
@@ -0,0 +1,96 @@
+#
+# ============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.
+""" clean_vvp_db
+Will delete content from database (almost all entities) to create initial environment.
+
+This command uses django orm to remove data.
+This command is part of clean_vvp_system command but can be used separately as well.
+
+WARNING: It will delete almost everything, if you have necessary data DO NOT USE THIS COMMAND!
+"""
+from django.core.management.base import BaseCommand
+from engagementmanager import models
+from engagementmanager.management.commands.initial_populate_db import admin_dummy_users, admin_ro_dummy_users, \
+ dummy_users, el_dummy_users
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.constants import Constants
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ logger.info("***************************************")
+ logger.info(">>%s db is about to be cleaned up!" % Constants.program_name)
+ logger.info("***************************************")
+
+ excluded_emails = [dummy_users[0][1], dummy_users[1][1],
+ el_dummy_users[0][1], el_dummy_users[1][1],
+ admin_dummy_users[0][1], admin_ro_dummy_users[0][1], ]
+
+ try:
+ models.EngagementStatus.objects.all().delete()
+ models.Invitation.objects.all().delete()
+ models.Notification.objects.all().delete()
+ models.Activity.objects.all().delete()
+ models.NextStep.objects.all().delete()
+ models.ChecklistAuditLog.objects.all().delete()
+ models.ChecklistDecision.objects.all().delete()
+ models.Checklist.objects.all().delete()
+ models.ChecklistLineItem.objects.all().delete()
+ models.ChecklistSection.objects.all().delete()
+ models.ChecklistTemplate.objects.all().delete()
+ models.RecentEngagement.objects.all().delete()
+ models.VFC.objects.all().delete()
+ models.VF.objects.all().delete()
+ models.EngagementStatus.objects.all().delete()
+ models.Engagement.objects.all().delete()
+ models.IceUserProfile.objects.exclude(email__in=excluded_emails)\
+ .delete()
+ models.CustomUser.objects.exclude(user_ptr_id__in=models.IceUserProfile.objects.all().values('id')).delete()
+
+ models.DeploymentTarget.objects.all().delete()
+ models.DeploymentTargetSite.objects.all().delete()
+ models.ECOMPRelease.objects.all().delete()
+ logger.info("***************************************")
+ logger.info(">>%s db is now clean!" % Constants.program_name)
+ logger.info("***************************************")
+ except Exception as exception:
+ logger.error("Something went wrong while trying"
+ " to clean %s db" % Constants.program_name, exception)
diff --git a/django/engagementmanager/management/commands/clean_vvp_system.py b/django/engagementmanager/management/commands/clean_vvp_system.py
new file mode 100755
index 0000000..a86f770
--- /dev/null
+++ b/django/engagementmanager/management/commands/clean_vvp_system.py
@@ -0,0 +1,93 @@
+#
+# ============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.
+""" clean_vvp_system
+Will clean all program data:
+1. Deletes all gitlab projects/users/groups.
+2. Deletes all data stored in database.
+3. Deletes all jobs stored in jenkins.
+
+It's recommended to clean the vvp system if you desire in a fresh copy of the vvp program
+without installing it all over again.
+
+WARNING: It will delete almost everything, if you have necessary data DO NOT USE THIS COMMAND!
+"""
+from django.core.management.base import BaseCommand
+from engagementmanager.management.commands import clean_gitlab_content
+from engagementmanager.management.commands import clean_jenkins_jobs
+from engagementmanager.management.commands import clean_vvp_db
+from engagementmanager.management.commands import initial_populate_db
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.constants import Constants
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ logger.info("***************************************")
+ logger.info("%s system is about to be cleaned up!" % Constants.program_name)
+ logger.info("***************************************")
+
+ try:
+ clean_gitlab_content_command = clean_gitlab_content.Command()
+ clean_gitlab_content_command.handle(args, options)
+ except Exception as e:
+ logger.error("There was a problem cleaning git-lab", e)
+
+ try:
+ clean_jenkins_jobs_command = clean_jenkins_jobs.Command()
+ clean_jenkins_jobs_command.handle(args, options)
+ except Exception as e:
+ logger.error("There was a problem cleaning Jenkins", e)
+
+ try:
+ clean_vvp_db_command = clean_vvp_db.Command()
+ clean_vvp_db_command.handle(args, options)
+ except Exception as e:
+ logger.error("There was a problem cleaning %s db" % Constants.program_name, e)
+
+ try:
+ initial_populate_db_command = initial_populate_db.Command()
+ initial_populate_db_command.handle(args, options)
+ except Exception as e:
+ logger.error("There was a problem populate %s db after cleaning" % Constants.program_name, e)
+
+ logger.info("***************************************")
+ logger.info("Done!")
+ logger.info("***************************************")
diff --git a/django/engagementmanager/management/commands/initial_populate_db.py b/django/engagementmanager/management/commands/initial_populate_db.py
new file mode 100755
index 0000000..a0ca177
--- /dev/null
+++ b/django/engagementmanager/management/commands/initial_populate_db.py
@@ -0,0 +1,912 @@
+#
+# ============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.
+""" intial_populate_db
+Will create initial content to use this system.
+
+This command is creating users, templates, companies, deployment targets, sites and much more.
+Will run at the state of a clean system so it won't cause data collisions.
+
+WARNING: Do not run while there is data at the system.
+"""
+import inspect
+import random
+from django.conf import settings
+from django.core.management.base import BaseCommand
+from django.utils import timezone
+from engagementmanager.models import Role, Vendor, IceUserProfile, DeploymentTarget, \
+ DeploymentTargetSite, Checklist, ChecklistDecision, ChecklistLineItem, \
+ ChecklistTemplate, ChecklistSection, ECOMPRelease, Engagement, \
+ CustomUser
+from engagementmanager.models import VF
+from engagementmanager.serializers import ThinVFModelSerializer
+from engagementmanager.utils.constants import Roles, Constants
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.views_helper import createUserTemplate
+from validationmanager.models import ValidationTest
+from uuid import uuid4
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+
+ def handle(self, *args, **options):
+ if (settings.ENVIRONMENT == "local" or settings.ENVIRONMENT == "development"):
+ execute_bootstrap_actions()
+
+
+companies = [
+ 'Affirmed Networks',
+ 'Amdocs',
+ 'Brocade',
+ 'Ciena',
+ 'Cisco',
+ 'Ericsson',
+ 'Fujitsu',
+ 'Juniper',
+ 'Metaswitch',
+ 'Nokia'
+]
+
+companies_not_public = [
+ 'Adtran',
+ 'Velocloud',
+ 'Spirent',
+ 'Mitel',
+]
+
+admin_dummy_users = [['admin bogus user', Constants.service_provider_admin_mail, '+1-23-456-78901']]
+
+admin_ro_dummy_users = [
+ ['ro admin bogus user', Constants.service_provider_admin_ro_mail, '+1-23-456-78901']]
+
+dummy_users = [
+ ['Bugs Bunny', 'bb@' + Constants.service_provider_mail_domain[0], '+1-404-986-9624'],
+ ['CI Standard 1', 'ci_standard_1@' + Constants.service_provider_mail_domain[0], '+1-404-986-9624'],
+]
+
+el_dummy_users = [
+ ['Donald Duck', 'dd1122@' + Constants.service_provider_mail_domain[0], '+1-404-986-9624'],
+ ['Homer Simpson', 'hs0007@' + Constants.service_provider_mail_domain[0], '+1-425-281-3547']
+]
+
+checklist_templates = [
+ {
+ 'name': 'Heat Templates',
+ 'category': 'heat',
+ 'version': 1,
+ 'sections': [
+ {
+ 'name': 'Basic Heat Format and Syntax',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Filenames',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Valid YAML and HEAT',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+ },
+ {
+ 'name': 'Parameter And Resource Specification',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Parameters',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Resources',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Unique Names for Resources',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Outputs',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+
+ },
+ {
+ 'name': 'Naming Conventions',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Name, Flavor, and Image Assignments',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Availability Zones',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Required Metadata',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Optional Metadata',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Volumes',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Keys and Keypairs',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Networks',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Subnet',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Fixed IPs',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Allowed Address Pairs',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Ports',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+
+ },
+ {
+ 'name': 'General Guidelines',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'HEAT Files Support (get_file)',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'HTTP-based references',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Anti-Affinity and Affinity Rules',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Resource Data Synchronization',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+
+ }
+ ]
+ },
+ {
+ 'name': 'Image Validation',
+ 'category': 'glance',
+ 'version': 1,
+ 'sections': [
+ {
+ 'name': 'Prerequisites',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Image Source',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Vendor Provided Image',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+ },
+ {
+ 'name': 'Image Scan',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Clam AV Scan',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ ]
+ },
+ ]
+ },
+ {
+ 'name': 'AIC Instantiation',
+ 'category': 'instantiation',
+ 'version': 1,
+ 'sections': [
+ {
+ 'name': 'Prerequisites',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Validated Heat Template(s)',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Validated Glance Image(s)',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+ },
+ {
+ 'name': 'Manual Instantiation in AIC',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Create the HEAT Stack',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Delete the HEAT Stack',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+ }
+ ]
+ },
+ {
+ 'name': 'ASDC Onboarding',
+ 'category': 'asdc',
+ 'version': 1,
+ 'sections': [
+ {
+ 'name': 'Prerequisites',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Validated Heat Template(s)',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Validated Glance Image(s)',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'Successful Manual Instantiation',
+ 'weight': 1,
+ 'description': 'Description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ }
+ ]
+ },
+ {
+ 'name': 'Onboard The VNF To The Target ASDC Environment',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'validation instructions',
+ 'line_items': [
+ {
+ 'name': 'Create the VNF',
+ 'weight': 1,
+ 'description': 'description',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ ]
+ },
+ ]
+ }
+]
+
+# Map all the validation tests to the right line items
+#
+# Get the validation test mappings like this from a reference deployment:
+# from validationmanager.models import ValidationTest
+# vts = sorted(ValidationTest.objects.all(), key=lambda vt: vt.name)
+# for vt in vts:
+# for li in vt.line_items.all():
+# print("['" + vt.name + "', '" + li.name + "'],")
+validation_tests = [
+ ['test_all_nested_templates_provided', 'Filenames'],
+ ['test_all_referenced_resources_exists', 'Resources'],
+ ['test_allowed_address_pairs_format', 'Allowed Address Pairs'],
+ ['test_allowed_address_pairs_format', 'Ports'],
+ ['test_allowed_address_pairs_include_vm_type_network_role', 'Ports'],
+ ['test_allowed_address_pairs_include_vm_type_network_role', 'Ports'],
+ ['test_alphanumeric_resource_ids_only', 'Resources'],
+ ['test_availability_zone_naming', 'Availability Zones'],
+ ['test_availability_zone_naming_use_get_param', 'Availability Zones'],
+ ['test_base_template_names', 'Filenames'],
+ ['test_base_template_outputs_consumed', 'Outputs'],
+ ['test_default_values', 'Parameters'],
+ ['test_env_and_yaml_same_name', 'Filenames'],
+ ['test_env_files_provided', 'Filenames'],
+ ['test_environment_file_contains_required_sections', 'Valid YAML and HEAT'],
+ ['test_environment_file_extension', 'Filenames'],
+ ['test_environment_file_sections_have_the_right_format', 'Valid YAML and HEAT'],
+ ['test_environment_structure', 'Valid YAML and HEAT'],
+ ['test_fixed_ips_format', 'Fixed IPs'],
+ ['test_fixed_ips_format', 'Ports'],
+ ['test_fixed_ips_format_use_get_parm', 'Fixed IPs'],
+ ['test_fixed_ips_format_use_get_parm', 'Ports'],
+ ['test_fixed_ips_include_vm_type_network_role', 'Ports'],
+ ['test_fixed_ips_include_vm_type_network_role', 'Ports'],
+ ['test_get_file_only_reference_local_files', 'HEAT Files Support (get_file)'],
+ ['test_heat_pairs_provided', 'Filenames'],
+ ['test_heat_template_file_extension', 'Filenames'],
+ ['test_heat_template_parameters_contain_required_fields', 'Valid YAML and HEAT'],
+ ['test_heat_template_structure', 'Valid YAML and HEAT'],
+ ['test_heat_template_structure_contains_required_sections', 'Valid YAML and HEAT'],
+ ['test_heat_template_structure_sections_have_the_right_format', 'Valid YAML and HEAT'],
+ ['test_heat_templates_provided', 'Filenames'],
+ ['test_network_format', 'Networks'],
+ ['test_network_format', 'Ports'],
+ ['test_network_format_use_get_param_or_get_resource', 'Networks'],
+ ['test_network_format_use_get_param_or_get_resource', 'Ports'],
+ ['test_no_unused_parameters_between_env_and_templates', 'Parameters'],
+ ['test_nova_servers_correct_parameter_types', 'Name, Flavor, and Image Assignments'],
+ ['test_nova_servers_valid_resource_ids', 'Resources'],
+ ['test_numeric_parameter', 'Parameters'],
+ ['test_parameter_valid_keys', 'Valid YAML and HEAT'],
+ ['test_parameter_valid_keys', 'Parameters'],
+ ['test_parse_yaml', 'Valid YAML and HEAT'],
+ ['test_port_resource_ids', 'Resources'],
+ ['test_port_resource_ids', 'Ports'],
+ ['test_referenced_and_defined_parameters_match', 'Parameters'],
+ ['test_required_parameters_no_constraints', 'Required Metadata'],
+ ['test_required_parameters_provided_in_env_file', 'Required Metadata'],
+ ['test_required_parameters_provided_in_heat_template', 'Required Metadata'],
+ ['test_required_parameters_provided_in_heat_template', 'Required Metadata'],
+ ['test_servers_have_optional_metadata', 'Optional Metadata'],
+ ['test_servers_have_required_metadata', 'Required Metadata'],
+ ['test_servers_metadata_use_get_param', 'Required Metadata'],
+ ['test_subnet_format', 'Subnet'],
+ ['test_subnet_format', 'Ports'],
+ ['test_subnet_format_use_get_param_or_get_resource', 'Subnet'],
+ ['test_subnet_format_use_get_param_or_get_resource', 'Ports'],
+ ['test_unique_name_resources', 'Unique Names for Resources'],
+ ['test_unique_name_str_replace_use_req_params', 'Unique Names for Resources'],
+ ['test_unique_name_str_replace_use_req_params_in_tmpl', 'Unique Names for Resources'],
+ ['test_unique_resources_across_all_yaml_files', 'Resources'],
+ ['test_unique_resources_across_yaml_file', 'Unique Names for Resources'],
+ ['test_unique_resources_across_yaml_file', 'Resources'],
+ ['test_valid_nesting', 'Filenames'],
+ ['test_vm_type_assignments_on_nova_servers_only_use_get_param', 'Name, Flavor, and Image Assignments'],
+ ['test_vm_type_consistent_on_nova_servers', 'Name, Flavor, and Image Assignments'],
+ ['test_volume_format_outputs', 'Volumes'],
+ ['test_volume_outputs_consumed', 'Volumes'],
+ ['test_volume_resource_ids', 'Resources'],
+ ['test_volume_resource_ids', 'Volumes'],
+ ['test_volume_templates_contains_outputs', 'Volumes'],
+ ['test_volume_templates_only_contains_cinder', 'Volumes'],
+ ['test_volume_templates_outputs_match_resources', 'Volumes'],
+]
+
+deployment_targets = [
+ ['AIC', '2.5'],
+ ['AIC', '3.0'],
+ ['AIC', '3.5'],
+ ['AIC', '4.0'],
+ ['Other', 'No version number available']
+]
+
+ecomps = [
+ ['Unknown']
+]
+
+deployment_targets_sites = [
+ "Alpharetta (PDK2)",
+ "Willows (RDM2)",
+ "Willows (RDM3)",
+ "Middletown (ICENJ)",
+ "Lisle (DPA2)",
+ "Lisle (DPA3)",
+ "Palo Alto (PAO21)"
+]
+
+
+def execute_bootstrap_actions():
+ create_roles()
+ create_companies()
+ create_deployment_targets()
+ create_ecomp()
+ create_deployment_targets_sites()
+
+ # Non-default data:
+ create_standard_users()
+ create_el_users()
+ create_admin_users()
+ create_admin_ro_users()
+ create_templates()
+ create_validation_tests()
+
+
+# TODO maybe enter this into migration scripts
+def patch_migration_missing_fields():
+ logger.info('Patching migration default fields')
+ vf_ids = VF.objects.filter()
+ if (vf_ids):
+ vf_list = ThinVFModelSerializer(vf_ids, many=True).data
+ for vf_data in vf_list:
+ # TODO remove into migration script
+ if vf_data['ecomp_release'] is None:
+ default_ecomp = ECOMPRelease.objects.get(name="Unknown")
+ vfObj = VF.objects.get(uuid=vf_data['uuid'])
+ vfObj.ecomp_release = default_ecomp
+ vfObj.save()
+ if vf_data['engagement']['reviewer'] is None:
+ # @UndefinedVariable
+ elRole = Role.objects.get(name=Roles.el.name)
+ ids_list = []
+ for user in vf_data['engagement']['engagement_team']:
+ ids_list.append(user['uuid'])
+ # Fetch another random el Reviewer
+ qs = IceUserProfile.objects.all().filter(role=elRole).filter(
+ uuid__in=ids_list) # @UndefinedVariable
+ if qs.count() > 0:
+ elUser = IceUserProfile.objects.get(uuid=qs[0].uuid)
+ engagementObj = Engagement.objects.get(
+ uuid=vf_data['engagement']['uuid'])
+ engagementObj.reviewer = elUser
+ engagementObj.save()
+
+ # TODO remove into migration script
+ if vf_data['engagement']['peer_reviewer'] is None:
+ # @UndefinedVariable
+ elRole = Role.objects.get(name=Roles.el.name)
+ ids_list = []
+ for user in vf_data['engagement']['engagement_team']:
+ ids_list.append(user['uuid'])
+ # Fetch another random el to be a Peer Reviewer
+ qs = IceUserProfile.objects.all().filter(role=elRole).exclude(
+ uuid__in=ids_list) # @UndefinedVariable
+ if qs.count() > 0:
+ randUser = qs[random.randint(0, qs.count() - 1)]
+ prUser = IceUserProfile.objects.get(uuid=randUser.uuid)
+ engagementObj = Engagement.objects.get(
+ uuid=vf_data['engagement']['uuid'])
+ engagementObj.peer_reviewer = prUser
+ engagementObj.save()
+
+
+# TODO remove after check engine is connected
+def populate_checklist_automation_value():
+ logger.info('Populating existing checklist with decisions value')
+
+ outerframes = inspect.getouterframes(inspect.currentframe())
+ for outerframe in outerframes:
+ if ('unittest' in str(outerframe)):
+ logger.error(
+ "Avoiding setting checklists in automation to be review since this is a test run: " + logEncoding(outerframe))
+ return
+
+ checklists = Checklist.objects.filter(state='automation')
+ first = True
+ for checklist in checklists:
+ checklist = Checklist.objects.get(uuid=checklist.uuid)
+ if (first):
+ checklist.state = 'review'
+ else:
+ checklist.state = 'peer_review'
+ checklist.save()
+ # first = False
+ decisions = ChecklistDecision.objects.filter(checklist=checklist)
+ first_decision = True
+ for decision in decisions:
+ decision = ChecklistDecision.objects.get(uuid=decision.uuid)
+ line_item = ChecklistLineItem.objects.get(uuid=decision.line_item_id)
+ if line_item.line_type == 'auto':
+ rand_decision_value = bool(random.getrandbits(1))
+ if rand_decision_value:
+ decision.review_value = 'approved'
+ else:
+ decision.review_value = 'denied'
+ decision.save()
+
+
+def create_templates():
+ logger.info('Creating Checklist templates')
+ for template in checklist_templates:
+ created_template, created = ChecklistTemplate.objects.get_or_create(name=template['name'],
+ defaults={
+ 'category': template['category'],
+ 'version': template['version'],
+ 'create_time': timezone.now()
+ })
+ for section in template['sections']:
+ created_section = ChecklistSection.objects.get_or_create(name=section['name'],
+ template_id=created_template.uuid,
+ defaults={
+ 'weight': section['weight'],
+ 'description': section['description'],
+ 'validation_instructions': section['validation_instructions']
+
+ })
+ created_section = ChecklistSection.objects.get(
+ name=section['name'], template_id=created_template.uuid)
+ for line_item in section['line_items']:
+ created_line_item = ChecklistLineItem.objects.get_or_create(name=line_item['name'],
+ section_id=created_section.uuid,
+ template_id=created_template.uuid,
+ defaults={
+ 'weight': line_item['weight'],
+ 'description': line_item['description'],
+ 'validation_instructions': line_item['validation_instructions'],
+ 'line_type': line_item['line_type'],
+ 'section_id': created_section.uuid,
+ })
+
+
+def create_validation_tests():
+ logger.info('Creating Validation Tests')
+ template = ChecklistTemplate.objects.get(category='heat')
+ for test_name, line_item_name in validation_tests:
+ line_item = ChecklistLineItem.objects.get(name=line_item_name, template=template)
+ if line_item:
+ validation_test, status = ValidationTest.objects.get_or_create(name=test_name)
+ validation_test.line_items.add(line_item)
+
+
+def create_roles():
+ role_standard_user, created = Role.objects.get_or_create(
+ name=Roles.standard_user.name) # @UndefinedVariable
+ Constants.role_standard_user = role_standard_user
+ logger.info(
+ 'user role found or created : ' + logEncoding(role_standard_user))
+
+ role_el, created = Role.objects.get_or_create(
+ name=Roles.el.name) # @UndefinedVariable
+ Constants.role_el = role_el
+ logger.info('user role found or created : ' + logEncoding(role_el))
+
+ role_admin, created = Role.objects.get_or_create(
+ name=Roles.admin.name) # @UndefinedVariable
+ Constants.role_admin = role_admin
+ logger.info('user role found or created : ' + logEncoding(role_admin))
+
+ role_admin_ro, created = Role.objects.get_or_create(
+ name=Roles.admin_ro.name) # @UndefinedVariable
+ Constants.role_admin_ro = role_admin_ro
+ logger.info('user role found or created : ' + logEncoding(role_admin_ro))
+
+
+def create_companies():
+ service_provider_company = None
+ created = None
+ try:
+ service_provider_company, created = Vendor.objects.get_or_create(
+ name=Constants.service_provider_company_name, public=True)
+ Constants.service_provider_company = service_provider_company
+ logger.info('The company was found or created : ' + str(service_provider_company))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_companies error:")
+ logger.error(e)
+ logger.error('The company could not be found or created : ' + Constants.service_provider_company_name)
+
+ for company in companies_not_public:
+ try:
+ company, created = Vendor.objects.get_or_create(
+ name=company, public=False) # @UndefinedVariable
+ logger.info('The company was found or created : ' + str(company))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_companies error:")
+ logger.error(e)
+ logger.error(
+ 'The company could not be found or created.' + str(company))
+
+ for company in companies:
+ try:
+ company, created = Vendor.objects.get_or_create(
+ name=company, public=True) # @UndefinedVariable
+ logger.info('The company was found or created : ' + str(company))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_companies error:")
+ logger.error(e)
+ logger.error(
+ 'The company could not be found or created.' + str(company))
+
+ try:
+ company_other, created = Vendor.objects.get_or_create(
+ name='Other', public=True, defaults={'public': True})
+ logger.info('The company was found or created : ' + str(company_other))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_deployment_targets error:")
+ logger.error(e)
+ logger.error('The company could not be found or created : Other')
+
+
+"""expected: nothing , result: IceUserProfiles with el role creation"""
+
+
+def create_standard_users():
+ service_provider_company = Vendor.objects.get(name=Constants.service_provider_company_name)
+ user_role = Role.objects.get(name="standard_user")
+ user_list = dummy_users
+
+ for user in user_list:
+ try:
+ user_object, created = CustomUser.objects.get_or_create(username=user[1], defaults={
+ 'is_active': True, 'email': user[1], 'activation_token': uuid4(), 'activation_token_create_time': timezone.now()})
+ user_object.set_password('iceusers')
+ user_object.save()
+ data = createUserTemplate(
+ service_provider_company, user[0], user_role, user[2], True, None, True, user_object)
+ standard_user, profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=data)
+ logger.info(
+ 'The Standard user was found or created: ' + str(standard_user.full_name))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_el_users error:")
+ logger.error(e)
+ logger.error('The EL User could not be found or created.')
+
+
+def create_el_users():
+ service_provider_company = Vendor.objects.get(name=Constants.service_provider_company_name)
+ el_role = Role.objects.get(name="el")
+ el_list = el_dummy_users
+
+ for user in el_list:
+ try:
+ user_object, created = CustomUser.objects.get_or_create(username=user[1], defaults={
+ 'is_active': True, 'email': user[1], 'activation_token': uuid4(), 'activation_token_create_time': timezone.now()})
+ user_object.set_password('iceusers')
+ user_object.save()
+ data = createUserTemplate(
+ service_provider_company, user[0], el_role, user[2], True, None, True, user_object)
+ el_user, profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=data)
+ logger.info(
+ 'The EL user was found or created: ' + str(el_user.full_name))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_el_users error:")
+ logger.error(e)
+ logger.error('The EL User could not be found or created.')
+
+
+def create_admin_users():
+ service_provider_company = Vendor.objects.get(name=Constants.service_provider_company_name)
+ admin_role = Role.objects.get(name=Roles.admin.name) # @UndefinedVariable
+
+ admin_list = admin_dummy_users
+
+ for user in admin_list:
+ try:
+ user_object, created = CustomUser.objects.get_or_create(username=user[1], defaults={'is_active': True, 'email': user[
+ 1], 'password': "iceusers", 'activation_token': uuid4(), 'activation_token_create_time': timezone.now()})
+ user_object.set_password('iceusers')
+ user_object.save()
+ data = createUserTemplate(
+ service_provider_company, user[0], admin_role, user[2], True, None, True, user_object)
+ admin_user, profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=data)
+ logger.info(
+ 'The admin user was found or created: ' + str(admin_user.full_name))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_admin_users error:")
+ logger.error(e)
+ logger.error('The admin user could not be found or created.')
+
+
+def create_admin_ro_users():
+ service_provider_company = Vendor.objects.get(name=Constants.service_provider_company_name)
+ admin_ro_role = Role.objects.get(
+ name=Roles.admin_ro.name) # @UndefinedVariable
+
+ admin_ro_list = admin_ro_dummy_users
+
+ for user in admin_ro_list:
+ try:
+ user_object, created = CustomUser.objects.get_or_create(username=user[1], defaults={'is_active': True, 'email': user[
+ 1], 'password': "iceusers", 'activation_token': uuid4(), 'activation_token_create_time': timezone.now()})
+ user_object.set_password('iceusers')
+ user_object.save()
+ data = createUserTemplate(
+ service_provider_company, user[0], admin_ro_role, user[2], True, None, True, user_object)
+ admin_ro_user, profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=data)
+ logger.info(
+ 'The admin_ro user was found or created: ' + str(admin_ro_user.full_name))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_admin_ro_users error:")
+ logger.error(e)
+ logger.error('The admin_ro user could not be found or created.')
+
+
+"""expected: nothing , result: Deployment Target objects creation"""
+
+
+def create_deployment_targets():
+ for dt in deployment_targets:
+ try:
+ deployment_target, created = DeploymentTarget.objects.get_or_create(
+ name=dt[0], version=dt[1], defaults={'version': dt[1]})
+ logger.info(
+ 'Deployment Target found or created: ' + str(deployment_target))
+ except Exception as e:
+ logger.error(
+ "bootstrap_actions - create_deployment_targets error:")
+ logger.error(e)
+ logger.error(
+ 'Deployment Target could not be found or created : ' + str(dt))
+
+
+"""expected: nothing , result: ECOMP objects creation"""
+
+
+def create_ecomp():
+ for dt in ecomps:
+ try:
+ ecomp, created = ECOMPRelease.objects.get_or_create(
+ name=dt[0])
+ logger.info('ECOMP Release found or created: ' + str(ecomp))
+ except Exception as e:
+ logger.error("bootstrap_actions - create_ecomp error:")
+ logger.error(e)
+ logger.error(
+ 'ECOMP Release could not be found or created : ' + str(dt))
+
+
+"""expected: nothing , result: creation of Deployment Target Sites objects"""
+
+
+def create_deployment_targets_sites():
+ for dt in deployment_targets_sites:
+ try:
+ deployment_target_site, created = DeploymentTargetSite.objects.get_or_create(
+ name=dt)
+ logger.info(
+ 'Deployment Target found or created: ' + str(deployment_target_site.name))
+ except Exception as e:
+ logger.error(
+ "bootstrap_actions - create_deployment_targets_sites error:")
+ logger.error(e)
+ logger.error(
+ 'Deployment Target could not be found or created : ' + str(dt))
diff --git a/django/engagementmanager/management/commands/populate_all_gitlab_repo_and_user_and_jenkins.py b/django/engagementmanager/management/commands/populate_all_gitlab_repo_and_user_and_jenkins.py
new file mode 100755
index 0000000..2d6c5be
--- /dev/null
+++ b/django/engagementmanager/management/commands/populate_all_gitlab_repo_and_user_and_jenkins.py
@@ -0,0 +1,78 @@
+#
+# ============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.
+""" populate_all_gitlab_repo_and_user_and_jenkins
+Will populate gitlab and jenkins with vf data (where it's not exists).
+
+This command will be used for systems with missing gitlab/jenkins data for some vfs.
+"""
+from django.core.management.base import BaseCommand
+from rest_framework.status import HTTP_200_OK
+from engagementmanager.models import VF
+from engagementmanager.utils.constants import EngagementStage
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.vm_integration import vm_client
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+
+ def handle(self, *args, **options):
+ engStageList = [EngagementStage.Intake.name, EngagementStage.Active.name,
+ EngagementStage.Validated.name, EngagementStage.Completed.name]
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)
+ log_array = []
+ error_array = []
+ for vf_found in vf_list:
+ logger.debug(vf_found.uuid)
+ msg, http_status, values = vm_client.send_provision_new_vf_event(vf_found)
+ vf_dict = {
+ 'vf_uuid': vf_found.uuid,
+ 'msg': msg,
+ 'http_status': http_status,
+ 'values': values
+ }
+
+ log_array.append(vf_dict)
+ if (http_status != HTTP_200_OK):
+ error_array.append(vf_dict)
+
+ logger.error("==== populate jenkins _ gitlab error log ======")
+ logger.error(logEncoding(error_array))
diff --git a/django/engagementmanager/management/commands/render_rgwa_credentials.py b/django/engagementmanager/management/commands/render_rgwa_credentials.py
new file mode 100755
index 0000000..52a1373
--- /dev/null
+++ b/django/engagementmanager/management/commands/render_rgwa_credentials.py
@@ -0,0 +1,61 @@
+#
+# ============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.
+""" render_rgwa_credentials
+Will create rados gateway user (S3 API) for each django user.
+
+This command will create the user if it's not exists so it safe to run it even the user are exists.
+This command is part of bucket usage (images) efforts.
+"""
+from django.db.models import Q
+from engagementmanager.models import IceUserProfile
+from validationmanager.em_integration.vm_api import create_user_rgwa
+from django.core.management.base import BaseCommand
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Command(BaseCommand):
+
+ def handle(self, *args, **options):
+ logger.debug("About to generate RGWA credentials for existing users")
+ users = IceUserProfile.objects.filter(
+ Q(rgwa_secret_key=None) | Q(rgwa_access_key=None))
+ for user in users:
+ create_user_rgwa(user)
diff --git a/django/engagementmanager/migrations/0001_initial.py b/django/engagementmanager/migrations/0001_initial.py
new file mode 100755
index 0000000..ffbb95a
--- /dev/null
+++ b/django/engagementmanager/migrations/0001_initial.py
@@ -0,0 +1,396 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-06-13 14:07
+from __future__ import unicode_literals
+
+import datetime
+
+from django.db import migrations, models
+import django.db.models.deletion
+from django.utils.timezone import utc
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Activity',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('description', models.CharField(max_length=512)),
+ ('is_notification', models.BooleanField(default=False)),
+ ('activity_type', models.CharField(choices=[
+ (b'3', b'eng_validation_request'), (b'4', b'next_steps'), (b'2', b'ssh_key_added'), (b'1', b'user_joined_eng')], max_length=36)),
+ ('metadata', models.CharField(max_length=1024)),
+ ],
+ options={
+ 'ordering': ['-create_time'],
+ 'db_table': 'ice_activity',
+ },
+ ),
+ migrations.CreateModel(
+ name='ApplicationServiceInfrastructure',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=100, unique=True)),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_application_service_infrastructure',
+ },
+ ),
+ migrations.CreateModel(
+ name='ContactRequest',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('fname', models.CharField(max_length=50)),
+ ('lname', models.CharField(max_length=50)),
+ ('email', models.EmailField(max_length=254, verbose_name='email')),
+ ('company', models.CharField(max_length=50)),
+ ('phone_number', models.CharField(max_length=30)),
+ ('message', models.TextField()),
+ ],
+ options={
+ 'db_table': 'ice_contact_request',
+ },
+ ),
+ migrations.CreateModel(
+ name='DeploymentTarget',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ('version', models.CharField(max_length=100)),
+ ],
+ options={
+ 'db_table': 'ice_deployment_target',
+ },
+ ),
+ migrations.CreateModel(
+ name='Engagement',
+ fields=[
+ ('uuid', models.CharField(max_length=64, primary_key=True, serialize=False)),
+ ('engagement_manual_id', models.CharField(blank=True, max_length=36, null=True)),
+ ('progress', models.IntegerField(default=0)),
+ ('target_completion_date', models.DateField(blank=True, default=datetime.datetime(
+ 2016, 6, 29, 14, 7, 41, 103000, tzinfo=utc), null=True)),
+ ('engagement_stage', models.CharField(default=b'Intake', max_length=15)),
+ ],
+ options={
+ 'db_table': 'ice_engagement',
+ },
+ ),
+ migrations.CreateModel(
+ name='EngagementRequest',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('fname', models.CharField(max_length=50)),
+ ('lname', models.CharField(max_length=50)),
+ ('email', models.EmailField(max_length=254, verbose_name='email')),
+ ('company', models.CharField(max_length=50)),
+ ('country_code', models.CharField(max_length=5)),
+ ('phone_number', models.CharField(max_length=30)),
+ ('vf_csv', models.CharField(max_length=80)),
+ ('att_contact_fname', models.CharField(max_length=50)),
+ ('att_contact_lname', models.CharField(max_length=50)),
+ ('att_contact_email', models.EmailField(max_length=254, verbose_name='email')),
+ ('att_contact_phone', models.CharField(max_length=30)),
+ ('request_type', models.CharField(max_length=20)),
+ ('description', models.TextField()),
+ ('mail_subscription', models.BooleanField()),
+ ],
+ options={
+ 'db_table': 'ice_engagement_request',
+ },
+ ),
+ migrations.CreateModel(
+ name='IceUser',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('phone_number', models.CharField(max_length=30)),
+ ('full_name', models.CharField(max_length=30)),
+ ('email', models.EmailField(max_length=254, unique=True, verbose_name='email')),
+ ('password', models.CharField(max_length=256)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last_login')),
+ ('ssh_public_key', models.CharField(
+ blank=True, max_length=1024, null=True, verbose_name='ssh_public_key')),
+ ('regular_email_updates', models.BooleanField(default=False)),
+ ('email_updates_on_every_notification', models.BooleanField(default=True)),
+ ('email_updates_daily_digest', models.BooleanField(default=False)),
+ ('is_active', models.BooleanField()),
+ ('is_att_contact', models.BooleanField()),
+ ('activation_token', models.CharField(max_length=128, unique=True)),
+ ('activation_token_create_time', models.DateTimeField(
+ default=django.utils.timezone.now, verbose_name='activation_token_create_time')),
+ ],
+ options={
+ 'db_table': 'ice_user',
+ },
+ ),
+ migrations.CreateModel(
+ name='NextStep',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('last_update_time', models.DateTimeField(
+ default=django.utils.timezone.now, verbose_name='last update time')),
+ ('last_update_type', models.CharField(default='Added', max_length=15)),
+ ('position', models.IntegerField()),
+ ('description', models.TextField()),
+ ('state', models.CharField(max_length=15)),
+ ('engagement_stage', models.CharField(max_length=15)),
+ ('creator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
+ related_name='NextStep_creator', to='engagementmanager.IceUser')),
+ ('engagement', models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement')),
+ ('last_updater', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='NextStep_last_updater', to='engagementmanager.IceUser')),
+ ],
+ options={
+ 'db_table': 'ice_next_step',
+ 'verbose_name_plural': 'Next steps',
+ },
+ ),
+ migrations.CreateModel(
+ name='Notification',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('is_sent', models.BooleanField(default=False)),
+ ('is_read', models.BooleanField(default=False)),
+ ('activity', models.ForeignKey(
+ null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Activity')),
+ ('user', models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUser')),
+ ],
+ options={
+ 'db_table': 'ice_notification',
+ },
+ ),
+ migrations.CreateModel(
+ name='Role',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('name', models.CharField(max_length=36, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_role',
+ },
+ ),
+ migrations.CreateModel(
+ name='Test',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=45)),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_test',
+ },
+ ),
+ migrations.CreateModel(
+ name='ValidationCycle',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('start_date', models.DateTimeField()),
+ ('end_date', models.DateTimeField()),
+ ('validated_by', models.CharField(max_length=45)),
+ ('validated_at', models.DateTimeField()),
+ ('peer_reviewer', models.CharField(max_length=45)),
+ ('peer_reviewed_at', models.DateTimeField()),
+ ('package_uuid', models.CharField(max_length=45)),
+ ('package_cksum', models.CharField(max_length=45)),
+ ('package_approval_date', models.DateTimeField()),
+ ('package_approver', models.CharField(max_length=45)),
+ ('image_uuid', models.CharField(max_length=45)),
+ ('image_name', models.CharField(max_length=100)),
+ ('image_cksum', models.CharField(max_length=100)),
+ ('passed', models.BooleanField()),
+ ],
+ options={
+ 'db_table': 'ice_validation_cycle',
+ },
+ ),
+ migrations.CreateModel(
+ name='ValidationException',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('type', models.CharField(max_length=45)),
+ ('external_ref_id', models.CharField(max_length=45)),
+ ],
+ options={
+ 'db_table': 'ice_validation_exception',
+ },
+ ),
+ migrations.CreateModel(
+ name='ValidationSteps',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36)),
+ ('requirment_id', models.CharField(blank=True, max_length=36, null=True)),
+ ('passed', models.BooleanField()),
+ ('log', models.BinaryField()),
+ ('validation_notes', models.CharField(blank=True, max_length=200, null=True)),
+ ('test', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Test')),
+ ('validation_cycle', models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.ValidationCycle')),
+ ('validation_exceptions', models.ManyToManyField(to='engagementmanager.ValidationException')),
+ ],
+ options={
+ 'db_table': 'ice_validation_step',
+ 'verbose_name_plural': 'Validation steps',
+ },
+ ),
+ migrations.CreateModel(
+ name='Vendor',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('name', models.CharField(max_length=100, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_vendor',
+ },
+ ),
+ migrations.CreateModel(
+ name='VF',
+ fields=[
+ ('name', models.CharField(max_length=100)),
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('is_att_internal', models.BooleanField(default=False)),
+ ('git_repo_url', models.CharField(blank=True, max_length=512, null=True)),
+ ('target_lab_entry_date', models.DateField(verbose_name='target_lab_entry_date')),
+ ('deployment_target', models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.SET_NULL, to='engagementmanager.DeploymentTarget')),
+ ('engagement', models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.SET_NULL, to='engagementmanager.Engagement')),
+ ('vendor', models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Vendor')),
+ ],
+ options={
+ 'db_table': 'ice_vf',
+ },
+ ),
+ migrations.CreateModel(
+ name='VFC',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=45)),
+ ('version', models.CharField(max_length=45)),
+ ('uuid', models.CharField(max_length=36, unique=True)),
+ ('vf_acronym', models.CharField(blank=True, max_length=100, null=True)),
+ ('vf', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.VF')),
+ ],
+ options={
+ 'db_table': 'ice_vfc',
+ },
+ ),
+ migrations.AlterUniqueTogether(
+ name='validationexception',
+ unique_together=set([('uuid', 'type')]),
+ ),
+ migrations.AddField(
+ model_name='validationcycle',
+ name='vfc',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.VFC'),
+ ),
+ migrations.AddField(
+ model_name='iceuser',
+ name='company',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Vendor'),
+ ),
+ migrations.AddField(
+ model_name='iceuser',
+ name='role',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Role'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='contact_user',
+ field=models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='engagement_team',
+ field=models.ManyToManyField(related_name='members', to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='deploymenttarget',
+ unique_together=set([('name', 'version')]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='applicationserviceinfrastructure',
+ unique_together=set([('name', 'uuid')]),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='activity_owner',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='engagement',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='vfc',
+ unique_together=set([('name', 'version')]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='validationsteps',
+ unique_together=set([('uuid', 'requirment_id')]),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0001_squashed_initial.py b/django/engagementmanager/migrations/0001_squashed_initial.py
new file mode 100755
index 0000000..1be6a07
--- /dev/null
+++ b/django/engagementmanager/migrations/0001_squashed_initial.py
@@ -0,0 +1,639 @@
+#
+# ============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 __future__ import unicode_literals
+from django.conf import settings
+import django.contrib.auth.models
+from django.db import models
+import django.db.models.deletion
+from django.utils.timezone import utc
+import django.utils.timezone
+import engagementmanager.models
+import uuid
+import os
+from django.db import migrations, connection
+import engagementmanager
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def forwards(apps, schema_editor):
+ if not schema_editor.connection.alias == 'default':
+ return
+
+ cursor = connection.cursor()
+ cursor.execute(open(os.path.join(os.path.dirname(engagementmanager.__file__),
+ 'sql-scripts/generate_excel_overview_sheet_procedure.sql'), "r").read())
+
+
+def create_user_for_pre_user_profiles(apps, schema_editor):
+ CustomUser = apps.get_model("engagementmanager", "CustomUser")
+ IceUserProfile = apps.get_model("engagementmanager", "IceUserProfile")
+ users_list = IceUserProfile.objects.filter(user=None)
+ count = 0
+ for profile in users_list:
+ try:
+ custom_user, created = CustomUser.objects.get_or_create(username=profile.email)
+ custom_user.is_active = profile.is_active
+ custom_user.email = profile.email
+ custom_user.activation_token = profile.activation_token
+ custom_user.password = profile.password
+ custom_user.activation_token_create_time = profile.activation_token_create_time
+ custom_user.save()
+ profile.user = custom_user
+ profile.save()
+
+ except Exception as e:
+ logger.error("migrations fail, error:")
+ logger.error(e.message)
+
+
+class Migration(migrations.Migration):
+ replaces = [('engagementmanager', '0001_initial'), ('engagementmanager', '0002_auto_20160704_1028'),
+ ('engagementmanager', '0003_auto_20160713_0929'), ('engagementmanager', '0004_auto_20160720_2143'),
+ ('engagementmanager', '0005_auto_20160815_1248'), ('engagementmanager', '0006_auto_20160825_0644'),
+ ('engagementmanager', '0007_auto_20160922_0421'), ('engagementmanager', '0008_auto_20161009_1210'),
+ ('engagementmanager', '0009_auto_20161018_0740'), ('engagementmanager', '0010_auto_20161025_0838'),
+ ('engagementmanager', '0011_auto_20161109_0811'), ('engagementmanager', '0012_auto_20161109_0822'),
+ ('engagementmanager', '0013_auto_20161128_1159'), ('engagementmanager', '0014_auto_20161129_1145'),
+ ('engagementmanager', '0015_engagementstatus'), ('engagementmanager', '0016_auto_20161208_0842'),
+ ('engagementmanager', '0017_auto_20161215_1535'), ('engagementmanager', '0018_set_old_notif_true'),
+ ('engagementmanager', '0019_auto_20170104_1715'), ('engagementmanager', '0020_add_indexes_20170108'),
+ ('engagementmanager', '0021_generate_excel_overview_sheet_procedure_20170110'),
+ ('engagementmanager', '0022_auto_20170118_1520'), ('engagementmanager', '0023_auto_20170123_1445'),
+ ('engagementmanager', '0024_auto_20170227_1224'),
+ ('engagementmanager', '0025_change_nextsteps_to_new_state'),
+ ('engagementmanager', '0026_add_slack_handle_to_ice_user_profile'),
+ ('engagementmanager', '0027_add_version_to_vf'), ('engagementmanager', '0028_auto_20170425_1310'),
+ ('engagementmanager', '0029_auto_20170504_0749'),
+ ('engagementmanager', '0030_engagement_archived_time'),
+ ('engagementmanager', '0031_auto_20170620_1312'), ('engagementmanager', '0032_auto_20170702_1435'),
+ ('engagementmanager', '0033_auto_20170704_0635'),
+ ('engagementmanager', '0034_engagement_is_with_files'), ('engagementmanager', '0035_rgwa_fields'),
+ ('engagementmanager', '0036_auto_20170906_0935')]
+
+ initial = True
+
+ dependencies = [
+ ('auth', '0008_alter_user_username_max_length'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Activity',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('description', models.CharField(max_length=512)),
+ ('is_notification', models.BooleanField(default=False)),
+ ('activity_type', models.CharField(choices=[('user_joined_eng', 'user_joined_eng'), ('ssh_key_added', 'ssh_key_added'), ('eng_validation_request', 'eng_validation_request'), ('update_next_steps', 'update_next_steps'), ('vfc', 'vfc'), ('change_checklist_state', 'change_checklist_state'), ('vf_provisioning_event', 'vf_provisioning_event'), ('test_finished_event', 'test_finished_event'), ('change_engagement_stage', 'change_engagement_stage'), ('add_next_steps', 'add_next_steps'), ('delete_next_steps', 'delete_next_steps'), ('notice_empty_engagement', 'notice_empty_engagement')], max_length=36)),
+ ('metadata', models.CharField(max_length=1024)),
+ ],
+ options={
+ 'db_table': 'ice_activity',
+ 'ordering': ['-create_time'],
+ },
+ ),
+ migrations.CreateModel(
+ name='ApplicationServiceInfrastructure',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=100, unique=True)),
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_application_service_infrastructure',
+ },
+ ),
+ migrations.CreateModel(
+ name='Checklist',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='checklist name')),
+ ('state', models.CharField(choices=[('automation', 'automation'), ('review', 'review'), ('peer_review', 'peer_review'), ('approval', 'approval'), ('handoff', 'handoff'), ('closed', 'closed'), ('archive', 'archive'), ('pending', 'pending')], default='pending', max_length=36)),
+ ('validation_cycle', models.IntegerField(verbose_name='validation cycle')),
+ ('weight', models.FloatField(default=0, verbose_name='checklist weight')),
+ ('associated_files', models.TextField(verbose_name='list of files from gitlab')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ],
+ options={
+ 'db_table': 'ice_checklist',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistAuditLog',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('category', models.CharField(max_length=255)),
+ ('description', models.TextField()),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('checklist', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Checklist')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_audit_log',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistDecision',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('review_value', models.CharField(choices=[('approved', 'approved'), ('denied', 'denied'), ('not_relevant', 'not_relevant'), ('na', 'na')], max_length=36)),
+ ('peer_review_value', models.CharField(choices=[('approved', 'approved'), ('denied', 'denied'), ('not_relevant', 'not_relevant'), ('na', 'na')], max_length=36)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('checklist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Checklist')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_decision',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistLineItem',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='line name')),
+ ('weight', models.FloatField(verbose_name='line weight')),
+ ('description', models.TextField(verbose_name='line description')),
+ ('line_type', models.CharField(choices=[('auto', 'auto'), ('manual', 'manual')], default='auto', max_length=36)),
+ ('validation_instructions', models.TextField(verbose_name='line validation instructions')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_line_item',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistSection',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='section name')),
+ ('weight', models.FloatField(verbose_name='checklist weight')),
+ ('description', models.TextField(verbose_name='section description')),
+ ('validation_instructions', models.TextField(verbose_name='section validation instructions')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('parent_section', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistSection')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_section',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistTemplate',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='template name')),
+ ('category', models.CharField(choices=[('overall', 'overall'), ('heat', 'heat'), ('glance', 'glance'), ('instantiation', 'instantiation'), ('asdc', 'asdc')], default='overall', max_length=36)),
+ ('version', models.IntegerField(verbose_name='template version')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_template',
+ },
+ ),
+ migrations.CreateModel(
+ name='CustomUser',
+ fields=[
+ ('user_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
+ ('activation_token', models.CharField(max_length=128, null=True, unique=True)),
+ ('activation_token_create_time', models.DateTimeField(default=django.utils.timezone.now, null=True, verbose_name='activation_token_create_time')),
+ ('temp_password', models.CharField(blank=True, default=None, max_length=256, null=True)),
+ ],
+ options={
+ 'db_table': 'ice_custom_user',
+ },
+ bases=('auth.user',),
+ managers=[
+ ('objects', django.contrib.auth.models.UserManager()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='DeploymentTarget',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ('version', models.CharField(max_length=100)),
+ ('weight', models.IntegerField(default=1)),
+ ('ui_visibility', models.BooleanField(default=True)),
+ ],
+ options={
+ 'db_table': 'ice_deployment_target',
+ },
+ ),
+ migrations.CreateModel(
+ name='DeploymentTargetSite',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ],
+ options={
+ 'db_table': 'ice_deployment_target_site',
+ },
+ ),
+ migrations.CreateModel(
+ name='ECOMPRelease',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ('weight', models.IntegerField(default=1)),
+ ('ui_visibility', models.BooleanField(default=True)),
+ ],
+ options={
+ 'db_table': 'ice_ecomp_release',
+ },
+ ),
+ migrations.CreateModel(
+ name='Engagement',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False)),
+ ('engagement_manual_id', models.CharField(db_index=True, default=-1, max_length=36)),
+ ('progress', models.IntegerField(default=0)),
+ ('target_completion_date', models.DateField(blank=True, default=engagementmanager.models.get_default_target_completion_date, null=True)),
+ ('engagement_stage', models.CharField(choices=[('Intake', 'Intake'), ('Active', 'Active'), ('Validated', 'Validated'), ('Completed', 'Completed'), ('Archived', 'Archived')], db_index=True, default='Intake', max_length=15)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('heat_validated_time', models.DateTimeField(blank=True, null=True, verbose_name='heat validated time')),
+ ('image_scan_time', models.DateTimeField(blank=True, null=True, verbose_name='image scan time')),
+ ('aic_instantiation_time', models.DateTimeField(blank=True, null=True, verbose_name='aic instantiation time')),
+ ('asdc_onboarding_time', models.DateTimeField(blank=True, null=True, verbose_name='asdc onboarding time')),
+ ('started_state_time', models.DateTimeField(blank=True, null=True, verbose_name='started state time')),
+ ('intake_time', models.DateTimeField(blank=True, null=True, verbose_name='intake time')),
+ ('active_time', models.DateTimeField(blank=True, null=True, verbose_name='active time')),
+ ('validated_time', models.DateTimeField(blank=True, null=True, verbose_name='validated time')),
+ ('completed_time', models.DateTimeField(blank=True, null=True, verbose_name='completed time')),
+ ('archive_reason', models.TextField(default=None, null=True)),
+ ('archived_time', models.DateTimeField(blank=True, null=True, verbose_name='archived time')),
+ ('is_with_files', models.BooleanField(default=False)),
+ ],
+ options={
+ 'db_table': 'ice_engagement',
+ },
+ ),
+ migrations.CreateModel(
+ name='EngagementStatus',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False)),
+ ('description', models.CharField(max_length=256)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('update_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ],
+ options={
+ 'db_table': 'ice_engagement_status',
+ },
+ ),
+ migrations.CreateModel(
+ name='Feedback',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('description', models.TextField(verbose_name='feedback_description')),
+ ],
+ options={
+ 'db_table': 'ice_feedback',
+ },
+ ),
+ migrations.CreateModel(
+ name='IceUserProfile',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, unique=True)),
+ ('phone_number', models.CharField(max_length=30)),
+ ('full_name', models.CharField(max_length=30)),
+ ('email', models.EmailField(db_index=True, max_length=254, unique=True, verbose_name='email')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('ssh_public_key', models.CharField(blank=True, max_length=1024, null=True, verbose_name='ssh_public_key')),
+ ('regular_email_updates', models.BooleanField(default=False)),
+ ('email_updates_on_every_notification', models.BooleanField(default=True)),
+ ('email_updates_daily_digest', models.BooleanField(default=False)),
+ ('is_service_provider_contact', models.BooleanField(default=False)),
+ ('rgwa_access_key', models.CharField(blank=True, max_length=1024, null=True, unique=True)),
+ ('rgwa_secret_key', models.CharField(blank=True, max_length=1024, null=True, unique=True)),
+ ('slack_handle', models.CharField(blank=True, default=None, max_length=64, null=True)),
+ ],
+ options={
+ 'db_table': 'ice_user_profile',
+ },
+ ),
+ migrations.CreateModel(
+ name='Invitation',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('engagement_uuid', models.CharField(db_index=True, max_length=64)),
+ ('invited_by_user_uuid', models.CharField(db_index=True, max_length=64)),
+ ('email', models.CharField(max_length=255)),
+ ('invitation_token', models.CharField(db_index=True, max_length=1024)),
+ ('accepted', models.BooleanField(default=False)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='invitation creation time')),
+ ],
+ options={
+ 'db_table': 'ice_invitation',
+ },
+ ),
+ migrations.CreateModel(
+ name='NextStep',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('last_update_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='last update time')),
+ ('last_update_type', models.CharField(default='Added', max_length=15)),
+ ('position', models.IntegerField()),
+ ('description', models.TextField()),
+ ('state', models.CharField(choices=[('Incomplete', 'Incomplete'), ('Completed', 'Completed')], max_length=15)),
+ ('engagement_stage', models.CharField(max_length=15)),
+ ('next_step_type', models.CharField(choices=[('set_ssh', 'set_ssh'), ('trial_agreements', 'trial_agreements'), ('add_contact_person', 'add_contact_person'), ('submit_vf_package', 'submit_vf_package'), ('el_handoff', 'el_handoff'), ('user_defined', 'user_defined')], default='user_defined', max_length=36)),
+ ('files', models.TextField(null=True, verbose_name='list of files')),
+ ('due_date', models.DateField(null=True, verbose_name='due_date')),
+ ('assignees', models.ManyToManyField(related_name='assignees', to='engagementmanager.IceUserProfile')),
+ ('creator', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='NextStep_creator', to='engagementmanager.IceUserProfile')),
+ ('engagement', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement')),
+ ('last_updater', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='NextStep_last_updater', to='engagementmanager.IceUserProfile')),
+ ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.IceUserProfile')),
+ ],
+ options={
+ 'verbose_name_plural': 'Next steps',
+ 'db_table': 'ice_next_step',
+ },
+ ),
+ migrations.CreateModel(
+ name='Notification',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('is_sent', models.BooleanField(default=False)),
+ ('is_read', models.BooleanField(default=False)),
+ ('activity', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Activity')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile')),
+ ],
+ options={
+ 'db_table': 'ice_notification',
+ },
+ ),
+ migrations.CreateModel(
+ name='RecentEngagement',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False)),
+ ('user_uuid', models.CharField(max_length=64)),
+ ('action_type', models.CharField(choices=[('JOINED_TO_ENGAGEMENT', 'JOINED_TO_ENGAGEMENT'), ('NEXT_STEP_ASSIGNED', 'NEXT_STEP_ASSIGNED'), ('GOT_OWNERSHIP_OVER_ENGAGEMENT', 'GOT_OWNERSHIP_OVER_ENGAGEMENT'), ('NAVIGATED_INTO_ENGAGEMENT', 'NAVIGATED_INTO_ENGAGEMENT'), ('NEW_VF_CREATED', 'NEW_VF_CREATED')], max_length=36)),
+ ('last_update', models.DateTimeField(default=django.utils.timezone.now, verbose_name='update time')),
+ ],
+ options={
+ 'db_table': 'ice_recent_engagement',
+ },
+ ),
+ migrations.CreateModel(
+ name='Role',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, unique=True)),
+ ('name', models.CharField(max_length=36, unique=True)),
+ ],
+ options={
+ 'db_table': 'ice_role',
+ },
+ ),
+ migrations.CreateModel(
+ name='Vendor',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, unique=True)),
+ ('name', models.CharField(max_length=100, unique=True)),
+ ('public', models.BooleanField()),
+ ],
+ options={
+ 'db_table': 'ice_vendor',
+ },
+ ),
+ migrations.CreateModel(
+ name='VF',
+ fields=[
+ ('name', models.CharField(db_index=True, max_length=100)),
+ ('version', models.CharField(db_index=True, max_length=100, null=True)),
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('is_service_provider_internal', models.BooleanField(default=False)),
+ ('git_repo_url', models.CharField(default=-1, max_length=512)),
+ ('target_lab_entry_date', models.DateField(verbose_name='target_lab_entry_date')),
+ ('deployment_target', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='engagementmanager.DeploymentTarget')),
+ ('deployment_target_sites', models.ManyToManyField(blank=True, default=None, related_name='DeployTarget_sites', to='engagementmanager.DeploymentTargetSite')),
+ ('ecomp_release', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ECOMPRelease')),
+ ('engagement', models.OneToOneField(default=-1, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Engagement')),
+ ('vendor', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Vendor')),
+ ],
+ options={
+ 'db_table': 'ice_vf',
+ },
+ ),
+ migrations.CreateModel(
+ name='VFC',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('name', models.CharField(db_index=True, max_length=100)),
+ ('external_ref_id', models.CharField(default='', max_length=20)),
+ ('ice_mandated', models.BooleanField(default=False)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('company', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='engagementmanager.Vendor')),
+ ('creator', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='Vfc_creator', to='engagementmanager.IceUserProfile')),
+ ('vf', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.VF')),
+ ],
+ options={
+ 'db_table': 'ice_vfc',
+ },
+ ),
+ migrations.AddField(
+ model_name='recentengagement',
+ name='vf',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.VF'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='invitation',
+ unique_together=set([('engagement_uuid', 'email')]),
+ ),
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='company',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Vendor'),
+ ),
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='role',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Role'),
+ ),
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='user',
+ field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.CustomUser'),
+ ),
+ migrations.AddField(
+ model_name='feedback',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagementstatus',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='status_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagementstatus',
+ name='engagement',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='contact_user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='Engagement_contact_user', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='Engagement_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='engagement_team',
+ field=models.ManyToManyField(related_name='members', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='peer_reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='Engagement_peer_reviewer', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='Engagement_el_reviewer', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='starred_engagement',
+ field=models.ManyToManyField(blank=True, default=None, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='deploymenttarget',
+ unique_together=set([('name', 'version')]),
+ ),
+ migrations.AddField(
+ model_name='checklistsection',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistlineitem',
+ name='section',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistSection'),
+ ),
+ migrations.AddField(
+ model_name='checklistlineitem',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistdecision',
+ name='lineitem',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistLineItem'),
+ ),
+ migrations.AddField(
+ model_name='checklistdecision',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistauditlog',
+ name='creator',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='checklistauditlog',
+ name='decision',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistDecision'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='creator',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='checklist_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='engagement',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Engagement'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='owner',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='checklist_owner', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='applicationserviceinfrastructure',
+ unique_together=set([('name', 'uuid')]),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='activity_owner',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='engagement',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement'),
+ ),
+ migrations.AlterIndexTogether(
+ name='notification',
+ index_together=set([('user', 'is_read')]),
+ ),
+ migrations.AlterIndexTogether(
+ name='nextstep',
+ index_together=set([('engagement_stage', 'owner')]),
+ ),
+ migrations.AlterIndexTogether(
+ name='feedback',
+ index_together=set([('user',)]),
+ ),
+ migrations.AlterIndexTogether(
+ name='activity',
+ index_together=set([('engagement', 'activity_owner')]),
+ ),
+ migrations.RunPython(forwards),
+ migrations.RunPython(create_user_for_pre_user_profiles),
+ ]
diff --git a/django/engagementmanager/migrations/0002_auto_20160704_1028.py b/django/engagementmanager/migrations/0002_auto_20160704_1028.py
new file mode 100755
index 0000000..682394a
--- /dev/null
+++ b/django/engagementmanager/migrations/0002_auto_20160704_1028.py
@@ -0,0 +1,176 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-04 07:28
+from __future__ import unicode_literals
+
+import datetime
+
+from django.db import migrations, models
+import django.db.models.deletion
+from django.utils.timezone import utc
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='validationcycle',
+ name='vfc',
+ ),
+ migrations.DeleteModel(
+ name='ValidationException',
+ ),
+ migrations.AlterUniqueTogether(
+ name='validationsteps',
+ unique_together=set([]),
+ ),
+ migrations.RemoveField(
+ model_name='validationsteps',
+ name='test',
+ ),
+ migrations.RemoveField(
+ model_name='validationsteps',
+ name='validation_cycle',
+ ),
+ migrations.RemoveField(
+ model_name='validationsteps',
+ name='validation_exceptions',
+ ),
+ migrations.AlterModelOptions(
+ name='nextstep',
+ options={},
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='create_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_creator', to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='vfc',
+ name='create_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
+ ),
+ migrations.AddField(
+ model_name='vfc',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Vfc_creator', to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='vfc',
+ name='external_ref_id',
+ field=models.CharField(default='', max_length=20),
+ ),
+ migrations.AddField(
+ model_name='vfc',
+ name='ice_mandated',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_owner',
+ field=models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'3', b'eng_validation_request'), (b'4', b'next_steps'),
+ (b'2', b'ssh_key_added'), (b'1', b'user_joined_eng'), (b'5', b'vfc')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='contact_user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_contact_user', to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='target_completion_date',
+ field=models.DateField(blank=True, default=datetime.datetime(
+ 2016, 7, 20, 7, 28, 25, 168000, tzinfo=utc), null=True),
+ ),
+ migrations.AlterField(
+ model_name='vfc',
+ name='name',
+ field=models.CharField(max_length=100),
+ ),
+ migrations.AlterField(
+ model_name='vfc',
+ name='uuid',
+ field=models.CharField(max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ migrations.AlterUniqueTogether(
+ name='vfc',
+ unique_together=set([]),
+ ),
+ migrations.DeleteModel(
+ name='Test',
+ ),
+ migrations.DeleteModel(
+ name='ValidationCycle',
+ ),
+ migrations.DeleteModel(
+ name='ValidationSteps',
+ ),
+ migrations.RemoveField(
+ model_name='vfc',
+ name='id',
+ ),
+ migrations.RemoveField(
+ model_name='vfc',
+ name='version',
+ ),
+ migrations.RemoveField(
+ model_name='vfc',
+ name='vf_acronym',
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0003_auto_20160713_0929.py b/django/engagementmanager/migrations/0003_auto_20160713_0929.py
new file mode 100755
index 0000000..3bc94a0
--- /dev/null
+++ b/django/engagementmanager/migrations/0003_auto_20160713_0929.py
@@ -0,0 +1,85 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-13 09:29
+from __future__ import unicode_literals
+
+import datetime
+
+from django.db import migrations, models
+import django.db.models.deletion
+from django.utils.timezone import utc
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0002_auto_20160704_1028'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='nextstep',
+ options={'verbose_name_plural': 'Next steps'},
+ ),
+ migrations.AddField(
+ model_name='nextstep',
+ name='next_step_type',
+ field=models.CharField(choices=[(b'(3,)', b'add_contact_person'), (b'(5,)', b'el_handoff'), (b'(1,)', b'set_ssh'), (
+ b'(4,)', b'submit_vf_package'), (b'(2,)', b'trial_agreements'), (b'6', b'user_defined')], default=b'user_defined', max_length=36),
+ ),
+ migrations.AddField(
+ model_name='nextstep',
+ name='owner',
+ field=models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='target_completion_date',
+ field=models.DateField(blank=True, default=datetime.datetime(
+ 2016, 7, 29, 9, 29, 32, 642800, tzinfo=utc), null=True),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='engagement',
+ field=models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0004_auto_20160720_2143.py b/django/engagementmanager/migrations/0004_auto_20160720_2143.py
new file mode 100755
index 0000000..cfc04d3
--- /dev/null
+++ b/django/engagementmanager/migrations/0004_auto_20160720_2143.py
@@ -0,0 +1,68 @@
+#
+# ============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.
+
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-20 18:43
+from __future__ import unicode_literals
+
+import datetime
+
+from django.db import migrations, models
+from django.utils.timezone import utc
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0003_auto_20160713_0929'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='iceuser',
+ name='temp_password',
+ field=models.CharField(blank=True, default=None, max_length=256, null=True, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='target_completion_date',
+ field=models.DateField(blank=True, default=datetime.datetime(
+ 2016, 8, 5, 18, 43, 43, 473000, tzinfo=utc), null=True),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0005_auto_20160815_1248.py b/django/engagementmanager/migrations/0005_auto_20160815_1248.py
new file mode 100755
index 0000000..decbe51
--- /dev/null
+++ b/django/engagementmanager/migrations/0005_auto_20160815_1248.py
@@ -0,0 +1,95 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-15 09:48
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+import engagementmanager.models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0004_auto_20160720_2143'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='DeploymentTargetSite',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ],
+ options={
+ 'db_table': 'ice_deployment_target_site',
+ },
+ ),
+ migrations.AddField(
+ model_name='vendor',
+ name='public',
+ field=models.BooleanField(default=True),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='vfc',
+ name='company',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL,
+ to='engagementmanager.Vendor'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='target_completion_date',
+ field=models.DateField(
+ blank=True, default=engagementmanager.models.get_default_target_completion_date, null=True),
+ ),
+ migrations.AlterField(
+ model_name='iceuser',
+ name='temp_password',
+ field=models.CharField(blank=True, default=None, max_length=256, null=True),
+ ),
+ migrations.AddField(
+ model_name='vf',
+ name='deployment_target_sites',
+ field=models.ManyToManyField(blank=True, default=None, related_name='DeployTarget_sites',
+ to='engagementmanager.DeploymentTargetSite'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0006_auto_20160825_0644.py b/django/engagementmanager/migrations/0006_auto_20160825_0644.py
new file mode 100755
index 0000000..285631d
--- /dev/null
+++ b/django/engagementmanager/migrations/0006_auto_20160825_0644.py
@@ -0,0 +1,237 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-25 06:44
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0005_auto_20160815_1248'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Checklist',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='checklist name')),
+ ('state', models.CharField(choices=[(b'(4,)', b'approval'), (b'(7,)', b'archive'), (b'(1,)', b'automation'), (b'(6,)', b'closed'), (
+ b'(5,)', b'handoff'), (b'(3,)', b'peer_review'), (b'8', b'pending'), (b'(2,)', b'review')], default=b'automation', max_length=36)),
+ ('validation_cycle', models.IntegerField(verbose_name='validation cycle')),
+ ('weight', models.FloatField(default=0, verbose_name='checklist weight')),
+ ('associated_files', models.TextField(verbose_name='list of files from gitlab')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='checklist_creator', to='engagementmanager.IceUser')),
+ ],
+ options={
+ 'db_table': 'ice_checklist',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistAuditLog',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('category', models.CharField(max_length=255)),
+ ('description', models.TextField()),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('checklist', models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Checklist')),
+ ('creator', models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUser')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_audit_log',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistDecision',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('review_value', models.CharField(choices=[
+ (b'(1,)', b'approved'), (b'(2,)', b'denied'), (b'4', b'na'), (b'(3,)', b'not_relevant')], max_length=36)),
+ ('peer_review_value', models.CharField(choices=[
+ (b'(1,)', b'approved'), (b'(2,)', b'denied'), (b'4', b'na'), (b'(3,)', b'not_relevant')], max_length=36)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('checklist', models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Checklist')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_decision',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistLineItem',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='line name')),
+ ('weight', models.FloatField(verbose_name='line weight')),
+ ('description', models.TextField(verbose_name='line description')),
+ ('line_type', models.CharField(choices=[(b'(1,)', b'auto'),
+ (b'2', b'manual')], default=b'auto', max_length=36)),
+ ('validation_instructions', models.TextField(verbose_name='line validation instructions')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_line_item',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistSection',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='section name')),
+ ('weight', models.FloatField(verbose_name='checklist weight')),
+ ('description', models.TextField(verbose_name='section description')),
+ ('validation_instructions', models.TextField(verbose_name='section validation instructions')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ('parent_section', models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.ChecklistSection')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_section',
+ },
+ ),
+ migrations.CreateModel(
+ name='ChecklistTemplate',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='template name')),
+ ('category', models.CharField(choices=[
+ (b'3', b'glance'), (b'(2,)', b'heat'), (b'(1,)', b'overall')], default=b'overall', max_length=36)),
+ ('version', models.IntegerField(verbose_name='template version')),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time')),
+ ('update_time', models.DateTimeField(blank=True, null=True, verbose_name='last update time')),
+ ],
+ options={
+ 'db_table': 'ice_checklist_template',
+ },
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='peer_reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_peer_reviewer', to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='nextstep',
+ name='assignees',
+ field=models.ManyToManyField(related_name='assignees', to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='nextstep',
+ name='due_date',
+ field=models.DateField(null=True, verbose_name='due_date'),
+ ),
+ migrations.AddField(
+ model_name='nextstep',
+ name='files',
+ field=models.TextField(null=True, verbose_name='list of files'),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'6', b'change_checklist_state'), (b'3', b'eng_validation_request'), (
+ b'4', b'next_steps'), (b'2', b'ssh_key_added'), (b'1', b'user_joined_eng'), (b'5', b'vfc')], max_length=36),
+ ),
+ migrations.AddField(
+ model_name='checklistsection',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
+ to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistlineitem',
+ name='section',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ChecklistSection'),
+ ),
+ migrations.AddField(
+ model_name='checklistlineitem',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistdecision',
+ name='lineitem',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ChecklistLineItem'),
+ ),
+ migrations.AddField(
+ model_name='checklistdecision',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ChecklistTemplate'),
+ ),
+ migrations.AddField(
+ model_name='checklistauditlog',
+ name='decision',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ChecklistDecision'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='engagement',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Engagement'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='owner',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='checklist_owner', to='engagementmanager.IceUser'),
+ ),
+ migrations.AddField(
+ model_name='checklist',
+ name='template',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
+ to='engagementmanager.ChecklistTemplate'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0007_auto_20160922_0421.py b/django/engagementmanager/migrations/0007_auto_20160922_0421.py
new file mode 100755
index 0000000..655f30d
--- /dev/null
+++ b/django/engagementmanager/migrations/0007_auto_20160922_0421.py
@@ -0,0 +1,70 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-22 04:21
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0006_auto_20160825_0644'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ECOMPRelease',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=45)),
+ ],
+ options={
+ 'db_table': 'ice_ecomp_release',
+ },
+ ),
+ migrations.AddField(
+ model_name='vf',
+ name='ecomp_release',
+ field=models.ForeignKey(blank=True, null=True,
+ on_delete=django.db.models.deletion.SET_NULL, to='engagementmanager.ECOMPRelease'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0008_auto_20161009_1210.py b/django/engagementmanager/migrations/0008_auto_20161009_1210.py
new file mode 100755
index 0000000..ce6ddcc
--- /dev/null
+++ b/django/engagementmanager/migrations/0008_auto_20161009_1210.py
@@ -0,0 +1,74 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-10-09 12:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0007_auto_20160922_0421'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='RecentEngagement',
+ fields=[
+ ('uuid', models.CharField(max_length=64, primary_key=True, serialize=False)),
+ ('user_uuid', models.CharField(max_length=64)),
+ ('action_type', models.CharField(choices=[(b'(3,)', b'GOT_OWNERSHIP_OVER_ENGAGEMENT'), (b'(1,)', b'JOINED_TO_ENGAGEMENT'), (
+ b'(4,)', b'NAVIGATED_INTO_ENGAGEMENT'), (b'(2,)', b'NEXT_STEP_ASSIGNED')], max_length=36)),
+ ('last_update', models.DateTimeField(default=django.utils.timezone.now, verbose_name='update time')),
+ ('vf', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.VF')),
+ ],
+ options={
+ 'db_table': 'ice_recent_engagement',
+ },
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='starred_engagement',
+ field=models.ManyToManyField(to='engagementmanager.IceUser'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0009_auto_20161018_0740.py b/django/engagementmanager/migrations/0009_auto_20161018_0740.py
new file mode 100755
index 0000000..5536536
--- /dev/null
+++ b/django/engagementmanager/migrations/0009_auto_20161018_0740.py
@@ -0,0 +1,65 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-10-18 07:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0008_auto_20161009_1210'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='checklist',
+ name='state',
+ field=models.CharField(choices=[(b'(4,)', b'approval'), (b'(7,)', b'archive'), (b'(1,)', b'automation'), (b'(6,)', b'closed'), (
+ b'(5,)', b'handoff'), (b'(3,)', b'peer_review'), (b'8', b'pending'), (b'(2,)', b'review')], default=b'pending', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='recentengagement',
+ name='action_type',
+ field=models.CharField(choices=[(b'(3,)', b'GOT_OWNERSHIP_OVER_ENGAGEMENT'), (b'(1,)', b'JOINED_TO_ENGAGEMENT'), (
+ b'(4,)', b'NAVIGATED_INTO_ENGAGEMENT'), (b'(5,)', b'NEW_VF_CREATED'), (b'(2,)', b'NEXT_STEP_ASSIGNED')], max_length=36),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0010_auto_20161025_0838.py b/django/engagementmanager/migrations/0010_auto_20161025_0838.py
new file mode 100755
index 0000000..19f8db6
--- /dev/null
+++ b/django/engagementmanager/migrations/0010_auto_20161025_0838.py
@@ -0,0 +1,106 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-10-25 08:38
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0009_auto_20161018_0740'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'change_checklist_state', b'change_checklist_state'), (b'eng_validation_request', b'eng_validation_request'), (
+ b'next_steps', b'next_steps'), (b'ssh_key_added', b'ssh_key_added'), (b'user_joined_eng', b'user_joined_eng'), (b'vfc', b'vfc')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='state',
+ field=models.CharField(choices=[(b'approval', b'approval'), (b'archive', b'archive'), (b'automation', b'automation'), (b'closed', b'closed'), (
+ b'handoff', b'handoff'), (b'peer_review', b'peer_review'), (b'pending', b'pending'), (b'review', b'review')], default=b'pending', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='peer_review_value',
+ field=models.CharField(choices=[(b'approved', b'approved'), (b'denied', b'denied'),
+ (b'na', b'na'), (b'not_relevant', b'not_relevant')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='review_value',
+ field=models.CharField(choices=[(b'approved', b'approved'), (b'denied', b'denied'),
+ (b'na', b'na'), (b'not_relevant', b'not_relevant')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistlineitem',
+ name='line_type',
+ field=models.CharField(choices=[(b'auto', b'auto'), (b'manual', b'manual')],
+ default=b'auto', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklisttemplate',
+ name='category',
+ field=models.CharField(choices=[(b'glance', b'glance'), (b'heat', b'heat'),
+ (b'overall', b'overall')], default=b'overall', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='starred_engagement',
+ field=models.ManyToManyField(blank=True, to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='next_step_type',
+ field=models.CharField(choices=[(b'add_contact_person', b'add_contact_person'), (b'el_handoff', b'el_handoff'), (b'set_ssh', b'set_ssh'), (
+ b'submit_vf_package', b'submit_vf_package'), (b'trial_agreements', b'trial_agreements'), (b'user_defined', b'user_defined')], default=b'user_defined', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='recentengagement',
+ name='action_type',
+ field=models.CharField(choices=[(b'GOT_OWNERSHIP_OVER_ENGAGEMENT', b'GOT_OWNERSHIP_OVER_ENGAGEMENT'), (b'JOINED_TO_ENGAGEMENT', b'JOINED_TO_ENGAGEMENT'), (
+ b'NAVIGATED_INTO_ENGAGEMENT', b'NAVIGATED_INTO_ENGAGEMENT'), (b'NEW_VF_CREATED', b'NEW_VF_CREATED'), (b'NEXT_STEP_ASSIGNED', b'NEXT_STEP_ASSIGNED')], max_length=36),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0011_auto_20161109_0811.py b/django/engagementmanager/migrations/0011_auto_20161109_0811.py
new file mode 100755
index 0000000..9bcf50c
--- /dev/null
+++ b/django/engagementmanager/migrations/0011_auto_20161109_0811.py
@@ -0,0 +1,81 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-11-09 08:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0010_auto_20161025_0838'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_manual_id',
+ field=models.CharField(max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='starred_engagement',
+ field=models.ManyToManyField(blank=True, default=None, to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='ecomp_release',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.ECOMPRelease'),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='engagement',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.Engagement'),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='git_repo_url',
+ field=models.CharField(default='', max_length=512),
+ preserve_default=False,
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0012_auto_20161109_0822.py b/django/engagementmanager/migrations/0012_auto_20161109_0822.py
new file mode 100755
index 0000000..79214dc
--- /dev/null
+++ b/django/engagementmanager/migrations/0012_auto_20161109_0822.py
@@ -0,0 +1,82 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-11-09 08:22
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0011_auto_20161109_0811'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='engagement',
+ name='reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_el_reviewer', to='engagementmanager.IceUser'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_manual_id',
+ field=models.CharField(default=-1, max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='state',
+ field=models.CharField(choices=[(b'Completed', b'Completed'), (b'Confirmed',
+ b'Confirmed'), (b'TODO', b'TODO')], max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='engagement',
+ field=models.ForeignKey(default=-1, on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.Engagement'),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='git_repo_url',
+ field=models.CharField(default=-1, max_length=512),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0013_auto_20161128_1159.py b/django/engagementmanager/migrations/0013_auto_20161128_1159.py
new file mode 100755
index 0000000..06a55c1
--- /dev/null
+++ b/django/engagementmanager/migrations/0013_auto_20161128_1159.py
@@ -0,0 +1,99 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-11-28 09:59
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0012_auto_20161109_0822'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='engagement',
+ name='active_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='active time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='aic_instantiation_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='aic instantiation time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='asdc_onboarding_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='asdc onboarding time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='completed_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='completed time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='heat_validated_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='heat validated time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='image_scan_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='image scan time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='intake_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='intake time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='started_state_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='started state time'),
+ ),
+ migrations.AddField(
+ model_name='engagement',
+ name='validated_time',
+ field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='validated time'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0014_auto_20161129_1145.py b/django/engagementmanager/migrations/0014_auto_20161129_1145.py
new file mode 100755
index 0000000..ee4efd4
--- /dev/null
+++ b/django/engagementmanager/migrations/0014_auto_20161129_1145.py
@@ -0,0 +1,104 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-11-29 09:45
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0013_auto_20161128_1159'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'change_checklist_state', b'change_checklist_state'), (b'eng_validation_request', b'eng_validation_request'), (b'next_steps', b'next_steps'), (b'ssh_key_added', b'ssh_key_added'), (
+ b'test_finished_event', b'test_finished_event'), (b'user_joined_eng', b'user_joined_eng'), (b'vf_provisioing_event', b'vf_provisioing_event'), (b'vfc', b'vfc')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='active_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='active time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='aic_instantiation_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='aic instantiation time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='asdc_onboarding_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='asdc onboarding time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='completed_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='completed time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='heat_validated_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='heat validated time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='image_scan_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='image scan time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='intake_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='intake time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='started_state_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='started state time'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='validated_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='validated time'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0015_engagementstatus.py b/django/engagementmanager/migrations/0015_engagementstatus.py
new file mode 100755
index 0000000..84eee4d
--- /dev/null
+++ b/django/engagementmanager/migrations/0015_engagementstatus.py
@@ -0,0 +1,71 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-12-07 09:15
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0014_auto_20161129_1145'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='EngagementStatus',
+ fields=[
+ ('uuid', models.CharField(max_length=64, primary_key=True, serialize=False)),
+ ('description', models.CharField(max_length=256)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('update_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('creator', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='status_creator', to='engagementmanager.IceUser')),
+ ('engagement', models.ForeignKey(
+ on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement')),
+ ],
+ options={
+ 'db_table': 'ice_engagement_status',
+ },
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0016_auto_20161208_0842.py b/django/engagementmanager/migrations/0016_auto_20161208_0842.py
new file mode 100755
index 0000000..92d1518
--- /dev/null
+++ b/django/engagementmanager/migrations/0016_auto_20161208_0842.py
@@ -0,0 +1,59 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-12-08 08:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0015_engagementstatus'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_stage',
+ field=models.CharField(choices=[(b'Active', b'Active'), (b'Completed', b'Completed'),
+ (b'Intake', b'Intake'), (b'Validated', b'Validated')], default=b'Intake', max_length=15),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0017_auto_20161215_1535.py b/django/engagementmanager/migrations/0017_auto_20161215_1535.py
new file mode 100755
index 0000000..c0adc38
--- /dev/null
+++ b/django/engagementmanager/migrations/0017_auto_20161215_1535.py
@@ -0,0 +1,74 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-12-15 13:35
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0016_auto_20161208_0842'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Invitation',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False)),
+ ('engagement_uuid', models.CharField(db_index=True, max_length=64)),
+ ('invited_by_user_uuid', models.CharField(db_index=True, max_length=64)),
+ ('email', models.CharField(max_length=255)),
+ ('invitation_token', models.CharField(max_length=1024)),
+ ('accepted', models.BooleanField(default=False)),
+ ('create_time', models.DateTimeField(
+ default=django.utils.timezone.now, verbose_name='invitation creation time')),
+ ],
+ options={
+ 'db_table': 'ice_invitation',
+ },
+ ),
+ migrations.AlterUniqueTogether(
+ name='invitation',
+ unique_together=set([('engagement_uuid', 'email')]),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0018_set_old_notif_true.py b/django/engagementmanager/migrations/0018_set_old_notif_true.py
new file mode 100755
index 0000000..76e8265
--- /dev/null
+++ b/django/engagementmanager/migrations/0018_set_old_notif_true.py
@@ -0,0 +1,54 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-12-29 13:49
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0017_auto_20161215_1535'),
+ ]
+
+ operations = [
+ migrations.RunSQL("update ice_notification SET is_sent = 't' where is_sent = 'f';"),
+ ]
diff --git a/django/engagementmanager/migrations/0019_auto_20170104_1715.py b/django/engagementmanager/migrations/0019_auto_20170104_1715.py
new file mode 100755
index 0000000..329ffa3
--- /dev/null
+++ b/django/engagementmanager/migrations/0019_auto_20170104_1715.py
@@ -0,0 +1,59 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2017-01-04 17:15
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0018_set_old_notif_true'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_stage',
+ field=models.CharField(choices=[(b'Active', b'Active'), (b'Archived', b'Archived'), (b'Completed', b'Completed'), (
+ b'Intake', b'Intake'), (b'Validated', b'Validated')], default=b'Intake', max_length=15),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0020_add_indexes_20170108.py b/django/engagementmanager/migrations/0020_add_indexes_20170108.py
new file mode 100755
index 0000000..2b71e1e
--- /dev/null
+++ b/django/engagementmanager/migrations/0020_add_indexes_20170108.py
@@ -0,0 +1,109 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2017-01-12 08:39
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0019_auto_20170104_1715'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='ContactRequest',
+ ),
+ migrations.DeleteModel(
+ name='EngagementRequest',
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_manual_id',
+ field=models.CharField(db_index=True, default=-1, max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_stage',
+ field=models.CharField(choices=[(b'Active', b'Active'), (b'Archived', b'Archived'), (b'Completed', b'Completed'), (
+ b'Intake', b'Intake'), (b'Validated', b'Validated')], db_index=True, default=b'Intake', max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='iceuser',
+ name='email',
+ field=models.EmailField(db_index=True, max_length=254, unique=True, verbose_name='email'),
+ ),
+ migrations.AlterField(
+ model_name='invitation',
+ name='invitation_token',
+ field=models.CharField(db_index=True, max_length=1024),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='engagement',
+ field=models.OneToOneField(default=-1, on_delete=django.db.models.deletion.CASCADE,
+ to='engagementmanager.Engagement'),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='name',
+ field=models.CharField(db_index=True, max_length=100),
+ ),
+ migrations.AlterField(
+ model_name='vfc',
+ name='name',
+ field=models.CharField(db_index=True, max_length=100),
+ ),
+ migrations.AlterIndexTogether(
+ name='activity',
+ index_together=set([('engagement', 'activity_owner')]),
+ ),
+ migrations.AlterIndexTogether(
+ name='nextstep',
+ index_together=set([('engagement_stage', 'owner')]),
+ ),
+ migrations.AlterIndexTogether(
+ name='notification',
+ index_together=set([('user', 'is_read')]),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0021_generate_excel_overview_sheet_procedure_20170110.py b/django/engagementmanager/migrations/0021_generate_excel_overview_sheet_procedure_20170110.py
new file mode 100755
index 0000000..b902df4
--- /dev/null
+++ b/django/engagementmanager/migrations/0021_generate_excel_overview_sheet_procedure_20170110.py
@@ -0,0 +1,65 @@
+#
+# ============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 __future__ import unicode_literals
+
+import os
+
+from django.db import migrations, connection
+
+import engagementmanager
+
+
+def forwards(apps, schema_editor):
+ if not schema_editor.connection.alias == 'default':
+ return
+
+ cursor = connection.cursor()
+ cursor.execute(open(os.path.join(os.path.dirname(engagementmanager.__file__),
+ 'sql-scripts/generate_excel_overview_sheet_procedure.sql'), "r").read())
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0020_add_indexes_20170108'),
+ ]
+
+ operations = [
+ migrations.RunPython(forwards),
+ ]
diff --git a/django/engagementmanager/migrations/0022_auto_20170118_1520.py b/django/engagementmanager/migrations/0022_auto_20170118_1520.py
new file mode 100755
index 0000000..b90451b
--- /dev/null
+++ b/django/engagementmanager/migrations/0022_auto_20170118_1520.py
@@ -0,0 +1,275 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-01-18 15:20
+from __future__ import unicode_literals
+
+import logging
+
+from django.conf import settings
+import django.contrib.auth.models
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+logger = logging.getLogger('ice.logger')
+
+
+def create_user_for_pre_user_profiles(apps, schema_editor):
+ CustomUser = apps.get_model("engagementmanager", "CustomUser")
+ IceUserProfile = apps.get_model("engagementmanager", "IceUserProfile")
+ users_list = IceUserProfile.objects.filter(user=None)
+ count = 0
+ for profile in users_list:
+ try:
+ custom_user, created = CustomUser.objects.get_or_create(username=profile.email)
+ custom_user.is_active = profile.is_active
+ custom_user.email = profile.email
+ custom_user.activation_token = profile.activation_token
+ custom_user.password = profile.password
+ custom_user.activation_token_create_time = profile.activation_token_create_time
+ custom_user.save()
+ profile.user = custom_user
+ profile.save()
+
+ except Exception as e:
+ logger.error("migrations fail, error:")
+ logger.error(e.message)
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ # ('auth', '0009_auto_20170118_0740'),
+ ('engagementmanager', '0021_generate_excel_overview_sheet_procedure_20170110'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='CustomUser',
+ fields=[
+ ('user_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE,
+ parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
+ ('activation_token', models.CharField(max_length=128, null=True, unique=True)),
+ ('activation_token_create_time', models.DateTimeField(
+ default=django.utils.timezone.now, null=True, verbose_name='activation_token_create_time')),
+ ('temp_password', models.CharField(blank=True, default=None, max_length=256, null=True)),
+ ],
+ options={
+ 'abstract': False,
+ 'verbose_name': 'user',
+ 'verbose_name_plural': 'users',
+ },
+ bases=('auth.user',),
+ managers=[
+ ('objects', django.contrib.auth.models.UserManager()),
+ ],
+ ),
+ migrations.AlterModelTable('IceUser', 'ice_user_profile'),
+ migrations.RenameModel('IceUser', 'IceUserProfile'),
+ migrations.AddField(
+ model_name='IceUserProfile',
+ name='user',
+ field=models.OneToOneField(null=True, on_delete=django.db.models.CASCADE, to='engagementmanager.CustomUser')
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'user_joined_eng', b'user_joined_eng'), (b'ssh_key_added', b'ssh_key_added'), (b'eng_validation_request', b'eng_validation_request'), (b'next_steps', b'next_steps'), (
+ b'vfc', b'vfc'), (b'change_checklist_state', b'change_checklist_state'), (b'vf_provisioing_event', b'vf_provisioing_event'), (b'test_finished_event', b'test_finished_event')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='state',
+ field=models.CharField(choices=[(b'pending', b'pending'), (b'automation', b'automation'), (b'review', b'review'), (b'peer_review', b'peer_review'), (
+ b'approval', b'approval'), (b'handoff', b'handoff'), (b'closed', b'closed'), (b'archive', b'archive')], default=b'pending', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='peer_review_value',
+ field=models.CharField(choices=[(b'na', b'na'), (b'approved', b'approved'),
+ (b'denied', b'denied'), (b'not_relevant', b'not_relevant')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='review_value',
+ field=models.CharField(choices=[(b'na', b'na'), (b'approved', b'approved'),
+ (b'denied', b'denied'), (b'not_relevant', b'not_relevant')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistlineitem',
+ name='line_type',
+ field=models.CharField(
+ choices=[(b'manual', b'manual'), (b'auto', b'auto')], default=b'auto', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklisttemplate',
+ name='category',
+ field=models.CharField(choices=[(b'glance', b'glance'), (b'instantiation', b'instantiation'), (
+ b'asdc', b'asdc'), (b'overall', b'overall'), (b'heat', b'heat')], default=b'overall', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_stage',
+ field=models.CharField(choices=[(b'Archived', b'Archived'), (b'Intake', b'Intake'), (b'Active', b'Active'), (
+ b'Validated', b'Validated'), (b'Completed', b'Completed')], db_index=True, default=b'Intake', max_length=15),
+ ),
+
+ migrations.AlterField(
+ model_name='nextstep',
+ name='next_step_type',
+ field=models.CharField(choices=[(b'user_defined', b'user_defined'), (b'set_ssh', b'set_ssh'), (b'trial_agreements', b'trial_agreements'), (
+ b'add_contact_person', b'add_contact_person'), (b'submit_vf_package', b'submit_vf_package'), (b'el_handoff', b'el_handoff')], default=b'user_defined', max_length=36),
+ ),
+
+ migrations.AlterField(
+ model_name='nextstep',
+ name='state',
+ field=models.CharField(
+ choices=[(b'Confirmed', b'Confirmed'), (b'TODO', b'TODO'), (b'Completed', b'Completed')], max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='recentengagement',
+ name='action_type',
+ field=models.CharField(choices=[(b'JOINED_TO_ENGAGEMENT', b'JOINED_TO_ENGAGEMENT'), (b'NEXT_STEP_ASSIGNED', b'NEXT_STEP_ASSIGNED'), (
+ b'GOT_OWNERSHIP_OVER_ENGAGEMENT', b'GOT_OWNERSHIP_OVER_ENGAGEMENT'), (b'NAVIGATED_INTO_ENGAGEMENT', b'NAVIGATED_INTO_ENGAGEMENT'), (b'NEW_VF_CREATED', b'NEW_VF_CREATED')], max_length=36),
+ ),
+ # migrations.DeleteModel(
+ # name='IceUser',
+ # ),
+ migrations.RunPython(create_user_for_pre_user_profiles),
+ migrations.AlterField(
+ model_name='notification',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='vfc',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Vfc_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='owner',
+ field=models.ForeignKey(
+ blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_team',
+ field=models.ManyToManyField(related_name='members', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='contact_user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_contact_user', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='checklistauditlog',
+ name='creator',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='peer_reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_peer_reviewer', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='reviewer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='Engagement_el_reviewer', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='starred_engagement',
+ field=models.ManyToManyField(blank=True, default=None, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='engagementstatus',
+ name='creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='status_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='assignees',
+ field=models.ManyToManyField(related_name='assignees', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='creator',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
+ related_name='NextStep_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='last_updater',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT,
+ related_name='NextStep_last_updater', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_owner',
+ field=models.ForeignKey(
+ blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='creator',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='checklist_creator', to='engagementmanager.IceUserProfile'),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='owner',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='checklist_owner', to='engagementmanager.IceUserProfile'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0023_auto_20170123_1445.py b/django/engagementmanager/migrations/0023_auto_20170123_1445.py
new file mode 100755
index 0000000..cd01832
--- /dev/null
+++ b/django/engagementmanager/migrations/0023_auto_20170123_1445.py
@@ -0,0 +1,108 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-01-23 14:45
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0022_auto_20170118_1520'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='customuser',
+ options={},
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='activation_token',
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='activation_token_create_time',
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='is_active',
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='last_login',
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='password',
+ ),
+ migrations.RemoveField(
+ model_name='iceuserprofile',
+ name='temp_password',
+ ),
+ migrations.AlterField(
+ model_name='iceuserprofile',
+ name='company',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT,
+ to='engagementmanager.Vendor'),
+ ),
+ migrations.AlterField(
+ model_name='iceuserprofile',
+ name='is_att_contact',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='iceuserprofile',
+ name='role',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT,
+ to='engagementmanager.Role'),
+ ),
+ migrations.AlterField(
+ model_name='iceuserprofile',
+ name='user',
+ field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.CustomUser'),
+ ),
+ migrations.AlterModelTable(
+ name='customuser',
+ table='ice_custom_user',
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0024_auto_20170227_1224.py b/django/engagementmanager/migrations/0024_auto_20170227_1224.py
new file mode 100755
index 0000000..3481eb5
--- /dev/null
+++ b/django/engagementmanager/migrations/0024_auto_20170227_1224.py
@@ -0,0 +1,64 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2017-02-27 12:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0023_auto_20170123_1445'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='engagement',
+ name='archive_reason',
+ field=models.TextField(default=None, null=True),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[(b'user_joined_eng', b'user_joined_eng'), (b'ssh_key_added', b'ssh_key_added'), (b'eng_validation_request', b'eng_validation_request'), (b'next_steps', b'next_steps'), (b'vfc', b'vfc'), (
+ b'change_checklist_state', b'change_checklist_state'), (b'vf_provisioing_event', b'vf_provisioing_event'), (b'test_finished_event', b'test_finished_event'), (b'change_engagement_stage', b'change_engagement_stage')], max_length=36),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0025_change_nextsteps_to_new_state.py b/django/engagementmanager/migrations/0025_change_nextsteps_to_new_state.py
new file mode 100755
index 0000000..bfec64d
--- /dev/null
+++ b/django/engagementmanager/migrations/0025_change_nextsteps_to_new_state.py
@@ -0,0 +1,54 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0024_auto_20170227_1224'),
+ ]
+
+ operations = [
+ migrations.RunSQL("update ice_next_step set state = 'Incomplete' where state = 'TODO';"),
+ migrations.RunSQL("update ice_next_step set state = 'Completed' where state = 'Confirmed';"),
+ ]
diff --git a/django/engagementmanager/migrations/0026_add_slack_handle_to_ice_user_profile.py b/django/engagementmanager/migrations/0026_add_slack_handle_to_ice_user_profile.py
new file mode 100755
index 0000000..489b6ce
--- /dev/null
+++ b/django/engagementmanager/migrations/0026_add_slack_handle_to_ice_user_profile.py
@@ -0,0 +1,57 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0025_change_nextsteps_to_new_state'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='slack_handle',
+ field=models.CharField(blank=True, default=None, max_length=64, null=True),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0027_add_version_to_vf.py b/django/engagementmanager/migrations/0027_add_version_to_vf.py
new file mode 100755
index 0000000..3bd618e
--- /dev/null
+++ b/django/engagementmanager/migrations/0027_add_version_to_vf.py
@@ -0,0 +1,58 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-04-06 08:05
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0026_add_slack_handle_to_ice_user_profile'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='vf',
+ name='version',
+ field=models.CharField(db_index=True, max_length=100, null=True),
+ )
+ ]
diff --git a/django/engagementmanager/migrations/0028_auto_20170425_1310.py b/django/engagementmanager/migrations/0028_auto_20170425_1310.py
new file mode 100755
index 0000000..68e15f5
--- /dev/null
+++ b/django/engagementmanager/migrations/0028_auto_20170425_1310.py
@@ -0,0 +1,111 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-04-25 13:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0027_add_version_to_vf'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[('user_joined_eng', 'user_joined_eng'), ('ssh_key_added', 'ssh_key_added'), ('eng_validation_request', 'eng_validation_request'), ('next_steps', 'next_steps'), ('vfc', 'vfc'), (
+ 'change_checklist_state', 'change_checklist_state'), ('vf_provisioing_event', 'vf_provisioing_event'), ('test_finished_event', 'test_finished_event'), ('change_engagement_stage', 'change_engagement_stage')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='state',
+ field=models.CharField(choices=[('automation', 'automation'), ('review', 'review'), ('peer_review', 'peer_review'), ('approval', 'approval'), (
+ 'handoff', 'handoff'), ('closed', 'closed'), ('archive', 'archive'), ('pending', 'pending')], default='pending', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='peer_review_value',
+ field=models.CharField(choices=[('approved', 'approved'), ('denied', 'denied'),
+ ('not_relevant', 'not_relevant'), ('na', 'na')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='review_value',
+ field=models.CharField(choices=[('approved', 'approved'), ('denied', 'denied'),
+ ('not_relevant', 'not_relevant'), ('na', 'na')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklistlineitem',
+ name='line_type',
+ field=models.CharField(choices=[('auto', 'auto'), ('manual', 'manual')], default='auto', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='checklisttemplate',
+ name='category',
+ field=models.CharField(choices=[('overall', 'overall'), ('heat', 'heat'), ('glance', 'glance'),
+ ('instantiation', 'instantiation'), ('asdc', 'asdc')], default='overall', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='engagement_stage',
+ field=models.CharField(choices=[('Intake', 'Intake'), ('Active', 'Active'), ('Validated', 'Validated'), (
+ 'Completed', 'Completed'), ('Archived', 'Archived')], db_index=True, default='Intake', max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='next_step_type',
+ field=models.CharField(choices=[('set_ssh', 'set_ssh'), ('trial_agreements', 'trial_agreements'), ('add_contact_person', 'add_contact_person'), (
+ 'submit_vf_package', 'submit_vf_package'), ('el_handoff', 'el_handoff'), ('user_defined', 'user_defined')], default='user_defined', max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='state',
+ field=models.CharField(choices=[('Incomplete', 'Incomplete'), ('Completed', 'Completed')], max_length=15),
+ ),
+ migrations.AlterField(
+ model_name='recentengagement',
+ name='action_type',
+ field=models.CharField(choices=[('JOINED_TO_ENGAGEMENT', 'JOINED_TO_ENGAGEMENT'), ('NEXT_STEP_ASSIGNED', 'NEXT_STEP_ASSIGNED'), ('GOT_OWNERSHIP_OVER_ENGAGEMENT',
+ 'GOT_OWNERSHIP_OVER_ENGAGEMENT'), ('NAVIGATED_INTO_ENGAGEMENT', 'NAVIGATED_INTO_ENGAGEMENT'), ('NEW_VF_CREATED', 'NEW_VF_CREATED')], max_length=36),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0029_auto_20170504_0749.py b/django/engagementmanager/migrations/0029_auto_20170504_0749.py
new file mode 100755
index 0000000..f1a4f9a
--- /dev/null
+++ b/django/engagementmanager/migrations/0029_auto_20170504_0749.py
@@ -0,0 +1,73 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-05-04 07:49
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0028_auto_20170425_1310'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='deploymenttarget',
+ name='ui_visibility',
+ field=models.BooleanField(default=True),
+ ),
+ migrations.AddField(
+ model_name='deploymenttarget',
+ name='weight',
+ field=models.IntegerField(default=1),
+ ),
+ migrations.AddField(
+ model_name='ecomprelease',
+ name='ui_visibility',
+ field=models.BooleanField(default=True),
+ ),
+ migrations.AddField(
+ model_name='ecomprelease',
+ name='weight',
+ field=models.IntegerField(default=1),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0030_engagement_archived_time.py b/django/engagementmanager/migrations/0030_engagement_archived_time.py
new file mode 100755
index 0000000..b24f67a
--- /dev/null
+++ b/django/engagementmanager/migrations/0030_engagement_archived_time.py
@@ -0,0 +1,58 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-06-07 08:13
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0029_auto_20170504_0749'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='engagement',
+ name='archived_time',
+ field=models.DateTimeField(blank=True, null=True, verbose_name='archived time'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0031_auto_20170620_1312.py b/django/engagementmanager/migrations/0031_auto_20170620_1312.py
new file mode 100755
index 0000000..f1956c4
--- /dev/null
+++ b/django/engagementmanager/migrations/0031_auto_20170620_1312.py
@@ -0,0 +1,64 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-06-20 13:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0030_engagement_archived_time'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[('user_joined_eng', 'user_joined_eng'), ('ssh_key_added', 'ssh_key_added'), ('eng_validation_request', 'eng_validation_request'), ('update_next_steps', 'update_next_steps'), ('vfc', 'vfc'), ('change_checklist_state', 'change_checklist_state'), ('vf_provisioning_event', 'vf_provisioning_event'), ('test_finished_event', 'test_finished_event'), ('change_engagement_stage', 'change_engagement_stage'), ('add_next_steps', 'add_next_steps'), ('delete_next_steps', 'delete_next_steps')], max_length=36),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='engagement',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='engagementmanager.Engagement'),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0032_auto_20170702_1435.py b/django/engagementmanager/migrations/0032_auto_20170702_1435.py
new file mode 100755
index 0000000..53e5a22
--- /dev/null
+++ b/django/engagementmanager/migrations/0032_auto_20170702_1435.py
@@ -0,0 +1,71 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-07-02 14:35
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0031_auto_20170620_1312'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Feedback',
+ fields=[
+ ('uuid', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('create_time', models.DateTimeField(default=django.utils.timezone.now)),
+ ('description', models.TextField(verbose_name='feedback_description')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engagementmanager.IceUserProfile')),
+ ],
+ options={
+ 'db_table': 'ice_feedback',
+ },
+ ),
+ migrations.AlterIndexTogether(
+ name='feedback',
+ index_together=set([('user',)]),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0033_auto_20170704_0635.py b/django/engagementmanager/migrations/0033_auto_20170704_0635.py
new file mode 100755
index 0000000..c6d1bb6
--- /dev/null
+++ b/django/engagementmanager/migrations/0033_auto_20170704_0635.py
@@ -0,0 +1,169 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-07-04 06:35
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import uuid
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0032_auto_20170702_1435'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='activity',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='applicationserviceinfrastructure',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='checklist',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='checklistauditlog',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='checklistdecision',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='checklistlineitem',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='checklistsection',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='checklisttemplate',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='deploymenttarget',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='deploymenttargetsite',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='ecomprelease',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='engagement',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='engagementstatus',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='feedback',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='iceuserprofile',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='invitation',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='nextstep',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='notification',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='recentengagement',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=64, primary_key=True, serialize=False),
+ ),
+ migrations.AlterField(
+ model_name='role',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='vendor',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='vf',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='vfc',
+ name='uuid',
+ field=models.CharField(default=uuid.uuid4, max_length=36, primary_key=True, serialize=False, unique=True),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0034_engagement_is_with_files.py b/django/engagementmanager/migrations/0034_engagement_is_with_files.py
new file mode 100755
index 0000000..01d15f5
--- /dev/null
+++ b/django/engagementmanager/migrations/0034_engagement_is_with_files.py
@@ -0,0 +1,58 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-07-13 04:48
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0033_auto_20170704_0635'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='engagement',
+ name='is_with_files',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0035_rgwa_fields.py b/django/engagementmanager/migrations/0035_rgwa_fields.py
new file mode 100755
index 0000000..cce62bf
--- /dev/null
+++ b/django/engagementmanager/migrations/0035_rgwa_fields.py
@@ -0,0 +1,68 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-07-25 07:43
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0034_engagement_is_with_files'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='rgwa_access_key',
+ field=models.CharField(blank=True, max_length=1024, null=True, unique=True),
+ ),
+ migrations.AddField(
+ model_name='iceuserprofile',
+ name='rgwa_secret_key',
+ field=models.CharField(blank=True, max_length=1024, null=True, unique=True),
+ ),
+ migrations.AlterField(
+ model_name='activity',
+ name='activity_type',
+ field=models.CharField(choices=[('user_joined_eng', 'user_joined_eng'), ('ssh_key_added', 'ssh_key_added'), ('eng_validation_request', 'eng_validation_request'), ('update_next_steps', 'update_next_steps'), ('vfc', 'vfc'), ('change_checklist_state', 'change_checklist_state'), ('vf_provisioning_event', 'vf_provisioning_event'), ('test_finished_event', 'test_finished_event'), ('change_engagement_stage', 'change_engagement_stage'), ('add_next_steps', 'add_next_steps'), ('delete_next_steps', 'delete_next_steps'), ('notice_empty_engagement', 'notice_empty_engagement')], max_length=36),
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/0036_auto_20170906_0935.py b/django/engagementmanager/migrations/0036_auto_20170906_0935.py
new file mode 100755
index 0000000..7c85b6c
--- /dev/null
+++ b/django/engagementmanager/migrations/0036_auto_20170906_0935.py
@@ -0,0 +1,63 @@
+#
+# ============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.
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.6 on 2017-09-06 09:35
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('engagementmanager', '0035_rgwa_fields'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='iceuserprofile',
+ old_name='is_att_contact',
+ new_name='is_service_provider_contact',
+ ),
+ migrations.RenameField(
+ model_name='vf',
+ old_name='is_att_internal',
+ new_name='is_service_provider_internal',
+ ),
+ ]
diff --git a/django/engagementmanager/migrations/__init__.py b/django/engagementmanager/migrations/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/migrations/__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/models.py b/django/engagementmanager/models.py
new file mode 100755
index 0000000..71deb84
--- /dev/null
+++ b/django/engagementmanager/models.py
@@ -0,0 +1,615 @@
+#
+# ============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 __future__ import unicode_literals
+import uuid
+from django.contrib.auth.models import User
+from django.db import models
+from django.db.models.deletion import SET_NULL
+from django.db.models.signals import post_save
+from django.utils import timezone
+from django.utils.timezone import timedelta
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.constants import EngagementStage, ActivityType, NextStepType, CheckListState, CheckListCategory, CheckListDecisionValue, CheckListLineType, \
+ RecentEngagementActionType, NextStepState
+
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Role(models.Model):
+ uuid = models.CharField(default=uuid.uuid4, max_length=36, unique=True)
+ name = models.CharField(max_length=36, unique=True)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_role"
+
+
+class Vendor(models.Model):
+ uuid = models.CharField(default=uuid.uuid4, max_length=36, unique=True)
+ name = models.CharField(max_length=100, unique=True)
+ public = models.BooleanField()
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_vendor"
+
+
+class CustomUser(User):
+ activation_token = models.CharField(max_length=128, unique=True, null=True)
+ activation_token_create_time = models.DateTimeField(
+ 'activation_token_create_time', default=timezone.now, null=True)
+ temp_password = models.CharField(
+ max_length=256, null=True, blank=True, default=None)
+
+ def __str__(self):
+ return self.email
+
+ class Meta:
+ db_table = "ice_custom_user"
+
+
+class IceUserProfile(models.Model):
+ user = models.OneToOneField(
+ CustomUser, null=False, on_delete=models.CASCADE)
+ uuid = models.CharField(default=uuid.uuid4, max_length=36, unique=True)
+ company = models.ForeignKey(Vendor, on_delete=models.PROTECT, null=True)
+ phone_number = models.CharField(max_length=30)
+ full_name = models.CharField(max_length=30)
+ role = models.ForeignKey(Role, on_delete=models.PROTECT, null=True)
+ # although number of expected users<10^5 we prefer to index it
+ email = models.EmailField('email', unique=True, db_index=True)
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ ssh_public_key = models.CharField(
+ 'ssh_public_key', max_length=1024, null=True, blank=True)
+ regular_email_updates = models.BooleanField(default=False)
+ email_updates_on_every_notification = models.BooleanField(default=True)
+ email_updates_daily_digest = models.BooleanField(default=False)
+ is_service_provider_contact = models.BooleanField(default=False)
+ rgwa_access_key = models.CharField(
+ max_length=1024, null=True, blank=True, unique=True)
+ rgwa_secret_key = models.CharField(
+ max_length=1024, null=True, blank=True, unique=True)
+ slack_handle = models.CharField(
+ max_length=64, null=True, blank=True, default=None)
+
+ def __str__(self):
+ return self.full_name + " - " + self.email
+
+ class Meta:
+ db_table = "ice_user_profile"
+
+
+def create_user_profile(sender, instance, created, **kwargs):
+ if created:
+ user = CustomUser.objects.get(username=instance)
+ profile, created = IceUserProfile.objects.get_or_create(
+ user=user, email=instance)
+
+
+post_save.connect(create_user_profile, sender=CustomUser)
+
+
+# Represents Deployment Target Cloud Version. For example name=AIC version=2.0
+class DeploymentTarget(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField(max_length=45)
+ version = models.CharField(max_length=100)
+ weight = models.IntegerField(default=1)
+ ui_visibility = models.BooleanField(default=True)
+
+ def __str__(self):
+ return self.name + ", Version: " + self.version
+
+ class Meta:
+ db_table = "ice_deployment_target"
+ unique_together = (("name", "version"),)
+
+
+# Represents ECOMPRelease
+class ECOMPRelease(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField(max_length=45)
+ weight = models.IntegerField(default=1)
+ ui_visibility = models.BooleanField(default=True)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_ecomp_release"
+
+
+# Represents Deployment Target site, for example: Willows. It is connected
+# to deployment target version
+class DeploymentTargetSite(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField(max_length=45)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_deployment_target_site"
+
+
+def get_default_target_completion_date():
+ return timezone.now() + timedelta(days=16)
+
+
+class Engagement(models.Model):
+ # no need to index this since index already exists thanks to it PK
+ # characteristics
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=64, primary_key=True)
+ engagement_team = models.ManyToManyField(
+ IceUserProfile, related_name='members')
+ creator = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='Engagement_creator')
+ contact_user = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='Engagement_contact_user')
+ engagement_manual_id = models.CharField(
+ max_length=36, null=False, blank=False, default=-1, db_index=True) # index in favor of dashboard search
+ progress = models.IntegerField(default=0)
+ target_completion_date = models.DateField(
+ null=True, blank=True, default=get_default_target_completion_date)
+ engagement_stage = models.CharField(max_length=15, default=EngagementStage.Intake.name, choices=EngagementStage.choices(
+ ), db_index=True) # Can be: Intake, Active, Validated, Completed @UndefinedVariable
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ peer_reviewer = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='Engagement_peer_reviewer')
+ reviewer = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='Engagement_el_reviewer')
+ starred_engagement = models.ManyToManyField(
+ IceUserProfile, default=None, blank=True)
+ heat_validated_time = models.DateTimeField(
+ 'heat validated time', null=True, blank=True)
+ image_scan_time = models.DateTimeField(
+ 'image scan time', null=True, blank=True)
+ aic_instantiation_time = models.DateTimeField(
+ 'aic instantiation time', null=True, blank=True)
+ asdc_onboarding_time = models.DateTimeField(
+ 'asdc onboarding time', null=True, blank=True)
+ started_state_time = models.DateTimeField(
+ 'started state time', null=True, blank=True)
+ intake_time = models.DateTimeField('intake time', null=True, blank=True)
+ active_time = models.DateTimeField('active time', null=True, blank=True)
+ validated_time = models.DateTimeField(
+ 'validated time', null=True, blank=True)
+ completed_time = models.DateTimeField(
+ 'completed time', null=True, blank=True)
+ archive_reason = models.TextField(default=None, null=True)
+ archived_time = models.DateTimeField(
+ 'archived time', null=True, blank=True)
+ is_with_files = models.BooleanField(default=False)
+
+ def __str__(self):
+ return " uuid: " + str(self.uuid)
+
+ class Meta:
+ db_table = "ice_engagement"
+
+
+class EngagementStatus(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=64, primary_key=True)
+ engagement = models.ForeignKey(Engagement, on_delete=models.PROTECT)
+ description = models.CharField(max_length=256)
+ creator = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='status_creator')
+ create_time = models.DateTimeField(default=timezone.now)
+ update_time = models.DateTimeField(default=timezone.now)
+
+ class Meta:
+ db_table = "ice_engagement_status"
+
+
+class Activity(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, unique=True, primary_key=True)
+ create_time = models.DateTimeField(default=timezone.now)
+ description = models.CharField(max_length=512)
+ is_notification = models.BooleanField(default=False)
+ engagement = models.ForeignKey(
+ Engagement, on_delete=models.PROTECT, db_index=True, null=True)
+ activity_type = models.CharField(
+ max_length=36, choices=ActivityType.choices())
+ activity_owner = models.ForeignKey(IceUserProfile, null=True, blank=True)
+ metadata = models.CharField(max_length=1024)
+
+ def __str__(self):
+ return 'Activity created at ' + str(self.create_time) + ', Description: ' + self.description + ', Notification:' + str(self.is_notification) + ', ActivityType=' + str(self.activity_type)
+
+ class Meta:
+ ordering = ['-create_time']
+ db_table = "ice_activity"
+ # index in favor of pullRecentActivities
+ index_together = ["engagement", "activity_owner"]
+
+
+class Notification(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, unique=True, primary_key=True)
+ user = models.ForeignKey(IceUserProfile, on_delete=models.CASCADE)
+ is_sent = models.BooleanField(default=False)
+ is_read = models.BooleanField(default=False)
+ activity = models.ForeignKey(Activity, on_delete=models.CASCADE, null=True)
+
+ def __str__(self):
+ return str(self.user) + ' ' + str(self.is_sent) + ' ' + str(self.is_read)
+
+ class Meta:
+ db_table = "ice_notification"
+ # index in favor of Notification screen (pull_recent_notifications,
+ # num_of_notifications_for_user)
+ index_together = ["user", "is_read"]
+
+
+class Feedback(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, unique=True, primary_key=True)
+ create_time = models.DateTimeField(default=timezone.now)
+ user = models.ForeignKey(IceUserProfile, null=False)
+ description = models.TextField('feedback_description')
+
+ def __str__(self):
+ return 'Feedback created at ' + str(self.create_time) + ' ' + str(self.user) + ', Description: ' + self.description
+
+ class Meta:
+ db_table = "ice_feedback"
+ # index in favor of Notification screen (pull_recent_notifications,
+ # num_of_notifications_for_user)
+ index_together = ["user"]
+
+
+class ApplicationServiceInfrastructure(models.Model):
+ name = models.CharField(max_length=100, unique=True)
+ uuid = models.CharField(default=uuid.uuid4, max_length=36, unique=True)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_application_service_infrastructure"
+ unique_together = (('name', 'uuid'),)
+
+
+class VF(models.Model):
+ # in favor of dashboard search by keyword
+ name = models.CharField(max_length=100, db_index=True)
+ # in favor of dashboard search by keyword
+ version = models.CharField(max_length=100, db_index=True, null=True)
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, unique=True, primary_key=True)
+ # index in favor of getRecentEng, getStarredEng
+ engagement = models.OneToOneField(
+ Engagement, null=False, blank=False, default=-1, db_index=True)
+ deployment_target = models.ForeignKey(
+ DeploymentTarget, on_delete=models.SET_NULL, null=True, blank=True)
+ ecomp_release = models.ForeignKey(ECOMPRelease, null=True, blank=False)
+ deployment_target_sites = models.ManyToManyField(
+ DeploymentTargetSite, default=None, blank=True, related_name='DeployTarget_sites')
+ is_service_provider_internal = models.BooleanField(default=False)
+ vendor = models.ForeignKey(Vendor, on_delete=models.PROTECT)
+ git_repo_url = models.CharField(max_length=512, blank=False, default=-1)
+ target_lab_entry_date = models.DateField(
+ 'target_lab_entry_date', null=False)
+
+ def jenkins_job_name(self):
+ if not self.engagement.engagement_manual_id:
+ raise ValueError(
+ "engagement_manual_id (%s) is not valid for jenkins job name" % self.engagement.engagement_manual_id)
+ return "{self.name}_{self.engagement.engagement_manual_id}".format(self=self)
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_vf"
+
+
+class VFC(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, unique=True, primary_key=True)
+ vf = models.ForeignKey(VF, on_delete=models.PROTECT, db_index=True)
+ # in favor of dashboard search by keyword
+ name = models.CharField(max_length=100, db_index=True)
+ external_ref_id = models.CharField(max_length=20, default='')
+ ice_mandated = models.BooleanField(default=False)
+ company = models.ForeignKey(Vendor, on_delete=SET_NULL, null=True)
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ creator = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True, related_name='Vfc_creator')
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ db_table = "ice_vfc"
+
+
+class RecentEngagement(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=64, primary_key=True)
+ vf = models.ForeignKey(VF, on_delete=models.CASCADE)
+ user_uuid = models.CharField(max_length=64)
+ action_type = models.CharField(
+ max_length=36, choices=RecentEngagementActionType.choices())
+ last_update = models.DateTimeField('update time', default=timezone.now)
+
+ def __str__(self):
+ return " uuid: " + str(self.uuid)
+
+ class Meta:
+ db_table = "ice_recent_engagement"
+
+# _________________________ C H E C K - L I S T __________________________
+
+
+class ChecklistTemplate(models.Model): # Reference Table
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField('template name', max_length=255)
+ category = models.CharField(max_length=36, choices=CheckListCategory.choices(
+ ), default=CheckListCategory.overall.name) # @UndefinedVariable
+ version = models.IntegerField('template version')
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+
+ def __str__(self):
+ return self.name + ' ' + self.category
+
+ class Meta:
+ db_table = "ice_checklist_template"
+
+
+class ChecklistSection(models.Model): # Reference Table
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField('section name', max_length=255)
+ weight = models.FloatField('checklist weight')
+ description = models.TextField('section description')
+ validation_instructions = models.TextField(
+ 'section validation instructions')
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+ parent_section = models.ForeignKey("self", null=True, blank=True)
+ template = models.ForeignKey(
+ ChecklistTemplate, on_delete=models.PROTECT, null=False, blank=False)
+
+ def __str__(self):
+ return self.name + ' ' + self.description
+
+ class Meta:
+ db_table = "ice_checklist_section"
+
+
+class ChecklistLineItem(models.Model): # Reference Table
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField('line name', max_length=255)
+ weight = models.FloatField('line weight')
+ description = models.TextField('line description')
+ line_type = models.CharField(max_length=36, choices=CheckListLineType.choices(
+ ), default=CheckListLineType.auto.name) # @UndefinedVariable
+ validation_instructions = models.TextField('line validation instructions')
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+ template = models.ForeignKey(
+ ChecklistTemplate, on_delete=models.CASCADE, null=False, blank=False)
+ section = models.ForeignKey(
+ ChecklistSection, on_delete=models.CASCADE, null=False, blank=False)
+
+ def save(self, *args, **kwargs):
+ if (self.template != self.section.template != None):
+ raise ValueError("ChecklistLineItem can't be saved/updated since the template " +
+ self.template.name + " is not equal to its section's template " + self.section.template.name)
+ super(ChecklistLineItem, self).save(*args, **kwargs)
+
+ def __str__(self):
+ return self.name + ' ' + self.description
+
+ class Meta:
+ db_table = "ice_checklist_line_item"
+
+
+class Checklist(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ name = models.CharField('checklist name', max_length=255)
+ state = models.CharField(max_length=36, choices=CheckListState.choices(
+ ), default=CheckListState.pending.name) # @UndefinedVariable
+ # On each validation cycle this counter is increased
+ validation_cycle = models.IntegerField('validation cycle')
+ weight = models.FloatField('checklist weight', default=0)
+ associated_files = models.TextField('list of files from gitlab')
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+ # index in favor of get StarredEngagements (especially for admin and EL)
+ engagement = models.ForeignKey(
+ Engagement, on_delete=models.CASCADE, db_index=True)
+ template = models.ForeignKey(ChecklistTemplate, on_delete=models.PROTECT)
+ # The EL that opened the modal.
+ creator = models.ForeignKey(
+ IceUserProfile, on_delete=models.CASCADE, related_name='checklist_creator')
+ # The user who currently validates the checklist
+ owner = models.ForeignKey(
+ IceUserProfile, on_delete=models.CASCADE, related_name='checklist_owner')
+
+ def __str__(self):
+ return self.name + ' ' + self.state
+
+ class Meta:
+ db_table = "ice_checklist"
+
+
+class NextStep(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ creator = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, related_name="NextStep_creator")
+ last_update_time = models.DateTimeField(
+ 'last update time', default=timezone.now)
+ last_updater = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, related_name="NextStep_last_updater")
+ # Can be: Modified, Added, Completed, Denied
+ last_update_type = models.CharField(max_length=15, default='Added')
+ position = models.IntegerField()
+ description = models.TextField()
+ # Can be: Incomplete, Completed
+ state = models.CharField(max_length=15, choices=NextStepState.choices())
+ # Can be: Intake, Active, Validated, Completed. This field is used to
+ # correlate between the engagement stage to the next step stage in favor
+ # of UI.
+ engagement_stage = models.CharField(max_length=15)
+ engagement = models.ForeignKey(
+ Engagement, on_delete=models.PROTECT, null=True, blank=True)
+ owner = models.ForeignKey(
+ IceUserProfile, on_delete=models.PROTECT, null=True, blank=True)
+ next_step_type = models.CharField(max_length=36, choices=NextStepType.choices(
+ ), default=NextStepType.user_defined.name) # @UndefinedVariable
+ files = models.TextField('list of files', null=True)
+ assignees = models.ManyToManyField(
+ IceUserProfile, related_name='assignees')
+ due_date = models.DateField('due_date', null=True)
+
+ def __str__(self):
+ return self.engagement_stage + ' ' + self.state + ' ' + self.description
+
+ class Meta:
+ db_table = "ice_next_step"
+ verbose_name_plural = 'Next steps'
+ # index in favor of nextstep_service.get_next_steps
+ index_together = ["engagement_stage", "owner"]
+
+
+class ChecklistDecision(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ review_value = models.CharField(
+ max_length=36, choices=CheckListDecisionValue.choices()) # @UndefinedVariable
+ peer_review_value = models.CharField(
+ max_length=36, choices=CheckListDecisionValue.choices()) # @UndefinedVariable
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+ checklist = models.ForeignKey(Checklist, on_delete=models.CASCADE)
+ template = models.ForeignKey(ChecklistTemplate, on_delete=models.CASCADE)
+ lineitem = models.ForeignKey(ChecklistLineItem, on_delete=models.CASCADE)
+
+ def save(self, *args, **kwargs):
+ if (self.template != self.checklist.template != None):
+ raise ValueError("ChecklistDecision can't be saved/updated since the template " +
+ self.template.name + " is not equal to its checklist's template " + self.checklist.template.name)
+ if (self.template != self.lineitem.section.template != None):
+ raise ValueError("ChecklistDecision can't be saved/updated since the template " + self.template.name +
+ " is not equal to its lineitem/section's template " + self.lineitem.section.template)
+ if (self.checklist.template != self.lineitem.section.template != None):
+ raise ValueError("ChecklistDecision can't be saved/updated since its checklist's template " +
+ self.checklist.template + " is not equal to its lineitem/section's template " + self.lineitem.section.template)
+ super(ChecklistDecision, self).save(*args, **kwargs)
+
+ def __str__(self):
+ return 'decision:' + self.uuid + ' ' + self.template.name + ' ' + self.review_value + ' ' + self.peer_review_value
+
+ class Meta:
+ db_table = "ice_checklist_decision"
+
+
+class ChecklistAuditLog(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ category = models.CharField(max_length=255)
+ description = models.TextField()
+ create_time = models.DateTimeField('creation time', default=timezone.now)
+ update_time = models.DateTimeField(
+ 'last update time', null=True, blank=True)
+ creator = models.ForeignKey(IceUserProfile)
+ # should be None if decisions is populated
+ checklist = models.ForeignKey(
+ Checklist, on_delete=models.CASCADE, null=True, blank=True)
+ # should be None if checklist is populated
+ decision = models.ForeignKey(
+ ChecklistDecision, on_delete=models.CASCADE, null=True, blank=True)
+
+ def save(self, *args, **kwargs):
+ if (self.checklist != None and self.decision != None):
+ raise ValueError(
+ "ChecklistAuditLog can't be attached to both checklist and decision. Please remove one of them and retry the operation")
+ super(ChecklistAuditLog, self).save(*args, **kwargs)
+
+ def __str__(self):
+ return self.category + ' ' + self.description
+
+ class Meta:
+ db_table = "ice_checklist_audit_log"
+
+
+class Invitation(models.Model):
+ uuid = models.CharField(
+ default=uuid.uuid4, max_length=36, primary_key=True)
+ engagement_uuid = models.CharField(
+ max_length=64, null=False, blank=False, db_index=True)
+ invited_by_user_uuid = models.CharField(
+ max_length=64, null=False, blank=False, db_index=True)
+ email = models.CharField(max_length=255, null=False, blank=False)
+ invitation_token = models.CharField(
+ max_length=1024, null=False, blank=False, db_index=True) # index in favor of signup
+ accepted = models.BooleanField(default=False)
+ create_time = models.DateTimeField(
+ 'invitation creation time', default=timezone.now)
+
+ def __str__(self):
+ return "Invite from " + self.invited_by_user_uuid + " to " + self.email + " for joining engagement " + self.engagement_uuid
+
+ class Meta:
+ db_table = "ice_invitation"
+ unique_together = (("engagement_uuid", "email"),)
diff --git a/django/engagementmanager/nextsteps.py b/django/engagementmanager/nextsteps.py
new file mode 100755
index 0000000..3fee019
--- /dev/null
+++ b/django/engagementmanager/nextsteps.py
@@ -0,0 +1,114 @@
+#
+# ============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.utils import timezone
+from django.utils.timezone import timedelta
+from engagementmanager.models import NextStep
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.constants import Constants, NextStepType
+
+
+logger = LoggingServiceFactory.get_logger()
+
+default_next_steps = [
+
+
+ {
+ 'position': 2,
+ 'stage': 'Intake',
+ 'text': 'Please work with your Engagement Lead (EL) to complete the necessary trial agreements.',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.trial_agreements.name # @UndefinedVariable
+ },
+ {
+ 'position': 3,
+ 'stage': 'Intake',
+ 'text': 'Please add your ' + Constants.service_provider_company_name + ' sponsor or vendor contact information.',
+ 'condition': lambda user, eng: False if (eng.contact_user) else True,
+ 'type': NextStepType.add_contact_person.name # @UndefinedVariable
+ },
+ {
+ 'position': 1,
+ 'stage': 'Active',
+ 'text': 'Please submit the first version of the VF package. If you have any problems or questions, please contact your Engagement Lead (EL)',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.submit_vf_package.name # @UndefinedVariable
+ },
+ {
+ 'position': 1,
+ 'stage': 'Validated',
+ 'text': 'Please schedule a time with your Engagement Lead (EL) to complete the handoff.',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.el_handoff.name # @UndefinedVariable
+ }
+]
+
+
+def create_default_next_steps_for_user(user, el_user):
+ """
+ This method is for personal default next step only since it has an owner
+ """
+ def cond(user): return False if (user.ssh_public_key and user.ssh_public_key != '') else True
+ if cond(user):
+ desc = "Please add your SSH key to be able to contribute."
+ nextstep = NextStep.objects.create(creator=el_user, last_updater=el_user, position=1, description=desc, last_update_type='Added', state='Incomplete',
+ engagement_stage='Intake', engagement=None, owner=user, next_step_type=NextStepType.set_ssh.name, due_date=timezone.now() + timedelta(days=1)) # @UndefinedVariable
+ nextstep.assignees.add(user)
+ nextstep.save()
+
+
+def create_default_next_steps(user, engagement, el_user):
+ """
+ This method is for non-personal default next step only since it doesn't have an owner
+ """
+ for step in default_next_steps:
+ cond = step['condition']
+ desc = step['text']
+ ns_type = step['type']
+ if cond(user, engagement):
+ if (user.company == Constants.service_provider_company):
+ desc = desc.replace('$Contact', 'Vendor Contact')
+ else:
+ desc = desc.replace('$Contact', Constants.service_provider_company_name + ' Sponsor Contact')
+ logger.debug('Creating default next step : ' + desc)
+ nextstep = NextStep.objects.create(creator=el_user, last_updater=el_user, position=step['position'], description=desc, state='Incomplete', engagement_stage=step[
+ 'stage'], engagement=engagement, next_step_type=ns_type, due_date=timezone.now() + timedelta(days=1))
+ nextstep.assignees.add(el_user)
+ nextstep.save()
+ else:
+ logger.debug('Skipping creation of default next step : ' + desc)
diff --git a/django/engagementmanager/notifications.py b/django/engagementmanager/notifications.py
new file mode 100755
index 0000000..59f2e1f
--- /dev/null
+++ b/django/engagementmanager/notifications.py
@@ -0,0 +1,71 @@
+#
+# ============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 engagementmanager.models import Notification, IceUserProfile
+from engagementmanager.serializers import ThinNotificationModelSerializer
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def num_of_notifications_for_user(user_uuid):
+ user = IceUserProfile.objects.get(uuid=user_uuid)
+ amountOfnotificationForUser = Notification.objects.filter(user=user, is_read=False).filter().count()
+ return amountOfnotificationForUser
+
+
+def pull_recent_notifications(user_uuid, offset, limit):
+ ModifiedNotificationsSet = []
+ logger.debug("Pulling unread notifications from DB")
+ user = IceUserProfile.objects.get(uuid=user_uuid)
+ notificationsList = Notification.objects.filter(user=user).order_by('is_read', '-activity__create_time')[int(offset):int(offset) + int(limit)]
+ num_of_objects = Notification.objects.filter(user=user).count()
+ for notif in notificationsList:
+ serializedNotification = ThinNotificationModelSerializer(notif).data
+ ModifiedNotificationsSet.append(serializedNotification)
+ notif.is_read = True
+ notif.save()
+ return ModifiedNotificationsSet, num_of_objects
+
+
+def reset_num_of_notifications_for_user(user_uuid):
+ user = IceUserProfile.objects.get(uuid=user_uuid)
+ notificationForUser = Notification.objects.filter(user=user, is_read=False)
+ for notif in notificationForUser:
+ notif.is_read = True
+ notif.save()
diff --git a/django/engagementmanager/rest/__init__.py b/django/engagementmanager/rest/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/rest/__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/rest/activation.py b/django/engagementmanager/rest/activation.py
new file mode 100755
index 0000000..3499b95
--- /dev/null
+++ b/django/engagementmanager/rest/activation.py
@@ -0,0 +1,123 @@
+#
+# ============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.template.loader import get_template
+from django.utils import timezone
+from itsdangerous import SignatureExpired
+from rest_framework.permissions import IsAuthenticatedOrReadOnly
+from rest_framework.response import Response
+from engagementmanager import mail
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import IceUserProfile
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.vvp_exceptions import VvpObjectNotAvailable, VvpGeneralException, VvpBadRequest
+from engagementmanager.views_helper import generateActivationLink, getFirstEngByUser
+from engagementmanager.vm_integration import vm_client
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+@classDecorator([logFuncEntry])
+class ResendActivationMail(VvpApiView):
+ permission_classes = (IsAuthenticatedOrReadOnly,)
+
+ def get(self, request, user_uuid, format=None):
+ ice_user_obj = IceUserProfile.objects.get(uuid=user_uuid)
+
+ data = {'activation_link': generateActivationLink(ice_user_obj.user.activation_token, ice_user_obj),
+ 'full_name': ice_user_obj.full_name}
+
+ # updating the activation time
+ ice_user_obj.user.activation_token_create_time = timezone.now()
+
+ ice_user_obj.save()
+ self.logger.debug("Activation Link: " + data['activation_link'])
+
+ body = get_template("{activate_template_dir}activate_mail_body.html".format(
+ activate_template_dir=Constants.activate_template_dir))
+ subject = get_template("{activate_template_dir}activate_mail_subject.html".format(
+ activate_template_dir=Constants.activate_template_dir))
+ mail.sendMail(ice_user_obj.email, data, body, subject)
+
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class ActivateUser(VvpApiView):
+ permission_classes = (IsAuthenticatedOrReadOnly,)
+
+ def get(self, request, format=None, **kwargs):
+ user_profile = IceUserProfile.objects.get(uuid=kwargs['uu_id'])
+ user = user_profile.user
+ if user is None:
+ raise VvpObjectNotAvailable(
+ "User's retrieved in the activation API doesn't exist.")
+
+ if user.is_active:
+ raise VvpGeneralException(
+ "User's retrieved in the activation API is active.")
+
+ if user.activation_token != kwargs['token']:
+ raise VvpBadRequest(
+ "User's activation token is not equal to the token in the activation path param.")
+
+ created = user.activation_token_create_time
+ current = timezone.now()
+ if created.year == current.year and created.month == current.month and (created.day == current.day or
+ created.day == current.day - 1):
+ delta = current - created
+ if abs(delta).total_seconds() / 3600.0 <= settings.TOKEN_EXPIRATION_IN_HOURS:
+ user.is_active = True
+ user.save()
+ self.logger.debug(
+ "User " + user_profile.full_name + " is activated successfully, redirecting to Login")
+ user = IceUserProfile.objects.get(email=user.email)
+ eng = getFirstEngByUser(user)
+ result = {'activation_success': True, }
+ if eng is not None:
+ result['engagement_uuid'] = str(eng.uuid)
+ vm_client.send_create_user_in_rgwa_event(user)
+ return Response(result)
+ else:
+ raise SignatureExpired("User's activation token expired.")
+
+ return Response({'activation_success': False, })
diff --git a/django/engagementmanager/rest/activity.py b/django/engagementmanager/rest/activity.py
new file mode 100755
index 0000000..47b4cc7
--- /dev/null
+++ b/django/engagementmanager/rest/activity.py
@@ -0,0 +1,65 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import Engagement
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import ActivityModelSerializer
+from engagementmanager.service.activities_service import ActivitiesSvc
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+@classDecorator([logFuncEntry])
+class PullActivities(VvpApiView):
+ def __init__(self):
+ self.activities_service = ActivitiesSvc()
+
+ @auth(Permissions.pull_activities)
+ def get(self, request, eng_uuid, num=None):
+ if not num:
+ num = settings.NUMBER_OF_POLLED_ACTIVITIES
+ eng = Engagement.objects.get(uuid=request_data_mgr.get_eng_uuid())
+ activities = self.activities_service.pull_recent_activities(eng, recent_activities_limit=num)
+ serializer = ActivityModelSerializer(activities, many=True)
+ return Response(serializer.data)
diff --git a/django/engagementmanager/rest/checklist.py b/django/engagementmanager/rest/checklist.py
new file mode 100755
index 0000000..200dcaa
--- /dev/null
+++ b/django/engagementmanager/rest/checklist.py
@@ -0,0 +1,139 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST,\
+ HTTP_500_INTERNAL_SERVER_ERROR
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.checklist_service import CheckListSvc
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import Validator
+
+
+@classDecorator([logFuncEntry])
+class NewCheckList(VvpApiView):
+
+ @auth(Permissions.view_checklist)
+ def get(self, request, eng_uuid):
+
+ user = request_data_mgr.get_user()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ data = CheckListSvc().getDataForCreateNewChecklist(user, eng_uuid)
+ if not data:
+ msg = "Create New checklist is not ready yet"
+ return Response(msg, status=HTTP_500_INTERNAL_SERVER_ERROR)
+ return Response(data)
+
+ @auth(Permissions.is_el_of_eng)
+ def post(self, request, eng_uuid):
+ data = request.data
+
+ if ('checkListName' not in data or not data['checkListName'] or
+ 'checkListTemplateUuid' not in data or not data['checkListTemplateUuid'] or
+ 'checkListAssociatedFiles' not in data):
+ msg = "One of the CheckList's input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ if not Validator.validateCheckListName(data['checkListName']):
+ msg = "Invalid characters in check list name."
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ data = CheckListSvc().createOrUpdateChecklist(
+ data['checkListName'], data['checkListTemplateUuid'], data['checkListAssociatedFiles'], None)
+
+ return Response(data)
+
+
+@classDecorator([logFuncEntry])
+class ExistingCheckList(VvpApiView):
+
+ @auth(Permissions.view_checklist)
+ def get(self, request, checklistUuid):
+ user = request_data_mgr.get_user()
+ checklist_uuid = request_data_mgr.get_cl_uuid()
+ data = CheckListSvc().getChecklist(user, checklist_uuid)
+ return Response(data)
+
+ @auth(Permissions.is_el_of_eng)
+ def delete(self, request):
+ CheckListSvc().deleteChecklist(request_data_mgr.get_cl_uuid())
+ return Response()
+
+ @auth(Permissions.is_el_of_eng)
+ def put(self, request, checklistUuid):
+ data = request.data
+ if ('checklistUuid' not in data or not data['checklistUuid'] or
+ 'checkListName' not in data or not data['checkListName'] or
+ 'checkListTemplateUuid' not in data or not data['checkListTemplateUuid'] or
+ 'checkListAssociatedFiles' not in data):
+ msg = "One of the CheckList's input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+ if not Validator.validateCheckListName(data['checkListName']):
+ msg = "Invalid characters in check list name."
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ data = CheckListSvc().createOrUpdateChecklist(
+ data['checkListName'], data['checkListTemplateUuid'], data['checkListAssociatedFiles'], data['checklistUuid'])
+
+ return Response(data)
+
+
+@classDecorator([logFuncEntry])
+class CheckListTemplates(VvpApiView):
+
+ @auth(Permissions.view_checklist_template)
+ def get(self, request, templateUuid=None):
+ data = CheckListSvc().getChecklistTemplates(templateUuid)
+ return Response(data)
+
+ @auth(Permissions.edit_checklist_template)
+ def put(self, request):
+ data = request.data
+ CheckListSvc().editChecklistTemplate(data)
+ return Response()
diff --git a/django/engagementmanager/rest/checklist_audit_log.py b/django/engagementmanager/rest/checklist_audit_log.py
new file mode 100755
index 0000000..4b86a33
--- /dev/null
+++ b/django/engagementmanager/rest/checklist_audit_log.py
@@ -0,0 +1,103 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import ChecklistDecision, Checklist
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.checklist_audit_log_service import getAuditLogsWithChecklist, \
+ addAuditLogToChecklist, getAuditLogsWithDecision, addAuditLogToDecision
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+@classDecorator([logFuncEntry])
+class ChecklistAuditLog(VvpApiView):
+
+ @auth(Permissions.view_checklist)
+ def get(self, request, checklistUuid):
+ user = request_data_mgr.get_user()
+ checklistUuid = request_data_mgr.get_cl_uuid()()
+ data = getAuditLogsWithChecklist(checklistUuid, user)
+ return Response(data)
+
+ @auth(Permissions.create_checklist_audit_log)
+ def post(self, request, checklistUuid):
+ data = request.data
+ user = request_data_mgr.get_user()
+ checklistUuid = request_data_mgr.get_cl_uuid()
+
+ if ('description' not in data or not data['description']):
+ msg = "description for the audit log is not provided in the request's body"
+ self.logger.error(msg)
+ raise KeyError(msg)
+ description = data['description']
+ checklist = Checklist.objects.get(uuid=checklistUuid)
+ data = addAuditLogToChecklist(checklist, description, user)
+ return Response(data)
+
+
+@classDecorator([logFuncEntry])
+class DecisionAuditLog(VvpApiView):
+
+ @auth(Permissions.view_checklist)
+ def get(self, request, decision_uuid):
+ user = request_data_mgr.get_user()
+ decisionUuid = decision_uuid
+ data = getAuditLogsWithDecision(decisionUuid, user)
+
+ return Response(data)
+
+ @auth(Permissions.create_checklist_decision)
+ def post(self, request, decision_uuid):
+ data = request.data
+ user = request_data_mgr.get_user()
+ decisionUuid = decision_uuid
+ if ('description' not in data or not data['description']):
+ msg = "value for decision is not provided in the request's body"
+ self.logger.error(msg)
+ raise KeyError(msg)
+ description = data['description']
+ decision = ChecklistDecision.objects.get(uuid=decisionUuid)
+ auditData = addAuditLogToDecision(decision, description, user)
+ return Response(auditData)
diff --git a/django/engagementmanager/rest/checklist_decision.py b/django/engagementmanager/rest/checklist_decision.py
new file mode 100755
index 0000000..a0cfe01
--- /dev/null
+++ b/django/engagementmanager/rest/checklist_decision.py
@@ -0,0 +1,76 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.checklist_decision_service import setDecision, getDecision
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+@classDecorator([logFuncEntry])
+class ClDecision(VvpApiView):
+
+ @auth(Permissions.view_checklist)
+ def get(self, request, decision_uuid):
+ user = request_data_mgr.get_user()
+ decisionUuid = decision_uuid
+ data = getDecision(decisionUuid, user)
+ return Response(data)
+
+ @auth(Permissions.update_checklist_decision)
+ def put(self, request, decision_uuid):
+ data = request.data
+
+ user = request_data_mgr.get_user()
+ decisionUuid = decision_uuid
+ if 'value' not in data or not data['value']:
+ msg = "value for decision is not provided in the request's body"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+ value = data['value']
+ msg = setDecision(decisionUuid, user, value)
+ msg = json.dumps(msg, ensure_ascii=False)
+ return Response(msg)
diff --git a/django/engagementmanager/rest/checklist_set_state.py b/django/engagementmanager/rest/checklist_set_state.py
new file mode 100755
index 0000000..e9c6eb3
--- /dev/null
+++ b/django/engagementmanager/rest/checklist_set_state.py
@@ -0,0 +1,67 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import SuperThinChecklistModelSerializer
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.checklist_state_service import set_state
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+@classDecorator([logFuncEntry])
+class ChecklistState(VvpApiView):
+
+ @auth(Permissions.update_checklist_state)
+ def put(self, request, checklistUuid):
+ data = request.data
+ decline = data['decline']
+ if decline == "True":
+ checklist = set_state(True, request_data_mgr.get_cl_uuid(),
+ isMoveToAutomation=False, description=data['description'])
+ else:
+ checklist = set_state(False, request_data_mgr.get_cl_uuid(), description=data['description'])
+
+ cldata = json.dumps(SuperThinChecklistModelSerializer(checklist).data, ensure_ascii=False)
+ return Response(cldata)
diff --git a/django/engagementmanager/rest/cms/__init__.py b/django/engagementmanager/rest/cms/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/rest/cms/__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/rest/cms/pages.py b/django/engagementmanager/rest/cms/pages.py
new file mode 100755
index 0000000..efe0b4e
--- /dev/null
+++ b/django/engagementmanager/rest/cms/pages.py
@@ -0,0 +1,80 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.cms.pages_service import CMSPagesService
+
+
+@classDecorator([logFuncEntry])
+class Pages(VvpApiView):
+ cms_service = CMSPagesService()
+
+ def get(self, request, format=None, **kwargs):
+ titleParam = request.GET.get('title', "")
+
+ pages = self.cms_service.getPages(titleParam)
+ return Response(pages)
+
+
+@classDecorator([logFuncEntry])
+class PageById(VvpApiView):
+ cms_service = CMSPagesService()
+
+ def get(self, request, format=None, **kwargs):
+ idParam = kwargs['id']
+
+ pages = self.cms_service.getPage(idParam)
+ return Response(pages)
+
+
+@classDecorator([logFuncEntry])
+class PageSearch(VvpApiView):
+ cms_service = CMSPagesService()
+
+ def get(self, request):
+ keyword = request.GET.get('keyword', "")
+ result = []
+
+ if keyword is not None and keyword != "":
+ result = self.cms_service.searchPages(keyword)
+
+ return Response(result)
diff --git a/django/engagementmanager/rest/cms/posts.py b/django/engagementmanager/rest/cms/posts.py
new file mode 100755
index 0000000..17e33fb
--- /dev/null
+++ b/django/engagementmanager/rest/cms/posts.py
@@ -0,0 +1,57 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.cms.posts_service import CMSPostsService
+
+
+@classDecorator([logFuncEntry])
+class Posts(VvpApiView):
+
+ def get(self, request, format=None, **kwargs):
+ categoryParam = request.GET.get('category', "")
+ limitParam = request.GET.get('limit', 5)
+ offsetParam = request.GET.get('offset', 0)
+ fromLastDaysParam = request.GET.get('fromLastDays', None)
+
+ posts = CMSPostsService().getPosts(offsetParam, limitParam, fromLastDaysParam, categoryParam)
+ return Response(posts)
diff --git a/django/engagementmanager/rest/csrf_exempt_session_authentication.py b/django/engagementmanager/rest/csrf_exempt_session_authentication.py
new file mode 100755
index 0000000..89a6243
--- /dev/null
+++ b/django/engagementmanager/rest/csrf_exempt_session_authentication.py
@@ -0,0 +1,47 @@
+#
+# ============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 rest_framework.authentication import SessionAuthentication
+
+
+class CsrfExemptSessionAuthentication(SessionAuthentication):
+
+ def enforce_csrf(self, request):
+ # To not perform the csrf check previously happening
+ # (http://stackoverflow.com/questions/30871033/django-rest-framework-remove-csrf)
+ return
diff --git a/django/engagementmanager/rest/data_loader.py b/django/engagementmanager/rest/data_loader.py
new file mode 100755
index 0000000..11e8dfc
--- /dev/null
+++ b/django/engagementmanager/rest/data_loader.py
@@ -0,0 +1,82 @@
+#
+# ============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 uuid import uuid4
+
+from django.utils import timezone
+from rest_framework.response import Response
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import IceUserProfile, Vendor, Role, CustomUser
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.views_helper import createUserTemplate
+
+
+@classDecorator([logFuncEntry])
+class EngLeadsDataLoader(VvpApiView):
+
+ def get(self, request):
+ data = request.data
+ service_provider_company = Vendor.objects.get(name=Constants.service_provider_company_name)
+ el_role = Role.objects.get(name="el")
+ for el in data:
+ user_object = CustomUser.objects.create_user(
+ username=el['full_name'], email=el['full_name'], password=el['password'], is_active=False, activation_token=uuid4(), activation_token_create_time=timezone.now())
+ data = createUserTemplate(service_provider_company, el['full_name'], el_role, '', True, None, True, user_object)
+ el_user, is_profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=data)
+ self.logger.info("User: " + el_user.full_name +
+ " was created successfully during bulk_load_engagement_leads function")
+ self.logger.info("All users were created successfully during bulk_load_engagement_leads function")
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class CompaniesDataLoader(VvpApiView):
+
+ def get(self, request):
+ data = request.data
+ for vendor in data:
+ Vendor.objects.get_or_create(name=vendor['name'], defaults={'public': True})
+ self.logger.info('Company found or created during bulk load vendors: ' + logEncoding(vendor))
+ self.logger.info("All companies were created successfully during bulk_load_companies function")
+ return Response()
diff --git a/django/engagementmanager/rest/deployment_target.py b/django/engagementmanager/rest/deployment_target.py
new file mode 100755
index 0000000..c52d9b9
--- /dev/null
+++ b/django/engagementmanager/rest/deployment_target.py
@@ -0,0 +1,69 @@
+#
+# ============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 rest_framework.permissions import IsAuthenticated
+from rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import DeploymentTarget
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import DeploymentTargetModelSerializer
+from engagementmanager.service.deploment_target_service import update_deployment_target
+
+
+@classDecorator([logFuncEntry])
+class DeploymentTargetRESTMethods(VvpApiView):
+ permission_classes = (IsAuthenticated,)
+
+ def put(self, request, engagement_uuid, dt_uuid):
+ msg = "OK"
+ if engagement_uuid and dt_uuid:
+ update_deployment_target(engagement_uuid, dt_uuid)
+ return Response(msg)
+ else:
+ msg = "DTarget PUT Request failed, engagement_uuid wasn't found in kwargs or its content is empty, therefore cannot filter by it to find the required VF"
+ self.logger.error(msg)
+ msg = "Action failed."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ def get(self, request):
+ deployment_targets = DeploymentTarget.objects.filter(ui_visibility=True).order_by('weight')
+ serializer = DeploymentTargetModelSerializer(deployment_targets, many=True)
+ return Response(serializer.data)
diff --git a/django/engagementmanager/rest/deployment_target_site.py b/django/engagementmanager/rest/deployment_target_site.py
new file mode 100755
index 0000000..32ff5a4
--- /dev/null
+++ b/django/engagementmanager/rest/deployment_target_site.py
@@ -0,0 +1,103 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_204_NO_CONTENT
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import VF, DeploymentTargetSite
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import ThinDeploymentTargetSiteModelSerializer
+from engagementmanager.service.authorization_service import Permissions
+
+
+@classDecorator([logFuncEntry])
+class DTSites(VvpApiView):
+
+ @auth(Permissions.get_deployment_target_site)
+ def get(self, request, vf_uuid=None):
+ if vf_uuid:
+ vf = VF.objects.get(uuid=vf_uuid)
+ dtsites = vf.deployment_target_sites
+ serializer = ThinDeploymentTargetSiteModelSerializer(dtsites, many=True)
+ return Response(serializer.data)
+ else:
+ dtsites = DeploymentTargetSite.objects.all()
+ serializer = ThinDeploymentTargetSiteModelSerializer(dtsites, many=True)
+ return Response(serializer.data)
+
+ """
+ expecting: VF object uuid, DeploymentTargetSite uuid
+ result: addition of the DeploymentTargetSite object with dtsite_uuid to the VF's deployment_target_sites
+ """
+ @auth(Permissions.add_deployment_target_site)
+ def post(self, request):
+ msg = ""
+ data = request.data
+ name = data['name']
+ dtsite = None
+
+ try:
+ dtsite = DeploymentTargetSite.objects.get(name=name)
+ msg = "DTSite was already existed, hence would next be added to the VF's sites list"
+ except DeploymentTargetSite.DoesNotExist:
+ dtsite = DeploymentTargetSite.objects.create(name=name)
+ dtsite.save()
+ vf = VF.objects.get(uuid=data['vf_uuid'])
+ vf.deployment_target_sites.add(dtsite)
+ vf.save()
+ return Response(msg)
+
+ @auth(Permissions.delete_deployment_target_site)
+ def delete(self, request, vf_uuid, dts_uuid):
+ msg = "OK"
+ dtsite = None
+ vf = None
+
+ if vf_uuid and dts_uuid:
+ dtsite = DeploymentTargetSite.objects.get(uuid=dts_uuid)
+ vf = VF.objects.get(uuid=vf_uuid)
+ vf.deployment_target_sites.remove(dtsite)
+ vf.save()
+ return Response(msg, status=HTTP_204_NO_CONTENT)
+ else:
+ msg = "dtsite uuid or vf uuid, wasn't provided"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
diff --git a/django/engagementmanager/rest/ecomp.py b/django/engagementmanager/rest/ecomp.py
new file mode 100755
index 0000000..a2585ac
--- /dev/null
+++ b/django/engagementmanager/rest/ecomp.py
@@ -0,0 +1,69 @@
+#
+# ============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 rest_framework.permissions import IsAuthenticated
+from rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_202_ACCEPTED
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import ECOMPRelease
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import ECOMPReleaseModelSerializer
+from engagementmanager.service.ecomp_service import update_ECOMP
+
+
+@classDecorator([logFuncEntry])
+class ECOMPReleaseRESTMethods(VvpApiView):
+ permission_classes = (IsAuthenticated,)
+
+ def put(self, request, engagement_uuid, ecomp_uuid):
+ msg = "OK"
+ if engagement_uuid and ecomp_uuid:
+ update_ECOMP(engagement_uuid, ecomp_uuid)
+ return Response(msg)
+ else:
+ msg = "ECOMPRelease PUT Request failed, engagement_uuid wasn't found in kwargs or its content is empty, therefore cannot filter by it to find the required VF"
+ self.logger.error(msg)
+ msg = "Action failed."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ def get(self, request):
+ ecomp_releases = ECOMPRelease.objects.filter(ui_visibility=True).order_by('weight')
+ serializer = ECOMPReleaseModelSerializer(ecomp_releases, many=True)
+ return Response(serializer.data)
diff --git a/django/engagementmanager/rest/engagement.py b/django/engagementmanager/rest/engagement.py
new file mode 100755
index 0000000..89e74fe
--- /dev/null
+++ b/django/engagementmanager/rest/engagement.py
@@ -0,0 +1,665 @@
+#
+# ============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.db.models.expressions import F
+from django.db.models.query_utils import Q
+from django.http.response import HttpResponse
+from django.utils.dateparse import parse_date
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.git.git_manager import GitManager
+from engagementmanager.models import Engagement, VF, VFC, Checklist, \
+ EngagementStatus
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import VFModelSerializer, \
+ EngagementStatusModelSerializer
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service import engagement_service as eng_svc
+from engagementmanager.utils.constants import Roles, RecentEngagementActionType, \
+ CheckListState, EngagementStage
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import logEncoding
+from rest_framework.response import Response
+from rest_framework.status import HTTP_500_INTERNAL_SERVER_ERROR, \
+ HTTP_400_BAD_REQUEST, HTTP_200_OK, HTTP_204_NO_CONTENT, \
+ HTTP_401_UNAUTHORIZED, HTTP_202_ACCEPTED
+
+
+@classDecorator([logFuncEntry])
+class ExpandedEngByUser(VvpApiView):
+
+ def post(self, request):
+ data = request.data
+ if ('stage' not in data or not data['stage']
+ or 'keyword' not in data
+ or 'offset' not in data or int(data['offset']) < 0
+ or 'limit' not in data or not data['limit'] or (data['limit'] < 1)):
+ msg = "GetExpandedEngByUser - get request: one of the parameters is missing or invalid."
+ self.logger.error(msg)
+ msg = "Action was failed due to bad request."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+ user = request_data_mgr.get_user()
+ data = eng_svc.get_dashboard_expanded_engs(
+ data['stage'], data['keyword'], data['offset'], data['limit'], user)
+ return Response(data)
+
+
+@classDecorator([logFuncEntry])
+class ExportEngagements(VvpApiView):
+
+ @auth(Permissions.export_engagments)
+ def get(self, request):
+ from openpyxl import Workbook
+ from openpyxl.writer.write_only import WriteOnlyCell
+ from openpyxl.styles import Font
+ # import csv
+ from django.utils.encoding import smart_str
+
+ user = request_data_mgr.get_user()
+ stageParam = request.GET['stage']
+ keywordParam = request.GET['keyword']
+
+ # data, status = eng_svc.get_dashboard_expanded_engs(stageParam, keywordParam, 0, sys.maxint, user)
+ vfs, deployment_targets = eng_svc.get_expanded_engs_for_export(
+ stageParam, keywordParam, user)
+
+ workbook = Workbook(write_only=True)
+ # Create 'Validation Details' sheet and fill it up with required data:
+ validationWorkSheet = workbook.create_sheet()
+ validationWorkSheet.title = 'Validation Details'
+ headlines = [WriteOnlyCell(validationWorkSheet, value=u"EId"),
+ WriteOnlyCell(validationWorkSheet, value=u"Engagement"),
+ WriteOnlyCell(validationWorkSheet, value=u"Reviewer"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Peer reviewer"),
+ WriteOnlyCell(validationWorkSheet, value=u"VFC"),
+ WriteOnlyCell(validationWorkSheet, value=u"VFC #"),
+ WriteOnlyCell(validationWorkSheet, value=u"Started"),
+ WriteOnlyCell(validationWorkSheet, value=u"Vendor"),
+ WriteOnlyCell(validationWorkSheet, value=u"AIC Version"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"ECOMP Release"),
+ WriteOnlyCell(validationWorkSheet, value=u"Validate"),
+ WriteOnlyCell(validationWorkSheet, value=u"Completed"),
+ WriteOnlyCell(validationWorkSheet, value=u"Stage"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Heat Pre-validated"),
+ WriteOnlyCell(validationWorkSheet, value=u"Image Scan"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"AIC Instantiated"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"ASDC Onboarded"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Overall Progress in %"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Target Completion Date"),
+ WriteOnlyCell(validationWorkSheet, value=u"Status")]
+ for headline in headlines:
+ headline.font = Font(name='Courier', size=16, bold=True)
+ validationWorkSheet.append(headlines)
+
+ for vf in vfs:
+ validationWorkSheet.append([smart_str(vf["engagement__engagement_manual_id"]),
+ smart_str(vf["vf__name"]),
+ smart_str(
+ vf["vf_engagement__reviewer"]),
+ smart_str(
+ vf["vf_engagement__peer_reviewer"]),
+ smart_str(vf["vfcs"]),
+ smart_str(vf["vfcs__number"]),
+ smart_str(
+ vf["engagement__started_state_time"]),
+ smart_str(vf["vendor__name"]),
+ smart_str(
+ vf["deployment_target__version"]),
+ smart_str(vf["ecomp_release__name"]),
+ smart_str(
+ vf["engagement__validated_time"]),
+ smart_str(
+ vf["engagement__completed_time"]),
+ smart_str(
+ vf["engagement__engagement_stage"]),
+ smart_str(
+ vf["engagement__heat_validated_time"]),
+ smart_str(
+ vf["engagement__image_scan_time"]),
+ smart_str(
+ vf["engagement__aic_instantiation_time"]),
+ smart_str(
+ vf["engagement__asdc_onboarding_time"]),
+ smart_str(vf["engagement__progress"]),
+ smart_str(
+ vf["engagement__target_completion_date"]),
+ smart_str(
+ vf["engagement__latest_status"])
+ ])
+
+ # Create 'Overview' sheet and fill it up with required data:
+ overviewWorkSheet = workbook.create_sheet()
+ overviewWorkSheet.title = 'Overview'
+ headlines = [WriteOnlyCell(validationWorkSheet, value=u"AIC/ECOMP"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Active Count of Engagement"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Sum of Nr of VFs"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Intake Count of Engagement"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Sum of Nr of VFs"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Completed Count of Engagement"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Sum of Nr of VFs"),
+ WriteOnlyCell(
+ validationWorkSheet, value=u"Total Count of Engagement"),
+ WriteOnlyCell(validationWorkSheet, value=u"Total Sum of Nr of VFs")]
+ for headline in headlines:
+ headline.font = Font(name='Courier', size=16, bold=True)
+ overviewWorkSheet.append(headlines)
+
+ for deployment_target in deployment_targets:
+ overviewWorkSheet.append(deployment_target)
+
+ # We are using HttpResponse and not Rest Response since we couldnt find
+ # support for content diposition
+ response = HttpResponse(
+ content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
+ response['Content-Disposition'] = 'attachment; filename=D2ICE.xlsx'
+
+ workbook.save(response)
+
+ return response
+
+
+@classDecorator([logFuncEntry])
+class GetEngByUser(VvpApiView):
+
+ @auth(Permissions.eng_membership)
+ def get(self, request):
+ user = request_data_mgr.get_user()
+ vf_list = []
+
+ engStageList = [EngagementStage.Intake.name, EngagementStage.Active.name,
+ EngagementStage.Validated.name, EngagementStage.Completed.name] # @UndefinedVariable
+
+ # @UndefinedVariable
+ if (user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .distinct().order_by('engagement__engagement_manual_id')\
+ .annotate(
+ engagement_manual_id=F('engagement__engagement_manual_id'),
+ engagement_uuid=F('engagement__uuid'),
+ vf_name=F('name'),
+ peer_reviewer__uuid=F('engagement__peer_reviewer__uuid'),
+ engagement_stage=F('engagement__engagement_stage'),
+ )\
+ .values(
+ 'uuid',
+ 'vf_name',
+ 'engagement_manual_id',
+ 'engagement_uuid',
+ 'peer_reviewer__uuid',
+ 'engagement_stage',
+ )
+ else:
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList).\
+ filter(Q(engagement__engagement_team__uuid=user.uuid)).distinct().order_by('engagement__engagement_manual_id')\
+ .annotate(
+ engagement_manual_id=F('engagement__engagement_manual_id'),
+ engagement_uuid=F('engagement__uuid'),
+ vf_name=F('name'),
+ peer_reviewer__uuid=F('engagement__peer_reviewer__uuid'),
+ reviewer__uuid=F('engagement__reviewer__uuid'),
+ engagement_stage=F('engagement__engagement_stage'),
+ )\
+ .values(
+ 'uuid',
+ 'vf_name',
+ 'engagement_manual_id',
+ 'engagement_uuid',
+ 'peer_reviewer__uuid',
+ 'reviewer__uuid',
+ 'engagement_stage',
+ )
+
+ vf_final_array = []
+ for vf in vf_list:
+ vfc_list = VFC.objects.filter(Q(vf=vf['uuid'])).values('name')
+ vf['vfc'] = []
+ for vfc in vfc_list:
+ vf['vfc'].append(vfc['name'])
+
+ vf['vfc'] = ', '.join(vf['vfc'])
+ vf_final_array.append(vf)
+
+ return Response(vf_final_array)
+
+
+@classDecorator([logFuncEntry])
+class SingleEngByUser(VvpApiView):
+
+ @auth(Permissions.eng_membership)
+ def get(self, request, eng_uuid):
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ user = request_data_mgr.get_user()
+
+ engagement = None
+
+ # @UndefinedVariable
+ if (user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ else:
+ try:
+ engagement = Engagement.objects.get(
+ peer_reviewer=user, uuid=eng_uuid)
+ except Engagement.DoesNotExist:
+ try:
+ engagement = Engagement.objects.get(
+ engagement_team__uuid=user.uuid, uuid=eng_uuid)
+ except:
+ msg = "Eng for the User with uuid " + \
+ user.uuid + " doesn't exist."
+ self.logger.error(msg)
+ msg = "Couldn't provide VF, internal server error"
+ return Response(msg, status=HTTP_500_INTERNAL_SERVER_ERROR)
+ vfObj = VF.objects.get(engagement__uuid=engagement.uuid)
+ eng_svc.update_or_insert_to_recent_engagements(
+ user.uuid, vfObj, RecentEngagementActionType.NAVIGATED_INTO_ENGAGEMENT.name) # @UndefinedVariable
+
+ vfList = VF.objects.filter(engagement__uuid=engagement.uuid)
+ formated_vf_list = VFModelSerializer(vfList, many=True).data
+ formated_vf = formated_vf_list[0]
+ if vfObj.git_repo_url != str(-1):
+ formated_vf['files'] = GitManager().getRepoAssociatedFilesForUser(
+ eng_uuid)
+ else:
+ formated_vf['files'] = []
+
+ return Response(formated_vf)
+
+ @auth(Permissions.edit_stage)
+ def put(self, request, eng_uuid, stage):
+ sts = HTTP_202_ACCEPTED
+ if not eng_uuid or not stage:
+ msg = "One of the Engagement's input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ msg = eng_svc.set_engagement_stage(eng_uuid, stage)
+ return Response(msg, status=sts)
+
+
+@classDecorator([logFuncEntry])
+class ArchiveEngagement(VvpApiView):
+
+ @auth(Permissions.archive_engagement)
+ def put(self, request, eng_uuid):
+ data = request.data
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ msg = eng_svc.archive_engagement(eng_uuid, data['reason'])
+ return Response(msg)
+
+
+@classDecorator([logFuncEntry])
+class StarredEngagements(VvpApiView):
+
+ @auth(Permissions.star_an_engagement)
+ def get(self, request):
+ user = request_data_mgr.get_user()
+ if (user == None):
+ msg = "User with uuid " + user.uuid + \
+ " doesn't exist. Can't fetch their engagements"
+ self.logger.error(logEncoding(msg))
+ msg = "You are not registered as a user, please sign up in order to perform this action"
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ vf_list = eng_svc.vf_retreiver(user, True)
+ if not vf_list:
+ msg = "Action succeeded, no starred VFs were found."
+ self.logger.debug(msg)
+ return Response(msg, status=HTTP_204_NO_CONTENT)
+
+ vfListData = []
+
+ for vf_data in vf_list:
+
+ # @UndefinedVariable
+ if (user.role.name == Roles.el.name or user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ if (vf_data['engagement__reviewer__uuid'] == user.uuid):
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['engagement__uuid']), Q(engagement__reviewer=user), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ # @UndefinedVariable
+ elif (user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['engagement__uuid']), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ else:
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['engagement__uuid']), Q(owner=user), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ vf_data['checklists'] = checklist_lists
+ else:
+ vf_data['checklists'] = None
+
+ vfListData.append(vf_data)
+
+ return Response(vfListData)
+
+ @auth(Permissions.star_an_engagement)
+ def put(self, request, **kwargs):
+ user = request_data_mgr.get_user()
+ data = request.data
+ sts = HTTP_200_OK
+ if ('engagement_uuid' not in data or not data['engagement_uuid']):
+ msg = "starred engagement uuid parameter is missing"
+ self.logger.error(msg)
+ msg = "Action was failed due to bad request."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ eng_uuid = data['engagement_uuid']
+ if (user == None):
+ msg = "User with uuid " + user.uuid + \
+ " doesn't exist. Can't fetch their engagements"
+ self.logger.error(logEncoding(msg))
+ msg = "You are not registered as a user, please sign up in order to perform this action"
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ msg = eng_svc.star_an_engagement(user, eng_uuid)
+
+ return Response(msg, status=sts)
+
+
+@classDecorator([logFuncEntry])
+class GetRecentEngagements(VvpApiView):
+
+ @auth(Permissions.eng_membership)
+ def get(self, request, format=None, **kwargs):
+ user = request_data_mgr.get_user()
+ if (user == None):
+ msg = "User with uuid " + user.uuid + \
+ " doesn't exist. Can't fetch their engagements"
+ self.logger.error(logEncoding(msg))
+ msg = "You are not registered as a user, please sign up in order to perform this action"
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ stared_list = eng_svc.vf_retreiver(user, True)
+
+ vf_list = eng_svc.vf_retreiver(user, False, True)
+
+ if not vf_list:
+ msg = "Action succeeded, no recent VFs were found."
+ self.logger.debug(msg)
+ return Response(msg, status=HTTP_204_NO_CONTENT)
+
+ vfListData = []
+ recentList = 20 + stared_list.count()
+ for idx, vf_data in enumerate(vf_list):
+ if (idx == recentList):
+ break
+ # @UndefinedVariable
+ if (user.role.name == Roles.el.name or user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ if (vf_data['vf__engagement__reviewer__uuid'] == user.uuid):
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['vf__engagement__uuid']), Q(engagement__reviewer=user), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ # @UndefinedVariable
+ elif (user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['vf__engagement__uuid']), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ else:
+ checklist_lists = Checklist.objects.filter(Q(engagement__uuid=vf_data['vf__engagement__uuid']), Q(owner=user), ~Q(
+ state=CheckListState.archive.name)).values('uuid', 'name', 'state', 'owner__uuid') # @UndefinedVariable
+ vf_data['checklists'] = checklist_lists
+ else:
+ vf_data['checklists'] = None
+ vfListData.append(vf_data)
+ return Response(vfListData)
+
+
+@classDecorator([logFuncEntry])
+class EngagementProgressBar(VvpApiView):
+
+ @auth(Permissions.edit_progress_bar)
+ def put(self, request, eng_uuid):
+ data = request.data
+ msg = "OK"
+
+ if ('progress' not in data or not data['progress'] or data['progress'] == ''):
+ msg = "progress parameter is missing or empty"
+ self.logger.error(msg)
+ msg = "Action has failed due to bad request."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ eng_svc.set_progress_for_engagement(progress=data['progress'])
+ return Response(msg, status=HTTP_202_ACCEPTED)
+
+ @auth(Permissions.get_progress_bar)
+ def post(self, request, eng_uuid):
+ data = request.data
+ eng = self.get_entity(Engagement, request_data_mgr.get_eng_uuid())
+ msg = "OK"
+
+ if ('target_date' not in data or not data['target_date'] or data['target_date'] == ''):
+ msg = "target_date parameter is missing or empty"
+ self.logger.error(msg)
+ msg = "Action has failed due to bad request."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ target_date = data['target_date']
+ date = parse_date(target_date)
+ eng.target_completion_date = date
+ eng.save()
+ return Response(msg)
+
+
+@classDecorator([logFuncEntry])
+class ChangeTargetLabEntryDate(VvpApiView):
+
+ @auth(Permissions.change_lab_entry)
+ def post(self, request, eng_uuid):
+ data = request.data
+ eng = self.get_entity(Engagement, request_data_mgr.get_eng_uuid())
+ msg = "OK"
+ vf = VF.objects.get(engagement__uuid=eng.uuid)
+ if ('target_date' not in data or not data['target_date'] or data['target_date'] == ''):
+ msg = "target_date parameter is missing or empty"
+ self.logger.error(msg)
+ msg = "Action has failed due to bad request."
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ target_date = data['target_date']
+ date = parse_date(target_date)
+ vf.target_lab_entry_date = date
+ vf.save()
+ return Response(msg)
+
+
+@classDecorator([logFuncEntry, ])
+class Status(VvpApiView):
+
+ @auth(Permissions.get_engagement_status)
+ def get(self, request, eng_uuid):
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ latest_status = EngagementStatus.objects.filter(
+ engagement=engagement).distinct().order_by('-update_time')[:1]
+ if (latest_status.count() > 0):
+ latest_status = latest_status[0]
+ latest_status = EngagementStatusModelSerializer(latest_status).data
+ else:
+ latest_status = False
+ return Response(latest_status)
+
+ @auth(Permissions.put_engagement_status)
+ def put(self, request, eng_uuid):
+ user = request_data_mgr.get_user()
+ data = request.data
+
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ eng_status_uuid = data['eng_status_uuid']
+ description = data['description']
+
+ if not description:
+ msg = "Not description sent"
+ self.logger.error(msg)
+ msg = "You are not registered as a user, please sign up in order to perform this action"
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ # @UndefinedVariable
+ if (user.role.name != Roles.admin.name and user.role.name != Roles.el.name):
+ msg = "User not authorized"
+ self.logger.error(msg)
+ msg = "Internal error."
+ return Response(msg, status=HTTP_401_UNAUTHORIZED)
+
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ status = EngagementStatus.objects.get(uuid=eng_status_uuid)
+ eng_svc.update_engagement_status(
+ user, description, eng_status_uuid, engagement)
+
+ status = EngagementStatus.objects.get(uuid=eng_status_uuid)
+ status = EngagementStatusModelSerializer(status).data
+
+ return Response(status)
+
+ @auth(Permissions.put_engagement_status)
+ def post(self, request, eng_uuid):
+ user = request_data_mgr.get_user()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ data = request.data
+
+ description = data['description']
+ if not description:
+ msg = "No description sent"
+ self.logger.error(msg)
+ msg = "No description sent"
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ # @UndefinedVariable
+ if (user.role.name != Roles.admin.name and user.role.name != Roles.el.name):
+ msg = "User not authorized"
+ self.logger.error(msg)
+ msg = "Internal error."
+ return Response(msg, status=HTTP_401_UNAUTHORIZED)
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ created_eng_staus = eng_svc.insert_engagement_status(
+ user, description, engagement)
+ created_eng_staus = EngagementStatusModelSerializer(
+ created_eng_staus).data
+ return Response(created_eng_staus)
+
+
+@classDecorator([logFuncEntry])
+class EngagementOps(VvpApiView):
+
+ @auth(Permissions.update_engagement)
+ def put(self, request, eng_uuid):
+ data = request.data
+ engagement_dict = data['engagement']
+ engagement = eng_svc.update_engagement(engagement_dict)
+
+ if engagement is None:
+ return Response(status=HTTP_400_BAD_REQUEST)
+ else:
+ if 'status' in data and data['status']:
+ user = request_data_mgr.get_user()
+ created_eng_status = eng_svc.insert_engagement_status(
+ user, data['status'], engagement)
+ return Response(EngagementStatusModelSerializer(created_eng_status).data)
+ else:
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class EngagementTeamUsers(VvpApiView):
+
+ @auth(Permissions.remove_from_engagement_team)
+ def put(self, request):
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ user = request_data_mgr.get_user()
+ data = request.data
+ if (data['user_uuid']):
+ requested_user_uuid = data['user_uuid']
+ if (eng_uuid is not None and user is not None and data['user_uuid'] is not None):
+ eng_svc.remove_user_from_engagement_team(
+ eng_uuid, user, requested_user_uuid)
+ return Response(status=HTTP_204_NO_CONTENT)
+
+
+@classDecorator([logFuncEntry])
+class EngagementReviewer(VvpApiView):
+
+ @auth(Permissions.update_engagement_reviewers)
+ def put(self, request, eng_uuid):
+ data = request.data
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ reviewer = eng_svc.set_engagement_reviewer(eng_uuid, data['reviewer'])
+
+ if reviewer is None:
+ return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
+ else:
+ return Response(reviewer)
+
+
+@classDecorator([logFuncEntry])
+class EngagementPeerReviewer(VvpApiView):
+
+ @auth(Permissions.update_engagement_reviewers)
+ def put(self, request, eng_uuid):
+ data = request.data
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ peer_reviewer = eng_svc.set_engagement_peer_reviewer(
+ eng_uuid, data['peerreviewer'])
+
+ if peer_reviewer is None:
+ return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
+ else:
+ return Response(peer_reviewer)
+
+
+@classDecorator([logFuncEntry])
+class SwitchEngagementReviewers(VvpApiView):
+
+ @auth(Permissions.update_engagement_reviewers)
+ def put(self, request, eng_uuid):
+ data = request.data
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ resp = eng_svc.switch_engagement_reviewers(
+ eng_uuid, data['reviewer'], data['peerreviewer'])
+ if resp is None:
+ return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
+ else:
+ return Response(resp)
diff --git a/django/engagementmanager/rest/feedback.py b/django/engagementmanager/rest/feedback.py
new file mode 100755
index 0000000..b8075b8
--- /dev/null
+++ b/django/engagementmanager/rest/feedback.py
@@ -0,0 +1,70 @@
+#
+# ============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 rest_framework import status
+from rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.slack_client.api import SlackClient
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.models import Feedback as FeedbackModal
+
+
+@classDecorator([logFuncEntry])
+class Feedback(VvpApiView):
+
+ slack_client = SlackClient()
+
+ @auth(Permissions.add_feedback)
+ def post(self, request):
+ user = request_data_mgr.get_user()
+ if ('description' not in request.data or not request.data['description']):
+ raise KeyError("One of the input parameters are missing")
+ new_description = request.data['description']
+ new_feedback = FeedbackModal(
+ user=user,
+ description=new_description
+ )
+ new_feedback.save()
+ self.slack_client.send_slack_notifications_for_new_feedback(new_feedback, user)
+
+ return Response(status.HTTP_200_OK)
diff --git a/django/engagementmanager/rest/invite.py b/django/engagementmanager/rest/invite.py
new file mode 100755
index 0000000..8060a69
--- /dev/null
+++ b/django/engagementmanager/rest/invite.py
@@ -0,0 +1,97 @@
+#
+# ============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 rest_framework import status
+from rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.invite_service import inviteUserToSignUpOrLogin
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import logEncoding
+
+
+@classDecorator([logFuncEntry])
+class InviteTeamMember(VvpApiView):
+
+ @auth(Permissions.invite)
+ def post(self, request):
+ inviterUser = request_data_mgr.get_user()
+ msg = "OK"
+ sts = status.HTTP_200_OK
+ if (inviterUser != None):
+ dataList = []
+ dataList = request.data
+
+ for data in dataList:
+ if 'eng_uuid' in data and data['eng_uuid'] and 'email' in data and data['email']:
+ inviteUserToSignUpOrLogin(inviterUser, data, is_contact_user=False)
+ else:
+ msg = "No eng_uuid or no email found on the request body to invite-team-members. data=" + str(data)
+ self.logger.error(logEncoding(msg))
+ sts = status.HTTP_500_INTERNAL_SERVER_ERROR
+
+ return Response(msg, status=sts)
+
+
+@classDecorator([logFuncEntry])
+class InviteContact(VvpApiView):
+
+ @auth(Permissions.invite)
+ def post(self, request):
+ msg = "OK"
+ sts = status.HTTP_200_OK
+ data = request.data
+
+ if ('full_name' not in data or not data['full_name'] or
+ 'email' not in data or not data['email'] or
+ 'phone_number' not in data or not data['phone_number'] or
+ 'eng_uuid' not in data or not data['eng_uuid']):
+ msg = "One of the input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=status.HTTP_400_BAD_REQUEST)
+
+ inviterUser = request_data_mgr.get_user()
+ inviteUserToSignUpOrLogin(inviterUser, data, is_contact_user=True)
+
+ return Response(msg, status=sts)
diff --git a/django/engagementmanager/rest/login.py b/django/engagementmanager/rest/login.py
new file mode 100755
index 0000000..53b906b
--- /dev/null
+++ b/django/engagementmanager/rest/login.py
@@ -0,0 +1,88 @@
+#
+# ============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 rest_framework.permissions import AllowAny
+from rest_framework.response import Response
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import IceUserProfile
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.login_service import LoginSvc
+from engagementmanager.utils.authentication import JWTAuthentication
+
+
+@classDecorator([logFuncEntry])
+class Login(VvpApiView):
+ permission_classes = (AllowAny,)
+
+ def post(self, request, param):
+ data = request.data
+ jwt_obj = JWTAuthentication()
+ msg = ""
+ user_profile = IceUserProfile.objects.get(email=data['email'])
+ login_svc = LoginSvc()
+
+ reset_password_param = None
+ if param:
+ reset_password_param = param
+
+ reset_password_email, is_reset_pwd_flow = login_svc.identify_reset_password(jwt_obj, reset_password_param)
+
+ if not user_profile.user.is_active:
+ msg = login_svc.render_user_not_active_message(data['email'])
+ else:
+ if is_reset_pwd_flow:
+ msg = login_svc.reset_password(
+ reset_password_email, data['password'], msg, user_profile)
+ else:
+ user_profile.user.User = login_svc.authenticate_user(
+ data['email'], data['password'], msg)
+
+ msg = login_svc.get_serialized_user_data(
+ is_reset_pwd_flow, user_profile, jwt_obj, user_profile.user)
+
+ if 'invitation' in data:
+ login_svc.handle_invite_token(data, msg, user_profile)
+
+ self.logger.debug("login has passed successfully for [email=" + data['email'] + "]")
+ login_svc.update_last_login(user_profile)
+
+ return Response(msg)
diff --git a/django/engagementmanager/rest/nextsteps.py b/django/engagementmanager/rest/nextsteps.py
new file mode 100755
index 0000000..7d4f850
--- /dev/null
+++ b/django/engagementmanager/rest/nextsteps.py
@@ -0,0 +1,163 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_204_NO_CONTENT
+
+from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import NextStep
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.utils.activities_data import DeleteNextStepsActivityData
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.nextstep_service import NextStepSvc
+from engagementmanager.utils.constants import NextStepState
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.apps import bus_service
+
+
+@classDecorator([logFuncEntry])
+class UserNextSteps(VvpApiView):
+
+ def get(self, request):
+ data_or_msg, count = NextStepSvc().get_user_next_steps(
+ 5, NextStepState.Incomplete.name) # @UndefinedVariable
+ return Response({'data': data_or_msg.data, 'count': count})
+
+
+@classDecorator([logFuncEntry])
+class NextSteps(VvpApiView):
+
+ @auth(Permissions.set_nextstep)
+ def post(self, request, **kwargs):
+ dataList = request.data
+ eng_uuid = request_data_mgr.get_eng_uuid()
+ user = request_data_mgr.get_user()
+
+ for data in dataList:
+ if ('description' not in data or not data['description']):
+ msg = "One of the input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ data = NextStepSvc().addNextStep(dataList)
+
+ for next_step in data:
+ if (next_step['files'] != None):
+ next_step['files'] = json.loads(next_step['files'])
+
+ self.logger.debug("Successfully added a Next Step to engagement_uuid=" +
+ eng_uuid + " for creator with uuid=" + str(user))
+ return Response(data)
+
+ @auth(Permissions.eng_membership)
+ def get(self, request, **kwargs):
+ next_steps_data = NextStepSvc().get_next_steps(eng_stage=kwargs['eng_stage'])
+ return Response(next_steps_data.data)
+
+ @auth(Permissions.update_personal_next_step)
+ def put(self, request, **kwargs):
+ data = request.data
+ ns_state = attribute = None
+ if ('attr' in kwargs):
+ attribute = kwargs['attr']
+ if ('state' in data):
+ ns_state = data['state']
+ NextStepSvc().set_next_step_status(attr=attribute, state=ns_state)
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class OrderNextSteps(VvpApiView):
+
+ @auth(Permissions.order_nextstep)
+ def put(self, request, eng_uuid):
+ data = request.data
+ NextStepSvc().update_next_steps_order(nextsteps=data)
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class EditNextSteps(VvpApiView):
+ @auth(Permissions.edit_nextstep)
+ def put(self, request, ns_uuid):
+ data = request.data
+ NextStepSvc().update_next_step(data)
+ return Response()
+
+ @auth(Permissions.delete_nextstep)
+ def delete(self, request, ns_uuid):
+ ns = self.get_entity(NextStep, request_data_mgr.get_ns_uuid())
+ ns.delete()
+
+ activity_data = DeleteNextStepsActivityData(request_data_mgr.get_user(), ns.engagement)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ return Response(status=HTTP_204_NO_CONTENT)
+
+
+@classDecorator([logFuncEntry])
+class ChecklistNextStep(VvpApiView):
+
+ @auth(Permissions.add_checklist_nextstep)
+ def post(self, request, eng_uuid, checklistUuid):
+ body_unicode = request.body
+ dataList = json.loads(body_unicode)
+ msg = "OK"
+
+ if (request_data_mgr.get_cl_uuid() == None or request_data_mgr.get_eng_uuid() == None):
+ msg = "check list uuid or engagement uuid is missing from the url path parameters"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ for data in dataList:
+ if ('assigneesUuids' not in data or not data['assigneesUuids'] or
+ 'description' not in data or not data['description'] or
+ 'duedate' not in data or not data['duedate']):
+ msg = "One of the CheckList's input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ data = NextStepSvc().addNextStep(
+ dataList, desc="Checklist is denied due to a creation of a new NextStep")
+
+ return Response(data)
diff --git a/django/engagementmanager/rest/notification.py b/django/engagementmanager/rest/notification.py
new file mode 100755
index 0000000..34c4a7b
--- /dev/null
+++ b/django/engagementmanager/rest/notification.py
@@ -0,0 +1,89 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_204_NO_CONTENT,\
+ HTTP_400_BAD_REQUEST
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+import engagementmanager.models
+from engagementmanager.notifications import num_of_notifications_for_user, reset_num_of_notifications_for_user,\
+ pull_recent_notifications
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+@classDecorator([logFuncEntry])
+class PullNotifCount4User(VvpApiView):
+
+ def get(self, request):
+ user = request_data_mgr.get_user()
+ dataToJson = {}
+ notificationCtr = num_of_notifications_for_user(user.uuid)
+ dataToJson['notifications_number'] = str(notificationCtr)
+ return Response(dataToJson)
+
+
+@classDecorator([logFuncEntry])
+class NotificationOps(VvpApiView):
+
+ @auth(Permissions.delete_notification)
+ def delete(self, request, notif_uuid):
+ notif = self.get_entity(
+ engagementmanager.models.Notification, notif_uuid)
+ notif.delete()
+ return Response(status=HTTP_204_NO_CONTENT)
+
+ # PullRecentNotif4User
+ def get(self, request, user_uuid, offset, limit):
+ user = request_data_mgr.get_user()
+ serilizedActivitySet, num_of_objects = pull_recent_notifications(user.uuid, offset, limit)
+ if serilizedActivitySet is not None:
+ data = {'serilizedActivitySet': serilizedActivitySet, 'num_of_objects': num_of_objects}
+ return Response(data)
+ else:
+ return Response("Activity set wasn't found", status=HTTP_400_BAD_REQUEST)
+
+ # Reset the number of an unread notifications
+ def put(self, request):
+ user = request_data_mgr.get_user()
+ reset_num_of_notifications_for_user(user.uuid)
+ return Response()
diff --git a/django/engagementmanager/rest/parsers.py b/django/engagementmanager/rest/parsers.py
new file mode 100755
index 0000000..fce516a
--- /dev/null
+++ b/django/engagementmanager/rest/parsers.py
@@ -0,0 +1,118 @@
+#
+# ============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 rest_framework import parsers
+from bleach.sanitizer import Cleaner
+from django.http.request import QueryDict
+
+
+sanitizer = Cleaner(
+ tags=['a', 'b', 'i', 'p', 'span', 'div'],
+ attributes=['font-weight', 'href', 'style', 'bold'],
+ styles=[
+ 'color', 'font-family', 'font-style', 'font-weight',
+ 'text-decoration-line',
+ ],
+ protocols=['http'],
+ strip=True,
+ )
+
+
+def clean_r(obj):
+ """Apply bleach.clean() to strings in the given object, recursively.
+
+ Note that this applies clean() to keys as well as values.
+ """
+
+ # DataAndFiles objects: recurse on .data, passthrough .files
+ if isinstance(obj, parsers.DataAndFiles):
+ return parsers.DataAndFiles(clean_r(obj.data), obj.files)
+
+ # QueryDict: make new empty mutable object. Update, make immutable, return.
+ if isinstance(obj, QueryDict):
+ new_obj = QueryDict(mutable=True, encoding=obj.encoding)
+ for k, v in obj.lists():
+ new_obj.setlistdefault(sanitizer.clean(k)).extend(clean_r(v))
+ new_obj._mutable = False
+ return new_obj
+
+ # dict-like objects: clean keys, recursive-clean values
+ if callable(getattr(obj, "items", None)):
+ return obj.__class__(
+ (sanitizer.clean(k), clean_r(v))
+ for k, v in obj.items())
+
+ # string-like objects: clean
+ if isinstance(obj, str):
+ return sanitizer.clean(obj)
+
+ # list-like objects / iterables: recurse on all items
+ if callable(getattr(obj, "__iter__", None)):
+ return obj.__class__(clean_r(x) for x in obj)
+
+ # anything else: pass through
+ return obj
+
+
+class XSSParserMixin(parsers.BaseParser):
+ """Apply this mixin to rest_framework.parsers.BaseParser subclasses to
+ cause clean_r() to be run against the parsed data.
+
+ """
+ def parse(self, stream, media_type=None, parser_context=None):
+ return clean_r(
+ super().parse(
+ stream,
+ media_type=media_type,
+ parser_context=parser_context))
+
+
+class XSSJSONParser(XSSParserMixin, parsers.JSONParser):
+ pass
+
+
+class XSSFormParser(XSSParserMixin, parsers.FormParser):
+ pass
+
+
+class XSSMultiPartParser(XSSParserMixin, parsers.MultiPartParser):
+ pass
+
+
+# There's no need to XSS-scrub FileUploadParser since its DataAndFiles.data is
+# always empty.
diff --git a/django/engagementmanager/rest/signup.py b/django/engagementmanager/rest/signup.py
new file mode 100755
index 0000000..85d63cd
--- /dev/null
+++ b/django/engagementmanager/rest/signup.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 uuid
+
+from django.template.loader import get_template
+from django.utils import timezone
+from rest_framework import status
+from rest_framework.parsers import JSONParser
+from rest_framework.permissions import AllowAny
+from rest_framework.response import Response
+
+from engagementmanager import mail
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import Vendor, Engagement, Role, Invitation, \
+ IceUserProfile, CustomUser
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import SuperThinIceUserProfileModelSerializer
+from engagementmanager.service.invite_service import markInvitationAsAccepted
+from engagementmanager.service.user_service import UserService
+from engagementmanager.utils.authentication import JWTAuthentication
+from engagementmanager.utils.constants import Constants, Roles
+from engagementmanager.utils.validator import Validator, logEncoding
+from engagementmanager.views_helper import generateActivationLink, \
+ createUserTemplate
+
+
+@classDecorator([logFuncEntry])
+class SignUp(VvpApiView):
+ permission_classes = (AllowAny,)
+
+ def post(self, request):
+ data = request.data
+ data_dont_save = JSONParser().parse(request)
+
+ if ('company' not in data or not data['company'] or
+ 'full_name' not in data or not data['full_name'] or
+ 'email' not in data or not data['email'] or
+ 'password' not in data or not data['password'] or
+ 'phone_number' not in data or not data['phone_number'] or
+ 'regular_email_updates' not in data):
+ msg = "One of the input parameters is missing"
+ self.logger.error(msg)
+ return Response(msg, status=status.HTTP_400_BAD_REQUEST)
+
+ Validator.validatePassword(data['password'])
+
+ i_full_name = data['full_name']
+ i_email = data['email']
+ i_phone_number = data['phone_number']
+ i_password = data['password']
+ i_regular_email_updates = data['regular_email_updates']
+ i_is_service_provider_contact = False
+
+ add_without_confirm = False
+
+ user_svc = UserService()
+
+ if 'add_from_import_excel' in data:
+ add_without_confirm = True
+
+ Validator.validateEmail(i_email)
+
+ if data_dont_save['company'] == Constants.service_provider_company_name:
+ i_is_service_provider_contact = True
+
+ mailTokens = i_email.split("@")
+ if mailTokens[1] not in Constants.service_provider_mail_domain and i_is_service_provider_contact:
+ msg = "Email address should be with service provider domain for signees that their company =" + \
+ Constants.service_provider_company_name
+ self.logger.error(logEncoding(msg))
+ return Response(msg, status=status.HTTP_400_BAD_REQUEST)
+
+ iceuser = IceUserProfile.objects.filter(email=i_email)
+ if (not iceuser.exists()):
+ roleObj = Role.objects.get(
+ name=Roles.standard_user.name) # @UndefinedVariable
+ activationToken = str(uuid.uuid4().hex)
+ i_company = Vendor.objects.get(name=data_dont_save['company'])
+
+ user_object = CustomUser.objects.create_user(username=i_email, email=i_email, password=i_password,
+ activation_token=activationToken, activation_token_create_time=timezone.now(), is_active=False)
+ info = createUserTemplate(i_company, i_full_name, roleObj, i_phone_number,
+ i_is_service_provider_contact, None, i_regular_email_updates, user_object)
+ newUserObj, is_profile_created = IceUserProfile.objects.update_or_create(
+ email=user_object.email, defaults=info)
+
+ self.logger.debug(
+ "Creating Non activated User: " + str(newUserObj))
+ userData = SuperThinIceUserProfileModelSerializer(newUserObj).data
+ # If we eng_uuid and inviter_uuid is supplied it means that this user was
+ # invited. We want to add them to the engagement team of the inviter
+
+ if 'invitation' in data:
+ invitation = Invitation.objects.get(
+ invitation_token=data['invitation'])
+ self.logger.debug("Looks like user " + i_full_name + " has arrived to the sign-up page from an invite email initiated by user with uuid=" +
+ invitation.invited_by_user_uuid + ". Adding them to the inviter's engagement_team...")
+
+ userData['eng_uuid'] = invitation.engagement_uuid
+ if data["is_contact_user"] == "true":
+ engObj = Engagement.objects.get(
+ uuid=invitation.engagement_uuid)
+ engObj.contact_user = newUserObj
+ self.logger.debug("Attaching the user (" + newUserObj.full_name +
+ ") to the engagement's (" + engObj.uuid + ") contact_user")
+ engObj.save()
+
+ user_svc.addUserToEngAndFireProvisionVfSig(
+ newUserObj, invitation)
+
+ otherInviteObj = Invitation.objects.filter(
+ accepted=False, email=i_email).exclude(uuid=invitation.uuid)
+
+ if data['is_contact_user'] == "true" or data['is_contact_user'] == "True":
+ engObj = Engagement.objects.get(
+ uuid=invitation.engagement_uuid)
+ engObj.contact_user = newUserObj
+ self.logger.debug("Attaching the user (" + newUserObj.full_name +
+ ") to the engagement's (" + engObj.uuid + ") contact_user")
+ engObj.save()
+
+ markInvitationAsAccepted(data['invitation'])
+ for inviteObj in otherInviteObj:
+ user_svc.addUserToEngAndFireProvisionVfSig(
+ newUserObj, inviteObj)
+ markInvitationAsAccepted(inviteObj.invitation_token)
+
+ if (add_without_confirm):
+ newUserObj.is_active = True
+ newUserObj.save()
+ else:
+ data['activation_link'] = generateActivationLink(
+ activationToken, newUserObj)
+ self.logger.debug(
+ "Activation Link: " + data['activation_link'])
+
+ body = get_template("{activate_template_dir}activate_mail_body.html".format(
+ activate_template_dir=Constants.activate_template_dir))
+ subject = get_template("{activate_template_dir}activate_mail_subject.html".format(
+ activate_template_dir=Constants.activate_template_dir))
+ mail.sendMail(i_email, data, body, subject)
+
+ self.logger.debug(
+ "sign-up has passed successfully for [email=" + i_email + "]")
+
+ return Response(userData)
+ else:
+ msg = "email " + i_email + \
+ " already exists, no need to perform signup, try to login"
+ self.logger.info(logEncoding(msg))
+ return Response(msg, status=status.HTTP_409_CONFLICT)
diff --git a/django/engagementmanager/rest/user.py b/django/engagementmanager/rest/user.py
new file mode 100755
index 0000000..13fc916
--- /dev/null
+++ b/django/engagementmanager/rest/user.py
@@ -0,0 +1,241 @@
+#
+# ============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
+import uuid
+
+from django.conf import settings
+from django.contrib.auth.hashers import make_password
+from django.template.loader import get_template
+from rest_framework.parsers import JSONParser
+from rest_framework.permissions import AllowAny
+from rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST
+from rest_framework.status import HTTP_500_INTERNAL_SERVER_ERROR
+
+from engagementmanager import mail
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import IceUserProfile, Vendor
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import ThinIceUserProfileModelSerializer
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.user_service import UserService
+from engagementmanager.utils.authentication import JWTAuthentication
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import Validator
+from engagementmanager.vm_integration import vm_client
+
+
+@classDecorator([logFuncEntry])
+class SetSsh(VvpApiView):
+
+ def post(self, request):
+ user = request_data_mgr.get_user()
+ data = request.data
+ if 'ssh_key' in data and data['ssh_key'] != user.ssh_public_key:
+ user_service = UserService()
+ user_service.validate_ssh_key(data['ssh_key'])
+ user_service.setSSH(user, data['ssh_key'], 'set')
+ user.save()
+ vm_client.fire_event_in_bg(
+ 'send_ssh_key_created_or_updated_event', user)
+ return Response()
+
+
+@classDecorator([logFuncEntry])
+class UpdatePassword(VvpApiView):
+
+ def put(self, request):
+ data = request.data
+ msg = "OK"
+ Validator.validatePassword(data['password'], data['confirm_password'])
+ user = request_data_mgr.get_user()
+ user.user.set_password(data['password'])
+ user.user.temp_password = None
+ user.user.save()
+ self.logger.info("Reset Password finished successfully for user with uuid=" +
+ user.uuid + " Redirecting to Login")
+ return Response(msg)
+
+
+@classDecorator([logFuncEntry])
+class SendResetPasswordInstructionMail(VvpApiView):
+ permission_classes = (AllowAny,)
+
+ def post(self, request):
+ msg = "OK"
+ user = None
+ data = request.data
+
+ if ('email' not in data or not data['email']):
+ msg = "Email address is missing"
+ self.logger.error(msg)
+ return Response(msg, status=HTTP_400_BAD_REQUEST)
+
+ Validator.validateEmail(data['email'])
+
+ user = IceUserProfile.objects.get(email=data['email'])
+ jwt_obj = JWTAuthentication()
+ token = jwt_obj.create_reset_password_token(user.user)
+
+ data['tempPassword'] = str(uuid.uuid1()).split("-")[0]
+ data['login_link'] = str(
+ settings.DOMAIN) + "/#/login?t=" + str(token)
+ self.logger.debug(
+ "The login link to reset Password: " + str(data['login_link']))
+
+ if (user != None):
+ body = get_template("{reset_pwd_template_dir}reset_pwd_instructions_mail_body.html" .format(
+ reset_pwd_template_dir=Constants.reset_pwd_template_dir))
+ subject = get_template("{reset_pwd_template_dir}reset_pwd_instructions_mail_subject.html".format(
+ reset_pwd_template_dir=Constants.reset_pwd_template_dir))
+
+ user.user.temp_password = make_password(data['tempPassword'])
+ user.user.save()
+ user.save()
+
+ try:
+ mail.sendMail(data['email'], data, body, subject)
+ except Exception as e:
+ msg = "Something went wrong while trying to send reset-password mail to " + \
+ data['email'] + "\n error: " + e.message
+ self.logger.error(
+ msg + " rolling back the temporary password from the DB")
+ user.user.temp_password = None
+ user.save()
+ return Response(msg, status=HTTP_500_INTERNAL_SERVER_ERROR)
+ return Response(msg)
+
+
+@classDecorator([logFuncEntry])
+class User(VvpApiView):
+
+ def get(self, request):
+ user = request_data_mgr.get_user()
+ return Response(ThinIceUserProfileModelSerializer(user).data)
+
+ def put(self, request):
+ data_dont_save = JSONParser().parse(request)
+ data = request.data
+ errors_list = []
+ self.validate_mandatory_fields(data, errors_list)
+ user = request_data_mgr.get_user()
+ user.company = Vendor.objects.get(name=data_dont_save['company'])
+ user.phone_number = data['phone_number']
+ user.full_name = data['full_name']
+ if len(user.full_name) > 30:
+ return Response("first name should be up to 30 characters", status=HTTP_400_BAD_REQUEST)
+
+ self.handle_password_change(data, user)
+
+ ssh_changed = self.handle_ssh_change(data, user)
+
+ self.handle_notifications_settings_change(data, user)
+
+ if len(errors_list) != 0:
+ return Response(errors_list, status=HTTP_400_BAD_REQUEST)
+
+ user.save()
+
+ if ssh_changed:
+ vm_client.fire_event_in_bg(
+ 'send_ssh_key_created_or_updated_event', user)
+
+ userData = ThinIceUserProfileModelSerializer(user).data
+ self.logger.info(
+ "Account updated successfully for user with uuid=" + user.uuid)
+ userData['password'] = ""
+ return Response(userData)
+
+ def handle_notifications_settings_change(self, data, user):
+ if 'regular_email_updates' in data:
+ user.regular_email_updates = data['regular_email_updates']
+ if 'email_updates_daily_digest' in data:
+ user.email_updates_daily_digest = data[
+ 'email_updates_daily_digest']
+ if 'email_updates_on_every_notification' in data:
+ user.email_updates_on_every_notification = data[
+ 'email_updates_on_every_notification']
+
+ def handle_ssh_change(self, data, user):
+ ssh_changed = False
+ if 'ssh_key' in data and data['ssh_key'] != user.ssh_public_key:
+ user_service = UserService()
+ user_service.validate_ssh_key(data['ssh_key'])
+ if not user.ssh_public_key:
+ user_service.setSSH(user, data['ssh_key'], 'add')
+ else:
+ user_service.setSSH(user, data['ssh_key'], 'set')
+ if data['ssh_key']:
+ ssh_changed = True
+ return ssh_changed
+
+ def handle_password_change(self, data, user):
+ if 'password' in data and data['password']:
+ Validator.validatePassword(
+ data['password'], data['confirm_password'])
+ user.user.set_password(data['password'])
+ user.user.save()
+
+ def validate_mandatory_fields(self, data, errors_list):
+ if ('company' not in data or not data['company'] or
+ 'full_name' not in data or not data['full_name'] or
+ 'email' not in data or not data['email'] or
+ 'phone_number' not in data or not data['phone_number']):
+ msg = "One of the input parameters is missing. #"
+ errors_list.append(msg)
+ self.logger.error(msg)
+
+
+@classDecorator([logFuncEntry])
+class EngagementLeads(VvpApiView):
+
+ @auth(Permissions.archive_engagement)
+ def get(self, request):
+ el_list = UserService().get_el_list()
+ return Response(el_list)
+
+
+@classDecorator([logFuncEntry])
+class RGWAAccessKey(VvpApiView):
+
+ def get(self, request):
+ return Response({"rgwa_secret_key": UserService().get_user_rgwa_secret()})
diff --git a/django/engagementmanager/rest/validation_details.py b/django/engagementmanager/rest/validation_details.py
new file mode 100755
index 0000000..1f1a929
--- /dev/null
+++ b/django/engagementmanager/rest/validation_details.py
@@ -0,0 +1,55 @@
+#
+# ============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 rest_framework.response import Response
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.views_helper import updateValidationDetails
+
+
+@classDecorator([logFuncEntry])
+class UpdateValidationDetails(VvpApiView):
+
+ @auth(Permissions.update_vf)
+ def put(self, request, vf_uuid):
+ updateValidationDetails(request)
+ return Response()
diff --git a/django/engagementmanager/rest/vendor.py b/django/engagementmanager/rest/vendor.py
new file mode 100755
index 0000000..b6ae351
--- /dev/null
+++ b/django/engagementmanager/rest/vendor.py
@@ -0,0 +1,95 @@
+#
+# ============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 rest_framework.permissions import AllowAny, IsAuthenticatedOrReadOnly
+from rest_framework.response import Response
+from rest_framework.status import HTTP_409_CONFLICT, HTTP_204_NO_CONTENT
+
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import Vendor
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import ThinVendorModelSerializer
+
+
+@classDecorator([logFuncEntry])
+class VendorREST(VvpApiView):
+ permission_classes = (IsAuthenticatedOrReadOnly,)
+
+ def get(self, request):
+ self.permission_classes = (AllowAny,)
+ vendors = Vendor.objects.filter(public=True)
+ serializer = ThinVendorModelSerializer(vendors, many=True)
+ return Response(serializer.data)
+
+ """
+ expecting: Vendor object fields
+ result: addition of a Vendor object to the DB
+ """
+
+ def post(self, request):
+ msg = ""
+ sts = None
+ data = request.data
+
+ vendor = None
+ public = False
+ if 'public' in data:
+ public = data['public']
+ try:
+ vendor = Vendor.objects.get(name=data['name'])
+ msg = "Company: " + vendor.name + " already exist"
+ self.logger.error(msg)
+ sts = HTTP_409_CONFLICT
+ return Response(msg, status=sts)
+ # If the VFC Does not exist, then continue as usual and create it.
+ except Vendor.DoesNotExist:
+ company = Vendor.objects.create(name=data['name'], public=False)
+ company.save()
+ return Response(msg)
+
+ """
+ expecting: Vendor object uuid
+ result: Deletion of the Vendor object from the DB
+ """
+
+ def delete(self, request, uuid):
+ msg = ""
+ sts = HTTP_204_NO_CONTENT
+ vendor = Vendor.objects.get(uuid=uuid).delete()
+ return Response(msg, status=sts)
diff --git a/django/engagementmanager/rest/vf.py b/django/engagementmanager/rest/vf.py
new file mode 100755
index 0000000..23ee5b9
--- /dev/null
+++ b/django/engagementmanager/rest/vf.py
@@ -0,0 +1,74 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_400_BAD_REQUEST
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.vf_service import VFSvc
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.views_helper import createVF
+
+
+@classDecorator([logFuncEntry])
+class VF(VvpApiView):
+
+ vf_svc = VFSvc()
+
+ @auth(Permissions.add_vf)
+ def post(self, request):
+ user = request_data_mgr.get_user()
+ vfList = []
+ if user is not None:
+ vfList = createVF(user, request)
+ return Response(vfList)
+ else:
+ msg = "User wasn't found on top of the kwargs"
+ sts = HTTP_400_BAD_REQUEST
+ self.logger.error(logEncoding(msg))
+ msg = "Action Failed"
+ return Response(msg, status=sts)
+
+ def get(self, request, vf_uuid):
+ vf_version = self.vf_svc.get_vf_version(vf_uuid)
+ return Response(vf_version)
diff --git a/django/engagementmanager/rest/vfc.py b/django/engagementmanager/rest/vfc.py
new file mode 100755
index 0000000..9ebf3bc
--- /dev/null
+++ b/django/engagementmanager/rest/vfc.py
@@ -0,0 +1,86 @@
+#
+# ============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 rest_framework.response import Response
+from rest_framework.status import HTTP_204_NO_CONTENT
+
+from engagementmanager.decorator.auth import auth
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.models import VF, VFC
+from engagementmanager.rest.vvp_api_view import VvpApiView
+from engagementmanager.serializers import VFCModelSerializer
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.vfc_service import VFCSvc
+
+
+@classDecorator([logFuncEntry])
+class VFCRest(VvpApiView):
+ vfc_service = VFCSvc()
+
+ @auth(Permissions.get_vfc)
+ def get(self, request, vf_uuid):
+
+ vf = VF.objects.get(uuid=vf_uuid)
+ vfcs = VFC.objects.filter(vf=vf)
+ serializer = VFCModelSerializer(vfcs, many=True)
+ return Response(serializer.data)
+
+ """
+ expecting: VF object uuid, VFC relevant fields(excluding the ones with default field)
+ result: addition of a VFC to the DB and concatenating them with the VF object
+ """
+ # This method doesn't need to be decorated with auth since it doesn't pass any engagement data from the front-end
+
+ @auth(Permissions.add_vfc)
+ def post(self, request):
+ data = request.data
+ msg = self.vfc_service.create_vfc(data)
+ return Response(msg)
+
+ """
+ expecting: VFC object uuid
+ result: Deletion of the VFC object with vfc_uuid
+ """
+
+ @auth(Permissions.delete_vfc)
+ def delete(self, request, vf_uuid, vfc_uuid):
+ self.vfc_service.delete_vfc(vfc_uuid)
+ return Response(status=HTTP_204_NO_CONTENT)
diff --git a/django/engagementmanager/rest/vvp_api_view.py b/django/engagementmanager/rest/vvp_api_view.py
new file mode 100755
index 0000000..4abe086
--- /dev/null
+++ b/django/engagementmanager/rest/vvp_api_view.py
@@ -0,0 +1,64 @@
+#
+# ============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 abc import ABCMeta
+from rest_framework.views import APIView
+from engagementmanager.decorator.class_decorator import classDecorator
+from engagementmanager.decorator.log_func_entry import logFuncEntry
+from engagementmanager.service.authorization_service import AuthorizationService
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+
+@classDecorator([logFuncEntry])
+class VvpApiView(APIView):
+ '''
+ classdocs This is the base abstract class of all ice REST views
+ '''
+ __metaclass__ = ABCMeta
+
+ logger = LoggingServiceFactory.get_logger()
+
+ def initial(self, request, *args, **kwargs):
+ super(VvpApiView, self).initial(request, *args, **kwargs)
+ auth_service = AuthorizationService()
+ args += request,
+ auth_service.prepare_data_for_auth(*args, **kwargs)
+
+ def get_entity(self, entity_name, uuid):
+ entity = entity_name.objects.get(uuid=uuid)
+ return entity
diff --git a/django/engagementmanager/scheduled_jobs.py b/django/engagementmanager/scheduled_jobs.py
new file mode 100755
index 0000000..9430ff6
--- /dev/null
+++ b/django/engagementmanager/scheduled_jobs.py
@@ -0,0 +1,67 @@
+#
+# ============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 apscheduler.schedulers.background import BackgroundScheduler
+from django.conf import settings
+from engagementmanager.bus.messages.daily_scheduled_message import DailyScheduledMessage
+from engagementmanager.bus.messages.hourly_scheduled_message import HourlyScheduledMessage
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class ScheduledJobs:
+ def __init__(self, bus_service):
+ self.bus_service = bus_service
+ self.background_scheduler = BackgroundScheduler()
+ self.background_scheduler.start()
+
+ def __daily_scheduled_job(self):
+ logger.debug("Daily scheduled job is about to start.")
+ self.bus_service.send_message(DailyScheduledMessage())
+
+ def setup_daily_job(self):
+ self.background_scheduler.add_job(self.__daily_scheduled_job, 'cron',
+ hour=settings.DAILY_SCHEDULED_JOB_HOUR, day='*')
+
+ def __hourly_scheduled_job(self):
+ logger.debug("Hourly scheduled job is about to start.")
+ self.bus_service.send_message(HourlyScheduledMessage())
+
+ def setup_hourly_job(self):
+ self.background_scheduler.add_job(self.__hourly_scheduled_job, 'cron', minute=0, hour='*', day='*')
diff --git a/django/engagementmanager/serializers.py b/django/engagementmanager/serializers.py
new file mode 100755
index 0000000..e3e88b0
--- /dev/null
+++ b/django/engagementmanager/serializers.py
@@ -0,0 +1,423 @@
+#
+# ============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.
+'''
+Each entity has a model serializer that save/update the object in its create()/update() methods and a regular dictionary (map) serializer that return a new/updated instance of the object
+
+'''
+from rest_framework import serializers
+
+from engagementmanager.models import NextStep, Notification, Activity, \
+ ChecklistTemplate, Checklist, ChecklistAuditLog, ChecklistDecision, \
+ ChecklistLineItem, ECOMPRelease, EngagementStatus, CustomUser, \
+ ChecklistSection
+
+from .models import IceUserProfile, VFC, Engagement, VF, DeploymentTarget, Role, Vendor, DeploymentTargetSite
+
+
+class RoleModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Role
+ fields = '__all__'
+
+
+class VendorModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Vendor
+ fields = '__all__'
+
+
+class ThinVendorModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Vendor
+ fields = ('uuid', 'name')
+
+
+class SuperThinCustomUserModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = CustomUser
+ fields = ('is_active', 'email', 'activation_token')
+
+
+class ThinCustomUserModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = CustomUser
+ fields = ('email', 'activation_token', 'is_active',
+ 'activation_token_create_time')
+
+
+class IceUserProfileModelSerializer(serializers.ModelSerializer):
+ role = RoleModelSerializer(many=False)
+ company = VendorModelSerializer(many=False)
+ user = ThinCustomUserModelSerializer(many=False)
+
+ class Meta:
+ model = IceUserProfile
+
+
+class SuperThinIceUserProfileModelSerializer(serializers.ModelSerializer):
+ role = RoleModelSerializer(many=False)
+ company = VendorModelSerializer(many=False)
+ user = SuperThinCustomUserModelSerializer(many=False)
+
+ class Meta:
+ model = IceUserProfile
+ fields = ('full_name', 'email', 'uuid', 'role',
+ 'user', 'company', 'phone_number')
+
+
+class SuperThinIceUserProfileModelSerializerForSignals(serializers.ModelSerializer):
+ role = RoleModelSerializer(many=False)
+
+ class Meta:
+ model = IceUserProfile
+ fields = ('full_name', 'email', 'role', 'uuid', 'ssh_public_key')
+
+
+class ThinIceUserProfileModelSerializer(serializers.ModelSerializer):
+ role = RoleModelSerializer(many=False)
+ company = VendorModelSerializer(many=False)
+ user = SuperThinCustomUserModelSerializer(many=False)
+
+ class Meta:
+ model = IceUserProfile
+ fields = ('email', 'full_name', 'user', 'is_service_provider_contact', 'phone_number', 'role', 'uuid', 'company',
+ 'ssh_public_key', 'regular_email_updates', 'email_updates_on_every_notification',
+ 'email_updates_daily_digest', 'rgwa_access_key')
+
+
+class EngagementStatusModelSerializer(serializers.ModelSerializer):
+ creator = SuperThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ model = EngagementStatus
+ fields = '__all__'
+
+
+class EngagementModelSerializer(serializers.ModelSerializer):
+ engagement_team = SuperThinIceUserProfileModelSerializer(many=True)
+ contact_user = SuperThinIceUserProfileModelSerializer(many=False)
+ creator = SuperThinIceUserProfileModelSerializer(many=False)
+ peer_reviewer = SuperThinIceUserProfileModelSerializer(many=False)
+ reviewer = SuperThinIceUserProfileModelSerializer(many=False)
+ starred_engagement = SuperThinIceUserProfileModelSerializer(many=True)
+
+ class Meta:
+ model = Engagement
+ fields = '__all__'
+
+
+class ThinEngagementModelSerializer(serializers.ModelSerializer):
+ creator = SuperThinIceUserProfileModelSerializer(many=False)
+ engagement_team = SuperThinIceUserProfileModelSerializer(many=True)
+ peer_reviewer = SuperThinIceUserProfileModelSerializer(many=False)
+ reviewer = SuperThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ model = Engagement
+ fields = ('uuid', 'engagement_manual_id', 'creator',
+ 'engagement_team', 'peer_reviewer', 'reviewer')
+
+
+class DeploymentTargetModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = DeploymentTarget
+ fields = ('uuid', 'name', 'version', 'weight', 'ui_visibility')
+
+
+class ECOMPReleaseModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ECOMPRelease
+ fields = ('uuid', 'name', 'weight', 'ui_visibility')
+
+
+class ThinVFModelSerializer(serializers.ModelSerializer):
+ engagement = ThinEngagementModelSerializer(many=False)
+
+ class Meta:
+ model = VF
+ fields = (
+ 'uuid', 'name', 'engagement', 'is_service_provider_internal', 'ecomp_release')
+
+
+class ThinDeploymentTargetSiteModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = DeploymentTargetSite
+ fields = ('uuid', 'name')
+
+
+class DeploymentTargetSiteModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = DeploymentTargetSite
+ fields = '__all__'
+
+
+class VFModelSerializer(serializers.ModelSerializer):
+ engagement = EngagementModelSerializer(many=False)
+ deployment_target = DeploymentTargetModelSerializer(many=False)
+ ecomp_release = ECOMPReleaseModelSerializer(many=False)
+ deployment_target_sites = ThinDeploymentTargetSiteModelSerializer(
+ many=True)
+ vendor = VendorModelSerializer(many=False)
+
+ class Meta:
+ model = VF
+ fields = '__all__'
+
+
+class VFCModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = VFC
+ fields = '__all__'
+
+
+class ActivityModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Activity
+ fields = '__all__'
+
+
+class ThinActivityModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Activity
+ fields = ('uuid', 'description', 'create_time', 'metadata')
+
+
+class NotificationModelSerializer(serializers.ModelSerializer):
+ activity = ActivityModelSerializer(many=False)
+
+ class Meta:
+ model = Notification
+ fields = '__all__'
+
+
+class ThinNotificationModelSerializer(serializers.ModelSerializer):
+ activity = ThinActivityModelSerializer(many=False)
+
+ class Meta:
+ model = Notification
+ fields = '__all__'
+
+
+class ChecklistTemplateModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistTemplate
+ exclude = ('create_time', 'update_time', 'category', 'version')
+
+
+class ThinChecklistTemplateModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistTemplate
+ fields = ('uuid', 'name')
+
+
+class ChecklistModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = Checklist
+ fields = '__all__'
+
+
+class SuperThinChecklistModelSerializer(serializers.ModelSerializer):
+ owner = ThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ model = Checklist
+ fields = ('uuid', 'name', 'state', 'owner')
+
+
+class ThinChecklistModelSerializer(serializers.ModelSerializer):
+ engagement = ThinEngagementModelSerializer(many=False)
+ template = ThinChecklistTemplateModelSerializer(many=False)
+ owner = ThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ model = Checklist
+ fields = ('uuid', 'name', 'state', 'owner', 'weight',
+ 'associated_files', 'engagement', 'template')
+
+
+class ThinPostChecklistResponseModelSerializer(serializers.ModelSerializer):
+ template = ThinChecklistTemplateModelSerializer(many=False)
+
+ class Meta:
+ model = Checklist
+ fields = ('uuid', 'name', 'state', 'associated_files', 'template')
+
+
+class UserNextStepModelSerializer(serializers.ModelSerializer):
+ engagement_manual_id = serializers.CharField(
+ source='engagement.engagement_manual_id')
+ engagement_uuid = serializers.CharField(source='engagement.uuid')
+ creator_full_name = serializers.CharField(source='creator.full_name')
+ vf_name = serializers.CharField(source='engagement.vf.name')
+
+ class Meta:
+ model = NextStep
+ fields = ('due_date', 'engagement_manual_id', 'description',
+ 'create_time', 'creator_full_name', 'vf_name', 'engagement_uuid')
+
+
+class NextStepModelSerializer(serializers.ModelSerializer):
+ engagement = EngagementModelSerializer(many=False)
+ creator = SuperThinIceUserProfileModelSerializer(many=False)
+ last_updater = SuperThinIceUserProfileModelSerializer(many=False)
+ assignees = SuperThinIceUserProfileModelSerializer(many=True)
+
+ class Meta:
+ model = NextStep
+ fields = '__all__'
+
+
+class ThinNextStepModelSerializer(serializers.ModelSerializer):
+ assignees = SuperThinIceUserProfileModelSerializer(many=True)
+ last_updater = SuperThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ ordering = ('position')
+ model = NextStep
+ fields = '__all__'
+
+
+class TestEngineChecklistModelSerializer(serializers.ModelSerializer):
+ template_id = serializers.CharField(source='template.uuid')
+ engagement_manual_id = serializers.CharField(
+ source='engagement.engagement_manual_id')
+ engagement_id = serializers.CharField(source='engagement.uuid')
+ creator_id = serializers.CharField(source='engagement.creator.uuid')
+
+ class Meta:
+ model = Checklist
+ fields = ('uuid', 'state', 'associated_files', 'template_id',
+ 'engagement_manual_id', 'engagement_id', 'creator_id')
+
+
+class ChecklistAuditLogModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistAuditLog
+ fields = '__all__'
+
+
+class ThinChecklistAuditLogModelSerializer(serializers.ModelSerializer):
+ creator = SuperThinIceUserProfileModelSerializer(many=False)
+
+ class Meta:
+ model = ChecklistAuditLog
+ fields = ('uuid', 'category', 'description', 'create_time', 'creator')
+
+
+class ChecklistSectionModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistSection
+ exclude = ('template', 'parent_section', 'create_time', 'update_time')
+
+
+class ChecklistLineItemModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistLineItem
+ exclude = ('section', 'template', 'create_time', 'update_time')
+
+
+class ThinChecklistSectionModelSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model = ChecklistLineItem
+ fields = ('uuid', 'name', 'weight', 'description')
+
+
+class ThinChecklistLineItemModelSerializer(serializers.ModelSerializer):
+ section = ThinChecklistSectionModelSerializer(many=False)
+
+ class Meta:
+ model = ChecklistLineItem
+ fields = ('uuid', 'name', 'line_type', 'weight',
+ 'description', 'validation_instructions', 'section')
+
+
+class ThinChecklistDecisionModelSerializer(serializers.ModelSerializer):
+ lineitem = ThinChecklistLineItemModelSerializer(many=False)
+
+ class Meta:
+ model = ChecklistDecision
+ fields = ('uuid', 'review_value', 'peer_review_value', 'lineitem')
+
+
+class EngagementModelSerializerForSignal(serializers.ModelSerializer):
+ engagement_team = SuperThinIceUserProfileModelSerializerForSignals(
+ many=True)
+ contact_user = SuperThinIceUserProfileModelSerializerForSignals(many=False)
+ creator = SuperThinIceUserProfileModelSerializerForSignals(many=False)
+ peer_reviewer = SuperThinIceUserProfileModelSerializerForSignals(
+ many=False)
+ reviewer = SuperThinIceUserProfileModelSerializerForSignals(many=False)
+ starred_engagement = SuperThinIceUserProfileModelSerializerForSignals(
+ many=True)
+
+ class Meta:
+ model = Engagement
+ fields = '__all__'
+
+
+class VFModelSerializerForSignal(serializers.ModelSerializer):
+ engagement = EngagementModelSerializerForSignal(many=False)
+ deployment_target = DeploymentTargetModelSerializer(many=False)
+ ecomp_release = ECOMPReleaseModelSerializer(many=False)
+ deployment_target_sites = ThinDeploymentTargetSiteModelSerializer(
+ many=True)
+ vendor = VendorModelSerializer(many=False)
+
+ class Meta:
+ model = VF
+ fields = '__all__'
diff --git a/django/engagementmanager/service/__init__.py b/django/engagementmanager/service/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/service/__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/service/activities_service.py b/django/engagementmanager/service/activities_service.py
new file mode 100755
index 0000000..b7edca4
--- /dev/null
+++ b/django/engagementmanager/service/activities_service.py
@@ -0,0 +1,238 @@
+#
+# ============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.utils import timezone
+from engagementmanager.bus.messages.new_notification_message import NewNotificationMessage
+from engagementmanager.models import IceUserProfile, Activity, Notification
+from engagementmanager.utils import activities_data
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class ActivitiesSvc:
+ def __init__(self):
+ pass
+
+ def generate_activity(self, activity_data):
+ if hasattr(activity_data, "users_list") and activity_data.users_list:
+ for user in activity_data.users_list:
+ activity_data.user = user
+ if hasattr(activity_data, "multiple_users_as_owners") and activity_data.multiple_users_as_owners:
+ activity_data.owner = activity_data.user
+ self.set_description(activity_data)
+ self.set_metadata(activity_data)
+ self.__create_activity(activity_data)
+ else:
+ self.set_description(activity_data)
+ self.set_metadata(activity_data)
+ self.__create_activity(activity_data)
+
+ def __create_activity(self, activity_data):
+ if activity_data.engagement is None:
+ msg = "Engagement provided is a None object, be careful not to generate " \
+ "description and metadata with engagement properties."
+ logger.warn(msg)
+ if activity_data.owner and not isinstance(activity_data.owner, IceUserProfile):
+ raise ValueError("owner should be IceUserProfile, was %r", activity_data.owner)
+ if activity_data.description is None:
+ logger.warn('createActivity called with description=None; setting to ""')
+ activity_data.description = ''
+
+ new_activity = Activity.objects.create(
+ activity_owner=activity_data.owner,
+ description=activity_data.description,
+ is_notification=activity_data.is_notification,
+ engagement=activity_data.engagement,
+ activity_type=activity_data.activity_type.name,
+ metadata=json.dumps(activity_data.metadata, ensure_ascii=False),)
+
+ if activity_data.engagement:
+ activity_data.engagement.activity_set.add(new_activity)
+ new_activity.save()
+
+ if activity_data.is_notification:
+ users_to_notify = []
+
+ if activity_data.owner is None:
+ if activity_data.engagement:
+ users_to_notify = activity_data.engagement.engagement_team.all()
+ else:
+ users_to_notify.append(activity_data.owner)
+
+ for user_to_notify in users_to_notify:
+ new_notification = Notification.objects.create(user=user_to_notify, activity=new_activity)
+ new_activity.notification_set.add(new_notification)
+ user_to_notify.notification_set.add(new_notification)
+ new_notification.save()
+ from engagementmanager.apps import bus_service
+ bus_service.send_message(NewNotificationMessage(new_notification))
+
+ def pull_recent_activities(self, engagement, recent_activities_limit):
+ """ expected: engagement object (Activity), recent_activities_limit (integer) - number of recent activities
+ result: Top-X Dict Activity objects (sort by create_time) """
+ logger.debug("Pulling top X activities from DB")
+ activities = Activity.objects.filter(
+ engagement=engagement, activity_owner=None).order_by('-create_time')[:recent_activities_limit]
+ return activities
+
+ def set_description(self, activity_data):
+ dt = timezone.now()
+ description = ''
+
+ if isinstance(activity_data, activities_data.UserJoinedEngagementActivityData):
+ description = "##user_name## joined ##vf_name## "
+ elif isinstance(activity_data, activities_data.UpdateNextStepsActivityData):
+ description = "##user_name## " + activity_data.update_type.lower() + " a next step"
+ elif isinstance(activity_data, activities_data.VFProvisioningActivityData):
+ description = "Failed Gitlab and/or Jenkins Provision ##vf_name##: " + activity_data.description
+ elif isinstance(activity_data, activities_data.TestFinishedActivityData):
+ description = "Failure in Jenkins Job: " + activity_data.description
+ elif isinstance(activity_data, activities_data.ChangeEngagementStageActivityData):
+ description = "Engagement stage is now " + activity_data.stage + " for the following VF: ##vf_name##"
+ elif isinstance(activity_data, activities_data.DeleteNextStepsActivityData):
+ description = activity_data.user.full_name + \
+ " has deleted a next step at " + dt.strftime("%Y-%m-%d %H:%M:%S")
+ elif isinstance(activity_data, activities_data.NoticeEmptyEngagementData):
+ description = "You have not added any parts of the VNF package to your engagement ##vf_name## since it was created " + activity_data.delta_days_from_creation +\
+ " days ago. Do note that if you have not added any parts of the VNF package by " + \
+ activity_data.max_empty_time + ", we will be automatically archive it."
+ elif isinstance(activity_data, activities_data.AddNextStepsActivityData):
+ description = activity_data.user.full_name + " has added a next step at " + dt.strftime("%Y-%m-%d %H:%M:%S")
+ elif isinstance(activity_data, activities_data.SSHKeyAddedActivityData):
+ if activity_data.action == 'add':
+ description = "You have added an SSH key to your profile"
+ elif activity_data.action == 'set':
+ description = "You have set a new SSH key in your profile"
+ else:
+ description = "SSH key activity"
+
+ activity_data.description = description
+
+ def set_metadata(self, activity_data):
+ dt = timezone.now()
+ metadata = {}
+
+ if isinstance(activity_data, activities_data.UserJoinedEngagementActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "Someone has joined the " + activity_data.vf.name + " team"
+ metadata['notification_message'] = activity_data.user.full_name + " joined the " + activity_data.vf.name + \
+ " team. You can reach the dashboard by going to this link: " + \
+ Constants.dashboard_href
+ metadata['macros'] = {
+ '##vf_name##': {
+ 'type': 'select_engagement',
+ 'short': activity_data.vf.name,
+ 'eng_uuid': str(activity_data.engagement.uuid),
+ },
+ '##user_name##': {
+ 'type': 'popover',
+ 'short': activity_data.user.full_name,
+ 'long': activity_data.user.email,
+ }
+ }
+ elif isinstance(activity_data, activities_data.UpdateNextStepsActivityData):
+ metadata['macros'] = {
+ '##user_name##': {
+ 'type': 'popover',
+ 'short': activity_data.user.full_name,
+ 'long': activity_data.user.email,
+ }
+ }
+ elif isinstance(activity_data, activities_data.NoticeEmptyEngagementData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "Inactive Engagement Alert - " + activity_data.vf_name
+
+ metadata['notification_message'] = "We have noticed that you have not added any parts of the VNF package to your engagement <em>" +\
+ activity_data.engagement.engagement_manual_id + ": " + activity_data.vf_name + "</em> since it was created " + activity_data.delta_days_from_creation +\
+ " days ago. If you have any questions around how you add your VNF package please check the relevant parts of the online documentation.<br/><br/>" +\
+ "Do note that if you have not added any parts of the VNF package by " + \
+ activity_data.max_empty_time + ", we will be automatically archive it."
+
+ metadata['macros'] = {
+ '##vf_name##': {
+ 'type': 'select_engagement',
+ 'short': activity_data.vf_name,
+ 'eng_uuid': activity_data.engagement.uuid,
+ },
+ }
+
+ elif isinstance(activity_data, activities_data.VFProvisioningActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "Failed Gitlab and/or Jenkins Provision: " + activity_data.vf.name
+ metadata['notification_message'] = activity_data.description
+ metadata['macros'] = {
+ '##vf_name##': {
+ 'type': 'select_engagement',
+ 'short': activity_data.vf.name,
+ 'eng_uuid': activity_data.vf.engagement.uuid,
+ },
+ }
+ elif isinstance(activity_data, activities_data.TestFinishedActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "Failed test_finished signal "
+ metadata['notification_message'] = activity_data.description
+ elif isinstance(activity_data, activities_data.ChangeEngagementStageActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "Engagement stage was changed for the following VF: " + \
+ activity_data.vf.name
+ metadata['notification_message'] = "Engagement stage is now " + activity_data.stage +\
+ " for the following VF: " + activity_data.vf.name
+ metadata['macros'] = {
+ '##vf_name##': {
+ 'type': 'select_engagement',
+ 'short': activity_data.vf.name,
+ 'eng_uuid': activity_data.engagement.uuid,
+ }
+ }
+ elif isinstance(activity_data, activities_data.AddNextStepsActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "New next-step was added to the following VF: " + activity_data.vf.name
+ metadata['notification_message'] = activity_data.user.full_name + " has added a next step at " +\
+ dt.strftime("%Y-%m-%d %H:%M:%S") + \
+ ", You can reach the dashboard by going to this link: " \
+ + Constants.dashboard_href
+ elif isinstance(activity_data, activities_data.SSHKeyAddedActivityData):
+ activity_data.is_notification = True
+ metadata['notification_subject'] = "You have set an SSH key"
+ metadata['notification_message'] = "You have set an SSH key to your profile. Please allow some time for" \
+ " it to propagate across the system."
+
+ activity_data.metadata = metadata
diff --git a/django/engagementmanager/service/authorization_service.py b/django/engagementmanager/service/authorization_service.py
new file mode 100755
index 0000000..c850b4a
--- /dev/null
+++ b/django/engagementmanager/service/authorization_service.py
@@ -0,0 +1,605 @@
+#
+# ============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 enum import Enum
+import rest_framework
+from engagementmanager.models import Role, Engagement, Checklist, NextStep, VFC, \
+ VF, ChecklistDecision, Notification
+from engagementmanager.utils.constants import Roles
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Permissions(Enum):
+ """
+ This ENUM holds all the actions that require permissions on the ICE portal
+ """
+ update_user = 1, # TODO Any user can update their own account
+ add_vendor = 2, # only el or admin
+ add_nextstep = 3, # only el or admin
+ complete_nextstep = 4, # any eng member
+ delete_nextstep = 5, # only el or admin
+ approve_nextstep = 6, # only el or admin
+ deny_nextstep = 7, # only el or admin
+ reset_nextstep = 8 # any eng member
+ add_checklist = 9, # only el of a given engagement
+ set_checklist_decision = 10, # TODO only el defined as owner of cl
+ add_checklist_audit_log = 11, # TODO only el defined as owner of cl
+ delete_checklist_audit_log = 12, # Do we have this capability ??
+ el_review_checklist = 13, # only checklist owner can set state.
+ # only el defined as peer_viewer of given engagement and is cl owner
+ peer_review_checklist = 14,
+ # TODO only admin which is defined as cl owner
+ admin_approve_checklist = 15,
+ # TODO only el of a given engagement and is the cl owner
+ handoff_checklist = 16,
+ add_vf = 17, # only standard_user
+ add_vfc = 18, # only standard_user ??
+ delete_vfc = 19, # only standard_user
+ add_checklist_nextstep = 20, # only el
+ is_el_of_eng = 21, # only el of engagement
+ update_personal_next_step = 22,
+ create_checklist_audit_log = 23,
+ create_checklist_decision = 24,
+ update_checklist_decision = 25,
+ update_checklist_state = 26,
+ create_deployment_target_site = 27,
+ star_an_engagement = 28,
+ invite = 29,
+ update_account = 30,
+ set_ssh = 31,
+ update_password = 32,
+ get_engagement_status = 34,
+ put_engagement_status = 35,
+ eng_membership = 36,
+ delete_engagement = 37,
+ view_checklist = 38, # only non-standard-user
+ get_vfc = 39,
+ pull_activities = 40,
+ get_deployment_target_site = 41,
+ add_deployment_target_site = 42,
+ delete_deployment_target_site = 43,
+ export_engagments = 44,
+ archive_engagement = 45,
+ get_el_list = 46,
+ update_engagement = 47,
+ view_checklist_template = 48,
+ edit_checklist_template = 49,
+ delete_notification = 50,
+ remove_from_engagement_team = 51,
+ update_engagement_reviewers = 52,
+ edit_nextstep = 54,
+ order_nextstep = 60,
+ set_nextstep = 56,
+ edit_stage = 57,
+ edit_progress_bar = 58,
+ get_progress_bar = 59,
+ change_lab_entry = 62,
+ update_vf = 61, # only non-standard-user
+ add_feedback = 63,
+
+
+class AuthorizationService:
+ """
+ The Authorization Service detemines whether a given action is authorized for a specific user.
+ The method: is_user_able_to performs the authorization check given a user and an action (from Permissions ENUM)
+ """
+ role_standard_user = None
+ role_el = None
+ role_admin = None
+ role_admin_ro = None
+
+ def __get_role_checks(self, user, action):
+ """
+ Returns the list of auth checks that should be performed per user action.
+ Returns None if the action is not listed in the authorized actions of the given user.
+ """
+ result = None
+
+ # EL #
+ if (user.role == self.role_el) and (action in self.el_permissions):
+ result = self.el_permissions[action]
+ # ADMIN #
+ elif user.role == self.role_admin and action in self.admin_permissions:
+ result = self.admin_permissions[action]
+ # ADMIN Read only #
+ elif user.role == self.role_admin_ro and action in self.admin_ro_permissions:
+ result = self.admin_ro_permissions[action]
+ # STANDRARD_USER #
+ if user.role == self.role_standard_user and action in self.standard_user_permissions:
+ result = self.standard_user_permissions[action]
+
+ return result
+
+ def __require_eng_membership(self, user, action, **kwargs):
+ """
+ Determines whether a given user is part of engagement team by the eng uuid
+ user = IceUser
+ eng = UUID as a string
+
+ :param user: user for auth check
+ :param action: action for auth check
+ :param kwargs: eng_uuid, checklist_uuid, ...
+ :return: Boolean, Message -> True/False if auth check succeeds/fails and a message describing auth failure
+ """
+ eng = kwargs['eng']
+
+ try:
+ # @UndefinedVariable
+ if (user.email == eng.reviewer.email or user.email == eng.peer_reviewer.email or user.role.name == Roles.admin.name):
+ return True, 'OK'
+ else:
+ # validate if user in Team
+ if user in eng.engagement_team.all():
+ return True, 'OK'
+ else:
+ return False, ""
+ except Engagement.DoesNotExist:
+ msg = 'User ' + user.email + ' is not a member of engagement: ' + eng.uuid + \
+ ' / User is a not peer reviewer / admin of the engagement / Engagement wasnt found while fetching from DB'
+ logger.info(msg)
+ return False, msg
+ except Exception as e:
+ print(e)
+ msg = 'A general error occurred while trying to validate that User ' + \
+ user.email + ' is a member of engagement '
+ logger.info(msg + " Error: " + str(e))
+ return False, msg
+
+ def __require_peer_review_ownership(self, user, action, **kwargs):
+ """
+ Determines whether the given user is the peer reviewer of the checklist
+ """
+
+ cl = kwargs['cl']
+ eng = kwargs['eng']
+ if cl and eng:
+ # @UndefinedVariable
+ if (eng.peer_reviewer == user and cl.owner == user) or (user.role.name == Roles.admin.name):
+ return True, 'OK'
+ else:
+ return False, 'User is either not the owner of the checklist or not a peer reviewer of the checklist'
+ else:
+ logger.error(
+ 'Internal Error - Checklist/Engagement not found while trying to check permissions for user ' + user.email)
+ return False, 'Internal Error - Checklist not found'
+
+ def __require_cl_ownership(self, user, action, **kwargs):
+ """
+ Determines whether the given user is the owner of the checklist
+ """
+
+ cl = kwargs['cl']
+ if cl:
+ # @UndefinedVariable
+ if cl.owner == user or user.role.name == Roles.admin.name:
+ return True, 'OK'
+ else:
+ return False, 'User is not the owner of the checklist'
+ else:
+ logger.error(
+ 'Internal Error - Checklist not found while trying to check permissions for user ' + user.email)
+ return False, 'Internal Error - Checklist not found'
+
+ def __require_el_of_engagement(self, user, action, **kwargs):
+ """
+ Determines whether the given user is the el of the engagement
+ """
+ eng = kwargs['eng']
+
+ if eng:
+ if (user.role.name == Roles.admin.name): # @UndefinedVariable
+ return True, 'OK'
+ if (user.uuid == eng.reviewer.uuid): # @UndefinedVariable
+ return True, 'OK'
+
+ return False, 'Role Not authorized'
+ else:
+ logger.error(
+ 'Internal Error - Engagement not found while trying to check permissions for user ' + user.email)
+ return False, 'Internal Error - Checklist not found'
+
+ def __noop(self, user, action, **kwargs):
+ """
+ Do nothing, just authorize the action for the given user
+ """
+ return True, 'OK'
+
+ def __prevent(self, user, action, **kwargs):
+ """
+ Do nothing, just prevent the action for the given user
+ """
+ return False, 'Role Not authorized'
+
+ def __is_notification_owner(self, user, action, **kwargs):
+ msg = 'Role Not authorized'
+ authorized = False
+
+ notification_uuid = request_data_mgr.get_notification_uuid()
+ if notification_uuid:
+ if Notification.objects.get(uuid=notification_uuid).user == user:
+ authorized = True
+ msg = 'OK'
+
+ return authorized, msg
+
+ ######################
+ # EL Permissions #
+ ######################
+ """
+ Each Permission Map is composed of the following key-val pairs:
+ Key='Action (Permission ENUM)' --> Value='Set of Checks to perform on this action.'
+ """
+ el_permissions = {
+ Permissions.add_vf: {__noop},
+ Permissions.add_feedback: {__noop},
+ Permissions.update_user: {__noop},
+ Permissions.add_vendor: {__noop},
+ Permissions.update_vf: {__require_eng_membership},
+ Permissions.add_nextstep: {__require_eng_membership},
+ Permissions.complete_nextstep: {__require_eng_membership},
+ Permissions.delete_nextstep: {__require_eng_membership},
+ Permissions.order_nextstep: {__require_eng_membership},
+ Permissions.set_nextstep: {__require_eng_membership},
+ Permissions.edit_stage: {__require_eng_membership},
+ Permissions.edit_progress_bar: {__require_eng_membership},
+ Permissions.get_progress_bar: {__require_eng_membership},
+ Permissions.change_lab_entry: {__require_eng_membership},
+ Permissions.approve_nextstep: {__require_eng_membership},
+ Permissions.deny_nextstep: {__require_eng_membership},
+ Permissions.add_checklist: {__require_eng_membership},
+ Permissions.set_checklist_decision: {__require_cl_ownership},
+ Permissions.add_checklist_audit_log: {__require_cl_ownership},
+ Permissions.delete_checklist_audit_log: {__require_cl_ownership},
+ Permissions.el_review_checklist: {__require_cl_ownership, __require_eng_membership},
+ Permissions.peer_review_checklist: {__require_peer_review_ownership},
+ Permissions.handoff_checklist: {__require_cl_ownership, __require_eng_membership},
+ Permissions.add_checklist_nextstep: {__require_cl_ownership, __require_eng_membership},
+ Permissions.edit_nextstep: {__require_eng_membership},
+ Permissions.is_el_of_eng: {__require_el_of_engagement},
+ Permissions.update_personal_next_step: {__noop},
+ Permissions.create_checklist_audit_log: {__require_eng_membership},
+ Permissions.create_checklist_decision: {__require_eng_membership},
+ Permissions.update_checklist_state: {__require_cl_ownership, __require_eng_membership},
+ Permissions.create_deployment_target_site: {__require_eng_membership},
+ Permissions.star_an_engagement: {__noop},
+ Permissions.invite: {__require_eng_membership},
+ Permissions.update_account: {__require_eng_membership},
+ Permissions.set_ssh: {__require_eng_membership},
+ Permissions.update_password: {},
+ Permissions.delete_vfc: {__require_eng_membership},
+ Permissions.get_engagement_status: {__require_eng_membership},
+ Permissions.put_engagement_status: {__require_eng_membership},
+ Permissions.eng_membership: {__noop},
+ Permissions.delete_engagement: {__require_eng_membership},
+ Permissions.view_checklist: {__require_eng_membership},
+ Permissions.pull_activities: {__require_eng_membership},
+ Permissions.get_deployment_target_site: {__noop},
+ Permissions.add_deployment_target_site: {__noop},
+ Permissions.delete_deployment_target_site: {__noop},
+ Permissions.export_engagments: {__noop},
+ Permissions.update_checklist_decision: {__noop},
+ Permissions.get_vfc: {__noop},
+ Permissions.add_vfc: {__noop},
+ Permissions.delete_notification: {__is_notification_owner},
+ Permissions.update_engagement: {__noop},
+ Permissions.remove_from_engagement_team: {__require_eng_membership},
+ }
+
+ #################################
+ # STANDARD_USER Permissions #
+ #################################
+ standard_user_permissions = {
+ Permissions.update_user: {__noop},
+ Permissions.add_vf: {__noop},
+ Permissions.add_feedback: {__noop},
+ Permissions.add_vfc: {__noop},
+ Permissions.get_vfc: {__require_eng_membership},
+ Permissions.delete_vfc: {__require_eng_membership},
+ Permissions.complete_nextstep: {__require_eng_membership},
+ Permissions.update_vf: {__require_eng_membership},
+ Permissions.reset_nextstep: {__require_eng_membership},
+ Permissions.update_personal_next_step: {__noop},
+ Permissions.update_checklist_state: {__require_cl_ownership, __require_eng_membership},
+ Permissions.create_deployment_target_site: {__require_eng_membership},
+ Permissions.star_an_engagement: {__noop},
+ Permissions.invite: {__require_eng_membership},
+ Permissions.update_account: {__require_eng_membership},
+ Permissions.set_ssh: {__require_eng_membership},
+ Permissions.update_password: {__require_eng_membership},
+ Permissions.delete_vfc: {__require_eng_membership},
+ Permissions.get_engagement_status: {__require_eng_membership},
+ Permissions.eng_membership: {__noop},
+ Permissions.pull_activities: {__require_eng_membership},
+ Permissions.export_engagments: {__noop},
+ Permissions.update_checklist_decision: {__noop},
+ Permissions.remove_from_engagement_team: {__require_eng_membership},
+ Permissions.delete_notification: {__is_notification_owner},
+ Permissions.change_lab_entry: {__require_eng_membership},
+ }
+
+ ######################
+ # ADMIN Permissions #
+ ######################
+ ######################################################
+ # TODO: We need to decide exactly what are the ADMIN
+ # TODO: permissions. Currently it matches EL +
+ # TODO: admin_approve_checklist
+ ######################################################
+ admin_permissions = dict(el_permissions) # Duplicate permissions of EL
+ admin_permissions.update( # Add Extra permissions to admin
+ {
+ Permissions.admin_approve_checklist: {__require_cl_ownership},
+ Permissions.remove_from_engagement_team: {__require_eng_membership},
+ Permissions.view_checklist_template: {__noop},
+ Permissions.edit_checklist_template: {__noop},
+ Permissions.archive_engagement: {__noop},
+ Permissions.get_el_list: {__noop},
+ Permissions.update_engagement_reviewers: {__noop},
+ Permissions.edit_nextstep: {__noop},
+ Permissions.delete_nextstep: {__noop},
+ Permissions.order_nextstep: {__noop},
+ Permissions.set_nextstep: {__noop},
+ Permissions.edit_stage: {__noop},
+ Permissions.edit_progress_bar: {__noop},
+ Permissions.get_progress_bar: {__noop},
+ Permissions.change_lab_entry: {__noop},
+ }
+ )
+
+ ######################
+ # ADMIN Read only Permissions #
+ ######################
+ admin_ro_permissions = dict()
+ admin_ro_permissions.update( # Add Extra permissions to admin_ro
+ {
+ Permissions.add_vf: {__prevent},
+ Permissions.add_feedback: {__noop},
+ Permissions.get_vfc: {__noop},
+ Permissions.get_engagement_status: {__noop},
+ Permissions.eng_membership: {__noop},
+ Permissions.pull_activities: {__noop},
+ Permissions.star_an_engagement: {__noop},
+ Permissions.export_engagments: {__noop},
+ }
+ )
+
+ def __init__(self):
+ self.role_standard_user = self.role_el = self.role_admin = self.role_admin_ro = None
+ self.__load_roles_from_db()
+
+ def check_permissions(self, user, action, eng_uuid, role, eng, cl):
+ # Retrieve the permission checks that should be performed on this user
+ # role and action
+ perm_checks = self.__get_role_checks(user, action)
+ if not perm_checks:
+ # Permission Checks were not found, it means that the action is not listed in the permitted
+ # actions for the role of the user
+ ret = False, 'Role ' + str(role.name) + ' is not permitted to ' + \
+ str(action.name) + '/ Engagement: ' + \
+ str(eng_uuid) + " isn't valid"
+ else:
+ # Start invoking permissions checks one by one.
+ for check in perm_checks:
+ ret = result, message = check(
+ self, user, action, eng=eng, cl=cl)
+ if result:
+ # Permission check succeeded
+ continue
+ else:
+ break # Permission check failed
+
+ return ret
+
+ """
+ Determines whether a user is able to perform some action.
+ """
+
+ def is_user_able_to(self, user, action, eng_uuid, checklist_uuid):
+ role = user.role
+ ret = True, 'OK'
+
+ checklist_uuid = request_data_mgr.get_cl_uuid()
+
+ # Retrieve Engagement and Checklist if their UUIDs were supplied
+ eng, cl = self.__get_objects_from_db(eng_uuid, checklist_uuid)
+ if eng and not eng_uuid:
+ eng_uuid = eng.uuid
+
+ ret = self.check_permissions(user, action, eng_uuid, role, eng, cl)
+
+ return ret
+
+ def __get_objects_from_db(self, eng_uuid, cl_uuid):
+ eng = cl = None
+
+ try:
+ if eng_uuid:
+ eng = Engagement.objects.get(uuid=eng_uuid)
+ except Engagement.DoesNotExist:
+ logger.error(
+ 'ENG was not found while checking permissions... returning 500')
+ return None, None
+
+ try:
+ if cl_uuid:
+ cl = Checklist.objects.get(uuid=cl_uuid)
+ if not eng:
+ eng = cl.engagement
+ except Checklist.DoesNotExist:
+ logger.error('CL was not found while checking permissions')
+ cl = None
+
+ return eng, cl
+
+ def __load_roles_from_db(self):
+ self.role_standard_user, created = Role.objects.get_or_create(
+ name=Roles.standard_user.name) # @UndefinedVariable
+ self.role_el, created = Role.objects.get_or_create(
+ name=Roles.el.name) # @UndefinedVariable
+ self.role_admin, created = Role.objects.get_or_create(
+ name=Roles.admin.name) # @UndefinedVariable
+ self.role_admin_ro, created = Role.objects.get_or_create(
+ name=Roles.admin_ro.name) # @UndefinedVariable
+
+ def prepare_data_for_auth(self, *args, **kwargs):
+ eng_uuid = None
+ # Extract ENG_UUID #
+ if 'eng_uuid' in kwargs:
+ eng_uuid = kwargs['eng_uuid']
+ elif 'engagement_uuid' in kwargs:
+ eng_uuid = kwargs['engagement_uuid']
+ else:
+ # Extract eng_uuid from request body
+ for arg in args:
+ if eng_uuid != None:
+ break
+ if isinstance(arg, rest_framework.request.Request):
+ try:
+ if arg.body:
+ data = json.loads(arg.body)
+ try:
+ iter(data)
+ for item in data:
+ if 'eng_uuid' in item and item['eng_uuid']:
+ eng_uuid = item['eng_uuid']
+ break
+ elif 'eng_uuid' in item and item.eng_uuid:
+ eng_uuid = item.eng_uuid
+ break
+ elif item == 'eng_uuid':
+ eng_uuid = item
+ break
+ except TypeError:
+ if 'eng_uuid' in data and data['eng_uuid']:
+ eng_uuid = data['eng_uuid']
+
+ elif 'engagement_uuid' in data and data['engagement_uuid']:
+ eng_uuid = data['engagement_uuid']
+ except Exception as e:
+ print(e)
+ pass
+
+ request_data_mgr.set_eng_uuid(eng_uuid)
+
+ # Extract CHECKLIST_UUID #
+ if 'checklistUuid' in kwargs:
+ request_data_mgr.set_cl_uuid(kwargs['checklistUuid'])
+ if (eng_uuid == None):
+ try:
+ eng_uuid = Checklist.objects.get(
+ uuid=request_data_mgr.get_cl_uuid()).engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except Checklist.DoesNotExist:
+ raise Exception("auth service couldn't fetch Checklist by checklist uuid=" +
+ request_data_mgr.get_cl_uuid())
+ except Exception as e:
+ raise Exception(
+ "Failed fetching engagement uuid from checklist " + request_data_mgr.get_cl_uuid())
+
+ # Extract engagement by NEXTSTEP_UUID #
+ if 'ns_uuid' in kwargs:
+ request_data_mgr.set_ns_uuid(kwargs['ns_uuid'])
+ if (eng_uuid == None):
+ next_step = None
+ try:
+ next_step = NextStep.objects.get(
+ uuid=request_data_mgr.get_ns_uuid())
+ except NextStep.DoesNotExist:
+ raise Exception("auth service couldn't fetch NextStep by nextstep uuid=" +
+ request_data_mgr.get_ns_uuid())
+
+ try:
+ eng_uuid = next_step.engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except:
+ # If we've gotten here it means that the next_step doesn't have attached
+ # engagement (e.g personal next_step)
+ pass
+
+ # Extract engagement by VFC
+ if ('uuid' in kwargs):
+ from engagementmanager.rest.vfc import VFCRest
+ if (isinstance(args[0], VFCRest) == True):
+ try:
+ vfc = VFC.objects.get(uuid=kwargs['uuid'])
+ if (eng_uuid == None):
+ eng_uuid = vfc.vf.engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except VFC.DoesNotExist:
+ raise Exception(
+ "auth service couldn't fetch vfc by vfc uuid=" + kwargs['uuid'])
+
+ # Extract engagement by VF (unfortunately the url exposed by the server
+ # get uuid as a parameter and serve both vf and vfc APIs) #
+ if 'vf_uuid' in kwargs and eng_uuid == None:
+ try:
+ eng_uuid = VF.objects.get(
+ uuid=kwargs['vf_uuid']).engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except VF.DoesNotExist:
+ logger.error(
+ "Prepare_data_for_auth: Couldn't fetch engagement object from VF, trying to fetch from VFC...")
+ vfc = None
+ try:
+ vfc = VFC.objects.get(uuid=kwargs['vf_uuid'])
+ if (vfc != None):
+ eng_uuid = vfc.vf.engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except VFC.DoesNotExist:
+ logger.error(
+ "Prepare_data_for_auth: Couldn't fetch engagement object from VFC")
+
+ # Extract engagement by ChecklistDecision
+ if 'decision_uuid' in kwargs and eng_uuid == None:
+ try:
+ eng_uuid = ChecklistDecision.objects.get(
+ uuid=kwargs['decision_uuid']).checklist.engagement.uuid
+ request_data_mgr.set_eng_uuid(eng_uuid)
+ except ChecklistDecision.DoesNotExist:
+ logger.error(
+ "Prepare_data_for_auth: Couldn't fetch engagement object from ChecklistDecision")
+
+ # Extract notification uuid for permission check
+ if 'notif_uuid' in kwargs:
+ request_data_mgr.set_notification_uuid(kwargs['notif_uuid'])
+
+ return eng_uuid
diff --git a/django/engagementmanager/service/base_service.py b/django/engagementmanager/service/base_service.py
new file mode 100755
index 0000000..93e48f8
--- /dev/null
+++ b/django/engagementmanager/service/base_service.py
@@ -0,0 +1,52 @@
+#
+# ============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 abc import ABCMeta
+from engagementmanager.git.git_manager import GitManager
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+
+class BaseSvc():
+ '''
+ classdocs This is the base abstract class of all ice Services delegated from the Rest layer
+ '''
+ __metaclass__ = ABCMeta
+
+ logger = LoggingServiceFactory.get_logger()
+
+ gitManager = GitManager()
diff --git a/django/engagementmanager/service/bus_service.py b/django/engagementmanager/service/bus_service.py
new file mode 100755
index 0000000..5096fbb
--- /dev/null
+++ b/django/engagementmanager/service/bus_service.py
@@ -0,0 +1,75 @@
+#
+# ============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 engagementmanager.bus.handlers.service_bus_base_handler import ServiceBusBaseHandler
+
+from engagementmanager.utils.vvp_exceptions import VvpGeneralException
+
+
+class BusService:
+ handlers_pairs = []
+
+ def __init__(self):
+ pass
+
+ def register(self, handler, message_type):
+ if not isinstance(handler, ServiceBusBaseHandler):
+ raise VvpGeneralException("You can't register handler which is not from type of ServiceBusBaseHandler")
+
+ handler_pair = self.__get_or_create_handler_pair(message_type)
+ handler_pair["handlers"].append(handler)
+
+ def send_message(self, message):
+ handler_pair = self.__get_or_create_handler_pair(type(message))
+
+ for handler in handler_pair["handlers"]:
+ handler.validate_message(message)
+ handler.handle_message(message)
+
+ def __get_or_create_handler_pair(self, message_type):
+ result = None
+ for handler_pair in self.handlers_pairs:
+ if handler_pair["type"] == message_type:
+ result = handler_pair
+ break
+
+ if result is None:
+ result = {"type": message_type, "handlers": []}
+ self.handlers_pairs.append(result)
+
+ return result
diff --git a/django/engagementmanager/service/checklist_audit_log_service.py b/django/engagementmanager/service/checklist_audit_log_service.py
new file mode 100755
index 0000000..f726950
--- /dev/null
+++ b/django/engagementmanager/service/checklist_audit_log_service.py
@@ -0,0 +1,105 @@
+#
+# ============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 engagementmanager.models import ChecklistDecision, ChecklistAuditLog, Checklist
+from engagementmanager.serializers import ThinChecklistAuditLogModelSerializer
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def addAuditLogToDecision(decision, description, user, category=''):
+ """
+ expected: decisionUuid(string), description(string), user(object), category is optional(string)
+ result: new auditlog object would be create and attached to a decision object.
+ """
+ audit = ChecklistAuditLog.objects.create(decision=decision,
+ description=description, category=category, creator=user)
+ auditData = ThinChecklistAuditLogModelSerializer(audit).data
+ return auditData
+
+
+def getAuditLogsWithDecision(decisionUuid, user):
+ """
+ expected: decisionUuid(string), user(object)
+ result: all audit logs objects that attached to a decision would be returned in a json.
+ """
+ data = dict()
+ if checklistUuid == '' or not user: # @UndefinedVariable
+ msg = "checklistUuid or user == None"
+ logger.error(msg)
+ msg = "AuditLogs were not retrieved due to bad parameters"
+ raise KeyError(msg)
+
+ decision = ChecklistDecision.objects.get(uuid=decisionUuid)
+ audits = ChecklistAuditLog.objects.filter(decision=decision)
+ data['audits'] = ThinChecklistAuditLogModelSerializer(audits, many=True).data
+ auditsData = json.dumps(data, ensure_ascii=False)
+ return auditsData
+
+
+def addAuditLogToChecklist(checklist, description, user, category=''):
+ """
+ expected: checklistUuid(string), description(string), user(object), category is optional(string)
+ result: new auditlog object would be create and attached to a checklist object.
+ """
+ audit = ChecklistAuditLog.objects.create(checklist=checklist,
+ description=description, category=category, creator=user)
+ auditData = ThinChecklistAuditLogModelSerializer(audit).data
+ logger.debug("audit log was successfully updated")
+ return auditData
+
+
+def getAuditLogsWithChecklist(checklistUuid, user):
+ """
+ expected: checklistUuid(string), user(object)
+ result: all audit logs objects that attached to a checklist would be returned in a json.
+ """
+ data = dict()
+ if checklistUuid == '' or not user: # @UndefinedVariable
+ msg = "checklistUuid or user == None"
+ logger.error(msg)
+ msg = "AuditLogs were not retrieved due to bad parameters"
+ raise KeyError(msg)
+
+ checklist = Checklist.objects.get(uuid=checklistUuid)
+ audits = ChecklistAuditLog.objects.filter(checklist=checklist)
+ data['audits'] = ThinChecklistAuditLogModelSerializer(audits, many=True).data
+ auditsData = json.dumps(data, ensure_ascii=False)
+ return auditsData
diff --git a/django/engagementmanager/service/checklist_decision_service.py b/django/engagementmanager/service/checklist_decision_service.py
new file mode 100755
index 0000000..e94c059
--- /dev/null
+++ b/django/engagementmanager/service/checklist_decision_service.py
@@ -0,0 +1,122 @@
+#
+# ============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 PermissionDenied
+from rest_framework.exceptions import MethodNotAllowed
+from engagementmanager.models import ChecklistDecision
+from engagementmanager.serializers import ThinChecklistDecisionModelSerializer
+from engagementmanager.utils.constants import CheckListState, \
+ CheckListDecisionValue, Roles
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def setDecision(decisionUuid, user, value):
+ logger.debug("attempting setDecision(user=%r, value=%r)...", user, value)
+
+ if not decisionUuid or not user or value not in CheckListDecisionValue.__members__:
+ msg = "decisionUuid or value are empty or invalid / user == None"
+ logger.error(msg)
+ msg = "decision wasn't change due to bad parameters"
+ raise KeyError(msg)
+
+ decision = ChecklistDecision.objects.get(uuid=decisionUuid)
+ checklist = decision.checklist
+
+ # @UndefinedVariable
+ if (checklist.owner.email == user.email and user.role.name == Roles.el.name) or (user.role.name == Roles.admin.name):
+ if checklist.state == CheckListState.review.name: # @UndefinedVariable
+ if decision.review_value != value:
+ decision.review_value = value
+ decision.save()
+ msg = "review_value was successfully changed for decision: " + decision.uuid + " , value: " + value
+ else:
+ msg = "review_value was already the same: " + decision.uuid + " , value: " + value
+ logger.debug(msg)
+ elif checklist.state == CheckListState.peer_review.name: # @UndefinedVariable
+ if decision.peer_review_value != value:
+ decision.peer_review_value = value
+ decision.save()
+ msg = "peer_review_value was successfully changed for decision: " + decision.uuid + " , value: " + value
+ else:
+ msg = "review_value was already the same: " + decision.uuid + " , value: " + value
+ logger.debug(msg)
+ elif checklist.state == CheckListState.automation.name: # @UndefinedVariable
+ if decision.review_value != value:
+ decision.peer_review_value = value
+ decision.save()
+ msg = "peer_review_value was successfully changed for decision: " + decision.uuid + " , value: " + value
+ else:
+ msg = "review_value was already the same: " + decision.uuid + " , value: " + value
+
+ if decision.review_value != value:
+ decision.review_value = value
+ decision.save()
+ msg = "review_value was successfully changed for decision: " + decision.uuid + " , value: " + value
+ else:
+ msg = "review_value was already the same: " + decision.uuid + " , value: " + value
+ logger.debug(msg)
+ else:
+ msg = "checklist's state is an invalid state for the decision change and should be different"
+ logger.error(msg)
+ msg = "decision wasn't change, Checklist's state is not allowed to change the decision"
+ raise MethodNotAllowed(msg)
+ return msg
+ else:
+ msg = "user isn't an EL / The User (" + user.full_name + \
+ ") tried to change the decision while the current owner is " + checklist.owner.full_name
+ logger.error(logEncoding(msg))
+ msg = "Action is forbidden"
+ raise PermissionDenied(msg)
+
+
+def getDecision(decisionUuid, user):
+ data = dict()
+ if decisionUuid == '' or (not user and user.role.name == Roles.el.name): # @UndefinedVariable
+ msg = "decisionUuid or (user == None / user.role != EL)"
+ logger.error(msg)
+ msg = "decision wasn't retrieved due to bad parameters / you are not authorized"
+ raise KeyError(msg)
+
+ decision = ChecklistDecision.objects.get(uuid=decisionUuid)
+ data['decision'] = ThinChecklistDecisionModelSerializer(decision, many=False).data
+ decisionData = json.dumps(data, ensure_ascii=False)
+ return decisionData
diff --git a/django/engagementmanager/service/checklist_service.py b/django/engagementmanager/service/checklist_service.py
new file mode 100755
index 0000000..0df7edd
--- /dev/null
+++ b/django/engagementmanager/service/checklist_service.py
@@ -0,0 +1,509 @@
+#
+# ============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.core.exceptions import ObjectDoesNotExist
+from django.db.models import Q
+from django.db.models.aggregates import Max
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.activity_event_message import \
+ ActivityEventMessage
+from engagementmanager.git.git_manager import GitManager
+from engagementmanager.models import ChecklistTemplate, Checklist, Engagement, \
+ ChecklistAuditLog, ChecklistDecision, ChecklistLineItem, IceUserProfile, VF, \
+ ChecklistSection, Role
+from engagementmanager.serializers import ThinChecklistModelSerializer, \
+ ThinChecklistAuditLogModelSerializer, ThinChecklistDecisionModelSerializer, \
+ ThinPostChecklistResponseModelSerializer, ChecklistTemplateModelSerializer, \
+ ChecklistSectionModelSerializer, ChecklistLineItemModelSerializer
+from engagementmanager.service.checklist_audit_log_service import \
+ addAuditLogToDecision, addAuditLogToChecklist
+from engagementmanager.service.checklist_decision_service import setDecision
+from engagementmanager.service.checklist_state_service import set_state
+from engagementmanager.service.base_service import BaseSvc
+from engagementmanager.utils.constants import Roles, CheckListState, \
+ CheckListLineType
+from engagementmanager.utils.activities_data import TestFinishedActivityData
+from engagementmanager.utils.vvp_exceptions import VvpObjectNotAvailable
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.vm_integration.vm_client import \
+ send_jenkins_job_and_gitlab_repo_exists, executor
+from validationmanager.em_integration.vm_api import get_jenkins_build_log
+import json
+import time
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class CheckListSvc(BaseSvc):
+ def retreive_cl_files_for_engagment(self, eng_uuid):
+ vf_associated_files_list = []
+
+ checklists_of_eng = Checklist.objects.filter(engagement__uuid=eng_uuid).exclude(
+ state=CheckListState.archive.name).exclude(state=CheckListState.closed.name) # @UndefinedVariable
+
+ for checklistObj in checklists_of_eng:
+ associated_files = json.loads(checklistObj.associated_files)
+ vf_associated_files_list = vf_associated_files_list + associated_files
+ return vf_associated_files_list
+
+ def getDataForCreateNewChecklist(self, user, eng_uuid):
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ vf = engagement.vf
+
+ if not send_jenkins_job_and_gitlab_repo_exists(vf):
+ msg = "Jenkins job or gitlab repo is still missing"
+ logger.error(msg)
+ return False
+
+ # Get all templates
+ data = self.getChecklistTemplates()
+
+ data['checkListAssociatedFiles'] = self.gitManager.getRepoAssociatedFilesForUser(
+ eng_uuid)
+ return data
+
+ def getChecklistTemplates(self, templateUuid=None):
+ """Return checklist template with nested sections and their nested line items"""
+ data = dict()
+ if not templateUuid:
+ checkListTemplates = ChecklistTemplate.objects.all()
+ if (checkListTemplates):
+ data['checkListTemplates'] = ChecklistTemplateModelSerializer(
+ checkListTemplates, many=True).data
+ return data
+ cl_template = ChecklistTemplate.objects.get(uuid=templateUuid)
+ if (cl_template != None):
+ data = ChecklistTemplateModelSerializer(
+ cl_template, many=False).data
+ sections = ChecklistSection.objects.filter(template=cl_template)
+ if (sections != None):
+ section_list = []
+ for sec in sections:
+ section_data = dict()
+ section_data = ChecklistSectionModelSerializer(
+ sec, many=False).data
+
+ lineItems = ChecklistLineItem.objects.filter(section=sec)
+ section_data['lineItems'] = ChecklistLineItemModelSerializer(
+ lineItems, many=True).data
+ section_list.append(section_data)
+
+ data['sections'] = section_list
+
+ return data
+
+ def createNewSection(self, section, templateObj):
+ """Create new section for a given template """
+ logger.debug(
+ "Creating a new section. Section name = " + section['name'])
+
+ weight = int(ChecklistSection.objects.filter(template=templateObj).aggregate(
+ max_weight=Max('weight'))['max_weight'] or 0) + 1
+
+ newSection = ChecklistSection.objects.create(
+ name=section.get('name', None),
+ description=section.get('description', None),
+ validation_instructions=section.get(
+ 'validation_instructions', None),
+ template=templateObj,
+ weight=weight)
+
+ return newSection
+
+ def createNewLineItemForSection(self, newSectionObj, listItem, templateObj):
+ """Create new line item for a given section and template """
+
+ weight = int(ChecklistLineItem.objects.filter(section=newSectionObj).aggregate(
+ max_weight=Max('weight'))['max_weight'] or 0) + 1
+
+ ChecklistLineItem.objects.create(
+ name=listItem['name'],
+ description=listItem.get('description', None),
+ # @UndefinedVariable
+ line_type=listItem.get('line_type', CheckListLineType.auto.name),
+ validation_instructions=listItem.get(
+ 'validation_instructions', None),
+ section=newSectionObj,
+ template=templateObj,
+ weight=weight)
+
+ def delete(self, dict_structure, query_set, entity, isDirty):
+ """Generically find the xor result of the user input and the db data. Assumption: If entities exits in DB but not in user input they'll be deleted"""
+ uuid_client = [dict['uuid'] for dict in dict_structure]
+ uuid_db = [record.uuid for record in query_set]
+ uuids_to_delete = set(uuid_db) - set(uuid_client)
+ for u_uid in uuids_to_delete:
+ entity.objects.filter(uuid=u_uid).delete()
+ # Note: No need to delete ChecklistLineItem corresponding to this section
+ # since there is a CASCADE operation on delete section
+ isDirty[0] = True
+
+ def editIfChanged(self, entity, uidict, fieldList):
+ """Generic function to check that set of fields are modified on a certain entity"""
+ isChanged = False
+ for field in fieldList:
+ if (field in uidict):
+ if (isChanged != True and entity.__dict__[field] == uidict[field]):
+ isChanged = False
+ else:
+ entity.__dict__[field] = uidict[field]
+ isChanged = True
+ return isChanged
+
+ def updateTemplateFields(self, clTemplate, checklistTemplate, isDirty):
+ if (self.editIfChanged(clTemplate, checklistTemplate, ['name'])):
+ clTemplate.save()
+ isDirty[0] = True
+
+ def updateSectionFields(self, section, sec, isDirty):
+ if (self.editIfChanged(section, sec, ['name'])):
+ section.save()
+ isDirty[0] = True
+
+ def updateLineItemFields(self, lineitem, li, isDirty):
+ if (self.editIfChanged(lineitem, li, ['name', 'description', 'validation_instructions', 'line_type'])):
+ lineitem.save()
+ isDirty[0] = True
+
+ def editChecklistTemplate(self, checklistTemplate):
+ """edit the template+section+line-item of user input"""
+ NEW_ENTITY = "newEntity" # this is an indication on top of the provided json to create the entity
+ templateObj = None
+ isDirty = [False]
+ if ('uuid' in checklistTemplate):
+ templateUuid = checklistTemplate['uuid']
+ templateObj = ChecklistTemplate.objects.get(uuid=templateUuid)
+ self.updateTemplateFields(templateObj, checklistTemplate, isDirty)
+ # SECTIONS
+ if ('sections' in checklistTemplate):
+ sections = checklistTemplate['sections']
+ query_set = templateObj.checklistsection_set.all()
+ self.delete(sections, query_set, ChecklistSection, isDirty)
+ sectionObj = None
+ for sec in sections:
+ if (sec['uuid'] == NEW_ENTITY):
+ sectionObj = self.createNewSection(sec, templateObj)
+ isDirty[0] = True
+ else: # section was only updated
+ sectionObj = ChecklistSection.objects.get(
+ uuid=sec['uuid'])
+ self.updateSectionFields(sectionObj, sec, isDirty)
+ # LINE-ITEMS
+ if ('lineItems' in sec):
+ lineItems = sec['lineItems']
+ query_set = sectionObj.checklistlineitem_set.all()
+ self.delete(lineItems, query_set,
+ ChecklistLineItem, isDirty)
+ for li in lineItems:
+ if (li['uuid'] == NEW_ENTITY):
+ self.createNewLineItemForSection(
+ sectionObj, li, templateObj)
+ isDirty[0] = True
+ else: # line-item was only updated
+ lineitem = ChecklistLineItem.objects.get(
+ uuid=li['uuid'])
+ self.updateLineItemFields(lineitem, li, isDirty)
+
+ executor.submit(self.decline_all_template_checklists,
+ isDirty[0], templateObj, request_data_mgr.get_user())
+
+ def decline_all_template_checklists(self, isDirty, templateObj, user):
+ request_data_mgr.set_user(user)
+ checklists = None
+
+ start = time.clock()
+ try:
+ if (isDirty == True):
+ states_to_exclude = [CheckListState.archive.name, CheckListState.closed.name,
+ CheckListState.pending.name] # @UndefinedVariable
+ checklists = Checklist.objects.filter(
+ template=templateObj).exclude(state__in=states_to_exclude)
+ logger.debug("Number of checklists=" +
+ str(len(checklists)))
+ for checklist in checklists:
+ request_data_mgr.set_cl_uuid(checklist.uuid)
+ request_data_mgr.set_eng_uuid(checklist.engagement.uuid)
+ set_state(
+ True, # means that the checklist will be declined and a cloned one is created in PENDING status
+ checklist.uuid,
+ isMoveToAutomation=True,
+ description="""Checklist {name} was rejected since its template ({template}) was edited/deleted""".format(
+ name=checklist.name, template=templateObj.name), # means the checklist will be triggered into automation cycle
+ )
+ except Exception as e:
+ msg = """Something went wrong while trying to reject check-lists which its template was changed. template={template}. Error:""".format(
+ template=templateObj.name)
+ logger.error(msg + " " + str(e))
+ raise e # Don't remove try-except, it supports async invocation
+ end = time.clock()
+ logger.debug("TIME:" + str(end - start))
+
+ def getChecklist(self, user, checklistUuid):
+
+ data = dict()
+ checklist = None
+
+ if user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name: # @UndefinedVariable
+ checklist = Checklist.objects.get(uuid=checklistUuid)
+ else:
+ checklist = Checklist.objects.get(
+ Q(uuid=checklistUuid), Q(creator=user) | Q(owner=user))
+
+ # CheckList
+ if checklist.state == CheckListState.archive.name: # @UndefinedVariable
+ msg = "got a request for a checklist which is an archived one, might have been due to an admin edit of a checklist template."
+ logger.error(msg)
+ msg = "Requested checklist is archived, reloading checklists list"
+ raise VvpObjectNotAvailable(msg)
+ data['checklist'] = ThinChecklistModelSerializer(
+ checklist, many=False).data
+ vf = VF.objects.get(engagement=checklist.engagement)
+ data['checklist']['associated_files'] = json.loads(
+ data['checklist']['associated_files'])
+ data['checklist']['jenkins_log'] = get_jenkins_build_log(
+ vf, checklistUuid)
+ data['checklist']['repo_associated_files'] = GitManager(
+ ).getRepoAssociatedFilesForUser(checklist.engagement.uuid)
+ # CheckList Audit Logs
+ # here all fetched records should have decision==null
+ checklistAuditLogs = ChecklistAuditLog.objects.filter(
+ checklist__uuid=checklistUuid)
+ serializedAuditLogsData = ThinChecklistAuditLogModelSerializer(
+ checklistAuditLogs, many=True).data
+ data['checklistAuditLogs'] = serializedAuditLogsData
+
+ # CheckList Decisions + LineItems + Sections (The data is nested thanks
+ # to the serializer)
+ checklistDecisions = ChecklistDecision.objects.filter(
+ checklist__uuid=checklistUuid)
+ serializedDecisionsData = ThinChecklistDecisionModelSerializer(
+ checklistDecisions, many=True).data
+ checklistLineItems = {}
+ for checklistDecision in serializedDecisionsData:
+ section_uuid = checklistDecision['lineitem']['section']['uuid']
+ section_weight = checklistDecision['lineitem']['section']['weight']
+ section_key = str(section_weight) + "_" + section_uuid
+ if section_key not in checklistLineItems:
+ checklistLineItems[section_key] = {}
+ checklistLineItems[section_key]['section'] = checklistDecision['lineitem']['section']
+ checklistLineItems[section_key]['decisions'] = {}
+ checklistLineItems[section_key]['weight'] = section_weight
+
+ decision_uuid = checklistDecision['uuid']
+ line_item_weight = checklistDecision['lineitem']['weight']
+ decision_key = str(line_item_weight) + "_" + decision_uuid
+ checklistLineItems[section_key]['decisions'][decision_key] = checklistDecision
+ checklistLineItems[section_key]['decisions'][decision_key]['weight'] = line_item_weight
+
+ data['checklistDecisions'] = checklistLineItems
+
+ # Decision Audit Logs
+ data['decisionAuditLogs'] = {}
+ for checklistDecision in checklistDecisions:
+ # here all fetched records should have checklist==null
+ decisionAuditLogs = ChecklistAuditLog.objects.filter(
+ decision=checklistDecision)
+ if decisionAuditLogs.count() > 0:
+ serializedAuditLogsData = ThinChecklistAuditLogModelSerializer(
+ decisionAuditLogs, many=True).data
+ data['decisionAuditLogs'][checklistDecision.uuid] = serializedAuditLogsData
+
+ logger.debug("get existing checklist has succeeded for checklist.uuid=" + str(checklist.uuid) +
+ ", user.uuid=" + str(user.uuid) + ", checklist.uuid=" + str(checklistUuid))
+
+ return data
+
+ def getEngagementFiles(self, eng_uuid):
+ repo_files = self.gitManager.getRepoAssociatedFilesForUser(eng_uuid)
+ return repo_files
+
+ def createOrUpdateChecklist(self, checkListName, checkListTemplateUuid, checkListAssociatedFiles, checklistUuid=None):
+ template = None
+ checklist = None
+ user = request_data_mgr.get_user()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+
+ vf = VF.objects.get(engagement__uuid=eng_uuid)
+
+ if not send_jenkins_job_and_gitlab_repo_exists(vf):
+ msg = "Jenkins job or gitlab repo is still missing"
+ logger.error(msg)
+ msg = "Create or update checklist is not ready yet"
+ raise Exception(msg)
+
+ # associated_files may be delivered in this format
+ # [{"File": "bar"}, {"File": "baz"}, {"File": "foo"}, {"File": "quux"}]
+ # but we want to store it in this format
+ # ["bar", "baz", "foo", "quux"]
+
+ repo_files = self.gitManager.getRepoAssociatedFilesForUser(eng_uuid)
+# checklist_files_list = [f['File'] if isinstance(f, dict) else f for f in checkListAssociatedFiles]
+ checklist_files_list = []
+ for file in checkListAssociatedFiles:
+ if isinstance(file, dict):
+ checklist_files_list.append(file['File'])
+ else:
+ checklist_files_list.append(file)
+ for added_name in checklist_files_list:
+ if added_name not in repo_files:
+ logger.error("Update checklist has failed. " +
+ added_name + " doesnt exist in repo")
+ msg = "Failed to create checklist, please select valid file"
+ raise ValueError(msg)
+
+ associated_files = json.dumps(checklist_files_list, ensure_ascii=False)
+
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ template = ChecklistTemplate.objects.get(uuid=checkListTemplateUuid)
+
+ if (checklistUuid != None): # Update Checklist
+ checklist = Checklist.objects.get(uuid=checklistUuid)
+ checklist.name = checkListName
+ checklist.associated_files = associated_files
+ checklist.template = template
+ checklist.save()
+
+ if (associated_files != None and len(checklist_files_list) > 0):
+ set_state(
+ decline=True,
+ description="Checklist: " + checklist.name +
+ "in Pending state will transition to Automation because it has associated files",
+ isMoveToAutomation=True, # means the checklist will be triggered into automation cycle
+ checklist_uuid=checklist.uuid
+ )
+ else: # create ChcekList
+ if (user.role.name == Roles.admin.name): # @UndefinedVariable
+ incharge_personal = engagement.reviewer
+ else:
+ incharge_personal = user
+ vf = None
+ vf = VF.objects.get(engagement=engagement)
+
+ if (vf.git_repo_url == None):
+ msg = "Can't create checklist since the attached VF (" + \
+ vf.name + ") doesn't contain git_repo_url"
+ logger.error(
+ "Update checklist has failed. " + logEncoding(msg))
+ raise ObjectDoesNotExist(msg)
+
+ checklist = Checklist(name=checkListName, validation_cycle=1, associated_files=associated_files,
+ state=CheckListState.pending.name, engagement=engagement, template=template, creator=user, owner=incharge_personal) # @UndefinedVariable
+ line_items_list = ChecklistLineItem.objects.filter(
+ template=template)
+ checklist.save()
+ for lineitem in line_items_list:
+ new_decision = ChecklistDecision(checklist=checklist,
+ template=template, lineitem=lineitem)
+ new_decision.save()
+
+ # When Checklist is created with files move it it automation
+ if (associated_files != None and len(checklist_files_list) > 0):
+ set_state(
+ decline=False,
+ checklist_uuid=checklist.uuid,
+ description="Checklist: " + checklist.name +
+ "in Pending state will transition to Automation because it has associated files",
+ isMoveToAutomation=True # means the checklist will be triggered into automation cycle
+ )
+
+ logger.debug(
+ "Create/Update checklist has succeeded for checklist.uuid=" + str(checklist.uuid))
+
+ return ThinPostChecklistResponseModelSerializer(checklist).data
+
+ def deleteChecklist(self, checklist_uuid):
+ checklist = Checklist.objects.get(uuid=checklist_uuid)
+ checklist.delete()
+
+ logger.debug(
+ "Delete checklist has succeeded for checklist.uuid=" + str(checklist_uuid))
+
+ def setChecklistDecisionsFromValMgr(self, user, checklist_uuid, decisions, checklist_results_from_jenkins):
+ checklist = Checklist.objects.get(uuid=checklist_uuid, owner=user,
+ state=CheckListState.automation.name) # @UndefinedVariable
+
+ logger.debug("setChecklistDecisionsFromValMgr() checklist_uuid=%r, len(decisions)=%d",
+ checklist_uuid, len(decisions),)
+
+ if ('error' in checklist_results_from_jenkins):
+ el_role = Role.objects.get(name=Roles.el.name)
+ admin_role = Role.objects.get(name=Roles.admin.name)
+ el_admin_list = IceUserProfile.objects.all().filter(
+ Q(role=el_role) | Q(role=admin_role))
+
+ activity_data = TestFinishedActivityData(
+ el_admin_list, checklist.engagement, checklist_results_from_jenkins['error'])
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ msg = "test_finished signal from Jenkins has arrived with error: {}".format(
+ checklist_results_from_jenkins['error'])
+ logger.error(msg)
+ set_state(True, checklist_uuid, isMoveToAutomation=False,
+ description=checklist_results_from_jenkins['error'])
+ raise Exception(msg)
+
+ ChecklistLineItem.objects.filter(template=checklist.template).update(
+ line_type=CheckListLineType.manual.name) # @UndefinedVariable
+
+ for decision in decisions:
+ lineitem_obj = ChecklistLineItem.objects.get(
+ uuid=decision['line_item_id'])
+ lineitem_obj.line_type = CheckListLineType.auto.name # @UndefinedVariable
+ lineitem_obj.save()
+
+ decision_obj = ChecklistDecision.objects.get(
+ checklist=checklist, lineitem=lineitem_obj)
+ setDecision(decisionUuid=decision_obj.uuid,
+ user=user, value=decision['value'])
+
+ if (decision['audit_log_text'] != '' and decision['audit_log_text'] != None):
+ addAuditLogToDecision(decision=decision_obj,
+ description=decision['audit_log_text'], user=user, category='')
+
+ desc = "The {} validation test suite has completed. The decisions " +\
+ "based on the test results have successfully been set in the " +\
+ "checklist.".format(checklist.template.category)
+ addAuditLogToChecklist(checklist=checklist, description=desc,
+ user=user, category='')
+ checklistData = ThinChecklistModelSerializer(checklist, many=False).data
+ set_state(False, checklist.uuid,
+ isMoveToAutomation=True, description="")
+
+ return checklistData
diff --git a/django/engagementmanager/service/checklist_state_service.py b/django/engagementmanager/service/checklist_state_service.py
new file mode 100755
index 0000000..1903c47
--- /dev/null
+++ b/django/engagementmanager/service/checklist_state_service.py
@@ -0,0 +1,434 @@
+#
+# ============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.db.models import Q
+from django.utils import timezone
+from engagementmanager.decorator.auth import auth
+from engagementmanager.slack_client.api import SlackClient
+from engagementmanager.models import ChecklistDecision, Checklist, \
+ IceUserProfile, VF, ChecklistLineItem, ChecklistAuditLog, Role
+from engagementmanager.service.authorization_service import Permissions
+from engagementmanager.service.checklist_audit_log_service import \
+ addAuditLogToChecklist
+from engagementmanager.service.engagement_service import \
+ update_or_insert_to_recent_engagements, update_eng_validation_details
+from engagementmanager.utils.constants import CheckListState, \
+ CheckListDecisionValue, Roles, RecentEngagementActionType
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.vm_integration.vm_client import \
+ send_cl_from_pending_to_automation_event
+from rest_framework.exceptions import MethodNotAllowed
+import random
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def insert_to_recent_engagements(owner=None, action=None, vf=None):
+ if vf == None:
+ # If VF wasn't supplied let's fetch it using checklist and
+ # checklist.engagement
+ checkListObj = Checklist.objects.get(
+ uuid=request_data_mgr.get_cl_uuid())
+ vf = VF.objects.get(engagement=checkListObj.engagement)
+
+ logger.debug("Adding vf " + str(vf.uuid) +
+ " to recent engagements table for user " + owner.full_name)
+ update_or_insert_to_recent_engagements(
+ owner.uuid, vf, action) # @UndefinedVariable
+
+
+def description_creator(checklist, next_state, additional_comment=""):
+ if additional_comment:
+ description = "The " + checklist.name + " checklist was changed to the " +\
+ next_state.lower() + " state. " + "\n" +\
+ additional_comment
+ else:
+ description = "The " + checklist.name + " checklist was changed to the " +\
+ next_state.lower() + " state."
+ return description
+
+
+'''
+ If kwargs['isMoveToAutomation']==True than the CL will not be cloned but reverted to automation, else (False) will be cloned and returned in pending
+'''
+
+
+def set_state(decline, checklist_uuid, isMoveToAutomation=True, description=None):
+ logger.debug('set_state(decline=%r,checklist_uuid=%r,get_request_data_vars= %r)',
+ decline, checklist_uuid, request_data_mgr.get_request_data_vars())
+
+ if checklist_uuid != None: # was sent explicitly
+ request_data_mgr.set_cl_uuid(checklist_uuid)
+
+ if any(x is None for x in [checklist_uuid, request_data_mgr.get_user(), description]):
+ msg = "checklist uuid or user or description is None"
+ logger.error(msg)
+ msg = "checklist state wasn't change due to bad parameters"
+ raise KeyError(msg)
+
+ additional_comment = description
+
+ checklist = retrieve_checklist_object(checklist_uuid)
+
+ # get metadata for slack notifications
+ slack_client = SlackClient()
+ checklist_name = checklist.name
+ engagement = checklist.engagement
+ reviewer = engagement.reviewer
+ peer_reviewer = engagement.peer_reviewer
+ engagement_manual_id = ''
+ if engagement is not None:
+ engagement_manual_id = engagement.engagement_manual_id
+
+ vf = VF.objects.get(engagement__uuid=engagement.uuid)
+ vf_name = ""
+ if vf is not None:
+ vf_name = vf.name
+
+ if not checklist:
+ msg = "checklist state wasn't change due to bad parameters"
+ raise KeyError(msg)
+
+ # @UndefinedVariable
+ if checklist.state == CheckListState.closed.name or checklist.state == CheckListState.archive.name:
+ msg = "attempt to change state to the next one from 'closed'/'archive', no actions were made."
+ logger.error(msg)
+ msg = "checklist's state is already closed/archive, can not move forward in states."
+ raise FileExistsError(msg)
+
+ elif decline and checklist.state != CheckListState.pending.name: # @UndefinedVariable
+ logger.debug(
+ 'set_state: decline and not pending -< about to set the state to ARCHIVE and duplicate the checklist')
+ set_state_to_archive(isMoveToAutomation, description)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.archive.name, additional_comment)
+
+ elif checklist.state == CheckListState.pending.name: # @UndefinedVariable
+ logger.debug('set_state: pending to automation')
+ set_state_to_automation()
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.automation.name, additional_comment)
+
+ # this case is when getting a signal from VM that jenkins has finished all
+ # tests
+ elif checklist.state == CheckListState.automation.name: # @UndefinedVariable
+ logger.debug('set_state: automation to review')
+ set_state_to_review(checklist)
+ slack_client.send_notification_to_reviewer_when_automation_completes(
+ engagement_manual_id, vf_name, reviewer, checklist_name)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.review.name, additional_comment)
+
+ elif checklist.state == CheckListState.review.name: # @UndefinedVariable
+ logger.debug('set_state: review to peer review')
+ set_state_to_peer_review()
+ slack_client.send_notification_to_peer_reviewer_when_the_review_completes(
+ engagement_manual_id, vf_name, reviewer, peer_reviewer, checklist_name)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.peer_review.name, additional_comment)
+
+ elif checklist.state == CheckListState.peer_review.name: # @UndefinedVariable
+ logger.debug('set_state: peer review to approval')
+ set_state_to_approval()
+ admins = IceUserProfile.objects.filter(role__name=Roles.admin.name)
+ slack_client.send_notification_to_admins_when_the_peer_review_completes(
+ engagement_manual_id, vf_name, reviewer, peer_reviewer, admins, checklist_name)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.approval.name, additional_comment)
+
+ elif checklist.state == CheckListState.approval.name: # @UndefinedVariable
+ logger.debug('set_state: approval to handoff')
+ set_state_to_handoff()
+ slack_client.send_notification_to_reviewer_when_approved(
+ engagement_manual_id, vf_name, reviewer, checklist_name)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.handoff.name, additional_comment)
+
+ elif checklist.state == CheckListState.handoff.name: # @UndefinedVariable
+ logger.debug('set_state: handoff to closed')
+ set_state_to_closed()
+ admins = IceUserProfile.objects.filter(role__name=Roles.admin.name)
+ slack_client.send_notifications_when_closed(
+ engagement_manual_id, vf_name, reviewer, peer_reviewer, admins, checklist_name)
+
+ # @UndefinedVariable
+ return check_sts(checklist, request_data_mgr.get_user(), CheckListState.closed.name, additional_comment)
+
+
+def duplicate_checklist_and_its_auditlogs(checklist, isMoveToAutomation):
+ ''' Create the basic duplicated checklist object based on the original one '''
+
+ newState = CheckListState.pending.name # @UndefinedVariable
+ checklistDupObject = Checklist.objects.create(
+ name=checklist.name,
+ validation_cycle=checklist.validation_cycle + 1,
+ associated_files=checklist.associated_files,
+ engagement=checklist.engagement,
+ template=checklist.template,
+ creator=checklist.creator,
+ owner=checklist.creator,
+ state=newState)
+
+ ''' Fetch all original cl audit logs and attach it to the duplicated one '''
+ audits = ChecklistAuditLog.objects.filter(checklist=checklist)
+ for item in audits:
+ audit = addAuditLogToChecklist(
+ checklistDupObject, item.description, item.creator)
+
+ if not audit:
+ logger.error(
+ "duplicate_checklist_and_its_auditlogs: Failed to create a duplicated audit log in the DB")
+ msg = "checklist state wasn't change"
+ raise Exception(msg)
+
+ ''' Fetch all original line items and attach it to the duplicated one '''
+ line_items_list = ChecklistLineItem.objects.filter(
+ template=checklist.template)
+ # Implementation is based on space and performance aspect and not particularly one of them
+ #(could have just change the internal object's cl field to the new object and reset their values)
+ for lineitem in line_items_list:
+ old_decisions = ChecklistDecision.objects.filter(
+ lineitem=lineitem, checklist=checklist, template=checklist.template)
+ if len(old_decisions) == 0:
+ new_decision = ChecklistDecision.objects.create(
+ checklist=checklistDupObject, template=checklistDupObject.template, lineitem=lineitem)
+ else:
+ for decision in old_decisions:
+ new_decision = ChecklistDecision.objects.create(
+ checklist=checklistDupObject, template=checklist.template, lineitem=lineitem)
+ old_decision_auditlogs = ChecklistAuditLog.objects.filter(
+ decision=decision)
+ for audit in old_decision_auditlogs:
+ audit = ChecklistAuditLog.objects.create(
+ decision=new_decision, description=audit.description, category='', creator=audit.creator)
+
+ if isMoveToAutomation == True: # This is a scenario in which we send to VM cl_from_pending_to_automation_event
+ logger.debug("Cloned Checklist is triggered as to automation")
+ try:
+ set_state_to_automation(checklistDupObject)
+ except KeyError:
+ # delete new checklist since we don't want duplicate checklist while
+ # the other one is still not archived
+ checklistDupObject.delete()
+
+ return checklistDupObject
+
+
+def check_sts(checklist, user, next_state, additional_comment):
+ description = description_creator(
+ checklist, next_state, additional_comment=additional_comment) # @UndefinedVariable
+ if not description:
+ msg = "failed to set the state to the next one due to invalid parameters."
+ raise ValueError(msg)
+ addAuditLogToChecklist(checklist, description, user)
+ return checklist
+
+
+def check_decision_meet_criterias(checkListObj, review_type):
+ if not type:
+ return True
+
+ if review_type == 'review_value':
+ invalid_decisions = ChecklistDecision.objects.filter(Q(checklist=checkListObj) &
+ (
+ Q(review_value=CheckListDecisionValue.na.name)
+ | Q(review_value=CheckListDecisionValue.denied.name)
+ )).count() # @UndefinedVariable
+ elif review_type == 'peer_review_value':
+ invalid_decisions = ChecklistDecision.objects.filter(Q(checklist=checkListObj) &
+ (
+ Q(peer_review_value=CheckListDecisionValue.na.name) |
+ Q(peer_review_value=CheckListDecisionValue.denied.name)
+ )).count() # @UndefinedVariable
+ else:
+ return True
+
+ if invalid_decisions:
+ msg = "checklist state wasn't change, not all decisions are approved / na"
+ raise MethodNotAllowed(msg)
+
+
+def retrieve_checklist_and_its_decisions(cluuid, review_type):
+ checkListObj = retrieve_checklist_object(cluuid)
+ if not checkListObj:
+ msg = "checklist state wasn't change"
+ raise KeyError(msg)
+ check_decision_meet_criterias(checkListObj, review_type)
+ return checkListObj
+
+
+def retrieve_checklist_object(cluuid):
+ checklist = Checklist.objects.get(uuid=cluuid)
+ return checklist
+
+
+"""
+This method is called when an EL / Peer Reviewer declines a CL or creates a Next step for them after declining a specific line item in the CL.
+"""
+
+
+@auth(Permissions.set_checklist_decision, is_internal=True)
+def set_state_to_archive(isMoveToAutomation=True, description=None):
+ checkListObj = retrieve_checklist_and_its_decisions(
+ request_data_mgr.get_cl_uuid(), '') # @UndefinedVariable
+
+ rejection_description = description_creator(
+ checkListObj, CheckListState.archive.name, description) # @UndefinedVariable
+ addAuditLogToChecklist(
+ checkListObj, rejection_description, request_data_mgr.get_user())
+ checklistDupObject = duplicate_checklist_and_its_auditlogs(
+ checkListObj, isMoveToAutomation)
+ checkListObj.state = CheckListState.archive.name # @UndefinedVariable
+ checkListObj.owner = checkListObj.creator
+ checkListObj.update_time = timezone.now()
+
+ checkListObj.save()
+
+ return checklistDupObject
+
+
+def set_state_to_automation(checkListObj=None):
+ if checkListObj is None:
+ checkListObj = retrieve_checklist_object(request_data_mgr.get_cl_uuid())
+
+ if checkListObj.associated_files == [] or not checkListObj.associated_files:
+ logger.error(
+ "set_state_to_automation failed: no files were found in the checkListObj.associated_file")
+ msg = "checklist state wasn't change, please add files to the checklist in order to start Automation state"
+ raise KeyError(msg)
+ originalState = checkListObj.state
+ checkListObj.state = CheckListState.automation.name # @UndefinedVariable
+ checkListObj.update_time = timezone.now()
+
+ checkListObj.save()
+
+ if originalState == CheckListState.pending.name: # @UndefinedVariable
+ send_cl_from_pending_to_automation_event(checkListObj)
+
+
+def set_state_to_review(checkListObj):
+ checkListObj.state = CheckListState.review.name # @UndefinedVariable
+ checkListObj.update_time = timezone.now()
+ # set the owner to reviewer and update_or_insert_to_recent_engagements(...)
+
+ checkListObj.save()
+
+
+@auth(Permissions.el_review_checklist, is_internal=True)
+def set_state_to_peer_review():
+ """
+ This method is called when EL approves a review and moves a CL to peer_review
+ """
+ checkListObj = retrieve_checklist_and_its_decisions(
+ request_data_mgr.get_cl_uuid(), 'review_value') # @UndefinedVariable
+ checkListObj.state = CheckListState.peer_review.name # @UndefinedVariable
+ checkListObj.owner = checkListObj.engagement.peer_reviewer
+
+ insert_to_recent_engagements(
+ owner=checkListObj.owner, action=RecentEngagementActionType.GOT_OWNERSHIP_OVER_ENGAGEMENT.name) # @UndefinedVariable
+
+ checkListObj.update_time = timezone.now()
+
+ checkListObj.save()
+
+
+@auth(Permissions.peer_review_checklist, is_internal=True)
+def set_state_to_approval():
+ """
+ This method is called when Peer Reviewer approves a review and moves a CL to approval state
+ """
+ checkListObj = retrieve_checklist_and_its_decisions(
+ request_data_mgr.get_cl_uuid(), 'peer_review_value') # @UndefinedVariable
+ checkListObj.state = CheckListState.approval.name # @UndefinedVariable
+ admin_role = Role.objects.get(name=Roles.admin.name) # @UndefinedVariable
+
+ admin_list = IceUserProfile.objects.all().filter(
+ role=admin_role) # @UndefinedVariable
+ if admin_list.count() < 1:
+ logger.error("Failed to save the new state of the Checklist to the DB")
+ msg = "checklist state wasn't change due to server error"
+ raise Exception(msg)
+
+ rand_admin = admin_list[random.randint(0, admin_list.count() - 1)]
+ admin = IceUserProfile.objects.get(uuid=rand_admin.uuid)
+
+ checkListObj.update_time = timezone.now()
+ checkListObj.owner = admin
+ insert_to_recent_engagements(
+ owner=checkListObj.owner, action=RecentEngagementActionType.GOT_OWNERSHIP_OVER_ENGAGEMENT.name) # @UndefinedVariable
+
+ checkListObj.save()
+
+
+@auth(Permissions.admin_approve_checklist)
+def set_state_to_handoff():
+ """
+ This method is called when an admin approves a CL and moves it to a handoff state
+ """
+ checkListObj = retrieve_checklist_and_its_decisions(
+ request_data_mgr.get_cl_uuid(), '')
+ checkListObj.state = CheckListState.handoff.name # @UndefinedVariable
+ checkListObj.owner = checkListObj.creator
+
+ insert_to_recent_engagements(
+ owner=checkListObj.owner, action=RecentEngagementActionType.GOT_OWNERSHIP_OVER_ENGAGEMENT.name) # @UndefinedVariable
+
+ checkListObj.update_time = timezone.now()
+
+ checkListObj.save()
+
+
+@auth(Permissions.handoff_checklist)
+def set_state_to_closed():
+ """
+ This method is called when an EL approves the handoff and moves the CL to closed state
+ """
+ checkListObj = retrieve_checklist_and_its_decisions(
+ request_data_mgr.get_cl_uuid(), '')
+ checkListObj.state = CheckListState.closed.name # @UndefinedVariable
+ checkListObj.owner = checkListObj.creator
+ checkListObj.update_time = timezone.now()
+ update_eng_validation_details(checkListObj)
+ checkListObj.save()
diff --git a/django/engagementmanager/service/cms/__init__.py b/django/engagementmanager/service/cms/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/service/cms/__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/service/cms/base_cms.py b/django/engagementmanager/service/cms/base_cms.py
new file mode 100755
index 0000000..8625d88
--- /dev/null
+++ b/django/engagementmanager/service/cms/base_cms.py
@@ -0,0 +1,51 @@
+#
+# ============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 abc import ABCMeta
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class BaseCms():
+ '''
+ classdocs This is the base abstract class of all ice cms operations
+ '''
+ __metaclass__ = ABCMeta
+
+ logger = LoggingServiceFactory.get_logger()
diff --git a/django/engagementmanager/service/cms/pages_service.py b/django/engagementmanager/service/cms/pages_service.py
new file mode 100755
index 0000000..ab6fc96
--- /dev/null
+++ b/django/engagementmanager/service/cms/pages_service.py
@@ -0,0 +1,68 @@
+#
+# ============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 re
+
+from engagementmanager.apps import cms_client
+from engagementmanager.service.cms.base_cms import BaseCms
+
+
+class CMSPagesService(BaseCms):
+
+ def __init__(self, params=None):
+ pass
+
+ def getPages(self, title=""):
+ pages = cms_client.get_pages(title)
+
+ return pages
+
+ def getPage(self, id):
+ page = cms_client.get_page(id)
+
+ # Handling static files address (like images) to get the full address of the CMS static file:
+ if 'content' in page and page['content']:
+ cmsAddress = re.sub('\/api/$', '', cms_client.api_url)
+ page['content'] = page['content'].replace('src="/static/media/', 'src="%s/static/media/' % cmsAddress)
+
+ return page
+
+ def searchPages(self, keyword):
+ pages = cms_client.search_pages(keyword)[:100]
+
+ return pages
diff --git a/django/engagementmanager/service/cms/posts_service.py b/django/engagementmanager/service/cms/posts_service.py
new file mode 100755
index 0000000..720f766
--- /dev/null
+++ b/django/engagementmanager/service/cms/posts_service.py
@@ -0,0 +1,58 @@
+#
+# ============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 datetime import datetime, timedelta
+
+from engagementmanager.apps import cms_client
+from engagementmanager.service.cms.base_cms import BaseCms
+
+
+class CMSPostsService(BaseCms):
+
+ def __init__(self, params=None):
+ pass
+
+ def getPosts(self, offset, limit, fromLastDays=None, category=""):
+ from_last_days_param = ""
+
+ if (fromLastDays is not None and fromLastDays != ""):
+ from_last_days_param = (datetime.now() - timedelta(days=int(fromLastDays))).strftime('%Y-%m-%d')
+
+ posts = cms_client.get_posts(offset, limit, category, from_last_days_param)
+
+ return posts
diff --git a/django/engagementmanager/service/deploment_target_service.py b/django/engagementmanager/service/deploment_target_service.py
new file mode 100755
index 0000000..69c5e6f
--- /dev/null
+++ b/django/engagementmanager/service/deploment_target_service.py
@@ -0,0 +1,47 @@
+#
+# ============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 engagementmanager.models import VF, DeploymentTarget
+
+
+def update_deployment_target(engagement_uuid, dt_uuid):
+
+ vf = VF.objects.get(engagement__uuid=engagement_uuid)
+ dpltarget = DeploymentTarget.objects.get(uuid=dt_uuid)
+ vf.deployment_target = dpltarget
+ vf.save()
diff --git a/django/engagementmanager/service/ecomp_service.py b/django/engagementmanager/service/ecomp_service.py
new file mode 100755
index 0000000..d151ac0
--- /dev/null
+++ b/django/engagementmanager/service/ecomp_service.py
@@ -0,0 +1,46 @@
+#
+# ============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 engagementmanager.models import VF, ECOMPRelease
+
+
+def update_ECOMP(engagement_uuid, ecomp_uuid):
+ vf = VF.objects.get(engagement__uuid=engagement_uuid)
+ ecomp = ECOMPRelease.objects.get(uuid=ecomp_uuid)
+ vf.ecomp_release = ecomp
+ vf.save()
diff --git a/django/engagementmanager/service/engagement_service.py b/django/engagementmanager/service/engagement_service.py
new file mode 100755
index 0000000..628bc57
--- /dev/null
+++ b/django/engagementmanager/service/engagement_service.py
@@ -0,0 +1,689 @@
+#
+# ============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 datetime import datetime, timedelta
+from django.conf import settings
+from django.core.exceptions import PermissionDenied
+from django.db import connection
+from django.db.models.aggregates import Count
+from django.db.models.expressions import F
+from django.db.models.query_utils import Q
+from django.utils import timezone
+from django.utils.datastructures import OrderedSet
+from engagementmanager.bus.messages.activity_event_message import \
+ ActivityEventMessage
+from engagementmanager.slack_client.api import SlackClient
+from engagementmanager.models import VF, Engagement, RecentEngagement, \
+ EngagementStatus, VFC, IceUserProfile, Checklist
+from engagementmanager.serializers import SuperThinIceUserProfileModelSerializer, \
+ VFModelSerializerForSignal
+from engagementmanager.utils.constants import Roles, EngagementStage, \
+ ChecklistDefaultNames
+from engagementmanager.utils.dates import parse_date
+from engagementmanager.utils.activities_data import \
+ ChangeEngagementStageActivityData
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.vm_integration import vm_client
+from validationmanager.utils.clients import get_gitlab_client
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def update_engagement_status(user, description, eng_status_uuid, engagement):
+ try:
+ status = EngagementStatus.objects.get(uuid=eng_status_uuid)
+ status.description = description
+ status.update_time = timezone.now()
+ status.save()
+ msg = "Status was successfully updated with a for engagement with uuid: " + \
+ engagement.uuid
+ logger.debug(msg)
+ except RecentEngagement.DoesNotExist:
+ EngagementStatus.objects.create(
+ creator=user, description=description)
+ msg = "Status was successfully created with a for engagement with uuid: " + \
+ engagement.uuid
+ logger.debug(msg)
+
+
+def insert_engagement_status(user, description, engagement):
+ created_eng = EngagementStatus.objects.create(
+ creator=user, description=description, engagement=engagement)
+ msg = "Status was successfully created with a for engagement with uuid: " + \
+ engagement.uuid
+ logger.debug(msg)
+ return created_eng
+
+
+def update_or_insert_to_recent_engagements(original_user_uuid, vf, action_type):
+ try:
+ user_uuid = ''
+ try:
+ user_uuid = original_user_uuid.urn[9:]
+ except:
+ user_uuid = original_user_uuid
+ recent_engs = RecentEngagement.objects.filter(
+ user_uuid=user_uuid, vf=vf.uuid).order_by('-last_update')
+
+ if len(recent_engs) == 0:
+ raise RecentEngagement.DoesNotExist()
+ else:
+ recent_eng = recent_engs[0]
+
+ if (recent_eng.action_type != action_type):
+ recent_eng.action_type = action_type
+ recent_eng.last_update = timezone.now()
+ msg = "Recent engagement table was successfully updated the row for a user with uuid: " + \
+ user_uuid + " and vf uuid: " + vf.uuid + \
+ "with a new action type: " + action_type
+ logger.debug(msg)
+ recent_eng.save()
+ else:
+ recent_eng.last_update = timezone.now()
+ msg = "Recent engagement table was successfully updated the last_update row for a user with uuid: " + \
+ user_uuid + " and vf uuid: " + vf.uuid
+ logger.debug(msg)
+ recent_eng.save()
+ RecentEngagement.objects.filter(
+ last_update__lt=datetime.now() - timedelta(days=settings.RECENT_ENG_TTL)).delete()
+ except RecentEngagement.DoesNotExist:
+ RecentEngagement.objects.create(
+ user_uuid=user_uuid, vf=vf, action_type=action_type)
+ msg = "Recent engagement table was successfully updated with a new row for a user with uuid: " + \
+ str(user_uuid) + " and vf uuid: " + str(vf.uuid)
+ logger.debug(msg)
+
+
+def get_dashboard_expanded_engs(stage, keyword, offset, limit, user):
+ """
+ Expecting:
+ stage: one of the choices in the defined constants.
+ keyword: string
+ offset: non-negative number to start the pull from them + 9 (Negative indexing (i.e. Entry.objects.all()[-1]) is not supported - according to Django 21.12.16).
+ user: user object of the requesting client.
+ Result:
+ Query-set of engs that match the parameters provided (10 objects).
+ """
+ engStageList = [EngagementStage.Intake.name, EngagementStage.Active.name,
+ EngagementStage.Validated.name, EngagementStage.Completed.name] # @UndefinedVariable
+
+ q_object = Q()
+ q_vfc_object = Q()
+ if len(keyword) >= 1:
+ q_object &= Q(name__icontains=keyword) | Q(
+ engagement__engagement_manual_id__icontains=keyword) | Q(
+ engagement__engagement_team__email__icontains=keyword) | Q(
+ engagement__engagement_team__full_name__icontains=keyword)
+ q_vfc_object &= Q(name__icontains=keyword)
+
+ if stage == "All":
+ q_object &= Q(engagement__engagement_stage__in=engStageList)
+ q_vfc_object &= Q(vf__engagement__engagement_stage__in=engStageList)
+ else:
+ q_object &= Q(engagement__engagement_stage=stage)
+ q_vfc_object &= Q(vf__engagement__engagement_stage=stage)
+
+ # @UndefinedVariable
+ if (user.role.name != Roles.admin.name and user.role.name != Roles.admin_ro.name):
+ q_object &= Q(engagement__engagement_team__uuid=user.uuid)
+ q_vfc_object &= Q(vf__engagement__engagement_team__uuid=user.uuid)
+
+ vf_list_uuids = VF.objects.filter(q_object).values_list(
+ 'uuid', flat=True).order_by('engagement__target_completion_date')
+ vfc_vflist_uuids = VFC.objects.filter(q_vfc_object).values_list(
+ 'vf__uuid', flat=True).order_by('vf__engagement__target_completion_date')
+
+ vf_list_uuids = OrderedSet(vf_list_uuids)
+ for current_vf in OrderedSet(vfc_vflist_uuids):
+ vf_list_uuids.add(current_vf)
+ num_of_objects = len(vf_list_uuids)
+
+ vf_final_array = []
+ vf_list = VF.objects.filter(uuid__in=vf_list_uuids)\
+ .annotate(vf__name=F('name'), vendor__name=F('vendor__name'),
+ )\
+ .values(
+ 'vf__name',
+ 'version',
+ 'deployment_target__version',
+ 'engagement__peer_reviewer__uuid',
+ 'ecomp_release__name',
+ 'engagement__engagement_stage',
+ 'engagement__engagement_manual_id',
+ 'engagement__uuid',
+ 'engagement__heat_validated_time',
+ 'engagement__image_scan_time',
+ 'engagement__aic_instantiation_time',
+ 'engagement__asdc_onboarding_time',
+ 'engagement__target_completion_date',
+ 'engagement__progress',
+ 'target_lab_entry_date',
+ 'engagement__started_state_time',
+ 'vendor__name',
+ 'engagement__validated_time',
+ 'engagement__completed_time',
+ 'uuid'
+ )\
+ .annotate(vf_uuid_count=Count('uuid', distinct=True))\
+ .order_by('engagement__target_completion_date')[int(offset):int(offset) + limit]
+ for current_vf in vf_list:
+ eng = Engagement.objects.get(uuid=current_vf['engagement__uuid'])
+ starred_users = eng.starred_engagement.all()
+ current_vf['starred_users'] = list()
+ if starred_users:
+ for current_starred in starred_users:
+ current_vf['starred_users'].append(current_starred.uuid)
+ vf_final_array.append(current_vf)
+ data = {'array': vf_final_array, 'num_of_objects': num_of_objects}
+ return data
+
+# Extension method for get_dashboard_expanded_engs which adds additional
+# data required by export process.
+
+
+def get_expanded_engs_for_export(stage, keyword, user):
+ # TODO replace this 1000000 with No limit value
+ data = get_dashboard_expanded_engs(
+ stage, keyword, 0, 10000000, user)
+
+ vf_list = data["array"]
+
+ for vf in vf_list:
+ eng = Engagement.objects.get(uuid=vf['engagement__uuid'])
+ latest_status = EngagementStatus.objects.filter(
+ engagement=eng).distinct().order_by('-update_time')[:1]
+ peer_reviewer = eng.peer_reviewer
+ reviewer = eng.reviewer
+ vf['vf_engagement__peer_reviewer'] = peer_reviewer
+ vf['vf_engagement__reviewer'] = reviewer
+ if latest_status.count() > 0:
+ vf['engagement__latest_status'] = latest_status[0].description
+ else:
+ vf['engagement__latest_status'] = "--"
+
+ vf['vfcs'] = "--"
+ vf['vfcs__number'] = "0"
+ vfObject = VF.objects.get(uuid=vf['uuid'])
+ if vfObject is not None:
+ vfcs = vfObject.vfc_set.values_list('name', flat=True)
+ if vfcs.count() > 0:
+ vf['vfcs'] = ', '.join(vfcs)
+ vf['vfcs__number'] = vfcs.count()
+
+ # Overview statistics:
+ cursor = connection.cursor()
+ cursor.callproc("generate_excel_overview_sheet", (stage, keyword,))
+ deployment_targets = cursor.fetchall()
+ cursor.execute("COMMIT")
+
+ return vf_list, deployment_targets
+
+
+def is_eng_stage_eql_to_requested_one(engagement, requested_stage):
+ if engagement.engagement_stage == requested_stage:
+ msg = "An attempt to change the Engagement's stage (uuid: " + engagement.uuid + \
+ ") to the same stage it is current in(" + \
+ engagement.engagement_stage + ") was made."
+ logger.debug(msg)
+ return True
+ return False
+
+
+def set_engagement_stage(eng_uuid, stage):
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ vfObj = engagement.vf
+ if is_eng_stage_eql_to_requested_one(engagement, stage):
+ msg = "Action denied."
+ raise ValueError(msg)
+ else:
+ engagement.engagement_stage = stage
+ engagement.intake_time = timezone.now()
+ engagement.save()
+ vm_client.fire_event_in_bg('send_provision_new_vf_event', vfObj)
+ msg = send_notifications_and_create_activity_after_eng_stage_update(
+ engagement)
+ return msg
+
+
+def send_notifications_and_create_activity_after_eng_stage_update(engagement):
+ # send notifications
+ res = get_engagement_manual_id_and_vf_name(engagement)
+ slack_client = SlackClient()
+ slack_client.update_for_change_of_the_engagement_stage(
+ res['engagement_manual_id'], res['vf_name'], engagement.engagement_stage)
+
+ activity_data = ChangeEngagementStageActivityData(VF.objects.get(engagement=engagement), engagement.engagement_stage,
+ engagement)
+ from engagementmanager.apps import bus_service
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ logger.debug("Engagement's stage (eng_uuid: " + engagement.uuid + ") was successfully changed to: "
+ + engagement.engagement_stage)
+ return "OK"
+
+
+def set_progress_for_engagement(progress=None):
+ prog = int(progress)
+ if prog < 0 or prog > 100:
+ msg = 'set_progress_for_engagement failed: Progress value is invalid (out of bounds). Should be 0-100'
+ logger.debug(msg)
+ raise ValueError(msg)
+ else:
+ eng = Engagement.objects.get(uuid=request_data_mgr.get_eng_uuid())
+ eng.progress = progress
+ eng.save()
+
+
+def vf_retreiver(user, star=False, recent=False, eng_uuid=""):
+ engStageList = [EngagementStage.Intake.name, EngagementStage.Active.name,
+ EngagementStage.Validated.name, EngagementStage.Completed.name] # @UndefinedVariable
+ # @UndefinedVariable
+ if (user.role.name == Roles.admin.name or user.role.name == Roles.admin_ro.name):
+ if star:
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(engagement__starred_engagement__uuid=user.uuid).distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+
+ for vf in vf_list:
+ red_dot_activity = RecentEngagement.objects.filter(
+ vf=vf['uuid']).values('action_type').order_by('-last_update')[:1]
+ if (red_dot_activity.count() > 0):
+ vf['action_type'] = red_dot_activity[0]['action_type']
+ else:
+ vf['action_type'] = ''
+
+ return vf_list
+
+ elif recent:
+ recent = RecentEngagement.objects.filter(vf__engagement__engagement_stage__in=engStageList)\
+ .filter(user_uuid=user.uuid).distinct().order_by('-last_update')\
+ .values(
+ 'vf__uuid',
+ 'vf__name',
+ 'vf__is_service_provider_internal',
+ 'vf__engagement__creator__uuid',
+ 'vf__engagement__engagement_manual_id',
+ 'vf__engagement__peer_reviewer__uuid',
+ 'vf__engagement__peer_reviewer__email',
+ 'vf__engagement__reviewer__uuid',
+ 'vf__engagement__reviewer__email',
+ 'vf__engagement__uuid',
+ 'action_type',
+ 'last_update'
+ )[:20]
+ return recent
+
+ else:
+ if eng_uuid != "":
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(engagement__uuid=eng_uuid).distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+ else:
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter().distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+
+ return vf_list
+ else:
+ if star:
+ if eng_uuid != "":
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(Q(engagement__uuid=eng_uuid, engagement__engagement_team__uuid=user.uuid, engagement__starred_engagement__uuid=user.uuid) | Q(engagement__uuid=eng_uuid, engagement__peer_reviewer=user, engagement__starred_engagement__uuid=user.uuid))\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+ else:
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(Q(engagement__engagement_team__uuid=user.uuid, engagement__starred_engagement__uuid=user.uuid) | Q(engagement__peer_reviewer=user, engagement__starred_engagement__uuid=user.uuid)).distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+ for vf in vf_list:
+ red_dot_activity = RecentEngagement.objects.filter(
+ vf=vf['uuid']).values('action_type').order_by('-last_update')[:1]
+ if (red_dot_activity.count() > 0):
+ vf['action_type'] = red_dot_activity[0]['action_type']
+ else:
+ vf['action_type'] = ''
+
+ return vf_list
+
+ elif recent:
+ recent = RecentEngagement.objects.filter(vf__engagement__engagement_stage__in=engStageList)\
+ .filter(Q(user_uuid=user.uuid, vf__engagement__engagement_team__uuid=user.uuid) | Q(user_uuid=user.uuid, vf__engagement__peer_reviewer=user)).distinct().order_by('-last_update')\
+ .values(
+ 'vf__uuid',
+ 'vf__name',
+ 'vf__is_service_provider_internal',
+ 'vf__engagement__creator__uuid',
+ 'vf__engagement__engagement_manual_id',
+ 'vf__engagement__peer_reviewer__uuid',
+ 'vf__engagement__peer_reviewer__email',
+ 'vf__engagement__reviewer__uuid',
+ 'vf__engagement__reviewer__email',
+ 'vf__engagement__uuid',
+ 'action_type',
+ 'last_update'
+ )[:20]
+ return recent
+ else:
+ if eng_uuid != "":
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(Q(engagement__uuid=eng_uuid, engagement__engagement_team__uuid=user.uuid) | Q(engagement__uuid=eng_uuid, engagement__peer_reviewer=user)).distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+ else:
+ vf_list = VF.objects.filter(engagement__engagement_stage__in=engStageList)\
+ .filter(Q(engagement__engagement_team__uuid=user.uuid) | Q(engagement__peer_reviewer=user)).distinct().order_by('engagement__engagement_manual_id')\
+ .values(
+ 'uuid',
+ 'name',
+ 'is_service_provider_internal',
+ 'engagement__creator__uuid',
+ 'engagement__engagement_manual_id',
+ 'engagement__peer_reviewer__uuid',
+ 'engagement__peer_reviewer__email',
+ 'engagement__reviewer__uuid',
+ 'engagement__reviewer__email',
+ 'engagement__uuid'
+ )
+ return vf_list
+
+
+def star_an_engagement(user, eng_uuid):
+ msg = "Engagement was successfully starred."
+ engObj = None
+ try:
+ engObj = Engagement.objects.get(
+ uuid=eng_uuid, starred_engagement__uuid=user.uuid)
+ engObj.starred_engagement.remove(user)
+ msg = "Engagement was successfully un-starred."
+ except Engagement.DoesNotExist:
+ engObj = Engagement.objects.get(uuid=eng_uuid)
+ engObj.starred_engagement.add(user)
+ engObj.save()
+
+ return msg
+
+
+def archive_engagement(eng_uuid, reason):
+ msg = "Engagement was successfully archived."
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ # get the vf
+ vf = VF.objects.get(engagement__uuid=engagement.uuid)
+ gitlab = get_gitlab_client()
+ project_id = "%s/%s" % (vf.engagement.engagement_manual_id,
+ vf.name.replace(' ', '_'))
+ formated_vf = VFModelSerializerForSignal(vf).data
+
+ # @UndefinedVariable
+ engagement.engagement_stage = EngagementStage.Archived.name
+ engagement.archive_reason = reason
+ engagement.archived_time = timezone.now()
+ engagement.save()
+ vm_client.send_remove_all_standard_users_from_project_event(
+ gitlab, project_id, formated_vf)
+ # send notifications
+ res = get_engagement_manual_id_and_vf_name(engagement)
+ slack_client = SlackClient()
+ slack_client.update_for_archived_engagement(
+ res['engagement_manual_id'], res['vf_name'], reason)
+ return msg
+
+
+def set_engagement_reviewer(eng_uuid, reviewer_uuid):
+ result = None
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+
+ reviewer = IceUserProfile.objects.get(uuid=reviewer_uuid)
+ if engagement.peer_reviewer != reviewer:
+ old_reviewer = engagement.reviewer
+ engagement.engagement_team.remove(old_reviewer)
+ engagement.engagement_team.add(reviewer)
+
+ checklist_lists_creator = Checklist.objects.filter(
+ engagement__uuid=eng_uuid, creator=old_reviewer)
+ for checklist in checklist_lists_creator:
+ checklist.creator = reviewer
+ checklist.save()
+
+ checklist_lists_owner = Checklist.objects.filter(
+ engagement__uuid=eng_uuid, owner=old_reviewer)
+ for checklist in checklist_lists_owner:
+ checklist.owner = reviewer
+ checklist.save()
+
+ engagement.reviewer = reviewer
+ engagement.save()
+
+ # send notifications
+ res = get_engagement_manual_id_and_vf_name(engagement)
+ slack_client = SlackClient()
+ slack_client.update_reviewer_or_peer_reviewer(
+ res['engagement_manual_id'], res['vf_name'], reviewer, old_reviewer, 'reviewer')
+
+ result = reviewer
+ else:
+ return result
+
+ return SuperThinIceUserProfileModelSerializer(result).data
+
+
+def set_engagement_peer_reviewer(eng_uuid, peer_reviewer_uuid):
+ result = None
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ peer_reviewer = IceUserProfile.objects.get(uuid=peer_reviewer_uuid)
+ if engagement.reviewer != peer_reviewer:
+ old_peer_reviewer = engagement.peer_reviewer
+ engagement.engagement_team.remove(old_peer_reviewer)
+ engagement.engagement_team.add(peer_reviewer)
+
+ checklist_lists_owner = Checklist.objects.filter(
+ engagement__uuid=eng_uuid, owner=old_peer_reviewer)
+ for checklist in checklist_lists_owner:
+ checklist.owner = peer_reviewer
+ checklist.save()
+
+ engagement.peer_reviewer = peer_reviewer
+ engagement.save()
+
+ # send notifications
+ res = get_engagement_manual_id_and_vf_name(engagement)
+ slack_client = SlackClient()
+ slack_client.update_reviewer_or_peer_reviewer(
+ res['engagement_manual_id'], res['vf_name'], peer_reviewer, old_peer_reviewer, 'peer reviewer')
+
+ result = peer_reviewer
+ else:
+ return result
+
+ return SuperThinIceUserProfileModelSerializer(result).data
+
+
+def switch_engagement_reviewers(eng_uuid, reviewer_uuid, peer_reviewer_uuid):
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ peer_reviewer = IceUserProfile.objects.get(uuid=peer_reviewer_uuid)
+ old_peer_reviewer = engagement.peer_reviewer
+ reviewer = IceUserProfile.objects.get(uuid=reviewer_uuid)
+ old_reviewer = engagement.reviewer
+
+ checklist_owners = Checklist.objects.filter(
+ Q(engagement__uuid=eng_uuid) & (Q(owner=old_reviewer) | Q(owner=old_peer_reviewer)))
+
+ for checklist in checklist_owners:
+ if checklist.owner == reviewer:
+ checklist.owner = peer_reviewer
+ if checklist.owner == peer_reviewer:
+ checklist.owner = reviewer
+ checklist.save()
+
+ engagement.peer_reviewer = peer_reviewer
+ engagement.reviewer = reviewer
+ engagement.save()
+
+ # send notifications
+ res = get_engagement_manual_id_and_vf_name(engagement)
+ slack_client = SlackClient()
+ slack_client.update_reviewer_or_peer_reviewer(
+ res['engagement_manual_id'], res['vf_name'], reviewer, old_reviewer, 'reviewer')
+ slack_client.update_reviewer_or_peer_reviewer(
+ res['engagement_manual_id'], res['vf_name'], peer_reviewer, old_peer_reviewer, 'peer reviewer')
+
+ return {"reviewer": reviewer_uuid, "peerreviewer": peer_reviewer_uuid}
+
+
+def get_engagement_manual_id_and_vf_name(engagement):
+ # get the engagement
+ engagement_manual_id = engagement.engagement_manual_id
+
+ # get the vf
+ vf = VF.objects.get(engagement__uuid=engagement.uuid)
+ vf_name = ""
+ if vf is not None:
+ vf_name = vf.name
+
+ return {'engagement_manual_id': engagement_manual_id, 'vf_name': vf_name}
+
+
+def update_engagement(engagement_dict):
+ engagement = Engagement.objects.get(uuid=engagement_dict['uuid'])
+
+ engagement.target_completion_date = parse_date(
+ engagement_dict['target_completion_date'])
+ engagement.heat_validated_time = parse_date(
+ engagement_dict['heat_validated_time'])
+ engagement.image_scan_time = parse_date(engagement_dict['image_scan_time'])
+ engagement.aic_instantiation_time = parse_date(
+ engagement_dict['aic_instantiation_time'])
+ engagement.asdc_onboarding_time = parse_date(
+ engagement_dict['asdc_onboarding_time'])
+ if 0 <= engagement_dict['progress'] <= 100:
+ engagement.progress = engagement_dict['progress']
+ else:
+ return None
+
+ engagement.save()
+ return engagement
+
+
+def remove_user_from_engagement_team(eng_uuid, user, removed_user_uuid):
+ msg = "User was successfully removed from the engagement team"
+ # @UndefinedVariable
+ if ((removed_user_uuid == user.uuid) or (removed_user_uuid != user.uuid and (user.role.name == Roles.admin.name or user.role.name == Roles.el.name))):
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ requested_user = IceUserProfile.objects.get(uuid=removed_user_uuid)
+ if (engagement.peer_reviewer == requested_user or engagement.reviewer == requested_user
+ or engagement.creator == requested_user or engagement.contact_user == requested_user):
+ msg = "Reviewer/Peer Reviewer/Creator/Contact user cannot be removed from engagement team."
+ logger.error(msg)
+ raise PermissionDenied
+ engagement.engagement_team.remove(requested_user)
+ engagement.save()
+ logger.debug(msg)
+ else:
+ msg = "removed user is not equal to conducting user or user is not an admin."
+ logger.error(msg)
+ raise PermissionDenied
+
+
+def update_eng_validation_details(cl):
+ setattr(cl.engagement,
+ ChecklistDefaultNames.VALIDATION_DATE_ARRAY[cl.name], timezone.now())
+ cl.engagement.save()
diff --git a/django/engagementmanager/service/invite_service.py b/django/engagementmanager/service/invite_service.py
new file mode 100755
index 0000000..c4780fd
--- /dev/null
+++ b/django/engagementmanager/service/invite_service.py
@@ -0,0 +1,179 @@
+#
+# ============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 datetime import datetime, timedelta
+from uuid import uuid4
+import bleach
+from django.conf import settings
+from django.template.loader import get_template
+from engagementmanager import mail
+from engagementmanager.models import Invitation, IceUserProfile, Engagement
+from engagementmanager.utils.constants import Roles, Constants
+from engagementmanager.utils.vvp_exceptions import VvpBadRequest
+from engagementmanager.utils.validator import Validator, logEncoding
+from engagementmanager.views_helper import getVfByEngUuid
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def enforce_invitation_throttling(eng_uuid, invited_email, inviterUser, invitedUser):
+ assert eng_uuid is not None
+ assert invited_email is not None
+
+ invitation = Invitation.objects.filter(engagement_uuid=eng_uuid, email=invited_email)
+ if len(invitation) > 0:
+ logger.warn("Oops, looks like an invitation with following details already exists: " + str(invitation))
+ return False
+
+ if ((invitedUser != None and invitedUser.role.name != Roles.admin.name and
+ invitedUser.role.name != Roles.el.name) or invitedUser == None):
+ numOfInvitationinLast24H = Invitation.objects.filter(email=invited_email,
+ create_time__gte=datetime.now() - timedelta(
+ hours=24)).count()
+ if numOfInvitationinLast24H >= 5:
+ logger.warn(
+ "Oops, looks like invited email (" + invited_email + ") which isn't EL nor admin has reached its "
+ "max invitations (5) in the last 24 hours")
+ return False
+
+ if ((invitedUser != None and invitedUser.role.name == Roles.standard_user.name) or
+ (invitedUser != None and invitedUser.role.name == Roles.admin_ro.name) or
+ invitedUser == None):
+ numOfInvitationinLast24H = Invitation.objects.filter(invited_by_user_uuid=inviterUser.uuid,
+ create_time__gte=datetime.now() - timedelta(
+ hours=24)).count()
+ if numOfInvitationinLast24H >= 25:
+ logger.warn(
+ "Oops, looks like a standard-user/admin-readonly inviter "
+ "(" + inviterUser.email + ") has reached its max invitations (25) in the last 24 hours")
+ return False
+ return True
+
+
+def generateInviteMail(data, inviterUser, invitedUser, is_contact_user):
+ vf = getVfByEngUuid(data['eng_uuid'])
+ if vf is not None:
+ data['vf_name'] = vf.name
+ else:
+ data['vf_name'] = "-"
+ logger.error("Couldn't fetch VF by engagement uuid=" + logEncoding(data['eng_uuid']))
+
+ body = get_template("{invite_template_dir}invite_mail_body.html".format(
+ invite_template_dir=Constants.invite_template_dir))
+ subject = get_template("{invite_template_dir}invite_mail_subject.html".format(
+ invite_template_dir=Constants.invite_template_dir))
+
+ data['dashboard_link'] = str(settings.DOMAIN) + "/#/dashboard/"
+ invitation = Invitation.objects.create(engagement_uuid=data['eng_uuid'],
+ invited_by_user_uuid=inviterUser.uuid, email=data['email'],
+ invitation_token=uuid4())
+
+ if invitedUser is not None:
+ data['invite_link'] = str(settings.DOMAIN) + "/#/login?invitation=" + str(invitation.invitation_token)
+ data['instruction'] = "To accept this invitation, please click this link:"
+ logger.debug("Invited Contact with email " + data['email'] + "already exist in the DB. Sending them an email "
+ "with link to login page. link=" + data[
+ 'invite_link'])
+ if is_contact_user:
+ logger.debug("Updating the Engagement with uuid=" + data[
+ 'eng_uuid'] + " to have this contact user: " + invitedUser.full_name)
+ engObj = Engagement.objects.get(uuid=data['eng_uuid'])
+ engObj.contact_user = invitedUser
+ engObj.save()
+
+ else:
+ prefix = str(settings.DOMAIN) + "/#/signUp?invitation=" + \
+ str(invitation.invitation_token) + "&email=" + data['email']
+ suffix = ""
+ if 'full_name' in data and data['full_name'] and 'phone_number' in data and data['phone_number']:
+ suffix += "&full_name=" + data['full_name'] + "&phone_number=" + data['phone_number']
+ if data.get('company'):
+ suffix += "&company=" + data['company']
+
+ data['invite_link'] = prefix + suffix
+ data['instruction'] = "To create an account and accept this invitation, please click this link:"
+
+ if is_contact_user:
+ data['invite_link'] += "&is_contact_user=true"
+ logger.debug("The invite mail is sent to a contact person (VF Contact or "
+ + Constants.service_provider_company_name + " Sponsor)")
+
+ logger.debug(
+ "Invited Person doesn't exists, sending them an email with link to signup. link=" + data['invite_link'])
+
+ return body, subject, invitation
+
+
+def inviteUserToSignUpOrLogin(inviterUser, data, is_contact_user):
+ invitedUser = None
+
+ Validator.validateEmail(data['email'])
+
+ data['email'] = bleach.clean(data['email'], tags=['a', 'b'])
+ rs = IceUserProfile.objects.filter(email=data['email'])
+
+ if len(rs) > 0:
+ invitedUser = IceUserProfile.objects.get(email=data['email'])
+
+ is_invite_ok = enforce_invitation_throttling(data['eng_uuid'], data['email'], inviterUser, invitedUser)
+
+ if is_invite_ok == False:
+ msg = "Invite couldn't be created"
+ logger.error(msg)
+ raise VvpBadRequest(msg)
+
+ body, subject, invitation = generateInviteMail(data, inviterUser, invitedUser, is_contact_user)
+
+ try:
+ mail.sendMail(data['email'], data, body, subject)
+ except Exception as e:
+ logger.error(e)
+ msg = "Something went wrong while trying to send mail to " + data['email'] + " from " + inviterUser.email
+ logger.error(msg)
+ if invitation:
+ logger.error("Rolling back the invitation (" + invitation + ") due to problems in sending its mail")
+ invitation.delete()
+ raise Exception(msg)
+
+
+def markInvitationAsAccepted(invitation_token):
+ invitation = Invitation.objects.get(invitation_token=invitation_token)
+ invitation.accepted = True
+ invitation.save()
+ logger.debug("Marking Invitation [" + str(invitation) + "] as accepted")
diff --git a/django/engagementmanager/service/logging_service.py b/django/engagementmanager/service/logging_service.py
new file mode 100755
index 0000000..b90bdbf
--- /dev/null
+++ b/django/engagementmanager/service/logging_service.py
@@ -0,0 +1,58 @@
+#
+# ============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 logging
+
+
+class LoggingServiceFactory(object):
+ __logger = None
+
+ def __init__(self):
+ if self.__logger is None:
+ self.__set_logger()
+
+ @classmethod
+ def __set_logger(cls):
+ if cls.__logger is None:
+ cls.__logger = logging.getLogger('vvp.logger')
+
+ @classmethod
+ def get_logger(cls):
+ if cls.__logger is None:
+ cls.__set_logger()
+ return cls.__logger
diff --git a/django/engagementmanager/service/login_service.py b/django/engagementmanager/service/login_service.py
new file mode 100755
index 0000000..7216b56
--- /dev/null
+++ b/django/engagementmanager/service/login_service.py
@@ -0,0 +1,136 @@
+#
+# ============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 bleach
+from django.contrib.auth import authenticate
+from django.contrib.auth import get_user_model
+from django.contrib.auth.hashers import check_password
+from django.core.exceptions import PermissionDenied
+from django.utils import timezone
+from rest_framework.exceptions import NotAcceptable
+
+from engagementmanager.models import Invitation, VF
+from engagementmanager.serializers import ThinIceUserProfileModelSerializer
+from engagementmanager.service.base_service import BaseSvc
+from engagementmanager.service.invite_service import markInvitationAsAccepted
+from engagementmanager.utils.vvp_exceptions import VvpConflict
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.views_helper import addUsersToEngTeam
+from engagementmanager.vm_integration import vm_client
+
+
+class LoginSvc(BaseSvc):
+
+ def get_user_by_email(self, email):
+ user_model = get_user_model()
+ user = user_model._default_manager.get(email=email)
+ return user
+
+ def update_last_login(self, user_profile):
+ user_profile.user.last_login = timezone.now()
+ user_profile.user.save()
+ user_profile.save()
+
+ def authenticate_user(self, i_email, i_password, msg):
+ user = authenticate(username=i_email, password=i_password)
+ if not user:
+ msg = "User or Password does not match"
+ self.logger.error(msg)
+ raise PermissionDenied(msg)
+ return user
+
+ def reset_password(self, reset_password_email, i_password, msg, user_profile):
+ token_user = self.get_user_by_email(reset_password_email)
+ if user_profile.user.id != token_user.id:
+ msg = self.render_user_conflict_message(user_profile.user, token_user)
+ temp_encrypted_password = user_profile.user.temp_password
+ is_temp_password_ok = check_password(i_password, temp_encrypted_password)
+ if is_temp_password_ok:
+ self.logger.debug("Temporary Passwords match... Checking temporary password expiration")
+ else:
+ msg = "User or Password does not match"
+ self.logger.error(msg + " in Reset Password flow")
+ raise PermissionDenied(msg)
+ return msg
+
+ def render_user_conflict_message(self, user, user_from_token):
+ msg = "User Conflict"
+ self.logger.error(msg + ". user uuid =" + user.id + ", user from token uuid=" + user_from_token.id)
+ raise VvpConflict
+
+ def render_user_not_active_message(self, i_email):
+ msg = "User " + i_email + " is not active hence cannot perform login"
+ self.logger.error(msg)
+ msg = bleach.clean(msg, tags=['a', 'b'])
+ raise NotAcceptable(msg)
+
+ def identify_reset_password(self, jwt_obj, reset_password_param):
+ email = None
+ is_reset_pwd_flow = False
+
+ if reset_password_param is not None:
+ is_reset_pwd_flow = True
+ self.logger.debug(
+ "Reset Password flow is identified. Checking temporary password expiration. t=" + reset_password_param)
+ token_arr = reset_password_param.split("token")
+ if len(token_arr) > 0:
+ email = jwt_obj.decode_reset_password_token(str(token_arr[1]))
+ else:
+ self.logger.error("token doesn't include token prefix: " + logEncoding(reset_password_param))
+ is_reset_pwd_flow = False
+ return email, is_reset_pwd_flow
+
+ def handle_invite_token(self, data, user_data, user_profile):
+ data['invitation'] = data['invitation'].strip()
+ invitation = Invitation.objects.get(invitation_token=data['invitation'])
+ addUsersToEngTeam(invitation.engagement_uuid, [user_profile])
+ vf_obj = VF.objects.get(engagement__uuid=invitation.engagement_uuid)
+ vm_client.fire_event_in_bg('send_provision_new_vf_event', vf_obj)
+ user_data['eng_uuid'] = invitation.engagement_uuid
+ markInvitationAsAccepted(data['invitation'])
+
+ def get_serialized_user_data(self, is_reset_pwd_flow, user_profile, jwt_obj, user):
+ user_data = ThinIceUserProfileModelSerializer(user_profile).data
+ user_data['isResetPwdFlow'] = is_reset_pwd_flow
+ user_data['token'] = jwt_obj.create_token(user)
+ if user_profile.ssh_public_key:
+ user_data['ssh_public_key'] = "exists"
+ else:
+ user_data['ssh_public_key'] = ""
+
+ return user_data
diff --git a/django/engagementmanager/service/nextstep_service.py b/django/engagementmanager/service/nextstep_service.py
new file mode 100755
index 0000000..9fa8672
--- /dev/null
+++ b/django/engagementmanager/service/nextstep_service.py
@@ -0,0 +1,280 @@
+#
+# ============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.db.models.query_utils import Q
+from django.utils import timezone
+from django.utils.timezone import timedelta
+from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.models import Engagement, IceUserProfile, NextStep, VF
+from engagementmanager.serializers import ThinNextStepModelSerializer, UserNextStepModelSerializer
+from engagementmanager.utils.activities_data import UpdateNextStepsActivityData, AddNextStepsActivityData
+from engagementmanager.service.engagement_service import update_or_insert_to_recent_engagements
+from engagementmanager.service.base_service import BaseSvc
+from engagementmanager.utils.constants import Constants, NextStepType, NextStepState, RecentEngagementActionType
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.apps import bus_service
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class NextStepSvc(BaseSvc):
+ default_next_steps = [
+ {
+ 'position': 2,
+ 'stage': 'Intake',
+ 'text': 'Please work with your Engagement Lead (EL) to complete the necessary trial agreements.',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.trial_agreements.name # @UndefinedVariable
+ },
+ {
+ 'position': 3,
+ 'stage': 'Intake',
+ 'text': 'Please add your ' + Constants.service_provider_company_name + ' sponsor or vendor contact information.',
+ 'condition': lambda user, eng: False if (eng.contact_user) else True,
+ 'type': NextStepType.add_contact_person.name # @UndefinedVariable
+ },
+ {
+ 'position': 1,
+ 'stage': 'Active',
+ 'text': 'Please submit the first version of the VF package. If you have any problems or questions, please contact your Engagement Lead (EL)',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.submit_vf_package.name # @UndefinedVariable
+ },
+ {
+ 'position': 1,
+ 'stage': 'Validated',
+ 'text': 'Please schedule a time with your Engagement Lead (EL) to complete the handoff.',
+ 'condition': lambda x, y: True,
+ 'type': NextStepType.el_handoff.name # @UndefinedVariable
+ }
+ ]
+
+ def get_user_next_steps(self, limit, state):
+ user = request_data_mgr.get_user()
+
+ nextSteps = NextStep.objects.filter(Q(assignees=user) & Q(state=state)).order_by('due_date').distinct()
+ count = nextSteps.count()
+ serializer = UserNextStepModelSerializer(nextSteps[:limit], many=True)
+ return serializer, count
+
+ def get_next_steps(self, eng_stage=None):
+ user = request_data_mgr.get_user()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+
+ ers = NextStep.objects.filter(Q(engagement__uuid=eng_uuid, owner=None, engagement_stage=eng_stage) | Q(
+ owner=user, engagement_stage=eng_stage)).order_by('position')
+
+ serializer = ThinNextStepModelSerializer(ers, many=True)
+ for next_step in serializer.data:
+ if next_step['files'] is not None:
+ next_step['files'] = json.loads(next_step['files'])
+ if 'engagement' in next_step and next_step['engagement'] is not None and 'engagement_team' in next_step['engagement'] and next_step['engagement']['engagement_team'] is not None:
+ for user in next_step['engagement']['engagement_team']:
+ if (user['ssh_public_key'] != None):
+ del user['ssh_public_key']
+ return serializer
+
+ def addNextStep(self, dataList, desc=""):
+ user = request_data_mgr.get_user()
+ checklist_uuid = request_data_mgr.get_cl_uuid()
+ eng_uuid = request_data_mgr.get_eng_uuid()
+
+ nextStepObj = None
+
+ engObj = Engagement.objects.get(uuid=eng_uuid)
+ vfObj = VF.objects.get(engagement=engObj)
+
+ nextStepData = []
+ due_date = None
+
+ for data in dataList:
+ try:
+ associated_files = json.dumps(data['files'], ensure_ascii=False)
+ except:
+ associated_files = "[]"
+
+ try:
+ due_date = data['duedate']
+ except:
+ due_date = None
+
+ nextStepObj = NextStep.objects.create(creator=user, last_updater=user, engagement=engObj, position=NextStep.objects.count() + 1,
+ # @UndefinedVariable
+ description=data[
+ 'description'], state=NextStepState.Incomplete.name, engagement_stage=engObj.engagement_stage,
+ files=associated_files, due_date=due_date) # @UndefinedVariable
+
+ try:
+ data['assigneesUuids']
+ except:
+ data['assigneesUuids'] = []
+
+ for assigneesUuid in data['assigneesUuids']:
+ assignee_user = None
+ assignee_user = IceUserProfile.objects.get(uuid=assigneesUuid)
+ nextStepObj.assignees.add(assignee_user)
+ nextStepObj.save()
+ update_or_insert_to_recent_engagements(
+ assignee_user.uuid, vfObj, RecentEngagementActionType.NEXT_STEP_ASSIGNED.name) # @UndefinedVariable
+
+ nextStepData.append(ThinNextStepModelSerializer(nextStepObj).data)
+
+ activity_data = AddNextStepsActivityData(VF.objects.get(engagement=engObj), user, engObj)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ if checklist_uuid != None:
+ from engagementmanager.service.checklist_state_service import set_state
+ set_state(True, checklist_uuid, isMoveToAutomation=True, description=desc)
+ logger.debug("Successfully added a Next Step to engagement_uuid=" +
+ eng_uuid + " for checklist=" + checklist_uuid)
+
+ return nextStepData
+
+ '''
+ This function shall return the update type in the next step (can be Completed or Denied)
+ '''
+
+ def validate_state_transition(self, user, current_state, next_state):
+ update_type = next_state.name
+ logger.debug('validating step transition by %s from %s to %s', user.role.name, current_state, next_state)
+
+ if (current_state == NextStepState.Completed and next_state == NextStepState.Incomplete):
+ if (user.role.name == 'el'):
+ update_type = 'Denied'
+ else:
+ update_type = 'Reset'
+
+ return update_type
+
+ def create_default_next_steps_for_user(self, user, el_user):
+ def cond(user): return False if (user.ssh_public_key and user.ssh_public_key != '') else True
+ if cond(user):
+ desc = "Please add your SSH key to be able to contribute."
+
+ nextstep = NextStep.objects.create(
+ creator=el_user,
+ last_updater=el_user,
+ position=1,
+ description=desc,
+ last_update_type='Added',
+ state='Incomplete',
+ engagement_stage='Intake',
+ engagement=None,
+ owner=user,
+ next_step_type=NextStepType.set_ssh.name, # @UndefinedVariable
+ due_date=timezone.now() + timedelta(days=1))
+ nextstep.save()
+
+ '''
+ This method is for non-personal default next step only since it doesn't have an owner
+ '''
+
+ def create_default_next_steps(self, user, engagement, el_user):
+ for step in self.default_next_steps:
+ cond = step['condition']
+ desc = step['text']
+ ns_type = step['type']
+ if cond(user, engagement):
+ if (user.company == Constants.service_provider_company):
+ desc = desc.replace('$Contact', 'Vendor Contact')
+ else:
+ desc = desc.replace('$Contact', Constants.service_provider_company_name + ' Sponsor Contact')
+ logger.debug('Creating default next step : ' + desc)
+
+ nextstep = NextStep.objects.create(creator=el_user, last_updater=el_user, position=step['position'], description=desc, state='Incomplete', engagement_stage=step[
+ 'stage'], engagement=engagement, next_step_type=ns_type, due_date=timezone.now() + timedelta(days=1))
+ nextstep.assignees.add(el_user)
+ nextstep.save()
+
+ else:
+ logger.debug('Skipping creation of default next step : ' + desc)
+
+ def update_next_steps_order(self, nextsteps):
+ counter = 0
+ for nextstep in nextsteps:
+ step = NextStep.objects.get(uuid=nextstep['uuid'])
+ step.position = counter
+ step.save()
+ counter += 1
+
+ def update_next_step(self, data):
+ step = NextStep.objects.get(uuid=request_data_mgr.get_ns_uuid())
+
+ if step.files != data['files']:
+ step.files = json.dumps(data['files'], ensure_ascii=False)
+ if data['duedate'] and data['duedate'] != step.due_date:
+ step.due_date = data['duedate']
+ if data['description'] and step.description != data['description']:
+ step.description = data['description']
+ if data['assigneesUuids'] != '':
+ for user in step.assignees.all():
+ step.assignees.remove(user)
+ for assigneesUuid in data['assigneesUuids']:
+ assigned_user = IceUserProfile.objects.get(uuid=assigneesUuid)
+ eng_team = Engagement.objects.get(uuid=request_data_mgr.get_eng_uuid()).engagement_team.all()
+ if (assigned_user in eng_team):
+ step.assignees.add(assigned_user)
+ step.save()
+ else:
+ logger.error(
+ "An attempt to edit a NS and assign a user who is not in the engagement team was conducted, user wasn't assigned!")
+ continue
+
+ step.last_updater = request_data_mgr.get_user()
+ step.last_update_time = timezone.now()
+ step.last_update_type = 'Edited'
+ step.save()
+
+ def set_next_step_status(self, attr=None, state=None):
+
+ step = NextStep.objects.get(uuid=request_data_mgr.get_ns_uuid())
+
+ if attr == 'state':
+ update_type = self.validate_state_transition(
+ request_data_mgr.get_user(), NextStepState[step.state], NextStepState[state])
+ step.state = state
+ step.last_updater = request_data_mgr.get_user()
+ step.last_update_time = timezone.now()
+ step.last_update_type = update_type
+ step.save()
+ if step.engagement:
+ activity_data = UpdateNextStepsActivityData(
+ step.last_update_type, request_data_mgr.get_user(), step.engagement)
+ bus_service.send_message(ActivityEventMessage(activity_data))
diff --git a/django/engagementmanager/service/user_service.py b/django/engagementmanager/service/user_service.py
new file mode 100755
index 0000000..8d6317e
--- /dev/null
+++ b/django/engagementmanager/service/user_service.py
@@ -0,0 +1,121 @@
+#
+# ============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.contrib.auth import get_user_model
+from sshpubkeys import SSHKey
+
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.models import IceUserProfile, Role, VF
+from engagementmanager.serializers import SuperThinIceUserProfileModelSerializerForSignals
+from engagementmanager.service.base_service import BaseSvc
+from engagementmanager.utils.cryptography import CryptographyText
+from engagementmanager.utils.activities_data import SSHKeyAddedActivityData
+from engagementmanager.utils.vvp_exceptions import VvpBadRequest
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.views_helper import checkAndModifyIfSSHNextStepExist, \
+ getFirstEngByUser, addUsersToEngTeam
+from engagementmanager.vm_integration import vm_client
+
+
+class UserService(BaseSvc):
+
+ def validate_ssh_key(self, sshkey):
+ ssh = SSHKey(sshkey)
+
+ try:
+ ssh.parse()
+ except Exception as e:
+ msg = """ssh provided by the user is invalid, type of exception: """ + \
+ str(e)
+ self.logger.error(msg)
+ msg = "Updating SSH Key failed due to invalid key."
+ raise VvpBadRequest(msg)
+
+ # remove comment from ssh key
+ # ssh.comment returns comment attached to key
+ if ssh.comment != None:
+ striped_key = sshkey.replace(ssh.comment, '').strip()
+ else:
+ striped_key = sshkey.strip()
+ try:
+ user_with_ssh = IceUserProfile.objects.get(
+ ssh_public_key__startswith=striped_key)
+ except IceUserProfile.DoesNotExist:
+ return True
+ except Exception as e:
+ self.logger.error(
+ "Exception thrown while looking for ssh - %s.", e)
+ msg = "Updating SSH Key failed."
+ raise Exception(msg)
+ else:
+ self.logger.debug(
+ "SSH key already taken by another user - uuid: %s", user_with_ssh.uuid)
+ msg = "Updating SSH Key failed due to invalid key."
+ raise VvpBadRequest(msg)
+
+ def setSSH(self, user, ssh, action):
+ user.ssh_public_key = ssh
+ checkAndModifyIfSSHNextStepExist(user)
+ eng = getFirstEngByUser(user)
+
+ activity_data = SSHKeyAddedActivityData(action, eng, user)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ def get_el_list(self):
+ el_role = Role.objects.get(name='el')
+ engagement_leads_users = IceUserProfile.objects.filter(role=el_role)
+ return SuperThinIceUserProfileModelSerializerForSignals(engagement_leads_users, many=True).data
+
+ def get_user_by_email(self, email):
+ UserModel = get_user_model()
+ try:
+ user = UserModel._default_manager.get(email=email)
+ except UserModel.DoesNotExist:
+ return None
+ return user
+
+ def addUserToEngAndFireProvisionVfSig(self, user_profile, inviteObj):
+ addUsersToEngTeam(inviteObj.engagement_uuid, [user_profile])
+ vfObj = VF.objects.get(engagement__uuid=inviteObj.engagement_uuid)
+ vm_client.fire_event_in_bg('send_provision_new_vf_event', vfObj)
+
+ def get_user_rgwa_secret(self):
+ secret = request_data_mgr.get_user().rgwa_secret_key
+ decoded_key = CryptographyText.decrypt(secret)
+ return decoded_key
diff --git a/django/engagementmanager/service/vf_service.py b/django/engagementmanager/service/vf_service.py
new file mode 100755
index 0000000..aa3a9d3
--- /dev/null
+++ b/django/engagementmanager/service/vf_service.py
@@ -0,0 +1,47 @@
+#
+# ============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 engagementmanager.models import VF
+from engagementmanager.service.base_service import BaseSvc
+
+
+class VFSvc(BaseSvc):
+
+ def get_vf_version(self, vf_uuid):
+ vf = VF.objects.get(uuid=vf_uuid)
+ return vf.version
diff --git a/django/engagementmanager/service/vfc_service.py b/django/engagementmanager/service/vfc_service.py
new file mode 100755
index 0000000..341cfc1
--- /dev/null
+++ b/django/engagementmanager/service/vfc_service.py
@@ -0,0 +1,112 @@
+#
+# ============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 bleach
+
+from engagementmanager.models import VFC, IceUserProfile, VF, Vendor
+from engagementmanager.service.base_service import BaseSvc
+
+
+class VFCSvc(BaseSvc):
+
+ def create_vfc(self, data):
+ msg = "OK"
+ vf = None
+ vfc = None
+ user = None
+ company = None
+ duplicateNames = []
+ duplicate = False
+ many = True
+ dict = {}
+ # Iterate through all the VFCs that are received from the user, if there's duplication -> check the VF, if it is the same ->duplicate = True
+ # If there's a duplication and the other VFCs trying to be created are not
+ # duplicated -> Many = True -> they would be successfully created any way
+ for i in range(len(data['vfcs'])):
+ dict.update(data['vfcs'][i])
+ # check if the VFC already exist (filter by name)
+ try:
+ vfc = VFC.objects.filter(name=dict['name'], external_ref_id=dict['external_ref_id'])
+ # if found VFC with same name and ref id
+ if (vfc.count() > 0):
+ for item in vfc:
+ if (item.vf.uuid == data['vf_uuid']):
+ if (not duplicate):
+ duplicate = True
+ duplicateNames.append(dict['name'])
+ # if found a similar VFC with name and ref_id, but VF is different (
+ # cannot use else, and raise, since the for has to check all vfcs that
+ # match - for example, 2 VFs with same vfc)
+ if not duplicate:
+ raise VFC.DoesNotExist
+ # didn't find any vfc with same name and ref_id
+ else:
+ raise VFC.DoesNotExist
+ # If the VFC Does not exist, then continue as usual and create it.
+ except VFC.DoesNotExist:
+ many = True # not used, unless there's a duplicate as well, just a helper
+
+ user = IceUserProfile.objects.get(email=data['creator']['email'])
+ vf = VF.objects.get(uuid=data['vf_uuid'])
+ # Check if the company that the user entered already exist.
+ try:
+ company = Vendor.objects.get(name=dict['company'])
+ except Vendor.DoesNotExist:
+ company = Vendor.objects.create(name=dict['company'], public=False)
+ company.save()
+ # create the VFC
+ vfc = VFC.objects.create(name=dict['name'], company=company, vf=vf,
+ creator=user, external_ref_id=dict['external_ref_id'])
+ if 'ice_mandated' in dict:
+ vfc.ice_mandated = dict['ice_mandated']
+ vfc.save()
+
+ dict = {}
+ if duplicate and many:
+ num = 1
+ for vfc_name in duplicateNames:
+ msg = msg + str(num) + ". The VFC " + vfc_name + \
+ " already exist, the VF that it is related to is: " + item.vf.name + "\n"
+ num += 1
+ msg = msg + "\nThe other VFCs were created succesfully\n"
+ self.logger.error(msg)
+ msg = bleach.clean(msg, tags=['a', 'b'])
+ return msg
+
+ def delete_vfc(self, vfc_uuid):
+ VFC.objects.get(uuid=vfc_uuid).delete()
diff --git a/django/engagementmanager/slack_client/__init__.py b/django/engagementmanager/slack_client/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/slack_client/__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/slack_client/api.py b/django/engagementmanager/slack_client/api.py
new file mode 100755
index 0000000..f006322
--- /dev/null
+++ b/django/engagementmanager/slack_client/api.py
@@ -0,0 +1,212 @@
+#
+# ============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 concurrent.futures
+from django.conf import settings
+from slacker import Slacker, Error
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
+
+
+class SlackClient(object):
+ """
+ ICE Slack API Client
+ """
+
+ def __init__(self):
+ """
+ Ice Slack client constructor ->
+ """
+ super(SlackClient, self).__init__()
+
+ # create the slack client
+ self.client = None
+ if settings.SLACK_API_TOKEN is not None and settings.SLACK_API_TOKEN != "":
+ try:
+ self.client = Slacker(settings.SLACK_API_TOKEN)
+ except Exception as exception:
+ logger.error('Unknown error while creating the a slack client: ' + str(exception))
+
+ # post a message via the Slack API
+ def trigger_slack_chat_post_message(self, to, message):
+ """
+ # Syntax for chat.post_message
+ def post_message(self, channel, text=None, username=None, as_user=None,
+ parse=None, link_names=None, attachments=None,
+ unfurl_links=None, unfurl_media=None, icon_url=None,
+ icon_emoji=None):
+ """
+ try:
+ # Send a message to a channel or a user
+ response = self.client.chat.post_message(to, message)
+ except Error as e:
+ logger.error('Invalid Slack API token was provided: ' + str(e))
+ except Exception as exception:
+ logger.error('Unknown error while posting a message to Slack: ' + str(exception))
+
+ # asynchronously post a message
+ def post_message(self, to, message):
+ """
+ Post a message to a channel or user
+ """
+ if self.client is None:
+ return None
+
+ if to and message:
+ logger.debug('Trigger Slack API - chat.post_message')
+ future = executor.submit(self.trigger_slack_chat_post_message, to, message)
+ logger.debug('Continuing after triggering the Slack API - chat.post_message')
+
+ # send slack message to the engagement channel
+ def update_engagement_channel(self, message, notify_channel=False):
+ prefix = ''
+ if notify_channel:
+ prefix = '<!channel> '
+ if settings.ENGAGEMENTS_CHANNEL:
+ # post to the engagement channel
+ self.post_message(settings.ENGAGEMENTS_CHANNEL, prefix + message)
+
+ # send slack message to the devops channel
+ def update_devops_channel(self, message, notify_channel=False):
+ prefix = ''
+ if notify_channel:
+ prefix = '<!channel> '
+ if settings.DEVOPS_CHANNEL:
+ # post to the engagement channel
+ self.post_message(settings.DEVOPS_CHANNEL, prefix + message)
+
+ # send slack message to a user
+ def send_message_to_user(self, user, message):
+ # send Slack message to the newly assigned user
+ if user and user.slack_handle:
+ self.post_message('@' + user.slack_handle, message)
+
+ # update reviewer or peer reviewer when a new engagement is created
+ def update_reviewer_or_peer_reviewer(self, engagement_manual_id, vf_name, user, old_user, notification_type='reviewer'):
+ # construct the Slack messages
+ user_message = 'You have been assigned as the _{}_ for the engagement _{}: {}_. '.format(
+ notification_type, engagement_manual_id, vf_name)
+ old_user_message_postfix = 'The assigned _{}_ is now _{}_.'.format(notification_type, user.full_name)
+
+ user_message_postfix = ""
+ old_user_message = ""
+ if old_user is not None:
+ user_message_postfix = 'The previously assigned _{}_ was _{}_ in case you need to reach out for questions.'.format(
+ notification_type, old_user.full_name)
+ old_user_message = 'You are no longer the assigned _{}_ for the engagement _{}: {}_. '.format(
+ notification_type, engagement_manual_id, vf_name)
+
+ # send Slack messages
+ self.send_message_to_user(user, user_message + user_message_postfix)
+ self.send_message_to_user(old_user, old_user_message + old_user_message_postfix)
+
+ # update the engagement channel when a new engagement is created
+ def update_engagement_channel_for_new_engagement(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, creator):
+ new_engagement_message = '_{}_ created a new engagement _{}: {}_. _{}_ was assigned as the reviewer and _{}_ as the peer reviewer'.format(
+ creator.full_name, engagement_manual_id, vf_name, reviewer.full_name, peer_reviewer.full_name)
+ self.update_engagement_channel(new_engagement_message, True)
+
+ # update reviewer, peer reviewer and the engagement channel when a new engagement is created
+ def send_slack_notifications_for_new_engagement(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, creator):
+ self.update_reviewer_or_peer_reviewer(engagement_manual_id, vf_name, reviewer, None, 'reviewer')
+ self.update_reviewer_or_peer_reviewer(engagement_manual_id, vf_name, peer_reviewer, None, 'peer reviewer')
+ self.update_engagement_channel_for_new_engagement(
+ engagement_manual_id, vf_name, reviewer, peer_reviewer, creator)
+
+ def send_slack_notifications_for_new_feedback(self, feedback, user):
+ new_feedback_message = 'Created a new Feedback by {} Description : {}.'.format(
+ user.full_name, feedback.description)
+ self.update_engagement_channel(new_feedback_message, True)
+ self.update_devops_channel(new_feedback_message, True)
+
+ # update the engagement channel when the stage is changed for an engagement
+ def update_for_change_of_the_engagement_stage(self, engagement_manual_id, vf_name, stage):
+ change_engagement_stage_message = 'The engagement _{}: {}_ was moved to the _{}_ stage.'.format(
+ engagement_manual_id, vf_name, stage)
+ self.update_engagement_channel(change_engagement_stage_message)
+
+ # update the engagement channel when an engagement is archived
+ def update_for_archived_engagement(self, engagement_manual_id, vf_name, reason):
+ archived_engagement_message = 'The engagement _{}: {}_ was archived because of this reason: _{}_.'.format(
+ engagement_manual_id, vf_name, reason)
+ self.update_engagement_channel(archived_engagement_message)
+
+ # update the reviewer and peer reviewer when the git repository is updated
+ def send_notifications_on_git_push(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, committed_files):
+ str_committed_files = "The following files was added or changed as part of the commit:\n\n- %s" % '\n- '.join(
+ committed_files)
+ message = 'The Git repository for the engagement _{}: {}_ in which you are assigned as a _{}_ was updated. ' + \
+ str_committed_files
+ self.send_message_to_user(reviewer, message.format(engagement_manual_id, vf_name, 'reviewer'))
+ self.send_message_to_user(peer_reviewer, message.format(engagement_manual_id, vf_name, 'peer_reviewer'))
+
+ # update the reviewer when the automation phase is completed for a checklist
+ def send_notification_to_reviewer_when_automation_completes(self, engagement_manual_id, vf_name, reviewer, checklist_name):
+ message = 'The automation phase completed for the checklist _{}_ under the engagement _{}: {}_. You can now start your review of it.'
+ self.send_message_to_user(reviewer, message.format(checklist_name, engagement_manual_id, vf_name))
+
+ # update the peer reviewer when the review phase is completed for a checklist
+ def send_notification_to_peer_reviewer_when_the_review_completes(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, checklist_name):
+ message = 'The review phase was completed by _{}_ for the checklist _{}_ under the engagement _{}: {}_. You can now start your peer review of it.'
+ self.send_message_to_user(peer_reviewer, message.format(
+ reviewer.full_name, checklist_name, engagement_manual_id, vf_name))
+
+ # update the admins when the review and peer reviews have been completed for a checklist
+ def send_notification_to_admins_when_the_peer_review_completes(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, admins, checklist_name):
+ message = 'The manual reviews have been completed by the reviewer _{}_ and peer reviewer _{}_ for the checklist _{}_ under the engagement _{}: {}_. It is now waiting for an approval by you or any other admin.'
+ for admin in admins:
+ self.send_message_to_user(admin, message.format(
+ reviewer.full_name, peer_reviewer.full_name, checklist_name, engagement_manual_id, vf_name))
+
+ # update reviewer when a checklist is approved
+ def send_notification_to_reviewer_when_approved(self, engagement_manual_id, vf_name, reviewer, checklist_name):
+ message = 'The checklist _{}_ under the engagement _{}: {}_ is now approved. You can now hand off the artifacts and close out the checklist.'
+ self.send_message_to_user(reviewer, message.format(checklist_name, engagement_manual_id, vf_name))
+
+ # update reviewer, peer reviewer and admins when a checklist is closed
+ def send_notifications_when_closed(self, engagement_manual_id, vf_name, reviewer, peer_reviewer, admins, checklist_name):
+ message = 'The checklist _{}_ under the engagement _{}: {}_ has now been closed and all the asssociated artifacts are validated. The reviewer was _{}_ and the peer reviewer was _{}_.'
+ self.send_message_to_user(reviewer, message.format(checklist_name, engagement_manual_id,
+ vf_name, reviewer.full_name, peer_reviewer.full_name))
+ self.send_message_to_user(peer_reviewer, message.format(
+ checklist_name, engagement_manual_id, vf_name, reviewer.full_name, peer_reviewer.full_name))
+ for admin in admins:
+ self.send_message_to_user(admin, message.format(checklist_name, engagement_manual_id,
+ vf_name, reviewer.full_name, peer_reviewer.full_name))
diff --git a/django/engagementmanager/sql-scripts/generate_excel_overview_sheet_procedure.sql b/django/engagementmanager/sql-scripts/generate_excel_overview_sheet_procedure.sql
new file mode 100755
index 0000000..79925be
--- /dev/null
+++ b/django/engagementmanager/sql-scripts/generate_excel_overview_sheet_procedure.sql
@@ -0,0 +1,203 @@
+--
+-- ============LICENSE_START==========================================
+-- org.onap.vvp/engagementmgr
+-- ===================================================================
+-- Copyright C 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.
+CREATE OR REPLACE FUNCTION generate_excel_overview_sheet(stage TEXT, keyword TEXT)
+RETURNS TABLE (name VARCHAR(200),
+ active_engagements INTEGER,
+ active_vfc_sum INTEGER,
+ intake_engagements INTEGER,
+ intake_vfc_sum INTEGER,
+ completed_engagements INTEGER,
+ completed_vfc_sum INTEGER,
+ total_engagements INTEGER,
+ total_vfc_sum INTEGER) AS $res$
+BEGIN
+ -- temp tables declarations:
+ CREATE TEMP TABLE result
+ (
+ name VARCHAR(200),
+ active_engagements INTEGER,
+ active_vfc_sum INTEGER,
+ intake_engagements INTEGER,
+ intake_vfc_sum INTEGER,
+ completed_engagements INTEGER,
+ completed_vfc_sum INTEGER,
+ total_engagements INTEGER,
+ total_vfc_sum INTEGER
+ ) ON COMMIT DROP;
+
+ CREATE TEMP TABLE filters
+ (
+ name VARCHAR(200),
+ value VARCHAR(200)
+ ) ON COMMIT DROP;
+
+ CREATE TEMP TABLE deployment_targets
+ (
+ deployment_target_uuid VARCHAR(200),
+ deployment_targets INTEGER
+ ) ON COMMIT DROP;
+
+ CREATE TEMP TABLE engagement_stages
+ (
+ engagement_stage VARCHAR(200),
+ total INTEGER
+ ) ON COMMIT DROP;
+
+ CREATE TEMP TABLE virtual_functions_componenets
+ (
+ name VARCHAR(200),
+ engagement_stage VARCHAR(200)
+ ) ON COMMIT DROP;
+
+ CREATE TEMP TABLE ecomp_releases
+ (
+ ecomp_release_uuid VARCHAR(200),
+ ecomp_release_name VARCHAR(200)
+ ) ON COMMIT DROP;
+
+ -- Handling filters
+ IF $1 = 'All' OR $1 = 'all' OR $1 IS NULL THEN stage := ''; ELSE stage := $1; END IF;
+ INSERT INTO filters VALUES('stage', stage);
+ IF $2 IS NULL THEN keyword := ''; ELSE keyword := $2; END IF;
+ INSERT INTO filters VALUES('keyword', keyword);
+
+ -- handling AIC (deployment targets) rows:
+ INSERT INTO deployment_targets
+ SELECT deployment_target_id, COUNT(deployment_target_id) AS total FROM ice_vf GROUP BY deployment_target_id;
+
+ -- Itearting throght each deployment:
+ DO $$
+ DECLARE
+ deployment record;
+ vf record;
+ ecomp record;
+ stage TEXT;
+ keyword TEXT;
+ BEGIN
+ -- Get the filters from outside:
+ SELECT value FROM filters WHERE name = 'stage' LIMIT 1 INTO stage;
+ SELECT value FROM filters WHERE name = 'keyword' LIMIT 1 INTO keyword;
+ FOR deployment IN SELECT * FROM deployment_targets LOOP
+ INSERT INTO engagement_stages
+ SELECT ice_engagement.engagement_stage, COUNT(ice_engagement.engagement_stage)
+ FROM ice_vf LEFT JOIN ice_engagement ON engagement_id = ice_engagement.uuid
+ WHERE ice_vf.deployment_target_id = deployment.deployment_target_uuid
+ AND ice_engagement.engagement_stage LIKE '%' || stage || '%' -- stage param filtering
+ AND (ice_engagement.engagement_manual_id LIKE '%' || keyword || '%' OR ice_vf.name LIKE '%' || keyword || '%') -- keyword param filtering
+ AND ice_engagement.engagement_stage IN ('Active', 'Intake', 'Completed')
+ GROUP BY ice_engagement.engagement_stage;
+
+ INSERT INTO virtual_functions_componenets
+ SELECT ice_vfc.name, ice_engagement.engagement_stage
+ FROM ice_vfc LEFT JOIN ice_vf ON ice_vfc.vf_id = ice_vf.uuid
+ LEFT JOIN ice_engagement ON ice_vf.engagement_id = ice_engagement.uuid
+ WHERE ice_vf.deployment_target_id = deployment.deployment_target_uuid
+ AND ice_engagement.engagement_stage LIKE '%' || stage || '%' -- stage param filtering
+ AND (ice_engagement.engagement_manual_id LIKE '%' || keyword || '%' OR ice_vf.name LIKE '%' || keyword || '%' OR ice_vfc.name LIKE '%' || keyword || '%') -- keyword param filtering
+ AND ice_engagement.engagement_stage IN ('Active', 'Intake', 'Completed');
+
+ --Insert the AIC row with its statistics:
+ INSERT INTO result VALUES
+ ((SELECT version FROM ice_deployment_target WHERE uuid = deployment.deployment_target_uuid LIMIT 1),
+ (SELECT total FROM engagement_stages where engagement_stage = 'Active' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Active'),
+ (SELECT total FROM engagement_stages where engagement_stage = 'Intake' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Intake'),
+ (SELECT total FROM engagement_stages where engagement_stage = 'Completed' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Completed'),
+ (SELECT SUM(total) FROM engagement_stages),
+ (SELECT COUNT(*) FROM virtual_functions_componenets)
+ );
+
+ --******************************************************************************************************
+ --Handling the ecomp release rows:
+ INSERT INTO ecomp_releases
+ SELECT DISTINCT ice_ecomp_release.uuid, ice_ecomp_release.name
+ FROM ice_vf LEFT JOIN ice_ecomp_release ON ice_ecomp_release.uuid = ice_vf.ecomp_release_id
+ WHERE ice_vf.deployment_target_id = deployment.deployment_target_uuid;
+
+ FOR ecomp IN SELECT * FROM ecomp_releases LOOP
+ --empty the temp tables:
+ DELETE FROM virtual_functions_componenets;
+ DELETE FROM engagement_stages;
+
+ INSERT INTO engagement_stages
+ SELECT ice_engagement.engagement_stage, COUNT(ice_engagement.engagement_stage)
+ FROM ice_vf LEFT JOIN ice_engagement ON engagement_id = ice_engagement.uuid
+ WHERE ice_vf.deployment_target_id = deployment.deployment_target_uuid AND ice_vf.ecomp_release_id = ecomp.ecomp_release_uuid
+ AND ice_engagement.engagement_stage LIKE '%' || stage || '%'--stage param filtering
+ AND (ice_engagement.engagement_manual_id LIKE '%' || keyword || '%' OR ice_vf.name LIKE '%' || keyword || '%') --keyword param filtering
+ AND ice_engagement.engagement_stage IN ('Active', 'Intake', 'Completed')
+ GROUP BY ice_engagement.engagement_stage;
+
+ INSERT INTO virtual_functions_componenets
+ SELECT ice_vfc.name, ice_engagement.engagement_stage
+ FROM ice_vfc LEFT JOIN ice_vf ON ice_vfc.vf_id = ice_vf.uuid
+ LEFT JOIN ice_engagement ON ice_vf.engagement_id = ice_engagement.uuid
+ WHERE ice_vf.deployment_target_id = deployment.deployment_target_uuid AND ice_vf.ecomp_release_id = ecomp.ecomp_release_uuid
+ AND ice_engagement.engagement_stage LIKE '%' || stage || '%'--stage param filtering
+ AND (ice_engagement.engagement_manual_id LIKE '%' || keyword || '%' OR ice_vf.name LIKE '%' || keyword || '%' OR ice_vfc.name LIKE '%' || keyword || '%') -- keyword param filtering
+ AND ice_engagement.engagement_stage IN ('Active', 'Intake', 'Completed');
+
+ --Insert the ecomp release row with its statistics:
+ INSERT INTO result VALUES
+ (' >>' || ecomp.ecomp_release_name,
+ (SELECT total FROM engagement_stages where engagement_stage = 'Active' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Active'),
+ (SELECT total FROM engagement_stages where engagement_stage = 'Intake' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Intake'),
+ (SELECT total FROM engagement_stages where engagement_stage = 'Completed' LIMIT 1),
+ (SELECT COUNT(*) FROM virtual_functions_componenets WHERE engagement_stage = 'Completed'),
+ (SELECT SUM(total) FROM engagement_stages),
+ (SELECT COUNT(*) FROM virtual_functions_componenets)
+ );
+ END LOOP;
+ --******************************************************************************************************
+
+ --empty the temp tables:
+ DELETE FROM virtual_functions_componenets;
+ DELETE FROM engagement_stages;
+ DELETE FROM ecomp_releases;
+ END LOOP;
+ END $$;
+
+ RETURN QUERY SELECT * FROM result;
+END;
+$res$
+LANGUAGE 'plpgsql' VOLATILE;
diff --git a/django/engagementmanager/templatetags/__init__.py b/django/engagementmanager/templatetags/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/templatetags/__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/templatetags/vvptags.py b/django/engagementmanager/templatetags/vvptags.py
new file mode 100755
index 0000000..1a6a0ee
--- /dev/null
+++ b/django/engagementmanager/templatetags/vvptags.py
@@ -0,0 +1,48 @@
+#
+# ============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.template import Library
+
+from engagementmanager.utils.constants import TemplatesConstants
+
+register = Library()
+
+
+@register.simple_tag
+def get_templates_constants(name):
+ return TemplatesConstants.context[name]
diff --git a/django/engagementmanager/tests/__init__.py b/django/engagementmanager/tests/__init__.py
new file mode 100755
index 0000000..1726c13
--- /dev/null
+++ b/django/engagementmanager/tests/__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/tests/test_access_credentials.py b/django/engagementmanager/tests/test_access_credentials.py
new file mode 100755
index 0000000..73d427c
--- /dev/null
+++ b/django/engagementmanager/tests/test_access_credentials.py
@@ -0,0 +1,175 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+import json
+from boto.s3.connection import S3Connection, OrdinaryCallingFormat
+from django.conf import settings
+from wheel.signatures import assertTrue
+from django.utils import timezone
+from engagementmanager.utils.constants import Constants
+from engagementmanager.vm_integration import vm_client
+from validationmanager.rados.rgwa_client import RGWAClient
+from validationmanager.tests.test_rgwa_client_factory import TestRGWAClientFactory
+
+
+class ActivateTestCase(TestBaseEntity):
+
+ def childSetup(self): # Variables to use in this class.
+ self.s3_host = '10.252.0.21' # settings.AWS_S3_HOST
+ self.s3_port = 8080 # settings.AWS_S3_PORT
+
+ self.urlStr = self.urlPrefix + "signup/"
+ self.createDefaultRoles()
+ uuid, vendor = self.creator.createVendor(Constants.service_provider_company_name)
+ self.activation_token_time = timezone.now()
+ self.activation_token_time = self.activation_token_time.replace(
+ 2012, 1, 2, 13, 48, 25)
+ print("This is the time that is going to be added to expiredTokenUser: " +
+ str(self.activation_token_time))
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ self.new_user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+ self.params = '{"company":"' + str(self.user.company) + '","full_name":"' + self.user.full_name + '","email":"' + self.user.email + '","phone_number":"' + self.user.phone_number + \
+ '","password":"' + self.user.user.password + '","regular_email_updates":"' + \
+ str(self.user.regular_email_updates) + \
+ '","is_service_provider_contact":"' + str(self.user.is_service_provider_contact) + '"}'
+ self.userToken = self.loginAndCreateSessionToken(self.user)
+ self.new_user_token = self.loginAndCreateSessionToken(self.new_user)
+
+ def test_validate_rgwauser_created_after_Activation(self):
+ if settings.IS_SIGNAL_ENABLED:
+ vm_client.fire_event_in_bg(
+ 'send_create_user_in_rgwa_event', self.user)
+ rgwa = TestRGWAClientFactory.admin()
+ rgwa_user = rgwa.get_user(self.user.full_name)
+ if rgwa_user is None:
+ print("Test Failed!")
+ else:
+ access_key = rgwa_user['access_key']
+ print("######access_key#################= ", access_key)
+ secret_key = rgwa_user['secret_key']
+ print("######secret_key#################= ", secret_key)
+ self.assertTrue(access_key and secret_key != None)
+ print("#################################")
+ print("Test PASS!")
+ self.printTestName("Test ended")
+
+
+# Whenever a new user is configured, we should create a RadosGW user for them.
+# If unspecified, the access keys are generated on the server and returned here
+# in the response.
+ def testCreateAndGetRgwaUser(self):
+ if settings.IS_SIGNAL_ENABLED:
+ base_url = 'http://{S3_HOST}:{S3_PORT}/admin'.format(
+ S3_HOST=self.s3_host, # settings.AWS_S3_HOST,
+ S3_PORT=self.s3_port, # settings.AWS_S3_PORT,
+ )
+ admin_conn = RGWAClient(base_url)
+ print("base_url=" + base_url)
+ print("S3_HOST = " + self.s3_host)
+ print("s3_port =" + str(self.s3_port))
+ print("admin_conn= ", admin_conn)
+ username = self.randomGenerator("randomString")
+ print("username", username)
+ new_user = admin_conn.create_user(
+ uid=username, display_name='User "%s"' % username)
+ print("new_user = " + str(new_user))
+ self.assertTrue(new_user['user_id'] != None)
+ get_user = admin_conn.get_user(new_user['user_id'])
+ self.assertTrue(new_user['user_id'] == get_user['user_id'])
+
+ def testCreateAndGetRgwaBucket(self):
+ if settings.IS_SIGNAL_ENABLED:
+ s3aws_access_key_id = settings.AWS_ACCESS_KEY_ID
+ s3aws_secret_access_key = settings.AWS_SECRET_ACCESS_KEY
+ print("s3aws_access_key_id=" + s3aws_access_key_id)
+ print("s3aws_secret_access_key=" + s3aws_secret_access_key)
+ print("S3_HOST = " + self.s3_host)
+ print("s3_port =" + str(self.s3_port))
+
+ boto_conn = S3Connection(host=self.s3_host,
+ port=self.s3_port,
+ aws_access_key_id=s3aws_access_key_id,
+ aws_secret_access_key=s3aws_secret_access_key,
+ calling_format=OrdinaryCallingFormat(),
+ is_secure=False,
+ )
+ boto_conn.num_retries = 0
+ bucketname = self.randomGenerator("randomString").lower()
+ new_bucket = boto_conn.create_bucket(bucketname)
+ assertTrue(new_bucket != None)
+ print("new_bucket = " + str(new_bucket))
+ bucket = boto_conn.get_bucket(bucketname)
+ print("bucket = " + str(bucket))
+ bucket_acl = bucket.get_acl()
+ print("bucket_acl = " + str(bucket_acl))
+
+ def testGetSecretKey(self):
+ vm_client.send_create_user_in_rgwa_event(self.user)
+ urlStr = self.urlPrefix + 'users/account/rgwa/'
+ print("urlStr of get secret key",urlStr)
+ self.printTestName("testGetSecretKey [Start]")
+ response = self.c.get(urlStr, data={}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.userToken})
+ print('Got response : ' + str(response.status_code))
+ dict_response = json.loads(response.content)
+ print("api response",dict_response)
+ self.assertTrue(dict_response["rgwa_secret_key"] is not None)
+ self.printTestName("testGetSecretKey [End]")
+
+ def testNegativeGetSecretKeyInvalidToken(self):
+ vm_client.send_create_user_in_rgwa_event(self.user)
+ urlStr = self.urlPrefix + 'users/account/rgwa/'
+ print("urlStr of get secret key",urlStr)
+ self.printTestName("testGetSecretKey [Start]")
+ response = self.c.get(urlStr, data={}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': 'token' + self.new_user_token})
+ print('Got response : ' + str(response.status_code))
+ dict_response = json.loads(response.content)
+ print("api response",dict_response)
+ self.assertTrue(dict_response[
+ "detail"] == 'You must authenticate in order to ' +
+ 'perform this action: Authentication credentials were not provided.')
+ self.printTestName("testGetSecretKey [End]")
diff --git a/django/engagementmanager/tests/test_activation.py b/django/engagementmanager/tests/test_activation.py
new file mode 100755
index 0000000..a845373
--- /dev/null
+++ b/django/engagementmanager/tests/test_activation.py
@@ -0,0 +1,173 @@
+#
+# ============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.utils import timezone
+
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class ActivateTestCase(TestBaseEntity):
+
+ def childSetup(self): # Variables to use in this class.
+ self.urlStr = self.urlPrefix + "signup/"
+ self.createDefaultRoles()
+ uuid, vendor = self.creator.createVendor(Constants.service_provider_company_name)
+ self.activation_token_time = timezone.now()
+ self.activation_token_time = self.activation_token_time.replace(2012, 1, 2, 13, 48, 25)
+ print("This is the time that is going to be added to expiredTokenUser: " + str(self.activation_token_time))
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, False)
+ self.expiredTokenUser = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, False, activation_token_create_time=self.activation_token_time)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+ self.params = '{"company":"' + str(self.user.company) + '","full_name":"' + self.user.full_name + '","email":"' + self.user.email + '","phone_number":"' + self.user.phone_number + \
+ '","password":"' + self.user.user.password + '","regular_email_updates":"' + \
+ str(self.user.regular_email_updates) + '","is_service_provider_contact":"' + str(self.user.is_service_provider_contact) + '"}'
+
+ def testActivation(self):
+ print("\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ print(" Test started: user activation")
+ print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ for a in range(2):
+ print("###############################################")
+ print(" Before activation, Current User's activation mode: " + str(self.user.user.is_active))
+ for a in range(2):
+ print("###############################################")
+ user_uuid = self.user.uuid
+ print(self.urlPrefix + 'activate/' + str(user_uuid) + '/' + str(self.user.user.activation_token))
+ print("Activating through the activate_user function: (simulating a GET request)")
+ response = self.c.get(self.urlPrefix + 'activate/' + str(user_uuid) +
+ '/' + str(self.user.user.activation_token))
+ print("Response: " + str(response.status_code))
+ self.user.refresh_from_db()
+ for a in range(5):
+ print("******")
+ for a in range(2):
+ print("###############################################")
+ print(" Current User's activation mode: " + str(self.user.user.is_active))
+ for a in range(2):
+ print("###############################################")
+ print("Current User's activation mode: " + str(self.user.user.is_active))
+ if (self.user.user.is_active != True):
+ for a in range(2):
+ print("###############################################")
+ print(" User's activation failed: is_active != True..")
+ for a in range(2):
+ print("###############################################")
+ else:
+ for a in range(2):
+ print("#################################")
+ print(" User's is activated ")
+ for a in range(2):
+ print("#################################")
+ self.printTestName("Test ended")
+
+ def testExpiredTokenActivation(self):
+ print("\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ print("Negative test started: Expired token activation")
+ print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ for a in range(2):
+ print("###############################################")
+ print("Current User's activation mode: " + str(self.user.user.is_active))
+ for a in range(2):
+ print("###############################################")
+
+ urlStrToGET = self.urlPrefix + "users/"
+ user_uuid = self.expiredTokenUser.uuid
+ print("\n\nA user with was pre-initiated with old token creation time : 2012-01-02 13:48:25.299000+00:00\n\n")
+ response = self.c.get(self.urlPrefix + 'activate/' + str(user_uuid) + '/' +
+ str(self.expiredTokenUser.user.activation_token))
+ self.user.refresh_from_db()
+ for a in range(2):
+ print("###############################################")
+ print(" Current User's activation mode: " + str(self.expiredTokenUser.user.is_active))
+ for a in range(2):
+ print("###############################################")
+ print("\n\n")
+ if (self.expiredTokenUser.user.activation_token != True):
+ for a in range(2):
+ print("###############################################")
+ print("Test Success!")
+ for a in range(2):
+ print("###############################################")
+ else:
+ for a in range(2):
+ print("###############################################")
+ print("Test Failed!")
+ for a in range(2):
+ print("###############################################")
+
+ def testUnMatchingTokenActivation(self):
+ print("\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ print("Negative test started: Un-matching token activation test")
+ print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ for a in range(2):
+ print("###############################################")
+ print("Current User's activation mode: " + str(self.user.user.is_active))
+ for a in range(2):
+ print("###############################################")
+
+ urlStrToGET = self.urlPrefix + "users/"
+ user_uuid = self.expiredTokenUser.uuid
+ print("\n\n Trying to activate a user with an unmatching token")
+ response = self.c.get(self.urlPrefix + 'activate/' + str(self.user.uuid) +
+ '/' + str(self.expiredTokenUser.user.activation_token))
+ self.user.refresh_from_db()
+ for a in range(2):
+ print("###############################################")
+ print(" Current User's activation mode: " + str(self.expiredTokenUser.user.is_active))
+ for a in range(2):
+ print("###############################################")
+ print("\n\n")
+ if (self.expiredTokenUser.user.activation_token != True):
+ for a in range(2):
+ print("###############################################")
+ print("Test Success!")
+ for a in range(2):
+ print("###############################################")
+ else:
+ for a in range(2):
+ print("###############################################")
+ print("Test Failed!")
+ for a in range(2):
+ print("###############################################")
diff --git a/django/engagementmanager/tests/test_activities.py b/django/engagementmanager/tests/test_activities.py
new file mode 100755
index 0000000..9e83e9f
--- /dev/null
+++ b/django/engagementmanager/tests/test_activities.py
@@ -0,0 +1,125 @@
+#
+# ============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 engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.models import Vendor
+from engagementmanager.utils.activities_data import UserJoinedEngagementActivityData
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.apps import bus_service
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class ActivityTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+ # Create a user with role el
+ vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.el_user = self.creator.createUser(vendor, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ vendor = Vendor.objects.get(name='Other')
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ self.pruser = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(self.randomGenerator(
+ "randomString"), self.randomGenerator("randomString"), None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.pruser
+ self.engagement.save()
+
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, vendor)
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def testCreateActivity(self):
+ urlStr = self.urlPrefix + 'engagement/${uuid}/activities/'
+ logger.debug("Starting Activity & notification creation test")
+
+ logger.debug("Starting activity test: User joined")
+ vendor = Vendor.objects.get(name='Other')
+ randomUser = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ self.engagement.engagement_team.add(randomUser)
+ self.engagement.save()
+
+ logger.debug(
+ "created a new user & added them to the engagement team, going to create the activity and consider it as a notification")
+ usersList = []
+ usersList.append(randomUser)
+ activity_data = UserJoinedEngagementActivityData(self.vf, usersList, self.engagement)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+ logger.debug(
+ "activity & notification created successfully, please manually verify that an email was sent / MX server tried to send")
+ logger.debug("Ended activity test: User joined ")
+
+ logger.debug("Starting pullActivities test")
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ content = response.content
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ logger.debug("Got content : " + str(content))
+ if (status != 200):
+ logger.error("Got response : " + str(status) + " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Ended pullActivities test ")
+
+ logger.debug("Starting activity test: delete user")
+ logger.debug("Verify that the 'User Joined' activity is deleted from the recent activities")
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ content = response.content
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ logger.debug("Got content : " + str(content))
+ if (status != 200):
+ logger.error("Got response : " + str(status) + " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Ended activity test: delete user ")
diff --git a/django/engagementmanager/tests/test_add_contact.py b/django/engagementmanager/tests/test_add_contact.py
new file mode 100755
index 0000000..c1af553
--- /dev/null
+++ b/django/engagementmanager/tests/test_add_contact.py
@@ -0,0 +1,141 @@
+#
+# ============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
+import random
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.models import Vendor
+from engagementmanager.utils.constants import Constants
+
+
+class TestAddContactTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator(
+ "main-vendor-email"), '55501000199', 'el user', self.el, True)
+
+ self.inviter = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator(
+ "main-vendor-email"), '55501000199', 'inviter user', self.standard_user, True)
+
+ self.reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator(
+ "main-vendor-email"), '55501000199', 'reviewer user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator(
+ "main-vendor-email"), '55501000199', 'peer-reviewer user', self.el, True)
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(
+ '123456789', 'Validation', None)
+ self.engagement.reviewer = self.reviewer
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.save()
+ self.engagement.engagement_team.add(self.inviter, self.el_user)
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"), self.engagement,
+ self.deploymentTarget, False, Vendor.objects.get(name='Other'))
+
+ self.urlStr = self.urlPrefix + "add-contact/"
+ self.data = dict()
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+
+ def initBody(self):
+ self.data['company'] = Vendor.objects.get(name=Constants.service_provider_company_name).name
+ self.data['full_name'] = "full name"
+ self.data['email'] = self.randomGenerator("main-vendor-email")
+ self.data['phone_number'] = "12345"
+
+ def addContact(self, expectedStatus=200):
+ self.contactData = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.post(self.urlStr, self.contactData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ def createContactUser(self):
+ self.contact = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.data['email'],
+ self.data['phone_number'], self.data['full_name'], self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.contact.uuid))
+ print('Full Name: ' + self.contact.full_name)
+ print('-----------------------------------------------------')
+
+ ### TESTS ###
+
+ def testAddContactForNonExistingContact(self):
+ self.initBody()
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.data['email'] = self.randomGenerator("main-vendor-email")
+ self.addContact()
+
+ def testAddContactForExistingContactAndEngUuid(self):
+ self.initBody()
+ self.createContactUser()
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.addContact(200)
+
+ def testNegativeAddContactForNonExistingContact(self):
+ self.initBody()
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.data['email'] = None
+ print("Negative test: removing mandatory field email --> Should fail on 400")
+ self.addContact(400)
+
+ def testNegativeAddContactForExistingContactAndFakeEngUUID(self):
+ self.initBody()
+ self.createContactUser()
+ self.data['eng_uuid'] = "FakeUuid"
+ print("Negative test: Non existing engagement UUID --> Should fail on 500")
+ self.addContact(401)
diff --git a/django/engagementmanager/tests/test_add_feedback.py b/django/engagementmanager/tests/test_add_feedback.py
new file mode 100755
index 0000000..33382aa
--- /dev/null
+++ b/django/engagementmanager/tests/test_add_feedback.py
@@ -0,0 +1,105 @@
+#
+# ============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
+import random
+
+from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.models import Vendor
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+class TestAddContactTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"), '55501000199', 'reviewer user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(
+ '123456789', 'Validation', None)
+ self.engagement.reviewer = self.reviewer
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.save()
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"), self.engagement,
+ self.deploymentTarget, False, Vendor.objects.get(name='Other'))
+
+ self.urlStr = self.urlPrefix + "add-feedback/"
+ self.data = dict()
+ self.token = self.loginAndCreateSessionToken(self.reviewer)
+
+ def initBody(self):
+ self.data['description'] = Vendor.objects.get(
+ name=Constants.service_provider_company_name).name + "ruslan gafiulin"
+
+ def addFeedback(self, expectedStatus=HTTP_200_OK):
+ self.feedbackData = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.post(self.urlStr, self.feedbackData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ ### TESTS ###
+
+ def testAddFeedbackForNonExistingContact(self):
+ self.initBody()
+ self.data['description'] = str(self.engagement.uuid)
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.addFeedback()
+
+ def testNegativeAddFeedbackWithoutDescription(self):
+ self.initBody()
+ self.data['description'] = ""
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.addFeedback(HTTP_400_BAD_REQUEST)
diff --git a/django/engagementmanager/tests/test_add_next_step_to_checklist.py b/django/engagementmanager/tests/test_add_next_step_to_checklist.py
new file mode 100755
index 0000000..e88cddd
--- /dev/null
+++ b/django/engagementmanager/tests/test_add_next_step_to_checklist.py
@@ -0,0 +1,157 @@
+#
+# ============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 uuid import uuid4
+
+from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED
+
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class TestAddNextStepToChecklistTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role el
+ self.peer_reviewer_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ self.user2 = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"), '55501000199', 'user', self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user2.uuid))
+ print('Full Name: ' + self.user2.full_name)
+ print('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement('123456789', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.engagement_team.add(self.el_user)
+ self.engagement.peer_reviewer = self.peer_reviewer_user
+ self.engagement.save()
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+ print('-----------------------------------------------------')
+ print('Created VF:')
+ print('UUID: ' + str(self.vf.uuid))
+ print('-----------------------------------------------------')
+
+ self.template = self.creator.createDefaultCheckListTemplate()
+ self.data = dict()
+ self.data['checkListName'] = "ice checklist for test"
+ self.data['checkListTemplateUuid'] = str(self.template.uuid)
+ self.data['checkListAssociatedFiles'] = []
+ for i in range(0, 2):
+ self.data['checkListAssociatedFiles'].append("file" + str(i))
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ self.clUrlStr = self.urlPrefix + "engagement/@eng_uuid/checklist/new/"
+ self.checklist = self.c.post(self.clUrlStr.replace("@eng_uuid", str(self.engagement.uuid)),
+ datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+
+ self.urlStr = self.urlPrefix + "engagement/@eng_uuid/checklist/@checklist_uuid/nextstep/"
+ self.nextStepList = []
+
+ def initBody(self):
+ assigneesData = [str(self.el_user.uuid), str(self.user2.uuid)]
+ files = ["f1", "f2"]
+ self.data['assigneesUuids'] = assigneesData
+ self.data['description'] = "Good Bye Norma Jin"
+ self.data['files'] = files
+ self.data['duedate'] = "2016-12-01"
+ self.nextStepList.append(self.data)
+
+ assigneesData = [str(self.el_user.uuid)]
+ files = ["f5"]
+ self.data['assigneesUuids'] = assigneesData
+ self.data['description'] = "Don't cry for me Argentina"
+ self.data['files'] = files
+ self.data['duedate'] = "2017-06-28"
+ self.nextStepList.append(self.data)
+
+ def testAddNextStepForCheckListPositive(self):
+ self.initBody()
+ self.nextStepList = json.dumps(self.nextStepList, ensure_ascii=False)
+ self.urlStr = self.urlStr.replace("@checklist_uuid", json.loads(self.checklist.content)[
+ 'uuid']).replace("@eng_uuid", str(self.engagement.uuid))
+ response = self.c.post(self.urlStr, self.nextStepList, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ return response
+
+ def testAddNextStepForCheckListNegative(self):
+ self.initBody()
+ self.nextStepList = json.dumps(self.nextStepList, ensure_ascii=False)
+ self.urlStr = self.urlStr.replace("@checklist_uuid", json.loads(
+ self.checklist.content)['uuid']).replace("@eng_uuid", str(uuid4()))
+ response = self.c.post(self.urlStr, self.nextStepList, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('------------------------------> Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ return response
diff --git a/django/engagementmanager/tests/test_audit_log_and_decision_api.py b/django/engagementmanager/tests/test_audit_log_and_decision_api.py
new file mode 100755
index 0000000..42395ae
--- /dev/null
+++ b/django/engagementmanager/tests/test_audit_log_and_decision_api.py
@@ -0,0 +1,375 @@
+#
+# ============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 uuid import uuid4
+from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST,\
+ HTTP_401_UNAUTHORIZED, HTTP_500_INTERNAL_SERVER_ERROR,\
+ HTTP_405_METHOD_NOT_ALLOWED
+from engagementmanager.models import Vendor, Checklist, ChecklistAuditLog, ChecklistDecision, ChecklistLineItem, ChecklistSection
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import CheckListLineType, CheckListDecisionValue, CheckListState, Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class AuditLogAndDecisionAPITest(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs', 'Other'])
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"), '12323245435', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # For negative tests
+ self.user = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name),
+ self.randomGenerator("main-vendor-email"), '12323245435', 'user', self.standard_user, True)
+
+ self.template = self.creator.createDefaultCheckListTemplate()
+ self.engagement = self.creator.createEngagement(
+ uuid4(), 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.save()
+ self.engagement.engagement_team.add(self.el_user, self.user)
+ self.clbodydata = dict()
+ self.initCLBody()
+ self.auditdata = dict()
+ self.checklist = Checklist.objects.create(uuid=uuid4(), name=self.clbodydata['checkListName'], validation_cycle=1, associated_files=self.clbodydata[
+ 'checkListAssociatedFiles'], engagement=self.engagement, template=self.template, creator=self.el_user, owner=self.el_user)
+ self.section = ChecklistSection.objects.create(uuid=uuid4(), name=self.randomGenerator("randomString"), weight=1.0, description=self.randomGenerator(
+ "randomString"), validation_instructions=self.randomGenerator("randomString"), template=self.template)
+ self.line_item = ChecklistLineItem.objects.create(uuid=uuid4(), name=self.randomGenerator("randomString"), weight=1.0, description=self.randomGenerator(
+ "randomString"), line_type=CheckListLineType.auto.name, validation_instructions=self.randomGenerator("randomString"), template=self.template, section=self.section) # @UndefinedVariable
+ self.decision = ChecklistDecision.objects.create(
+ uuid=uuid4(), checklist=self.checklist, template=self.template, lineitem=self.line_item)
+ self.section.save()
+ self.line_item.save()
+ self.decision.save()
+ self.checklist.save()
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ def initCLBody(self):
+ self.clbodydata['checkListName'] = "ice-checklist-for-test"
+ self.clbodydata['checkListTemplateUuid'] = str(self.template.uuid)
+ self.clbodydata[
+ 'checkListAssociatedFiles'] = "[\"file0/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\", \"file1/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\", \"file2/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\"]"
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def testCreateAuditLogViaChecklistPositive(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Create AuditLog Via Checklist")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/@cl_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+ self.auditdata['description'] = "description text"
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_200_OK))
+
+ check = True
+ try:
+ ChecklistAuditLog.objects.get(checklist=self.checklist)
+ except ChecklistAuditLog.DoesNotExist:
+ check = False
+
+ if (response.status_code == HTTP_200_OK and check):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testCreateAuditLogViaChecklistNegativeEmptyDescription(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Negative Test started: Create AuditLog Via Checklist with empty description")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/@cl_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+
+ self.auditdata['description'] = ""
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_400_BAD_REQUEST))
+
+ if (response.status_code == HTTP_400_BAD_REQUEST):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+
+ def testCreateAuditLogViaChecklistNegativeBadCLUuid(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Negative Test started: Create AuditLog Via Checklist with bad CL uuid")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/@cl_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+
+ self.auditdata['description'] = "description text"
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@cl_uuid", str(uuid4())),
+ datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_500_INTERNAL_SERVER_ERROR))
+
+ if (response.status_code == HTTP_500_INTERNAL_SERVER_ERROR):
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+
+ self.assertEqual(response.status_code, HTTP_500_INTERNAL_SERVER_ERROR)
+
+ def testCreateAuditLogViaDecisionPositive(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Create AuditLog Via Decision")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+
+ self.auditdata['description'] = "description text"
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_200_OK))
+
+ check = ChecklistAuditLog.objects.get(decision=self.decision)
+ if (response.status_code == HTTP_200_OK and check):
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testCreateAuditLogViaDecisionNegativeEmptyDescription(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Negative Test started: Create AuditLog Via Decision with empty description")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+
+ self.auditdata['description'] = ""
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_400_BAD_REQUEST))
+
+ if (response.status_code == HTTP_400_BAD_REQUEST):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+
+ def testCreateAuditLogViaDecisionNegativeBadCLUuid(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Negative Test started: Create AuditLog Via Decision with bad Decision uuid")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid/auditlog/"
+
+ logger.debug("Creating a checklist")
+
+ self.auditdata['description'] = "description text"
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.post(self.urlStr.replace("@decision_uuid", str(uuid4())), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_400_BAD_REQUEST))
+
+ if (response.status_code == HTTP_400_BAD_REQUEST):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ def testSetDecisionPositive(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Set decision's value to approved")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ logger.debug("Creating a checklist")
+
+ self.checklist.state = CheckListState.review.name # @UndefinedVariable
+ self.checklist.owner = self.el_user
+ self.checklist.save()
+ # @UndefinedVariable
+ self.auditdata['value'] = CheckListDecisionValue.approved.name
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.put(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_200_OK))
+
+ check = ChecklistDecision.objects.get(checklist=self.checklist)
+ if (response.status_code == HTTP_200_OK and check.review_value == 'approved'):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testSetDecisionNegativeOwnerDifferentThanUser(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Negative Test started: Owner Different Than User")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ logger.debug("Creating a checklist")
+
+ self.checklist.state = CheckListState.review.name # @UndefinedVariable
+ self.checklist.owner = self.user
+ self.checklist.save()
+ # @UndefinedVariable
+ self.auditdata['value'] = CheckListDecisionValue.approved.name
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.put(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_401_UNAUTHORIZED))
+
+ if (response.status_code == HTTP_401_UNAUTHORIZED):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ def testSetDecisionNegativeInvalidDecisionValue(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Negative Test started: Invalid Decision Value")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ logger.debug("Creating a checklist")
+
+ self.checklist.state = CheckListState.review.name # @UndefinedVariable
+ self.checklist.owner = self.el_user
+ self.checklist.save()
+ self.auditdata['value'] = self.randomGenerator("randomString")
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.put(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_400_BAD_REQUEST))
+
+ if (response.status_code == HTTP_400_BAD_REQUEST):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+
+ def testSetDecisionNegativeInvalidChecklistState(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Negative Test started: Invalid checklist state")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ logger.debug("Creating a checklist")
+
+ self.checklist.state = self.randomGenerator(
+ "randomString") # @UndefinedVariable
+ self.checklist.owner = self.el_user
+ self.checklist.save()
+ # @UndefinedVariable
+ self.auditdata['value'] = CheckListDecisionValue.approved.name
+ datajson = json.dumps(self.auditdata, ensure_ascii=False)
+
+ response = self.c.put(self.urlStr.replace("@decision_uuid", str(self.decision.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Got response : ' + str(response.status_code) +
+ " Expecting " + str(HTTP_400_BAD_REQUEST))
+
+ if (response.status_code == HTTP_400_BAD_REQUEST):
+ self.loggerTestFailedOrSucceded(True)
+ self.assertEqual(response.status_code, HTTP_400_BAD_REQUEST)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, HTTP_405_METHOD_NOT_ALLOWED)
diff --git a/django/engagementmanager/tests/test_auth_service.py b/django/engagementmanager/tests/test_auth_service.py
new file mode 100755
index 0000000..b61de8d
--- /dev/null
+++ b/django/engagementmanager/tests/test_auth_service.py
@@ -0,0 +1,244 @@
+#
+# ============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 engagementmanager.models import Vendor
+from engagementmanager.service.authorization_service import AuthorizationService, Permissions
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+
+
+class TestAuthService(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+
+ self.admin_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail,
+ '55501000199', 'admin user', self.admin, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.admin_user.uuid))
+ print('Full Name: ' + self.admin_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.peer_reviewer.uuid))
+ print('Full Name: ' + self.peer_reviewer.full_name)
+ print('-----------------------------------------------------')
+
+ # Create another EL
+ self.another_el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user2', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.another_el_user.uuid))
+ print('Full Name: ' + self.another_el_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user with SSH key
+ self.user_with_ssh = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'ssh user', self.standard_user, True, 'just-a-fake-ssh-key')
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user_with_ssh.uuid))
+ print('Full Name: ' + self.user_with_ssh.full_name)
+ print('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.save()
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with team with SSH Key
+ self.engagement_ssh = self.creator.createEngagement('just-another-fake-uuid', 'Validation', None)
+ self.engagement_ssh.engagement_team.add(self.user_with_ssh, self.el_user)
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_ssh.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with Main Contact
+ self.engagement_with_contact = self.creator.createEngagement('yet-just-another-fake-uuid', 'Validation', None)
+ self.engagement_with_contact.engagement_team.add(self.user_with_ssh, self.el_user)
+ self.engagement_with_contact.contact_user = self.user_with_ssh
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_with_contact.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with Main Contact
+ self.engagement_4_createNS = self.creator.createEngagement('yet-just-another-fake-uuid2', 'Validation', None)
+ self.engagement_4_createNS.engagement_team.add(self.user_with_ssh, self.el_user)
+ self.engagement_4_createNS.contact_user = self.user_with_ssh
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_4_createNS.uuid))
+ print('-----------------------------------------------------')
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.sshtoken = self.loginAndCreateSessionToken(self.user_with_ssh)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ self.checklist_template = self.creator.createDefaultCheckListTemplate()
+ print('-----------------------------------------------------')
+ print('Created Check List Template')
+ print('UUID: ' + str(self.checklist_template.uuid))
+ print('-----------------------------------------------------')
+
+ self.checklist = self.creator.createCheckList('some-checklist', 'Automation', 1, '{}', self.engagement,
+ self.checklist_template, self.el_user, self.peer_reviewer)
+ print('-----------------------------------------------------')
+ print('Created Check List')
+ print('UUID: ' + str(self.checklist.uuid))
+ print('-----------------------------------------------------')
+
+ def testAuthorization(self):
+ auth = AuthorizationService()
+
+ ######################
+ # TEST EL PERMISSIONS
+ ######################
+ # Test Add VF for EL
+ auth_result, message = auth.is_user_able_to(self.el_user, Permissions.add_vf, str(self.engagement.uuid), '')
+ print('ADD_VF Got Result : ' + str(auth_result) + ' ' + message)
+ self.assertEquals(auth_result, True)
+
+ auth_result, message = auth.is_user_able_to(self.el_user, Permissions.add_vendor, '', '')
+ print('ADD_VENDOR Got Result : ' + message)
+ self.assertEquals(auth_result, True)
+
+ # Check that EL that belong to ENG can create next step
+ auth_result, message = auth.is_user_able_to(
+ self.el_user, Permissions.add_nextstep, str(self.engagement.uuid), '')
+ print('ADD_NEXTSTEP Got Result : ' + message)
+ self.assertEquals(auth_result, True)
+
+ # Check that EL that does not belong to ENG cannot create next step
+ auth_result, message = auth.is_user_able_to(
+ self.another_el_user, Permissions.add_nextstep, str(self.engagement.uuid), '')
+ print('ADD_NEXTSTEP Got Result : ' + message)
+ self.assertEquals(auth_result, False)
+
+ # Check that CL can be created only by EL that belongs to ENG
+ auth_result, message = auth.is_user_able_to(
+ self.el_user, Permissions.add_checklist, str(self.engagement.uuid), '')
+ print('ADD_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, True)
+
+ # Check that CL can be created only by EL that belongs to ENG (use another el)
+ auth_result, message = auth.is_user_able_to(
+ self.another_el_user, Permissions.add_checklist, str(self.engagement.uuid), '')
+ print('ADD_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, False)
+
+ auth_result, message = auth.is_user_able_to(self.user, Permissions.add_checklist, str(self.engagement.uuid), '')
+ print('ADD_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, False)
+
+ # Check that only peer reviewer can do peer review
+ request_data_mgr.set_cl_uuid(str(self.checklist.uuid))
+ auth_result, message = auth.is_user_able_to(
+ self.peer_reviewer, Permissions.peer_review_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+ print('PEER_REVIEW_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, True)
+
+ # Check that a user that is not defined as peer review cannot review
+ auth_result, message = auth.is_user_able_to(
+ self.el_user, Permissions.peer_review_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+ print('PEER_REVIEW_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, False)
+
+ # Check that admin which is not owner cannot approve CL
+ # Test is greyed out due to the fact that admin can approve any CL
+# auth_result, message = auth.is_user_able_to(self.admin_user, Permissions.admin_approve_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+# print('ADMIN_APPROVE_CHECKLIST Got Result : ' + message)
+# self.assertEquals(auth_result, False)
+
+ # Check that only admin which is the cl owner can approve CL
+ self.checklist.owner = self.admin_user # Make admin the owner
+ self.checklist.save()
+ auth_result, message = auth.is_user_able_to(
+ self.admin_user, Permissions.admin_approve_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+ print('ADMIN_APPROVE_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, True)
+
+ # Check that only admin can approve CL (attempt with regular EL)
+ auth_result, message = auth.is_user_able_to(
+ self.el_user, Permissions.admin_approve_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+ print('ADMIN_APPROVE_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, False)
+
+ # Check that only admin can approve CL (attempt with regular user)
+ auth_result, message = auth.is_user_able_to(
+ self.user, Permissions.admin_approve_checklist, str(self.engagement.uuid), str(self.checklist.uuid))
+ print('ADMIN_APPROVE_CHECKLIST Got Result : ' + message)
+ self.assertEquals(auth_result, False)
diff --git a/django/engagementmanager/tests/test_base_entity.py b/django/engagementmanager/tests/test_base_entity.py
new file mode 100755
index 0000000..a90be1f
--- /dev/null
+++ b/django/engagementmanager/tests/test_base_entity.py
@@ -0,0 +1,319 @@
+#
+# ============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 abc import ABCMeta, abstractmethod
+import http.client
+import inspect
+import re
+import django
+from django.conf import settings
+from django.test import TestCase
+from django.test.client import Client
+import psycopg2
+from rest_framework.parsers import JSONParser
+from wheel.signatures import assertTrue
+django.setup()
+from engagementmanager.tests.vvpEntitiesCreator import VvpEntitiesCreator
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestBaseEntity(TestCase):
+ __metaclass__ = ABCMeta
+
+ def setUp(self):
+ logger.debug("---------------------- TestCase " + self.__class__.__name__ + " ----------------------")
+ self.urlPrefix = "/ice/v1/engmgr/"
+ self.conn = http.client.HTTPConnection("127.0.0.1", 8000) # @UndefinedVariable
+ self.c = Client()
+ self.creator = VvpEntitiesCreator()
+ settings.IS_SIGNAL_ENABLED = False
+ self.childSetup()
+
+ def tearDown(self):
+ settings.IS_SIGNAL_ENABLED = True
+ self.conn.close()
+ logger.debug("---------------------- TestCase " + self.__class__.__name__ + " ---------------------- ")
+ logger.debug("")
+ logger.debug("")
+
+ def createVendors(self, vendorList):
+ for vendor in vendorList:
+ vendorUuid, vendor = self.creator.createVendor(vendor)
+ logger.debug(vendorUuid)
+
+ def createDefaultRoles(self):
+ # Create Default Roles if does not exist
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+
+ def printTestName(self, testNameTrigger):
+ if testNameTrigger == "START":
+ logger.debug("[TestName: " + inspect.stack()[1][3] + " - START]")
+ elif testNameTrigger == "END":
+ logger.debug("[TestName: " + inspect.stack()[1][3] + " - END]")
+
+ @abstractmethod
+ def childSetup(self):
+ pass
+
+ def nativeConnect2Db(self):
+ return psycopg2.connect("dbname='icedb' user='iceuser' host='localhost' password='Aa123456' port='5433'")
+
+ def deleteRecord(self, urlStr, getRecord, isNegativeTest):
+ logger.debug("DELETE: " + urlStr + "/" + getRecord)
+ self.conn.request("DELETE", urlStr + "/" + getRecord)
+ r1 = self.conn.getresponse()
+ logger.debug("DELETE response status code: " + str(r1.status))
+# logger.debug("Number of records in the table: " + self.getNumOfRecordViaRest(urlStr))
+ if (isNegativeTest == False):
+ assertTrue(r1.status == 204)
+ return r1
+ elif (isNegativeTest == True):
+ return r1
+
+ def createEntityViaPost(self, urlStr, params, headers=None):
+ logger.debug("POST: " + urlStr + " Body: " + params + " Headers: " + str(headers))
+ self.conn.request("POST", urlStr, params, headers)
+ r1 = self.conn.getresponse()
+ return r1
+
+ def editEntityViaPut(self, urlStr, getRecord, params, isNegativeTest):
+ logger.debug("PUT: " + urlStr + "/" + getRecord + " " + params)
+ self.conn.request("PUT", urlStr + "/" + getRecord, params)
+ r1 = self.conn.getresponse()
+ logger.debug("PUT response status code: " + str(r1.status))
+ if (isNegativeTest == False):
+ assertTrue(r1.status == 200)
+ return r1
+ elif (isNegativeTest == True):
+ return r1
+
+ '''
+ If you wish to "SELECT *" and get the first record then send queryFilterName=1 and queryFilterValue=1 to the method
+ '''
+
+ def filterTableByColAndVal(self, queryColumnName, queryTableName, queryFilterName, queryFilterValue):
+ dbConn = self.nativeConnect2Db()
+ cur = dbConn.cursor()
+ queryStr = "SELECT %s FROM %s WHERE %s ='%s'" % (
+ queryColumnName, queryTableName, queryFilterName, queryFilterValue)
+ logger.debug(queryStr)
+ cur.execute(queryStr)
+ result = str(cur.fetchone())
+ if (bool(re.search('[^0-9]', result)) == True):
+ logger.debug("Looks like result (" + result +
+ ") from DB is in a multi column pattern: [col1, col2,...,coln], omitting it all colm beside " + queryColumnName)
+ if (result.find("',)") != -1): # formatting strings e.g uuid
+ result = result.partition('\'')[-1].rpartition('\'')[0]
+ elif (result.find(",)") != -1): # formatting ints e.g id
+ result = result.partition('(')[-1].rpartition(',')[0]
+ logger.debug("Filter result: " + result)
+ return result
+
+ def selectLastValue(self, queryColumnName, queryTableName, orderBy="id"):
+ dbConn = self.nativeConnect2Db()
+ cur = dbConn.cursor()
+ queryStr = "select %s from %s ORDER BY %s DESC LIMIT 1;" % (queryColumnName, queryTableName, orderBy)
+ logger.debug(queryStr)
+ cur.execute(queryStr)
+ result = str(cur.fetchone())
+ if (bool(re.search('[^0-9]', result)) == True):
+ logger.debug("Looks like result (" + result +
+ ") from DB is in a multi column pattern: [col1, col2,...,coln], omitting it all colm beside " + queryColumnName)
+ if (result.find("',)") != -1): # formatting strings e.g uuid
+ result = result.partition('\'')[-1].rpartition('\'')[0]
+ elif (result.find(",)") != -1): # formatting ints e.g id
+ result = result.partition('(')[-1].rpartition(',')[0]
+ logger.debug("Filter result: " + result)
+ return result
+
+ def columnMaxLength(self, tableName, columnName):
+ dbConn = self.nativeConnect2Db()
+ cur = dbConn.cursor()
+ queryStr = "SELECT character_maximum_length from information_schema.columns WHERE table_name ='%s' and column_name = '%s'" % (
+ tableName, columnName)
+ cur.execute(queryStr)
+ result = str(cur.fetchone())
+ if (bool(re.search('[^0-9]', result)) == True):
+ if (result.find("',)") != -1): # formatting strings e.g uuid
+ result = result.partition('\'')[-1].rpartition('\'')[0]
+ elif (result.find(",)") != -1): # formatting ints e.g id
+ result = result.partition('(')[-1].rpartition(',')[0]
+ return int(result)
+
+ def getNumOfRecordViaRest(self, urlStr):
+ logger.debug("GET: " + urlStr)
+ self.conn.request("GET", urlStr)
+ data_list = JSONParser().parse(self.conn.getresponse())
+ cnt = str(len(data_list))
+ return cnt
+
+ def getMaximalNameValue(self, urlStr):
+ logger.debug("GET: " + urlStr)
+ self.conn.request("GET", urlStr)
+ data_list = JSONParser().parse(self.conn.getresponse())
+ maxName = 0
+ for asi in data_list:
+ logger.debug(asi)
+ for key, value in asi.items():
+ if (key == "name"):
+ if (maxName < int(value)):
+ maxName = int(value)
+ logger.debug("MaximalNameValue=" + str(maxName))
+ return maxName
+
+ def getRecordAndDeserilizeIt(self, urlStr, getFilter, serializer, isCreateObj):
+ logger.debug("GET: " + urlStr + "/" + getFilter)
+ try:
+ self.conn.request("GET", urlStr + "/" + getFilter)
+ data = JSONParser().parse(self.conn.getresponse())
+ logger.debug("DATA After JSON Parse:" + str(data))
+ ser = serializer(data=data)
+# logger.debug(" --> Serializer data: "+repr(ser))
+ if (isCreateObj == True):
+ logger.debug("Creating ...")
+ obj = ser.create(data)
+ else:
+ logger.debug("Updating ...")
+ obj = ser.create(data)
+ ser.update(obj, data)
+ except Exception:
+ logger.debug(Exception)
+ raise Exception
+ return obj
+
+ def newParameters(self, oldValue, newValue, uuidValue):
+ newParams = re.sub(oldValue, newValue, self.params) # Find and replace in string.
+ newParams = re.sub("}", ', "uuid":"' + uuidValue + '"}', newParams) # Add UUID to params
+ return newParams
+
+ def negativeTestPost(self, getFilter, allowTwice=False):
+ logger.debug("POST negative tests are starting now!")
+ if (allowTwice == False):
+ logger.debug("Negative 01: Insert the same record twice via REST")
+ r1 = self.createEntityViaPost(self.urlStr, self.params)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ self.deleteRecord(self.urlStr, getFilter, False)
+ logger.debug("Negative 02: Insert record with empty value via REST")
+ paramsEmptyValue = re.sub(r':\".*?\"', ':\"\"', self.params) # Create params with empty values.
+ r1 = self.createEntityViaPost(self.urlStr, paramsEmptyValue)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ logger.debug("Negative 03: Insert record with missing value via REST")
+ paramsMissingValue = re.sub(r'{\".*?\":', '{\"\":', self.params) # Create params without records part 1.
+ # Create params without records part 2.
+ paramsMissingValue = re.sub(r', \".*?\":', ', \"\":', paramsMissingValue)
+ r1 = self.createEntityViaPost(self.urlStr, paramsMissingValue)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ logger.debug("Negative 04: Insert record with more than " + str(self.longValueLength) + " chars via REST")
+ paramsLongValue = re.sub(
+ r':\".*?\"', ':\"' + str(self.randomGenerator("randomNumber", self.longValueLength)) + '\"', self.params)
+ r1 = self.createEntityViaPost(self.urlStr, paramsLongValue)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ if (allowTwice == True):
+ logger.debug("Deleting record from database...")
+ self.deleteRecord(self.urlStr, getFilter, False)
+
+ def negativeTestPut(self, getFilter, params):
+ logger.debug("PUT negative tests are starting now!")
+ match = re.search("\D", getFilter) # Check if getFilter contains non-digit characters.
+ if not match:
+ logger.debug("Negative 01: Edit non existing record via REST")
+ nonExistingValue = self.randomGenerator("randomNumber", 5)
+ r1 = self.editEntityViaPut(self.urlStr, nonExistingValue, params, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 404)
+ logger.debug("Negative 02: Edit record with string in URL instead of integer via REST")
+ randStr = self.randomGenerator("randomString")
+ r1 = self.editEntityViaPut(self.urlStr, randStr, params, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ else:
+ logger.debug("Negative 01: Edit non existing record via REST")
+ nonExistingValue = self.randomGenerator("randomString")
+ r1 = self.editEntityViaPut(self.urlStr, nonExistingValue, params, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 404)
+ logger.debug("Negative 02: Edit record without URL pointer via REST")
+ r1 = self.editEntityViaPut(self.urlStr, "", params, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 405)
+ logger.debug("Negative 03: Edit record with empty value via REST")
+ paramsEmptyValue = re.sub(r':\".*?\"', ':\"\"', params) # Create params with empty values.
+ r1 = self.editEntityViaPut(self.urlStr, getFilter, paramsEmptyValue, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ logger.debug("Negative 04: Edit record with missing value via REST")
+ paramsMissingValue = re.sub(r'{\".*?\":', '{\"\":', params) # Create params without records part 1.
+ # Create params without records part 2.
+ paramsMissingValue = re.sub(r', \".*?\":', ', \"\":', paramsMissingValue)
+ r1 = self.editEntityViaPut(self.urlStr, getFilter, paramsMissingValue, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 400)
+ logger.debug("Deleting record from database...")
+ self.deleteRecord(self.urlStr, getFilter, False)
+
+ def negativeTestDelete(self):
+ logger.debug("DELETE negative tests are starting now!")
+ logger.debug("Negative 01: Delete non existing record via REST or wrong URL pointer")
+ nonExistingValue = self.randomGenerator("randomString")
+ r1 = self.deleteRecord(self.urlStr, nonExistingValue, True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 404 or r1.status == 500 or r1.status == 400)
+ logger.debug("Negative 02: Delete record without URL pointer via REST")
+ r1 = self.deleteRecord(self.urlStr, "", True)
+ logger.debug(r1.status, r1.reason)
+ assertTrue(r1.status == 405)
+
+ def failTest(self, failureReason):
+ logger.debug(">>> Test failed!\n", failureReason)
+ self.assertTrue(False)
+
+ def failRestTest(self, r1):
+ logger.debug("Previous HTTP POST request has failed with " + str(r1.status))
+ self.assertTrue(False)
+
+ def randomGenerator(self, typeOfValue, numberOfDigits=0):
+ return self.creator.randomGenerator(typeOfValue, numberOfDigits)
+
+ def loginAndCreateSessionToken(self, user):
+ return self.creator.loginAndCreateSessionToken(user)
diff --git a/django/engagementmanager/tests/test_base_transaction_entity.py b/django/engagementmanager/tests/test_base_transaction_entity.py
new file mode 100755
index 0000000..c4a5159
--- /dev/null
+++ b/django/engagementmanager/tests/test_base_transaction_entity.py
@@ -0,0 +1,76 @@
+#
+# ============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 abc import ABCMeta, abstractmethod
+import http.client
+import django
+from django.conf import settings
+from django.test.client import Client
+from django.test.testcases import TransactionTestCase
+from engagementmanager.tests.vvpEntitiesCreator import VvpEntitiesCreator
+from engagementmanager.service.logging_service import LoggingServiceFactory
+django.setup()
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestBaseTransactionEntity(TransactionTestCase):
+ __metaclass__ = ABCMeta
+
+ def setUp(self):
+ logger.debug("---------------------- TransactionTestCase " + self.__class__.__name__ + " ----------------------")
+ self.urlPrefix = "/ice/v1/engmgr/"
+ self.conn = http.client.HTTPConnection("127.0.0.1", 8000) # @UndefinedVariable
+ self.c = Client()
+ self.creator = VvpEntitiesCreator()
+ settings.IS_SIGNAL_ENABLED = False
+ self.childSetup()
+
+ def tearDown(self):
+ settings.IS_SIGNAL_ENABLED = True
+ self.conn.close()
+ logger.debug("---------------------- TransactionTestCase " + self.__class__.__name__ + " ---------------------- ")
+
+ @abstractmethod
+ def childSetup(self):
+ pass
+
+ def randomGenerator(self, typeOfValue, numberOfDigits=0):
+ return self.creator.randomGenerator(typeOfValue, numberOfDigits)
+
+ def loginAndCreateSessionToken(self, user):
+ return self.creator.loginAndCreateSessionToken(user)
diff --git a/django/engagementmanager/tests/test_checklist.py b/django/engagementmanager/tests/test_checklist.py
new file mode 100755
index 0000000..a7fa800
--- /dev/null
+++ b/django/engagementmanager/tests/test_checklist.py
@@ -0,0 +1,177 @@
+#
+# ============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 uuid import uuid4
+
+from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST
+
+from engagementmanager.models import ChecklistTemplate, ChecklistLineItem
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class TestChecklistTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs', 'Other'])
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # For negative tests
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.urlStr = self.urlPrefix + "engagement/@eng_uuid/checklist/new/"
+ self.data = dict()
+ self.template = self.creator.createDefaultCheckListTemplate()
+# self.engagement = Engagement.objects.create(uuid='just-a-fake-uuid',engagement_stage='Validation')
+ self.engagement = self.creator.createEngagement(
+ uuid4(), 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_team.add(self.user)
+ self.engagement.engagement_team.add(self.el_user)
+ self.engagement.save()
+ self.vendor = Vendor.objects.get(name='Other')
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+
+ def initBody(self):
+ self.data['checkListName'] = "ice checklist for test"
+ self.data['checkListTemplateUuid'] = str(self.template.uuid)
+ self.data['checkListAssociatedFiles'] = list()
+ self.data['checkListAssociatedFiles'].append("file0")
+ self.data['checkListAssociatedFiles'].append("file1")
+ self.data['checkListAssociatedFiles'].append("file2")
+
+ def getOrCreateChecklist(self, expectedStatus=HTTP_200_OK, httpMethod="GET"):
+ if (httpMethod == "GET"):
+ response = self.c.get(self.urlStr.replace("@eng_uuid", str(self.engagement.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ elif (httpMethod == "POST"):
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.post(self.urlStr.replace("@eng_uuid", str(self.engagement.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+
+ print('Got response : ' + str(response.status_code) +
+ " Expecting " + str(expectedStatus))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ def testGetChecklistPositive(self):
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ print("testGetChecklistPositive")
+ self.getOrCreateChecklist(HTTP_200_OK)
+
+ def testGetChecklistNegativeNoEng(self):
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ self.engagement.uuid = uuid4()
+ print("testGetChecklistPositive")
+ self.getOrCreateChecklist(HTTP_401_UNAUTHORIZED)
+#
+
+ def testPostChecklistPositive(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ print("testPostChecklistPositive")
+ self.getOrCreateChecklist(HTTP_200_OK, "POST")
+
+ def testPostChecklistNegativeNotElUser(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.user)
+ print("testPostChecklistNegativeNotElUser")
+ self.getOrCreateChecklist(HTTP_401_UNAUTHORIZED, "POST")
+
+ def testPostChecklistNegativeNoEng(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ self.engagement.uuid = uuid4()
+ print("testPostChecklistNegativeNoEng")
+ self.getOrCreateChecklist(HTTP_401_UNAUTHORIZED, "POST")
+
+ def testPostChecklistNegativeMissingParam(self):
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ print("testPostChecklistNegativeMissingParam")
+ self.getOrCreateChecklist(HTTP_400_BAD_REQUEST, "POST")
+
+ def testPostTestEngineDecisions(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.el_user)
+ print("testGetChecklistPositive")
+ response = self.getOrCreateChecklist(HTTP_200_OK, "POST")
+
+ checklist = json.loads(response.content)
+ self.urlStr = self.urlPrefix + "checklist/@checklist_uuid/testengine/"
+
+ # ChecklistLineItem.objects.get(uuid=decision['line_item_id']);
+
+ print(checklist['template']['uuid'])
+ template = ChecklistTemplate.objects.get(
+ uuid=checklist['template']['uuid'])
+ print(template)
+ line_items = ChecklistLineItem.objects.filter(template=template)
+ for line_item in line_items:
+ print(line_item)
+
+ return
+ self.data = dict()
+ self.data['decisions'] = "{123}"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.get(self.urlStr.replace("@checklist_uuid", str(checklist['uuid'])),
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+
+ print(json.loads(response.content))
+
+ return
+
+ self.data = dict()
+ self.data['decisions'] = "{123}"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.post(self.urlStr.replace("@checklist_uuid", str(checklist['uuid'])), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
diff --git a/django/engagementmanager/tests/test_checklist_template.py b/django/engagementmanager/tests/test_checklist_template.py
new file mode 100755
index 0000000..c3c63e4
--- /dev/null
+++ b/django/engagementmanager/tests/test_checklist_template.py
@@ -0,0 +1,168 @@
+#
+# ============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
+
+import mock
+from rest_framework.status import HTTP_200_OK, HTTP_404_NOT_FOUND,\
+ HTTP_500_INTERNAL_SERVER_ERROR
+
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+def dummy_true():
+ return True
+
+
+@mock.patch('engagementmanager.service.checklist_service.CheckListSvc.decline_all_template_checklists', dummy_true)
+class TestChecklistTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs', 'Other'])
+ self.createDefaultRoles()
+ # Create a user with role el
+ self.el_user = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.admin_user = self.creator.createUser(Vendor.objects.get(name=Constants.service_provider_company_name),
+ Constants.service_provider_admin_mail, '55501000199',
+ 'admin user', self.admin, True)
+ # For negative tests
+ self.user = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.urlStrForSave = self.urlPrefix + "checklist/template/"
+ self.urlStrForGetTmpl = self.urlPrefix + "checklist/template/@template_uuid"
+ self.urlStrForGetTmpls = self.urlPrefix + "checklist/templates/"
+ self.data = dict()
+ self.template = self.creator.createDefaultCheckListTemplate()
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.el_user
+ self.engagement.engagement_team.add(self.user)
+ self.engagement.engagement_team.add(self.el_user)
+ self.engagement.save()
+ self.vendor = Vendor.objects.get(name='Other')
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(
+ self.randomGenerator("randomString"), self.engagement, self.deploymentTarget, False, self.vendor)
+
+ def initBody(self):
+ self.data['uuid'] = str(self.template.uuid)
+ self.data['name'] = self.template.name
+ self.data['sections'] = list()
+ li1 = dict()
+ li1["uuid"] = "newEntity"
+ li1["name"] = "li1_name"
+ li1["description"] = "li1_description"
+ li1["validation_instructions"] = "li1_validation_instructions"
+
+ sec1 = dict()
+ sec1["uuid"] = "newEntity"
+ sec1["name"] = "sec1_name"
+ sec1["description"] = "sec1_description"
+ sec1["validation_instructions"] = "sec1_validation_instructions"
+
+ sec1["lineItems"] = list()
+ sec1["lineItems"].append(li1)
+
+ self.data['sections'].append(sec1)
+ print(self.data)
+
+ def getOrCreateChecklistTemplate(self, urlStr, expectedStatus=HTTP_200_OK, httpMethod="GET"):
+ if (httpMethod == "GET"):
+ if (urlStr == self.urlStrForGetTmpls):
+ response = self.c.get(urlStr,
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ else:
+ response = self.c.get(urlStr.replace("@template_uuid", str(self.template.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ elif (httpMethod == "PUT"):
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.put(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code) + " Expecting " + str(expectedStatus))
+ print('Got response : ' + str(response.status_code) + " Expecting " + str(expectedStatus))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ ### TESTS ###
+ def testSaveChecklistTemplate(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ print("testSaveChecklistTemplate")
+ self.getOrCreateChecklistTemplate(self.urlStrForSave, httpMethod="PUT")
+
+ def testSaveChecklistTemplateMissingTemplateUuid(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ self.data['uuid'] = ""
+ print("testSaveChecklistTemplateMissingTemplateUuid")
+ self.getOrCreateChecklistTemplate(self.urlStrForSave, expectedStatus=HTTP_404_NOT_FOUND, httpMethod="PUT")
+
+ def testSaveChecklistTemplateNotExistingTemplate(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ print("testSaveChecklistTemplateNoExistanceTemplate")
+ self.data['uuid'] = 'fake_uuid'
+ self.getOrCreateChecklistTemplate(self.urlStrForSave, expectedStatus=HTTP_404_NOT_FOUND, httpMethod="PUT")
+
+ def testSaveChecklistTemplateMissingKey(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ print("testSaveChecklistTemplateNoExistanceTemplate")
+ # take the first line item (li1_name) which is newEntity and remove its name, expect 500
+ self.data['sections'][0]["lineItems"][0]["name"] = None
+ self.getOrCreateChecklistTemplate(
+ self.urlStrForSave, expectedStatus=HTTP_500_INTERNAL_SERVER_ERROR, httpMethod="PUT")
+
+ def testGetChecklistTemplates(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ print("testSaveChecklistTemplate")
+ self.getOrCreateChecklistTemplate(self.urlStrForGetTmpls, httpMethod="GET")
+
+ def testGetChecklistTemplate(self):
+ self.initBody()
+ self.token = self.loginAndCreateSessionToken(self.admin_user)
+ print("testSaveChecklistTemplate")
+ self.getOrCreateChecklistTemplate(self.urlStrForGetTmpl, httpMethod="GET")
diff --git a/django/engagementmanager/tests/test_cms_documentation_search.py b/django/engagementmanager/tests/test_cms_documentation_search.py
new file mode 100755
index 0000000..2d13f96
--- /dev/null
+++ b/django/engagementmanager/tests/test_cms_documentation_search.py
@@ -0,0 +1,103 @@
+#
+# ============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
+import mock
+from rest_framework.status import HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def search_page_mock(keyword):
+ result = [{u'id': 1, u'title': 'exists_title', u'children': [], u'status': '', u'_order': 1}, ]
+ return result
+
+
+def search_empty_page_mock(keyword):
+ return []
+
+
+class TestCMSDocumentationSearch(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.user = self.creator.createUser(Vendor.objects.get(name='Other'),
+ self.randomGenerator("main-vendor-email"), 'Aa123456',
+ 'user', self.standard_user, True)
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def testSearchEmptyString(self):
+ urlStr = self.urlPrefix + 'cms/pages/search/?keyword='
+ self.printTestName("testSearchEmptyString [Start]")
+ logger.debug("action should success (200), and return empty array")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ content = json.loads(response.content)
+ self.assertEqual(content, [])
+ self.printTestName("testSearchEmptyString [End]")
+
+ @mock.patch('engagementmanager.apps.cms_client.search_pages', search_empty_page_mock)
+ def testSearchNotExistsKeyword(self):
+ urlStr = self.urlPrefix + 'cms/pages/search/?keyword=somewordnotexists'
+ self.printTestName("testSearchNotExistsKeyword [Start]")
+ logger.debug("action should success (200), and return empty array")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ content = json.loads(response.content)
+ self.assertEqual(content, [])
+ self.printTestName("testSearchNotExistsKeyword [End]")
+
+ @mock.patch('engagementmanager.apps.cms_client.search_pages', search_page_mock)
+ def testSearchExistsKeyword(self):
+ urlStr = self.urlPrefix + 'cms/pages/search/?keyword=exists_title'
+ self.printTestName("testSearchExistsKeyword [Start]")
+ logger.debug("action should success (200), and return array with one page (by mock)")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ content = json.loads(response.content)
+ self.assertEqual(content[0]['title'], 'exists_title')
+ self.printTestName("testSearchExistsKeyword [End]")
diff --git a/django/engagementmanager/tests/test_cms_pages.py b/django/engagementmanager/tests/test_cms_pages.py
new file mode 100755
index 0000000..4fd9473
--- /dev/null
+++ b/django/engagementmanager/tests/test_cms_pages.py
@@ -0,0 +1,135 @@
+#
+# ============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
+import mock
+from rest_framework.status import HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def get_pages_mock(title=""):
+ result = [{u'meta_description': u'Content of page #1', u'parent': None, u'title': u'Page #1',
+ u'login_required': True, u'children': [], u'id': 1,
+ u'content': u'<p>Content of page #1</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#1', u'tags': u''},
+ {u'meta_description': u'Content of page #2', u'parent': None, u'title': u'Page #2',
+ u'login_required': True, u'children': [], u'id': 2,
+ u'content': u'<p>Content of page #2</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#2', u'tags': u''},
+ {u'meta_description': u'Content of page #3', u'parent': None, u'title': u'Page #3',
+ u'login_required': True, u'children': [], u'id': 3,
+ u'content': u'<p>Content of page #3</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#3', u'tags': u''},
+ {u'meta_description': u'Content of page #4', u'parent': None, u'title': u'Page #4',
+ u'login_required': True, u'children': [], u'id': 4,
+ u'content': u'<p>Content of page #4</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#4', u'tags': u''},
+ {u'meta_description': u'Content of page #5', u'parent': None, u'title': u'Page #5',
+ u'login_required': True, u'children': [], u'id': 5,
+ u'content': u'<p>Content of page #5</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#5', u'tags': u''},
+ {u'meta_description': u'Content of page #6', u'parent': None, u'title': u'Page #6',
+ u'login_required': True, u'children': [], u'id': 6,
+ u'content': u'<p>Content of page #6</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#6', u'tags': u''}]
+ if title != "":
+ return [result[0]]
+ else:
+ return result
+
+
+def get_page_mock(id):
+ result = {u'meta_description': u'Content of page #1', u'parent': None, u'title': u'Page #1',
+ u'login_required': True, u'children': [], u'id': 1,
+ u'content': u'<p>Content of page #1</p>', u'content_model': u'richtextpage',
+ u'publish_date': u'2017-01-01T13:47:15Z', u'slug': u'documentation/page#1', u'tags': u''}
+
+ return result
+
+
+@mock.patch('engagementmanager.apps.cms_client.get_pages', get_pages_mock)
+@mock.patch('engagementmanager.apps.cms_client.get_page', get_page_mock)
+class CMSGetPagesTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.user = self.creator.createUser(Vendor.objects.get(name='Other'),
+ self.randomGenerator("main-vendor-email"), 'Aa123456',
+ 'user', self.standard_user, True)
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def testGetPageById(self):
+ urlStr = self.urlPrefix + 'cms/pages/1/'
+ self.printTestName("testGetPageById [Start]")
+ logger.debug("action should success (200), and return page by id")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ content = json.loads(response.content)
+ self.assertEqual(content["title"], 'Page #1')
+ self.printTestName("testGetPageById [End]")
+
+ def testGetPages(self):
+ urlStr = self.urlPrefix + 'cms/pages/'
+ self.printTestName("testGetPages [Start]")
+ logger.debug("action should success (200), and return all pages")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(json.loads(response.content)), 6) # Suppose to be 6 The amount of Pages in the mock.
+ self.printTestName("testGetPages [End]")
+
+ def testGetPagesByTitle(self):
+ urlStr = self.urlPrefix + 'cms/pages/?title=Documentation'
+ print(urlStr)
+ self.printTestName("testGetPagesByTitle [Start]")
+ logger.debug("action should success (200), and return filtered pages")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ content = json.loads(response.content)
+ self.assertEqual(len(content), 1) # Suppose to be 1 The amount of Documentation titled pages in the mock.
+ self.assertEqual(content[0]["title"], 'Page #1')
+ self.printTestName("testGetPagesByTitle [End]")
diff --git a/django/engagementmanager/tests/test_cms_posts.py b/django/engagementmanager/tests/test_cms_posts.py
new file mode 100755
index 0000000..7132c2c
--- /dev/null
+++ b/django/engagementmanager/tests/test_cms_posts.py
@@ -0,0 +1,137 @@
+#
+# ============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
+import mock
+from rest_framework.status import HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def get_posts_mock(offset=0, limit=10, category="", date_min=""):
+ result = [{u'updated': u'2017-01-17T15:57:19.567778Z', u'title': u'announcement..new.1', u'url': u'http://127.0.0.1:8001/blog/announcementnew1/', u'short_url': u'/blog/announcementnew1/', u'tags': u'', u'excerpt': u'announcement..new.announcement..new.', u'allow_comments': True, u'comments': [], u'slug': u'announcementnew1', u'content': u'<p>announcement..new.announcement..new.</p>', u'publish_date': u'2017-01-14T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 1, u'categories': [{u'slug': u'announcement', u'id': 1, u'title': u'Announcement'}]},
+ {u'updated': u'2017-01-16T15:57:19.567778Z', u'title': u'announcement..new.2', u'url': u'http://127.0.0.1:8001/blog/announcementnew2/', u'short_url': u'/blog/announcementnew2/', u'tags': u'', u'excerpt': u'announcement..new.announcement..new.', u'allow_comments': True, u'comments': [], u'slug': u'announcementnew2',
+ u'content': u'<p>announcement..new.announcement..new.</p>', u'publish_date': u'2017-01-15T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 2, u'categories': [{u'slug': u'announcement', u'id': 1, u'title': u'Announcement'}]},
+ {u'updated': u'2017-01-15T15:57:19.567778Z', u'title': u'announcement..new.3', u'url': u'http://127.0.0.1:8001/blog/announcementnew3/', u'short_url': u'/blog/announcementnew3/', u'tags': u'', u'excerpt': u'announcement..new.announcement..new.', u'allow_comments': True, u'comments': [], u'slug': u'announcementnew3',
+ u'content': u'<p>announcement..new.announcement..new.</p>', u'publish_date': u'2017-01-16T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 3, u'categories': [{u'slug': u'announcement', u'id': 1, u'title': u'Announcement'}]},
+ {u'updated': u'2017-01-14T15:57:19.567778Z', u'title': u'news..new.1', u'url': u'http://127.0.0.1:8001/blog/news1/', u'short_url': u'/blog/news1/', u'tags': u'', u'excerpt': u'news..new.news..new.', u'allow_comments': True, u'comments': [], u'slug': u'news1', u'content': u'<p>news..new.news..new.</p>',
+ u'publish_date': u'2017-01-14T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 4, u'categories': [{u'slug': u'news', u'id': 1, u'title': u'News'}]},
+ {u'updated': u'2017-01-13T15:57:19.567778Z', u'title': u'news..new.2', u'url': u'http://127.0.0.1:8001/blog/news2/', u'short_url': u'/blog/news2/', u'tags': u'', u'excerpt': u'news..new.news..new.', u'allow_comments': True, u'comments': [], u'slug': u'news2', u'content': u'<p>news..new.news..new.</p>',
+ u'publish_date': u'2017-01-15T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 5, u'categories': [{u'slug': u'news', u'id': 1, u'title': u'News'}]},
+ {u'updated': u'2017-01-12T15:57:19.567778Z', u'title': u'news..new.3', u'url': u'http://127.0.0.1:8001/blog/news3/', u'short_url': u'/blog/news3/', u'tags': u'', u'excerpt': u'news..new.news..new.', u'allow_comments': True, u'comments': [], u'slug': u'news3', u'content': u'<p>news..new.news..new.</p>', u'publish_date': u'2017-01-16T19:53:52Z', u'user': {u'username': u'al942u', u'first_name': u'', u'last_name': u'', u'email': u'al942u@mail.com', u'is_staff': True, u'id': 1}, u'featured_image': u'', u'comments_count': 0, u'id': 6, u'categories': [{u'slug': u'news', u'id': 1, u'title': u'News'}]}]
+
+ if category == "News":
+ return [result[3], result[4], result[5]]
+ elif date_min != "":
+ return [result[0], result[1]]
+ elif category == "Announcement" and limit == 1:
+ return [result[0]]
+ elif limit != 10:
+ return result[:int(limit)]
+ else:
+ return result
+
+
+@mock.patch('engagementmanager.apps.cms_client.get_posts', get_posts_mock)
+class CMSGetPostsTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.user = self.creator.createUser(Vendor.objects.get(name='Other'),
+ self.randomGenerator("main-vendor-email"), 'Aa123456',
+ 'user', self.standard_user, True)
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def testGetPostsByCategory(self):
+ urlStr = self.urlPrefix + 'cms/posts/?category=News'
+ print(urlStr)
+ self.printTestName("GetPostsByCategoryTest [Start]")
+ logger.debug("action should success (200), and return filtered posts")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(json.loads(response.content)), 3) # Suppose to be 3 The amount of News in the mock.
+ self.printTestName("GetPostsByCategoryTest [End]")
+
+ def testGetAllPosts(self):
+ urlStr = self.urlPrefix + 'cms/posts/?limit=10'
+ self.printTestName("GetAllPostsTest [Start]")
+ logger.debug("action should success (200), and return all posts")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ # Suppose to be 6 items like the amount of items of the mock.
+ self.assertEqual(len(json.loads(response.content)), 6)
+ self.printTestName("GetAllPostsTest [End]")
+
+ def testGetLimitedPosts(self):
+ limit = 2
+ urlStr = self.urlPrefix + 'cms/posts/?limit=' + str(limit)
+ self.printTestName("GetLimitedPostsTest [Start]")
+ logger.debug("action should success (200), and filtered with limit all posts")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(json.loads(response.content)), limit) # Suppose to be {{limit}} amount of items
+ self.printTestName("GetLimitedPostsTest [End]")
+
+ def testGetPostsByDateMin(self):
+ urlStr = self.urlPrefix + 'cms/posts/?fromLastDays=2&limit=10'
+ self.printTestName("GetPostsByDateMinTest [Start]")
+ logger.debug("action should success (200), and return filtered posts")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(json.loads(response.content)), 2) # Suppose to be 2 items that are after this date
+ self.printTestName("GetPostsByDateMinTest [End]")
+
+ def testGetOneAnnouncementPost(self):
+ urlStr = self.urlPrefix + 'cms/posts/?limit=1&category=Announcement'
+ self.printTestName("GetOneAnnouncementPostTest [Start]")
+ logger.debug("action should success (200), and return one announcement post")
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(json.loads(response.content)), 1) # Suppose to be just 1 item like that.
+ self.printTestName("GetOneAnnouncementPostTest [End]")
diff --git a/django/engagementmanager/tests/test_deployment_target_sites.py b/django/engagementmanager/tests/test_deployment_target_sites.py
new file mode 100755
index 0000000..ddfb448
--- /dev/null
+++ b/django/engagementmanager/tests/test_deployment_target_sites.py
@@ -0,0 +1,163 @@
+#
+# ============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 rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class DeploymentTargetSitesTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+
+ # Create users:
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.el_user = self.creator.createUser(Vendor.objects.get(name=Constants.service_provider_company_name),
+ self.randomGenerator("main-vendor-email"), 'Aa123456',
+ 'el user1', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"), 'Aa123456',
+ 'user', self.standard_user, True)
+ self.admin_user = self.creator.createUser(Vendor.objects.get(name=Constants.service_provider_company_name),
+ Constants.service_provider_admin_mail, 'Aa123456',
+ 'admin user', self.admin, True)
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(
+ 'just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.save()
+ self.deploymentTarget = self.creator.createDeploymentTarget(self.randomGenerator("randomString"),
+ self.randomGenerator("randomString"))
+ self.vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"), self.engagement,
+ self.deploymentTarget, False, self.vendor)
+
+ # Login with users:
+ self.user_token = self.loginAndCreateSessionToken(self.user)
+ self.el_token = self.loginAndCreateSessionToken(self.el_user)
+ self.admin_token = self.loginAndCreateSessionToken(self.admin_user)
+
+ def testPostDeploymentTargetSitesForStandardUser(self):
+ urlStr = self.urlPrefix + 'dtsites/'
+
+ myjson = '{"name": "Middletown (ICENJ)", "vf_uuid": "' + \
+ str(self.vf.uuid) + '"}'
+ print(myjson)
+
+ response = self.c.post(urlStr, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.user_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ def testPostDeploymentTargetSitesForELUser(self):
+ urlStr = self.urlPrefix + 'dtsites/'
+
+ myjson = '{"name": "Middletown (ICENJ)", "vf_uuid": "' + \
+ str(self.vf.uuid) + '"}'
+ print(myjson)
+
+ response = self.c.post(urlStr, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.el_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testPostDeploymentTargetSitesForAdminUser(self):
+ urlStr = self.urlPrefix + 'dtsites/'
+
+ myjson = '{"name": "Middletown (ICENJ)", "vf_uuid": "' + \
+ str(self.vf.uuid) + '"}'
+ print(myjson)
+
+ response = self.c.post(urlStr, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testGetDeploymentTargetSitesForStandardUser(self):
+ urlStr = self.urlPrefix + 'vf/' + str(self.vf.uuid) + '/dtsites/'
+ print(urlStr)
+ self.printTestName("testGetDeploymentTargetSites [Start]")
+ logger.debug("action should unauthorized (401)")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.user_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.printTestName("testGetDeploymentTargetSites [End]")
+
+ def testGetDeploymentTargetSitesForELUser(self):
+ urlStr = self.urlPrefix + 'vf/' + str(self.vf.uuid) + '/dtsites/'
+ print(urlStr)
+ self.printTestName("testGetDeploymentTargetSitesForELUser [Start]")
+ logger.debug("action should authorized (200)")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.el_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.printTestName("testGetDeploymentTargetSitesForELUser [End]")
+
+ def testGetDeploymentTargetSitesForAdminUser(self):
+ urlStr = self.urlPrefix + 'vf/' + str(self.vf.uuid) + '/dtsites/'
+ print(urlStr)
+ self.printTestName("testGetDeploymentTargetSitesForAdminUser [Start]")
+ logger.debug("action should authorized (200)")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.printTestName("testGetDeploymentTargetSitesForAdminUser [End]")
+
+ def testDelDeploymentTargetSitesForStandardUser(self):
+ urlStr = self.urlPrefix + 'vf/' + str(self.vf.uuid) + '/dtsites/'
+ print(urlStr)
+ logger.debug("action should unauthorized (401)")
+ response = self.c.delete(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.user_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
diff --git a/django/engagementmanager/tests/test_digest_email_notifications.py b/django/engagementmanager/tests/test_digest_email_notifications.py
new file mode 100755
index 0000000..b3e75df
--- /dev/null
+++ b/django/engagementmanager/tests/test_digest_email_notifications.py
@@ -0,0 +1,128 @@
+#
+# ============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
+import mock
+from rest_framework.status import HTTP_202_ACCEPTED
+from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.bus.messages.daily_scheduled_message import DailyScheduledMessage
+from engagementmanager.models import Vendor
+from engagementmanager.utils.activities_data import UserJoinedEngagementActivityData
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants, EngagementStage
+from engagementmanager.apps import bus_service
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def digest_mock(self, bus_message):
+ DigestEmailNotificationsTestCase.is_digested_mock_sent = True
+ DigestEmailNotificationsTestCase.message = bus_message
+
+
+# engagementmanager/bus/handlers/digest_email_notification_handler.py
+@mock.patch('engagementmanager.bus.handlers.digest_email_notification_handler.'
+ 'DigestEmailNotificationHandler.handle_message', digest_mock)
+class DigestEmailNotificationsTestCase(TestBaseEntity):
+ is_digested_mock_sent = False
+ message = None
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+ vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.el_user = self.creator.createUser(vendor, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ vendor = Vendor.objects.get(name='Other')
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ self.pruser = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+
+ self.engagement = self.creator.createEngagement(self.randomGenerator(
+ "randomString"), self.randomGenerator("randomString"), None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.pruser
+ self.engagement.save()
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, vendor)
+
+ def testDigestEmailForActivities(self):
+ """
+ Will check if the service bus deliver the message of sending digested mails
+ No need to check if the mail is sent or if the python scheduling is working
+ """
+ # Create the activities:
+ self.urlStr = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid) + "/stage/@stage"
+
+ random_user = self.creator.createUser(Vendor.objects.get(name='Other'),
+ self.randomGenerator("email"),
+ self.randomGenerator("randomNumber"),
+ self.randomGenerator("randomString"),
+ self.el, True)
+
+ self.engagement.engagement_team.add(random_user)
+ self.engagement.save()
+
+ users_list = []
+ users_list.append(random_user)
+ activity_data = UserJoinedEngagementActivityData(self.vf, users_list, self.engagement)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ token = self.loginAndCreateSessionToken(random_user)
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Active.name),
+ json.dumps(dict(), ensure_ascii=False), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + token})
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+
+ urlStr = self.urlPrefix + 'engagement/${uuid}/activities/'
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + token})
+ content = json.loads(response.content)
+ self.assertEqual(len(content), 2)
+
+ message = DailyScheduledMessage()
+ bus_service.send_message(message)
+ self.assertTrue(self.is_digested_mock_sent)
+ self.assertEqual(self.message, message)
diff --git a/django/engagementmanager/tests/test_eng_progress.py b/django/engagementmanager/tests/test_eng_progress.py
new file mode 100755
index 0000000..563c3cd
--- /dev/null
+++ b/django/engagementmanager/tests/test_eng_progress.py
@@ -0,0 +1,99 @@
+#
+# ============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 rest_framework.status import HTTP_401_UNAUTHORIZED, HTTP_202_ACCEPTED, HTTP_500_INTERNAL_SERVER_ERROR
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class EngProgressTestCase(TestBaseEntity):
+
+ def childSetup(self): # Variables to use in this class.
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # Create a user with role standard_user
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(
+ 'just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.save()
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ def testSetProgress(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/progress'
+
+ self.printTestName("START")
+
+ logger.debug(
+ "action should fail (401), Only Engagement Lead can set Engagement Progress")
+ response = self.c.put(urlStr, '{ "progress" : 50 }', content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ response = self.c.put(urlStr, '{ "progress" : 50 }', content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+
+ response = self.c.put(urlStr, '{ "progress" : 101 }', content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_500_INTERNAL_SERVER_ERROR)
+
+ self.printTestName("END")
diff --git a/django/engagementmanager/tests/test_eng_status.py b/django/engagementmanager/tests/test_eng_status.py
new file mode 100755
index 0000000..62f787d
--- /dev/null
+++ b/django/engagementmanager/tests/test_eng_status.py
@@ -0,0 +1,161 @@
+#
+# ============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 uuid import uuid4
+from rest_framework.status import HTTP_401_UNAUTHORIZED, HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class EngagementStatusTestCase(TestBaseEntity):
+
+ def childSetup(self): # Variables to use in this class.
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_review_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # Create a user with role standard_user
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.user_not_team = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user not team', self.standard_user, True)
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(uuid4(), 'Validation', None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_review_user
+ self.engagement.save()
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+ self.user_not_team_token = self.loginAndCreateSessionToken(self.user_not_team)
+
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+ myjson = json.dumps({"description": "blah blah"}, ensure_ascii=False)
+ response = self.c.post(urlStr.replace('${uuid}', str(self.engagement.uuid)), myjson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ self.created_status = json.loads(response.content)
+
+ def testPutStatus(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+
+ self.printTestName("START - testPutStatus")
+
+ logger.debug("action should fail (401), Only Engagement Lead can set Engagement Progress")
+
+ myjson = json.dumps(
+ {"eng_status_uuid": self.created_status['uuid'], "description": "blah2 blah2"}, ensure_ascii=False)
+ response = self.c.put(urlStr.replace('${uuid}', str(self.engagement.uuid)), myjson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ myjson = json.dumps(
+ {"eng_status_uuid": self.created_status['uuid'], "description": "blah2 blah2"}, ensure_ascii=False)
+ response = self.c.put(urlStr.replace('${uuid}', str(self.engagement.uuid)), myjson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ self.printTestName("END - testPutStatus")
+
+ def testPostStatus(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+
+ self.printTestName("START - testPostStatus")
+
+ logger.debug("action should fail (401), Only Engagement Lead can set Engagement Progress")
+
+ myjson = json.dumps({"description": "blah blah"}, ensure_ascii=False)
+ response = self.c.post(urlStr.replace('${uuid}', str(self.engagement.uuid)), myjson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ logger.debug("action should fail (400), For fake engagement uuid")
+ myjson = json.dumps({"description": "blah blah"}, ensure_ascii=False)
+ response = self.c.post(urlStr.replace(
+ '${uuid}', str(uuid4())), myjson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ myjson = json.dumps({"description": "blah blah"}, ensure_ascii=False)
+ response = self.c.post(urlStr.replace('${uuid}', str(self.engagement.uuid)), myjson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ self.printTestName("END - testPostStatus")
+
+ def testGetStatus(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+
+ self.printTestName("START - testGetStatus")
+
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement.uuid)),
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ logger.debug("action should fail (401), Only team members can get status")
+
+ response = self.c.get(urlStr.replace('${uuid}', str(
+ self.engagement.uuid)), content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.user_not_team_token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ logger.debug("action should fail (401), Only existing eng_uuid cab ne fetched")
+ response = self.c.get(urlStr.replace('${uuid}', str(
+ uuid4())), content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ self.printTestName("END - testGetStatus")
diff --git a/django/engagementmanager/tests/test_engagement_admin_operations.py b/django/engagementmanager/tests/test_engagement_admin_operations.py
new file mode 100755
index 0000000..a50e49f
--- /dev/null
+++ b/django/engagementmanager/tests/test_engagement_admin_operations.py
@@ -0,0 +1,306 @@
+#
+# ============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 engagementmanager.models import Vendor, Engagement, IceUserProfile, \
+ Checklist
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import EngagementStage, Constants
+from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED
+import json
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class EngagementAdminOperationsTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.el_user = self.creator.createUser(Vendor.objects.get(name=Constants.service_provider_company_name),
+ self.randomGenerator("main-vendor-email"), '55501000199',
+ 'el user', self.el, True)
+ self.second_el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"), '55501000199',
+ 'el user2', self.el, True)
+ self.el_user_to_update = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name),
+ self.randomGenerator("main-vendor-email"), '55501000199',
+ 'el user 3', self.el, True)
+ self.user = self.creator.createUser(Vendor.objects.get(name='Other'),
+ self.randomGenerator("main-vendor-email"), '55501000199',
+ 'user', self.standard_user, True)
+ self.admin_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail, '55501000199',
+ 'admin user', self.admin, True)
+
+ self.engagement = self.creator.createEngagement(
+ 'just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(
+ self.user, self.el_user, self.second_el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.second_el_user
+ self.engagement.save()
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(self.randomGenerator("randomString"),
+ self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"), self.engagement, self.deploymentTarget,
+ False, Vendor.objects.get(name='Other'))
+
+ self.userToken = self.loginAndCreateSessionToken(self.user)
+ self.elToken = self.loginAndCreateSessionToken(self.el_user)
+ self.elUserToUpdateToken = self.loginAndCreateSessionToken(
+ self.el_user_to_update)
+ self.adminToken = self.loginAndCreateSessionToken(self.admin_user)
+
+ def testGetAllEls(self):
+ num_of_els = IceUserProfile.objects.filter(role=self.el).count()
+ urlStr = self.urlPrefix + 'users/engagementleads/'
+ print(urlStr)
+ self.printTestName("testGetAllEls [Start]")
+ logger.debug(
+ "action should success (200), and return all els exists in the system")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ data = json.loads(response.content)
+ self.assertEqual(len(data), num_of_els)
+ self.assertEqual(data[0]['full_name'] == 'el user 3' or data[
+ 0]['full_name'] == 'el user', True)
+ self.assertEqual(data[1]['full_name'] == 'el user 3' or data[
+ 1]['full_name'] == 'el user2', True)
+ self.printTestName("testGetAllEls [End]")
+
+ def testArchiveEngagement(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/archive'
+ print(urlStr)
+ self.printTestName("testArchiveEngagement [Start]")
+ logger.debug("action should success (202), and archive the engagement")
+ response = self.c.put(urlStr, json.dumps({'reason': 'test_reason'}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ eng_object = Engagement.objects.get(uuid=self.engagement.uuid)
+ # @UndefinedVariable
+ self.assertEqual(
+ eng_object.engagement_stage, EngagementStage.Archived.name)
+ self.assertEqual(eng_object.archive_reason, 'test_reason')
+ self.printTestName("testArchiveEngagement [End]")
+
+ def testArchiveEngagementValidateDate(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/archive'
+ print(urlStr)
+ self.printTestName("testArchiveEngagement [Start]")
+ logger.debug("action should success (202), and archive the engagement")
+ response = self.c.put(urlStr, json.dumps({'reason': 'test_reason'}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ eng_object = Engagement.objects.get(uuid=self.engagement.uuid)
+ self.assertEqual(eng_object.engagement_stage,
+ EngagementStage.Archived.name) # @UndefinedVariable
+ self.assertTrue(eng_object.archived_time)
+ print(eng_object.archived_time)
+ self.printTestName("testArchiveEngagement [End]")
+
+ def testSetEngagementReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/reviewer/'
+ print(urlStr)
+ self.printTestName("testSetEngagementReviewer [Start]")
+ logger.debug(
+ "action should success (200), and set the engagement reviewer")
+ response = self.c.put(urlStr, json.dumps({'reviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ eng_object = Engagement.objects.get(uuid=self.engagement.uuid)
+ self.assertEqual(
+ eng_object.reviewer.uuid, str(self.el_user_to_update.uuid))
+ self.printTestName("testSetEngagementReviewer [End]")
+
+ def testSetEngagementPeerReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/peerreviewer/'
+ print(urlStr)
+ self.printTestName("testSetEngagementPeerReviewer [Start]")
+ logger.debug(
+ "action should success (200), and set the engagement peer reviewer")
+ response = self.c.put(urlStr, json.dumps({'peerreviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ eng_object = Engagement.objects.get(uuid=self.engagement.uuid)
+ self.assertEqual(eng_object.peer_reviewer.uuid,
+ str(self.el_user_to_update.uuid))
+ self.printTestName("testSetEngagementPeerReviewer [End]")
+
+ def testNegativeGetAllEls(self):
+ urlStr = self.urlPrefix + 'users/engagementleads/'
+ print(urlStr)
+ self.printTestName("testNegativeGetAllEls [Start]")
+ logger.debug("action should failed due to missing permissions (401)")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.elToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.printTestName("testNegativeGetAllEls [End]")
+
+ def testNegativeArchiveEngagement(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/archive'
+ print(urlStr)
+ self.printTestName("testNegativeArchiveEngagement [Start]")
+ logger.debug("action should failed due to missing permissions (401)")
+ response = self.c.put(urlStr, json.dumps({'reason': 'test_reason'}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.elToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.printTestName("testNegativeArchiveEngagement [End]")
+
+ def testNegativeSetEngagementReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/reviewer/'
+ print(urlStr)
+ self.printTestName("testNegativeSetEngagementReviewer [Start]")
+ logger.debug("action should failed due to missing permissions (401)")
+ response = self.c.put(urlStr, json.dumps({'reviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.elToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.printTestName("testNegativeSetEngagementReviewer [End]")
+
+ def testNegativeSetEngagementPeerReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/peerreviewer/'
+ print(urlStr)
+ self.printTestName("testNegativeSetEngagementPeerReviewer [Start]")
+ logger.debug("action should failed due to missing permissions (401)")
+ response = self.c.put(urlStr, json.dumps({'peerreviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.elToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.printTestName("testNegativeSetEngagementPeerReviewer [End]")
+
+ def testSwitchEngagementReviewers(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/switch-reviewers/'
+ print(urlStr)
+ self.printTestName("testSetEngagementReviewer [Start]")
+ logger.debug(
+ "action should success (200), and switch between the engagement reviewer and peer reviewer")
+ logger.debug("Reviewer: %s, PeerReviewer: %s" %
+ (self.engagement.reviewer, self.engagement.peer_reviewer))
+ response = self.c.put(urlStr, json.dumps({'reviewer': str(self.second_el_user.uuid), 'peerreviewer': str(
+ self.el_user.uuid)}), content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ eng_object = Engagement.objects.get(uuid=self.engagement.uuid)
+ self.assertEqual(
+ eng_object.reviewer.uuid, str(self.second_el_user.uuid))
+ self.assertEqual(
+ eng_object.peer_reviewer.uuid, str(self.el_user.uuid))
+ logger.debug("Reviewer: %s, PeerReviewer: %s" %
+ (eng_object.reviewer, eng_object.peer_reviewer))
+ self.printTestName("testSetEngagementReviewer [End]")
+
+ def testChecklistOwnerAfterChangeReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/reviewer/'
+ print(urlStr)
+ self.printTestName("testChecklistOwnerAfterChangeReviewer [Start]")
+ cl_template = self.creator.createDefaultCheckListTemplate()
+ checklist = self.creator.createCheckList(
+ "cl-name", "review", 1, None, self.engagement, cl_template,
+ self.admin_user, self.el_user)
+ logger.debug(
+ "action should success (200), set the engagement reviewer and change checklist owner")
+ response = self.c.put(urlStr, json.dumps({'reviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ checklist = Checklist.objects.get(uuid=checklist.uuid)
+ self.assertEqual(checklist.owner, self.el_user_to_update)
+ self.printTestName("testChecklistOwnerAfterChangeReviewer [End]")
+
+ def testChecklistOwnerAfterChangePeerReviewer(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/peerreviewer/'
+ print(urlStr)
+ self.printTestName("testChecklistOwnerAfterChangePeerReviewer [Start]")
+ cl_template = self.creator.createDefaultCheckListTemplate()
+ checklist = self.creator.createCheckList(
+ "cl-name", "peer_review", 1, None, self.engagement, cl_template,
+ self.admin_user, self.second_el_user)
+ logger.debug(
+ "action should success (200), set the engagement peer reviewer and change checklist owner")
+ response = self.c.put(urlStr, json.dumps({'peerreviewer': str(self.el_user_to_update.uuid)}), content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ checklist = Checklist.objects.get(uuid=checklist.uuid)
+ self.assertEqual(checklist.owner, self.el_user_to_update)
+ self.printTestName("testChecklistOwnerAfterChangePeerReviewer [End]")
+
+ def testChecklistOwnerAfterSwitchReviewers(self):
+ urlStr = self.urlPrefix + 'engagements/' + \
+ str(self.engagement.uuid) + '/switch-reviewers/'
+ print(urlStr)
+ self.printTestName("testChecklistOwnerAfterSwitchReviewers [Start]")
+ cl_template = self.creator.createDefaultCheckListTemplate()
+ checklist = self.creator.createCheckList(
+ "cl-name", "review", 1, None, self.engagement, cl_template,
+ self.admin_user, self.el_user)
+ logger.debug(
+ "action should success (200), switch between the engagement reviewer and peer reviewer and change checklist owner")
+ logger.debug("Reviewer: %s, PeerReviewer: %s" %
+ (self.engagement.reviewer, self.engagement.peer_reviewer))
+ response = self.c.put(urlStr, json.dumps({'reviewer': str(self.second_el_user.uuid), 'peerreviewer': str(
+ self.el_user.uuid)}), content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.adminToken})
+ print('Got response : ' + str(response.status_code))
+ checklist = Checklist.objects.get(uuid=checklist.uuid)
+ self.assertEqual(checklist.owner, self.second_el_user)
+ self.printTestName("testChecklistOwnerAfterSwitchReviewers [End]")
diff --git a/django/engagementmanager/tests/test_engagement_export.py b/django/engagementmanager/tests/test_engagement_export.py
new file mode 100755
index 0000000..9cbceb0
--- /dev/null
+++ b/django/engagementmanager/tests/test_engagement_export.py
@@ -0,0 +1,161 @@
+#
+# ============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 rest_framework.status import HTTP_200_OK,\
+ HTTP_500_INTERNAL_SERVER_ERROR
+from engagementmanager.models import Vendor, ECOMPRelease
+from engagementmanager.service.engagement_service import get_expanded_engs_for_export
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import EngagementStage, Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class EngagementExportTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ self.admin = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail,
+ 'Aa123456', 'admin user', self.el, True)
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ 'Aa123456', 'user', self.standard_user, True)
+
+ # Create an VF with Engagement (Active) - #1
+ self.engagement = self.creator.createEngagement(
+ 'just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(self.user, self.admin)
+ self.engagement.reviewer = self.admin
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_stage = EngagementStage.Active.name
+ self.engagement.save()
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"), self.engagement,
+ self.deploymentTarget, False, Vendor.objects.get(name=Constants.service_provider_company_name))
+ self.vf.ecomp_release = ECOMPRelease.objects.create(
+ uuid='uuid1', name='ActiveECOMPRelease')
+ self.vf.save()
+
+ # Create an VF with Engagement (Intake) - #2
+ self.engagement2 = self.creator.createEngagement(
+ 'just-a-fake-uuid2', 'Validation', None)
+ self.engagement2.engagement_team.add(self.user, self.admin)
+ self.engagement2.reviewer = self.admin
+ self.engagement2.peer_reviewer = self.peer_reviewer
+ self.engagement2.engagement_stage = EngagementStage.Intake.name
+ self.engagement2.save()
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf2 = self.creator.createVF(self.randomGenerator("randomString"), self.engagement2,
+ self.deploymentTarget, False, Vendor.objects.get(name='Other'))
+ self.vf2.ecomp_release = ECOMPRelease.objects.create(
+ uuid='uuid2', name='IntakeECOMPRelease')
+ self.vf2.save()
+
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.adminToken = self.loginAndCreateSessionToken(self.admin)
+
+ def testFailExport(self):
+ urlStr = self.urlPrefix + 'engagement/export/'
+ self.printTestName("Failed export [start]")
+ logger.debug(
+ "action should fail (500), missing arguments - stage and keyword")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_500_INTERNAL_SERVER_ERROR)
+ self.printTestName("Failed export [end]")
+
+ def testSuccessExport(self):
+ self.printTestName("Success export [start]")
+
+ urlStr = self.urlPrefix + 'engagement/export/?stage=Active&keyword'
+ logger.debug(
+ "action should success (200), and return one active engagement")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(response.content) > 0, True)
+ vfs, deployment_targets = get_expanded_engs_for_export(
+ "Active", "", self.user)
+ self.assertEqual(len(vfs) == 1, True)
+ self.assertEqual('ecomp_release__name' in vfs[0] and vfs[0]
+ ['ecomp_release__name'] == "ActiveECOMPRelease", True)
+
+ urlStr = self.urlPrefix + 'engagement/export/?stage=Intake&keyword'
+ logger.debug(
+ "action should success (200), and return one intake engagement")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(response.content) > 0, True)
+ vfs, deployment_targets = get_expanded_engs_for_export(
+ "Intake", "", self.user)
+ self.assertEqual(len(vfs) == 1, True)
+ self.assertEqual('ecomp_release__name' in vfs[0] and vfs[0]
+ ['ecomp_release__name'] == "IntakeECOMPRelease", True)
+
+ # Check keyword filtering:
+ urlStr = self.urlPrefix + 'engagement/export/?stage=All&keyword=Active'
+ logger.debug(
+ "action should success (200), and not return Intake engagement")
+ response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.assertEqual(len(response.content) > 0, True)
+ vfs, deployment_targets = get_expanded_engs_for_export(
+ "All", "Active", self.user)
+ self.assertEqual(len(vfs) == 0, True)
+
+ # Check overview sheet data procedure:
+ logger.debug("Check if the store procedure return data as expected (suppose to return 4 rows of overview "
+ "sheet) and by that assume that it exists")
+ self.assertEqual(len(deployment_targets), 4)
+
+ self.printTestName("Success export [end]")
diff --git a/django/engagementmanager/tests/test_expanded_eng.py b/django/engagementmanager/tests/test_expanded_eng.py
new file mode 100755
index 0000000..ec89d0b
--- /dev/null
+++ b/django/engagementmanager/tests/test_expanded_eng.py
@@ -0,0 +1,325 @@
+#
+# ============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
+import random
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.models import Vendor, VF
+from engagementmanager.utils.constants import Constants, EngagementStage
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class testGetExpandedEngsAndSearch(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+ # Create a user with role el
+ vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.el_user = self.creator.createUser(vendor, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ self.vendor = Vendor.objects.get(name='Other')
+ self.user = self.creator.createUser(self.vendor, "Johnny@d2ice.com", self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+ self.service_provider = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.peer_reviewer = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created Peer Reviewer:')
+ logger.debug('UUID: ' + str(self.peer_reviewer.uuid))
+ logger.debug('Full Name: ' + self.peer_reviewer.full_name)
+ logger.debug('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ engStageList = [EngagementStage.Intake.name, EngagementStage.Active.name,
+ EngagementStage.Validated.name, EngagementStage.Completed.name] # @UndefinedVariable
+ self.random_stage = engStageList[(random.randint(0, 3) * 2 + 1) % 4]
+ self.names_array = list()
+ for i in range(0, 14):
+ self.engagement = self.creator.createEngagement(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"), None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_manual_id = self.randomGenerator(
+ "randomString")
+ self.engagement.engagement_team.add(
+ self.el_user, self.peer_reviewer)
+ self.engagement.engagement_stage = engStageList[(
+ random.randint(0, 3) * 2 + 1) % 4]
+ self.engagement.save()
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+ self.names_array.append(self.engagement.engagement_manual_id)
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ # self.asInfrastructure = self.creator.createApplicationServiceInfrastructure(self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(
+ "vf_" + str(i), self.engagement, self.deploymentTarget, False, vendor)
+ self.vf.save()
+ self.names_array.append(self.vf.name)
+ print('-----------------------------------------------------')
+ print('Created VF:')
+ print('UUID: ' + str(self.vf.uuid))
+ print('-----------------------------------------------------')
+ if (i % 2 == 0):
+ self.engagement.engagement_team.add(self.user)
+ vfc = self.creator.createVFC(
+ "vfc_" + str(i), self.randomGenerator("randomNumber"), self.vendor, self.vf, self.el_user)
+ self.names_array.append(vfc.name)
+ self.engagement.save()
+
+ self.random_keyword = self.names_array[(
+ random.randint(0, len(self.names_array) - 1))]
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def test_get_expanded_even_numbered_engs_by_standard_user_no_keyword(self):
+ urlStr = self.urlPrefix + 'engagement/expanded/'
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Test started: test_get_expanded_even_numbered_engs_by_standard_user_no_keyword")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ postData = {'stage': 'All', 'keyword': '', 'offset': 0, 'limit': 15}
+ datajson = json.dumps(postData, ensure_ascii=False)
+ response = self.c.post(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ if (status != 200):
+ logger.error("Got response : " + str(status) +
+ " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Got content : " + str(response.content))
+ data = json.loads(response.content)
+ if (data['num_of_objects'] != 7):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "num of objects returned from server != 7 (all even numbers)")
+ self.assertEqual(data['num_of_objects'], 7)
+ for x in data['array']:
+ shortened_name = x['vf__name'].split('_')
+ if (int(shortened_name[1]) % 2 != 0):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error("Odd VF name returned")
+ self.assertEqual(int(shortened_name[1]) % 2, 0)
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_get_expanded_engs_with_filter_no_keyword(self):
+ urlStr = self.urlPrefix + 'engagement/expanded/'
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Test started: test_get_expanded_engs_with_filter_no_keyword")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ postData = {'stage': self.random_stage,
+ 'keyword': '', 'offset': 0, 'limit': 15}
+ datajson = json.dumps(postData, ensure_ascii=False)
+ response = self.c.post(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ if (status != 200):
+ logger.error("Got response : " + str(status) +
+ " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Got content : " + str(response.content))
+ data = json.loads(response.content)
+ print("random stage chosen: " + self.random_stage)
+ for x in data['array']:
+ print("engagement's stage: " + x['engagement__engagement_stage'])
+ if (x['engagement__engagement_stage'] != self.random_stage):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "VF With different stage than defined filter was retrieved")
+ self.assertEqual(
+ x['engagement__engagement_stage'], self.random_stage)
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_get_expanded_engs_with_keyword_nofilter(self):
+ urlStr = self.urlPrefix + 'engagement/expanded/'
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Test started: test_get_expanded_engs_with_filter_no_keyword")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ postData = {'stage': 'All', 'keyword': self.random_keyword,
+ 'offset': 0, 'limit': 15}
+ datajson = json.dumps(postData, ensure_ascii=False)
+ response = self.c.post(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Got content : " + str(response.content))
+ data = json.loads(response.content)
+ print("random keyword chosen: " + self.random_keyword)
+ for x in data['array']:
+ bool = False
+ if (x['engagement__engagement_manual_id'] != self.random_keyword and x['vf__name'] != self.random_keyword):
+ vf = VF.objects.get(engagement__uuid=x['engagement__uuid'])
+ urlStr = self.urlPrefix + 'vf/' + str(vf.uuid) + '/vfcs/'
+ vfc_of_x_response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ vfc_list = json.loads(vfc_of_x_response.content)
+ for vfc in vfc_list:
+ if vfc['name'] == self.random_keyword:
+ bool = True
+ break
+ else:
+ continue
+ else:
+ bool = True
+ if (not bool):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "VF With different stage than filter was retrieved")
+ self.assertEqual(
+ x['engagement__engagement_stage'], self.random_stage)
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_get_expanded_engs_with_keyword_and_filter(self):
+ urlStr = self.urlPrefix + 'engagement/expanded/'
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Test started: test_get_expanded_engs_with_filter_no_keyword")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ postData = {'stage': self.random_stage,
+ 'keyword': self.random_keyword, 'offset': 0, 'limit': 15}
+ datajson = json.dumps(postData, ensure_ascii=False)
+ response = self.c.post(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ if (status != 200):
+ logger.error("Got response : " + str(status) +
+ " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Got content : " + str(response.content))
+ data = json.loads(response.content)
+ print("random keyword chosen: " + self.random_keyword)
+ for x in data['array']:
+ bool = False
+ if (x['engagement__engagement_stage'] != self.random_stage):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "VF With different stage than defined filter was retrieved")
+ self.assertEqual(
+ x['engagement__engagement_stage'], self.random_stage)
+ if (x['engagement__engagement_manual_id'] != self.random_keyword and x['vf__name'] != self.random_keyword):
+ vf = VF.objects.get(engagement__uuid=x['engagement__uuid'])
+ urlStr = self.urlPrefix + 'vf' + str(vf.uuid) + '/vfcs/'
+ vfc_of_x_response = self.c.get(
+ urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ vfc_list = json.loads(vfc_of_x_response.content)
+ for vfc in vfc_list:
+ if (vfc['name'] == self.random_keyword):
+ bool = True
+ break
+ else:
+ continue
+ else:
+ bool = True
+ if (not bool):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "VF With different stage than filter was retrieved")
+ self.assertEqual(
+ x['engagement__engagement_stage'], self.random_stage)
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_get_expanded_engs_with_keyword_email(self):
+ urlStr = self.urlPrefix + 'engagement/expanded/'
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(
+ " Test started: test_get_expanded_engs_with_filter_no_keyword")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ email_test = "Johnny@d2ice.com"
+ postData = {'stage': 'All', 'keyword': email_test,
+ 'offset': 0, 'limit': 15}
+ datajson = json.dumps(postData, ensure_ascii=False)
+ response = self.c.post(
+ urlStr, datajson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Got content : " + str(response.content))
+ data = json.loads(response.content)
+ print("random keyword chosen: " + email_test)
+ if data['num_of_objects'] >= 1:
+ for vf_record in data['array']:
+ vf = VF.objects.get(
+ engagement__uuid=vf_record['engagement__uuid'])
+ if (not vf.engagement.engagement_team.filter(uuid=self.user.uuid).exists()):
+ self.loggerTestFailedOrSucceded(False)
+ logger.error(
+ "VF With different stage than filter was retrieved")
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
diff --git a/django/engagementmanager/tests/test_import_engagement_xls.py b/django/engagementmanager/tests/test_import_engagement_xls.py
new file mode 100755
index 0000000..8513998
--- /dev/null
+++ b/django/engagementmanager/tests/test_import_engagement_xls.py
@@ -0,0 +1,72 @@
+#
+# ============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 io import StringIO
+import os
+
+from django.core import management
+
+from engagementmanager.management.commands.initial_populate_db import execute_bootstrap_actions
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+
+
+class TestImportEngagementXLSTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ execute_bootstrap_actions()
+ pass
+
+ def initBody(self):
+ pass
+
+ ### TESTS ###
+ def testImportEngagementXLSTestCase(self):
+ self.initBody()
+ xls_path = 'engagementmanager/tests/D2_ICE_Engagements_Import_Example.xlsx'
+
+ if not os.path.exists(xls_path):
+ print("File doesnt exists")
+ return True
+
+ response = StringIO()
+
+ management.call_command('import_xls', xls_path, '2', stdout=response)
+ response = response.getvalue()
+ if response.find('True') != -1:
+ response = True
+ self.assertEqual(response, True)
diff --git a/django/engagementmanager/tests/test_invite_members.py b/django/engagementmanager/tests/test_invite_members.py
new file mode 100755
index 0000000..460eded
--- /dev/null
+++ b/django/engagementmanager/tests/test_invite_members.py
@@ -0,0 +1,164 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+import json
+from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
+from engagementmanager.models import Vendor, IceUserProfile
+from engagementmanager.utils.constants import Constants
+
+
+class TestInviteMembersTestCase(TestBaseEntity):
+
+ def createEng(self, name):
+ # Create an Engagement with team
+ engagement = self.creator.createEngagement(name, 'Validation', None)
+ engagement.reviewer = self.reviewer
+ engagement.peer_reviewer = self.reviewer
+ engagement.save()
+ engagement.engagement_team.add(self.inviter, self.el_user)
+ self.engList.append(engagement)
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(engagement.uuid))
+ print('-----------------------------------------------------')
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+ self.engList = []
+ self.vfList = []
+
+ # Create a user with role el
+ self.el_user_email = self.randomGenerator("main-vendor-email")
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name),
+ self.el_user_email, '55501000199', 'el user', self.el, True)
+ self.inviter = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'inviter user', self.standard_user, True)
+ self.reviewer = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'reviewer user', self.standard_user, True)
+
+ self.createEng('123456789')
+ self.createEng('abcdefghi')
+
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+
+ for eng in self.engList:
+ vf = self.creator.createVF(self.randomGenerator("randomString"), eng,
+ self.deploymentTarget, False, Vendor.objects.get(name='Other'))
+ self.vfList.append(vf)
+
+ self.urlStr = self.urlPrefix + "invite-team-members/"
+ self.data = dict()
+ self.data2 = dict()
+ self.token = self.loginAndCreateSessionToken(self.inviter)
+
+ def initBody(self):
+ self.invitedData = []
+
+ self.data['email'] = self.randomGenerator("main-vendor-email")
+ self.data['eng_uuid'] = str(self.engList[0].uuid)
+ self.invitedData.append(self.data)
+
+ self.data2['email'] = self.el_user_email
+ self.data2['eng_uuid'] = str(self.engList[0].uuid)
+ self.invitedData.append(self.data2)
+
+ def inviteContact(self, expectedStatus=HTTP_200_OK):
+ self.invitedDataStr = json.dumps(self.invitedData, ensure_ascii=False)
+ response = self.c.post(self.urlStr, self.invitedDataStr, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code), str(response.content))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ def createContactUser(self):
+ self.contact = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.data['email'], self.data['phone_number'], self.data['full_name'], self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.contact.uuid))
+ print('Full Name: ' + self.contact.full_name)
+ print('-----------------------------------------------------')
+
+ ### TESTS ###
+ def testAddContactForNonExistingContact(self):
+ self.initBody()
+ self.inviteContact()
+
+ def testThrotellingInviteSameEmailSameEng(self):
+ self.invitedData = []
+
+ self.data['email'] = self.el_user_email
+ self.data['eng_uuid'] = str(self.engList[0].uuid)
+ self.invitedData.append(self.data)
+
+ self.data2['email'] = self.el_user_email
+ self.data2['eng_uuid'] = str(self.engList[0].uuid)
+ self.invitedData.append(self.data2)
+
+ self.inviteContact(expectedStatus=HTTP_400_BAD_REQUEST)
+
+ def testThrotellingInviteMoreThan5EmailsToSameEng(self):
+ self.invitedData = []
+
+ for i in range(0, 30):
+ data = dict()
+ data['email'] = self.randomGenerator("main-vendor-email")
+ data['eng_uuid'] = str(self.engList[0].uuid)
+ self.invitedData.append(data)
+
+ self.inviteContact(expectedStatus=HTTP_400_BAD_REQUEST)
+
+ def testMultipleInvitationsForSameUserDiffEng(self):
+ for i in range(0, 2):
+ data = dict()
+ data['email'] = self.el_user_email
+ data['eng_uuid'] = str(self.engList[i].uuid)
+ self.invitedData = []
+ self.invitedData.append(data)
+ self.inviteContact(expectedStatus=HTTP_200_OK)
+ invitedUser = IceUserProfile.objects.get(email=data['email'])
+ self.assertTrue(invitedUser in self.engList[i].engagement_team.all())
diff --git a/django/engagementmanager/tests/test_next_steps.py b/django/engagementmanager/tests/test_next_steps.py
new file mode 100755
index 0000000..95a8227
--- /dev/null
+++ b/django/engagementmanager/tests/test_next_steps.py
@@ -0,0 +1,80 @@
+#
+# ============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 unittest
+
+from mock import MagicMock
+
+from engagementmanager.service.nextstep_service import NextStepSvc
+from engagementmanager.utils.constants import NextStepState
+
+
+class NextStepTest(unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testStandardUserActions(self):
+ print('---------------------------------- Testing standard_user Actions ------------------------------------')
+ user = MagicMock()
+ user.role.name = 'standard_user'
+
+ NextStepSvc().validate_state_transition(
+ user, NextStepState.Incomplete, NextStepState.Completed)
+
+ NextStepSvc().validate_state_transition(
+ user, NextStepState.Completed, NextStepState.Incomplete)
+
+ def testELUserActions(self):
+ print('---------------------------------- Testing EL Actions ------------------------------------')
+ user = MagicMock()
+ user.role.name = 'el'
+
+ print(user.role)
+
+ update_type = NextStepSvc().validate_state_transition(
+ user, NextStepState.Completed, NextStepState.Incomplete)
+ assert update_type == 'Denied'
+
+
+if __name__ == "__main__":
+ # import sys;sys.argv = ['', 'Test.testSetState']
+ unittest.main()
diff --git a/django/engagementmanager/tests/test_next_steps_api.py b/django/engagementmanager/tests/test_next_steps_api.py
new file mode 100755
index 0000000..b0be468
--- /dev/null
+++ b/django/engagementmanager/tests/test_next_steps_api.py
@@ -0,0 +1,367 @@
+#
+# ============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 uuid import uuid4
+
+from rest_framework import status
+from rest_framework.status import HTTP_403_FORBIDDEN, HTTP_200_OK, \
+ HTTP_204_NO_CONTENT
+
+from engagementmanager.models import Vendor, NextStep
+from engagementmanager.service.nextstep_service import NextStepSvc
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class TestNextStepsAPI(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ self.pruser = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.pruser.uuid))
+ print('Full Name: ' + self.pruser.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user with SSH key
+ self.user_with_ssh = self.creator.createUser(Vendor.objects.get(
+ name='Other'), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'ssh user', self.standard_user, True, 'just-a-fake-ssh-key')
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user_with_ssh.uuid))
+ print('Full Name: ' + self.user_with_ssh.full_name)
+ print('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.el_user
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.save()
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with team with SSH Key
+ self.engagement_ssh = self.creator.createEngagement('just-another-fake-uuid', 'Validation', None)
+ self.engagement_ssh.engagement_team.add(self.user_with_ssh, self.el_user)
+ self.engagement_ssh.peer_reviewer = self.pruser
+ self.engagement_ssh.save()
+
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_ssh.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with Main Contact
+ self.engagement_with_contact = self.creator.createEngagement('yet-just-another-fake-uuid', 'Validation', None)
+ self.engagement_with_contact.engagement_team.add(self.user, self.el_user)
+ self.engagement_with_contact.contact_user = self.user
+ self.engagement_with_contact.peer_reviewer = self.pruser
+ self.engagement_with_contact.save()
+
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_with_contact.uuid))
+ print('-----------------------------------------------------')
+
+ # Create another Engagement with Main Contact
+ self.engagement_4_createNS = self.creator.createEngagement('yet-just-another-fake-uuid2', 'Validation', None)
+ self.engagement_4_createNS.reviewer = self.el_user
+ self.engagement_4_createNS.peer_reviewer = self.el_user
+ self.engagement_4_createNS.engagement_team.add(self.user_with_ssh, self.el_user)
+ self.engagement_4_createNS.contact_user = self.user_with_ssh
+ self.engagement_4_createNS.save()
+
+ # Create engagement for order
+ self.engagement_4_order = self.creator.createEngagement('yet-just-another-fake-uuid3', 'Validation', None)
+ self.engagement_4_order.reviewer = self.el_user
+ self.engagement_4_order.peer_reviewer = self.el_user
+ self.engagement_4_order.engagement_team.add(self.user_with_ssh, self.el_user)
+ self.engagement_4_order.contact_user = self.user_with_ssh
+ self.engagement_4_order.save()
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vendor = Vendor.objects.get(name='Other')
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement_4_createNS, self.deploymentTarget, False, self.vendor)
+
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement_4_createNS.uuid))
+ print('-----------------------------------------------------')
+
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.sshtoken = self.loginAndCreateSessionToken(self.user_with_ssh)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ def testCreateDefaultNextStepsAndSetNextStepsState(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/nextsteps/Intake'
+ NextStepSvc().create_default_next_steps(self.user, self.engagement, self.el_user)
+ NextStepSvc().create_default_next_steps_for_user(self.user, self.el_user)
+ num_of_steps = 3
+
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+# content = response.content
+
+ print('Test that GET nextsteps was successful')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ print('Test that GET nextsteps in Intake state returns 3 items ')
+ self.assertEqual(len(response.json()), num_of_steps)
+
+ print('Test First item state is Incomplete: ' + response.json()[0]['state'])
+ self.assertEqual(response.json()[0]['state'], 'Incomplete')
+
+ step_uuid = response.json()[0]['uuid']
+ urlStr = self.urlPrefix + 'nextsteps/' + step_uuid + '/state'
+
+ print('attempt change state of next step Incomplete->COMPLETED by standard_user. This should succeed...')
+ response = self.c.put(urlStr, '{ "state" : "Completed" }',
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ print('Negative: attempt change state of next step COMPLETED->Incomplete by EL. This should success')
+ response = self.c.put(urlStr, '{ "state" : "Incomplete" }',
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testCreateDefaultNextStepsForUserWithSSHKey(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/nextsteps/Intake'
+ NextStepSvc().create_default_next_steps(self.user_with_ssh, self.engagement_ssh, self.el_user)
+ # Would not create any next step, due to the reason that the user already has an SSH
+ NextStepSvc().create_default_next_steps_for_user(self.user_with_ssh, self.el_user)
+ num_of_steps = 2
+
+ response = self.c.get(urlStr.replace('${uuid}', str(self.engagement_ssh.uuid)),
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+ print('Test that GET nextsteps was successful')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ print('Test that GET nextsteps in Intake state returns 3 items ')
+ self.assertEqual(len(response.json()), num_of_steps)
+
+ def testOrderNextSteps(self):
+
+ nsDict = {}
+ nsDict["position"] = 4
+ nsDict["creator_uuid"] = str(self.el_user.uuid)
+ nsDict[
+ "description"] = "Please submit the first version of the VF package. If you have any problems or questions please contact your Engagement Lead (EL)"
+ nsDict["state"] = "Incomplete"
+ nsDict["engagement_stage"] = "Active"
+
+ myjson = json.dumps([nsDict], ensure_ascii=False)
+
+ create_nextsteps_url = self.urlPrefix + "engagements/" + str(self.engagement_4_order.uuid) + "/nextsteps/"
+ response = self.c.post(create_nextsteps_url, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ response = self.c.post(create_nextsteps_url, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ response = self.c.post(create_nextsteps_url, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+
+ get_nextsteps_url = self.urlPrefix + 'engagements/${uuid}/nextsteps/Intake'
+ response = self.c.get(get_nextsteps_url.replace('${uuid}', str(
+ self.engagement_4_order.uuid)), **{'HTTP_AUTHORIZATION': "token " + self.sshtoken})
+
+ decoded_ns = json.loads(response.content)
+ myjson = json.dumps(decoded_ns, ensure_ascii=False)
+ order_nextsteps_url = self.urlPrefix + 'engagements/' + \
+ str(self.engagement_4_order.uuid) + '/nextsteps/order_next_steps/'
+ response = self.c.put(order_nextsteps_url, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+
+ response = self.c.get(get_nextsteps_url.replace('${uuid}', str(
+ self.engagement_4_order.uuid)), **{'HTTP_AUTHORIZATION': "token " + self.sshtoken})
+
+ decoded_ns = json.loads(response.content)
+ counter = 0
+ for next_step in decoded_ns:
+ self.assertEqual(next_step['position'], counter)
+ counter += 1
+
+ def testCreateDefaultNextStepsWhenENGContactExist(self):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/nextsteps/Intake'
+ NextStepSvc().create_default_next_steps(self.user, self.engagement_with_contact, self.el_user)
+ NextStepSvc().create_default_next_steps_for_user(self.user, self.el_user)
+ num_of_steps = 2
+
+ response = self.c.get(urlStr.replace('${uuid}', str(
+ self.engagement_with_contact.uuid)), **{'HTTP_AUTHORIZATION': "token " + self.token})
+
+ print('Got response : ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+ print('Test that GET nextsteps was successful')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ print('Test that GET nextsteps in Intake state returns 3 items ')
+ self.assertEqual(len(response.json()), num_of_steps)
+
+ def testAddNextStepToEng(self):
+ urlStr = self.urlPrefix + "engagements/" + str(self.engagement_4_createNS.uuid) + "/nextsteps/"
+
+ NextStepSvc().create_default_next_steps(self.user_with_ssh, self.engagement_4_createNS, self.el_user)
+ # Would not create any next step, due to the reason that the user already has an SSH
+ NextStepSvc().create_default_next_steps_for_user(self.user_with_ssh, self.el_user)
+
+ nsDict = {}
+ nsDict["position"] = "4"
+ nsDict["creator_uuid"] = str(self.el_user.uuid)
+ nsDict[
+ "description"] = "Please submit the first version of the VF package. If you have any problems or questions please contact your Engagement Lead (EL)"
+ nsDict["state"] = "Incomplete"
+ nsDict["engagement_stage"] = "Active"
+
+ myjson = json.dumps([nsDict], ensure_ascii=False)
+ print(myjson)
+
+ response = self.c.post(urlStr, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ def testDelNextStepToEng(self):
+ nsObj = NextStep.objects.create(uuid=uuid4(), creator=self.el_user, position=2, description="testDelNextStepToEng",
+ state='Incomplete', engagement_stage="Intake", engagement=self.engagement)
+ urlStr = self.urlPrefix + "nextsteps/" + str(nsObj.uuid)
+
+ response = self.c.delete(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+ self.assertEqual(response.status_code, HTTP_204_NO_CONTENT)
+
+ def testNegativeDelNextStepToEngNoHeader(self):
+ nsObj = NextStep.objects.create(uuid=uuid4(), creator=self.el_user, position=2, description="testDelNextStepToEng",
+ state='Incomplete', engagement_stage="Intake", engagement=self.engagement)
+ urlStr = self.urlPrefix + "nextsteps/" + str(nsObj.uuid)
+
+ response = self.c.delete(urlStr)
+ print('Negative: Expecting response 403, got: ' + str(response.status_code))
+ print("DATA After JSON Parse:" + str(response.content))
+
+ self.assertEqual(response.status_code, HTTP_403_FORBIDDEN)
+
+ def testEditNextSteps(self):
+ print(
+ '---------------------------------- testEditNextSteps, Expecting 200 ------------------------------------')
+ print('---------------------------------- Creating a next step ------------------------------------')
+ step = NextStep.objects.create(position="4", creator=self.el_user, engagement=self.engagement,
+ description="Please submit the first version of the VF package. If you have any problems or questions please contact your Engagement Lead (EL)",
+ state="TODO", engagement_stage="Active",
+ uuid=uuid4())
+ print('---------------------------------- Editing the next step ------------------------------------')
+ urlStr = self.urlPrefix + "nextsteps/" + str(step.uuid)
+ body = {}
+ files = []
+ for i in range(4):
+ files.append(self.randomGenerator('randomString'))
+ body['files'] = files
+ body['duedate'] = "2012-01-03"
+ body['description'] = self.randomGenerator('randomString')
+ body['assigneesUuids'] = [str(self.user.uuid), str(self.el_user.uuid)]
+ myjson = json.dumps(body, ensure_ascii=False)
+ print(myjson)
+ response = self.c.put(urlStr, myjson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print(urlStr)
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, status.HTTP_200_OK)
+
+ def testUserNextSteps(self):
+ NextStepSvc().create_default_next_steps(self.user_with_ssh, self.engagement_4_createNS, self.el_user)
+ # Needs to return 0 elements for regular user which is not the assignee:
+ urlStr = self.urlPrefix + 'engagements/user/nextsteps/'
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.sshtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ data = json.loads(response.content)
+ self.assertEqual(data["data"], [])
+ self.assertEqual(data["count"], 0)
+
+ # Needs to return 3 elements to el user which is the assignee:
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ data = json.loads(response.content)
+ self.assertEqual(data["count"], 3)
diff --git a/django/engagementmanager/tests/test_notify_inactive_engagements.py b/django/engagementmanager/tests/test_notify_inactive_engagements.py
new file mode 100755
index 0000000..afeb835
--- /dev/null
+++ b/django/engagementmanager/tests/test_notify_inactive_engagements.py
@@ -0,0 +1,232 @@
+#
+# ============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 random
+from uuid import uuid4
+
+from django.utils.timezone import timedelta
+import mock
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.daily_scheduled_message import DailyScheduledMessage
+from engagementmanager.models import Vendor, Engagement, Activity, Notification
+from engagementmanager.utils.constants import EngagementStage, ActivityType, Constants
+from django.utils import timezone
+
+
+def mocked_max_empty_date_negative(self, creation_time):
+ max_empty_time = creation_time + timedelta(days=-1)
+ return max_empty_time
+
+
+def with_files(vf):
+ list_of_files = list()
+ for index in range(3):
+ current_file_dict = dict()
+ current_file_dict['id'] = ''.join(random.choice(
+ '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16))
+ current_file_dict['name'] = 'file%d' % index
+ current_file_dict['type'] = 'blob'
+ current_file_dict['mode'] = '100644'
+ list_of_files.append(current_file_dict)
+ return list_of_files
+
+
+def get_days_delta_plus_1(self, start_time, end_time):
+ end_time = end_time + timedelta(days=1)
+ return (end_time - start_time).days
+
+
+def get_days_delta_plus_7(self, start_time, end_time):
+ end_time = end_time + timedelta(days=7)
+ return (end_time - start_time).days
+
+
+def get_days_delta_plus_23(self, start_time, end_time):
+ end_time = end_time + timedelta(days=23)
+ return (end_time - start_time).days
+
+
+def get_days_delta_plus_29(self, start_time, end_time):
+ end_time = end_time + timedelta(days=29)
+ return (end_time - start_time).days
+
+
+def no_files(vf):
+ return []
+
+
+class TestNotifyInactiveEngagements(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs', 'Other'])
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ # For negative tests
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.urlStr = self.urlPrefix + "engagement/@eng_uuid/checklist/new/"
+ self.data = dict()
+ self.template = self.creator.createDefaultCheckListTemplate()
+# self.engagement = Engagement.objects.create(uuid='just-a-fake-uuid',engagement_stage='Validation')
+ self.engagement = self.creator.createEngagement(uuid4(), 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.el_user
+ self.engagement.engagement_team.add(self.user)
+ self.engagement.engagement_manual_id = str(timezone.now().year) + "-1"
+ self.engagement.engagement_team.add(self.el_user)
+ self.engagement.engagement_stage = EngagementStage.Active.name
+ self.engagement.save()
+ self.vendor = Vendor.objects.get(name='Other')
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', with_files)
+ def testOnlyNotActiveEngagementsAreNotEffected(self):
+ self.engagement.engagement_stage = EngagementStage.Archived.name
+ self.engagement.save()
+
+ bus_service.send_message(DailyScheduledMessage())
+ updated_engagement = Engagement.objects.get(uuid=self.engagement.uuid)
+
+ self.assertEqual(updated_engagement.is_with_files, False)
+
+ @mock.patch('engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler.DailyNotifyInactiveEngagementsHandler.get_max_empty_date', mocked_max_empty_date_negative)
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ def testEngagementsWithouthFilesOlderThan30DaysAreArchive(self):
+ bus_service.send_message(DailyScheduledMessage())
+ updated_engagement = Engagement.objects.get(uuid=self.engagement.uuid)
+
+ self.assertEqual(updated_engagement.is_with_files, False)
+ self.assertEqual(updated_engagement.engagement_stage, EngagementStage.Archived.name)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ def testEngagementsWithouthFilesYoungerThan30DaysNotArchive(self):
+ bus_service.send_message(DailyScheduledMessage())
+ updated_engagement = Engagement.objects.get(uuid=self.engagement.uuid)
+
+ self.assertEqual(updated_engagement.is_with_files, False)
+ self.assertEqual(updated_engagement.engagement_stage, EngagementStage.Active.name)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ def testEngagementsWithouthFilesIsNotMarked(self):
+ bus_service.send_message(DailyScheduledMessage())
+ updated_engagement = Engagement.objects.get(uuid=self.engagement.uuid)
+
+ self.assertEqual(updated_engagement.is_with_files, False)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', with_files)
+ def testEngagementsWithoFilesNotSentEmail(self):
+ bus_service.send_message(DailyScheduledMessage())
+ new_activity = Activity.objects.filter(
+ engagement=self.engagement,
+ activity_type=ActivityType.notice_empty_engagement.name
+ )
+ self.assertEqual(0, len(new_activity))
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ @mock.patch('engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler.DailyNotifyInactiveEngagementsHandler.get_days_delta', get_days_delta_plus_1)
+ def testEngagementsWithoutFilesOneDayEmailNotSent(self):
+ bus_service.send_message(DailyScheduledMessage())
+ new_activity = Activity.objects.filter(
+ engagement=self.engagement,
+ activity_type=ActivityType.notice_empty_engagement.name
+ )
+ self.assertEqual(0, len(new_activity))
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ @mock.patch('engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler.DailyNotifyInactiveEngagementsHandler.get_days_delta', get_days_delta_plus_7)
+ def testEngagementsWithoutFiles7DayEmailSent(self):
+ bus_service.send_message(DailyScheduledMessage())
+ new_activity = Activity.objects.get(
+ engagement=self.engagement,
+ activity_type=ActivityType.notice_empty_engagement.name
+ )
+
+ new_notifications = Notification.objects.filter(activity=new_activity)
+ self.assertNotEqual(0, len(new_notifications))
+
+ for notifcation in new_notifications:
+ self.assertEqual(notifcation.is_sent, True)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ @mock.patch('engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler.DailyNotifyInactiveEngagementsHandler.get_days_delta', get_days_delta_plus_23)
+ def testEngagementsWithoutFiles23DayEmailSent(self):
+ bus_service.send_message(DailyScheduledMessage())
+ new_activity = Activity.objects.get(
+ engagement=self.engagement,
+ activity_type=ActivityType.notice_empty_engagement.name
+ )
+
+ new_notifications = Notification.objects.filter(activity=new_activity)
+ self.assertNotEqual(0, len(new_notifications))
+
+ for notifcation in new_notifications:
+ self.assertEqual(notifcation.is_sent, True)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', no_files)
+ @mock.patch('engagementmanager.bus.handlers.daily_notify_inactive_engagements_handler.DailyNotifyInactiveEngagementsHandler.get_days_delta', get_days_delta_plus_29)
+ def testEngagementsWithoutFiles29DayEmailSent(self):
+ bus_service.send_message(DailyScheduledMessage())
+ new_activity = Activity.objects.get(
+ engagement=self.engagement,
+ activity_type=ActivityType.notice_empty_engagement.name
+ )
+
+ new_notifications = Notification.objects.filter(activity=new_activity)
+ self.assertNotEqual(0, len(new_notifications))
+
+ for notifcation in new_notifications:
+ self.assertEqual(notifcation.is_sent, True)
+
+ @mock.patch('validationmanager.em_integration.vm_api.get_list_of_repo_files_callback', with_files)
+ def testEngagementsWithFilesIsMarked(self):
+
+ bus_service.send_message(DailyScheduledMessage())
+ updated_engagement = Engagement.objects.get(uuid=self.engagement.uuid)
+
+ self.assertEqual(updated_engagement.is_with_files, True)
diff --git a/django/engagementmanager/tests/test_pull_notifications.py b/django/engagementmanager/tests/test_pull_notifications.py
new file mode 100755
index 0000000..1c22437
--- /dev/null
+++ b/django/engagementmanager/tests/test_pull_notifications.py
@@ -0,0 +1,134 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.activity_event_message import ActivityEventMessage
+from engagementmanager.models import Vendor
+from engagementmanager.utils.constants import Constants, ActivityType
+from engagementmanager.utils.activities_data import ActivityData, UserJoinedEngagementActivityData
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class NotificationsTestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+
+ self.createDefaultRoles()
+ # Create a user with role el
+ vendor = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.peer_reviewer = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ self.el_user = self.creator.createUser(vendor,
+ self.randomGenerator("main-vendor-email"),
+ self.randomGenerator("randomNumber"),
+ self.randomGenerator("randomString"), self.el, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.el_user.uuid))
+ print('Full Name: ' + self.el_user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ vendor = Vendor.objects.get(name='Other')
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(self.randomGenerator(
+ "randomString"), self.randomGenerator("randomString"), None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ print('-----------------------------------------------------')
+ print('Created Engagement:')
+ print('UUID: ' + str(self.engagement.uuid))
+ print('-----------------------------------------------------')
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ # Create a VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, vendor)
+
+ print('-----------------------------------------------------')
+ print('Created VF:')
+ print('UUID: ' + str(vendor.uuid))
+ print('-----------------------------------------------------')
+
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def testPullNotifications(self):
+
+ urlStr = self.urlPrefix + 'notifications/'
+
+ logger.debug("Starting pull notification test")
+ logger.debug("Creating a random new user")
+ vendor = Vendor.objects.get(name='Other')
+ randomUser = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ self.engagement.engagement_team.add(randomUser)
+ self.engagement.save()
+
+ logger.debug(
+ "created a new user & added them to the engagement team, going to create the activity and consider it as a notification")
+ usersList = []
+ usersList.append(randomUser)
+ activity_data = UserJoinedEngagementActivityData(
+ self.vf, usersList, self.engagement)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+ response = self.c.get(urlStr + str(randomUser.uuid) +
+ "/0/1", **{'HTTP_AUTHORIZATION': "token " + self.token})
+ content = response.content
+ status = response.status_code
+ logger.debug("Got response : " + str(status))
+ logger.debug("Got response : " + str(content))
+ if (status != 200):
+ logger.error("Got response : " + str(status) +
+ " , wrong http response returned ")
+ self.assertEqual(response.status_code, 200)
+ logger.debug("Ended pullNotifications test ")
diff --git a/django/engagementmanager/tests/test_rados_gateway.py b/django/engagementmanager/tests/test_rados_gateway.py
new file mode 100755
index 0000000..0d81ecc
--- /dev/null
+++ b/django/engagementmanager/tests/test_rados_gateway.py
@@ -0,0 +1,178 @@
+#
+# ============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
+import time
+from engagementmanager.tests.test_base_transaction_entity import TestBaseTransactionEntity
+from django.test.testcases import TransactionTestCase
+from django.conf import settings
+import mock
+from rest_framework.status import HTTP_202_ACCEPTED
+from engagementmanager.models import Vendor, Engagement, VF
+from engagementmanager.utils.constants import Constants, EngagementStage
+from wheel.signatures import assertTrue
+
+
+def get_or_create_bucket_mock(name):
+ bucket = {'bucket': name,
+ 'categories': [
+ {'bytes_received': 0,
+ 'bytes_sent': 1388,
+ 'category': 'list_buckets',
+ 'ops': 4,
+ 'successful_ops': 4}],
+ 'epoch': 1499821200,
+ 'owner': 'staticfiles',
+ 'time': '2017-07-12 01:00:00.000000Z'}
+
+ return bucket
+
+
+def add_bucket_user_mock(user, bucket):
+ RadosGatewayTestCase.users_added_to_mock.append(user)
+ RadosGatewayTestCase.added_bucket = bucket
+ print("*****RadosGatewayTestCase.added_bucket*****",RadosGatewayTestCase.added_bucket)
+
+
+def remove_bucket_user_grants_mock(bucket, user):
+ RadosGatewayTestCase.added_bucket = bucket
+ RadosGatewayTestCase.users_added_to_mock.remove(user)
+
+
+def blank_mock(vf):
+ print("===--blank mock was activated--===")
+ pass
+
+
+@mock.patch('validationmanager.em_integration.vm_api.get_or_create_bucket', get_or_create_bucket_mock)
+@mock.patch('validationmanager.em_integration.vm_api.add_bucket_user', add_bucket_user_mock)
+@mock.patch('validationmanager.em_integration.vm_api.remove_bucket_user_grants', remove_bucket_user_grants_mock)
+@mock.patch('validationmanager.em_integration.vm_api.ensure_git_entities', blank_mock)
+@mock.patch('validationmanager.em_integration.vm_api.ensure_jenkins_job', blank_mock)
+@mock.patch('validationmanager.em_integration.vm_api.ensure_checklists', blank_mock)
+class RadosGatewayTestCase(TestBaseTransactionEntity):
+ users_added_to_mock = []
+ added_bucket = None
+
+ def changeEngagementStage(self, stage):
+ self.urlStr = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid) + "/stage/@stage"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.put(self.urlStr.replace("@stage", stage), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+
+ def waitForBucket(self):
+ counter = 1
+ while (RadosGatewayTestCase.added_bucket == None and counter <=20):
+ time.sleep(1)
+ time.sleep(1)
+ if RadosGatewayTestCase.added_bucket == None :
+ raise Exception("Max retries exceeded, failing test...")
+ return False
+ elif RadosGatewayTestCase.added_bucket != None:
+ return True
+
+ def childSetup(self):
+ RadosGatewayTestCase.users_added_to_mock = []
+ RadosGatewayTestCase.added_bucket = None
+ settings.IS_SIGNAL_ENABLED = True
+ self.s3_host = settings.AWS_S3_HOST
+ self.s3_port = settings.AWS_S3_PORT
+
+ vendor_uuid, self.service_provider = self.creator.createVendor(Constants.service_provider_company_name)
+ self.urlStr = self.urlPrefix + "signup/"
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+
+ self.data = dict()
+ uuid, vendor = self.creator.createVendor(Constants.service_provider_company_name)
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+
+ self.params = '{"company":"' + str(self.user.company) + '","full_name":"' + self.user.full_name + '","email":"' \
+ + self.user.email + '","phone_number":"' + self.user.phone_number + \
+ '","password":"' + self.user.user.password + '","regular_email_updates":"' + \
+ str(self.user.regular_email_updates) + \
+ '","is_service_provider_contact":"' + str(self.user.is_service_provider_contact) + '"}'
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_team.add(self.el_user, self.user)
+ self.engagement.engagement_manual_id = self.randomGenerator("randomString")
+ self.engagement.save()
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.service_provider)
+ self.userToken = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ def testCreateBucketWithUser(self):
+ self.assertTrue(self.added_bucket is None)
+ self.changeEngagementStage(EngagementStage.Active.name)
+ self.assertTrue(RadosGatewayTestCase.added_bucket is not None)
+ team_members_list = [entry for entry in self.engagement.engagement_team.all()]
+ for team_member in team_members_list:
+ assertTrue(any(team_member.full_name == entity.full_name for entity in RadosGatewayTestCase.users_added_to_mock))
+
+
+ def testDeleteUsersFromBucket(self):
+ self.changeEngagementStage(EngagementStage.Active.name)
+ self.changeEngagementStage(EngagementStage.Validated.name)
+ self.waitForBucket()
+ self.assertTrue(RadosGatewayTestCase.added_bucket is not None)
+ self.assertTrue(RadosGatewayTestCase.users_added_to_mock == [])
+
+ def testDeleteUsersFromBucketWhichNotCreated(self):
+ self.assertTrue(RadosGatewayTestCase.added_bucket is None)
+ self.changeEngagementStage(EngagementStage.Validated.name)
+ self.waitForBucket()
+ self.assertTrue(RadosGatewayTestCase.added_bucket is not None)
+ self.assertTrue(RadosGatewayTestCase.users_added_to_mock == [])
+
+ def testDeleteUsersFromBucketWhwenStageArchive(self):
+ self.assertTrue(RadosGatewayTestCase.added_bucket is None)
+ self.changeEngagementStage(EngagementStage.Archived.name)
+ self.waitForBucket()
+ self.assertTrue(RadosGatewayTestCase.added_bucket is not None)
+ self.assertTrue(RadosGatewayTestCase.users_added_to_mock == [])
diff --git a/django/engagementmanager/tests/test_remove_user_from_eng_team.py b/django/engagementmanager/tests/test_remove_user_from_eng_team.py
new file mode 100755
index 0000000..15bcf2d
--- /dev/null
+++ b/django/engagementmanager/tests/test_remove_user_from_eng_team.py
@@ -0,0 +1,210 @@
+#
+# ============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 rest_framework.status import HTTP_204_NO_CONTENT
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestEngagementSetStage(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+ self.vendor = Vendor.objects.get(name='Amdocs')
+ self.service_provider = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.createDefaultRoles()
+
+ # For negative tests
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.user2 = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user2', self.standard_user, True)
+ # Create users with role el (el+peer reviwer)
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ # Create a user with admin role
+ self.admin_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail,
+ '55501000199', 'admin user', self.admin, True)
+
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_team.add(self.el_user, self.user, self.user2)
+ self.engagement.save()
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+# self.asInfrastructure = self.creator.createApplicationServiceInfrastructure(self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+# self.vf.service_infrastructures.add(self.asInfrastructure)
+
+ self.data = dict()
+ self.user_token = self.loginAndCreateSessionToken(self.user)
+ self.user2_token = self.loginAndCreateSessionToken(self.user2)
+ self.admin_token = self.loginAndCreateSessionToken(self.admin_user)
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def test_remove_user_from_eng_team_by_admin(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test 2 started: Admin removes user from the eng team!")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ self.urlStr = self.urlPrefix + "engagements/engagement-team/"
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.data['user_uuid'] = str(self.user.uuid)
+
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- sending put request with body -----")
+ logger.debug("**********************************************************************")
+
+ response = self.c.put(self.urlStr, datajson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ if (response.status_code != HTTP_204_NO_CONTENT):
+ print(response.status_code)
+ response2 = self.c.get(self.get_engagement_url, {}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+
+ # Check if the user it still in the engagement team
+ received_eng = json.loads(response2.content)
+ found = False
+ for item in received_eng["engagement"]["engagement_team"]:
+ if (self.user.email == item["email"]):
+ found = True
+ break
+ if found:
+ self.loggerTestFailedOrSucceded(False)
+ self.assert_(False, "user is still in the eng_team")
+ else:
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_negative_remove_user_from_eng_team_by_another_user(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test 3 (Negative) started: User2 removes user1 from the eng team!")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ self.urlStr = self.urlPrefix + "engagements/engagement-team/"
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.data['user_uuid'] = str(self.user.uuid)
+
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- sending put request with body -----")
+ logger.debug("**********************************************************************")
+
+ response = self.c.put(self.urlStr, datajson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.user2_token})
+ if (response.status_code != HTTP_204_NO_CONTENT):
+ print(response.status_code)
+ response2 = self.c.get(self.get_engagement_url, {}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+
+ # Check if the user it still in the engagement team(it is supposed to remain there)
+ received_eng = json.loads(response2.content)
+ found = False
+ for item in received_eng["engagement"]["engagement_team"]:
+ if (self.user.email == item["email"]):
+ found = True
+ break
+ if not found:
+ self.loggerTestFailedOrSucceded(False)
+ self.assert_(False, "user is NOT in the eng_team")
+ else:
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_negative_remove_el_user_from_eng_team_by_admin(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test 4 (Negative) started: admin removes el_user from the eng team!")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ self.urlStr = self.urlPrefix + "engagements/engagement-team/"
+ self.data['eng_uuid'] = str(self.engagement.uuid)
+ self.data['user_uuid'] = str(self.el_user.uuid)
+
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- sending put request with body -----")
+ logger.debug("**********************************************************************")
+
+ response = self.c.put(self.urlStr, datajson, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ if (response.status_code != HTTP_204_NO_CONTENT):
+ print(response.status_code)
+ response2 = self.c.get(self.get_engagement_url, {}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+
+ # Check if the user it still in the engagement team(it is supposed to remain there)
+ received_eng = json.loads(response2.content)
+ found = False
+ for item in received_eng["engagement"]["engagement_team"]:
+ if (self.el_user.email == item["email"]):
+ found = True
+ break
+ if not found:
+ self.loggerTestFailedOrSucceded(False)
+ self.assert_(False, "el user was NOT found in the eng_team")
+ else:
+ self.loggerTestFailedOrSucceded(True)
diff --git a/django/engagementmanager/tests/test_request_data_manager.py b/django/engagementmanager/tests/test_request_data_manager.py
new file mode 100755
index 0000000..580301e
--- /dev/null
+++ b/django/engagementmanager/tests/test_request_data_manager.py
@@ -0,0 +1,205 @@
+#
+# ============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 concurrent.futures import ThreadPoolExecutor
+import json
+from random import randint
+import threading
+import time
+from django.db import connections
+from django.test.client import Client
+from django.test.testcases import TransactionTestCase
+from rest_framework.status import HTTP_401_UNAUTHORIZED, HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.vvpEntitiesCreator import VvpEntitiesCreator
+from engagementmanager.utils.authentication import JWTAuthentication
+from engagementmanager.utils.constants import Constants
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestRequestDataManager(TransactionTestCase):
+
+ def childSetup(self):
+ logger.debug("---------------------- TestCase " + self.__class__.__name__ + " ----------------------")
+ self.urlPrefix = "/ice/v1/engmgr/"
+ self.c = Client()
+ self.creator = VvpEntitiesCreator()
+
+ for vendor in [Constants.service_provider_company_name, 'Other']:
+ vendorUuid, vendor = self.creator.createVendor(vendor)
+ logger.debug(vendorUuid)
+
+ self.admin, self.el, self.standard_user = self.creator.createAndGetDefaultRoles()
+
+ # Create a user with role el
+ self.el_user = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name), self.creator.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_review_user = self.creator.createUser(
+ Vendor.objects.get(name=Constants.service_provider_company_name), self.creator.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # Create a user with role standard_user
+ self.user = self.creator.createUser(
+ Vendor.objects.get(name='Other'), self.creator.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ self.user_not_team = self.creator.createUser(
+ Vendor.objects.get(name='Other'), self.creator.randomGenerator("main-vendor-email"),
+ '55501000199', 'user2', self.standard_user, True)
+# # Create an Engagement with team
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(self.user, self.el_user)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_review_user
+ self.engagement.save()
+
+ self.jwt_service = JWTAuthentication()
+ self.token = self.jwt_service.create_token(self.user.user)
+ self.ELtoken = self.jwt_service.create_token(self.el_user.user)
+
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+ myjson = json.dumps({"description": "blah blah"}, ensure_ascii=False)
+ response = self.c.post(urlStr.replace('${uuid}', str(
+ self.engagement.uuid)), myjson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ self.created_status = json.loads(response.content)
+
+ def my_task(self, eng_id):
+ thread_local_id = threading.currentThread().ident
+
+ # Inject an attribute into request data
+ request_data_mgr.set_eng_uuid(eng_id)
+
+ # Inject thread id into requeat data
+ request_data_mgr.set_cl_uuid(thread_local_id)
+
+ return self.my_inner_funcion(eng_id)
+
+ def my_inner_funcion(self, eng_id):
+ thread_local_id = threading.currentThread().ident
+
+ assert request_data_mgr.get_request_data()
+
+ assert request_data_mgr.get_request_data()._eng_uuid == eng_id
+ assert request_data_mgr.get_eng_uuid() == eng_id
+
+ # Checks that the allocated thread from testRequestDataManager is the same thread running in inner function
+ assert request_data_mgr.get_request_data()._cl_uuid == thread_local_id
+ assert request_data_mgr.get_cl_uuid() == thread_local_id
+
+ print('thread: ' + str(thread_local_id) + '. request data : ' + str(request_data_mgr.get_request_data_vars()))
+ return "OK"
+
+ def lauchTests(self):
+ executor = ThreadPoolExecutor(max_workers=10)
+
+ for i in range(0, 100):
+ future1 = executor.submit(self.my_task, "eng#" + str(i))
+ assert future1.result() == "OK"
+
+ ########### TESTS ###########
+
+ def testRequestDataManager(self):
+ executor = ThreadPoolExecutor(max_workers=2)
+ executor.submit(self.lauchTests)
+ executor.submit(self.lauchTests)
+
+ def testMultipleRequestsInParallel(self):
+ self.childSetup()
+ number_of_concurrent_requests = 10
+ executor = ThreadPoolExecutor(max_workers=number_of_concurrent_requests)
+
+ def close_db_connections(func, *args, **kwargs):
+ """
+ Decorator to explicitly close db connections during threaded execution
+
+ Note this is necessary to work around:
+ https://code.djangoproject.com/ticket/22420
+ """
+ def _close_db_connections(*args, **kwargs):
+ ret = None
+ try:
+ ret = func(*args, **kwargs)
+ finally:
+ for conn in connections.all():
+ logger.debug("Closing DB connection. connection=" + str(conn))
+ conn.close()
+ return ret
+ return _close_db_connections
+
+ @close_db_connections
+ def invokeRequest(metadata, token):
+ urlStr = self.urlPrefix + 'engagements/${uuid}/status'
+
+ logger.debug("START - " + metadata)
+
+ myjson = json.dumps(
+ {"eng_status_uuid": self.created_status['uuid'], "description": "blah2 blah2"}, ensure_ascii=False)
+ response = self.c.put(urlStr.replace('${uuid}', str(
+ self.engagement.uuid)), myjson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+
+ time.sleep(randint(0, 1))
+
+ myjson = json.dumps(
+ {"eng_status_uuid": self.created_status['uuid'], "description": "blah2 blah2"}, ensure_ascii=False)
+ response = self.c.put(urlStr.replace('${uuid}', str(
+ self.engagement.uuid)), myjson, content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + token})
+ print('Got response : ' + str(response.status_code))
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ logger.debug("END - " + metadata)
+
+ return metadata
+
+ for i in range(0, number_of_concurrent_requests):
+ eluser = self.creator.createUser(
+ Vendor.objects.get(name='Other'), self.creator.randomGenerator("main-vendor-email"),
+ '55501000199', 'user' + str(i), self.el, True)
+ token = self.jwt_service.create_token(eluser.user)
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.engagement_team.add(eluser)
+ self.engagement.reviewer = eluser
+ self.engagement.peer_reviewer = self.peer_review_user
+ self.engagement.save()
+
+ metadata = "test " + str(i)
+ future = executor.submit(invokeRequest, metadata, token)
+ assert future.result() == metadata
diff --git a/django/engagementmanager/tests/test_resend_activation_email.py b/django/engagementmanager/tests/test_resend_activation_email.py
new file mode 100755
index 0000000..b544001
--- /dev/null
+++ b/django/engagementmanager/tests/test_resend_activation_email.py
@@ -0,0 +1,62 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class TestResendActivationEmail(TestBaseEntity):
+
+ def childSetup(self):
+ self.createDefaultRoles()
+ uuid, vendor = self.creator.createVendor(Constants.service_provider_company_name)
+ self.user = self.creator.createUser(vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, False)
+ self.urlStr = self.urlPrefix + \
+ "users/activation-mail/" + self.user.uuid
+ self.params = {"email": self.user.email}
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+
+ def test_resend_activation_email(self):
+ response = self.c.get(
+ self.urlStr, self.params, content_type='application/json')
+ self.assertTrue(response.status_code, "200")
diff --git a/django/engagementmanager/tests/test_reset_password.py b/django/engagementmanager/tests/test_reset_password.py
new file mode 100755
index 0000000..7cfdd54
--- /dev/null
+++ b/django/engagementmanager/tests/test_reset_password.py
@@ -0,0 +1,75 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.models import Vendor
+from engagementmanager.utils.constants import Constants
+
+
+class TestResetPasswordTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+
+ self.urlStr = self.urlPrefix + "users/pwd/sendresetinstr/"
+ self.data = dict()
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def initBody(self):
+ self.data['email'] = self.user.email
+
+ def resetPwd(self, expectedStatus=200, httpMethod="PUT"):
+ self.accountData = json.dumps(self.data, ensure_ascii=False)
+ if (httpMethod == "PUT"):
+ response = self.c.put(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ elif (httpMethod == "POST"):
+ response = self.c.post(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code) + " Expecting " + str(expectedStatus))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
diff --git a/django/engagementmanager/tests/test_rgwa_client.py b/django/engagementmanager/tests/test_rgwa_client.py
new file mode 100755
index 0000000..a65f5b3
--- /dev/null
+++ b/django/engagementmanager/tests/test_rgwa_client.py
@@ -0,0 +1,214 @@
+#
+# ============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 engagementmanager.utils.constants import Constants
+from validationmanager.rados.rgwa_client import _validate_args, RGWAClient
+
+
+try:
+ from unittest.mock import patch, ANY
+except ImportError:
+ from mock import patch, ANY
+
+try:
+ from unittest import assertRaises, expectedFailure
+except ImportError:
+ from pytest import raises as assertRaises
+ from pytest import mark
+ expectedFailure = mark.xfail
+
+
+class Test_ValidateArgs(object):
+
+ def setup(self):
+ self.valid_args = {
+ 'foo': ['foo1', 'foo2'],
+ 'bar': [1, 2, 3],
+ }
+
+ def test_unconstrained(self):
+ _validate_args(self.valid_args, baz="quux")
+
+ def test_none_value(self):
+ _validate_args(self.valid_args, foo=None)
+
+ def test_good_value(self):
+ _validate_args(self.valid_args, foo="foo1")
+
+ def test_bad_value_raises(self):
+ with assertRaises(ValueError):
+ _validate_args(self.valid_args, foo="foo3")
+
+
+@patch('ice_rgwa_client.request')
+class TestRGWAClientMethods(object):
+ """Tests that all the methods invoke requests.request() with the
+ appropriate arguments.
+
+ """
+
+ def setup(self):
+ self.access_key = 'ABCDEFGHIJKLMNOPQRST'
+ self.secret_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
+ self.conn = RGWAClient(
+ access_key=self.access_key,
+ secret_key=self.secret_key,
+ base_url=Constants.rgwa_base_url
+ )
+
+ def test_get_usage(self, r):
+ self.conn.get_usage(uid='foo', show_entries=True)
+ r.assert_called_once_with(
+ auth=ANY,
+ method='get',
+ json={},
+ params={'show-entries': True, 'show-summary': False, 'uid': 'foo'},
+ url=Constants.rgwa_base_url+'/usage',
+ verify=True,
+ )
+
+ def test_trim_usage(self, r):
+ self.conn.trim_usage(uid='foo', remove_all=True)
+ r.assert_called_once_with(
+ auth=ANY,
+ method='delete',
+ json={},
+ params={'remove-all': True, 'uid': 'foo'},
+ url='http://localhost:8123/admin/usage',
+ verify=True,
+ )
+
+ def test_get_user(self, r):
+ self.conn.get_user(uid='foo')
+ r.assert_called_once_with(
+ auth=ANY,
+ method='get',
+ json={},
+ params={'uid': 'foo'},
+ url=Constants.rgwa_base_url+'/user',
+ verify=True,
+ )
+
+ # Marked FIXME because we experience diminishing returns here. All the
+ # methods in the library are basically one-liner calls to the common
+ # _request method, which has been sufficiently covered. There's no
+ # additional business logic that would be tested, only ensuring beyond api
+ # stability. Time would be better spent figuring out how to get tox to
+ # stand up testing instances of various versions of an actual radosgw
+ # server for integration testing.
+
+ @expectedFailure
+ def test_create_user(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_modify_user(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_user(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_create_subuser(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_modify_subuser(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_subuser(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_create_key(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_key(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_bucket(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_check_bucket_index(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_bucket(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_unlink_bucket(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_link_bucket(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_object(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_policy(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_add_capability(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_remove_capability(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_quota(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_set_quota(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_user_quota(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_set_user_quota(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_user_bucket_quota(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_set_user_bucket_quota(self, r):
+ raise NotImplementedError # FIXME
+
+ @expectedFailure
+ def test_get_users(self, r):
+ raise NotImplementedError # FIXME
+ @expectedFailure
+ def test_get_buckets(self, r):
+ raise NotImplementedError # FIXME
+
+
+# FIXME TODO Add integration tests against a local ceph radosgw instance,
+# (disabled by default). Record result of test suite in repository.
diff --git a/django/engagementmanager/tests/test_set_checklist_state.py b/django/engagementmanager/tests/test_set_checklist_state.py
new file mode 100755
index 0000000..54d3c8e
--- /dev/null
+++ b/django/engagementmanager/tests/test_set_checklist_state.py
@@ -0,0 +1,236 @@
+#
+# ============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 engagementmanager.models import Vendor, Checklist, ChecklistDecision, \
+ ChecklistLineItem, ChecklistSection
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import CheckListLineType, \
+ CheckListDecisionValue, CheckListState, ChecklistDefaultNames, Constants
+from rest_framework.status import HTTP_200_OK
+from uuid import uuid4
+import json
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestChecklistSetState(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+ self.vendor = Vendor.objects.get(name='Amdocs')
+ self.createDefaultRoles()
+
+ # For negative tests
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ # Create users with role el (el+peer reviwer)
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_review_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'peer-reviewer user', self.el, True)
+ # Create a user with admin role
+ self.admin_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail,
+ '55501000199', 'admin user', self.admin, True)
+
+ self.template = self.creator.createDefaultCheckListTemplate()
+ self.engagement = self.creator.createEngagement(
+ 'just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_review_user
+ self.engagement.engagement_team.add(self.el_user, self.user)
+ self.engagement.save()
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+# self.asInfrastructure = self.creator.createApplicationServiceInfrastructure(self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+# self.vf.service_infrastructures.add(self.asInfrastructure)
+
+ self.clbodydata = dict()
+ self.initCLBody()
+ self.checklist = Checklist.objects.create(uuid=uuid4(), name=self.clbodydata['checkListName'], validation_cycle=1, associated_files=self.clbodydata[
+ 'checkListAssociatedFiles'], engagement=self.engagement, template=self.template, creator=self.el_user, owner=self.el_user)
+ self.checklist.save()
+ self.section = ChecklistSection.objects.create(uuid=uuid4(), name=self.randomGenerator("randomString"), weight=1.0, description=self.randomGenerator(
+ "randomString"), validation_instructions=self.randomGenerator("randomString"), template=self.template)
+ self.section.save()
+ self.line_item = ChecklistLineItem.objects.create(uuid=uuid4(), name=self.randomGenerator("randomString"), weight=1.0, description=self.randomGenerator(
+ "randomString"), line_type=CheckListLineType.auto.name, validation_instructions=self.randomGenerator("randomString"), template=self.template, section=self.section) # @UndefinedVariable
+ self.line_item2 = ChecklistLineItem.objects.create(uuid=uuid4(), name=self.randomGenerator("randomString"), weight=1.0, description=self.randomGenerator(
+ "randomString"), line_type=CheckListLineType.auto.name, validation_instructions=self.randomGenerator("randomString"), template=self.template, section=self.section) # @UndefinedVariable
+ self.line_item.save()
+ self.line_item2.save()
+ self.decision = ChecklistDecision.objects.create(
+ uuid=uuid4(), checklist=self.checklist, template=self.template, lineitem=self.line_item)
+ self.decision2 = ChecklistDecision.objects.create(
+ uuid=uuid4(), checklist=self.checklist, template=self.template, lineitem=self.line_item2)
+ self.decision.save()
+ self.decision2.save()
+ self.data = dict()
+ self.peer_review_token = self.loginAndCreateSessionToken(
+ self.peer_review_user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+ self.admin_token = self.loginAndCreateSessionToken(self.admin_user)
+
+ def initCLBody(self):
+ self.clbodydata['checkListName'] = ChecklistDefaultNames.HEAT_TEMPLATES
+ self.clbodydata['checkListTemplateUuid'] = str(self.template.uuid)
+ self.clbodydata[
+ 'checkListAssociatedFiles'] = "[\"file0/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\", \"file1/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\", \"file2/f69f4ce7-51d5-409c-9d0e-ec6b1e79df28\"]"
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def testSetStateFullWorkFlow(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Full positive work flow")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "checklist/@cl_uuid/state/"
+ self.get_checklist_url = self.urlPrefix + "checklist/@cl_uuid"
+ self.url_for_decision = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ self.data['decline'] = "False"
+ self.data['description'] = "BLA BLA BLA"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug(
+ "**********************************************************************")
+ logger.debug("----- 1. Current state is " +
+ self.checklist.state + " -----")
+ logger.debug(
+ "**********************************************************************")
+
+ logger.debug(
+ "----- 1.1 Wishing to move from pending state to automation state -----")
+ logger.debug(
+ "----- 1.2 Performing a request to move forward to the next state -----")
+ response = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('1.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_200_OK) + ' response')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+
+ logger.debug(
+ "----- 2 Test engine Mock retrieved tests results, hence checklist state moved to review state. -----")
+ logger.debug(
+ "----- 3.1 changing decisions' review value to APPROVED -----")
+ decisions = ChecklistDecision.objects.filter(checklist=self.checklist)
+ for dec in decisions:
+ self.data['value'] = "approved"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+ response = self.c.put(self.url_for_decision.replace("@decision_uuid", str(dec.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug(
+ "----- 3.2 Wishing to move from review state to peer_review state -----")
+ logger.debug(
+ "----- 3.3 Performing a request to move forward to the next state -----")
+
+ response = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('3.4 you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_200_OK) + ' response')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ logger.debug(
+ "----- 4.1 changing the cl peer_reviews' decisions values to NA -----")
+ for dec in decisions:
+ dec.peer_review_value = CheckListDecisionValue.not_relevant.name # @UndefinedVariable
+ dec.save()
+
+ logger.debug(
+ "----- 4.2 Wishing to move from peer_review state to approval state -----")
+ logger.debug(
+ "----- 4.3 Performing a request to move forward to the next state -----")
+ response = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.peer_review_token})
+ logger.debug('4.4 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_200_OK) + ' response')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ logger.debug(
+ "----- 5.1 Wishing to move from approval state to handoff state -----")
+ logger.debug(
+ "----- 5.2 Performing a request to move forward to the next state -----")
+ response = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ logger.debug('Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_200_OK) + ' response')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ logger.debug(
+ "----- 6.1 Wishing to move from handoff state to closed state -----")
+ logger.debug(
+ "----- 6.2 Performing a request to move forward to the last state -----")
+ response = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_200_OK) + ' response')
+ self.assertEqual(response.status_code, HTTP_200_OK)
+ self.loggerTestFailedOrSucceded(True)
+
+ '''
+ This test checks that the signal is sent and responds with 200OK. Also that the signal logic change the checklist state to automation
+ '''
+
+ def testClFromPendingToAutomationSignal(self):
+
+ self.urlStr = self.urlPrefix + "checklist/@cl_uuid/state/"
+ self.get_checklist_url = self.urlPrefix + "checklist/@cl_uuid"
+ self.url_for_decision = self.urlPrefix + "checklist/decision/@decision_uuid"
+
+ self.data['decline'] = "False"
+ self.data['description'] = "BLA BLA BLA"
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ cl = Checklist.objects.get(uuid=self.checklist.uuid)
+ cl.state = CheckListState.pending.name # @UndefinedVariable
+ cl.save()
+ res1 = self.c.put(self.urlStr.replace("@cl_uuid", str(self.checklist.uuid)), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ self.assertEqual(res1.status_code, HTTP_200_OK)
diff --git a/django/engagementmanager/tests/test_set_eng_stage.py b/django/engagementmanager/tests/test_set_eng_stage.py
new file mode 100755
index 0000000..f26b70b
--- /dev/null
+++ b/django/engagementmanager/tests/test_set_eng_stage.py
@@ -0,0 +1,207 @@
+#
+# ============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 rest_framework.status import HTTP_202_ACCEPTED,\
+ HTTP_401_UNAUTHORIZED
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import EngagementStage, Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class TestEngagementSetStage(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+ self.vendor = Vendor.objects.get(name='Amdocs')
+ self.service_provider = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.createDefaultRoles()
+
+ # For negative tests
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ # Create users with role el (el+peer reviwer)
+ self.el_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'el user', self.el, True)
+ self.peer_reviewer = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ # Create a user with admin role
+ self.admin_user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), Constants.service_provider_admin_mail,
+ '55501000199', 'admin user', self.admin, True)
+
+ self.engagement = self.creator.createEngagement('just-a-fake-uuid', 'Validation', None)
+ self.engagement.reviewer = self.el_user
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.engagement_team.add(self.el_user, self.user)
+ self.engagement.save()
+
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+# self.asInfrastructure = self.creator.createApplicationServiceInfrastructure(self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+# self.vf.service_infrastructures.add(self.asInfrastructure)
+
+ self.data = dict()
+ self.user_token = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+ self.admin_token = self.loginAndCreateSessionToken(self.admin_user)
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def testSetEngagementStageFullWorkFlowELUser(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: change from Intake to Active, using --EL-- user!")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ self.urlStr = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid) + "/stage/@stage"
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- 1. Current stage is " + self.engagement.engagement_stage + " -----")
+ logger.debug("**********************************************************************")
+
+ logger.debug("----- 1.1 Wishing to move from Intake stage to Active stage -----")
+ logger.debug("----- 1.2 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Active.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ response2 = self.c.get(self.get_engagement_url, {}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+
+ # Check if the correct activity was created for stage change to Active
+ self.notifcation_url = self.urlPrefix + "engagement/" + str(self.engagement.uuid) + "/activities/"
+ response3 = self.c.get(self.notifcation_url, {}, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ received_notification = json.loads(response3.content)[0]['description']
+ should_be = "Engagement stage is now Active for the following VF: ##vf_name##"
+ self.assertEqual(should_be, received_notification)
+ self.assertEqual(self.vf.name in json.loads(response3.content)[0]['metadata'], True)
+ logger.debug('1.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ logger.debug("----- 2 Wishing to move from Active stage to Validated stage -----")
+ logger.debug("----- 2.1 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Validated.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('2.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ logger.debug("----- 3.1 Wishing to move from Validated stage to Completed stage -----")
+ logger.debug("----- 3.2 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Completed.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.ELtoken})
+ logger.debug('2.4 you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ self.loggerTestFailedOrSucceded(True)
+
+ def testSetEngagementStageFullWorkFlowAdminUser(self):
+
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: change from Intake to Active, using --ADMIN-- user!")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid) + "/stage/@stage"
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- 1. Current stage is " + self.engagement.engagement_stage + " -----")
+ logger.debug("**********************************************************************")
+
+ logger.debug("----- 1.1 Wishing to move from Intake stage to Active stage -----")
+ logger.debug("----- 1.2 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Active.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ logger.debug('1.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ self.loggerTestFailedOrSucceded(False)
+ logger.debug("----- 2 Wishing to move from Active stage to Validated stage -----")
+ logger.debug("----- 2.1 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Validated.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ logger.debug('2.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ logger.debug("----- 3 Wishing to move from Validated stage to Completed stage -----")
+ logger.debug("----- 3.1 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Completed.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.admin_token})
+ logger.debug('2.4 you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_202_ACCEPTED) + ' response')
+ self.assertEqual(response.status_code, HTTP_202_ACCEPTED)
+ self.loggerTestFailedOrSucceded(True)
+
+ def test_negative_set_eng_Stage(self):
+
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Negative test to change stage with un authorized user")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ self.urlStr = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid) + "/stage/@stage"
+ self.get_engagement_url = self.urlPrefix + "single-engagement/" + str(self.engagement.uuid)
+ datajson = json.dumps(self.data, ensure_ascii=False)
+
+ logger.debug("**********************************************************************")
+ logger.debug("----- 1. Current stage is " + self.engagement.engagement_stage + " -----")
+ logger.debug("**********************************************************************")
+
+ logger.debug("----- 1.1 Wishing to try move from Intake stage to Active stage AND FAIL! -----")
+ logger.debug("----- 1.2 Performing a request to move forward to the next stage -----")
+ response = self.c.put(self.urlStr.replace("@stage", EngagementStage.Active.name), datajson,
+ content_type='application/json', **{'HTTP_AUTHORIZATION': "token " + self.user_token})
+ logger.debug('1.3 Please Notice, you got a ' + str(response.status_code) +
+ ' response, and was expecting a ' + str(HTTP_401_UNAUTHORIZED) + ' response')
+ self.assertEqual(response.status_code, HTTP_401_UNAUTHORIZED)
+ self.loggerTestFailedOrSucceded(True)
diff --git a/django/engagementmanager/tests/test_update_password.py b/django/engagementmanager/tests/test_update_password.py
new file mode 100755
index 0000000..08b25b2
--- /dev/null
+++ b/django/engagementmanager/tests/test_update_password.py
@@ -0,0 +1,99 @@
+#
+# ============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 engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.models import Vendor
+from engagementmanager.utils.constants import Constants
+
+
+class TestUpdatePasswordTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+
+ self.urlStr = self.urlPrefix + "users/pwd/"
+ self.data = dict()
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def initBody(self):
+ self.data['password'] = "Aa12345"
+ self.data['confirm_password'] = "Aa12345"
+
+ def updatePwd(self, expectedStatus=200, httpMethod="PUT"):
+ self.accountData = json.dumps(self.data, ensure_ascii=False)
+ if (httpMethod == "PUT"):
+ response = self.c.put(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ elif (httpMethod == "POST"):
+ response = self.c.post(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code) + " Expecting " + str(expectedStatus))
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ ### TESTS ###
+ def testUpdatePasswordPositive(self):
+ self.initBody()
+ print("testUpdatePasswordPositive")
+ self.updatePwd(200, "PUT")
+
+ def testUpdatePasswordNegative(self):
+ self.initBody()
+ print("testUpdatePasswordNegative")
+ self.updatePwd(405, "POST")
+
+ def testUpdatePasswordNegativePwdNotMatch(self):
+ self.initBody()
+ self.data['confirm_password'] = self.data['password'] + "extraletters"
+ print("testUpdatePasswordNegativePwdNotMatch")
+ self.updatePwd(400, "PUT")
+
+ def testUpdatePasswordNegativeMissingPassword(self):
+ self.initBody()
+ self.data['confirm_password'] = None
+ print("testUpdatePasswordNegativePwdNotMatch")
+ self.updatePwd(400, "PUT")
diff --git a/django/engagementmanager/tests/test_update_user_account.py b/django/engagementmanager/tests/test_update_user_account.py
new file mode 100755
index 0000000..fd0becd
--- /dev/null
+++ b/django/engagementmanager/tests/test_update_user_account.py
@@ -0,0 +1,119 @@
+#
+# ============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 engagementmanager.models import Vendor, IceUserProfile
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+
+
+class TestUpdateUserAccountTestCase(TestBaseEntity):
+
+ def childSetup(self):
+
+ self.createVendors([Constants.service_provider_company_name, 'Amdocs'])
+
+ self.createDefaultRoles()
+
+ # Create a user with role el
+ self.user = self.creator.createUser(Vendor.objects.get(
+ name=Constants.service_provider_company_name), self.randomGenerator("main-vendor-email"),
+ '55501000199', 'user', self.standard_user, True)
+ print('-----------------------------------------------------')
+ print('Created User:')
+ print('UUID: ' + str(self.user.uuid))
+ print('Full Name: ' + self.user.full_name)
+ print('-----------------------------------------------------')
+
+ self.urlStr = self.urlPrefix + "users/account/"
+ self.data = dict()
+ self.token = self.loginAndCreateSessionToken(self.user)
+
+ def initBody(self):
+ self.data['company'] = Vendor.objects.get(name='Amdocs').name
+ self.data['full_name'] = "user"
+ self.data['email'] = self.randomGenerator("main-vendor-email")
+ self.data['phone_number'] = "12345"
+ self.data['password'] = "Aa12345"
+ self.data['confirm_password'] = "Aa12345"
+
+ def updateAccount(self, expectedStatus=200, httpMethod="PUT"):
+ self.accountData = json.dumps(self.data, ensure_ascii=False)
+ if (httpMethod == "PUT"):
+ response = self.c.put(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ elif (httpMethod == "POST"):
+ response = self.c.post(self.urlStr, self.accountData, content_type='application/json',
+ **{'HTTP_AUTHORIZATION': "token " + self.token})
+ print('Got response : ' + str(response.status_code) + " Expecting 200")
+ self.assertEqual(response.status_code, expectedStatus)
+ return response
+
+ ### TESTS ###
+ def testUpdateNegativeWrongHttpMethodAccount(self):
+ self.initBody()
+ print("Negative Test: Wrong HTTP Method --> Expecting status code 405")
+ self.updateAccount(405, "POST")
+
+ def testUpdateNegativeDiffPasswords(self):
+ self.initBody()
+ print("Negative Test: password!=confirm_password --> Expecting status code 400")
+ self.data['confirm_password'] = "fakePassword"
+ self.updateAccount(400, "PUT")
+
+ def testUpdatePositive(self):
+ self.initBody()
+ print("Positive Test: --> Expecting status code 200")
+ self.updateAccount(200, "PUT")
+
+ def testUpdateUserProfileNotificationsSettings(self):
+ self.initBody()
+
+ self.data['regular_email_updates'] = False
+ self.data['email_updates_daily_digest'] = True
+ self.data['email_updates_on_every_notification'] = False
+
+ print("Positive Test: --> Expecting status code 200")
+
+ self.updateAccount(200, "PUT")
+
+ user = IceUserProfile.objects.get(uuid=self.user.uuid)
+ self.assertEqual(user.regular_email_updates, False)
+ self.assertEqual(user.email_updates_daily_digest, True)
+ self.assertEqual(user.email_updates_on_every_notification, False)
diff --git a/django/engagementmanager/tests/test_vfc.py b/django/engagementmanager/tests/test_vfc.py
new file mode 100755
index 0000000..e7f374a
--- /dev/null
+++ b/django/engagementmanager/tests/test_vfc.py
@@ -0,0 +1,180 @@
+#
+# ============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 rest_framework.status import HTTP_204_NO_CONTENT, HTTP_200_OK
+from engagementmanager.models import Vendor
+from engagementmanager.tests.test_base_entity import TestBaseEntity
+from engagementmanager.utils.constants import Constants
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class VFCAPITestCase(TestBaseEntity):
+
+ def childSetup(self):
+ self.createVendors([Constants.service_provider_company_name, 'Other'])
+ self.createDefaultRoles()
+ # Create a user with role el
+ self.service_provider = Vendor.objects.get(name=Constants.service_provider_company_name)
+ self.el_user = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created User:')
+ logger.debug('UUID: ' + str(self.el_user.uuid))
+ logger.debug('Full Name: ' + self.el_user.full_name)
+ logger.debug('-----------------------------------------------------')
+ self.peer_reviewer = self.creator.createUser(self.service_provider, self.randomGenerator(
+ "main-vendor-email"), self.randomGenerator("randomNumber"), self.randomGenerator("randomString"), self.el, True)
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created Peer Reviewer:')
+ logger.debug('UUID: ' + str(self.peer_reviewer.uuid))
+ logger.debug('Full Name: ' + self.peer_reviewer.full_name)
+ logger.debug('-----------------------------------------------------')
+
+ # Create a user with role standard_user
+ self.vendor = Vendor.objects.get(name='Other')
+ self.user = self.creator.createUser(self.vendor, self.randomGenerator("email"), self.randomGenerator(
+ "randomNumber"), self.randomGenerator("randomString"), self.standard_user, True)
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created User:')
+ logger.debug('UUID: ' + str(self.user.uuid))
+ logger.debug('Full Name: ' + self.user.full_name)
+ logger.debug('-----------------------------------------------------')
+
+ # Create an Engagement with team
+ self.engagement = self.creator.createEngagement(self.randomGenerator(
+ "randomString"), self.randomGenerator("randomString"), None)
+ self.engagement.engagement_team.add(self.user, self.el_user, self.peer_reviewer)
+ self.engagement.peer_reviewer = self.peer_reviewer
+ self.engagement.reviewer = self.el_user
+ self.engagement.save()
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created Engagement:')
+ logger.debug('UUID: ' + str(self.engagement.uuid))
+ logger.debug('-----------------------------------------------------')
+
+ # Create a DT, DTSite, VF
+ self.deploymentTarget = self.creator.createDeploymentTarget(
+ self.randomGenerator("randomString"), self.randomGenerator("randomString"))
+ self.vf = self.creator.createVF(self.randomGenerator("randomString"),
+ self.engagement, self.deploymentTarget, False, self.vendor)
+
+ logger.debug('-----------------------------------------------------')
+ logger.debug('Created VF:')
+ logger.debug('UUID: ' + str(self.vendor.uuid))
+ logger.debug('-----------------------------------------------------')
+
+ self.token = self.loginAndCreateSessionToken(self.user)
+ self.ELtoken = self.loginAndCreateSessionToken(self.el_user)
+
+ def retrieveCurrentObjectsOfEngagementByFilter(self, method, detailOrObject, entity):
+ if method == 'filter':
+ list = entity.objects.filter(engagement=detailOrObject)
+ return list
+ elif method == 'get':
+ list = entity.objects.get(uuid=detailOrObject)
+ return list
+
+ def loggerTestFailedOrSucceded(self, bool):
+ if bool:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test Succeeded")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ else:
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug("Test failed")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+
+ def testCreateDTSiteAddToVF(self):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Create DTSite and add to VF")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ self.deploymentTargetSite = self.creator.createDeploymentTargetSite(self.randomGenerator("randomString"))
+ self.vf.deployment_target_sites.add(self.deploymentTargetSite)
+ sites = self.vf.deployment_target_sites.all()
+ num = 1
+ for item in sites:
+ logger.debug(str(num) + ". " + item.name)
+ print("\n")
+ if (self.vf.deployment_target_sites.all().count() > 0):
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+
+ def testDeleteVFC(self, expectedStatus=HTTP_204_NO_CONTENT):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Delete VFC")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ vfc = self.creator.createVFC(self.randomGenerator("randomString"), self.randomGenerator(
+ "randomNumber"), self.vendor, self.vf, self.el_user)
+ urlStr = self.urlPrefix + 'vf/' + str(vfc.uuid) + '/vfcs/' + str(vfc.uuid)
+ if (vfc == None):
+ logger.error("vfc wasn't created successfully before the deletion attempt")
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(500, expectedStatus)
+ response = self.c.delete(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ logger.debug('Got response : ' + str(response.status_code))
+ if (response.status_code == HTTP_204_NO_CONTENT):
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, expectedStatus)
+
+ def testGetVFC(self, expectedStatus=HTTP_200_OK):
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
+ logger.debug(" Test started: Get VFCs")
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n")
+ vfc = self.creator.createVFC(self.randomGenerator("randomString"), self.randomGenerator(
+ "randomNumber"), self.vendor, self.vf, self.el_user)
+ vfc2 = self.creator.createVFC(self.randomGenerator("randomString"), self.randomGenerator(
+ "randomNumber"), self.service_provider, self.vf, self.el_user)
+ urlStr = self.urlPrefix + 'vf/' + str(self.vf.uuid) + '/vfcs/'
+ if (vfc == None or vfc2 == None):
+ logger.error("The VFCs were not created successfully before the deletion attempt")
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(500, expectedStatus)
+ response = self.c.get(urlStr, **{'HTTP_AUTHORIZATION': "token " + self.token})
+ logger.debug('Got response : ' + str(response.status_code))
+ logger.debug("VFCs found in the VF(through the GET request):")
+ logger.debug(str(response.content))
+ if (response.status_code == HTTP_200_OK):
+ self.loggerTestFailedOrSucceded(True)
+ else:
+ self.loggerTestFailedOrSucceded(False)
+ self.assertEqual(response.status_code, expectedStatus)
diff --git a/django/engagementmanager/tests/vvpEntitiesCreator.py b/django/engagementmanager/tests/vvpEntitiesCreator.py
new file mode 100755
index 0000000..0ba619e
--- /dev/null
+++ b/django/engagementmanager/tests/vvpEntitiesCreator.py
@@ -0,0 +1,290 @@
+#
+# ============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 uuid import uuid4
+from django.utils import timezone
+import string
+import random
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.utils.authentication import JWTAuthentication
+from engagementmanager.models import Vendor, IceUserProfile, Role, Engagement, DeploymentTarget, ApplicationServiceInfrastructure, VF,\
+ NextStep, ChecklistTemplate, DeploymentTargetSite, VFC, Checklist, ChecklistSection, ChecklistLineItem,\
+ CustomUser
+from engagementmanager.utils.constants import Constants
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class VvpEntitiesCreator:
+
+ def __init__(self):
+ pass
+
+ def createUserTemplate(self, company, email, full_name, role, is_service_provider_contact, ssh_key=None, ):
+ return {
+ 'company': company,
+ 'email': email,
+ 'phone_number': '555019900',
+ 'full_name': full_name,
+ 'role': role,
+ 'create_time': timezone.now(),
+ 'is_service_provider_contact': is_service_provider_contact,
+ 'ssh_public_key': ssh_key,
+ }
+
+ def createEngagementTemplate(self, engagement_type, engagement_team):
+ return {
+ # 'engagement_type' : engagement_type,
+ # 'members' : engagement_team,
+ # 'start_date' : timezone.now(),
+ 'progress': 0
+ }
+
+ def createVendor(self, vendorName):
+ ven = Vendor.objects.filter(name=vendorName)
+ if (not ven.exists()):
+ vendor = Vendor.objects.create(name=vendorName, public=True)
+ else:
+ vendor = Vendor.objects.get(name=vendorName)
+ return vendor.uuid, vendor
+
+ def createDeploymentTarget(self, name, version):
+ deployment = DeploymentTarget.objects.create(
+ name=name, version=version)
+ return deployment
+
+ def createDeploymentTargetSite(self, name):
+ dtsite = DeploymentTargetSite.objects.create(name=name)
+ return dtsite
+
+ def createApplicationServiceInfrastructure(self, name):
+ asinfrastructure = ApplicationServiceInfrastructure.objects.create(
+ name=name)
+ return asinfrastructure
+
+ def getOrCreateIfNotExist(self, entity, getCriteria, creationFields):
+ obj = None
+ try:
+ logger.debug("about to look for object: " + str(getCriteria))
+ obj = entity.objects.get(**getCriteria)
+ logger.debug('found object')
+ except entity.DoesNotExist:
+ logger.error('not found. Trying to create...')
+ obj = entity.objects.create(**creationFields)
+ return obj
+
+ def createAndGetDefaultRoles(self):
+ admin = self.getOrCreateIfNotExist(
+ Role, {'name': 'admin'}, {'name': 'admin'})
+ el = self.getOrCreateIfNotExist(Role, {'name': 'el'}, {'name': 'el'})
+ standard_user = self.getOrCreateIfNotExist(Role, {'name': 'standard_user'}, {
+ 'name': 'standard_user'})
+ return admin, el, standard_user
+
+ def createUser(self, company, email, phone, fullName, role, is_active=False, ssh_key=None, activation_token_create_time=timezone.now()):
+ try:
+ user, is_user_created = CustomUser.objects.get_or_create(username=email, defaults={'email': email, 'password': '12345678', 'activation_token': uuid4(
+ ), 'activation_token_create_time': timezone.now(), 'last_login': timezone.now(), 'is_active': is_active})
+ user_profile, is_profile_created = IceUserProfile.objects.update_or_create(
+ email=email, defaults=self.createUserTemplate(company, email, fullName, role, False, ssh_key))
+ except Exception as e:
+ logger.error("VvpEntitiesCreator - createUser - error:")
+ logger.error(e)
+ return None
+ return user_profile
+
+ def createEngagement(self, uuid, engagement_type, engagement_team):
+ return self.getOrCreateIfNotExist(Engagement, {'uuid': uuid}, self.createEngagementTemplate(engagement_type, engagement_team))
+
+ def createVF(self, name, engagement, deployment, is_service_provider_internal, vendor, **kwargs):
+ vf = VF.objects.create(name=name, engagement=engagement,
+ deployment_target=deployment,
+ is_service_provider_internal=is_service_provider_internal,
+ vendor=vendor,
+ target_lab_entry_date=timezone.now(), **kwargs)
+ return vf
+
+ def createNextStep(self, uuid, createFields):
+ return self.getOrCreateIfNotExist(NextStep, {'uuid': uuid}, createFields)
+
+ def createDefaultCheckListTemplate(self):
+ checklist_templates = [
+ {
+ 'name': 'Heat',
+ 'category': 'first category',
+ 'version': 1,
+ 'sections': [
+ {
+ 'name': 'Parameter Specification',
+ 'weight': 1,
+ 'description': 'section description',
+ 'validation_instructions': 'valid instructions',
+ 'lineitems': [
+ {
+ 'name': 'Parameters',
+ 'weight': 1,
+ 'description': 'Numeric parameters should include range and/or allowed values.',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'auto',
+ },
+ {
+ 'name': 'String parameters',
+ 'weight': 1,
+ 'description': 'Numeric parameters should include range and/or allowed values.',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'auto',
+ },
+ {
+ 'name': 'Numeric parameters',
+ 'weight': 1,
+ 'description': 'Numeric parameters should include range and/or allowed values.',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'auto',
+ }
+ ]
+ },
+ {
+ 'name': 'External References',
+ 'weight': 1,
+ 'description': 'section descripyion',
+ 'validation_instructions': 'valid instructions',
+ 'lineitems': [
+ {
+ 'name': 'Normal references',
+ 'weight': 1,
+ 'description': 'Numeric parameters should include range and/or allowed values.',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'manual',
+ },
+ {
+ 'name': 'VF image',
+ 'weight': 1,
+ 'description': 'Numeric parameters should include range and/or allowed values.',
+ 'validation_instructions': 'Here are some useful tips for how to validate this item in the most awesome way:<br><br><ul><li>Here is my awesome tip 1</li><li>Here is my awesome tip 2</li><li>Here is my awesome tip 3</li></ul>',
+ 'line_type': 'auto',
+ }
+ ]
+
+ }
+ ]
+ }
+ ]
+
+ for template in checklist_templates:
+ created_template = ChecklistTemplate.objects.get_or_create(name=template['name'], defaults={
+ 'category': template['category'],
+ 'version': template['version'],
+ 'create_time': timezone.now()
+ })
+ created_template = ChecklistTemplate.objects.get(
+ name=template['name'])
+ for section in template['sections']:
+ created_section = ChecklistSection.objects.get_or_create(
+ name=section['name'],
+ template_id=created_template.uuid, defaults={
+ 'weight': section['weight'],
+ 'description': section['description'],
+ 'validation_instructions': section['validation_instructions']
+
+ })
+ created_section = ChecklistSection.objects.get(
+ name=section['name'], template_id=created_template.uuid)
+ for lineitem in section['lineitems']:
+ created_lineitem = ChecklistLineItem.objects.get_or_create(
+ name=lineitem['name'],
+ template_id=created_template.uuid,
+ defaults={
+ 'weight': lineitem['weight'],
+ 'description': lineitem['description'],
+ 'validation_instructions': lineitem['validation_instructions'],
+ 'line_type': lineitem['line_type'],
+ 'section_id': created_section.uuid,
+ })
+
+ self.defaultCheklistTemplate = ChecklistTemplate.objects.get(
+ name="Heat")
+
+ return self.defaultCheklistTemplate
+
+ def createCheckList(self, name, state, validation_cycle, associated_files, engagement, template, creator, owner):
+ if (associated_files == None):
+ associated_files = '{}'
+ return self.getOrCreateIfNotExist(Checklist, {'name': name}, {
+ 'state': state,
+ 'name': name,
+ 'validation_cycle': 1,
+ 'associated_files': associated_files,
+ 'engagement': engagement,
+ 'template': template,
+ 'creator': creator,
+ 'owner': owner
+ })
+
+ def createVFC(self, name, ext_ref, company, vf, creator):
+ obj = None
+ try:
+ obj = VFC.objects.get(name=name)
+ except VFC.DoesNotExist:
+ return VFC.objects.create(name=name, external_ref_id=ext_ref, company=company, creator=creator, vf=vf)
+ return obj
+
+ def randomGenerator(self, typeOfValue, numberOfDigits=0):
+ lettersAndNumbers = string.ascii_letters + string.digits
+ if typeOfValue == 'email':
+ myEmail = ''.join(random.choice(lettersAndNumbers) for _ in range(4)) + "@" + \
+ ''.join(random.choice(string.ascii_uppercase) for _ in range(4)) + ".com"
+ return myEmail
+ elif typeOfValue == 'main-vendor-email':
+ myEmail = ''.join(random.choice(lettersAndNumbers) for _ in range(4)) + "@" + \
+ Constants.service_provider_mail_domain[0]
+ return myEmail
+ elif typeOfValue == 'randomNumber':
+ randomNumber = ''.join("%s" % random.randint(0, 9) for _ in range(0, (numberOfDigits + 1)))
+ return randomNumber
+ elif typeOfValue == 'randomString':
+ randomString = "".join(random.sample(lettersAndNumbers, 5))
+ return randomString
+ else:
+ logger.debug("Error on randonGenerator - given bad value.")
+ exit
+
+ def loginAndCreateSessionToken(self, user):
+ jwt_service = JWTAuthentication()
+ token = jwt_service.create_token(user.user)
+ logger.debug("token " + token)
+ return token
diff --git a/django/engagementmanager/urls.py b/django/engagementmanager/urls.py
new file mode 100755
index 0000000..9cc5be3
--- /dev/null
+++ b/django/engagementmanager/urls.py
@@ -0,0 +1,227 @@
+#
+# ============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.urls import url
+
+from engagementmanager.rest import checklist_audit_log
+from engagementmanager.rest import user, activation, activity, vf, invite, feedback, nextsteps, engagement, \
+ login, signup, notification, checklist, deployment_target_site, vendor, data_loader, checklist_decision, \
+ vfc, checklist_set_state, deployment_target, ecomp, validation_details
+from engagementmanager.rest.cms.pages import Pages, PageById, PageSearch
+from engagementmanager.rest.cms.posts import Posts
+from engagementmanager.rest.engagement import EngagementProgressBar, ChangeTargetLabEntryDate, EngagementOps, \
+ EngagementReviewer, EngagementPeerReviewer, ArchiveEngagement, SwitchEngagementReviewers
+from engagementmanager.rest.user import User
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+# Our UUIDs are always uuid4; a 36-character string of lowercase hexadecimal
+# and '-' characters.
+re_uuid = r'[a-f0-9-]{36}'
+# UUIDs in tokens are the same as above without '-', so 32 lowercase
+# hexadecimal characters.
+re_token = r'[a-f0-9]{32}'
+# Parameters like 'stage' correspond to Enums, so have the same rules as Python
+# identifiers: upper and lower case, numbers, and underscore.
+re_enum = r'[a-zA-Z0-9_\.-]+'
+
+re_token_reset_password = r'[a-zA-Z0-9-\._]+'
+
+
+urlpatterns = [
+ url(r'^users/engagementleads/?$', user.EngagementLeads.as_view()),
+ url(r'^users/ssh/?$', user.SetSsh.as_view()),
+ url(r'^users/account/?$', user.User.as_view()),
+ url(r'^users/account/rgwa/?$', user.RGWAAccessKey.as_view()),
+ url(r'^users/pwd/reset-instructions/?$',
+ user.SendResetPasswordInstructionMail.as_view()),
+ url(r'^users/pwd/?$', user.UpdatePassword.as_view()),
+ url(r'^users/?$', User.as_view()),
+
+ # User Activation
+ url(r'^users/activation-mail/(?P<user_uuid>%s)$' % re_uuid,
+ activation.ResendActivationMail.as_view()),
+ url(r'^users/activate/(?P<uu_id>%s)/(?P<token>%s)$' %
+ (re_uuid, re_token), activation.ActivateUser.as_view()),
+
+ # Engagements API
+ url(r'^single-engagement/(?P<eng_uuid>%s)/stage/(?P<stage>%s)$' %
+ (re_uuid, re_enum), engagement.SingleEngByUser.as_view()),
+ url(r'^single-engagement/(?P<eng_uuid>%s)$' %
+ re_uuid, engagement.SingleEngByUser.as_view()),
+ url(r'^engagements/user/nextsteps/?$', nextsteps.UserNextSteps.as_view()),
+ url(r'^engagements/starred_eng/?$',
+ engagement.StarredEngagements.as_view()),
+ url(r'^engagements/recent_eng/?$',
+ engagement.GetRecentEngagements.as_view()),
+ url(r'^engagements/engagement-team/?$',
+ engagement.EngagementTeamUsers.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/status/?$' %
+ re_uuid, engagement.Status.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/nextsteps/?$' %
+ re_uuid, nextsteps.NextSteps.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/nextsteps/order_next_steps$' %
+ re_uuid, nextsteps.OrderNextSteps.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/nextsteps/(?P<eng_stage>%s)/?$' % (re_uuid, re_enum),
+ nextsteps.NextSteps.as_view()), # Set Next Step State
+ # Set Progress bar for Engagement
+ url(r'^engagements/(?P<eng_uuid>%s)/progress/?$' %
+ re_uuid, EngagementProgressBar.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/target_date/?$' %
+ re_uuid, EngagementProgressBar.as_view()), # Set Target Date
+ # Set Target Lab Entry Date
+ url(r'^engagements/(?P<eng_uuid>%s)/target_lab_date/?$' %
+ re_uuid, ChangeTargetLabEntryDate.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/archive/?$' %
+ re_uuid, ArchiveEngagement.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/reviewer/?$' %
+ re_uuid, EngagementReviewer.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/peerreviewer/?$' %
+ re_uuid, EngagementPeerReviewer.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/switch-reviewers/?$' %
+ re_uuid, SwitchEngagementReviewers.as_view()),
+ url(r'^engagements/(?P<eng_uuid>%s)/$' %
+ re_uuid, EngagementOps.as_view()), # Used by delete engagement
+ url(r'^engagement/expanded/?$', engagement.ExpandedEngByUser.as_view()),
+ url(r'^engagement/export/', engagement.ExportEngagements.as_view()),
+ url(r'^engagement/?$', engagement.GetEngByUser.as_view()),
+ # Activities - pull top X objects
+ url(r'^engagement/(?P<eng_uuid>%s)/activities/?$' %
+ re_uuid, activity.PullActivities.as_view()),
+
+ # DeploymentTarget(version)
+ url(r'^engagement/(?P<engagement_uuid>%s)/deployment-targets/(?P<dt_uuid>%s)$'
+ % (re_uuid, re_uuid),
+ deployment_target.DeploymentTargetRESTMethods.as_view()),
+ url(r'^deployment-targets/?$',
+ deployment_target.DeploymentTargetRESTMethods.as_view()),
+
+ # ECOMP
+ url(r'^engagement/(?P<engagement_uuid>%s)/ecomp-releases/(?P<ecomp_uuid>%s)$' % (re_uuid, re_uuid),
+ ecomp.ECOMPReleaseRESTMethods.as_view()),
+ url(r'^ecomp-releases/?$', ecomp.ECOMPReleaseRESTMethods.as_view()),
+ # VFVERSION
+ url(r'^vf/(?P<vf_uuid>%s)/vf-version/$' % re_uuid, vf.VF.as_view()),
+ # DeploymentTargetSite%s
+ url(r'^vf/(?P<vf_uuid>%s)/validation-details/$' %
+ re_uuid, validation_details.UpdateValidationDetails.as_view()),
+ url(r'^vf/(?P<vf_uuid>%s)/dtsites/$' %
+ re_uuid, deployment_target_site.DTSites.as_view()),
+ url(r'^vf/(?P<vf_uuid>%s)/dtsites/(?P<dts_uuid>%s)$' %
+ (re_uuid, re_uuid), deployment_target_site.DTSites.as_view()),
+ url(r'^dtsites/?$', deployment_target_site.DTSites.as_view()),
+
+ # Vendor
+ url(r'^vendors/?$', vendor.VendorREST.as_view()),
+ url(r'^vendors/(?P<uuid>%s)$' % re_uuid, vendor.VendorREST.as_view()),
+
+ url(r'^vfcs/?$', vfc.VFCRest.as_view()),
+ url(r'^vf/(?P<vf_uuid>%s)/vfcs/$' % re_uuid, vfc.VFCRest.as_view()),
+ url(r'^vf/(?P<vf_uuid>%s)/vfcs/(?P<vfc_uuid>%s)?$' %
+ (re_uuid, re_uuid), vfc.VFCRest.as_view()),
+
+ # Next Steps
+ url(r'^nextsteps/(?P<ns_uuid>%s)/engagement/(?P<eng_uuid>%s)?$' % (re_uuid, re_uuid),
+ nextsteps.EditNextSteps.as_view()), # Set State for a next step
+ url(r'^nextsteps/(?P<ns_uuid>%s)/(?P<attr>state)/?$' %
+ re_uuid, nextsteps.NextSteps.as_view()), # Set State for a next step
+ url(r'^nextsteps/(?P<ns_uuid>%s)$' %
+ re_uuid, nextsteps.EditNextSteps.as_view()),
+
+ # Login + Signup:
+ url(r'^login(?P<param>%s)?$' %
+ re_token_reset_password, login.Login.as_view()),
+ url(r'^signup/?$', signup.SignUp.as_view()),
+
+ # User Actions
+ url(r'^vf/?$', vf.VF.as_view()),
+ url(r'^add-contact/?$', invite.InviteContact.as_view()),
+ url(r'^invite-team-members/?$', invite.InviteTeamMember.as_view()),
+ url(r'^add-feedback/?$', feedback.Feedback.as_view()),
+
+ # Notifications - set notifications for specific user to is_read = True
+ url(r'^notifications/reset/?$', notification.NotificationOps.as_view()),
+ url(r'^notifications/num/?$', notification.PullNotifCount4User.as_view()),
+
+ # Notifications - pull unread objects
+ url(r'^notifications/(?P<user_uuid>%s)/(?P<offset>\d+)/(?P<limit>\d+)$' %
+ re_uuid, notification.NotificationOps.as_view()),
+ # Notifications - delete specific notification for a user
+ url(r'^notifications/(?P<notif_uuid>%s)$' %
+ re_uuid, notification.NotificationOps.as_view()),
+
+ # Initialize the engagement leads
+ url(r'^load-engagement-leads/?$',
+ data_loader.EngLeadsDataLoader.as_view()),
+ # Initialize companies
+ url(r'^load-companies/?$', data_loader.CompaniesDataLoader.as_view()),
+
+ # get/add CLAuditLogs
+ url(r'^checklist/decision/(?P<decision_uuid>%s)/auditlog/$' %
+ re_uuid, checklist_audit_log.DecisionAuditLog.as_view()),
+ url(r'^checklist/(?P<checklistUuid>%s)/auditlog/$' %
+ re_uuid, checklist_audit_log.ChecklistAuditLog.as_view()),
+
+ # get/set CLDecision
+ url(r'^checklist/decision/(?P<decision_uuid>%s)$' %
+ re_uuid, checklist_decision.ClDecision.as_view()),
+ # get/set CLDecision
+ url(r'^checklist/(?P<checklistUuid>%s)/state/$' %
+ re_uuid, checklist_set_state.ChecklistState.as_view()),
+
+ url(r'^checklist/template/$', checklist.CheckListTemplates.as_view()),
+ url(r'^checklist/templates/$', checklist.CheckListTemplates.as_view()),
+ url(r'^checklist/template/(?P<templateUuid>%s)$' %
+ re_uuid, checklist.CheckListTemplates.as_view()),
+
+ # get Checklist (returns files and all templates)
+ url(r'^engagement/(?P<eng_uuid>%s)/checklist/(?P<checklistUuid>%s)/nextstep/$' % (re_uuid, re_uuid),
+ nextsteps.ChecklistNextStep.as_view()),
+ url(r'^engagement/(?P<eng_uuid>%s)/checklist/new/$' %
+ re_uuid, checklist.NewCheckList.as_view()),
+ url(r'^checklist/(?P<checklistUuid>%s)$' %
+ re_uuid, checklist.ExistingCheckList.as_view()),
+ url(r'^checklist/$', checklist.ExistingCheckList.as_view()),
+
+ url(r'^cms/posts/$', Posts.as_view()),
+ url(r'^cms/pages/$', Pages.as_view()),
+ url(r'^cms/pages/search/?$', PageSearch.as_view()),
+ url(r'^cms/pages/(?P<id>\d+)/$', PageById.as_view()),
+]
diff --git a/django/engagementmanager/utils/__init__.py b/django/engagementmanager/utils/__init__.py
new file mode 100755
index 0000000..371b694
--- /dev/null
+++ b/django/engagementmanager/utils/__init__.py
@@ -0,0 +1,65 @@
+#
+# ============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.
+
+
+def dict_path_get(dicttree, path, default=None):
+ """Use a /-separated path to query a structure of nested dicts.
+
+ Note: If the path does not exist, this will return None instead of
+ raising an exception.
+
+ >>> nested = {
+ ... 'a': {
+ ... 'b': {
+ ... 'c': 'foo'
+ ... }
+ ... }
+ ... }
+ ...
+ >>> dict_path_get(nested, 'a/b/c')
+ 'foo'
+
+ """
+ d = dicttree
+ try:
+ for k in path.split('/'):
+ d = d[k]
+ except KeyError:
+ d = default
+ return d
diff --git a/django/engagementmanager/utils/activities_data.py b/django/engagementmanager/utils/activities_data.py
new file mode 100755
index 0000000..24275d6
--- /dev/null
+++ b/django/engagementmanager/utils/activities_data.py
@@ -0,0 +1,116 @@
+#
+# ============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 engagementmanager.utils.constants import ActivityType
+
+
+class ActivityData:
+ def __init__(self, engagement, activity_type, owner=None):
+ self.engagement = engagement
+ self.description = ''
+ self.metadata = {}
+ self.activity_type = activity_type
+ self.is_notification = False
+ self.owner = owner
+ self.multiple_users_as_owners = False
+ self.user = None
+
+
+class UserJoinedEngagementActivityData(ActivityData):
+ def __init__(self, vf, users_list, engagement, owner=None):
+ super(UserJoinedEngagementActivityData, self).__init__(engagement, ActivityType.user_joined_eng, owner)
+ self.vf = vf
+ self.users_list = users_list
+
+
+class VFProvisioningActivityData(ActivityData):
+ def __init__(self, vf, users_list, engagement, description="There was an error provisioning the VF", owner=None):
+ super(VFProvisioningActivityData, self).__init__(engagement, ActivityType.vf_provisioning_event, owner)
+ self.vf = vf
+ self.description = description
+ self.users_list = users_list
+
+
+class TestFinishedActivityData(ActivityData):
+ def __init__(self, users_list, engagement, description="There was an error in Test"
+ " Finished signal from Jenkins", owner=None):
+ super(TestFinishedActivityData, self).__init__(engagement, ActivityType.test_finished_event, owner)
+ self.description = description
+ self.users_list = users_list
+
+
+class ChangeEngagementStageActivityData(ActivityData):
+ def __init__(self, vf, stage, engagement, owner=None):
+ super(ChangeEngagementStageActivityData, self).__init__(engagement, ActivityType.change_engagement_stage, owner)
+ self.vf = vf
+ self.stage = stage
+
+
+class AddNextStepsActivityData(ActivityData):
+ def __init__(self, vf, user, engagement, owner=None):
+ super(AddNextStepsActivityData, self).__init__(engagement, ActivityType.add_next_steps, owner)
+ self.vf = vf
+ self.user = user
+
+
+class NoticeEmptyEngagementData(ActivityData):
+ def __init__(self, vf_name, max_empty_time, git_repo_url, delta_days_from_creation, engagement, owner=None):
+ super(NoticeEmptyEngagementData, self).__init__(engagement, ActivityType.notice_empty_engagement, owner)
+ self.max_empty_time = max_empty_time
+ self.vf_name = vf_name
+ self.git_repo_url = git_repo_url
+ self.delta_days_from_creation = delta_days_from_creation
+
+
+class UpdateNextStepsActivityData(ActivityData):
+ def __init__(self, update_type, user, engagement, owner=None):
+ super(UpdateNextStepsActivityData, self).__init__(engagement, ActivityType.update_next_steps, owner)
+ self.update_type = update_type
+ self.user = user
+
+
+class DeleteNextStepsActivityData(ActivityData):
+ def __init__(self, user, engagement, owner=None):
+ super(DeleteNextStepsActivityData, self).__init__(engagement, ActivityType.delete_next_steps, owner)
+ self.user = user
+
+
+class SSHKeyAddedActivityData(ActivityData):
+ def __init__(self, action, engagement, owner=None):
+ super(SSHKeyAddedActivityData, self).__init__(engagement, ActivityType.ssh_key_added, owner)
+ self.action = action
diff --git a/django/engagementmanager/utils/authentication.py b/django/engagementmanager/utils/authentication.py
new file mode 100755
index 0000000..6a857d6
--- /dev/null
+++ b/django/engagementmanager/utils/authentication.py
@@ -0,0 +1,91 @@
+#
+# ============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 itsdangerous import URLSafeTimedSerializer
+from rest_framework_jwt.settings import api_settings
+from rest_framework_jwt.utils import jwt_decode_handler
+from engagementmanager.models import IceUserProfile
+from engagementmanager.utils.request_data_mgr import request_data_mgr
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def ice_jwt_decode_handler(token):
+ decoded_dict = jwt_decode_handler(token)
+ email = decoded_dict.get('email', None)
+ user = IceUserProfile.objects.get(email=email)
+ request_data_mgr.clear_old_request_data()
+ request_data_mgr.set_user(user)
+ return decoded_dict
+
+
+class JWTAuthentication(object):
+ """
+ Simple token based authentication.
+ Clients should authenticate by passing the token key in the "Authorization" HTTP header, prepended with the string "Token ".
+ For example: Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a
+ """
+
+ def create_token(self, user_data):
+ jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
+ jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
+
+ payload = jwt_payload_handler(user_data)
+ token = jwt_encode_handler(payload)
+ return token
+
+ def create_reset_password_token(self, user_data):
+ """
+ Create token for reset password flow.
+ """
+ encryptor = URLSafeTimedSerializer(api_settings.JWT_SECRET_KEY)
+ return encryptor.dumps(user_data.email, salt=api_settings.JWT_SECRET_KEY)
+
+ def decode_reset_password_token(self, token):
+ """
+ Decoded the token created at reset password flow and return what was encrypted.
+ """
+ decryptor = URLSafeTimedSerializer(api_settings.JWT_SECRET_KEY)
+ email = decryptor.loads(
+ token,
+ salt=api_settings.JWT_SECRET_KEY,
+ max_age=3600
+ )
+
+ return email
diff --git a/django/engagementmanager/utils/choice_enum.py b/django/engagementmanager/utils/choice_enum.py
new file mode 100755
index 0000000..ef19de2
--- /dev/null
+++ b/django/engagementmanager/utils/choice_enum.py
@@ -0,0 +1,56 @@
+#
+# ============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 enum import Enum
+
+
+class ChoiceEnum(Enum):
+ """An Enumeration with an added choices() method useful in Django"""
+
+ @classmethod
+ def choices(cls):
+ """Return this Enum's values in a format suitable for use as Django Field.choices param.
+
+ https://docs.python.org/3/library/enum.html
+ https://docs.djangoproject.com/en/1.10/ref/models/fields/#choices
+
+ """
+ # FIXME it might be more useful in some situations to return (x.value, x.name), but we do
+ # this way is for compatibility with older versions of this code. Changing would require a
+ # data migration.`
+ return [(x.name, x.name) for x in cls]
diff --git a/django/engagementmanager/utils/constants.py b/django/engagementmanager/utils/constants.py
new file mode 100755
index 0000000..c5b1ae9
--- /dev/null
+++ b/django/engagementmanager/utils/constants.py
@@ -0,0 +1,211 @@
+#
+# ============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 enum import Enum
+from engagementmanager.utils.choice_enum import ChoiceEnum
+
+
+class Roles(Enum):
+ standard_user = 1
+ el = 2
+ admin = 3
+ admin_ro = 4
+
+
+class Constants(object):
+ service_provider_company = None
+ role_el = None
+ role_standard_user = None
+ role_admin = None
+ role_admin_ro = None
+ service_provider_company_name = "ExampleServiceProvider"
+ service_provider_mail_domain = ["example.com"]
+ service_provider_admin_mail = "admin@example.com"
+ service_provider_admin_ro_mail = "admin_ro@example.com"
+ ice_base_ctx = "/vvp/v1/engmgr/"
+ rgwa_base_url ='http://localhost:8123/admin'
+ default_vfc_version = "1.0.0"
+ dbConnectionStr = "dbname='icedb' user='iceuser' host='localhost' password='Aa123456' port='5433'"
+ dashboard_href = "<A href=" + \
+ str(settings.DOMAIN) + "/#/dashboard/" + ">Dashboard</A>"
+ prodDomain = 'https://www.vvp.example.com'
+ invite_template_dir = "emails/invite/"
+ activate_template_dir = "emails/activate/"
+ notification_template_dir = "emails/notification/"
+ reset_pwd_template_dir = "emails/reset_pwd/"
+ activation_prefix = "/#/activate/"
+ program_name = "VVP"
+
+
+class TemplatesConstants(object):
+ logo_url = "https://www.d2ice.att.io/styles/images/d2sandbox_logos-150x30.png"
+ contact_mail = "d2ice@att.com"
+ context = {"service_provider": Constants.service_provider_company_name,
+ "program_name": Constants.program_name,
+ "logo_url": logo_url,
+ "contact_mail": contact_mail,
+ }
+
+
+'''
+In order to get Enum Value as String use: EngagementType.Validation.name
+'''
+class EngagementModelValidationDate:
+ HEAT_VALIDATED = "heat_validated_time"
+ IMAGE_SCAN = "image_scan_time"
+ AIC_INSTANTIATION = "aic_instantiation_time"
+ ASDC_ONBOARDING = "asdc_onboarding_time"
+
+
+class JenkinsBuildParametersNames:
+ CHECKLIST_UUID = "checklist_uuid"
+ GIT_REPO_URL = "git_repo_url"
+
+
+class MockJenkinsBuildLog:
+ TEXT = "from server: Started by user admin \n \
+ Building in workspace /var/jenkins_home/workspace/{vf_name}_{eng_man_id} \n \
+ [{vf_name}_{eng_man_id}] $ /bin/sh /tmp/jenkins{random_id}.sh \n \
+ Cloning into '/var/jenkins_home/workspace/{vf_name}_{eng_man_id}/VF'"
+
+
+class ChecklistDefaultNames:
+ HEAT_TEMPLATES = "Heat Templates"
+ IMAGE_VALIDATION = "Image Validation"
+ AIC_INSTANTIATION = "AIC Instantiation"
+ ASDC_ONBOARDING = "ASDC Onboarding"
+ VALIDATION_DATE_ARRAY = {
+ HEAT_TEMPLATES: EngagementModelValidationDate.HEAT_VALIDATED,
+ IMAGE_VALIDATION: EngagementModelValidationDate.IMAGE_SCAN,
+ AIC_INSTANTIATION: EngagementModelValidationDate.AIC_INSTANTIATION,
+ ASDC_ONBOARDING: EngagementModelValidationDate.ASDC_ONBOARDING
+ }
+
+
+class EngagementType(Enum):
+ Validation = 1
+ Other = 2
+
+
+class EngagementStage(ChoiceEnum):
+ Intake = 1,
+ Active = 2,
+ Validated = 3,
+ Completed = 4,
+ Archived = 5
+
+
+class NextStepState(ChoiceEnum):
+ Incomplete = 1,
+ Completed = 2
+
+
+class RGWApermission:
+ READ = 'READ',
+ WRITE = 'WRITE'
+
+
+class NextStepType(ChoiceEnum):
+ set_ssh = 1,
+ trial_agreements = 2,
+ add_contact_person = 3,
+ submit_vf_package = 4,
+ el_handoff = 5,
+ user_defined = 6
+
+
+class ExceptionType(Enum):
+ TSS = 1
+ STAT = 2
+
+
+# NOTE: For each added activity that you wish to send notification mail,
+# add an "if" in activity_log::getSubjectAndDescByActivityType
+class ActivityType(ChoiceEnum):
+ user_joined_eng = 1
+ ssh_key_added = 2
+ eng_validation_request = 3
+ update_next_steps = 4
+ vfc = 5
+ change_checklist_state = 6
+ vf_provisioning_event = 7
+ test_finished_event = 8
+ change_engagement_stage = 9
+ add_next_steps = 10
+ delete_next_steps = 11
+ notice_empty_engagement = 12
+
+
+class CheckListLineType(ChoiceEnum):
+ auto = 1,
+ manual = 2
+
+
+class CheckListState(ChoiceEnum):
+ automation = 1,
+ review = 2,
+ peer_review = 3,
+ approval = 4,
+ handoff = 5,
+ closed = 6,
+ archive = 7,
+ pending = 8
+
+
+class CheckListCategory(ChoiceEnum):
+ overall = 1,
+ heat = 2,
+ glance = 3
+ instantiation = 4
+ asdc = 5
+
+
+class CheckListDecisionValue(ChoiceEnum):
+ approved = 1,
+ denied = 2,
+ not_relevant = 3,
+ na = 4
+
+
+class RecentEngagementActionType(ChoiceEnum):
+ JOINED_TO_ENGAGEMENT = 1,
+ NEXT_STEP_ASSIGNED = 2,
+ GOT_OWNERSHIP_OVER_ENGAGEMENT = 3,
+ NAVIGATED_INTO_ENGAGEMENT = 4,
+ NEW_VF_CREATED = 5,
diff --git a/django/engagementmanager/utils/cryptography.py b/django/engagementmanager/utils/cryptography.py
new file mode 100755
index 0000000..723efa0
--- /dev/null
+++ b/django/engagementmanager/utils/cryptography.py
@@ -0,0 +1,61 @@
+#
+# ============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 itsdangerous import URLSafeTimedSerializer
+from rest_framework_jwt.settings import api_settings
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class CryptographyText(object):
+
+ @staticmethod
+ def encrypt(text):
+ encryptor = URLSafeTimedSerializer(api_settings.JWT_SECRET_KEY)
+ return encryptor.dumps(text, salt=api_settings.JWT_SECRET_KEY)
+
+ @staticmethod
+ def decrypt(encoded_text):
+ decryptor = URLSafeTimedSerializer(api_settings.JWT_SECRET_KEY)
+ text = decryptor.loads(
+ encoded_text,
+ salt=api_settings.JWT_SECRET_KEY,
+ )
+
+ return text
diff --git a/django/engagementmanager/utils/dates.py b/django/engagementmanager/utils/dates.py
new file mode 100755
index 0000000..db1d8fe
--- /dev/null
+++ b/django/engagementmanager/utils/dates.py
@@ -0,0 +1,51 @@
+#
+# ============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 datetime import datetime
+
+
+def parse_date(date_string, convention=None):
+ result = None
+
+ if convention is None:
+ convention = '%Y-%m-%dT%H:%M:%S.%fZ'
+
+ if date_string is not None:
+ result = datetime.strptime(str(date_string), convention)
+
+ return result
diff --git a/django/engagementmanager/utils/exception_handler.py b/django/engagementmanager/utils/exception_handler.py
new file mode 100755
index 0000000..b1b46ee
--- /dev/null
+++ b/django/engagementmanager/utils/exception_handler.py
@@ -0,0 +1,73 @@
+#
+# ============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 traceback
+from rest_framework.response import Response
+from rest_framework.views import exception_handler
+from engagementmanager.utils.exception_message_factory import ExceptionMessageFactory
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def ice_exception_handler(exc, context):
+ """
+ our own exception handler so we will catch every exception occurred in rest and print it's stack into log
+ :param exc: The exception
+ :param context: The context which the exception occurred in.
+ """
+ response = exception_handler(exc, context)
+
+ if exc is not None:
+ message_factory = ExceptionMessageFactory()
+ exception_msg_obj = message_factory.get_exception_message(exc)
+ data = {'detail': exception_msg_obj['msg']}
+
+ if exception_msg_obj['include_exception']:
+ data['detail'] += str(exc)
+ if 'include_additional_exc_str' in exception_msg_obj and exception_msg_obj['include_additional_exc_str']:
+ data['exception_message'] = str(exc)
+
+ response = Response(data, status=exception_msg_obj['status'])
+
+ logger.error("General exception occurred in rest framework: %s", exc)
+ logger.debug("*******************************************************************************************")
+ logger.debug(traceback.format_exc())
+ logger.debug("*******************************************************************************************")
+
+ return response
diff --git a/django/engagementmanager/utils/exception_message_factory.py b/django/engagementmanager/utils/exception_message_factory.py
new file mode 100755
index 0000000..6ea96f4
--- /dev/null
+++ b/django/engagementmanager/utils/exception_message_factory.py
@@ -0,0 +1,92 @@
+#
+# ============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.core.exceptions import ObjectDoesNotExist
+from django.core.management.base import CommandError
+from engagementmanager.utils.vvp_exceptions import VvpObjectNotAvailable, \
+ VvpGeneralException, VvpBadRequest, VvpConflict
+from itsdangerous import SignatureExpired
+from requests import ConnectionError
+from rest_framework import status
+from rest_framework.exceptions import MethodNotAllowed, NotAuthenticated, \
+ PermissionDenied, NotAcceptable
+
+
+class ExceptionMessageFactory:
+ messages_dictionary = {
+ ObjectDoesNotExist.__name__: {'msg': 'User or Password does not match', 'include_exception': False,
+ 'status': status.HTTP_404_NOT_FOUND},
+ MethodNotAllowed.__name__: {'msg': 'Method not allowed: ', 'include_exception': True,
+ 'status': status.HTTP_405_METHOD_NOT_ALLOWED},
+ NotAuthenticated.__name__: {'msg': 'You must authenticate in order to perform this action: ',
+ 'include_exception': True, 'status': status.HTTP_403_FORBIDDEN},
+ SignatureExpired.__name__: {'msg': 'Signature expired for this token: ', 'include_exception': True,
+ 'status': status.HTTP_405_METHOD_NOT_ALLOWED},
+ KeyError.__name__: {'msg': 'KeyError occurred over the backend.', 'include_exception': True,
+ 'include_additional_exc_str': True, 'status': status.HTTP_400_BAD_REQUEST},
+ ValueError.__name__: {'msg': 'ValueError occurred over the backend: ', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ ConnectionError.__name__: {'msg': 'ConnectionError occurred over the backend: ', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ ImportError.__name__: {'msg': 'ImportError occurred over the backend: ', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ CommandError.__name__: {'msg': 'CommandError occurred over the backend: ', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ PermissionDenied.__name__: {'msg': 'PermissionDenied occurred over the backend: ', 'include_exception': True,
+ 'status': status.HTTP_401_UNAUTHORIZED},
+ VvpObjectNotAvailable.__name__: {'msg': '', 'include_exception': True, 'status': status.HTTP_410_GONE},
+ NotAcceptable.__name__: {'msg': '', 'include_exception': True, 'status': status.HTTP_403_FORBIDDEN},
+ VvpGeneralException.__name__: {'msg': '', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ FileExistsError.__name__: {'msg': 'Not modified due to: ', 'include_exception': True,
+ 'status': status.HTTP_304_NOT_MODIFIED},
+ VvpBadRequest.__name__: {'msg': '', 'include_exception': True, 'status': status.HTTP_400_BAD_REQUEST},
+ VvpConflict.__name__: {'msg': '', 'include_exception': True, 'status': status.HTTP_409_CONFLICT},
+ Exception.__name__: {'msg': 'General error on backend: ', 'include_exception': True,
+ 'status': status.HTTP_500_INTERNAL_SERVER_ERROR},
+ }
+
+ def get_exception_message(self, exception):
+ if isinstance(exception, ObjectDoesNotExist):
+ result = self.messages_dictionary[ObjectDoesNotExist.__name__]
+ elif exception.__class__.__name__ in self.messages_dictionary:
+ result = self.messages_dictionary[exception.__class__.__name__]
+ else:
+ result = self.messages_dictionary[Exception.__name__]
+
+ return result
diff --git a/django/engagementmanager/utils/request_data_mgr.py b/django/engagementmanager/utils/request_data_mgr.py
new file mode 100755
index 0000000..46557b4
--- /dev/null
+++ b/django/engagementmanager/utils/request_data_mgr.py
@@ -0,0 +1,128 @@
+#
+# ============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 threading
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class RequsetData():
+ _thread_id = None
+ _cl_uuid = None
+ _eng_uuid = None
+ _user = None
+ _ns_uuid = None
+ _notification_uuid = None
+
+ def __init__(self):
+ pass
+
+
+class RequsetDataMgr:
+
+ threadLocal = threading.local()
+
+ '''
+ Managing the request data per each request
+ '''
+
+ def __init__(self):
+ pass
+
+ '''
+ Private method
+ '''
+
+ def get_request_data(self):
+ request_data = getattr(self.threadLocal, 'request_data', None)
+ if request_data is None:
+ request_data = RequsetData()
+ self.threadLocal.request_data = request_data
+
+ return request_data
+
+ def get_user(self):
+ return self.get_request_data()._user
+
+ def get_eng_uuid(self):
+ return self.get_request_data()._eng_uuid
+
+ def get_cl_uuid(self):
+ return self.get_request_data()._cl_uuid
+
+ def get_ns_uuid(self):
+ return self.get_request_data()._ns_uuid
+
+ def get_notification_uuid(self):
+ return self.get_request_data()._notification_uuid
+
+ def set_user(self, user):
+ self.get_request_data()._user = user
+
+ def set_eng_uuid(self, eng_uuid):
+ self.get_request_data()._eng_uuid = eng_uuid
+
+ def set_cl_uuid(self, cl_uuid):
+ self.get_request_data()._cl_uuid = cl_uuid
+
+ def set_ns_uuid(self, ns_uuid):
+ self.get_request_data()._ns_uuid = ns_uuid
+
+ def set_notification_uuid(self, notification_uuid):
+ self.get_request_data()._notification_uuid = notification_uuid
+
+ def get_request_data_vars(self):
+ return {
+ 'cl_uuid': self.get_request_data()._cl_uuid,
+ 'eng_uuid': self.get_request_data()._eng_uuid,
+ 'user': self.get_request_data()._user,
+ 'ns_uuid': self.get_request_data()._ns_uuid,
+ 'notification_uuid': self.get_request_data()._notification_uuid,
+ }
+
+ '''
+ Called from the verify_token decorator which is a central place that populates the user and all other attributes in RequestData object
+ '''
+
+ def clear_old_request_data(self):
+ self.threadLocal.request_data = RequsetData()
+
+
+# singleton pattern, allocated on server startup
+request_data_mgr = RequsetDataMgr()
diff --git a/django/engagementmanager/utils/validator.py b/django/engagementmanager/utils/validator.py
new file mode 100755
index 0000000..cef67f6
--- /dev/null
+++ b/django/engagementmanager/utils/validator.py
@@ -0,0 +1,90 @@
+#
+# ============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.
+'''
+Taken from https://pypi.python.org/pypi/validate_email
+'''
+import re
+import bleach
+from validate_email import validate_email
+from engagementmanager.utils.vvp_exceptions import VvpBadRequest
+from engagementmanager.service.logging_service import LoggingServiceFactory
+
+logger = LoggingServiceFactory.get_logger()
+
+
+class Validator(object):
+
+ @staticmethod
+ def validateEmail(email):
+ if not validate_email(email):
+ msg = "email address validation error"
+ logger.error(msg)
+ raise KeyError(msg)
+
+ @staticmethod
+ def validatePassword(password, confirm_password=False):
+ if confirm_password is not False and password != confirm_password:
+ msg = "'Password' and 'Confirm Password' do not match."
+ logger.error(msg)
+ raise VvpBadRequest(msg)
+ if len(password) < 4:
+ msg = "'Password' must be more than 4 letters."
+ logger.error(msg)
+ raise VvpBadRequest(msg)
+ if len(password) > 32:
+ msg = "'Password' must be less than 32 letters"
+ logger.error(msg)
+ raise VvpBadRequest(msg)
+
+ @staticmethod
+ def validateCheckListName(name):
+ regex_pattern = "^[a-zA-Z0-9\&\ ]*$"
+ pattern = re.compile(regex_pattern)
+
+ return pattern.match(name)
+
+
+def logEncoding(data):
+ try:
+ clean_data = bleach.clean(str(data))
+ clean_data += " (User Input)"
+ except Exception as e:
+ clean_data = "couldnt bleach data"
+ pass
+ return clean_data
diff --git a/django/engagementmanager/utils/vvp_exceptions.py b/django/engagementmanager/utils/vvp_exceptions.py
new file mode 100755
index 0000000..2cc9cee
--- /dev/null
+++ b/django/engagementmanager/utils/vvp_exceptions.py
@@ -0,0 +1,66 @@
+#
+# ============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 rest_framework import status
+from rest_framework.exceptions import APIException
+
+"""Custom exceptions for VVP project"""
+
+
+class VvpBadRequest(APIException):
+ status_code = status.HTTP_400_BAD_REQUEST
+ default_detail = 'Bad request.'
+ default_code = 'bad_request'
+
+
+class VvpObjectNotAvailable(APIException):
+ status_code = status.HTTP_410_GONE
+ default_detail = 'Bad request.'
+ default_code = 'bad_request'
+
+
+class VvpGeneralException(APIException):
+ status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
+ default_detail = 'Bad request.'
+ default_code = 'bad_request'
+
+
+class VvpConflict(APIException):
+ status_code = status.HTTP_409_CONFLICT
+ default_detail = 'Conflic.'
+ default_code = 'conflict'
diff --git a/django/engagementmanager/views_helper.py b/django/engagementmanager/views_helper.py
new file mode 100755
index 0000000..418290b
--- /dev/null
+++ b/django/engagementmanager/views_helper.py
@@ -0,0 +1,347 @@
+#
+# ============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.utils import timezone
+from engagementmanager.apps import bus_service
+from engagementmanager.bus.messages.activity_event_message import \
+ ActivityEventMessage
+from engagementmanager.slack_client.api import SlackClient
+from engagementmanager.models import IceUserProfile, Engagement, \
+ DeploymentTarget, VF, Role, NextStep, ECOMPRelease
+from engagementmanager.serializers import VFModelSerializer
+from engagementmanager.service.checklist_state_service import \
+ insert_to_recent_engagements
+from engagementmanager.service.engagement_service import \
+ update_or_insert_to_recent_engagements
+from engagementmanager.service.logging_service import LoggingServiceFactory
+from engagementmanager.service.nextstep_service import NextStepSvc
+from engagementmanager.utils.constants import Constants, NextStepType, \
+ NextStepState, RecentEngagementActionType, Roles
+from engagementmanager.utils.activities_data import \
+ UserJoinedEngagementActivityData
+from engagementmanager.utils.validator import logEncoding
+from engagementmanager.vm_integration import vm_client
+import random
+import re
+
+
+logger = LoggingServiceFactory.get_logger()
+
+
+def addEntityIfNotExist(entity, entityObj):
+ entResultSet = entity.objects.filter(uuid=entityObj.uuid)
+
+ if entResultSet.exists():
+ logger.debug(str(entityObj) + " Exists with UUID |" + entityObj.uuid)
+ was_created = False
+ else:
+ entityObj.save()
+ was_created = True
+
+ return entity.objects.get(uuid=entityObj.uuid), was_created
+
+
+def createEngagement(user, manual_el_id=False):
+ eng_manual_id = str(timezone.now().year) + "-" + \
+ str(Engagement.objects.count() + 31)
+ eng = Engagement(
+ engagement_manual_id=eng_manual_id, creator=user)
+ elUser = None
+ randUser = None
+ elRole = Role.objects.get(name=Roles.el.name) # @UndefinedVariable
+ if user.role == elRole:
+ manual_el_id = user.email
+
+ # Attaching EL and Peer Reviewer to the Engagment
+ if user.role != elRole:
+ if not manual_el_id:
+ # Fetch a random EL
+ qs = IceUserProfile.objects.all().filter(role=elRole) # @UndefinedVariable
+ if qs.count() > 0:
+ randUser = qs[random.randint(0, qs.count() - 1)]
+ elUser = IceUserProfile.objects.get(uuid=randUser.uuid)
+ else:
+ # Set el manually, for example when using import from xls el is
+ # already assigned
+ elUser = IceUserProfile.objects.get(email=manual_el_id)
+ else:
+ logger.debug("Since the user " + user.full_name +
+ " is an EL, no need to find another one")
+ elUser = user
+
+ logger.debug("Selected engagement lead=" + elUser.full_name)
+ eng.reviewer = elUser
+
+ # Fetch another random el to be a Peer Reviewer
+ qs = IceUserProfile.objects.all().filter(
+ role=elRole, user__is_active=True).exclude(uuid=elUser.uuid) # @UndefinedVariable
+ prUser = None
+ if qs.count() > 0:
+ randUser = qs[random.randint(0, qs.count() - 1)]
+ prUser = IceUserProfile.objects.get(uuid=randUser.uuid)
+ eng.peer_reviewer = prUser
+ logger.debug("Selected peer reviewer=" + prUser.full_name)
+
+ engObj, was_created = addEntityIfNotExist(Engagement, eng)
+
+ return engObj, elUser, prUser
+
+
+def is_str_supports_git_naming_convention(item):
+ """
+ validates that string can contain only letters, digits hyphen and dot. Also, String cannot end with dot
+ """
+ return bool(re.compile("^[a-zA-Z0-9-]*$").match(item))
+
+
+def createVF(user, request):
+ """
+ Create DeploymentTarget
+ Create Engagement
+ Create Application_Service_Infrastructure
+ Create VF
+ """
+ dataList = request.data
+ vfList = []
+
+ for data in dataList:
+ logger.debug("Processing VF - " + str(data))
+
+ if ('virtual_function' not in data or not data['virtual_function'] or
+ 'version' not in data or not data['version'] or
+ 'target_lab_entry_date' not in data or not data['target_lab_entry_date'] or
+ 'target_aic_uuid' not in data or not data['target_aic_uuid'] or
+ 'ecomp_release' not in data or not data['ecomp_release'] or
+ 'is_service_provider_internal' not in data):
+ raise KeyError("One of the input parameters are missing")
+
+ # Set el manually, for example when using import from xls el is
+ # already assigned
+ if 'manual_el_id' in data:
+ manual_el_id = data['manual_el_id']
+ else:
+ manual_el_id = False
+ engObj, elUser, prUser = createEngagement(user, manual_el_id)
+
+ if engObj is None or elUser is None:
+ raise ValueError("Couldn't fetch engagement or engagement lead")
+
+ if user is not None and engObj is not None:
+ NextStepSvc().create_default_next_steps(user, engObj, elUser)
+
+ i_target_aic_uuid = data['target_aic_uuid']
+ dtObj = DeploymentTarget.objects.get(uuid=i_target_aic_uuid)
+
+ i_ecomp_release = data['ecomp_release']
+ ecompObj = ECOMPRelease.objects.get(uuid=i_ecomp_release)
+
+ i_vfName = data['virtual_function']
+ if not is_str_supports_git_naming_convention(i_vfName):
+ msg = "VF Name can contain only letters, digits hyphen and dot. VF Name cannot end with dot"
+ logger.error(msg)
+ raise ValueError(msg)
+ i_vfVersion = data['version']
+ i_is_service_provider_internal = data['is_service_provider_internal']
+ i_target_lab_entry_date = data['target_lab_entry_date']
+
+ vf = VF(name=i_vfName,
+ version=i_vfVersion,
+ engagement=engObj,
+ deployment_target=dtObj,
+ ecomp_release=ecompObj,
+ is_service_provider_internal=i_is_service_provider_internal,
+ vendor=user.company,
+ target_lab_entry_date=i_target_lab_entry_date
+ )
+
+ vfObj, was_created = addEntityIfNotExist(VF, vf)
+
+ insert_to_recent_engagements(
+ user, RecentEngagementActionType.NEW_VF_CREATED.name, vfObj) # @UndefinedVariable
+
+ addUsersToEngTeam(engObj.uuid, [user, elUser, prUser])
+ sendSlackNotifications(engObj.uuid, [user, elUser, prUser])
+ # trigger repo creation as soon as vf is created and users are added to
+ # team
+ if was_created:
+ vm_client.fire_event_in_bg('send_provision_new_vf_event', vfObj)
+ vfData = VFModelSerializer(vfObj).data
+ vfList.append(vfData)
+
+ return vfList
+
+
+def updateValidationDetails(request):
+ # if data['target_aic_uuid'] is not None and data['target_aic_uuid'] != "":
+ data = request.data
+ logger.debug("Processing VF_Details - " + str(data))
+ vf = VF.objects.get(uuid=data['vf_uuid'])
+ if 'target_aic_uuid' in data:
+ dt_obj = DeploymentTarget.objects.get(uuid=data['target_aic_uuid'])
+ vf.deployment_target = dt_obj
+ if 'ecomp_release' in data: # is not None and data['ecomp_release'] != "":
+ ecomp_obj = ECOMPRelease.objects.get(uuid=data['ecomp_release'])
+ vf.ecomp_release = ecomp_obj
+ if 'version' in data:
+ vf.version = data['version']
+ vf.save()
+
+
+def checkAndModifyIfSSHNextStepExist(user):
+ SSHStep = None
+ qs = NextStep.objects.filter(
+ owner=user, next_step_type=NextStepType.set_ssh.name) # @UndefinedVariable
+ if qs is None or qs.count() == 0:
+ return None
+ else:
+ SSHStep = NextStep.objects.get(
+ owner=user, next_step_type=NextStepType.set_ssh.name) # @UndefinedVariable
+
+ # @UndefinedVariable
+ if SSHStep.state in (NextStepState.Incomplete.name) and user.ssh_public_key:
+ SSHStep.state = 'Completed'
+ SSHStep.last_update_time = timezone.now()
+ SSHStep.last_update_type = 'Completed'
+ SSHStep.save()
+
+ return SSHStep
+
+
+def addUsersToEngTeam(eng_uuid, newUserList):
+ """
+ If the user isn't an EL and their doesn't have an SSH step then create personal SSH next step for him.
+ """
+ engObj = Engagement.objects.get(uuid=eng_uuid)
+ vfObj = engObj.vf
+ el_user = IceUserProfile.objects.get(uuid=engObj.reviewer.uuid)
+ if not el_user:
+ el_user = newUserList[1]
+ for newUser in newUserList:
+ engObj.engagement_team.add(newUser)
+ update_or_insert_to_recent_engagements(
+ newUser.uuid, vfObj, RecentEngagementActionType.JOINED_TO_ENGAGEMENT.name) # @UndefinedVariable
+ SSHStep = checkAndModifyIfSSHNextStepExist(newUser)
+ if not SSHStep and newUser != el_user:
+ NextStepSvc().create_default_next_steps_for_user(newUser, el_user)
+ if vfObj is not None:
+ activity_data = UserJoinedEngagementActivityData(
+ vfObj, newUserList, engObj)
+ bus_service.send_message(ActivityEventMessage(activity_data))
+
+
+def sendSlackNotifications(eng_uuid, newUserList):
+ """
+ Send Slack notifications to the reviewer, peer reviewer and also the engagements channel
+ """
+ # get the engagement
+ engagement = Engagement.objects.get(uuid=eng_uuid)
+ engagement_manual_id = ""
+ if engagement is not None:
+ engagement_manual_id = engagement.engagement_manual_id
+
+ # get the vf
+ vf = VF.objects.get(engagement__uuid=eng_uuid)
+ vf_name = ""
+ if vf is not None:
+ vf_name = vf.name
+
+ # get the creator
+ creator = engagement.creator
+
+ # get the reviewer
+ reviewer = IceUserProfile.objects.get(uuid=engagement.reviewer.uuid)
+ if not reviewer:
+ reviewer = newUserList[1]
+
+ # get the peer reviewer
+ peer_reviewer = IceUserProfile.objects.get(
+ uuid=engagement.peer_reviewer.uuid)
+ if not peer_reviewer:
+ peer_reviewer = newUserList[2]
+
+ # send Slack messages when a new engagement is created
+ slack_client = SlackClient()
+ slack_client.send_slack_notifications_for_new_engagement(
+ engagement_manual_id, vf_name, reviewer, peer_reviewer, creator)
+
+
+def getVfByEngUuid(engUuid):
+ vfList = VF.objects.filter(engagement__uuid=engUuid)
+ if vfList:
+ logger.debug("Found VF name=" + vfList[0].name)
+ if len(vfList) > 1:
+ logger.warning(
+ "!! There seems to be more than one VF attached to the engagement with uuid=" + logEncoding(engUuid))
+ # Assumption: the list only has one item because the relation
+ # Engagement-VF is 1:1 business wise
+ return vfList[0]
+ else:
+ logger.error(
+ "There are no VFs in the engagement identified by eng_uuid=" + logEncoding(engUuid))
+ return None
+
+
+def generateActivationLink(activationToken, user):
+ return str(settings.DOMAIN) + Constants.activation_prefix + str(user.uuid) + "/" + activationToken
+
+
+def getFirstEngByUser(user):
+ engList = Engagement.objects.filter(engagement_team__uuid=user.uuid)
+ if engList.exists():
+ logger.debug("user was found in a an ENG:" + str(engList[0]))
+ return engList[0]
+ else:
+ logger.debug("user wasn't found in an ENG")
+ return None
+
+
+def createUserTemplate(company, full_name, role, phone, is_service_provider_contact, ssh_key=None, regular_email_updates=False, user=None):
+ data = {
+ 'company': company,
+ 'phone_number': phone,
+ 'full_name': full_name,
+ 'role': role,
+ 'create_time': timezone.now(),
+ 'is_service_provider_contact': is_service_provider_contact,
+ 'regular_email_updates': regular_email_updates,
+ 'ssh_public_key': ssh_key,
+ }
+ if user:
+ data['user'] = user
+ return data
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...")