mirror of
https://github.com/ansible/awx.git
synced 2026-04-16 07:20:19 -02:30
prevent field lookups on Host.ansible_facts keys (it doesn't work)
under the hood, Host.ansible_facts is a postgres jsonb field which
performs match operations using the JSON containment operator (@>)
this operator _only_ works on exact matches on containment (i.e.,
"does the `ansible_distribution` jsonb value contain _this exact_ JSON
structure"):
SELECT ...
FROM main_host
WHERE ansible_facts @> '{"ansible_distribution": "centos"}'
SELECT ...
FROM main_host
WHERE ansible_facts @> '{"packages": {"dnsmasq": [{"version": 2}]}}'
postgres does _not_ expose any operator for fuzzy or lookup-based
matches with this operator, so host filter values like these don't
really make sense (postgres can't _filter_ in the way intended in these
examples):
ansible_distribution__startswith=\"Cent\"
ansible_distribution__icontains=\"CentOS\"
ansible_facts__packages__dnsmasq[]__version__startswith=\"2\"
This commit is contained in:
@@ -47,7 +47,7 @@ from awx.main.constants import (
|
||||
)
|
||||
from awx.main.models import * # noqa
|
||||
from awx.main.models.base import NEW_JOB_TYPE_CHOICES
|
||||
from awx.main.fields import ImplicitRoleField
|
||||
from awx.main.fields import ImplicitRoleField, JSONBField
|
||||
from awx.main.utils import (
|
||||
get_type_for_model, get_model_for_type, timestamp_apiformat,
|
||||
camelcase_to_underscore, getattrd, parse_yaml_or_json,
|
||||
@@ -1542,6 +1542,18 @@ class InventorySerializer(BaseSerializerWithVariables):
|
||||
def validate_host_filter(self, host_filter):
|
||||
if host_filter:
|
||||
try:
|
||||
for match in JSONBField.get_lookups().keys():
|
||||
if match == 'exact':
|
||||
# __exact is allowed
|
||||
continue
|
||||
match = '__{}'.format(match)
|
||||
if re.match(
|
||||
'ansible_facts[^=]+{}='.format(match),
|
||||
host_filter
|
||||
):
|
||||
raise models.base.ValidationError({
|
||||
'host_filter': 'ansible_facts does not support searching with {}'.format(match)
|
||||
})
|
||||
SmartFilter().query_from_string(host_filter)
|
||||
except RuntimeError as e:
|
||||
raise models.base.ValidationError(e)
|
||||
|
||||
Reference in New Issue
Block a user