Ask Your Question

augeas services - add same service name on multiple ports/protocols

asked 2016-05-05 17:56:57 -0500

EricL gravatar image

updated 2016-05-05 17:57:34 -0500

Hello, I would like to use the augeas services lens within Puppet to add services with the same name but on different ports and/or protocols to /etc/services, like this example from the default services file:

systat 11/tcp users
systat 11/udp users

I can currently add a unique service as follows, but I need the onlyif clause for it to work, and that also prevents me from doing what I need:

augeas {"my-service-tcp":
        incl        => "/etc/services",
        lens        => "Services.lns",
        changes     => [
            "ins service-name after service-name[last()]",
            "set service-name[last()] 'my-service'",
            "set service-name[. = 'my-service']/port 2200",
            "set service-name[. = 'my-service']/protocol tcp",
     onlyif   => "match service-name[. ='my-service'] size ==0",

I'd like to add another service, also called 'my-service' but on say port 2250 or with udp instead of tcp.
How can this be done?
Thanks, Eric

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2016-05-05 20:40:18 -0500

DarylW gravatar image

updated 2016-05-05 21:07:19 -0500

I think for complicated examples like that, most of the based implementations use a custom type/provider under the hood to interact with augeas through the augeas gem, which allows them to programmatically look at the contents of the file.

I have seen some examples where you can do a match query with multiple parameters, but people seemed to have issues using them..

They were using the following code..

define services::ifx_services($id,$value){  
require services::services_icl
  augeas {$value:
    lens    => 'services.lns',
    incl    => '/etc/services',
    changes => ["insert service-name after service-name[last()]",
                "set service-name[last()] test$id",
                "set service-name[.='test$id']/port $value",
                "set service-name[.='test$id']/protocol tcp",
                "insert service-name after service-name[last()]",
                "set service-name[last()] test$id",
                "set service-name[.='test$id'][2]/port $value",
                "set service-name[.='test$id'][2]/protocol udp"],
     onlyif  => "match service-name[service-name = 'test$id'][port = '$value'] size == 0"

... But on the second run, it would throw errors... In that answer, someone recommended the ccin2p3 module..

Give that a try and see if it can do what you need.

edit flag offensive delete link more


DarylW, I looked at That does allow me to add the same service name and ports using different protocols (like in my example) I also need to add the same service name and protocols on different ports, like this: myservice 5000/tcp myservice 5020/tcp

EricL gravatar imageEricL ( 2016-05-06 11:04:03 -0500 )edit

That doesn't work because the service name and protocol make up the resource name, so you can only add one unique service name per protocol

EricL gravatar imageEricL ( 2016-05-06 11:05:01 -0500 )edit

answered 2016-05-06 14:14:14 -0500

EricL gravatar image

I ended up modifying the etc_services defined type from ccin2p3 to include the port in the service name. Now, I can use that module to do what I need to do.
I will submit a git pull request at the project URL.

edit flag offensive delete link more


I'm glad you found a solution!

DarylW gravatar imageDarylW ( 2016-05-06 20:42:45 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2016-05-05 17:56:57 -0500

Seen: 72 times

Last updated: May 06 '16