mirror of
https://github.com/ansible/awx.git
synced 2026-05-14 12:57:40 -02:30
Refactor Host manager and dynamic Inventory tests and update
validation/serialization
This commit is contained in:
@@ -45,6 +45,8 @@ from awx.main.fields import ImplicitRoleField
|
|||||||
from awx.main.utils import (
|
from awx.main.utils import (
|
||||||
get_type_for_model, get_model_for_type, timestamp_apiformat,
|
get_type_for_model, get_model_for_type, timestamp_apiformat,
|
||||||
camelcase_to_underscore, getattrd, parse_yaml_or_json)
|
camelcase_to_underscore, getattrd, parse_yaml_or_json)
|
||||||
|
from awx.main.utils.filters import DynamicFilter
|
||||||
|
|
||||||
from awx.main.validators import vars_validate_or_raise
|
from awx.main.validators import vars_validate_or_raise
|
||||||
|
|
||||||
from awx.conf.license import feature_enabled
|
from awx.conf.license import feature_enabled
|
||||||
@@ -1113,7 +1115,7 @@ class InventorySerializer(BaseSerializerWithVariables):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Inventory
|
model = Inventory
|
||||||
fields = ('*', 'organization', 'variables', 'has_active_failures',
|
fields = ('*', 'organization', 'kind', 'host_filter', 'variables', 'has_active_failures',
|
||||||
'total_hosts', 'hosts_with_active_failures', 'total_groups',
|
'total_hosts', 'hosts_with_active_failures', 'total_groups',
|
||||||
'groups_with_active_failures', 'has_inventory_sources',
|
'groups_with_active_failures', 'has_inventory_sources',
|
||||||
'total_inventory_sources', 'inventory_sources_with_failures')
|
'total_inventory_sources', 'inventory_sources_with_failures')
|
||||||
@@ -1145,6 +1147,17 @@ class InventorySerializer(BaseSerializerWithVariables):
|
|||||||
ret['organization'] = None
|
ret['organization'] = None
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
kind = attrs.get('kind', 'standard')
|
||||||
|
if kind == 'dynamic':
|
||||||
|
host_filter = attrs.get('host_filter')
|
||||||
|
if host_filter is not None:
|
||||||
|
try:
|
||||||
|
DynamicFilter().query_from_string(host_filter)
|
||||||
|
except RuntimeError, e:
|
||||||
|
raise models.base.ValidationError(e)
|
||||||
|
return super(InventorySerializer, self).validate(attrs)
|
||||||
|
|
||||||
|
|
||||||
class InventoryDetailSerializer(InventorySerializer):
|
class InventoryDetailSerializer(InventorySerializer):
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ from awx.main.utils import * # noqa
|
|||||||
from awx.main.utils import (
|
from awx.main.utils import (
|
||||||
callback_filter_out_ansible_extra_vars
|
callback_filter_out_ansible_extra_vars
|
||||||
)
|
)
|
||||||
|
from awx.main.utils.filters import DynamicFilter
|
||||||
|
|
||||||
from awx.api.permissions import * # noqa
|
from awx.api.permissions import * # noqa
|
||||||
from awx.api.renderers import * # noqa
|
from awx.api.renderers import * # noqa
|
||||||
from awx.api.serializers import * # noqa
|
from awx.api.serializers import * # noqa
|
||||||
@@ -79,7 +81,6 @@ from awx.api.metadata import RoleMetadata
|
|||||||
from awx.main.consumers import emit_channel_notification
|
from awx.main.consumers import emit_channel_notification
|
||||||
from awx.main.models.unified_jobs import ACTIVE_STATES
|
from awx.main.models.unified_jobs import ACTIVE_STATES
|
||||||
from awx.main.scheduler.tasks import run_job_complete
|
from awx.main.scheduler.tasks import run_job_complete
|
||||||
from awx.main.querysets import DynamicFilterQuerySet
|
|
||||||
|
|
||||||
logger = logging.getLogger('awx.api.views')
|
logger = logging.getLogger('awx.api.views')
|
||||||
|
|
||||||
@@ -1764,10 +1765,10 @@ class HostList(ListCreateAPIView):
|
|||||||
capabilities_prefetch = ['inventory.admin']
|
capabilities_prefetch = ['inventory.admin']
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = DynamicFilterQuerySet(HostList, using=self._db)
|
qs = super(HostList, self).get_queryset()
|
||||||
filter_string = self.request.query_params.get('host_filter', None)
|
filter_string = self.request.query_params.get('host_filter', None)
|
||||||
if filter_string:
|
if filter_string:
|
||||||
filter_q = qs.query_from_string(filter_string)
|
filter_q = DynamicFilter.query_from_string(filter_string)
|
||||||
qs = qs.filter(filter_q)
|
qs = qs.filter(filter_q)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class HostManager(models.Manager):
|
|||||||
set. Use the `host_filter` to generate the queryset for the hosts.
|
set. Use the `host_filter` to generate the queryset for the hosts.
|
||||||
"""
|
"""
|
||||||
qs = super(HostManager, self).get_queryset()
|
qs = super(HostManager, self).get_queryset()
|
||||||
if self.instance is not None:
|
if hasattr(self, 'instance') and self.instance is not None:
|
||||||
if hasattr(self.instance, 'kind') and self.instance.kind == 'dynamic':
|
if hasattr(self.instance, 'kind') and self.instance.kind == 'dynamic':
|
||||||
if hasattr(self.instance, 'host_filter') and self.instance.host_filter is not None:
|
if hasattr(self.instance, 'host_filter') and self.instance.host_filter is not None:
|
||||||
q = DynamicFilter.query_from_string(self.instance.host_filter)
|
q = DynamicFilter.query_from_string(self.instance.host_filter)
|
||||||
|
|||||||
@@ -37,11 +37,8 @@ class TestSCMUpdateFeatures:
|
|||||||
assert not mck_update.called
|
assert not mck_update.called
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.fixture
|
||||||
def test_host_objects_manager(organization):
|
def setup_ec2_gce(organization):
|
||||||
dynamic_inventory = Inventory(organization=organization, name='dynamic', host_filter='inventory_sources__source=ec2')
|
|
||||||
dynamic_inventory.save()
|
|
||||||
|
|
||||||
ec2_inv = Inventory(name='test_ec2', organization=organization)
|
ec2_inv = Inventory(name='test_ec2', organization=organization)
|
||||||
ec2_inv.save()
|
ec2_inv.save()
|
||||||
|
|
||||||
@@ -59,7 +56,35 @@ def test_host_objects_manager(organization):
|
|||||||
gce_host.inventory_sources.add(gce_source)
|
gce_host.inventory_sources.add(gce_source)
|
||||||
gce_inv.save()
|
gce_inv.save()
|
||||||
|
|
||||||
hosts = dynamic_inventory.hosts.all()
|
|
||||||
assert len(hosts) == 2
|
@pytest.mark.django_db
|
||||||
assert hosts[0].inventory_sources.first() == ec2_source
|
class TestHostManager:
|
||||||
assert hosts[1].inventory_sources.first() == ec2_source
|
def test_host_filter_change(self, setup_ec2_gce, organization):
|
||||||
|
dynamic_inventory = Inventory(name='dynamic',
|
||||||
|
kind='dynamic',
|
||||||
|
organization=organization,
|
||||||
|
host_filter='inventory_sources__source=ec2')
|
||||||
|
dynamic_inventory.save()
|
||||||
|
assert len(dynamic_inventory.hosts.all()) == 2
|
||||||
|
|
||||||
|
dynamic_inventory.host_filter = 'inventory_sources__source=gce'
|
||||||
|
dynamic_inventory.save()
|
||||||
|
assert len(dynamic_inventory.hosts.all()) == 1
|
||||||
|
|
||||||
|
def test_host_filter_not_dynamic(self, setup_ec2_gce, organization):
|
||||||
|
dynamic_inventory = Inventory(name='dynamic',
|
||||||
|
organization=organization,
|
||||||
|
host_filter='inventory_sources__source=ec2')
|
||||||
|
assert len(dynamic_inventory.hosts.all()) == 0
|
||||||
|
|
||||||
|
def test_host_objects_manager(self, setup_ec2_gce, organization):
|
||||||
|
dynamic_inventory = Inventory(kind='dynamic',
|
||||||
|
name='dynamic',
|
||||||
|
organization=organization,
|
||||||
|
host_filter='inventory_sources__source=ec2')
|
||||||
|
dynamic_inventory.save()
|
||||||
|
|
||||||
|
hosts = dynamic_inventory.hosts.all()
|
||||||
|
assert len(hosts) == 2
|
||||||
|
assert hosts[0].inventory_sources.first().source == 'ec2'
|
||||||
|
assert hosts[1].inventory_sources.first().source == 'ec2'
|
||||||
|
|||||||
Reference in New Issue
Block a user