fix tests for new inv plugin behavior

* Enforce plugin:
This commit is contained in:
Chris Meyers 2020-07-28 13:14:43 -04:00 committed by Ryan Petrello
parent a8a47f314e
commit 34adbe6028
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
15 changed files with 111 additions and 417 deletions

View File

@ -7,6 +7,7 @@ import time
import logging
import re
import copy
import json
import os.path
from urllib.parse import urljoin
import yaml
@ -1157,6 +1158,20 @@ class InventorySource(UnifiedJobTemplate, InventorySourceOptions, CustomVirtualE
raise ValidationError(_("Cannot set source_path if not SCM type."))
return self.source_path
def clean_source_vars(self):
injector = self.injectors.get(self.source)
source_vars = dict(self.source_vars_dict) # make a copy
if injector and self.source_vars_dict.get('plugin', '') != injector.get_proper_name():
source_vars['plugin'] = injector.get_proper_name()
elif not injector:
source_vars = dict(self.source_vars_dict) # make a copy
collection_pattern = re.compile("^(.+)\.(.+)\.(.+)$") # noqa
if 'plugin' not in source_vars:
raise ValidationError(_("plugin: must be present and of the form namespace.collection.inv_plugin"))
elif not bool(collection_pattern.match(source_vars['plugin'])):
raise ValidationError(_("plugin: must be of the form namespace.collection.inv_plugin"))
return json.dumps(source_vars)
'''
RelatedJobsMixin
'''
@ -1344,6 +1359,12 @@ class PluginFileInjector(object):
# This is InventoryOptions instance, could be source or inventory update
self.ansible_version = ansible_version
@classmethod
def get_proper_name(cls):
if cls.plugin_name is None:
return None
return f'{cls.namespace}.{cls.collection}.{cls.plugin_name}'
@property
def filename(self):
"""Inventory filename for using the inventory plugin

View File

@ -1,43 +0,0 @@
conditional_groups:
azure: true
default_host_filters: []
exclude_host_filters:
- resource_group not in ['foo_resources', 'bar_resources']
- '"Creator" not in tags.keys()'
- tags["Creator"] != "jmarshall"
- '"peanutbutter" not in tags.keys()'
- tags["peanutbutter"] != "jelly"
- location not in ['southcentralus', 'westus']
fail_on_template_errors: false
hostvar_expressions:
ansible_host: private_ipv4_addresses[0]
computer_name: name
private_ip: private_ipv4_addresses[0] if private_ipv4_addresses else None
provisioning_state: provisioning_state | title
public_ip: public_ipv4_addresses[0] if public_ipv4_addresses else None
public_ip_id: public_ip_id if public_ip_id is defined else None
public_ip_name: public_ip_name if public_ip_name is defined else None
tags: tags if tags else None
type: resource_type
keyed_groups:
- key: location
prefix: ''
separator: ''
- key: tags.keys() | list if tags else []
prefix: ''
separator: ''
- key: security_group
prefix: ''
separator: ''
- key: resource_group
prefix: ''
separator: ''
- key: os_disk.operating_system_type
prefix: ''
separator: ''
- key: dict(tags.keys() | map("regex_replace", "^(.*)$", "\1_") | list | zip(tags.values() | list)) if tags else []
prefix: ''
separator: ''
plain_host_names: true
plugin: azure.azcollection.azure_rm
use_contrib_script_compatible_sanitization: true

View File

@ -1,81 +0,0 @@
boto_profile: /tmp/my_boto_stuff
compose:
ansible_host: public_dns_name
ec2_account_id: owner_id
ec2_ami_launch_index: ami_launch_index | string
ec2_architecture: architecture
ec2_block_devices: dict(block_device_mappings | map(attribute='device_name') | list | zip(block_device_mappings | map(attribute='ebs.volume_id') | list))
ec2_client_token: client_token
ec2_dns_name: public_dns_name
ec2_ebs_optimized: ebs_optimized
ec2_eventsSet: events | default("")
ec2_group_name: placement.group_name
ec2_hypervisor: hypervisor
ec2_id: instance_id
ec2_image_id: image_id
ec2_instance_profile: iam_instance_profile | default("")
ec2_instance_type: instance_type
ec2_ip_address: public_ip_address
ec2_kernel: kernel_id | default("")
ec2_key_name: key_name
ec2_launch_time: launch_time | regex_replace(" ", "T") | regex_replace("(\+)(\d\d):(\d)(\d)$", ".\g<2>\g<3>Z")
ec2_monitored: monitoring.state in ['enabled', 'pending']
ec2_monitoring_state: monitoring.state
ec2_persistent: persistent | default(false)
ec2_placement: placement.availability_zone
ec2_platform: platform | default("")
ec2_private_dns_name: private_dns_name
ec2_private_ip_address: private_ip_address
ec2_public_dns_name: public_dns_name
ec2_ramdisk: ramdisk_id | default("")
ec2_reason: state_transition_reason
ec2_region: placement.region
ec2_requester_id: requester_id | default("")
ec2_root_device_name: root_device_name
ec2_root_device_type: root_device_type
ec2_security_group_ids: security_groups | map(attribute='group_id') | list | join(',')
ec2_security_group_names: security_groups | map(attribute='group_name') | list | join(',')
ec2_sourceDestCheck: source_dest_check | default(false) | lower | string
ec2_spot_instance_request_id: spot_instance_request_id | default("")
ec2_state: state.name
ec2_state_code: state.code
ec2_state_reason: state_reason.message if state_reason is defined else ""
ec2_subnet_id: subnet_id | default("")
ec2_tag_Name: tags.Name
ec2_virtualization_type: virtualization_type
ec2_vpc_id: vpc_id | default("")
filters:
instance-state-name:
- running
groups:
ec2: true
hostnames:
- dns-name
iam_role_arn: arn:aws:iam::123456789012:role/test-role
keyed_groups:
- key: placement.availability_zone
parent_group: zones
prefix: ''
separator: ''
- key: instance_type | regex_replace("[^A-Za-z0-9\_]", "_")
parent_group: types
prefix: type
- key: placement.region
parent_group: regions
prefix: ''
separator: ''
- key: dict(tags.keys() | map("regex_replace", "[^A-Za-z0-9\_]", "_") | list | zip(tags.values() | map("regex_replace", "[^A-Za-z0-9\_]", "_") | list))
parent_group: tags
prefix: tag
- key: tags.keys() | map("regex_replace", "[^A-Za-z0-9\_]", "_") | list
parent_group: tags
prefix: tag
- key: placement.availability_zone
parent_group: '{{ placement.region }}'
prefix: ''
separator: ''
plugin: amazon.aws.aws_ec2
regions:
- us-east-2
- ap-south-1
use_contrib_script_compatible_sanitization: true

View File

@ -1,50 +0,0 @@
auth_kind: serviceaccount
compose:
ansible_ssh_host: networkInterfaces[0].accessConfigs[0].natIP | default(networkInterfaces[0].networkIP)
gce_description: description if description else None
gce_id: id
gce_image: image
gce_machine_type: machineType
gce_metadata: metadata.get("items", []) | items2dict(key_name="key", value_name="value")
gce_name: name
gce_network: networkInterfaces[0].network.name
gce_private_ip: networkInterfaces[0].networkIP
gce_public_ip: networkInterfaces[0].accessConfigs[0].natIP | default(None)
gce_status: status
gce_subnetwork: networkInterfaces[0].subnetwork.name
gce_tags: tags.get("items", [])
gce_zone: zone
hostnames:
- name
- public_ip
- private_ip
keyed_groups:
- key: gce_subnetwork
prefix: network
- key: gce_private_ip
prefix: ''
separator: ''
- key: gce_public_ip
prefix: ''
separator: ''
- key: machineType
prefix: ''
separator: ''
- key: zone
prefix: ''
separator: ''
- key: gce_tags
prefix: tag
- key: status | lower
prefix: status
- key: image
prefix: ''
separator: ''
plugin: google.cloud.gcp_compute
projects:
- fooo
retrieve_image_info: true
use_contrib_script_compatible_sanitization: true
zones:
- us-east4-a
- us-west1-b

View File

@ -1,7 +1,3 @@
ansible:
expand_hostvars: true
fail_on_errors: true
use_hostnames: false
clouds:
devstack:
auth:
@ -11,5 +7,5 @@ clouds:
project_domain_name: fooo
project_name: fooo
username: fooo
private: false
private: true
verify: false

View File

@ -1,4 +0,0 @@
expand_hostvars: true
fail_on_errors: true
inventory_hostname: uuid
plugin: openstack.cloud.openstack

View File

@ -1,20 +0,0 @@
base_source_var: value_of_var
compose:
ansible_host: (devices.values() | list)[0][0] if devices else None
groups:
dev: '"dev" in tags'
keyed_groups:
- key: cluster
prefix: cluster
separator: _
- key: status
prefix: status
separator: _
- key: tags
prefix: tag
separator: _
ovirt_hostname_preference:
- name
- fqdn
ovirt_insecure: false
plugin: ovirt.ovirt.ovirt

View File

@ -1,30 +0,0 @@
base_source_var: value_of_var
compose:
ansible_ssh_host: foreman['ip6'] | default(foreman['ip'], true)
group_prefix: foo_group_prefix
keyed_groups:
- key: foreman['environment_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_') | regex_replace('none', '')
prefix: foo_group_prefixenvironment_
separator: ''
- key: foreman['location_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')
prefix: foo_group_prefixlocation_
separator: ''
- key: foreman['organization_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')
prefix: foo_group_prefixorganization_
separator: ''
- key: foreman['content_facet_attributes']['lifecycle_environment_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')
prefix: foo_group_prefixlifecycle_environment_
separator: ''
- key: foreman['content_facet_attributes']['content_view_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')
prefix: foo_group_prefixcontent_view_
separator: ''
- key: '"%s-%s-%s" | format(app, tier, color)'
separator: ''
- key: '"%s-%s" | format(app, color)'
separator: ''
legacy_hostvars: true
plugin: theforeman.foreman.foreman
validate_certs: false
want_facts: true
want_hostcollections: true
want_params: true

View File

@ -1,3 +0,0 @@
include_metadata: true
inventory_id: 42
plugin: awx.awx.tower

View File

@ -1,55 +0,0 @@
compose:
ansible_host: guest.ipAddress
ansible_ssh_host: guest.ipAddress
ansible_uuid: 99999999 | random | to_uuid
availablefield: availableField
configissue: configIssue
configstatus: configStatus
customvalue: customValue
effectiverole: effectiveRole
guestheartbeatstatus: guestHeartbeatStatus
layoutex: layoutEx
overallstatus: overallStatus
parentvapp: parentVApp
recenttask: recentTask
resourcepool: resourcePool
rootsnapshot: rootSnapshot
triggeredalarmstate: triggeredAlarmState
filters:
- config.zoo == "DC0_H0_VM0"
hostnames:
- config.foo
keyed_groups:
- key: config.asdf
prefix: ''
separator: ''
plugin: community.vmware.vmware_vm_inventory
properties:
- availableField
- configIssue
- configStatus
- customValue
- datastore
- effectiveRole
- guestHeartbeatStatus
- layout
- layoutEx
- name
- network
- overallStatus
- parentVApp
- permission
- recentTask
- resourcePool
- rootSnapshot
- snapshot
- triggeredAlarmState
- value
- capability
- config
- guest
- runtime
- storage
- summary
strict: false
with_nested_properties: true

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import pytest
import json
from unittest import mock
from django.core.exceptions import ValidationError
@ -8,8 +9,6 @@ from awx.api.versioning import reverse
from awx.main.models import InventorySource, Inventory, ActivityStream
import json
@pytest.fixture
def scm_inventory(inventory, project):
@ -457,6 +456,56 @@ def test_inventory_source_vars_prohibition(post, inventory, admin_user):
assert 'FOOBAR' in r.data['source_vars'][0]
@pytest.mark.django_db
@pytest.mark.parametrize('source,source_var_actual,source_var_expected,description', [
('ec2', {'plugin': 'blah'}, {'plugin': 'amazon.aws.aws_ec2'}, 'source plugin mismatch'),
('ec2', {'plugin': 'amazon.aws.aws_ec2'}, {'plugin': 'amazon.aws.aws_ec2'}, 'valid plugin'),
])
def test_inventory_source_vars_source_plugin_ok(post, inventory, admin_user, source, source_var_actual, source_var_expected, description):
r = post(reverse('api:inventory_source_list'),
{'name': 'new inv src', 'source_vars': json.dumps(source_var_actual), 'inventory': inventory.pk, 'source': source},
admin_user, expect=201)
assert r.data['source_vars'] == json.dumps(source_var_expected)
@pytest.mark.django_db
@pytest.mark.parametrize('source_var_actual,description', [
({'plugin': 'namespace.collection.script'}, 'valid scm user plugin'),
])
def test_inventory_source_vars_source_plugin_scm_ok(post, inventory, admin_user, project, source_var_actual, description):
r = post(reverse('api:inventory_source_list'),
{'name': 'new inv src',
'source_vars': json.dumps(source_var_actual),
'inventory': inventory.pk,
'source': 'scm',
'source_project': project.id,},
admin_user, expect=201)
assert r.data['source_vars'] == json.dumps(source_var_actual)
@pytest.mark.django_db
@pytest.mark.parametrize('source_var_actual,err_msg,description', [
({'foo': 'bar'}, 'plugin: must be present and of the form namespace.collection.inv_plugin', 'no plugin line'),
({'plugin': ''}, 'plugin: must be of the form namespace.collection.inv_plugin', 'blank plugin line'),
({'plugin': '.'}, 'plugin: must be of the form namespace.collection.inv_plugin', 'missing namespace, collection name, and inventory plugin'),
({'plugin': 'a.'}, 'plugin: must be of the form namespace.collection.inv_plugin', 'missing collection name and inventory plugin'),
({'plugin': 'a.b'}, 'plugin: must be of the form namespace.collection.inv_plugin', 'missing inventory plugin'),
({'plugin': 'a.b.'}, 'plugin: must be of the form namespace.collection.inv_plugin', 'missing inventory plugin'),
])
def test_inventory_source_vars_source_plugin_scm_invalid(post, inventory, admin_user, project, source_var_actual, err_msg, description):
r = post(reverse('api:inventory_source_list'),
{'name': 'new inv src',
'source_vars': json.dumps(source_var_actual),
'inventory': inventory.pk,
'source': 'scm',
'source_project': project.id,},
admin_user, expect=400)
assert err_msg in r.data['source_vars'][0]
@pytest.mark.django_db
@pytest.mark.parametrize('role,expect', [
('admin_role', 200),
@ -522,7 +571,8 @@ class TestInventorySourceCredential:
data={
'inventory': inventory.pk, 'name': 'fobar', 'source': 'scm',
'source_project': project.pk, 'source_path': '',
'credential': vault_credential.pk
'credential': vault_credential.pk,
'source_vars': 'plugin: a.b.c',
},
expect=400,
user=admin_user
@ -561,7 +611,7 @@ class TestInventorySourceCredential:
data={
'inventory': inventory.pk, 'name': 'fobar', 'source': 'scm',
'source_project': project.pk, 'source_path': '',
'credential': os_cred.pk
'credential': os_cred.pk, 'source_vars': 'plugin: a.b.c',
},
expect=201,
user=admin_user
@ -636,8 +686,14 @@ class TestControlledBySCM:
assert scm_inventory.inventory_sources.count() == 0
def test_adding_inv_src_ok(self, post, scm_inventory, project, admin_user):
post(reverse('api:inventory_inventory_sources_list', kwargs={'pk': scm_inventory.id}),
{'name': 'new inv src', 'source_project': project.pk, 'update_on_project_update': False, 'source': 'scm', 'overwrite_vars': True},
post(reverse('api:inventory_inventory_sources_list',
kwargs={'pk': scm_inventory.id}),
{'name': 'new inv src',
'source_project': project.pk,
'update_on_project_update': False,
'source': 'scm',
'overwrite_vars': True,
'source_vars': 'plugin: a.b.c'},
admin_user, expect=201)
def test_adding_inv_src_prohibited(self, post, scm_inventory, project, admin_user):
@ -657,7 +713,7 @@ class TestControlledBySCM:
def test_adding_inv_src_without_proj_access_prohibited(self, post, project, inventory, rando):
inventory.admin_role.members.add(rando)
post(reverse('api:inventory_inventory_sources_list', kwargs={'pk': inventory.id}),
{'name': 'new inv src', 'source_project': project.pk, 'source': 'scm', 'overwrite_vars': True},
{'name': 'new inv src', 'source_project': project.pk, 'source': 'scm', 'overwrite_vars': True, 'source_vars': 'plugin: a.b.c'},
rando, expect=403)

View File

@ -2,7 +2,6 @@
import pytest
from unittest import mock
import json
from django.core.exceptions import ValidationError
@ -259,30 +258,19 @@ class TestInventorySourceInjectors:
injector = InventorySource.injectors[source]('2.7.7')
assert injector.filename == filename
def test_group_by_azure(self):
injector = InventorySource.injectors['azure_rm']('2.9')
inv_src = InventorySource(
name='azure source', source='azure_rm',
source_vars={'group_by_os_family': True}
)
group_by_on = injector.inventory_as_dict(inv_src, '/tmp/foo')
# suspicious, yes, that is just what the script did
expected_groups = 6
assert len(group_by_on['keyed_groups']) == expected_groups
inv_src.source_vars = json.dumps({'group_by_os_family': False})
group_by_off = injector.inventory_as_dict(inv_src, '/tmp/foo')
# much better, everyone should turn off the flag and live in the future
assert len(group_by_off['keyed_groups']) == expected_groups - 1
def test_tower_plugin_named_url(self):
injector = InventorySource.injectors['tower']('2.9')
inv_src = InventorySource(
name='my tower source', source='tower',
# named URL pattern "inventory++organization"
instance_filters='Designer hair 읰++Cosmetic_products䵆'
)
result = injector.inventory_as_dict(inv_src, '/tmp/foo')
assert result['inventory_id'] == 'Designer%20hair%20%EC%9D%B0++Cosmetic_products%E4%B5%86'
@pytest.mark.parametrize('source,proper_name', [
('ec2', 'amazon.aws.aws_ec2'),
('openstack', 'openstack.cloud.openstack'),
('gce', 'google.cloud.gcp_compute'),
('azure_rm', 'azure.azcollection.azure_rm'),
('vmware', 'community.vmware.vmware_vm_inventory'),
('rhv', 'ovirt.ovirt.ovirt'),
('satellite6', 'theforeman.foreman.foreman'),
('tower', 'awx.awx.tower'),
])
def test_plugin_proper_names(self, source, proper_name):
injector = InventorySource.injectors[source]('2.9')
assert injector.get_proper_name() == proper_name
@pytest.mark.django_db

View File

@ -14,69 +14,6 @@ from django.conf import settings
DATA = os.path.join(os.path.dirname(data.__file__), 'inventory')
TEST_SOURCE_FIELDS = {
'vmware': {
'instance_filters': '{{ config.name == "only_my_server" }},{{ somevar == "bar"}}',
'group_by': 'fouo'
},
'ec2': {
'instance_filters': 'foobaa',
# group_by selected to capture some non-trivial cross-interactions
'group_by': 'availability_zone,instance_type,tag_keys,region',
'source_regions': 'us-east-2,ap-south-1'
},
'gce': {
'source_regions': 'us-east4-a,us-west1-b' # surfaced as env var
},
'azure_rm': {
'source_regions': 'southcentralus,westus'
},
'tower': {
'instance_filters': '42'
}
}
INI_TEST_VARS = {
'ec2': {
'boto_profile': '/tmp/my_boto_stuff',
'iam_role_arn': 'arn:aws:iam::123456789012:role/test-role',
'hostname_variable': 'public_dns_name',
'destination_variable': 'public_dns_name'
},
'gce': {},
'openstack': {
'private': False,
'use_hostnames': False,
'expand_hostvars': True,
'fail_on_errors': True
},
'tower': {}, # there are none
'vmware': {
'alias_pattern': "{{ config.foo }}",
'host_filters': '{{ config.zoo == "DC0_H0_VM0" }}',
'groupby_patterns': "{{ config.asdf }}",
# setting VMWARE_VALIDATE_CERTS is duplicated with env var
},
'azure_rm': {
'use_private_ip': True,
'resource_groups': 'foo_resources,bar_resources',
'tags': 'Creator:jmarshall, peanutbutter:jelly'
},
'satellite6': {
'satellite6_group_patterns': '["{app}-{tier}-{color}", "{app}-{color}"]',
'satellite6_group_prefix': 'foo_group_prefix',
'satellite6_want_hostcollections': True,
'satellite6_want_ansible_ssh_host': True,
'satellite6_want_facts': True
},
'rhv': { # options specific to the plugin
'ovirt_insecure': False,
'groups': {
'dev': '"dev" in tags'
}
}
}
def generate_fake_var(element):
"""Given a credential type field element, makes up something acceptable.
@ -245,25 +182,21 @@ def create_reference_data(source_dir, env, content):
@pytest.mark.django_db
@pytest.mark.parametrize('this_kind', CLOUD_PROVIDERS)
def test_inventory_update_injected_content(this_kind, inventory, fake_credential_factory):
injector = InventorySource.injectors[this_kind]
if injector.plugin_name is None:
pytest.skip('Use of inventory plugin is not enabled for this source')
src_vars = dict(base_source_var='value_of_var')
if this_kind in INI_TEST_VARS:
src_vars.update(INI_TEST_VARS[this_kind])
extra_kwargs = {}
if this_kind in TEST_SOURCE_FIELDS:
extra_kwargs.update(TEST_SOURCE_FIELDS[this_kind])
src_vars['plugin'] = injector.get_proper_name()
inventory_source = InventorySource.objects.create(
inventory=inventory,
source=this_kind,
source_vars=src_vars,
**extra_kwargs
)
inventory_source.credentials.add(fake_credential_factory(this_kind))
inventory_update = inventory_source.create_unified_job()
task = RunInventoryUpdate()
if InventorySource.injectors[this_kind].plugin_name is None:
pytest.skip('Use of inventory plugin is not enabled for this source')
def substitute_run(envvars=None, **_kw):
"""This method will replace run_pexpect
instead of running, it will read the private data directory contents
@ -274,6 +207,12 @@ def test_inventory_update_injected_content(this_kind, inventory, fake_credential
assert envvars.pop('ANSIBLE_INVENTORY_ENABLED') == 'auto'
set_files = bool(os.getenv("MAKE_INVENTORY_REFERENCE_FILES", 'false').lower()[0] not in ['f', '0'])
env, content = read_content(private_data_dir, envvars, inventory_update)
# Assert inventory plugin inventory file is in private_data_dir
inventory_filename = InventorySource.injectors[inventory_update.source]('2.9').filename
assert len([True for k in content.keys() if k.endswith(inventory_filename)]) > 0, \
f"'{inventory_filename}' file not found in inventory update runtime files {content.keys()}"
env.pop('ANSIBLE_COLLECTIONS_PATHS', None) # collection paths not relevant to this test
base_dir = os.path.join(DATA, 'plugins')
if not os.path.exists(base_dir):
@ -283,6 +222,8 @@ def test_inventory_update_injected_content(this_kind, inventory, fake_credential
create_reference_data(source_dir, env, content)
pytest.skip('You set MAKE_INVENTORY_REFERENCE_FILES, so this created files, unset to run actual test.')
else:
source_dir = os.path.join(base_dir, this_kind) # this_kind is a global
if not os.path.exists(source_dir):
raise FileNotFoundError(
'Maybe you never made reference files? '
@ -292,9 +233,6 @@ def test_inventory_update_injected_content(this_kind, inventory, fake_credential
expected_file_list = os.listdir(files_dir)
except FileNotFoundError:
expected_file_list = []
assert set(expected_file_list) == set(content.keys()), (
'Inventory update runtime environment does not have expected files'
)
for f_name in expected_file_list:
with open(os.path.join(files_dir, f_name), 'r') as f:
ref_content = f.read()

View File

@ -72,23 +72,6 @@ def test_invalid_kind_clean_insights_credential():
assert json.dumps(str(e.value)) == json.dumps(str([u'Assignment not allowed for Smart Inventory']))
@pytest.mark.parametrize('source_vars,validate_certs', [
({'ssl_verify': True}, True),
({'ssl_verify': False}, False),
({'validate_certs': True}, True),
({'validate_certs': False}, False)])
def test_satellite_plugin_backwards_support_for_ssl_verify(source_vars, validate_certs):
injector = InventorySource.injectors['satellite6']('2.9')
inv_src = InventorySource(
name='satellite source', source='satellite6',
source_vars=source_vars
)
ret = injector.inventory_as_dict(inv_src, '/tmp/foo')
assert 'validate_certs' in ret
assert ret['validate_certs'] in (validate_certs, str(validate_certs))
class TestControlledBySCM():
def test_clean_source_path_valid(self):
inv_src = InventorySource(source_path='/not_real/',

View File

@ -8,8 +8,6 @@ from datetime import timedelta
# global settings
from django.conf import global_settings
# ugettext lazy
from django.utils.translation import ugettext_lazy as _
# Update this module's local settings from the global settings module.
this_module = sys.modules[__name__]