Share data between custom functions/resources/providers?

44 views
Skip to first unread message

Nick Howes

unread,
Mar 5, 2015, 9:22:33 AM3/5/15
to puppet...@googlegroups.com
Hello,

I am trying to define something that would let me do this, or something like it:

  fw_service { elasticsearch: 
    ports => [ '9200-9300' ],
    zone => work,
  }

  fw_zone { work:
    source_addresses => [ '10.0.0.0/16' ]
  }

And for the fw_zone resource to be able to enumerate data from services that declared that zone name. Since it end goal is generating XML I could always use the concat module to create concat::fragments in the fw_service resource, but I wondered if there was any other way of passing data between functions within a catalog run? Going into Ruby is fine and I'm using future parser so any Puppet 4 API specific stuff would be usable.

Cheers


Felix Frank

unread,
Mar 5, 2015, 5:08:35 PM3/5/15
to puppet...@googlegroups.com
Hi,

there might be ways to achieve this, but also plenty caveats.

You mention all of functions, resources and providers, but I see no
indication that all of them relate to your question. Are you aware of
the differences between the three?

Have you implemented anything already, or are you still in the interface
design phase?

Will Puppet do anything besides generating XML? Do you have any code to
do this already?

Thanks,
Felix

Nick Howes

unread,
Mar 6, 2015, 10:12:23 AM3/6/15
to puppet...@googlegroups.com

Hi Felix,

I'm aware there are no functions in the example, which would be implemented either as a `define` in Puppet or as a custom type in Ruby - I was just expressing that I'm open to any solution, which may involve some helper function under the hood.

At the moment I'm using an existing module called firewalld which expects you to pass the services in to the zone declaration, avoiding the need to share data between types/defines. But this requires you to know the zone definition and the services at the same time. It only really needs to generate this XML and possibly notify the service on any changes, so certainly achievable through the concat module.

The resulting work.xml file would look roughly like this

<zone>
  <source address="10.0.0.0/16" /> 
  <service name="elasticsearch" />
</zone>

I suspect that the reason the concat module exists is because this isn't possible any other way, without nasty hackery.

Having written all this, I've learned that the `firewall-cmd` frontend to firewalld can be used to manipulate these files, so a solution might be to write a provider that drives this command rather than manage the files directly.

Felix Frank

unread,
Mar 6, 2015, 11:15:14 AM3/6/15
to puppet...@googlegroups.com
On 03/06/2015 04:12 PM, Nick Howes wrote:
> I'm aware there are no functions in the example, which would be
> implemented either as a `define` in Puppet or as a custom type in Ruby -
> I was just expressing that I'm open to any solution, which may involve
> some helper function under the hood.

That's why I was asking so intently. Please be aware that "functions" in
the context of Puppet are usually custom parser functions, which serve a
purpose that has nothing to do with providers whatsoever.

> Having written all this, I've
> learned that the `firewall-cmd` frontend to firewalld can be used to
> manipulate these files, so a solution might be to write a provider that
> drives this command rather than manage the files directly.

That sounds promising. Please verify carefully whether a "service" and a
"zone" really need to exchange any information. Your Puppet model should
ideally make it possible to represent a complete configuration through a
set of distinct resources, each of which is self-sufficient.

Puppet will manage relationships such as ordering and dependencies for
you, conveniently defined in the DSL, just as between all other
resources that Puppet can manage out of the box.

If you face difficulty devising such a model for your use case, feel
free to ask for help on this list.

Once you arrived at a design, I would advise to implement it using
define() and exec {} first. Once you have some manifests that
successfully use these defined types, you can consider if it's worth the
effort to implement actual native types and providers to do that work
more efficiently (mind you, that effort is substantial in comparison to
a manifest-only approach).

HTH,
Felix

Nick Howes

unread,
Mar 6, 2015, 11:37:20 AM3/6/15
to puppet...@googlegroups.com
Thanks Felix; all good points. I'll probably start off with define & exec to drive `firewall-cmd` then, and see how that turns out.

Ian Mortimer

unread,
Mar 6, 2015, 6:16:26 PM3/6/15
to puppet...@googlegroups.com
On Sat, 7 Mar 2015, Nick Howes wrote:

> Thanks Felix; all good points. I'll probably start off with define & exec to
> drive `firewall-cmd` then, and see how that turns out.

There's a puppet-firewalld package in the Fedora and Epel repos
which installs Jiri Popelka's firewalld module.


--
Ian

Nick Howes

unread,
Mar 7, 2015, 5:07:54 AM3/7/15
to puppet...@googlegroups.com


On Friday, 6 March 2015 23:16:26 UTC, ianm wrote:

There's a puppet-firewalld package in the Fedora and Epel repos
which installs Jiri Popelka's firewalld module.


That's the one I've been using up til now (installed using r10k rather than an OS package) - the issue with that module is that the resources it declares exactly mirror the XML files, so when you declare a zone you have to list the services in that zone at the same time, rather than being able to do it the other way round and separately link services to zones. As I use the roles and profiles pattern, I'd like to be able to have my elasticsearch profile be able to declare a firewall service that should belong to the work zone. The work zone would be described in a different profile, as other services will likely want to reference it too.
Reply all
Reply to author
Forward
0 new messages