From 3243110496f1dc4baa88863a46934a955c0efa46 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 2 May 2017 14:10:59 -0400 Subject: [PATCH] connect CredentialType to activity stream --- .../0040_v320_add_credentialtype_model.py | 17 ++++++ awx/main/models/__init__.py | 1 + awx/main/models/activity_stream.py | 1 + .../functional/models/test_activity_stream.py | 53 ++++++++++++++++++- 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/awx/main/migrations/0040_v320_add_credentialtype_model.py b/awx/main/migrations/0040_v320_add_credentialtype_model.py index fa335d8e3c..da3b4de342 100644 --- a/awx/main/migrations/0040_v320_add_credentialtype_model.py +++ b/awx/main/migrations/0040_v320_add_credentialtype_model.py @@ -64,4 +64,21 @@ class Migration(migrations.Migration): name='credential', unique_together=set([('organization', 'name', 'credential_type')]), ), + + # Connecting activity stream + migrations.AddField( + model_name='activitystream', + name='credential_type', + field=models.ManyToManyField(to='main.CredentialType', blank=True), + ), + migrations.AlterField( + model_name='credential', + name='credential_type', + field=models.ForeignKey(related_name='credentials', to='main.CredentialType', help_text='Type for this credential. Credential Types define valid fields (e.g,. "username", "password") and their properties (e.g,. "username is required" or "password should be stored with encryption").'), + ), + migrations.AlterField( + model_name='credential', + name='inputs', + field=awx.main.fields.CredentialInputField(default={}, help_text='Data structure used to specify input values (e.g., {"username": "jane-doe", "password": "secret"}). Valid fields and their requirements vary depending on the fields defined on the chosen CredentialType.', blank=True), + ), ] diff --git a/awx/main/models/__init__.py b/awx/main/models/__init__.py index c4623571ac..646618d1e8 100644 --- a/awx/main/models/__init__.py +++ b/awx/main/models/__init__.py @@ -109,6 +109,7 @@ activity_stream_registrar.connect(Group) activity_stream_registrar.connect(InventorySource) #activity_stream_registrar.connect(InventoryUpdate) activity_stream_registrar.connect(Credential) +activity_stream_registrar.connect(CredentialType) activity_stream_registrar.connect(Team) activity_stream_registrar.connect(Project) #activity_stream_registrar.connect(ProjectUpdate) diff --git a/awx/main/models/activity_stream.py b/awx/main/models/activity_stream.py index ddbdae1227..0e78cc2d56 100644 --- a/awx/main/models/activity_stream.py +++ b/awx/main/models/activity_stream.py @@ -45,6 +45,7 @@ class ActivityStream(models.Model): inventory_source = models.ManyToManyField("InventorySource", blank=True) inventory_update = models.ManyToManyField("InventoryUpdate", blank=True) credential = models.ManyToManyField("Credential", blank=True) + credential_type = models.ManyToManyField("CredentialType", blank=True) team = models.ManyToManyField("Team", blank=True) project = models.ManyToManyField("Project", blank=True) project_update = models.ManyToManyField("ProjectUpdate", blank=True) diff --git a/awx/main/tests/functional/models/test_activity_stream.py b/awx/main/tests/functional/models/test_activity_stream.py index b9c1611f05..44c19fc7d8 100644 --- a/awx/main/tests/functional/models/test_activity_stream.py +++ b/awx/main/tests/functional/models/test_activity_stream.py @@ -1,7 +1,15 @@ import pytest +import json + # AWX models -from awx.main.models import ActivityStream, Organization, JobTemplate +from awx.main.models import ( + ActivityStream, + Organization, + JobTemplate, + Credential, + CredentialType +) @@ -80,3 +88,46 @@ class TestRolesAssociationEntries: proj2.use_role.parents.add(proj1.admin_role) assert ActivityStream.objects.filter(role=proj1.admin_role, project=proj2).count() == 1 + + +@pytest.fixture +def somecloud_type(): + return CredentialType.objects.create( + kind='cloud', + name='SomeCloud', + managed_by_tower=False, + inputs={ + 'fields': [{ + 'id': 'api_token', + 'label': 'API Token', + 'type': 'string', + 'secret': True + }] + }, + injectors={ + 'env': { + 'MY_CLOUD_API_TOKEN': '{{api_token.foo()}}' + } + } + ) + + +@pytest.mark.django_db +class TestCredentialModels: + ''' + Assure that core elements of activity stream feature are working + ''' + + def test_create_credential_type(self, somecloud_type): + assert ActivityStream.objects.filter(credential_type=somecloud_type).count() == 1 + entry = ActivityStream.objects.filter(credential_type=somecloud_type)[0] + assert entry.operation == 'create' + + def test_credential_hidden_information(self, somecloud_type): + cred = Credential.objects.create( + credential_type=somecloud_type, + inputs = {'api_token': 'ABC123'} + ) + entry = ActivityStream.objects.filter(credential=cred)[0] + assert entry.operation == 'create' + assert json.loads(entry.changes)['inputs'] == 'hidden'