hot needs a better select

Registered by Angus Salkeld

In cfn we have "Fn::Select", but it is very messy in retrieving data from nested json.
Like server addresses. We need something like jsonpath (http://goessner.net/articles/JsonPath/).

Blueprint information

Status:
Complete
Approver:
Steve Baker
Priority:
Medium
Drafter:
Steve Baker
Direction:
Approved
Assignee:
Pablo Andres Fuente
Definition:
Approved
Series goal:
Accepted for icehouse
Implementation:
Implemented
Milestone target:
milestone icon 2014.1
Started by
Pablo Andres Fuente
Completed by
Steve Baker

Related branches

Sprints

Whiteboard

Some use cases:

Provide a specific item out of a complex resource attribute as output, e.g. network address information in Server resource is complex data but we often want one item (the IP address).

Access a specific item in a parameter of a template (in case we open up HOT to allow not only simple data types for parameters).

One idea how this could be solved:
Introduce an additional, optional parameter to the get_attr function to select a specific item based on jsonpath expression.
Do the same for the get_param function for complex template parameters.

(stevebaker) Like the get_attr, get_param suggestion above, but instead of jsonpath allow extra arguments where values will traverse whatever data is returned by dict key or list index.

For example, here is an important use case, getting an IP address for a server on a given network, the name of which sometimes needs to be passed in as a template parameter:

when the network name is stable, and always known:
get_attr:
- my_server
- networks
- public
- 0

or if the network name is something other than public:
get_attr:
- my_server
- networks
- get_param: my_network_name
- 0

This would be less confusing than jsonpath since some resource attributes already have dots in their names

(therve) I don't really like the get_attr proposal. First it mixes attributes retrieval and index retrieval, but the function is still called get_attr. Second, it puts the object at the same layer as the attributes, thus making hard to read the difference above between my_server, networks and public. It's also worth mentioning that python getattr 3rd argument is the default value.

(pafuent) IMHO the get_attr syntax is clearer to read and could be easily embedd in big/complex resources. But (therve) has good points about that could be confusing if no one explain to you get_attr. So I have another proposal:
  select:
    resource: my_resource
    attribute: an_attribute
    traverse: [nested_list, 0, nested_attribute]

The only thing that I don't like about this syntax is that is bigger than get_attr syntax

Another option is one that proposed (jasond) on IRC: the attribute parameter could use dot notation to provide the idea of traversal.
  {get_attr: [my_resource, nested_list.0.nested_attribute]}
Regarding to this, (stevebaker) said that some resource attributes had dots in their names, so could be confusing.

(thomas-spatzier) If just using a list of addtional parameters in get_attr is not enough and we want to have some kind of select syntax, maybe we should really stick to something that exists out there like http://goessner.net/articles/JsonPath/ instead of coming up with our own notation?

(pafuent) Regarding to the dot-notation (jasond) said this in a review comment:
  I'd prefer dot-notation. Regarding your comment from the blueprint:
  "This would be less confusing than jsonpath since some resource attributes already have dots in their names"
  Wouldn't it be less confusing (from the user's perspective) if it used the same notation that ResourceGroup uses? Currently, a user can access a specific resource in a ResourceGroup using:
  {get_attr: [wordpress_group.resource.0, addresses]}

  So accessing the private IP would look like:
  {get_attr: [wordpress_group.resource.0, addresses.private.addr.0]}

(stevebaker) I don't think dot notation is better than what this change proposes, for these reasons:
* its another thing that has to be parsed, why not represent it in a parsed format already?
* we already have multiple resources which use dot notation in their attributes, so we'd have to escape those
* see the commit message for the get_param: my_network_name example. The only way I can see of doing dynamic paths in dot notation is with a str_replace - this is really not a nice user experience.

(jasond)
> * its another thing that has to be parsed, why not represent it in a parsed format already?
I don't think this should be considered. A more complex implementation would be worth the effort if it results in a more consistent user experience.

> * we already have multiple resources which use dot notation in their attributes, so we'd have to escape those
Maybe dot notation wasn't the best choice in those other resources. If we use a list here, shouldn't we also use a list to access the other resource attributes to make the user experience consistent?

> * see the commit message for the get_param: my_network_name example. The only way I can see of doing dynamic paths in dot notation is with a str_replace - this is really not a nice user experience.
Good point. This seems like a reason to never use dot notation.

Gerrit topic: https://review.openstack.org/#q,topic:bp/hot-select,n,z

Addressed by: https://review.openstack.org/67562
    HOT templates get_attr allows extra attributes

(zaneb) So the get_attr part is implemented, but there was a suggestion in the review comments to implement the same thing for get_param. So I'll set the status back to 'Good Progress' rather than close this blueprint.

Addressed by: https://review.openstack.org/70710
    HOT templates get_param allows extra attributes

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.