[openstack-dev] [heat][yaql] Deep merge map of lists?
Steven Hardy
shardy at redhat.com
Tue Aug 30 16:02:06 UTC 2016
On Tue, Aug 30, 2016 at 04:10:47PM +0200, Jiří Stránský wrote:
>
> On 30.8.2016 10:17, Steven Hardy wrote:
>
> <snip>
>
> > Yeah, that gets us closer, but we do need to handle more than one value
> > (list entry) per key, e.g:
> >
> > data:
> > l:
> > - "gnocchi_metricd_node_names": ["a0", "a1", "a2"]
> > "tripleo_packages_node_names": ["a0", "a1", "a2"]
> > - "nova_compute_node_names": ["b0"]
> > "tripleo_packages_node_names": ["b0"]
> >
> > Output needs to be like:
> >
> > "gnocchi_metricd_node_names": ["a0", "a1", "a2"]
> > "tripleo_packages_node_names": ["a0", "a1", "a2", "b0"]
> > "nova_compute_node_names": ["b0"]
> >
>
> Hoping this could do it:
>
> [stack at instack ~]$ cat yaq.yaml
> heat_template_version: 2016-10-14
>
> outputs:
> debug:
> value:
> yaql:
> expression: $.data.l.reduce($1.mergeWith($2))
> data:
> l:
> - "gnocchi_metricd_node_names": ["a0", "a1", "a2"]
> "tripleo_packages_node_names": ["a0", "a1", "a2"]
> - "nova_compute_node_names": ["b0"]
> "tripleo_packages_node_names": ["b0"]
Thanks for this!
Unfortunately I dont think it works with more than two list items:
debug_tripleo2:
value:
yaql:
expression: $.data.l.reduce($1.mergeWith($2))
data:
l:
- "gnocchi_metricd_node_names": ["overcloud-controller-0",
"overcloud-controller-1", "overcloud-controller-2"]
"tripleo_packages_node_names": ["overcloud-controller-0", "overcloud-controller-1", "overcloud-controller-2"]
- "nova_compute_node_names": ["overcloud-compute-0"]
"tripleo_packages_node_names": ["overcloud-compute-0"]
"tripleo_packages_node_names2": ["overcloud-compute-0"]
- "ceph_osd_node_names": ["overcloud-cephstorage-0"]
"tripleo_packages_node_names": ["overcloud-cephstorage-0"]
"tripleo_packages_node_names2": ["overcloud-cephstorage-0"]
$ heat output-show foo5 debug_tripleo2
stack output show" instead
Output error: can only concatenate tuple (not "list") to tuple
I've not dug too deeply yet, but assuming that's a yaql error vs a heat bug
it looks like it won't work.
However I did find an approach earler with therve which seems to do what is
needed:
debug_tripleo:
value:
yaql:
# $.selectMany($.items()).groupBy($[0], $[1][0])
# reduce($1 + $2)')
# dict($.selectMany($.items()).groupBy($[0], $[1], [$[0],
# $[1].flatten()]))
expression: dict($.data.l.selectMany($.items()).groupBy($[0], $[1],
[$[0], $[1].flatten()]))
data:
l:
- "gnocchi_metricd_node_names": ["overcloud-controller-0",
"overcloud-controller-1", "overcloud-controller-2"]
"tripleo_packages_node_names": ["overcloud-controller-0", "overcloud-controller-1", "overcloud-controller-2"]
"tripleo_packages_node_names2": ["overcloud-controller-0", "overcloud-controller-1", "overcloud-controller-2"]
- "nova_compute_node_names": ["overcloud-compute-0"]
"tripleo_packages_node_names": ["overcloud-compute-0"]
"tripleo_packages_node_names2": ["overcloud-compute-0"]
- "ceph_osd_node_names": ["overcloud-cephstorage-0"]
"tripleo_packages_node_names": ["overcloud-cephstorage-0"]
"tripleo_packages_node_names2": ["overcloud-cephstorage-0"]
Output:
$ heat output-show foo5 debug_tripleo
stack output show" instead
{
"gnocchi_metricd_node_names": [
"overcloud-controller-0",
"overcloud-controller-1",
"overcloud-controller-2"
],
"tripleo_packages_node_names": [
"overcloud-controller-0",
"overcloud-controller-1",
"overcloud-controller-2",
"overcloud-compute-0",
"overcloud-cephstorage-0"
],
"ceph_osd_node_names": [
"overcloud-cephstorage-0"
],
"tripleo_packages_node_names2": [
"overcloud-controller-0",
"overcloud-controller-1",
"overcloud-controller-2",
"overcloud-compute-0",
"overcloud-cephstorage-0"
],
"nova_compute_node_names": [
"overcloud-compute-0"
]
}
It's a bit complex, but I think it will work as a stopgap solution until we
can land a map_deep_merge function for heat (further yaql optimizations
welcome! :)
Thanks!
Steve
More information about the OpenStack-dev
mailing list