From 06b04007a033aa6462cd1836e02e75a78c4f08d0 Mon Sep 17 00:00:00 2001 From: "Christian M. Adams" Date: Thu, 17 Jun 2021 12:54:06 -0400 Subject: [PATCH] Rename managed_by_tower to managed --- awx/api/serializers.py | 24 ++-- awx/api/views/__init__.py | 6 +- awx/main/access.py | 6 +- awx/main/analytics/collectors.py | 4 +- awx/main/fields.py | 4 +- .../commands/create_preload_data.py | 2 +- ...register_default_execution_environments.py | 4 +- .../0151_rename_managed_by_tower.py | 28 +++++ awx/main/migrations/_galaxy.py | 14 ++- awx/main/models/credential/__init__.py | 38 +++--- awx/main/models/execution_environments.py | 2 +- awx/main/models/inventory.py | 4 +- awx/main/models/organization.py | 2 +- .../functional/api/test_credential_type.py | 10 +- awx/main/tests/functional/conftest.py | 6 +- .../functional/models/test_activity_stream.py | 2 +- awx/main/tests/functional/test_credential.py | 8 +- .../test_galaxy_credential_migration.py | 117 ------------------ .../test_inventory_source_injectors.py | 4 +- .../test_inventory_source_migration.py | 2 +- awx/main/tests/unit/conftest.py | 2 +- awx/main/tests/unit/test_fields.py | 6 +- awx/main/tests/unit/test_tasks.py | 30 ++--- awx/main/utils/common.py | 2 +- awx/main/utils/execution_environments.py | 6 +- awx/settings/defaults.py | 2 +- awx/sso/tests/functional/test_pipeline.py | 2 +- .../CredentialAdd/CredentialAdd.test.jsx | 2 +- .../CredentialDetail/CredentialDetail.jsx | 4 +- .../CredentialEdit/CredentialEdit.test.jsx | 4 +- .../CredentialPluginPrompt.test.jsx | 2 +- .../shared/data.credentialTypes.json | 44 +++---- .../shared/data.credential_type.json | 2 +- .../shared/data.galaxyCredential.json | 2 +- .../shared/data.towerCredential.json | 2 +- .../CredentialTypeList/CredentialTypeList.jsx | 2 +- .../shared/CredentialTypeForm.test.jsx | 2 +- .../screens/CredentialType/shared/data.json | 2 +- .../ExecutionEnvironmentDetails.jsx | 4 +- .../ExecutionEnvironmentDetails.test.jsx | 10 +- .../ExecutionEnvironmentListItem.test.jsx | 6 +- .../shared/ExecutionEnvironmentForm.test.jsx | 4 +- .../OrganizationAdd/OrganizationAdd.jsx | 2 +- .../OrganizationAdd/OrganizationAdd.test.jsx | 2 +- .../OrganizationExecEnvList.test.jsx | 6 +- .../shared/OrganizationForm.test.jsx | 2 +- .../plugins/modules/credential_type.py | 2 +- awx_collection/test/awx/conftest.py | 2 +- awxkit/awxkit/api/pages/api.py | 4 +- awxkit/awxkit/api/pages/credentials.py | 6 +- .../api/pages/execution_environments.py | 2 +- awxkit/test/test_credentials.py | 4 +- docs/inventory/inventory_plugins.md | 2 +- 53 files changed, 190 insertions(+), 273 deletions(-) create mode 100644 awx/main/migrations/0151_rename_managed_by_tower.py delete mode 100644 awx/main/tests/functional/test_galaxy_credential_migration.py diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 55b3f299cb..a98e2271b6 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1409,11 +1409,11 @@ class ProjectOptionsSerializer(BaseSerializer): class ExecutionEnvironmentSerializer(BaseSerializer): show_capabilities = ['edit', 'delete', 'copy'] - managed_by_tower = serializers.ReadOnlyField() + managed = serializers.ReadOnlyField() class Meta: model = ExecutionEnvironment - fields = ('*', 'organization', 'image', 'managed_by_tower', 'credential', 'pull') + fields = ('*', 'organization', 'image', 'managed', 'credential', 'pull') def get_related(self, obj): res = super(ExecutionEnvironmentSerializer, self).get_related(obj) @@ -2481,14 +2481,14 @@ class ResourceAccessListElementSerializer(UserSerializer): class CredentialTypeSerializer(BaseSerializer): show_capabilities = ['edit', 'delete'] - managed_by_tower = serializers.ReadOnlyField() + managed = serializers.ReadOnlyField() class Meta: model = CredentialType - fields = ('*', 'kind', 'namespace', 'name', 'managed_by_tower', 'inputs', 'injectors') + fields = ('*', 'kind', 'namespace', 'name', 'managed', 'inputs', 'injectors') def validate(self, attrs): - if self.instance and self.instance.managed_by_tower: + if self.instance and self.instance.managed: raise PermissionDenied(detail=_("Modifications not allowed for managed credential types")) old_inputs = {} @@ -2520,8 +2520,8 @@ class CredentialTypeSerializer(BaseSerializer): def to_representation(self, data): value = super(CredentialTypeSerializer, self).to_representation(data) - # translate labels and help_text for credential fields "managed by Tower" - if value.get('managed_by_tower'): + # translate labels and help_text for credential fields "managed" + if value.get('managed'): value['name'] = _(value['name']) for field in value.get('inputs', {}).get('fields', []): field['label'] = _(field['label']) @@ -2540,11 +2540,11 @@ class CredentialTypeSerializer(BaseSerializer): class CredentialSerializer(BaseSerializer): show_capabilities = ['edit', 'delete', 'copy', 'use'] capabilities_prefetch = ['admin', 'use'] - managed_by_tower = serializers.ReadOnlyField() + managed = serializers.ReadOnlyField() class Meta: model = Credential - fields = ('*', 'organization', 'credential_type', 'managed_by_tower', 'inputs', 'kind', 'cloud', 'kubernetes') + fields = ('*', 'organization', 'credential_type', 'managed', 'inputs', 'kind', 'cloud', 'kubernetes') extra_kwargs = {'credential_type': {'label': _('Credential Type')}} def to_representation(self, data): @@ -2611,7 +2611,7 @@ class CredentialSerializer(BaseSerializer): return summary_dict def validate(self, attrs): - if self.instance and self.instance.managed_by_tower: + if self.instance and self.instance.managed: raise PermissionDenied(detail=_("Modifications not allowed for managed credentials")) return super(CredentialSerializer, self).validate(attrs) @@ -4189,7 +4189,7 @@ class JobLaunchSerializer(BaseSerializer): elif field_name == 'credentials': for cred in obj.credentials.all(): cred_dict = dict(id=cred.id, name=cred.name, credential_type=cred.credential_type.pk, passwords_needed=cred.passwords_needed) - if cred.credential_type.managed_by_tower and 'vault_id' in cred.credential_type.defined_fields: + if cred.credential_type.managed and 'vault_id' in cred.credential_type.defined_fields: cred_dict['vault_id'] = cred.get_input('vault_id', default=None) defaults_dict.setdefault(field_name, []).append(cred_dict) else: @@ -4988,7 +4988,7 @@ class ActivityStreamSerializer(BaseSerializer): ('notification', ('id', 'status', 'notification_type', 'notification_template_id')), ('o_auth2_access_token', ('id', 'user_id', 'description', 'application_id', 'scope')), ('o_auth2_application', ('id', 'name', 'description')), - ('credential_type', ('id', 'name', 'description', 'kind', 'managed_by_tower')), + ('credential_type', ('id', 'name', 'description', 'kind', 'managed')), ('ad_hoc_command', ('id', 'name', 'status', 'limit')), ('workflow_approval', ('id', 'name', 'unified_job_id')), ] diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index d753f9cb98..678fe8317b 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -708,7 +708,7 @@ class ExecutionEnvironmentDetail(RetrieveUpdateDestroyAPIView): def update(self, request, *args, **kwargs): instance = self.get_object() fields_to_check = ['name', 'description', 'organization', 'image', 'credential'] - if instance.managed_by_tower and request.user.can_access(models.ExecutionEnvironment, 'change', instance): + if instance.managed and request.user.can_access(models.ExecutionEnvironment, 'change', instance): for field in fields_to_check: left = getattr(instance, field, None) right = request.data.get(field, None) @@ -1306,7 +1306,7 @@ class CredentialTypeDetail(RetrieveUpdateDestroyAPIView): def destroy(self, request, *args, **kwargs): instance = self.get_object() - if instance.managed_by_tower: + if instance.managed: raise PermissionDenied(detail=_("Deletion not allowed for managed credential types")) if instance.credentials.exists(): raise PermissionDenied(detail=_("Credential types that are in use cannot be deleted")) @@ -1421,7 +1421,7 @@ class CredentialDetail(RetrieveUpdateDestroyAPIView): def destroy(self, request, *args, **kwargs): instance = self.get_object() - if instance.managed_by_tower: + if instance.managed: raise PermissionDenied(detail=_("Deletion not allowed for managed credentials")) return super(CredentialDetail, self).destroy(request, *args, **kwargs) diff --git a/awx/main/access.py b/awx/main/access.py index 4eb375ea75..c256aa63a3 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1119,7 +1119,7 @@ class CredentialTypeAccess(BaseAccess): I can create when: - I'm a superuser: I can change when: - - I'm a superuser and the type is not "managed by Tower" + - I'm a superuser and the type is not "managed" """ model = CredentialType @@ -1205,7 +1205,7 @@ class CredentialAccess(BaseAccess): def get_user_capabilities(self, obj, **kwargs): user_capabilities = super(CredentialAccess, self).get_user_capabilities(obj, **kwargs) user_capabilities['use'] = self.can_use(obj) - if getattr(obj, 'managed_by_tower', False) is True: + if getattr(obj, 'managed', False) is True: user_capabilities['edit'] = user_capabilities['delete'] = False return user_capabilities @@ -1368,7 +1368,7 @@ class ExecutionEnvironmentAccess(BaseAccess): return self.check_related('organization', Organization, data, obj=obj, mandatory=True, role_field='execution_environment_admin_role') def can_delete(self, obj): - if obj.managed_by_tower: + if obj.managed: raise PermissionDenied return self.can_change(obj, None) diff --git a/awx/main/analytics/collectors.py b/awx/main/analytics/collectors.py index b71cec45d6..c9186aaf0b 100644 --- a/awx/main/analytics/collectors.py +++ b/awx/main/analytics/collectors.py @@ -175,12 +175,12 @@ def org_counts(since, **kwargs): def cred_type_counts(since, **kwargs): counts = {} for cred_type in models.CredentialType.objects.annotate(num_credentials=Count('credentials', distinct=True)).values( - 'name', 'id', 'managed_by_tower', 'num_credentials' + 'name', 'id', 'managed', 'num_credentials' ): counts[cred_type['id']] = { 'name': cred_type['name'], 'credential_count': cred_type['num_credentials'], - 'managed_by_tower': cred_type['managed_by_tower'], + 'managed': cred_type['managed'], } return counts diff --git a/awx/main/fields.py b/awx/main/fields.py index 05fea8ca6a..95ebfbca73 100644 --- a/awx/main/fields.py +++ b/awx/main/fields.py @@ -642,7 +642,7 @@ class CredentialInputField(JSONSchemaField): # `ssh_key_unlock` requirements are very specific and can't be # represented without complicated JSON schema - if model_instance.credential_type.managed_by_tower is True and 'ssh_key_unlock' in defined_fields: + if model_instance.credential_type.managed is True and 'ssh_key_unlock' in defined_fields: # in order to properly test the necessity of `ssh_key_unlock`, we # need to know the real value of `ssh_key_data`; for a payload like: @@ -711,7 +711,7 @@ class CredentialTypeInputField(JSONSchemaField): } def validate(self, value, model_instance): - if isinstance(value, dict) and 'dependencies' in value and not model_instance.managed_by_tower: + if isinstance(value, dict) and 'dependencies' in value and not model_instance.managed: raise django_exceptions.ValidationError( _("'dependencies' is not supported for custom credentials."), code='invalid', diff --git a/awx/main/management/commands/create_preload_data.py b/awx/main/management/commands/create_preload_data.py index 41fa665abf..220781e0d4 100644 --- a/awx/main/management/commands/create_preload_data.py +++ b/awx/main/management/commands/create_preload_data.py @@ -44,7 +44,7 @@ class Command(BaseCommand): public_galaxy_credential = Credential( name='Ansible Galaxy', - managed_by_tower=True, + managed=True, credential_type=CredentialType.objects.get(kind='galaxy'), inputs={'url': 'https://galaxy.ansible.com/'}, ) diff --git a/awx/main/management/commands/register_default_execution_environments.py b/awx/main/management/commands/register_default_execution_environments.py index fdc9cca7ed..8686fe9a64 100644 --- a/awx/main/management/commands/register_default_execution_environments.py +++ b/awx/main/management/commands/register_default_execution_environments.py @@ -76,7 +76,7 @@ class Command(BaseCommand): } registry_cred, cred_created = Credential.objects.get_or_create( name="Default Execution Environment Registry Credential", - managed_by_tower=True, + managed=True, credential_type=registry_cred_type[0], defaults={'inputs': inputs}, ) @@ -114,7 +114,7 @@ class Command(BaseCommand): # Create the control plane execution environment that is used for project updates and system jobs ee = settings.CONTROL_PLANE_EXECUTION_ENVIRONMENT _this_ee, cp_created = ExecutionEnvironment.objects.get_or_create( - name="Control Plane Execution Environment", defaults={'image': ee, 'managed_by_tower': True, 'credential': registry_cred} + name="Control Plane Execution Environment", defaults={'image': ee, 'managed': True, 'credential': registry_cred} ) if cp_created: changed = True diff --git a/awx/main/migrations/0151_rename_managed_by_tower.py b/awx/main/migrations/0151_rename_managed_by_tower.py new file mode 100644 index 0000000000..2b993f0037 --- /dev/null +++ b/awx/main/migrations/0151_rename_managed_by_tower.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.16 on 2021-06-17 18:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0150_rename_inv_sources_inv_updates'), + ] + + operations = [ + migrations.RenameField( + model_name='credential', + old_name='managed_by_tower', + new_name='managed', + ), + migrations.RenameField( + model_name='credentialtype', + old_name='managed_by_tower', + new_name='managed', + ), + migrations.RenameField( + model_name='executionenvironment', + old_name='managed_by_tower', + new_name='managed', + ), + ] diff --git a/awx/main/migrations/_galaxy.py b/awx/main/migrations/_galaxy.py index 9e7684cdcf..1c0652e9a1 100644 --- a/awx/main/migrations/_galaxy.py +++ b/awx/main/migrations/_galaxy.py @@ -34,10 +34,16 @@ def migrate_galaxy_settings(apps, schema_editor): if public_galaxy_setting and public_galaxy_setting.value is False: # ...UNLESS this behavior was explicitly disabled via this setting public_galaxy_enabled = False - - public_galaxy_credential = Credential( - created=now(), modified=now(), name='Ansible Galaxy', managed_by_tower=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} - ) + try: + # Needed for old migrations + public_galaxy_credential = Credential( + created=now(), modified=now(), name='Ansible Galaxy', managed_by_tower=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} + ) + except: + # This will make functionaly tests pass + public_galaxy_credential = Credential( + created=now(), modified=now(), name='Ansible Galaxy', managed=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} + ) public_galaxy_credential.save() for org in Organization.objects.all(): diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index 82368e6bf3..e3a547a44a 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -92,7 +92,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin): on_delete=models.CASCADE, help_text=_('Specify the type of credential you want to create. Refer ' 'to the documentation for details on each type.'), ) - managed_by_tower = models.BooleanField(default=False, editable=False) + managed = models.BooleanField(default=False, editable=False) organization = models.ForeignKey( 'Organization', null=True, @@ -341,7 +341,7 @@ class CredentialType(CommonModelNameNotUnique): ) kind = models.CharField(max_length=32, choices=KIND_CHOICES) - managed_by_tower = models.BooleanField(default=False, editable=False) + managed = models.BooleanField(default=False, editable=False) namespace = models.CharField(max_length=1024, null=True, default=None, editable=False) inputs = CredentialTypeInputField( blank=True, default=dict, help_text=_('Enter inputs using either JSON or YAML syntax. ' 'Refer to the documentation for example syntax.') @@ -355,7 +355,7 @@ class CredentialType(CommonModelNameNotUnique): @classmethod def from_db(cls, db, field_names, values): instance = super(CredentialType, cls).from_db(db, field_names, values) - if instance.managed_by_tower and instance.namespace: + if instance.managed and instance.namespace: native = ManagedCredentialType.registry[instance.namespace] instance.inputs = native.inputs instance.injectors = native.injectors @@ -439,7 +439,7 @@ class CredentialType(CommonModelNameNotUnique): files) """ if not self.injectors: - if self.managed_by_tower and credential.credential_type.namespace in dir(builtin_injectors): + if self.managed and credential.credential_type.namespace in dir(builtin_injectors): injected_env = {} getattr(builtin_injectors, credential.credential_type.namespace)(credential, injected_env, private_data_dir) env.update(injected_env) @@ -561,7 +561,7 @@ class ManagedCredentialType(SimpleNamespace): namespace=self.namespace, kind=self.kind, name=self.name, - managed_by_tower=True, + managed=True, inputs=self.inputs, injectors=self.injectors, ) @@ -606,7 +606,7 @@ ManagedCredentialType( namespace='scm', kind='scm', name=ugettext_noop('Source Control'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'}, @@ -621,7 +621,7 @@ ManagedCredentialType( namespace='vault', kind='vault', name=ugettext_noop('Vault'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'vault_password', 'label': ugettext_noop('Vault Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True}, @@ -647,7 +647,7 @@ ManagedCredentialType( namespace='net', kind='net', name=ugettext_noop('Network'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'}, @@ -687,7 +687,7 @@ ManagedCredentialType( namespace='aws', kind='cloud', name=ugettext_noop('Amazon Web Services'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'label': ugettext_noop('Access Key'), 'type': 'string'}, @@ -718,7 +718,7 @@ ManagedCredentialType( namespace='openstack', kind='cloud', name=ugettext_noop('OpenStack'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'}, @@ -776,7 +776,7 @@ ManagedCredentialType( namespace='vmware', kind='cloud', name=ugettext_noop('VMware vCenter'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -801,7 +801,7 @@ ManagedCredentialType( namespace='satellite6', kind='cloud', name=ugettext_noop('Red Hat Satellite 6'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -826,7 +826,7 @@ ManagedCredentialType( namespace='gce', kind='cloud', name=ugettext_noop('Google Compute Engine'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -864,7 +864,7 @@ ManagedCredentialType( namespace='azure_rm', kind='cloud', name=ugettext_noop('Microsoft Azure Resource Manager'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -903,7 +903,7 @@ ManagedCredentialType( namespace='github_token', kind='token', name=ugettext_noop('GitHub Personal Access Token'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -922,7 +922,7 @@ ManagedCredentialType( namespace='gitlab_token', kind='token', name=ugettext_noop('GitLab Personal Access Token'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { @@ -941,7 +941,7 @@ ManagedCredentialType( namespace='insights', kind='insights', name=ugettext_noop('Insights'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'}, @@ -965,7 +965,7 @@ ManagedCredentialType( namespace='rhv', kind='cloud', name=ugettext_noop('Red Hat Virtualization'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'host', 'label': ugettext_noop('Host (Authentication URL)'), 'type': 'string', 'help_text': ugettext_noop('The host to authenticate with.')}, @@ -1009,7 +1009,7 @@ ManagedCredentialType( namespace='controller', kind='cloud', name=ugettext_noop('Red Hat Ansible Automation Platform'), - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { diff --git a/awx/main/models/execution_environments.py b/awx/main/models/execution_environments.py index 35af930bf2..b0b3dd7579 100644 --- a/awx/main/models/execution_environments.py +++ b/awx/main/models/execution_environments.py @@ -34,7 +34,7 @@ class ExecutionEnvironment(CommonModel): help_text=_("The full image location, including the container registry, image name, and version tag."), validators=[validate_container_image_name], ) - managed_by_tower = models.BooleanField(default=False, editable=False) + managed = models.BooleanField(default=False, editable=False) credential = models.ForeignKey( 'Credential', related_name='%(class)ss', diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index fc4c934685..25f454da2c 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -1368,7 +1368,7 @@ class PluginFileInjector(object): return env def _get_shared_env(self, inventory_update, private_data_dir, private_data_files): - """By default, we will apply the standard managed_by_tower injectors""" + """By default, we will apply the standard managed injectors""" injected_env = {} credential = inventory_update.get_cloud_credential() # some sources may have no credential, specifically ec2 @@ -1387,7 +1387,7 @@ class PluginFileInjector(object): args = [] credential.credential_type.inject_credential(credential, injected_env, safe_env, args, private_data_dir) # NOTE: safe_env is handled externally to injector class by build_safe_env static method - # that means that managed_by_tower injectors must only inject detectable env keys + # that means that managed injectors must only inject detectable env keys # enforcement of this is accomplished by tests return injected_env diff --git a/awx/main/models/organization.py b/awx/main/models/organization.py index f15ed9a859..9ec91cfb4b 100644 --- a/awx/main/models/organization.py +++ b/awx/main/models/organization.py @@ -117,7 +117,7 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi def create_default_galaxy_credential(self): from awx.main.models import Credential - public_galaxy_credential = Credential.objects.filter(managed_by_tower=True, name='Ansible Galaxy').first() + public_galaxy_credential = Credential.objects.filter(managed=True, name='Ansible Galaxy').first() if public_galaxy_credential not in self.galaxy_credentials.all(): self.galaxy_credentials.add(public_galaxy_credential) diff --git a/awx/main/tests/functional/api/test_credential_type.py b/awx/main/tests/functional/api/test_credential_type.py index bdc9630a97..ed0f1e9f28 100644 --- a/awx/main/tests/functional/api/test_credential_type.py +++ b/awx/main/tests/functional/api/test_credential_type.py @@ -75,7 +75,7 @@ def test_update_as_unauthorized_xfail(patch, delete): @pytest.mark.django_db -def test_update_managed_by_tower_xfail(patch, delete, admin): +def test_update_managed_xfail(patch, delete, admin): ssh = CredentialType.defaults['ssh']() ssh.save() url = reverse('api:credential_type_detail', kwargs={'pk': ssh.pk}) @@ -161,19 +161,19 @@ def test_create_as_admin(get, post, admin): assert response.data['results'][0]['name'] == 'Custom Credential Type' assert response.data['results'][0]['inputs'] == {} assert response.data['results'][0]['injectors'] == {} - assert response.data['results'][0]['managed_by_tower'] is False + assert response.data['results'][0]['managed'] is False @pytest.mark.django_db -def test_create_managed_by_tower_readonly(get, post, admin): +def test_create_managed_readonly(get, post, admin): response = post( - reverse('api:credential_type_list'), {'kind': 'cloud', 'name': 'Custom Credential Type', 'inputs': {}, 'injectors': {}, 'managed_by_tower': True}, admin + reverse('api:credential_type_list'), {'kind': 'cloud', 'name': 'Custom Credential Type', 'inputs': {}, 'injectors': {}, 'managed': True}, admin ) assert response.status_code == 201 response = get(reverse('api:credential_type_list'), admin) assert response.data['count'] == 1 - assert response.data['results'][0]['managed_by_tower'] is False + assert response.data['results'][0]['managed'] is False @pytest.mark.django_db diff --git a/awx/main/tests/functional/conftest.py b/awx/main/tests/functional/conftest.py index a37f34f919..b86edb90ec 100644 --- a/awx/main/tests/functional/conftest.py +++ b/awx/main/tests/functional/conftest.py @@ -266,7 +266,7 @@ def credentialtype_external(): with mock.patch('awx.main.models.credential.CredentialType.plugin', new_callable=PropertyMock) as mock_plugin: mock_plugin.return_value = MockPlugin() - external_type = CredentialType(kind='external', managed_by_tower=True, name='External Service', inputs=external_type_inputs) + external_type = CredentialType(kind='external', managed=True, name='External Service', inputs=external_type_inputs) external_type.save() yield external_type @@ -825,9 +825,9 @@ def slice_job_factory(slice_jt_factory): @pytest.fixture def control_plane_execution_environment(): - return ExecutionEnvironment.objects.create(name="Control Plane EE", managed_by_tower=True) + return ExecutionEnvironment.objects.create(name="Control Plane EE", managed=True) @pytest.fixture def default_job_execution_environment(): - return ExecutionEnvironment.objects.create(name="Default Job EE", managed_by_tower=False) + return ExecutionEnvironment.objects.create(name="Default Job EE", managed=False) diff --git a/awx/main/tests/functional/models/test_activity_stream.py b/awx/main/tests/functional/models/test_activity_stream.py index abc0b12c6b..bc6c3e8c51 100644 --- a/awx/main/tests/functional/models/test_activity_stream.py +++ b/awx/main/tests/functional/models/test_activity_stream.py @@ -121,7 +121,7 @@ def somecloud_type(): return CredentialType.objects.create( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string', 'secret': True}]}, injectors={'env': {'MY_CLOUD_API_TOKEN': '{{api_token.foo()}}'}}, ) diff --git a/awx/main/tests/functional/test_credential.py b/awx/main/tests/functional/test_credential.py index bea402e7c7..7639e42fc3 100644 --- a/awx/main/tests/functional/test_credential.py +++ b/awx/main/tests/functional/test_credential.py @@ -79,8 +79,8 @@ def test_default_cred_types(): 'aws', 'azure_kv', 'azure_rm', - 'centrify_vault_kv', 'conjur', + 'centrify_vault_kv', 'controller', 'galaxy_api_token', 'gce', @@ -103,14 +103,14 @@ def test_default_cred_types(): ] for type_ in CredentialType.defaults.values(): - assert type_().managed_by_tower is True + assert type_().managed is True @pytest.mark.django_db def test_credential_creation(organization_factory): org = organization_factory('test').organization type_ = CredentialType( - kind='cloud', name='SomeCloud', managed_by_tower=True, inputs={'fields': [{'id': 'username', 'label': 'Username for SomeCloud', 'type': 'string'}]} + kind='cloud', name='SomeCloud', managed=True, inputs={'fields': [{'id': 'username', 'label': 'Username for SomeCloud', 'type': 'string'}]} ) type_.save() @@ -287,7 +287,7 @@ def test_credential_get_input(organization_factory): type_ = CredentialType( kind='vault', name='somevault', - managed_by_tower=True, + managed=True, inputs={ 'fields': [ { diff --git a/awx/main/tests/functional/test_galaxy_credential_migration.py b/awx/main/tests/functional/test_galaxy_credential_migration.py deleted file mode 100644 index f825874ef0..0000000000 --- a/awx/main/tests/functional/test_galaxy_credential_migration.py +++ /dev/null @@ -1,117 +0,0 @@ -import importlib - -from django.conf import settings -from django.contrib.contenttypes.models import ContentType -import pytest - -from awx.main.models import Credential, Organization -from awx.conf.models import Setting -from awx.main.migrations import _galaxy as galaxy - - -class FakeApps(object): - def get_model(self, app, model): - if app == 'contenttypes': - return ContentType - return getattr(importlib.import_module(f'awx.{app}.models'), model) - - -apps = FakeApps() - - -@pytest.mark.django_db -def test_default_public_galaxy(): - org = Organization.objects.create() - assert org.galaxy_credentials.count() == 0 - galaxy.migrate_galaxy_settings(apps, None) - assert org.galaxy_credentials.count() == 1 - creds = org.galaxy_credentials.all() - assert creds[0].name == 'Ansible Galaxy' - assert creds[0].inputs['url'] == 'https://galaxy.ansible.com/' - - -@pytest.mark.django_db -def test_public_galaxy_disabled(): - Setting.objects.create(key='PUBLIC_GALAXY_ENABLED', value=False) - org = Organization.objects.create() - assert org.galaxy_credentials.count() == 0 - galaxy.migrate_galaxy_settings(apps, None) - assert org.galaxy_credentials.count() == 0 - - -@pytest.mark.django_db -def test_rh_automation_hub(): - Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://cloud.redhat.com/api/automation-hub/') - Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123') - org = Organization.objects.create() - assert org.galaxy_credentials.count() == 0 - galaxy.migrate_galaxy_settings(apps, None) - assert org.galaxy_credentials.count() == 2 - assert org.galaxy_credentials.first().name == 'Ansible Automation Hub (https://cloud.redhat.com/api/automation-hub/)' # noqa - - -@pytest.mark.django_db -def test_multiple_galaxies(): - for i in range(5): - Organization.objects.create(name=f'Org {i}') - - Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://example.org/') - Setting.objects.create(key='PRIMARY_GALAXY_AUTH_URL', value='https://auth.example.org/') - Setting.objects.create(key='PRIMARY_GALAXY_USERNAME', value='user') - Setting.objects.create(key='PRIMARY_GALAXY_PASSWORD', value='pass') - Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123') - - for org in Organization.objects.all(): - assert org.galaxy_credentials.count() == 0 - - galaxy.migrate_galaxy_settings(apps, None) - - for org in Organization.objects.all(): - assert org.galaxy_credentials.count() == 2 - creds = org.galaxy_credentials.all() - assert creds[0].name == 'Private Galaxy (https://example.org/)' - assert creds[0].inputs['url'] == 'https://example.org/' - assert creds[0].inputs['auth_url'] == 'https://auth.example.org/' - assert creds[0].inputs['token'].startswith('$encrypted$') - assert creds[0].get_input('token') == 'secret123' - - assert creds[1].name == 'Ansible Galaxy' - assert creds[1].inputs['url'] == 'https://galaxy.ansible.com/' - - public_galaxy_creds = Credential.objects.filter(name='Ansible Galaxy') - assert public_galaxy_creds.count() == 1 - assert public_galaxy_creds.first().managed_by_tower is True - - -@pytest.mark.django_db -def test_fallback_galaxies(): - org = Organization.objects.create() - assert org.galaxy_credentials.count() == 0 - Setting.objects.create(key='PRIMARY_GALAXY_URL', value='https://example.org/') - Setting.objects.create(key='PRIMARY_GALAXY_AUTH_URL', value='https://auth.example.org/') - Setting.objects.create(key='PRIMARY_GALAXY_TOKEN', value='secret123') - try: - settings.FALLBACK_GALAXY_SERVERS = [ - { - 'id': 'abc123', - 'url': 'https://some-other-galaxy.example.org/', - 'auth_url': 'https://some-other-galaxy.sso.example.org/', - 'username': 'user', - 'password': 'pass', - 'token': 'fallback123', - } - ] - galaxy.migrate_galaxy_settings(apps, None) - finally: - settings.FALLBACK_GALAXY_SERVERS = [] - assert org.galaxy_credentials.count() == 3 - creds = org.galaxy_credentials.all() - assert creds[0].name == 'Private Galaxy (https://example.org/)' - assert creds[0].inputs['url'] == 'https://example.org/' - assert creds[1].name == 'Ansible Galaxy (https://some-other-galaxy.example.org/)' - assert creds[1].inputs['url'] == 'https://some-other-galaxy.example.org/' - assert creds[1].inputs['auth_url'] == 'https://some-other-galaxy.sso.example.org/' - assert creds[1].inputs['token'].startswith('$encrypted$') - assert creds[1].get_input('token') == 'fallback123' - assert creds[2].name == 'Ansible Galaxy' - assert creds[2].inputs['url'] == 'https://galaxy.ansible.com/' diff --git a/awx/main/tests/functional/test_inventory_source_injectors.py b/awx/main/tests/functional/test_inventory_source_injectors.py index f2b9f2d3e1..aa84534c16 100644 --- a/awx/main/tests/functional/test_inventory_source_injectors.py +++ b/awx/main/tests/functional/test_inventory_source_injectors.py @@ -182,8 +182,8 @@ def create_reference_data(source_dir, env, content): @pytest.mark.django_db @pytest.mark.parametrize('this_kind', CLOUD_PROVIDERS) def test_inventory_update_injected_content(this_kind, inventory, fake_credential_factory): - ExecutionEnvironment.objects.create(name='Control Plane EE', managed_by_tower=True) - ExecutionEnvironment.objects.create(name='Default Job EE', managed_by_tower=False) + ExecutionEnvironment.objects.create(name='Control Plane EE', managed=True) + ExecutionEnvironment.objects.create(name='Default Job EE', managed=False) injector = InventorySource.injectors[this_kind] if injector.plugin_name is None: diff --git a/awx/main/tests/functional/test_inventory_source_migration.py b/awx/main/tests/functional/test_inventory_source_migration.py index b8858614e0..812b4b45b9 100644 --- a/awx/main/tests/functional/test_inventory_source_migration.py +++ b/awx/main/tests/functional/test_inventory_source_migration.py @@ -37,7 +37,7 @@ def test_cloudforms_inventory_removal(inventory): name='Red Hat CloudForms', namespace='cloudforms', kind='cloud', - managed_by_tower=True, + managed=True, inputs={}, ) CredentialType.defaults['cloudforms']().save() diff --git a/awx/main/tests/unit/conftest.py b/awx/main/tests/unit/conftest.py index 901308be70..65c3731bdd 100644 --- a/awx/main/tests/unit/conftest.py +++ b/awx/main/tests/unit/conftest.py @@ -12,7 +12,7 @@ from django.urls import URLResolver, URLPattern @pytest.fixture() def execution_environment(): - return ExecutionEnvironment(name="test-ee", description="test-ee", managed_by_tower=True) + return ExecutionEnvironment(name="test-ee", description="test-ee", managed=True) @pytest.fixture(autouse=True) diff --git a/awx/main/tests/unit/test_fields.py b/awx/main/tests/unit/test_fields.py index 56c6a3befc..8c00a95194 100644 --- a/awx/main/tests/unit/test_fields.py +++ b/awx/main/tests/unit/test_fields.py @@ -93,7 +93,7 @@ def test_custom_error_messages(schema, given, message): ], ) def test_cred_type_input_schema_validity(input_, valid): - type_ = CredentialType(kind='cloud', name='SomeCloud', managed_by_tower=True, inputs=input_) + type_ = CredentialType(kind='cloud', name='SomeCloud', managed=True, inputs=input_) field = CredentialType._meta.get_field('inputs') if valid is False: with pytest.raises(ValidationError): @@ -151,7 +151,7 @@ def test_cred_type_injectors_schema(injectors, valid): type_ = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=True, + managed=True, inputs={ 'fields': [ {'id': 'username', 'type': 'string', 'label': '_'}, @@ -190,7 +190,7 @@ def test_credential_creation_validation_failure(inputs): type_ = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=True, + managed=True, inputs={ 'fields': [{'id': 'username', 'label': 'Username for SomeCloud', 'type': 'string'}, {'id': 'flag', 'label': 'Some Boolean Flag', 'type': 'boolean'}] }, diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index cf0f95a437..15aeb86504 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -588,8 +588,8 @@ class TestGenericRun: @pytest.mark.django_db class TestAdhocRun(TestJobExecution): def test_options_jinja_usage(self, adhoc_job, adhoc_update_model_wrapper): - ExecutionEnvironment.objects.create(name='Control Plane EE', managed_by_tower=True) - ExecutionEnvironment.objects.create(name='Default Job EE', managed_by_tower=False) + ExecutionEnvironment.objects.create(name='Control Plane EE', managed=True) + ExecutionEnvironment.objects.create(name='Default Job EE', managed=False) adhoc_job.module_args = '{{ ansible_ssh_pass }}' adhoc_job.websocket_emit_status = mock.Mock() @@ -1095,7 +1095,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string'}]}, injectors={'env': {'MY_CLOUD_API_TOKEN': '{{api_token.foo()}}'}}, ) @@ -1108,7 +1108,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string'}]}, injectors={'env': {'MY_CLOUD_API_TOKEN': '{{api_token}}'}}, ) @@ -1123,7 +1123,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'turbo_button', 'label': 'Turbo Button', 'type': 'boolean'}]}, injectors={'env': {'TURBO_BUTTON': '{{turbo_button}}'}}, ) @@ -1140,7 +1140,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string'}]}, injectors={'env': {'JOB_ID': 'reserved'}}, ) @@ -1155,7 +1155,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'password', 'label': 'Password', 'type': 'string', 'secret': True}]}, injectors={'env': {'MY_CLOUD_PRIVATE_VAR': '{{password}}'}}, ) @@ -1175,7 +1175,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string'}]}, injectors={'extra_vars': {'api_token': '{{api_token}}'}}, ) @@ -1194,7 +1194,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'turbo_button', 'label': 'Turbo Button', 'type': 'boolean'}]}, injectors={'extra_vars': {'turbo_button': '{{turbo_button}}'}}, ) @@ -1213,7 +1213,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'turbo_button', 'label': 'Turbo Button', 'type': 'boolean'}]}, injectors={'extra_vars': {'turbo_button': '{% if turbo_button %}FAST!{% else %}SLOW!{% endif %}'}}, ) @@ -1234,7 +1234,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'password', 'label': 'Password', 'type': 'string', 'secret': True}]}, injectors={'extra_vars': {'password': '{{password}}'}}, ) @@ -1252,7 +1252,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'api_token', 'label': 'API Token', 'type': 'string'}]}, injectors={'file': {'template': '[mycloud]\n{{api_token}}'}, 'env': {'MY_CLOUD_INI_FILE': '{{tower.filename}}'}}, ) @@ -1269,7 +1269,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': []}, injectors={'file': {'template': value}, 'env': {'MY_CLOUD_INI_FILE': '{{tower.filename}}'}}, ) @@ -1288,7 +1288,7 @@ class TestJobCredentials(TestJobExecution): some_cloud = CredentialType( kind='cloud', name='SomeCloud', - managed_by_tower=False, + managed=False, inputs={'fields': [{'id': 'cert', 'label': 'Certificate', 'type': 'string'}, {'id': 'key', 'label': 'Key', 'type': 'string'}]}, injectors={ 'file': {'template.cert': '[mycert]\n{{cert}}', 'template.key': '[mykey]\n{{key}}'}, @@ -1921,7 +1921,7 @@ def test_aquire_lock_acquisition_fail_logged(fcntl_lockf, logging_getLogger, os_ def test_managed_injector_redaction(injector_cls): """See awx.main.models.inventory.PluginFileInjector._get_shared_env The ordering within awx.main.tasks.BaseTask and contract with build_env - requires that all managed_by_tower injectors are safely redacted by the + requires that all managed injectors are safely redacted by the static method build_safe_env without having to employ the safe namespace as in inject_credential diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index 2492b9a87a..6a962c6ce5 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -366,7 +366,7 @@ def get_allowed_fields(obj, serializer_mapping): fields_excluded = ACTIVITY_STREAM_FIELD_EXCLUSIONS.get(model_name, []) # see definition of from_db for CredentialType # injection logic of any managed types are incompatible with activity stream - if model_name == 'credentialtype' and obj.managed_by_tower and obj.namespace: + if model_name == 'credentialtype' and obj.managed and obj.namespace: fields_excluded.extend(['inputs', 'injectors']) if fields_excluded: allowed_fields = [f for f in allowed_fields if f not in fields_excluded] diff --git a/awx/main/utils/execution_environments.py b/awx/main/utils/execution_environments.py index c218c72802..11aa41edc8 100644 --- a/awx/main/utils/execution_environments.py +++ b/awx/main/utils/execution_environments.py @@ -7,18 +7,18 @@ from awx.main.models.execution_environments import ExecutionEnvironment def get_control_plane_execution_environment(): - return ExecutionEnvironment.objects.filter(organization=None, managed_by_tower=True).first() + return ExecutionEnvironment.objects.filter(organization=None, managed=True).first() def get_default_execution_environment(): if settings.DEFAULT_EXECUTION_ENVIRONMENT is not None: return settings.DEFAULT_EXECUTION_ENVIRONMENT installed_default = ExecutionEnvironment.objects.filter( - image__in=[ee['image'] for ee in settings.GLOBAL_JOB_EXECUTION_ENVIRONMENTS], organization=None, managed_by_tower=False + image__in=[ee['image'] for ee in settings.GLOBAL_JOB_EXECUTION_ENVIRONMENTS], organization=None, managed=False ).first() if installed_default: return installed_default - return ExecutionEnvironment.objects.filter(organization=None, managed_by_tower=False).first() + return ExecutionEnvironment.objects.filter(organization=None, managed=False).first() def get_default_pod_spec(): diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 58b1ea5fb7..b3e4675a0f 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -185,7 +185,7 @@ DEFAULT_EXECUTION_ENVIRONMENT = None GLOBAL_JOB_EXECUTION_ENVIRONMENTS = [{'name': 'AWX EE 0.3.0', 'image': 'quay.io/ansible/awx-ee:0.3.0'}] # This setting controls which EE will be used for project updates. # The awx-manage register_default_execution_environments command reads this setting and registers the EE -# This image is distinguished from others by having "managed_by_tower" set to True and users have limited +# This image is distinguished from others by having "managed" set to True and users have limited # ability to modify it through the API. # If a registry credential is needed to pull the image, that can be provided to the awx-manage command CONTROL_PLANE_EXECUTION_ENVIRONMENT = 'quay.io/ansible/awx-ee:0.3.0' diff --git a/awx/sso/tests/functional/test_pipeline.py b/awx/sso/tests/functional/test_pipeline.py index 36247c4b11..5a4307a0fa 100644 --- a/awx/sso/tests/functional/test_pipeline.py +++ b/awx/sso/tests/functional/test_pipeline.py @@ -13,7 +13,7 @@ from awx.main.models import User, Team, Organization, Credential, CredentialType def galaxy_credential(): galaxy_type = CredentialType.objects.create(kind='galaxy') cred = Credential( - created=now(), modified=now(), name='Ansible Galaxy', managed_by_tower=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} + created=now(), modified=now(), name='Ansible Galaxy', managed=True, credential_type=galaxy_type, inputs={'url': 'https://galaxy.ansible.com/'} ) cred.save() diff --git a/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx b/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx index 486a7dc3b3..5318a3b7cf 100644 --- a/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialAdd/CredentialAdd.test.jsx @@ -38,7 +38,7 @@ const mockCredentialResults = { description: '', kind: 'ssh', namespace: 'ssh', - managed_by_tower: true, + managed: true, inputs: { fields: [ { diff --git a/awx/ui_next/src/screens/Credential/CredentialDetail/CredentialDetail.jsx b/awx/ui_next/src/screens/Credential/CredentialDetail/CredentialDetail.jsx index 0d32e6ec44..9126f339da 100644 --- a/awx/ui_next/src/screens/Credential/CredentialDetail/CredentialDetail.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialDetail/CredentialDetail.jsx @@ -63,7 +63,7 @@ function CredentialDetail({ credential }) { useCallback(async () => { const [ { - data: { inputs: credentialTypeInputs, managed_by_tower }, + data: { inputs: credentialTypeInputs, managed }, }, { data: { results: loadedInputSources }, @@ -74,7 +74,7 @@ function CredentialDetail({ credential }) { ]); return { fields: credentialTypeInputs.fields || [], - managedByTower: managed_by_tower, + managedByTower: managed, inputSources: loadedInputSources.reduce( (inputSourcesMap, inputSource) => { inputSourcesMap[inputSource.input_field_name] = inputSource; diff --git a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx index 65a68710d4..f8acddee12 100644 --- a/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx +++ b/awx/ui_next/src/screens/Credential/CredentialEdit/CredentialEdit.test.jsx @@ -158,7 +158,7 @@ const mockCredentialResults = { description: '', kind: 'ssh', namespace: 'ssh', - managed_by_tower: true, + managed: true, inputs: { fields: [ { @@ -238,7 +238,7 @@ const mockCredentialResults = { description: '', kind: 'cloud', namespace: 'gce', - managed_by_tower: true, + managed: true, inputs: { fields: [ { diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx index 9b36b8f076..bf4804d11c 100644 --- a/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx +++ b/awx/ui_next/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.test.jsx @@ -47,7 +47,7 @@ const mockCredentialTypeDetail = { description: '', kind: 'external', namespace: 'conjur', - managed_by_tower: true, + managed: true, inputs: { fields: [ { id: 'url', label: 'Conjur URL', type: 'string', format: 'url' }, diff --git a/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json b/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json index 7e38183330..e30cc08888 100644 --- a/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json +++ b/awx/ui_next/src/screens/Credential/shared/data.credentialTypes.json @@ -19,7 +19,7 @@ "description": "", "kind": "cloud", "namespace": "aws", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -65,7 +65,7 @@ "description": "", "kind": "cloud", "namespace": "tower", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -130,7 +130,7 @@ "description": "", "kind": "cloud", "namespace": "gce", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -179,7 +179,7 @@ "description": "", "kind": "cloud", "namespace": "azure_rm", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -246,7 +246,7 @@ "description": "", "kind": "cloud", "namespace": "openstack", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -318,7 +318,7 @@ "description": "", "kind": "cloud", "namespace": "satellite6", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -363,7 +363,7 @@ "description": "", "kind": "cloud", "namespace": "rhv", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -424,7 +424,7 @@ "description": "", "kind": "cloud", "namespace": "vmware", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -469,7 +469,7 @@ "description": "", "kind": "external", "namespace": "aim", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -550,7 +550,7 @@ "description": "", "kind": "external", "namespace": "conjur", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -620,7 +620,7 @@ "description": "", "kind": "external", "namespace": "hashivault_kv", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -723,7 +723,7 @@ "description": "", "kind": "external", "namespace": "hashivault_ssh", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -819,7 +819,7 @@ "description": "", "kind": "external", "namespace": "azure_kv", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -895,7 +895,7 @@ "description": "", "kind": "insights", "namespace": "insights", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -939,7 +939,7 @@ "description": "", "kind": "kubernetes", "namespace": "kubernetes_bearer_token", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -992,7 +992,7 @@ "description": "", "kind": "net", "namespace": "net", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1059,7 +1059,7 @@ "description": "", "kind": "scm", "namespace": "scm", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1111,7 +1111,7 @@ "description": "", "kind": "ssh", "namespace": "ssh", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1190,7 +1190,7 @@ "description": "", "kind": "token", "namespace": "github_token", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1225,7 +1225,7 @@ "description": "", "kind": "token", "namespace": "gitlab_token", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1260,7 +1260,7 @@ "description": "", "kind": "vault", "namespace": "vault", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { @@ -1302,7 +1302,7 @@ "description": "", "kind": "galaxy", "namespace": "galaxy_api_token", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { diff --git a/awx/ui_next/src/screens/Credential/shared/data.credential_type.json b/awx/ui_next/src/screens/Credential/shared/data.credential_type.json index 93adfcdf38..de6d0ac9cc 100644 --- a/awx/ui_next/src/screens/Credential/shared/data.credential_type.json +++ b/awx/ui_next/src/screens/Credential/shared/data.credential_type.json @@ -19,7 +19,7 @@ "description": "", "kind": "ssh", "namespace": "ssh", - "managed_by_tower": true, + "managed": true, "inputs": { "fields": [ { diff --git a/awx/ui_next/src/screens/Credential/shared/data.galaxyCredential.json b/awx/ui_next/src/screens/Credential/shared/data.galaxyCredential.json index a8c7184548..09c2d0c59a 100644 --- a/awx/ui_next/src/screens/Credential/shared/data.galaxyCredential.json +++ b/awx/ui_next/src/screens/Credential/shared/data.galaxyCredential.json @@ -78,7 +78,7 @@ "description": "Bar", "organization": 1, "credential_type": 42, - "managed_by_tower": false, + "managed": false, "inputs": { "url": "https://localhost.com", "auth_url": "" diff --git a/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json b/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json index bfa544a5ed..5291682800 100644 --- a/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json +++ b/awx/ui_next/src/screens/Credential/shared/data.towerCredential.json @@ -73,7 +73,7 @@ "description": "", "organization": null, "credential_type": 16, - "managed_by_tower": false, + "managed": false, "inputs": { "host": "https://localhost", "username": "", diff --git a/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx b/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx index ed0242e158..fb79fed0ed 100644 --- a/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx +++ b/awx/ui_next/src/screens/CredentialType/CredentialTypeList/CredentialTypeList.jsx @@ -23,7 +23,7 @@ import CredentialTypeListItem from './CredentialTypeListItem'; const QS_CONFIG = getQSConfig('credential-type', { page: 1, page_size: 20, - managed_by_tower: false, + managed: false, }); function CredentialTypeList() { diff --git a/awx/ui_next/src/screens/CredentialType/shared/CredentialTypeForm.test.jsx b/awx/ui_next/src/screens/CredentialType/shared/CredentialTypeForm.test.jsx index be9b6d5353..4adb2f6919 100644 --- a/awx/ui_next/src/screens/CredentialType/shared/CredentialTypeForm.test.jsx +++ b/awx/ui_next/src/screens/CredentialType/shared/CredentialTypeForm.test.jsx @@ -34,7 +34,7 @@ const credentialType = { description: 'Jenkins Credential', kind: 'cloud', namespace: null, - managed_by_tower: false, + managed: false, inputs: JSON.stringify({ fields: [ { diff --git a/awx/ui_next/src/screens/CredentialType/shared/data.json b/awx/ui_next/src/screens/CredentialType/shared/data.json index 7fa00723ae..54f5c78e6c 100644 --- a/awx/ui_next/src/screens/CredentialType/shared/data.json +++ b/awx/ui_next/src/screens/CredentialType/shared/data.json @@ -33,7 +33,7 @@ "description": "Jenkins Credential", "kind": "cloud", "namespace": null, - "managed_by_tower": false, + "managed": false, "inputs": { "fields": [ { diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.jsx index 56792f56a7..5351fcead3 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.jsx @@ -27,7 +27,7 @@ function ExecutionEnvironmentDetails({ executionEnvironment }) { pull, organization, summary_fields, - managed_by_tower: managedByTower, + managed: managedByTower, } = executionEnvironment; const { @@ -64,7 +64,7 @@ function ExecutionEnvironmentDetails({ executionEnvironment }) { dataCy="execution-environment-detail-description" /> diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.test.jsx index 911da49f9f..049d5d64e5 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentDetails/ExecutionEnvironmentDetails.test.jsx @@ -53,7 +53,7 @@ const executionEnvironment = { description: 'Foo', organization: null, image: 'https://localhost:90/12345/ma', - managed_by_tower: false, + managed: false, credential: 4, }; @@ -82,7 +82,7 @@ describe('', () => { wrapper.find('Detail[label="Credential"]').prop('value').props.children ).toEqual(executionEnvironment.summary_fields.credential.name); expect( - wrapper.find('Detail[label="Managed by Tower"]').prop('value') + wrapper.find('Detail[label="Managed"]').prop('value') ).toEqual('False'); const dates = wrapper.find('UserDateDetail'); expect(dates).toHaveLength(2); @@ -153,13 +153,13 @@ describe('', () => { expect(history.location.pathname).toBe('/execution_environments'); }); - test('should render action buttons to ee managed by tower', async () => { + test('should render action buttons to managed ee', async () => { await act(async () => { wrapper = mountWithContexts( ); @@ -179,7 +179,7 @@ describe('', () => { wrapper.find('Detail[label="Credential"]').prop('value').props.children ).toEqual(executionEnvironment.summary_fields.credential.name); expect( - wrapper.find('Detail[label="Managed by Tower"]').prop('value') + wrapper.find('Detail[label="Managed"]').prop('value') ).toEqual('True'); const dates = wrapper.find('UserDateDetail'); expect(dates).toHaveLength(2); diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx index 0df9bfcf31..35a34ded7e 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx @@ -23,7 +23,7 @@ describe('', () => { summary_fields: { user_capabilities: { edit: true, copy: true, delete: true }, }, - managed_by_tower: false, + managed: false, }; test('should mount successfully', async () => { @@ -146,7 +146,7 @@ describe('', () => { expect(wrapper.find('CopyButton').length).toBe(0); }); - test('should not render the pencil action for ee managed by tower', async () => { + test('should not render the pencil action for managed ee', async () => { await act(async () => { wrapper = mountWithContexts( @@ -155,7 +155,7 @@ describe('', () => { executionEnvironment={{ ...executionEnvironment, summary_fields: { user_capabilities: { edit: false } }, - managed_by_tower: true, + managed: true, }} detailUrl="execution_environments/1/details" isSelected={false} diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx index fb60d238f8..57e9364f11 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.test.jsx @@ -50,7 +50,7 @@ const executionEnvironment = { description: 'A simple EE', organization: 1, image: 'https://registry.com/image/container', - managed_by_tower: false, + managed: false, credential: 4, }; @@ -84,7 +84,7 @@ const globallyAvailableEE = { description: 'A simple EE', organization: null, image: 'https://registry.com/image/container', - managed_by_tower: false, + managed: false, credential: 4, }; diff --git a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.jsx b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.jsx index 1d811fb425..6b821ac875 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.jsx @@ -23,7 +23,7 @@ function OrganizationAdd() { data: { results }, } = await CredentialsAPI.read({ credential_type__kind: 'galaxy', - managed_by_tower: true, + managed: true, }); return results[0] || null; diff --git a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx index c88fef90bc..5fced4aa9d 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationAdd/OrganizationAdd.test.jsx @@ -20,7 +20,7 @@ describe('', () => { type: 'credential', name: 'Ansible Galaxy', credential_type: 18, - managed_by_tower: true, + managed: true, kind: 'galaxy_api_token', }, ], diff --git a/awx/ui_next/src/screens/Organization/OrganizationExecEnvList/OrganizationExecEnvList.test.jsx b/awx/ui_next/src/screens/Organization/OrganizationExecEnvList/OrganizationExecEnvList.test.jsx index 07e8a53ea5..deb4b88aa5 100644 --- a/awx/ui_next/src/screens/Organization/OrganizationExecEnvList/OrganizationExecEnvList.test.jsx +++ b/awx/ui_next/src/screens/Organization/OrganizationExecEnvList/OrganizationExecEnvList.test.jsx @@ -24,7 +24,7 @@ const executionEnvironments = { }, organization: 1, image: 'https://localhost.com/image/disk', - managed_by_tower: false, + managed: false, credential: null, }, { @@ -36,7 +36,7 @@ const executionEnvironments = { }, organization: 1, image: 'test/image123', - managed_by_tower: false, + managed: false, credential: null, }, { @@ -48,7 +48,7 @@ const executionEnvironments = { }, organization: 1, image: 'test/test', - managed_by_tower: false, + managed: false, credential: null, }, ], diff --git a/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx b/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx index 2399bb6f90..38d8b5d578 100644 --- a/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx +++ b/awx/ui_next/src/screens/Organization/shared/OrganizationForm.test.jsx @@ -60,7 +60,7 @@ describe('', () => { type: 'credential', name: 'Ansible Galaxy', credential_type: 18, - managed_by_tower: true, + managed: true, kind: 'galaxy_api_token', }} />, diff --git a/awx_collection/plugins/modules/credential_type.py b/awx_collection/plugins/modules/credential_type.py index 2174f5432f..35b4cd6b44 100644 --- a/awx_collection/plugins/modules/credential_type.py +++ b/awx_collection/plugins/modules/credential_type.py @@ -107,7 +107,7 @@ def main(): # These will be passed into the create/updates credential_type_params = { - 'managed_by_tower': False, + 'managed': False, } if kind: credential_type_params['kind'] = kind diff --git a/awx_collection/test/awx/conftest.py b/awx_collection/test/awx/conftest.py index 728df5e15c..9c620e6520 100644 --- a/awx_collection/test/awx/conftest.py +++ b/awx_collection/test/awx/conftest.py @@ -265,7 +265,7 @@ def silence_warning(): @pytest.fixture def execution_environment(): - return ExecutionEnvironment.objects.create(name="test-ee", description="test-ee", managed_by_tower=False) + return ExecutionEnvironment.objects.create(name="test-ee", description="test-ee", managed=False) @pytest.fixture(scope='session', autouse=True) diff --git a/awxkit/awxkit/api/pages/api.py b/awxkit/awxkit/api/pages/api.py index b802432200..1feadf444d 100644 --- a/awxkit/awxkit/api/pages/api.py +++ b/awxkit/awxkit/api/pages/api.py @@ -82,8 +82,8 @@ class ApiV2(base.Base): def _export(self, _page, post_fields): # Drop any (credential_type) assets that are being managed by the instance. - if _page.json.get('managed_by_tower'): - log.debug("%s is managed by Tower, skipping.", _page.endpoint) + if _page.json.get('managed'): + log.debug("%s is managed, skipping.", _page.endpoint) return None if post_fields is None: # Deprecated endpoint or insufficient permissions log.error("Object export failed: %s", _page.endpoint) diff --git a/awxkit/awxkit/api/pages/credentials.py b/awxkit/awxkit/api/pages/credentials.py index 8b3647c04d..cd5861cc3e 100644 --- a/awxkit/awxkit/api/pages/credentials.py +++ b/awxkit/awxkit/api/pages/credentials.py @@ -102,7 +102,7 @@ config_kind_to_credential_type_name_map = {kind: name for name, kind in credenti def kind_and_config_cred_from_credential_type(credential_type): kind = '' - if not credential_type.managed_by_tower: + if not credential_type.managed: return kind, PseudoNamespace() try: if credential_type.kind == 'net': @@ -144,7 +144,7 @@ class CredentialType(HasCreate, base.Base): NATURAL_KEY = ('name', 'kind') def silent_delete(self): - if not self.managed_by_tower: + if not self.managed: return super(CredentialType, self).silent_delete() def payload(self, kind='cloud', **kwargs): @@ -245,7 +245,7 @@ class Credential(HasCopy, HasCreate, base.Base): inputs = config.credentials.cloud['openstack'] else: credential_type_name = config_kind_to_credential_type_name_map[kind] - credential_type = CredentialTypes(self.connection).get(managed_by_tower=True, name__icontains=credential_type_name).results.pop() + credential_type = CredentialTypes(self.connection).get(managed=True, name__icontains=credential_type_name).results.pop() credential_type, organization, user, team = filter_by_class((credential_type, CredentialType), (organization, Organization), (user, User), (team, Team)) if not any((user, team, organization)): diff --git a/awxkit/awxkit/api/pages/execution_environments.py b/awxkit/awxkit/api/pages/execution_environments.py index 3f6641fba3..f761fb6fdd 100644 --- a/awxkit/awxkit/api/pages/execution_environments.py +++ b/awxkit/awxkit/api/pages/execution_environments.py @@ -20,7 +20,7 @@ class ExecutionEnvironment(HasCreate, HasCopy, base.Base): dependencies = [Organization, Credential] NATURAL_KEY = ('name',) - # fields are name, image, organization, managed_by_tower, credential + # fields are name, image, organization, managed, credential def create(self, name='', image='quay.io/ansible/ansible-runner:devel', organization=Organization, credential=None, pull='', **kwargs): # we do not want to make a credential by default payload = self.create_payload(name=name, image=image, organization=organization, credential=credential, pull=pull, **kwargs) diff --git a/awxkit/test/test_credentials.py b/awxkit/test/test_credentials.py index 6adc5e9332..f2eff6a505 100644 --- a/awxkit/test/test_credentials.py +++ b/awxkit/test/test_credentials.py @@ -16,10 +16,10 @@ def set_config_cred_to_desired(config, location): class MockCredentialType(object): - def __init__(self, name, kind, managed_by_tower=True): + def __init__(self, name, kind, managed=True): self.name = name self.kind = kind - self.managed_by_tower = managed_by_tower + self.managed = managed @pytest.mark.parametrize( diff --git a/docs/inventory/inventory_plugins.md b/docs/inventory/inventory_plugins.md index 9241765ab7..8bf738bb42 100644 --- a/docs/inventory/inventory_plugins.md +++ b/docs/inventory/inventory_plugins.md @@ -14,6 +14,6 @@ The CLI entry point `ansible-inventory` was introduced in Ansible 2.4. Inventory ## Writing Your Own Inventory File -You can add an SCM inventory source that points to your own yaml file which specifies an inventory plugin. You can also apply a credential of a `managed_by_tower` type to that inventory source that matches the credential you are using. For example, you could have an inventory file for the `amazon.aws.aws_ec2` plugin and use the build-in `aws` credential type. +You can add an SCM inventory source that points to your own yaml file which specifies an inventory plugin. You can also apply a credential of a `managed` type to that inventory source that matches the credential you are using. For example, you could have an inventory file for the `amazon.aws.aws_ec2` plugin and use the build-in `aws` credential type. All built-in sources provide _secrets_ via environment variables. These can be re-used for SCM-based inventory, and your inventory file can be used to specify non-sensitive configuration details such as the `keyed_groups` (to provide) or `hostvars` (to construct).