settingsLogin | Registersettings

[Openstack] HOT ResourceGroup index referencing with get_attr

0 votes

I'm trying to figure out a way to setup a [number of] 'OS::Neutron::LBaaS::PoolMember’
resource, from a list of IPs…

I’m setting up my initial resources like this:

—— s n i p ——
resources:
lbaas:
type: Turbo::LoadBalancer
properties:
name: { getparam: 'OS::stackname' }
network: { getparam: network }
protocol: TCP
port
nr: 8300
dnsname: consul

instance:
type: OS::Heat::ResourceGroup
properties:
count: { getparam: capacity }
resource
def:
type: Turbo::InstancePoolMember
properties:
name: { listjoin: ['-', [ { getparam: "OS::stackname"} ] ] }
image: { get
param: image }
poolid: { getattr: [lbaas, pool] }
portnr: { getattr: [lbaas, port] }
[etc]
—— s n i p ——

My “Turbo::LoadBalancer” is a [seriously] nested resource to setup
the LBaaS, Pool, Monitor, FloatingIP, DNS forward and reverse
resource and one listener (the “initial” one).

My "Turbo::InstancePoolMember” creates the instance(s) and adds
it/them to the listener created in the ‘lbaas’ resource.

This work just fine, took quite a while to get all that working in a
generic way. But it works.

However, this specific service (Hashicorps Consul) I’m trying to create
now needs additional listeners. Over all, I don’t “know” how many listeners
a service need, so the nested resources only create one (at least one
is required).

My plan/idea was then to create additional listeners and add the
‘instance’s created from/in the ‘instance’ resource above to that
listener in the HOT.

I can create the listener just fine (this creates a listener and
attaches a pool to that listener, then attaches the listener to the
LBaaS created above):

—— s n i p ——
listenertcp8301:
type: Turbo::LoadBalancerListener
properties:
name: { listjoin: ['-', [ { getparam: "OS::stackname"} ] ] }
lbaas: { get
attr: [lbaas, lbaas] }
protocol: TCP
port_nr: 8301
—— s n i p ——

However, creating the members have shown to be a lot more complicated:

—— s n i p ——
membertcp8301:
type: OS::Heat::ResourceGroup
properties:
count: { getparam: capacity }
resource
def:
type: OS::Neutron::LBaaS::PoolMember
properties:
protocolport: 8301
pool: { get
attr: [listenertcp8301, pool] }
address: { getattr: [instance, address, %index%] }
subnet: { get
attr: [instance, port_subnet, %index%] }
—— s n i p ——

(All resources in this mail is in one HOT, just referencing others, not
shown).

The problem is that

get_attr: [instance, address, %index%]

doesn't seem to work :(

This is what I’ve tried so far:

—— s n i p ——
address: { getattr: [instance, address, "%index%"] }
subnet: { get
attr: [instance, portsubnet, "%index%"] }
2017-03-11 21:22:42Z [member
tcp8301]: CREATEFAILED resources.membertcp8301: Property error: resources[1].properties.subnet: Value must be a string
2017-03-11 21:22:42Z [admin-consul]: CREATEFAILED Resource CREATE failed: resources.membertcp_8301: Property error: resources[1].properties.subnet: Value must be a string
—— s n i p ——

—— s n i p ——
address: { getattr: [instance, address.%index%] }
subnet: { get
attr: [instance, portsubnet.%index%] }
2017-03-11 23:31:35Z [admin-consul]: CREATE
FAILED Resource CREATE failed: The Referenced Attribute (0 port_subnet.%index%) is incorrect.
—— s n i p ——

—— s n i p ——
address: { getattr: [instance, %index%, address] }
subnet: { get
attr: [instance, %index%, portsubnet] }
found character '%' that cannot start any token
in "", line 71, column 43:
... address: { get
attr: [instance, %index%, address] }
—— s n i p ——

—— s n i p ——
address: { getattr: [instance, address, %index%] }
subnet: { get
attr: [instance, portsubnet, %index%] }
found character '%' that cannot start any token
in "", line 71, column 52:
... { get
attr: [instance, address, %index%] }
—— s n i p ——

—— s n i p ——
address: { getattr: [instance, address, { listjoin: ['', [ '', "%index%" ] ] } ] }
subnet: { getattr: [instance, portsubnet, { listjoin: ['', [ '', "%index%" ] ] } ] }
2017-03-12 00:32:56Z [member
tcp8301]: CREATEFAILED resources.membertcp8301: Property error: resources[1].properties.subnet: Value must be a string
2017-03-12 00:32:56Z [admin-consul]: CREATEFAILED Resource CREATE failed: resources.membertcp_8301: Property error: resources[1].properties.subnet: Value must be a string
—— s n i p ——

I didn’t really expect the last one to work, but I figured I try something that
would, in the shell, look like:

eval echo "$”${variable}

The first example here seems like it almost (?) worked, at least in
regards to the “address” field. Heat didn’t complain about that, only
on the “subnet” on the following line.

I’m sure that "[instance, port_subnet]” DO work, because I have two
outputs at the end of the HOT:

—— s n i p ——
outputs:
address:
value: { getattr: [instance, address] }
description: The IP address(es) of the server(s)
lbaas
internal:
value: { getattr: [lbaas, lbaasaddress] }
description: The (internal) IP address of the LBaaS
lbaasexternal:
value: { get
attr: [lbaas, address] }
description: The (external) IP address of the LBaaS
portsubnet:
value: { get
attr: [instance, port_subnet] }
description: The subnet ID(s) of the instance(s)
—— s n i p ——

and if/when I comment out the “membertcp8301” resource, I see
(in Horizon):

—— s n i p ——
port_subnet The subnet ID(s) of the instance(s)
[
"b776011f-0b72-4642-923e-935929dfb8f4",
"b776011f-0b72-4642-923e-935929dfb8f4",
"b776011f-0b72-4642-923e-935929dfb8f4"
]

lbaas_internal The (internal) IP address of the LBaaS
10.0.17.28

lbaas_external The (external) IP address of the LBaaS
10.0.6.11

address The IP address(es) of the server(s)
[
"10.0.17.25",
"10.0.17.32",
"10.0.17.26”
]
—— s n i p ——


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
asked Mar 12, 2017 in openstack by Turbo_Fredriksson (8,980 points)   7 13 19

8 Responses

0 votes

I have also had similar problems with %index% and have resolved these using an additional “child” resource where I use “%index%” as a parameter and within the child resource use { get_attr: [instance, address, index] }

/Lasse

On 2017-03-12, 13:28, "Turbo Fredriksson" turbo@bayour.com wrote:

I'm trying to figure out a way to setup a [number of] 'OS::Neutron::LBaaS::PoolMember’
resource, from a list of IPs…

I’m setting up my initial resources like this:

—— s n i p ——
resources:
  lbaas:
    type: Turbo::LoadBalancer
    properties:
      name: { get_param: 'OS::stack_name' }
      network: { get_param: network }
      protocol: TCP
      port_nr: 8300
      dnsname: consul

  instance:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: capacity }
      resource_def:
        type: Turbo::InstancePoolMember
        properties:
          name: { list_join: ['-', [ { get_param: "OS::stack_name"} ] ] }
          image: { get_param: image }
          pool_id: { get_attr: [lbaas, pool] }
          port_nr: { get_attr: [lbaas, port] }
          [etc]
—— s n i p ——

My “Turbo::LoadBalancer” is a [seriously] nested resource to setup
the LBaaS, Pool, Monitor, FloatingIP, DNS forward and reverse
resource and _one_ listener (the “initial” one).

My "Turbo::InstancePoolMember” creates the instance(s) _and_ adds
it/them to the listener created in the ‘lbaas’ resource.

This work just fine, took quite a while to get all that working in a
generic way. But it works.

However, this specific service (Hashicorps Consul) I’m trying to create
now needs additional listeners. Over all, I don’t “know” how many listeners
a service need, so the nested resources only create one (at least one
is required).

My plan/idea was then to create additional listeners and add the
‘instance’s created from/in the ‘instance’ resource above to that
listener in the HOT.

I can create the listener just fine (this creates a listener and
attaches a pool to that listener, then attaches the listener to the
LBaaS created above):

—— s n i p ——
  listener_tcp_8301:
    type: Turbo::LoadBalancerListener
    properties:
      name: { list_join: ['-', [ { get_param: "OS::stack_name"} ] ] }
      lbaas: { get_attr: [lbaas, lbaas] }
      protocol: TCP
      port_nr: 8301
—— s n i p ——

However, creating the members have shown to be a lot more complicated:

—— s n i p ——
  member_tcp_8301:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: capacity }
      resource_def:
        type: OS::Neutron::LBaaS::PoolMember
        properties:
          protocol_port: 8301
          pool: { get_attr: [listener_tcp_8301, pool] }
          address: { get_attr: [instance, address, %index%] }
          subnet: { get_attr: [instance, port_subnet, %index%] }
—— s n i p ——

(All resources in this mail is in _one_ HOT, just referencing others, not
shown).

The problem is that

  get_attr: [instance, address, %index%]

doesn't seem to work :(

This is what I’ve tried so far:

—— s n i p ——
address: { get_attr: [instance, address, "%index%"] }
subnet: { get_attr: [instance, port_subnet, "%index%"] }
2017-03-11 21:22:42Z [member_tcp_8301]: CREATE_FAILED  resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
2017-03-11 21:22:42Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
—— s n i p ——

—— s n i p ——
address: { get_attr: [instance, address.%index%] }
subnet: { get_attr: [instance, port_subnet.%index%] }
2017-03-11 23:31:35Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: The Referenced Attribute (0 port_subnet.%index%) is incorrect.
—— s n i p ——

—— s n i p ——
address: { get_attr: [instance, %index%, address] }
subnet: { get_attr: [instance, %index%, port_subnet] }
found character '%' that cannot start any token
  in "<unicode string>", line 71, column 43:
     ... address: { get_attr: [instance, %index%, address] }
—— s n i p ——

—— s n i p ——
address: { get_attr: [instance, address, %index%] }
subnet: { get_attr: [instance, port_subnet, %index%] }
found character '%' that cannot start any token
  in "<unicode string>", line 71, column 52:
     ... { get_attr: [instance, address, %index%] }
—— s n i p ——

—— s n i p ——
address: { get_attr: [instance, address, { list_join: ['', [ '', "%index%" ] ] } ] }
subnet: { get_attr: [instance, port_subnet, { list_join: ['', [ '', "%index%" ] ] } ] }
2017-03-12 00:32:56Z [member_tcp_8301]: CREATE_FAILED  resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
2017-03-12 00:32:56Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
—— s n i p ——

I didn’t really expect the last one to work, but I figured I try something that
would, in the shell, look like:

  eval echo "$”${variable}

The first example here seems like it almost (?) worked, at least in
regards to the “address” field. Heat didn’t complain about that, only
on the  “subnet” on the following line.

I’m sure that "[instance, port_subnet]” DO work, because I have two
outputs at the end of the HOT:

—— s n i p ——
outputs:
  address:
    value: { get_attr: [instance, address] }
    description: The IP address(es) of the server(s)
  lbaas_internal:
    value: { get_attr: [lbaas, lbaas_address] }
    description: The (internal) IP address of the LBaaS
  lbaas_external:
    value: { get_attr: [lbaas, address] }
    description: The (external) IP address of the LBaaS
  port_subnet:
    value: { get_attr: [instance, port_subnet] }
    description: The subnet ID(s) of the instance(s)
—— s n i p ——

and if/when I comment out the “member_tcp_8301” resource, I see
(in Horizon):

—— s n i p ——
port_subnet     The subnet ID(s) of the instance(s)
[
  "b776011f-0b72-4642-923e-935929dfb8f4",
  "b776011f-0b72-4642-923e-935929dfb8f4",
  "b776011f-0b72-4642-923e-935929dfb8f4"
]

lbaas_internal  The (internal) IP address of the LBaaS
10.0.17.28

lbaas_external  The (external) IP address of the LBaaS
10.0.6.11

address         The IP address(es) of the server(s)
[
  "10.0.17.25",
  "10.0.17.32",
  "10.0.17.26”
]
—— s n i p ——

_______________________________________________
Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to     : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
responded Mar 12, 2017 by Lars-Erik_Helander (560 points)   1 1
0 votes

On 12 Mar 2017, at 14:03, Lars-Erik Helander lars-erik.helander@proceranetworks.com wrote:

I have also had similar problems with %index% and have resolved these using an additional “child” resource where I use “%index%” as a parameter and within the child resource use { get_attr: [instance, address, index] }

So how do you pass on ‘%index%’ to that child?

Because I still need to “retrieve” the IP with get_attr so I can send it to the child..

Do you have an example I can look at?


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
responded Mar 12, 2017 by Turbo_Fredriksson (8,980 points)   7 13 19
0 votes

On 12 Mar 2017, at 14:50, Turbo Fredriksson turbo@bayour.com wrote:

So how do you pass on ‘%index%’ to that child?

Because I still need to “retrieve” the IP with get_attr so I can send it to the child..

Well, I could just send the whole ‘instance’ ID, and in the child retrieve it.

But I still can’t figure out how to “send” it to the child:

—— s n i p ——
membertcp8301:
type: OS::Heat::ResourceGroup
properties:
count: { getparam: capacity }
resource
def:
type: Turbo::LoadBalancerMember
properties:
index: %index%
instance: { getattr: [instance, instance] }
pool: { get
attr: [listenertcp8301, pool] }
port: 8301
—— s n i p ——

gives:

—— s n i p ——
found character '%' that cannot start any token
in "", line 71, column 18:
index: %index%
—— s n i p ——

This with a child like:

—— s n i p ——
heattemplateversion: 2015-04-30
description: Add an instance to a Loadbalancer pool listener.

parameters:
instance:
type: string
description: Instance ID of the instance to add to the listener.

pool:
type: string
description: Pool ID of the pool to add the instance to.

port:
type: string
description: Port number to forward from the listner to the instance.

index:
type: number
description: Index in address list to use

resources:
member:
type: OS::Neutron::LBaaS::PoolMember
properties:
address: { getattr: [{ getparam: instance }, address, index] }
subnet: { getattr: [{ getparam: subnet }, portsubnet, index] }
pool: { get
param: pool }
protocolport: { getparam: port }

outputs:
member:
value: { get_resource: member }
description: The member ID.
—— s n i p ——

responded Mar 12, 2017 by Turbo_Fredriksson (8,980 points)   7 13 19
0 votes

I think you need to pass %index% in a string, e.g.

        type: Turbo::LoadBalancerMember
        properties:
          index: “%index%”
          instance: { get_attr: [instance, instance] }
          pool: { get_attr: [listener_tcp_8301, pool] }

/Lasse

On 2017-03-12, 16:09, "Turbo Fredriksson" turbo@bayour.com wrote:

On 12 Mar 2017, at 14:50, Turbo Fredriksson <turbo@bayour.com> wrote:
> So how do you pass on ‘%index%’ to that child?
> 
> Because I still need to “retrieve” the IP with get_attr so I can send it to the child..
Well, I could just send the whole ‘instance’ ID, and in the child retrieve it.

But I still can’t figure out how to “send” it to the child:

—— s n i p ——
  member_tcp_8301:
    type: OS::Heat::ResourceGroup
    properties:
      count: { get_param: capacity }
      resource_def:
        type: Turbo::LoadBalancerMember
        properties:
          index: %index%
          instance: { get_attr: [instance, instance] }
          pool: { get_attr: [listener_tcp_8301, pool] }
          port: 8301
—— s n i p ——

gives:

—— s n i p ——
found character '%' that cannot start any token
  in "<unicode string>", line 71, column 18:
              index: %index%
—— s n i p ——

This with a child like:

—— s n i p ——
heat_template_version: 2015-04-30
description: Add an instance to a Loadbalancer pool listener.

parameters:
  instance:
    type: string
    description: Instance ID of the instance to add to the listener.

  pool:
    type: string
    description: Pool ID of the pool to add the instance to.

  port:
    type: string
    description: Port number to forward from the listner to the instance.

  index:
    type: number
    description: Index in address list to use

resources:
  member:
    type: OS::Neutron::LBaaS::PoolMember
    properties:
      address: { get_attr: [{ get_param: instance }, address, index] }
      subnet: { get_attr: [{ get_param: subnet }, port_subnet, index] }
      pool: { get_param: pool }
      protocol_port: { get_param: port }

outputs:
  member:
    value: { get_resource: member }
    description: The member ID.
—— s n i p ——

_______________________________________________
Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to     : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
responded Mar 12, 2017 by Lars-Erik_Helander (560 points)   1 1
0 votes

On 12 Mar 2017, at 15:59, Lars-Erik Helander lars-erik.helander@proceranetworks.com wrote:

I think you need to pass %index% in a string, e.g.

Could you give me some examples? I’m really struggling to get this working!

responded Mar 12, 2017 by Turbo_Fredriksson (8,980 points)   7 13 19
0 votes

Here are two templates foo.yaml and bar.yaml

foo.yaml

heattemplateversion: newton

description: >
Create a set of channel ports on a specific network.

parameters:

network:
type: string
description: Network
label: Network

port_count:
type: number
description: Number of channel ports to create
label: Port count
default: 1

channelports:
type: comma
delimited_list
description: List of channel ports
label: Channel ports

resources:

ports:
type: OS::Heat::ResourceGroup
properties:
count: { getparam: portcount }
resourcedef:
type: bar.yaml
properties:
network: { get
param: network}
ports: { getparam: channelports }
index: "%index%"

bar.yaml

heattemplateversion: newton

description: >
A port created based on a list of names

parameters:

ports:
type: commadelimitedlist
description: List of channel ports
label: Channel ports

index:
type: number
description: Index into channel ports list
label: index

network:
type: string
description: Network to allocate port from
label: Network

resources:

port:
type: OS::Neutron::Port
properties:
networkid: { getparam: network}
name: { getparam: [ports, { getparam: index } ] }
portsecurityenabled: False

On 2017-03-12, 17:59, "Turbo Fredriksson" turbo@bayour.com wrote:

On 12 Mar 2017, at 15:59, Lars-Erik Helander <lars-erik.helander@proceranetworks.com> wrote:
> I think you need to pass %index% in a string, e.g.
Could you give me some examples? I’m really struggling to get this working!

_______________________________________________
Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to     : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
responded Mar 12, 2017 by Lars-Erik_Helander (560 points)   1 1
0 votes

On 12 Mar 2017, at 18:09, Lars-Erik Helander lars-erik.helander@proceranetworks.com wrote:

Here are two templates foo.yaml and bar.yaml

Thanx, it looks like something I did, with a few details here and there
different.

But I’m starting to think that there’s something else a-foot here!

2017-03-12 18:32:48Z [membertcp8301]: CREATEFAILED resources.membertcp8301: Property error: resources[1].properties.subnet: Value must be a string
2017-03-12 18:32:48Z [admin-consul]: CREATE
FAILED Resource CREATE failed: resources.membertcp8301: Property error: resources[1].properties.subnet: Value must be a string


Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
Post to : openstack@lists.openstack.org
Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
responded Mar 12, 2017 by Turbo_Fredriksson (8,980 points)   7 13 19
0 votes

On 12 Mar 2017, at 18:56, Turbo Fredriksson turbo@bayour.com wrote:

2017-03-12 18:32:48Z [membertcp8301]: CREATEFAILED resources.membertcp_8301: Property error: resources[1].properties.subnet: Value must be a string

I’m such a dope!

subnet:
type: commadelimitedlist
description: List of subnets for the instances to add to the listener.

Doh! Not string!

responded Mar 12, 2017 by Turbo_Fredriksson (8,980 points)   7 13 19
...