Skip to content

Instantly share code, notes, and snippets.

@thomasem
Last active March 13, 2017 14:46
# Host 13 is parent to Host 14, so set variable - thomas:foo
$ http PUT http://127.0.0.1:8080/v1/hosts/13/variables content-type:application/json x-auth-token:demo_root x-auth-user:demo_root x-auth-project:b9f10eca66ac4c279c139d01e65f96b4 thomas=foo
{
"variables": {
"thomas": "foo"
}
}
# Host 14 is child to Host 13, so override "thomas" with value "baz"
$ http PUT http://127.0.0.1:8080/v1/hosts/14/variables content-type:application/json x-auth-token:demo_root x-auth-user:demo_root x-auth-project:b9f10eca66ac4c279c139d01e65f96b4 thomas=baz
{
"variables": {
"thomas": "baz"
}
}
# Now query for only thomas:foo, and we get both Host 13 and 14, which is incorrect:
$ http "http://127.0.0.1:8080/v1/hosts?details=all&vars=thomas:foo" content-type:application/json x-auth-token:demo_root x-auth-user:demo_root x-auth-project:b9f10eca66ac4c279c139d01e65f96b4
{
"hosts": [
{
"active": true,
"cell_id": 2,
"cloud_id": 1,
"created_at": "2017-03-13T13:57:20.000000",
"device_type": "server",
"id": 13,
"ip_address": "192.168.1.10",
"links": [
{
"href": "http://127.0.0.1:8080/v1/network-devices/10",
"rel": "up"
}
],
"name": "host1.ORD135.C0002.C-1.example1.com",
"note": null,
"parent_id": 10,
"project_id": "b9f10eca-66ac-4c27-9c13-9d01e65f96b4",
"region_id": 1,
"updated_at": null,
"variables": {
"cell_capabilities": "flavor_classes=performance1",
"console_host": "10.20.1.100",
"glance_default_store": "swift",
"neutron_l2_population": true,
"nova_console_type": "novnc",
"openstack_release": "juno",
"tempest_public_subnet_cidr": "192.168.1.0/22",
"thomas": "foo"
}
},
{
"active": true,
"cell_id": 2,
"cloud_id": 1,
"created_at": "2017-03-13T13:57:21.000000",
"device_type": "container",
"id": 14,
"ip_address": "172.0.0.7",
"links": [
{
"href": "http://127.0.0.1:8080/v1/hosts/13",
"rel": "up"
}
],
"name": "container_host1.ORD135.C0002.C-1.example1.com",
"note": null,
"parent_id": 13,
"project_id": "b9f10eca-66ac-4c27-9c13-9d01e65f96b4",
"region_id": 1,
"updated_at": null,
"variables": {
"cell_capabilities": "flavor_classes=performance1",
"console_host": "10.20.1.100",
"glance_default_store": "swift",
"neutron_l2_population": true,
"nova_console_type": "novnc",
"openstack_release": "juno",
"tempest_public_subnet_cidr": "192.168.1.0/22",
"thomas": "baz"
}
}
],
"links": [
{
"href": "http://127.0.0.1:8080/v1/hosts?details=True&sort_keys=created_at%2Cid&resolved-values=True&vars=thomas%3Afoo&sort_dir=asc&limit=30",
"rel": "first"
},
{
"href": "http://127.0.0.1:8080/v1/hosts?details=True&sort_keys=created_at%2Cid&resolved-values=True&vars=thomas%3Afoo&sort_dir=asc&limit=30",
"rel": "prev"
},
{
"href": "http://127.0.0.1:8080/v1/hosts?details=True&sort_keys=created_at%2Cid&resolved-values=True&vars=thomas%3Afoo&sort_dir=asc&limit=30",
"rel": "self"
},
{
"href": "http://127.0.0.1:8080/v1/hosts?details=True&sort_keys=created_at%2Cid&resolved-values=True&vars=thomas%3Afoo&sort_dir=asc&marker=14&limit=30",
"rel": "next"
}
]
}
@thomasem
Copy link
Author

diff --git a/craton/db/sqlalchemy/api.py b/craton/db/sqlalchemy/api.py
index da0c68a..aa126b4 100644
--- a/craton/db/sqlalchemy/api.py
+++ b/craton/db/sqlalchemy/api.py
@@ -189,11 +189,18 @@ def _matching_resources(query, resource_cls, get_descendants, kv):
             ((models.Variable.key == k) & (models.Variable.value == v)))
     q = q.filter(or_(*or_clauses))

-    for variable in q:
+    variables = set(q)
+    for variable in variables:
         match = matches[(variable.key, variable.value)]
         if isinstance(variable.parent, resource_cls):
             match.add(variable.parent)
-        match.update(get_descendants(variable.parent))
+        for descendant in get_descendants(variable.parent):
+            for level in descendant.resolution_order:
+                desc_variable = level._variables.get(variable.key)
+                if desc_variable is not None:
+                    if desc_variable in variables:
+                        match.add(descendant)
+                    break

     # NOTE(jimbaker) For now, we simply match for the conjunction
     # ("and") of all the supplied kv pairs we are matching

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment