[openstack-dev] [heat][yaql] Deep merge map of lists?

Steven Hardy shardy at redhat.com
Mon Aug 29 13:16:01 UTC 2016


On Mon, Aug 29, 2016 at 07:07:09AM +0200, Thomas Herve wrote:
> On Sun, Aug 28, 2016 at 11:58 PM, Steven Hardy <shardy at redhat.com> wrote:
> > Hi all,
> >
> > I have a need to merge a list of maps of lists:
> >
> > heat_template_version: 2016-10-14
> >
> > outputs:
> >   debug:
> >     value:
> >       yaql:
> >         # dict(vms=>dict($.vms.select([$.name, $])))
> >         expression: dict($.data.l.select([$.keys().toList()[0],
> > $.values().toList()[0]]))
> >         data:
> >           l:
> >             - a: [123]
> >             - b: [123]
> >             - a: [456]
> >
> >
> >
> > I want to end up with debug as:
> >
> >   a: [123, 456]
> >   b: [123]
> >
> > Perhaps we need a map_deep_merge function, but can this be done with yaql?
> >
> > I suspect it can, but can't currently figure out how the assignment to the
> > intermediate "a" value is supposed to work, any ideas on the cleanest
> > approach appreciated!
> 
> I believe you don't need the intermediate value, and can rely on what
> you'd do in Python with setdefault:
> 
> dict($.groupBy($.keys().toList()[0], $.values().toList()[0][0]))
> 
> ought to work, I believe?

So, as it turns out, my example above was bad, and groupBy only works if
you have a list of maps with exactly one key, we actually need this:

  # Example of tripleo format
  # We need an output of
  # "gnocchi_metricd_node_names": ["overcloud-controller-0"]
  # "tripleo_packages_node_names": ["overcloud-controller-0", "overcloud-compute-0"]
  # "nova_compute_node_names": ["overcloud-compute-0"]
  debug_tripleo:
    value:
      yaql:
        expression: dict($.data.l.groupBy($.keys().toList()[0], $.values().toList()[0][0]))
        data:
          l:
            - "gnocchi_metricd_node_names": ["overcloud-controller-0"]
              "tripleo_packages_node_names": ["overcloud-controller-0"]
            - "nova_compute_node_names": ["overcloud-compute-0"]
              "tripleo_packages_node_names": ["overcloud-compute-0"]

So, I'm back to wondering how we make the intermediate assignement of tripleo_packages_node_names

Thanks for the ideas - I think this probably does highlight the value of a map_deep_merge function
so perhaps that's something we can consider for ocata :)

Thanks!

Steve



More information about the OpenStack-dev mailing list