mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 02:50:02 -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:
parent
87eea59845
commit
7c0513d5ee
@ -1,6 +1,7 @@
|
||||
from awx.main import utils
|
||||
from awx.main.models import CredentialType
|
||||
from awx.main.utils.common import encrypt_field, decrypt_field
|
||||
from django.db.models import Q
|
||||
|
||||
|
||||
DEPRECATED_CRED_KIND = {
|
||||
@ -48,6 +49,14 @@ def _populate_deprecated_cred_types(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):
|
||||
CredentialType.setup_tower_managed_defaults()
|
||||
deprecated_cred = _generate_deprecated_cred_types()
|
||||
@ -64,7 +73,11 @@ def migrate_to_v2_credentials(apps, schema_editor):
|
||||
data = {}
|
||||
if getattr(cred, 'vault_password', None):
|
||||
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)
|
||||
|
||||
defined_fields = credential_type.defined_fields
|
||||
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.vault_credential = cred
|
||||
job.save()
|
||||
if data.get('is_insights', False):
|
||||
cred.kind = 'insights'
|
||||
cred.save()
|
||||
|
||||
#
|
||||
@ -145,3 +160,4 @@ def migrate_job_credentials(apps, schema_editor):
|
||||
obj.save()
|
||||
finally:
|
||||
utils.get_current_apps = orig_current_apps
|
||||
|
||||
|
||||
@ -469,6 +469,8 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
requirements['kind'] = 'vault'
|
||||
else:
|
||||
requirements['kind'] = 'ssh'
|
||||
elif kind == 'scm' and data.get('is_insights', False):
|
||||
requirements['kind'] = 'insights'
|
||||
elif kind in ('net', 'scm'):
|
||||
requirements['kind'] = kind
|
||||
elif kind in kind_choices:
|
||||
|
||||
@ -8,6 +8,7 @@ from django.apps import apps
|
||||
from awx.main.models import Credential, CredentialType
|
||||
from awx.main.migrations._credentialtypes import migrate_to_v2_credentials
|
||||
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-----'
|
||||
|
||||
@ -15,12 +16,12 @@ EXAMPLE_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxyz==\n-----END PRIVATE KEY-
|
||||
|
||||
|
||||
@contextmanager
|
||||
def migrate(credential, kind):
|
||||
def migrate(credential, kind, is_insights=False):
|
||||
with mock.patch.object(Credential, 'kind', kind), \
|
||||
mock.patch.object(Credential, 'objects', mock.Mock(
|
||||
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__):
|
||||
def get_model(self, app, model):
|
||||
if model == 'Credential':
|
||||
@ -307,3 +308,40 @@ def test_azure_rm_migration():
|
||||
assert decrypt_field(cred, 'secret') == 'some-secret'
|
||||
assert cred.inputs['tenant'] == 'some-tenant'
|
||||
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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user