How to collect hostnames or host ips

790 views
Skip to first unread message

Dusty Doris

unread,
Jan 28, 2013, 9:30:14 PM1/28/13
to puppet...@googlegroups.com
I'd like to be able to collect all the hostnames (fqdn) or ips of certain hosts to be used in setting up firewall rules.  I'd like to search for hosts that have included a particular class, perhaps by simply setting a tag when that resource is included.

eg:

node 'node1' {
  include 'somewebclass'
}

class somewebclass {
  tag 'web'
  # other stuff
}


Then in another class, I'd like to find all my 'web' hosts and allow them access in a firewall rule.
eg:

class somedbclass {
  tag 'db'
  iptables { "allow db access":
    proto => 'tcp',
    dport => '3306'
    source => Node <| tag == 'web' |>,
    jump => 'ACCEPT'
  } 
}

So, ultimately, I'd need that Node <| tag == 'web' |> to be an array of hostnames or ipaddresses.

This is just an example to try to explain what I am doing.  Does anyone know how to do this?  Can I do this in puppet?  Do I need to write my own function to handle this?  Or, can I use something like hiera or puppetdb to do this?

Thanks for any tips.




Luke Bigum

unread,
Jan 29, 2013, 4:08:26 AM1/29/13
to puppet...@googlegroups.com
Hi Dusty,
Native Puppet doesn't have any such feature. I asked a similar question in this thread about a month ago where I was trying bend Exported Resources to my will:


To save you some reading I would recommend using this module to pull raw data from PuppetDB, or something similar:


From there you could build your hash/array, then use that in a template or to create individual Puppet resources from for your firewall rules.

Hope that helps,

-Luke

Ohad Levy

unread,
Jan 29, 2013, 4:35:27 AM1/29/13
to puppet...@googlegroups.com

Cheers,
Ohad 




--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To post to this group, send email to puppet...@googlegroups.com.
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Dusty Doris

unread,
Jan 29, 2013, 2:05:49 PM1/29/13
to puppet...@googlegroups.com
Thanks Luke and Ohad, this is great information.  Going to check out both foreman and puppetdb.

Jared Curtis

unread,
Jan 29, 2013, 10:23:24 PM1/29/13
to puppet...@googlegroups.com
This should work for you. I didn't test it but it should be close to what you need. The basic idea is have the node who already knows it's IP address to export a iptables resource, then have the server collect the resources. I like to break these sorts of things into a class that I can just include into all my web nodes.

class db::client {
  @@iptables { "Allow db access to ${::hostname}":
    proto => 'tcp',
    dport => '3306'
    source => $::ipaddress,
    jump => 'ACCEPT',
    tag
  } 
}

class db::server {
  Iptables <<| tag == 'db::client' |>>

node webclient {
  include db::client
  # web stuff
}

Dusty Doris

unread,
Jan 30, 2013, 7:11:38 PM1/30/13
to puppet...@googlegroups.com
Thanks Jared, that implementation is nice and opened my eyes to exported resources.  I appreciate that.  I ended up going with puppetdb as my stored config and so far my tests are showing this may be a good solution for us. 

Thanks!

Dusty Doris

unread,
Jan 31, 2013, 9:22:27 PM1/31/13
to puppet...@googlegroups.com
Thanks everyone for your feedback.  I have been testing with puppetdb and stored configs and its working great.  Below is an example using two different ways.  The first one is using the collection syntax suggested by Jared and the other is using the puppet-puppetdb module as suggested by Luke.  This gives me a lot of flexibility!


class core::nodes::dbclient {
  @@iptables { "Allow db access to ${::hostname}":
    proto => 'tcp',
    dport => '3306',
    source => $::ipaddress,
    jump => 'ACCEPT',
    tag => 'db::client'
  }
}

class core::nodes::dbserver {
  Iptables <<| tag == 'db::client' |>>
}

class core::nodes::appclient {
}

class core::nodes::appserver {
  $clients = pdbresourcequery(["and",["=",["node","active"],true],["and",["=","type","Class"],["=","title","Core::Nodes::Appclient"]]], 'certname')
  iptables { "allow web":
    proto  => 'tcp',
    dport  => '80',
    source => $clients,
    jump => 'ACCEPT'
  }
}


So if I had the following node definitions, then appserver1 would have rules built to allow port 80 and port 3306 from appclient1.


node 'appclient1' {
  include core::nodes::dbclient
  include core::nodes::appclient
}

node 'appserver1' {
  include core::nodes::dbserver
  include core::nodes::appserver
}


Thanks for your input and I hope this follow-up helps someone else in the future. 

Take care.

Reply all
Reply to author
Forward
0 new messages