Programmatically discover IP address based on tag search

All -

I have a pair of application nodes that need to use a pair of Memcached nodes. For simplicity sake I’ll call that application nodes app1 and app2, and the Memcached nodes mem1 and mem2.

I need to open the firewall on mem1 and mem2 to allow incoming access on port 11211, therefore I want to programmatically discover the IP addresses of app1 and app2. Since this same cookbook will be used on alpha and production nodes I also need to discover the current tier.

In the code below, the memcached_instance attribute contains the same value as one of the tags on app1 and app2, e.g., “sso"

determine if we are an alpha or production node

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

get the list of nodes…

application_nodes = search(:node, “tags:#{node[‘memcached’][‘memcached_instance’]} AND tags:#{local_environment}”)

application_nodes.each do |application_node|

firewall_rule “allow application node ips” do
source application_node[‘ipaddress’]
port node[‘memcached’][‘port’]
protocol :tcp
action :allow
notifies :enable, 'firewall[ufw]'
end

end

All of this looks good but it doesn’t work. My guess is that the array structure returned by my search statement is more complex than I suspect or differently structured in someway. I’ve looked at the results of the same basic command via knife (which returns the results I expect) but I can’t get this working.

What am I missing?

Thanks,
Mark

Mark,

Can you provide some output on how your search results come out? "It
doesn't work" is pretty open-ended.

Inside a chef-shell -z session, you can actually execute the search from
your recipe, so you can test the conditions of your search.

-M

application_nodes = search(:node,

"tags:#{node['memcached']['memcached_instance']}
AND tags:prod")

I suspect it may have something to do with the tags that are added to those
nodes,

On Sat, Nov 29, 2014 at 9:31 AM, Mark Nichols chef@zanshin.net wrote:

All -

I have a pair of application nodes that need to use a pair of Memcached
nodes. For simplicity sake I’ll call that application nodes app1 and app2,
and the Memcached nodes mem1 and mem2.

I need to open the firewall on mem1 and mem2 to allow incoming access on
port 11211, therefore I want to programmatically discover the IP addresses
of app1 and app2. Since this same cookbook will be used on alpha and
production nodes I also need to discover the current tier.

In the code below, the memcached_instance attribute contains the same
value as one of the tags on app1 and app2, e.g., “sso"

determine if we are an alpha or production node

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

get the list of nodes...

application_nodes = search(:node,
"tags:#{node['memcached']['memcached_instance']} AND
tags:#{local_environment}")

application_nodes.each do |application_node|

firewall_rule "allow application node ips" do
source application_node['ipaddress']
port node['memcached']['port']
protocol :tcp
action :allow
notifies :enable, 'firewall[ufw]'
end

end

All of this looks good but it doesn’t work. My guess is that the array
structure returned by my search statement is more complex than I suspect or
differently structured in someway. I’ve looked at the results of the same
basic command via knife (which returns the results I expect) but I can’t
get this working.

What am I missing?

Thanks,
Mark

On Nov 29, 2014, at 8:43 AM, Mike miketheman@gmail.com wrote:

Mark,

Can you provide some output on how your search results come out? "It doesn't work" is pretty open-ended.

The run-list completes with no errors, but when I examine iptables on the memcached nodes no entries have been added for the two application nodes.

Inside a chef-shell -z session, you can actually execute the search from your recipe, so you can test the conditions of your search.

I guess I need to setup chef-shell as it gives me an error saying it can’t write /etc/chef/client.pem. Looks like a permissions issue. I’ll see if I can get that sorted.

-M

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']} AND tags:prod")

I suspect it may have something to do with the tags that are added to those nodes,

Here’s the output from the knife search command:

$ knife search "tags:lti AND tags:alpha" -a ipaddress
2 items found

ome-vm33.campus.ksu.edu:
ipaddress: 10.139.8.13

ome-vm34.campus.ksu.edu:
ipaddress: 10.139.8.14

And a search showing the environment and tags for the nodes in question:

$ knife search "tags:lti" -a environment -a tags -a ipaddress
2 items found

ome-vm33.campus.ksu.edu:
environment: ome-alpha
ipaddress: 10.139.8.13
tags:
alpha
lti

ome-vm34.campus.ksu.edu:
environment: ome-alpha
ipaddress: 10.139.8.14
tags:
alpha
lti

— Mark

On Sat, Nov 29, 2014 at 9:31 AM, Mark Nichols <chef@zanshin.net mailto:chef@zanshin.net> wrote:
All -

I have a pair of application nodes that need to use a pair of Memcached nodes. For simplicity sake I’ll call that application nodes app1 and app2, and the Memcached nodes mem1 and mem2.

I need to open the firewall on mem1 and mem2 to allow incoming access on port 11211, therefore I want to programmatically discover the IP addresses of app1 and app2. Since this same cookbook will be used on alpha and production nodes I also need to discover the current tier.

In the code below, the memcached_instance attribute contains the same value as one of the tags on app1 and app2, e.g., “sso"

determine if we are an alpha or production node

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

get the list of nodes...

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']} AND tags:#{local_environment}")

application_nodes.each do |application_node|

firewall_rule "allow application node ips" do
source application_node['ipaddress']
port node['memcached']['port']
protocol :tcp
action :allow
notifies :enable, 'firewall[ufw]'
end

end

All of this looks good but it doesn’t work. My guess is that the array structure returned by my search statement is more complex than I suspect or differently structured in someway. I’ve looked at the results of the same basic command via knife (which returns the results I expect) but I can’t get this working.

What am I missing?

Thanks,
Mark

I think I see the problem.

It appears you're searching for a tag named environment instead of
searching for the environment named ome-aplha.

A patter we use freuqnetly to discover this is like so:

localnodes = search(:node, "tags:somequalifier AND

chef_environment:#{node.chef_environment}"

This will find any nodes with the somequalifier tag as well as if they are
in the same environment as the local node.
To switch to your method, it would look something like this:

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

application_nodes = search(:node,
"tags:#{node['memcached']['memcached_instance']}
AND chef_environment:#{local_environment}")
...

I think the method I show above is a little simpler, as it removes the
conditional lookup, and will scale with any amount of environments.

A side note on chef-shell - nothing to set up there, since chef-shell -z
executes a chef-client compile against the actual chef-server, the node's
permissions are needed to make the requests.
I'm betting you were using a regular user, whereas root has access to the
client certificate.

Hope this helps,
-Mike Fiedler

On Sat, Nov 29, 2014 at 10:08 AM, Mark Nichols chef@zanshin.net wrote:

On Nov 29, 2014, at 8:43 AM, Mike miketheman@gmail.com wrote:

Mark,

Can you provide some output on how your search results come out? "It
doesn't work" is pretty open-ended.

The run-list completes with no errors, but when I examine iptables on the
memcached nodes no entries have been added for the two application nodes.

Inside a chef-shell -z session, you can actually execute the search from
your recipe, so you can test the conditions of your search.

I guess I need to setup chef-shell as it gives me an error saying it can’t
write /etc/chef/client.pem. Looks like a permissions issue. I’ll see if I
can get that sorted.

-M

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']}

AND tags:prod")

I suspect it may have something to do with the tags that are added to
those nodes,

Here’s the output from the knife search command:

$ knife search "tags:lti AND tags:alpha" -a ipaddress

2 items found

ome-vm33.campus.ksu.edu:
ipaddress: 10.139.8.13

ome-vm34.campus.ksu.edu:
ipaddress: 10.139.8.14

And a search showing the environment and tags for the nodes in question:

$ knife search "tags:lti" -a environment -a tags -a ipaddress

2 items found

ome-vm33.campus.ksu.edu:
environment: ome-alpha
ipaddress: 10.139.8.13
tags:
alpha
lti

ome-vm34.campus.ksu.edu:
environment: ome-alpha
ipaddress: 10.139.8.14
tags:
alpha
lti

— Mark

On Sat, Nov 29, 2014 at 9:31 AM, Mark Nichols chef@zanshin.net wrote:

All -

I have a pair of application nodes that need to use a pair of Memcached
nodes. For simplicity sake I’ll call that application nodes app1 and app2,
and the Memcached nodes mem1 and mem2.

I need to open the firewall on mem1 and mem2 to allow incoming access on
port 11211, therefore I want to programmatically discover the IP addresses
of app1 and app2. Since this same cookbook will be used on alpha and
production nodes I also need to discover the current tier.

In the code below, the memcached_instance attribute contains the same
value as one of the tags on app1 and app2, e.g., “sso"

determine if we are an alpha or production node

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

get the list of nodes...

application_nodes = search(:node,
"tags:#{node['memcached']['memcached_instance']} AND
tags:#{local_environment}")

application_nodes.each do |application_node|

firewall_rule "allow application node ips" do
source application_node['ipaddress']
port node['memcached']['port']
protocol :tcp
action :allow
notifies :enable, 'firewall[ufw]'
end

end

All of this looks good but it doesn’t work. My guess is that the array
structure returned by my search statement is more complex than I suspect or
differently structured in someway. I’ve looked at the results of the same
basic command via knife (which returns the results I expect) but I can’t
get this working.

What am I missing?

Thanks,
Mark

On Nov 29, 2014, at 9:16 AM, Mike miketheman@gmail.com wrote:

I think I see the problem.

It appears you're searching for a tag named environment instead of searching for the environment named ome-aplha.

D’oh. facepalm

A patter we use freuqnetly to discover this is like so:

localnodes = search(:node, "tags:somequalifier AND chef_environment:#{node.chef_environment}"

This will find any nodes with the somequalifier tag as well as if they are in the same environment as the local node.
To switch to your method, it would look something like this:

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']} AND chef_environment:#{local_environment}")
...

I think the method I show above is a little simpler, as it removes the conditional lookup, and will scale with any amount of environments.

Much simpler and more straight-forward. Thank you.

A side note on chef-shell - nothing to set up there, since chef-shell -z executes a chef-client compile against the actual chef-server, the node's permissions are needed to make the requests.
I'm betting you were using a regular user, whereas root has access to the client certificate.

You’d be correct. :slight_smile:

Hope this helps,
-Mike Fiedler

Thank you for your help.
Mark

On Sat, Nov 29, 2014 at 10:08 AM, Mark Nichols <chef@zanshin.net mailto:chef@zanshin.net> wrote:

On Nov 29, 2014, at 8:43 AM, Mike <miketheman@gmail.com mailto:miketheman@gmail.com> wrote:

Mark,

Can you provide some output on how your search results come out? "It doesn't work" is pretty open-ended.

The run-list completes with no errors, but when I examine iptables on the memcached nodes no entries have been added for the two application nodes.

Inside a chef-shell -z session, you can actually execute the search from your recipe, so you can test the conditions of your search.

I guess I need to setup chef-shell as it gives me an error saying it can’t write /etc/chef/client.pem. Looks like a permissions issue. I’ll see if I can get that sorted.

-M

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']} AND tags:prod")

I suspect it may have something to do with the tags that are added to those nodes,

Here’s the output from the knife search command:

$ knife search "tags:lti AND tags:alpha" -a ipaddress
2 items found

ome-vm33.campus.ksu.edu http://ome-vm33.campus.ksu.edu/:
ipaddress: 10.139.8.13

ome-vm34.campus.ksu.edu http://ome-vm34.campus.ksu.edu/:
ipaddress: 10.139.8.14

And a search showing the environment and tags for the nodes in question:

$ knife search "tags:lti" -a environment -a tags -a ipaddress
2 items found

ome-vm33.campus.ksu.edu http://ome-vm33.campus.ksu.edu/:
environment: ome-alpha
ipaddress: 10.139.8.13
tags:
alpha
lti

ome-vm34.campus.ksu.edu http://ome-vm34.campus.ksu.edu/:
environment: ome-alpha
ipaddress: 10.139.8.14
tags:
alpha
lti

— Mark

On Sat, Nov 29, 2014 at 9:31 AM, Mark Nichols <chef@zanshin.net mailto:chef@zanshin.net> wrote:
All -

I have a pair of application nodes that need to use a pair of Memcached nodes. For simplicity sake I’ll call that application nodes app1 and app2, and the Memcached nodes mem1 and mem2.

I need to open the firewall on mem1 and mem2 to allow incoming access on port 11211, therefore I want to programmatically discover the IP addresses of app1 and app2. Since this same cookbook will be used on alpha and production nodes I also need to discover the current tier.

In the code below, the memcached_instance attribute contains the same value as one of the tags on app1 and app2, e.g., “sso"

determine if we are an alpha or production node

if node.chef_environment == "ome-alpha"
local_environment = "alpha"
else
local_environment = "prod"
end

get the list of nodes...

application_nodes = search(:node, "tags:#{node['memcached']['memcached_instance']} AND tags:#{local_environment}")

application_nodes.each do |application_node|

firewall_rule "allow application node ips" do
source application_node['ipaddress']
port node['memcached']['port']
protocol :tcp
action :allow
notifies :enable, 'firewall[ufw]'
end

end

All of this looks good but it doesn’t work. My guess is that the array structure returned by my search statement is more complex than I suspect or differently structured in someway. I’ve looked at the results of the same basic command via knife (which returns the results I expect) but I can’t get this working.

What am I missing?

Thanks,
Mark