puppet module - check if port is opened before running resource

837 views
Skip to first unread message

aldantas

unread,
Sep 14, 2015, 8:55:01 PM9/14/15
to Puppet Users
Hello, 

I am writing a puppet module and I am looking into a way to have a validation before trying to execute something in puppet. 

For example:  

If host is listing on port 3306 {

    file { 'name':
        ensure => file,
    }

}

or 

If host is listing on port 3306 {

include '::module::manifest'

}


I am a little lost on how to accomplish this. I have tried creating a custom function and custom factor but I wasn't successful.


Does anyone have any good solution for this?


Thanks!!

Trevor Vaughan

unread,
Sep 14, 2015, 10:01:00 PM9/14/15
to puppet...@googlegroups.com
Is this the *local* host listening on that port, or some remote system?

If it's the local host, then you would want to use a fact that calls something like netstat or ss and returns a Boolean based on the result of that port selection. You could also return all listening ports as a Hash and go from there.

Generally, Puppet would be managing the service that actually listens on the port and you would simply include your manifest after starting that service. However, without knowing your setup, it's difficult to tell if you are in this situation.

Thanks,

Trevor

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/7776a753-d752-4a90-81a6-5cd71de6a3aa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Trevor Vaughan
Vice President, Onyx Point, Inc
(410) 541-6699

-- This account not approved for unencrypted proprietary information --

aldantas

unread,
Sep 15, 2015, 10:28:51 AM9/15/15
to Puppet Users
No, it is remote. I am deploying a application cluster that has some nodes dependencies, so basically in order to execute a script in one node I need to make sure first that the remote node is already listening on a specific port, if that node is not listening on that port I do not want to execute the script.

I used to work with Chef before and it was easy to accomplish that with ruby blocks.

require 'socket'
require 'timeout'

def port_open?(ip, port, seconds=1)
  Timeout::timeout(seconds) do
    begin
      TCPSocket.new(ip, port).close
      true
    rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
      false
    end
  end
rescue Timeout::Error
  false
end

I'm not sure how I can use something like that in puppet, I don't seem to be able to pass puppet module variables to factors?  With custom functions, I can pass variables as arguments but I was having trouble to get a boolean value returned. I might have to play with that some more, I just thought I would ask to see if anybody had any working example of that.

Thanks!!

Trevor Vaughan

unread,
Sep 15, 2015, 12:23:57 PM9/15/15
to puppet...@googlegroups.com
In this case, you can have a fact that uses the code that you posted above. Facts are just Ruby so you can pretty much do whatever you need and return the boolean as the fact content.

However, you may need to get a bit fancy and use a confine to ensure that only that one node is triggering the fact run and not every node in your infrastructure.

The most precise way to do this would be to drop a file on the system whose presence indicates that the fact should run and bind the confine to the presence of that file.

More information on creating custom facts can be found at https://docs.puppetlabs.com/facter/2.2/custom_facts.html.

Thanks,

Trevor


For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages