mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
Merge pull request #3257 from ryanpetrello/native_credential_types
define native CredentialType inputs/injectors in code, not in the DB Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
commit
1ece764547
@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.16 on 2019-02-19 04:27
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
from awx.main.models import CredentialType
|
||||
|
||||
|
||||
def migrate_to_static_inputs(apps, schema_editor):
|
||||
CredentialType.setup_tower_managed_defaults()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0060_v350_update_schedule_uniqueness_constraint'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='credentialtype',
|
||||
name='namespace',
|
||||
field=models.CharField(default=None, editable=False, max_length=1024, null=True),
|
||||
),
|
||||
migrations.RunPython(migrate_to_static_inputs)
|
||||
]
|
@ -62,155 +62,40 @@ def _disassociate_non_insights_projects(apps, cred):
|
||||
|
||||
|
||||
def migrate_to_v2_credentials(apps, schema_editor):
|
||||
CredentialType.setup_tower_managed_defaults()
|
||||
deprecated_cred = _generate_deprecated_cred_types()
|
||||
|
||||
# this monkey-patch is necessary to make the implicit role generation save
|
||||
# signal use the correct Role model (the version active at this point in
|
||||
# migration, not the one at HEAD)
|
||||
orig_current_apps = utils.get_current_apps
|
||||
try:
|
||||
utils.get_current_apps = lambda: apps
|
||||
for cred in apps.get_model('main', 'Credential').objects.all():
|
||||
job_templates = cred.jobtemplates.all()
|
||||
jobs = cred.jobs.all()
|
||||
data = {}
|
||||
if getattr(cred, 'vault_password', None):
|
||||
data['vault_password'] = cred.vault_password
|
||||
if _is_insights_scm(apps, cred):
|
||||
_disassociate_non_insights_projects(apps, cred)
|
||||
credential_type = _get_insights_credential_type()
|
||||
else:
|
||||
credential_type = _populate_deprecated_cred_types(deprecated_cred, cred.kind) or CredentialType.from_v1_kind(cred.kind, data)
|
||||
|
||||
defined_fields = credential_type.defined_fields
|
||||
cred.credential_type = apps.get_model('main', 'CredentialType').objects.get(pk=credential_type.pk)
|
||||
|
||||
for field in defined_fields:
|
||||
if getattr(cred, field, None):
|
||||
cred.inputs[field] = getattr(cred, field)
|
||||
if cred.vault_password:
|
||||
for jt in job_templates:
|
||||
jt.credential = None
|
||||
jt.vault_credential = cred
|
||||
jt.save()
|
||||
for job in jobs:
|
||||
job.credential = None
|
||||
job.vault_credential = cred
|
||||
job.save()
|
||||
if data.get('is_insights', False):
|
||||
cred.kind = 'insights'
|
||||
cred.save()
|
||||
|
||||
#
|
||||
# If the credential contains a vault password, create a new
|
||||
# *additional* credential for the ssh details
|
||||
#
|
||||
if cred.vault_password:
|
||||
# We need to make an ssh credential, too
|
||||
ssh_type = CredentialType.from_v1_kind('ssh')
|
||||
new_cred = apps.get_model('main', 'Credential').objects.get(pk=cred.pk)
|
||||
new_cred.pk = None
|
||||
new_cred.vault_password = ''
|
||||
new_cred.credential_type = apps.get_model('main', 'CredentialType').objects.get(pk=ssh_type.pk)
|
||||
if 'vault_password' in new_cred.inputs:
|
||||
del new_cred.inputs['vault_password']
|
||||
|
||||
# unset these attributes so that new roles are properly created
|
||||
# at save time
|
||||
new_cred.read_role = None
|
||||
new_cred.admin_role = None
|
||||
new_cred.use_role = None
|
||||
|
||||
if any([getattr(cred, field) for field in ssh_type.defined_fields]):
|
||||
new_cred.save(force_insert=True)
|
||||
|
||||
# copy rbac roles
|
||||
for role_type in ('read_role', 'admin_role', 'use_role'):
|
||||
for member in getattr(cred, role_type).members.all():
|
||||
getattr(new_cred, role_type).members.add(member)
|
||||
for role in getattr(cred, role_type).parents.all():
|
||||
getattr(new_cred, role_type).parents.add(role)
|
||||
|
||||
for jt in job_templates:
|
||||
jt.credential = new_cred
|
||||
jt.save()
|
||||
for job in jobs:
|
||||
job.credential = new_cred
|
||||
job.save()
|
||||
|
||||
# passwords must be decrypted and re-encrypted, because
|
||||
# their encryption is based on the Credential's primary key
|
||||
# (which has changed)
|
||||
for field in ssh_type.defined_fields:
|
||||
if field in ssh_type.secret_fields:
|
||||
value = decrypt_field(cred, field)
|
||||
if value:
|
||||
setattr(new_cred, field, value)
|
||||
new_cred.inputs[field] = encrypt_field(new_cred, field)
|
||||
setattr(new_cred, field, '')
|
||||
elif getattr(cred, field):
|
||||
new_cred.inputs[field] = getattr(cred, field)
|
||||
new_cred.save()
|
||||
finally:
|
||||
utils.get_current_apps = orig_current_apps
|
||||
# TODO: remove once legacy/EOL'd Towers no longer support this upgrade path
|
||||
pass
|
||||
|
||||
|
||||
def migrate_job_credentials(apps, schema_editor):
|
||||
# this monkey-patch is necessary to make the implicit role generation save
|
||||
# signal use the correct Role model (the version active at this point in
|
||||
# migration, not the one at HEAD)
|
||||
orig_current_apps = utils.get_current_apps
|
||||
try:
|
||||
utils.get_current_apps = lambda: apps
|
||||
for type_ in ('Job', 'JobTemplate'):
|
||||
for obj in apps.get_model('main', type_).objects.all():
|
||||
if obj.cloud_credential:
|
||||
obj.extra_credentials.add(obj.cloud_credential)
|
||||
if obj.network_credential:
|
||||
obj.extra_credentials.add(obj.network_credential)
|
||||
obj.save()
|
||||
finally:
|
||||
utils.get_current_apps = orig_current_apps
|
||||
# TODO: remove once legacy/EOL'd Towers no longer support this upgrade path
|
||||
pass
|
||||
|
||||
|
||||
def add_vault_id_field(apps, schema_editor):
|
||||
vault_credtype = CredentialType.objects.get(kind='vault')
|
||||
vault_credtype.inputs = CredentialType.defaults.get('vault')().inputs
|
||||
vault_credtype.save()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def remove_vault_id_field(apps, schema_editor):
|
||||
vault_credtype = CredentialType.objects.get(kind='vault')
|
||||
idx = 0
|
||||
for i, input in enumerate(vault_credtype.inputs['fields']):
|
||||
if input['id'] == 'vault_id':
|
||||
idx = i
|
||||
break
|
||||
vault_credtype.inputs['fields'].pop(idx)
|
||||
vault_credtype.save()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def create_rhv_tower_credtype(apps, schema_editor):
|
||||
CredentialType.setup_tower_managed_defaults()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def add_tower_verify_field(apps, schema_editor):
|
||||
tower_credtype = CredentialType.objects.get(
|
||||
kind='cloud', name='Ansible Tower', managed_by_tower=True
|
||||
)
|
||||
tower_credtype.inputs = CredentialType.defaults.get('tower')().inputs
|
||||
tower_credtype.save()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def add_azure_cloud_environment_field(apps, schema_editor):
|
||||
azure_rm_credtype = CredentialType.objects.get(kind='cloud',
|
||||
name='Microsoft Azure Resource Manager')
|
||||
azure_rm_credtype.inputs = CredentialType.defaults.get('azure_rm')().inputs
|
||||
azure_rm_credtype.save()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
||||
|
||||
def remove_become_methods(apps, schema_editor):
|
||||
become_credtype = CredentialType.objects.filter(kind='ssh', managed_by_tower=True).first()
|
||||
become_credtype.inputs = CredentialType.defaults.get('ssh')().inputs
|
||||
become_credtype.save()
|
||||
# this is no longer necessary; schemas are defined in code
|
||||
pass
|
||||
|
@ -16,7 +16,7 @@ from awx.main.models.organization import ( # noqa
|
||||
Organization, Profile, Team, UserSessionMembership
|
||||
)
|
||||
from awx.main.models.credential import ( # noqa
|
||||
Credential, CredentialType, V1Credential, build_safe_env
|
||||
Credential, CredentialType, ManagedCredentialType, V1Credential, build_safe_env
|
||||
)
|
||||
from awx.main.models.projects import Project, ProjectUpdate # noqa
|
||||
from awx.main.models.inventory import ( # noqa
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -47,7 +47,7 @@ __all__ = ['get_object_or_400', 'camelcase_to_underscore', 'memoize', 'memoize_d
|
||||
'wrap_args_with_proot', 'build_proot_temp_dir', 'check_proot_installed', 'model_to_dict',
|
||||
'model_instance_diff', 'timestamp_apiformat', 'parse_yaml_or_json', 'RequireDebugTrueOrTest',
|
||||
'has_model_field_prefetched', 'set_environ', 'IllegalArgumentError', 'get_custom_venv_choices', 'get_external_account',
|
||||
'task_manager_bulk_reschedule', 'schedule_task_manager']
|
||||
'task_manager_bulk_reschedule', 'schedule_task_manager', 'classproperty']
|
||||
|
||||
|
||||
def get_object_or_400(klass, *args, **kwargs):
|
||||
@ -1113,3 +1113,17 @@ def get_external_account(user):
|
||||
getattr(settings, 'TACACSPLUS_HOST', None)) and user.enterprise_auth.all():
|
||||
account_type = "enterprise"
|
||||
return account_type
|
||||
|
||||
|
||||
class classproperty:
|
||||
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
|
||||
self.fget = fget
|
||||
self.fset = fset
|
||||
self.fdel = fdel
|
||||
if doc is None and fget is not None:
|
||||
doc = fget.__doc__
|
||||
self.__doc__ = doc
|
||||
|
||||
def __get__(self, instance, ownerclass):
|
||||
return self.fget(ownerclass)
|
||||
|
Loading…
Reference in New Issue
Block a user