Exemple #1
0
def mk_inventory(name, organization=None, persisted=True):
    inv = Inventory(name=name)
    if organization is not None:
        inv.organization = organization
    if persisted:
        inv.save()
    return inv
Exemple #2
0
def test_host_summary_generation_with_deleted_hosts():
    hostnames = [f'Host {i}' for i in range(10)]
    inv = Inventory()
    inv.save()
    Host.objects.bulk_create([Host(created=now(), modified=now(), name=h, inventory_id=inv.id) for h in hostnames])
    j = Job(inventory=inv)
    j.save()
    host_map = dict((host.name, host.id) for host in inv.hosts.all())

    # delete half of the hosts during the playbook run
    for h in inv.hosts.all()[:5]:
        h.delete()

    JobEvent.create_from_data(
        job_id=j.pk,
        parent_uuid='abc123',
        event='playbook_on_stats',
        event_data={
            'ok': dict((hostname, len(hostname)) for hostname in hostnames),
            'changed': {},
            'dark': {},
            'failures': {},
            'ignored': {},
            'processed': {},
            'rescued': {},
            'skipped': {},
        },
        host_map=host_map,
    ).save()

    ids = sorted([s.host_id or -1 for s in j.job_host_summaries.order_by('id').all()])
    names = sorted([s.host_name for s in j.job_host_summaries.all()])
    assert ids == [-1, -1, -1, -1, -1, 6, 7, 8, 9, 10]
    assert names == ['Host 0', 'Host 1', 'Host 2', 'Host 3', 'Host 4', 'Host 5', 'Host 6', 'Host 7', 'Host 8', 'Host 9']
def test_invalid_kind_clean_insights_credential():
    cred_type = CredentialType.defaults['insights']()
    insights_cred = Credential(credential_type=cred_type)
    inv = Inventory(kind='smart', insights_credential=insights_cred)

    with pytest.raises(ValidationError) as e:
        inv.clean_insights_credential()

    assert json.dumps(str(e.value)) == json.dumps(str([u'Assignment not allowed for Smart Inventory']))
def test_invalid_clean_insights_credential():
    cred_type = CredentialType.defaults['scm']()
    cred = Credential(credential_type=cred_type)
    inv = Inventory(insights_credential=cred)

    with pytest.raises(ValidationError) as e:
        inv.clean_insights_credential()

    assert json.dumps(str(e.value)) == json.dumps(str([u"Credential kind must be 'insights'."]))
Exemple #5
0
def test_create_inventory_smart_inventory_sources(post, get, inventory, admin_user, organization):
    data = {'name': 'Inventory Source 1', 'description': 'Test Inventory Source'}
    smart_inventory = Inventory(name='smart', kind='smart', organization=organization, host_filter='inventory_sources__source=ec2')
    smart_inventory.save()
    post(reverse('api:inventory_inventory_sources_list', kwargs={'pk': smart_inventory.id}), data, admin_user)
    resp = get(reverse('api:inventory_inventory_sources_list', kwargs={'pk': smart_inventory.id}), admin_user)
    jdata = json.loads(resp.content)

    assert getattr(smart_inventory, 'kind') == 'smart'
    assert jdata['count'] == 0
Exemple #6
0
def test_empty_inventory(post, get, admin_user, organization, group_factory):
    inventory = Inventory(name='basic_inventory',
                          kind='',
                          organization=organization)
    inventory.save()
    resp = get(reverse('api:inventory_script_view', kwargs={'version': 'v2', 'pk': inventory.pk}), admin_user)
    jdata = json.loads(resp.content)
    jdata.pop('all')

    assert inventory.hosts.count() == 0
    assert jdata == {}
def test_host_summary_generation_with_limit():
    # Make an inventory with 10 hosts, run a playbook with a --limit
    # pointed at *one* host,
    # Verify that *only* that host has an associated JobHostSummary and that
    # *only* that host has an updated value for .last_job.
    hostnames = [f'Host {i}' for i in range(10)]
    inv = Inventory()
    inv.save()
    Host.objects.bulk_create([
        Host(created=now(), modified=now(), name=h, inventory_id=inv.id)
        for h in hostnames
    ])
    j = Job(inventory=inv)
    j.save()

    # host map is a data structure that tracks a mapping of host name --> ID
    # for the inventory, _regardless_ of whether or not there's a limit
    # applied to the actual playbook run
    host_map = dict((host.name, host.id) for host in inv.hosts.all())

    # by making the playbook_on_stats *only* include Host 1, we're emulating
    # the behavior of a `--limit=Host 1`
    matching_host = Host.objects.get(name='Host 1')
    JobEvent.create_from_data(
        job_id=j.pk,
        parent_uuid='abc123',
        event='playbook_on_stats',
        event_data={
            'ok': {
                matching_host.name: len(matching_host.name)
            },  # effectively, limit=Host 1
            'changed': {},
            'dark': {},
            'failures': {},
            'ignored': {},
            'processed': {},
            'rescued': {},
            'skipped': {},
        },
        host_map=host_map).save()

    # since the playbook_on_stats only references one host,
    # there should *only* be on JobHostSummary record (and it should
    # be related to the appropriate Host)
    assert JobHostSummary.objects.count() == 1
    for h in Host.objects.all():
        if h.name == 'Host 1':
            assert h.last_job_id == j.id
            assert h.last_job_host_summary_id == JobHostSummary.objects.first(
            ).id
        else:
            # all other hosts in the inventory should remain untouched
            assert h.last_job_id is None
            assert h.last_job_host_summary_id is None
Exemple #8
0
def test_ungrouped_hosts(post, get, admin_user, organization, group_factory):
    inventory = Inventory(name='basic_inventory',
                          kind='',
                          organization=organization)
    inventory.save()
    Host.objects.create(name='first_host', inventory=inventory)
    Host.objects.create(name='second_host', inventory=inventory)
    resp = get(reverse('api:inventory_script_view', kwargs={'version': 'v2', 'pk': inventory.pk}), admin_user)
    jdata = json.loads(resp.content)
    assert inventory.hosts.count() == 2
    assert len(jdata['all']['hosts']) == 2
def job(container_group):
    return Job(pk=1,
               id=1,
               project=Project(),
               instance_group=container_group,
               inventory=Inventory(),
               job_template=JobTemplate(id=1, name='foo'))
Exemple #10
0
    def get_serializer_context(self, *args, **kwargs):
        full_context = super(OrganizationDetail,
                             self).get_serializer_context(*args, **kwargs)

        if not hasattr(self, 'kwargs') or 'pk' not in self.kwargs:
            return full_context
        org_id = int(self.kwargs['pk'])

        org_counts = {}
        access_kwargs = {
            'accessor': self.request.user,
            'role_field': 'read_role'
        }
        direct_counts = Organization.objects.filter(id=org_id).annotate(
            users=Count('member_role__members', distinct=True),
            admins=Count('admin_role__members',
                         distinct=True)).values('users', 'admins')

        if not direct_counts:
            return full_context

        org_counts = direct_counts[0]
        org_counts['inventories'] = Inventory.accessible_objects(
            **access_kwargs).filter(organization__id=org_id).count()
        org_counts['teams'] = Team.accessible_objects(**access_kwargs).filter(
            organization__id=org_id).count()
        org_counts['projects'] = Project.accessible_objects(
            **access_kwargs).filter(organization__id=org_id).count()
        org_counts['job_templates'] = JobTemplate.accessible_objects(
            **access_kwargs).filter(organization__id=org_id).count()

        full_context['related_field_counts'] = {}
        full_context['related_field_counts'][org_id] = org_counts

        return full_context
Exemple #11
0
 def test_job_metavars(self):
     maker = User(username='******', pk=47, id=47)
     inv = Inventory(name='example-inv', id=45)
     assert Job(
         name='fake-job',
         pk=42, id=42,
         launch_type='manual',
         created_by=maker,
         inventory=inv
     ).awx_meta_vars() == {
         'tower_job_id': 42,
         'awx_job_id': 42,
         'tower_job_launch_type': 'manual',
         'awx_job_launch_type': 'manual',
         'awx_user_name': 'joe',
         'tower_user_name': 'joe',
         'awx_user_email': '',
         'tower_user_email': '',
         'awx_user_first_name': '',
         'tower_user_first_name': '',
         'awx_user_last_name': '',
         'tower_user_last_name': '',
         'awx_user_id': 47,
         'tower_user_id': 47,
         'tower_inventory_id': 45,
         'awx_inventory_id': 45,
         'tower_inventory_name': 'example-inv',
         'awx_inventory_name': 'example-inv'
     }
Exemple #12
0
def job_template_with_ids(job_template_factory):
    # Create non-persisted objects with IDs to send to job_template_factory
    ssh_type = CredentialType(kind='ssh')
    credential = Credential(id=1,
                            pk=1,
                            name='testcred',
                            credential_type=ssh_type)

    net_type = CredentialType(kind='net')
    net_cred = Credential(id=2,
                          pk=2,
                          name='testnetcred',
                          credential_type=net_type)

    cloud_type = CredentialType(kind='aws')
    cloud_cred = Credential(id=3,
                            pk=3,
                            name='testcloudcred',
                            credential_type=cloud_type)

    inv = Inventory(id=11, pk=11, name='testinv')
    proj = Project(id=14, pk=14, name='testproj')

    jt_objects = job_template_factory('testJT',
                                      project=proj,
                                      inventory=inv,
                                      credential=credential,
                                      cloud_credential=cloud_cred,
                                      network_credential=net_cred,
                                      persisted=False)
    return jt_objects.job_template
 def jt(self, survey_spec_factory):
     return JobTemplate(
         name='fake-jt',
         survey_enabled=True,
         survey_spec=survey_spec_factory(variables='var1', default_type='password'),
         project=Project('fake-proj'), project_id=42,
         inventory=Inventory('fake-inv'), inventory_id=42
     )
Exemple #14
0
def test_host_summary_generation():
    hostnames = [f'Host {i}' for i in range(100)]
    inv = Inventory()
    inv.save()
    Host.objects.bulk_create([
        Host(created=now(), modified=now(), name=h, inventory_id=inv.id)
        for h in hostnames
    ])
    j = Job(inventory=inv)
    j.save()
    host_map = dict((host.name, host.id) for host in inv.hosts.all())
    JobEvent.create_from_data(job_id=j.pk,
                              parent_uuid='abc123',
                              event='playbook_on_stats',
                              event_data={
                                  'ok':
                                  dict((hostname, len(hostname))
                                       for hostname in hostnames),
                                  'changed': {},
                                  'dark': {},
                                  'failures': {},
                                  'ignored': {},
                                  'processed': {},
                                  'rescued': {},
                                  'skipped': {},
                              },
                              host_map=host_map).save()

    assert j.job_host_summaries.count() == len(hostnames)
    assert sorted([s.host_name
                   for s in j.job_host_summaries.all()]) == sorted(hostnames)

    for s in j.job_host_summaries.all():
        assert host_map[s.host_name] == s.host_id
        assert s.ok == len(s.host_name)
        assert s.changed == 0
        assert s.dark == 0
        assert s.failures == 0
        assert s.ignored == 0
        assert s.processed == 0
        assert s.rescued == 0
        assert s.skipped == 0

    for host in Host.objects.all():
        assert host.last_job_id == j.id
        assert host.last_job_host_summary.host == host
Exemple #15
0
 def test_jt_extra_vars_counting(self, provided_vars, valid):
     jt = JobTemplate(name='foo',
                      extra_vars={'tmpl_var': 'bar'},
                      project=Project(),
                      project_id=42,
                      playbook='helloworld.yml',
                      inventory=Inventory(),
                      inventory_id=42)
     prompted_fields, ignored_fields, errors = jt._accept_or_ignore_job_kwargs(
         extra_vars=provided_vars)
     self.process_vars_and_assert(jt, provided_vars, valid)
Exemple #16
0
def wfjt_node_with_prompts(wfjt_node_no_prompts):
    wfjt_node_no_prompts.char_prompts = example_prompts
    wfjt_node_no_prompts.inventory = Inventory(name='example-inv')
    ssh_type = CredentialType.defaults['ssh']()
    wfjt_node_no_prompts.credential = Credential(name='example-inv',
                                                 credential_type=ssh_type,
                                                 inputs={
                                                     'username': '******',
                                                     'password': '******'
                                                 })
    return wfjt_node_no_prompts
Exemple #17
0
def test_change_jt_sensitive_data(job_template_with_ids, mocker, user_unit):
    """Assure that can_add is called with all ForeignKeys."""
    class RoleReturnsTrue(Role):
        class Meta:
            proxy = True

        def __contains__(self, accessor):
            return True

    job_template_with_ids.admin_role = RoleReturnsTrue()
    job_template_with_ids.organization.job_template_admin_role = RoleReturnsTrue(
    )

    inv2 = Inventory()
    inv2.use_role = RoleReturnsTrue()
    data = {'inventory': inv2}

    access = JobTemplateAccess(user_unit)

    assert not access.changes_are_non_sensitive(job_template_with_ids, data)

    job_template_with_ids.inventory.use_role = RoleReturnsTrue()
    job_template_with_ids.project.use_role = RoleReturnsTrue()
    assert access.can_change(job_template_with_ids, data)
Exemple #18
0
 def test_job_metavars(self):
     maker = User(username='******', pk=47, id=47)
     inv = Inventory(name='example-inv', id=45)
     result_hash = {}
     for name in JOB_VARIABLE_PREFIXES:
         result_hash['{}_job_id'.format(name)] = 42
         result_hash['{}_job_launch_type'.format(name)] = 'manual'
         result_hash['{}_user_name'.format(name)] = 'joe'
         result_hash['{}_user_email'.format(name)] = ''
         result_hash['{}_user_first_name'.format(name)] = ''
         result_hash['{}_user_last_name'.format(name)] = ''
         result_hash['{}_user_id'.format(name)] = 47
         result_hash['{}_inventory_id'.format(name)] = 45
         result_hash['{}_inventory_name'.format(name)] = 'example-inv'
     assert Job(name='fake-job',
                pk=42,
                id=42,
                launch_type='manual',
                created_by=maker,
                inventory=inv).awx_meta_vars() == result_hash
Exemple #19
0
 def test_host_filter_not_smart(self, setup_ec2_gce, organization):
     smart_inventory = Inventory(
         name='smart',
         organization=organization,
         host_filter='inventory_sources__source=ec2')
     assert len(smart_inventory.hosts.all()) == 0
Exemple #20
0
def inventory():
    return Inventory(id=5)
Exemple #21
0
    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


@pytest.mark.django_db
@pytest.mark.parametrize('relation, related_obj', [
    ['ad_hoc_commands', AdHocCommand()],
    ['insights_inventories', Inventory()],
    ['unifiedjobs', Job()],
    ['unifiedjobtemplates', JobTemplate()],
    ['unifiedjobtemplates', InventorySource()],
    ['projects', Project()],
    ['workflowjobnodes', WorkflowJobNode()],
])
def test_credential_type_mutability(patch, organization, admin, credentialtype_ssh,
                                    credentialtype_aws, relation, related_obj):
    cred = Credential(
        credential_type=credentialtype_ssh,
        name='Best credential ever',
        organization=organization,
        inputs={
            'username': u'jim',
            'password': u'pass'
Exemple #22
0
def test_valid_kind_clean_insights_credential():
    inv = Inventory(kind='smart')

    inv.clean_insights_credential()
Exemple #23
0
def test_valid_clean_insights_credential():
    cred_type = CredentialType.defaults['insights']()
    insights_cred = Credential(credential_type=cred_type)
    inv = Inventory(insights_credential=insights_cred)

    inv.clean_insights_credential()
def wfjt_node_with_prompts(wfjt_node_no_prompts, mocker):
    wfjt_node_no_prompts.char_prompts = example_prompts
    wfjt_node_no_prompts.inventory = Inventory(name='example-inv')
    return wfjt_node_no_prompts
def job_node_with_prompts(job_node_no_prompts, mocker):
    job_node_no_prompts.char_prompts = example_prompts
    job_node_no_prompts.inventory = Inventory(name='example-inv', id=45)
    job_node_no_prompts.inventory_id = 45
    return job_node_no_prompts
Exemple #26
0
 def get_queryset(self):
     qs = Inventory.accessible_objects(self.request.user, 'read_role')
     qs = qs.select_related('admin_role', 'read_role', 'update_role', 'use_role', 'adhoc_role')
     qs = qs.prefetch_related('created_by', 'modified_by', 'organization')
     return qs