[Puppet-users] Pupppet Ruby DSL

Luke Kanies
Mon, 31 Jul 2006 08:59:03 -0000

On Jul 29, 2006, at 8:37 AM, David Schmitt wrote:
>
> Yes and no. I was thinking about having some kind of (legacy/
> management)
> database which already has information I would want to use to
> configure
> puppets. Using ruby as DSL, I could query the database everytime a
> puppet
> asks for its manifest. Using a .pp compiler, I could regenerate
> the .pp
> scripts everytime the database changes.

The mechanism for each of these, depending on your willingness to use
Ruby, would probably be pretty similar.

If I had a bunch of data outside of Puppet that I wanted in it, I''d
just create a function to turn that data into Puppet elements.  This
function would work equivalently in both the language and the DSL.

Puppet does not currently autoload functions, but I just added a
feature request for that and it''s easy to do.

> Implementing a kind of SQL type which takes a SELECT statement like:
>
> sql { "SELECT name, mode, owner, group, content FROM files WHERE
> hostname > $hostname":
> }
>
> or even
>
> sql { default-files:
> 	type => file,
> 	fields => "name, mode, owner, group, content"
> 	table => files,
> 	where => "hostname = $hostname"
> }
>
> that would go in the spirit of the declarative .pp philosophy.

Yep, it should be pretty easy to model the entire Puppet
configuration in a database.  Obviously the objects are easy to
model, but even the control structures shouldn''t be all that difficult.

> As soon as the puppetmaster serializes the manifest for the client ...

What do you mean?  Puppetmasterd does serialize the compiled client
configuration, into YAML (mostly because I was too lazy to figure out
how to do it in XML, but I''m perfectly willing to switch to that if
someone is willing to contribute the code or pay for the work or
whatever).

> Architecturally, this already defines the interfaces for the manifest
> components:
>
> * Input: used by the server to create the in-memory representation
> ** .pp parser
> ** .rb scripts/objects
>
> * De-/Serializer: translation from/to a static string
> representation of a
> configuration
> ** yaml for "native" clients
> ** XML for others

There''s a pretty important "compile" step in here, though.
Converting from the configuration that specifies for everyone to a
host-specific configuration is pretty important, and how you get the
compiled configuration to the client is significantly less
important.  Right now it''s in YAML, but it''s pretty darn easy
to
switch to something else -- I''ve already even got the hooks for using
and specifying a different format.

> * Performer: Applies the in-memory representation to a system
>
> Currently these parts are not very separated. Exposing interfaces
> for these
> parts would enable a more flexible usage by e.g. writing a custom
> Input/Serialisation component.

Actually, these steps are entirely decoupled.

There are clearly separate entities for each step, and they have
clean interfaces to the surrounding steps.  See http://
reductivelabs.com/projects/puppet/documentation/howitworks.html for
all of the details, but the short of it is:

The parser converts from text to a parse tree.

The interpreter creates a scope and converts from a parse tree to an
individual host''s configuration.

The Master server serializes and sends the individual configuration
to the client.

The Master client turns that serialized configuration into a
collection of Puppet::Type instances and also handles applying those
instances.

As I said, the interfaces between these objects are all pretty darn
clean; if you disagree, please provide detail, as I would consider
that a bug and fix it ASAP.

One of my primary goals throughout this whole process has been to
keep everything as decoupled as possible.

--
Luke Kanies
http://madstop.com
615-594-8199