mirror of
https://github.com/ansible/awx.git
synced 2026-03-01 00:38:45 -03:30
migrate insights credentials
* A credential is considered an insights credential if a project of scm_type 'insights' is associated. * all non-insights Projects that point at an insights credential are nulled
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
from awx.main import utils
|
from awx.main import utils
|
||||||
from awx.main.models import CredentialType
|
from awx.main.models import CredentialType
|
||||||
from awx.main.utils.common import encrypt_field, decrypt_field
|
from awx.main.utils.common import encrypt_field, decrypt_field
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
DEPRECATED_CRED_KIND = {
|
DEPRECATED_CRED_KIND = {
|
||||||
@@ -48,6 +49,14 @@ def _populate_deprecated_cred_types(cred, kind):
|
|||||||
return cred[kind]
|
return cred[kind]
|
||||||
|
|
||||||
|
|
||||||
|
def _is_insights_scm(apps, cred):
|
||||||
|
return apps.get_model('main', 'Credential').objects.filter(id=cred.id, projects__scm_type='insights').exists()
|
||||||
|
|
||||||
|
|
||||||
|
def _disassociate_non_insights_projects(apps, cred):
|
||||||
|
apps.get_model('main', 'Project').objects.filter(~Q(scm_type='insights') & Q(credential=cred)).update(credential=None)
|
||||||
|
|
||||||
|
|
||||||
def migrate_to_v2_credentials(apps, schema_editor):
|
def migrate_to_v2_credentials(apps, schema_editor):
|
||||||
CredentialType.setup_tower_managed_defaults()
|
CredentialType.setup_tower_managed_defaults()
|
||||||
deprecated_cred = _generate_deprecated_cred_types()
|
deprecated_cred = _generate_deprecated_cred_types()
|
||||||
@@ -64,7 +73,11 @@ def migrate_to_v2_credentials(apps, schema_editor):
|
|||||||
data = {}
|
data = {}
|
||||||
if getattr(cred, 'vault_password', None):
|
if getattr(cred, 'vault_password', None):
|
||||||
data['vault_password'] = cred.vault_password
|
data['vault_password'] = cred.vault_password
|
||||||
|
if _is_insights_scm(apps, cred):
|
||||||
|
data['is_insights'] = True
|
||||||
|
_disassociate_non_insights_projects(apps, cred)
|
||||||
credential_type = _populate_deprecated_cred_types(deprecated_cred, cred.kind) or CredentialType.from_v1_kind(cred.kind, data)
|
credential_type = _populate_deprecated_cred_types(deprecated_cred, cred.kind) or CredentialType.from_v1_kind(cred.kind, data)
|
||||||
|
|
||||||
defined_fields = credential_type.defined_fields
|
defined_fields = credential_type.defined_fields
|
||||||
cred.credential_type = apps.get_model('main', 'CredentialType').objects.get(pk=credential_type.pk)
|
cred.credential_type = apps.get_model('main', 'CredentialType').objects.get(pk=credential_type.pk)
|
||||||
|
|
||||||
@@ -80,6 +93,8 @@ def migrate_to_v2_credentials(apps, schema_editor):
|
|||||||
job.credential = None
|
job.credential = None
|
||||||
job.vault_credential = cred
|
job.vault_credential = cred
|
||||||
job.save()
|
job.save()
|
||||||
|
if data.get('is_insights', False):
|
||||||
|
cred.kind = 'insights'
|
||||||
cred.save()
|
cred.save()
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -145,3 +160,4 @@ def migrate_job_credentials(apps, schema_editor):
|
|||||||
obj.save()
|
obj.save()
|
||||||
finally:
|
finally:
|
||||||
utils.get_current_apps = orig_current_apps
|
utils.get_current_apps = orig_current_apps
|
||||||
|
|
||||||
|
|||||||
@@ -469,6 +469,8 @@ class CredentialType(CommonModelNameNotUnique):
|
|||||||
requirements['kind'] = 'vault'
|
requirements['kind'] = 'vault'
|
||||||
else:
|
else:
|
||||||
requirements['kind'] = 'ssh'
|
requirements['kind'] = 'ssh'
|
||||||
|
elif kind == 'scm' and data.get('is_insights', False):
|
||||||
|
requirements['kind'] = 'insights'
|
||||||
elif kind in ('net', 'scm'):
|
elif kind in ('net', 'scm'):
|
||||||
requirements['kind'] = kind
|
requirements['kind'] = kind
|
||||||
elif kind in kind_choices:
|
elif kind in kind_choices:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from django.apps import apps
|
|||||||
from awx.main.models import Credential, CredentialType
|
from awx.main.models import Credential, CredentialType
|
||||||
from awx.main.migrations._credentialtypes import migrate_to_v2_credentials
|
from awx.main.migrations._credentialtypes import migrate_to_v2_credentials
|
||||||
from awx.main.utils.common import decrypt_field
|
from awx.main.utils.common import decrypt_field
|
||||||
|
from awx.main.migrations._credentialtypes import _disassociate_non_insights_projects
|
||||||
|
|
||||||
EXAMPLE_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxyz==\n-----END PRIVATE KEY-----'
|
EXAMPLE_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxyz==\n-----END PRIVATE KEY-----'
|
||||||
|
|
||||||
@@ -15,12 +16,12 @@ EXAMPLE_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxyz==\n-----END PRIVATE KEY-
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def migrate(credential, kind):
|
def migrate(credential, kind, is_insights=False):
|
||||||
with mock.patch.object(Credential, 'kind', kind), \
|
with mock.patch.object(Credential, 'kind', kind), \
|
||||||
mock.patch.object(Credential, 'objects', mock.Mock(
|
mock.patch.object(Credential, 'objects', mock.Mock(
|
||||||
get=lambda **kw: deepcopy(credential),
|
get=lambda **kw: deepcopy(credential),
|
||||||
all=lambda: [credential]
|
all=lambda: [credential],
|
||||||
)):
|
)), mock.patch('awx.main.migrations._credentialtypes._is_insights_scm', return_value=is_insights):
|
||||||
class Apps(apps.__class__):
|
class Apps(apps.__class__):
|
||||||
def get_model(self, app, model):
|
def get_model(self, app, model):
|
||||||
if model == 'Credential':
|
if model == 'Credential':
|
||||||
@@ -307,3 +308,40 @@ def test_azure_rm_migration():
|
|||||||
assert decrypt_field(cred, 'secret') == 'some-secret'
|
assert decrypt_field(cred, 'secret') == 'some-secret'
|
||||||
assert cred.inputs['tenant'] == 'some-tenant'
|
assert cred.inputs['tenant'] == 'some-tenant'
|
||||||
assert Credential.objects.count() == 1
|
assert Credential.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_insights_migration():
|
||||||
|
cred = Credential(name='My Credential')
|
||||||
|
|
||||||
|
with migrate(cred, 'scm', is_insights=True):
|
||||||
|
cred.__dict__.update({
|
||||||
|
'username': 'bob',
|
||||||
|
'password': 'some-password',
|
||||||
|
})
|
||||||
|
|
||||||
|
assert cred.credential_type.name == 'Insights Basic Auth'
|
||||||
|
assert cred.inputs['username'] == 'bob'
|
||||||
|
assert cred.inputs['password'].startswith('$encrypted$')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="Need some more mocking here or something.")
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_insights_project_migration():
|
||||||
|
cred1 = apps.get_model('main', 'Credential').objects.create(name='My Credential')
|
||||||
|
cred2 = apps.get_model('main', 'Credential').objects.create(name='My Credential')
|
||||||
|
projA1 = apps.get_model('main', 'Project').objects.create(name='Insights Project A1', scm_type='insights', credential=cred1)
|
||||||
|
|
||||||
|
projB1 = apps.get_model('main', 'Project').objects.create(name='Git Project B1', scm_type='git', credential=cred1)
|
||||||
|
projB2 = apps.get_model('main', 'Project').objects.create(name='Git Project B2', scm_type='git', credential=cred1)
|
||||||
|
|
||||||
|
projC1 = apps.get_model('main', 'Project').objects.create(name='Git Project C1', scm_type='git', credential=cred2)
|
||||||
|
|
||||||
|
_disassociate_non_insights_projects(apps, cred1)
|
||||||
|
_disassociate_non_insights_projects(apps, cred2)
|
||||||
|
|
||||||
|
assert apps.get_model('main', 'Project').objects.get(pk=projA1).credential is None
|
||||||
|
assert apps.get_model('main', 'Project').objects.get(pk=projB1).credential is None
|
||||||
|
assert apps.get_model('main', 'Project').objects.get(pk=projB2).credential is None
|
||||||
|
assert apps.get_model('main', 'Project').objects.get(pk=projC1).credential == cred2
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user