Ejemplo n.º 1
0
def test_ssh_unlock_with_prior_value(put, organization, admin,
                                     credentialtype_ssh):
    params = {
        'name': 'Best credential ever',
        'credential_type': 1,
        'inputs': {
            'username': '******',
            'ssh_key_data': '$encrypted$',
            'ssh_key_unlock': 'new-unlock',
        },
    }
    cred = Credential(
        credential_type=credentialtype_ssh,
        name='Best credential ever',
        organization=organization,
        inputs={
            'username': u'joe',
            'ssh_key_data': EXAMPLE_ENCRYPTED_PRIVATE_KEY,
            'ssh_key_unlock': 'old-unlock'
        },
    )
    cred.save()

    params['organization'] = organization.id
    response = put(reverse('api:credential_detail', kwargs={'pk': cred.pk}),
                   params, admin)
    assert response.status_code == 200

    cred = Credential.objects.all()[:1].get()
    assert decrypt_field(cred, 'ssh_key_unlock') == 'new-unlock'
Ejemplo n.º 2
0
def test_credential_creation_validation_failure(organization_factory, inputs):
    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'
                               }, {
                                   'id': 'flag',
                                   'label': 'Some Boolean Flag',
                                   'type': 'boolean'
                               }]
                           })
    type_.save()

    with pytest.raises(Exception) as e:
        cred = Credential(credential_type=type_,
                          name="Bob's Credential",
                          inputs=inputs,
                          organization=org)
        cred.save()
        cred.full_clean()
        assert e.type in (ValidationError, serializers.ValidationError)
Ejemplo n.º 3
0
def test_ssh_unlock_not_needed(put, organization, admin, credentialtype_ssh):
    params = {
        'name': 'Best credential ever',
        'credential_type': 1,
        'inputs': {
            'username': '******',
            'ssh_key_data': '$encrypted$',
            'ssh_key_unlock': 'superfluous-key-unlock',
        },
    }
    cred = Credential(
        credential_type=credentialtype_ssh,
        name='Best credential ever',
        organization=organization,
        inputs={
            'username': u'joe',
            'ssh_key_data': EXAMPLE_PRIVATE_KEY,
        },
    )
    cred.save()

    params['organization'] = organization.id
    response = put(reverse('api:credential_detail', kwargs={'pk': cred.pk}),
                   params, admin)
    assert response.status_code == 400
    assert response.data['inputs']['ssh_key_unlock'] == [
        'should not be set when SSH key is not encrypted.'
    ]
Ejemplo n.º 4
0
def test_ssh_bad_key_unlock_not_checked(put, organization, admin,
                                        credentialtype_ssh):
    params = {
        'name': 'Best credential ever',
        'credential_type': 1,
        'inputs': {
            'username': '******',
            'ssh_key_data': 'invalid-key',
            'ssh_key_unlock': 'unchecked-unlock',
        },
    }
    cred = Credential(
        credential_type=credentialtype_ssh,
        name='Best credential ever',
        organization=organization,
        inputs={
            'username': u'oscar',
            'ssh_key_data': 'invalid-key',
            'ssh_key_unlock': 'unchecked-unlock',
        },
    )
    cred.save()

    params['organization'] = organization.id
    response = put(reverse('api:credential_detail', kwargs={'pk': cred.pk}),
                   params, admin)
    assert response.status_code == 400
    assert response.data['inputs']['ssh_key_data'] == [
        'Invalid certificate or key: invalid-key...'
    ]
    assert 'ssh_key_unlock' not in response.data['inputs']
Ejemplo n.º 5
0
def test_secret_encryption_previous_value(patch, organization, admin,
                                          credentialtype_ssh):
    params = {
        'inputs': {
            'username': '******',
            'password': '******',
        }
    }
    cred = Credential(credential_type=credentialtype_ssh,
                      name='Best credential ever',
                      organization=organization,
                      inputs={
                          'username': u'jim',
                          'password': u'secret'
                      })
    cred.save()

    assert decrypt_field(cred, 'password') == 'secret'
    response = patch(reverse('api:credential_detail', kwargs={'pk': cred.pk}),
                     params, admin)
    assert response.status_code == 200

    cred = Credential.objects.all()[:1].get()
    assert cred.inputs['username'] == 'joe'
    assert cred.inputs['password'].startswith('$encrypted$UTF8$AES')
    assert decrypt_field(cred, 'password') == 'secret'
Ejemplo n.º 6
0
def test_field_removal(put, organization, admin, credentialtype_ssh):
    params = {
        'name': 'Best credential ever',
        'credential_type': 1,
        'inputs': {
            'username': '******',
            'password': '',
        },
    }
    cred = Credential(credential_type=credentialtype_ssh,
                      name='Best credential ever',
                      organization=organization,
                      inputs={
                          'username': u'jim',
                          'password': u'secret'
                      })
    cred.save()

    params['organization'] = organization.id
    response = put(reverse('api:credential_detail', kwargs={'pk': cred.pk}),
                   params, admin)
    assert response.status_code == 200

    cred = Credential.objects.all()[:1].get()
    assert cred.inputs['username'] == 'joe'
    assert 'password' not in cred.inputs
Ejemplo n.º 7
0
def test_clean_credential_with_ssh_type(credentialtype_ssh, job_template):
    credential = Credential(name='My Credential',
                            credential_type=credentialtype_ssh)
    credential.save()

    job_template.credential = credential
    job_template.full_clean()
def test_prevent_multiple_machine_creds_at_launch(get, post, job_template, admin, machine_credential):
    other_cred = Credential(credential_type=machine_credential.credential_type, name="Second", inputs={'username': '******'})
    other_cred.save()
    creds = [machine_credential.pk, other_cred.pk]
    url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
    resp = post(url, {'credentials': creds}, admin)
    assert 'Cannot assign multiple Machine credentials.' in smart_str(resp.content)
Ejemplo n.º 9
0
    def handle(self, *args, **kwargs):
        changed = False

        # Create a default organization as the first superuser found.
        try:
            superuser = User.objects.filter(is_superuser=True).order_by('pk')[0]
        except IndexError:
            superuser = None
        with impersonate(superuser):
            with disable_computed_fields():
                if not Organization.objects.exists():
                    o = Organization.objects.create(name='Default')

                    p = Project(
                        name='Demo Project',
                        scm_type='git',
                        scm_url='https://github.com/ansible/ansible-tower-samples',
                        scm_update_on_launch=True,
                        scm_update_cache_timeout=0,
                        organization=o,
                    )
                    p.save(skip_update=True)

                    ssh_type = CredentialType.objects.filter(namespace='ssh').first()
                    c = Credential.objects.create(
                        credential_type=ssh_type, name='Demo Credential', inputs={'username': superuser.username}, created_by=superuser
                    )

                    c.admin_role.members.add(superuser)

                    public_galaxy_credential = Credential(
                        name='Ansible Galaxy',
                        managed_by_tower=True,
                        credential_type=CredentialType.objects.get(kind='galaxy'),
                        inputs={'url': 'https://galaxy.ansible.com/'},
                    )
                    public_galaxy_credential.save()
                    o.galaxy_credentials.add(public_galaxy_credential)

                    i = Inventory.objects.create(name='Demo Inventory', organization=o, created_by=superuser)

                    Host.objects.create(
                        name='localhost',
                        inventory=i,
                        variables="ansible_connection: local\nansible_python_interpreter: '{{ ansible_playbook_python }}'",
                        created_by=superuser,
                    )

                    jt = JobTemplate.objects.create(name='Demo Job Template', playbook='hello_world.yml', project=p, inventory=i)
                    jt.credentials.add(c)

                    print('Default organization added.')
                    print('Demo Credential, Inventory, and Job Template added.')
                    changed = True

        if changed:
            print('(changed: True)')
        else:
            print('(changed: False)')
Ejemplo n.º 10
0
def test_credential_encryption_with_ask(organization_factory, credentialtype_ssh):
    org = organization_factory('test').organization
    cred = Credential(credential_type=credentialtype_ssh, name="Bob's Credential", inputs={'password': '******'}, organization=org)
    cred.save()

    assert Credential.objects.count() == 1
    cred = Credential.objects.all()[:1].get()
    assert cred.inputs['password'] == 'ASK'
Ejemplo n.º 11
0
def test_credential_get_input(organization_factory):
    organization = organization_factory('test').organization
    type_ = CredentialType(
        kind='vault',
        name='somevault',
        managed_by_tower=True,
        inputs={
            'fields': [
                {
                    'id': 'vault_password',
                    'type': 'string',
                    'secret': True,
                },
                {
                    'id': 'vault_id',
                    'type': 'string',
                    'secret': False
                },
                {
                    'id': 'secret',
                    'type': 'string',
                    'secret': True,
                },
            ]
        },
    )
    type_.save()

    cred = Credential(organization=organization,
                      credential_type=type_,
                      name="Bob's Credential",
                      inputs={'vault_password': '******'})
    cred.save()
    cred.full_clean()

    assert isinstance(cred, Credential)
    # verify expected exception is raised when attempting to access an unset
    # input without providing a default
    with pytest.raises(AttributeError):
        cred.get_input('vault_id')
    # verify that the provided default is used for unset inputs
    assert cred.get_input('vault_id', default='foo') == 'foo'
    # verify expected exception is raised when attempting to access an undefined
    # input without providing a default
    with pytest.raises(AttributeError):
        cred.get_input('field_not_on_credential_type')
    # verify that the provided default is used for undefined inputs
    assert cred.get_input('field_not_on_credential_type',
                          default='bar') == 'bar'
    # verify expected exception is raised when attempting to access an unset secret
    # input without providing a default
    with pytest.raises(AttributeError):
        cred.get_input('secret')
    # verify that the provided default is used for undefined inputs
    assert cred.get_input('secret', default='fiz') == 'fiz'
    # verify return values for encrypted secret fields are decrypted
    assert cred.inputs['vault_password'].startswith('$encrypted$')
    assert cred.get_input('vault_password') == 'testing321'
Ejemplo n.º 12
0
def test_credential_encryption(organization_factory, credentialtype_ssh):
    org = organization_factory('test').organization
    cred = Credential(credential_type=credentialtype_ssh, name="Bob's Credential", inputs={'password': '******'}, organization=org)
    cred.save()

    assert Credential.objects.count() == 1
    cred = Credential.objects.all()[:1].get()
    assert cred.inputs['password'].startswith('$encrypted$')
    assert decrypt_field(cred, 'password') == 'testing123'
Ejemplo n.º 13
0
def galaxy_credential():
    galaxy_type = CredentialType.objects.create(kind='galaxy')
    cred = Credential(created=now(),
                      modified=now(),
                      name='Ansible Galaxy',
                      managed=True,
                      credential_type=galaxy_type,
                      inputs={'url': 'https://galaxy.ansible.com/'})
    cred.save()
Ejemplo n.º 14
0
def test_clean_credential_with_invalid_type_xfail(credentialtype_aws,
                                                  job_template):
    credential = Credential(name='My Credential',
                            credential_type=credentialtype_aws)
    credential.save()

    with pytest.raises(ValidationError):
        job_template.credential = credential
        job_template.full_clean()
Ejemplo n.º 15
0
def test_clean_credential_with_custom_types(credentialtype_aws,
                                            credentialtype_net, job_template):
    aws = Credential(name='AWS Credential', credential_type=credentialtype_aws)
    aws.save()
    net = Credential(name='Net Credential', credential_type=credentialtype_net)
    net.save()

    job_template.extra_credentials.add(aws)
    job_template.extra_credentials.add(net)
    job_template.full_clean()
Ejemplo n.º 16
0
def mk_credential(name, credential_type='ssh', persisted=True):
    if persisted:
        type_, status = CredentialType.objects.get_or_create(kind=credential_type)
        type_.save()
    else:
        type_ = CredentialType.defaults[credential_type]()
    cred = Credential(credential_type=type_, name=name)
    if persisted:
        cred.save()
    return cred
Ejemplo n.º 17
0
def test_vault_validation(organization, inputs, valid):
    cred_type = CredentialType.defaults['vault']()
    cred_type.save()
    cred = Credential(credential_type=cred_type, name="Best credential ever", inputs=inputs, organization=organization)
    cred.save()
    if valid:
        cred.full_clean()
    else:
        with pytest.raises(Exception) as e:
            cred.full_clean()
        assert e.type in (ValidationError, serializers.ValidationError)
def test_prompted_credential_replaced_on_launch(get, post, job_template, admin, machine_credential):
    # If a JT has a credential that needs a password, but the launch POST
    # specifies credential that does not require any passwords
    cred2 = Credential(name='second-cred', inputs=machine_credential.inputs, credential_type=machine_credential.credential_type)
    cred2.inputs['password'] = '******'
    cred2.save()
    job_template.credentials.add(cred2)
    url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
    resp = post(url, {}, admin, expect=400)
    resp = post(url, {'credentials': [machine_credential.pk]}, admin, expect=201)
    assert 'job' in resp.data
Ejemplo n.º 19
0
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'}]}
    )
    type_.save()

    cred = Credential(credential_type=type_, name="Bob's Credential", inputs={'username': '******'}, organization=org)
    cred.save()
    cred.full_clean()
    assert isinstance(cred, Credential)
    assert cred.name == "Bob's Credential"
    assert cred.inputs['username'] == 'bob'
Ejemplo n.º 20
0
def test_choices_validity(become_method, valid, organization):
    inputs = {'become_method': become_method}
    cred_type = CredentialType.defaults['ssh']()
    cred_type.save()
    cred = Credential(credential_type=cred_type, name="Best credential ever", inputs=inputs, organization=organization)
    cred.save()

    if valid:
        cred.full_clean()
    else:
        with pytest.raises(serializers.ValidationError) as e:
            cred.full_clean()
        assert "'%s' is not one of" % become_method in str(e)
def test_cred_unique_org_name_kind(organization_factory, credentialtype_ssh):
    objects = organization_factory("test")

    cred = Credential(name="test",
                      credential_type=credentialtype_ssh,
                      organization=objects.organization)
    cred.save()

    with pytest.raises(IntegrityError):
        cred = Credential(name="test",
                          credential_type=credentialtype_ssh,
                          organization=objects.organization)
        cred.save()
Ejemplo n.º 22
0
def test_credential_with_multiple_secrets(organization_factory, credentialtype_ssh):
    org = organization_factory('test').organization
    cred = Credential(
        credential_type=credentialtype_ssh, name="Bob's Credential", inputs={'ssh_key_data': 'SOMEKEY', 'ssh_key_unlock': 'testing123'}, organization=org
    )
    cred.save()

    assert Credential.objects.count() == 1
    cred = Credential.objects.all()[:1].get()

    assert cred.inputs['ssh_key_data'].startswith('$encrypted$')
    assert decrypt_field(cred, 'ssh_key_data') == 'SOMEKEY'
    assert cred.inputs['ssh_key_unlock'].startswith('$encrypted$')
    assert decrypt_field(cred, 'ssh_key_unlock') == 'testing123'
Ejemplo n.º 23
0
def test_ssh_key_data_validation(organization, kind, ssh_key_data, ssh_key_unlock, valid):
    inputs = {'username': '******'}
    if ssh_key_data:
        inputs['ssh_key_data'] = ssh_key_data
    if ssh_key_unlock:
        inputs['ssh_key_unlock'] = ssh_key_unlock
    cred_type = CredentialType.defaults[kind]()
    cred_type.save()
    cred = Credential(credential_type=cred_type, name="Best credential ever", inputs=inputs, organization=organization)
    cred.save()
    if valid:
        cred.full_clean()
    else:
        with pytest.raises(Exception) as e:
            cred.full_clean()
        assert e.type in (ValidationError, serializers.ValidationError)
Ejemplo n.º 24
0
def test_cloud_credential_type_mutability(patch, organization, admin, credentialtype_ssh,
                                          credentialtype_aws):
    cred = Credential(
        credential_type=credentialtype_aws,
        name='Best credential ever',
        organization=organization,
        inputs={
            'username': u'jim',
            'password': u'pass'
        }
    )
    cred.save()

    jt = JobTemplate()
    jt.save()
    jt.credentials.add(cred)

    def _change_credential_type():
        return patch(
            reverse('api:credential_detail', kwargs={'pk': cred.pk}),
            {
                'credential_type': credentialtype_ssh.pk,
                'inputs': {
                    'username': u'jim',
                    'password': u'pass'
                }
            },
            admin
        )

    response = _change_credential_type()
    assert response.status_code == 400
    expected = ['You cannot change the credential type of the credential, '
                'as it may break the functionality of the resources using it.']
    assert response.data['credential_type'] == expected

    response = patch(
        reverse('api:credential_detail', kwargs={'pk': cred.pk}),
        {'name': 'Worst credential ever'},
        admin
    )
    assert response.status_code == 200
    assert Credential.objects.get(pk=cred.pk).name == 'Worst credential ever'

    jt.delete()
    response = _change_credential_type()
    assert response.status_code == 200
def test_invalid_credential_type_at_launch(get, post, job_template, admin,
                                           kind):
    cred_type = CredentialType.defaults[kind]()
    cred_type.save()
    cred = Credential(name='Some Cred',
                      credential_type=cred_type,
                      inputs={
                          'username': '******',
                          'password': '******',
                      })
    cred.save()
    url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})

    resp = post(url, {'credentials': [cred.pk]}, admin, expect=400)
    assert 'Cannot assign a Credential of kind `{}`'.format(
        kind) in resp.data.get('credentials', [])
    assert Job.objects.count() == 0