Git Product home page Git Product logo

puppet-interfaces's Introduction

Puppet Interfaces

A set of executables that provide complete CLI access to Puppet's core data types. They also provide Interface classes for each of the core data types, which are extensible via plugins.

For instance, you can create a new action for catalogs at lib/puppet/interface/catalog/$action.rb.

This is a Puppet module and should work fine if you install it in Puppet's module path.

Note that this only works with Puppet 2.6.next (and thus will work with 2.6.5), because there is otherwise a bug in finding Puppet applications. You also have to either install the lib files into your Puppet libdir, or you need to add this lib directory to your RUBYLIB.

This is meant to be tested and iterated upon, with the plan that it will be merged into Puppet core once we're satisfied with it.

Usage

The general usage is:

$ puppet <interface> <verb> <name>

So, e.g.:

$ puppet facts find myhost.domain.com
$ puppet node destroy myhost

You can use it to list all known data types and the available terminus classes:

$ puppet interface list
catalog                       : active_record, compiler, queue, rest, yaml
certificate                   : ca, file, rest
certificate_request           : ca, file, rest
certificate_revocation_list   : ca, file, rest
file_bucket_file              : file, rest
inventory                     : yaml
key                           : ca, file
node                          : active_record, exec, ldap, memory, plain, rest, yaml
report                        : processor, rest, yaml
resource                      : ral, rest
resource_type                 : parser, rest
status                        : local, rest

But most interestingly, you can use it for two main purposes:

  • As a client for any Puppet REST server, such as catalogs, facts, reports, etc.
  • As a local CLI for any local Puppet data

A simple case is looking at the local facts:

$ puppet facts find localhost

If you're on the server, you can look in that server's fact collection:

$ puppet facts --mode master --vardir /tmp/foo --terminus yaml find localhost

Note that we're setting both the vardir and the 'mode', which switches from the default 'agent' mode to server mode (requires a patch in my branch).

If you'd prefer the data be outputted in json instead of yaml, well, you can do that, too:

$ puppet find --mode master facts --vardir /tmp/foo --terminus yaml --format pson localhost

To test using it as an endpoint for compiling and retrieving catalogs from a remote server, (from my commit), try this:

# Terminal 1
$ sbin/puppetmasterd --trace --confdir /tmp/foo --vardir /tmp/foo --debug --manifest ~/bin/test.pp --certname localhost --no-daemonize

# Terminal 2
$ sbin/puppetd --trace --debug --confdir /tmp/foo --vardir /tmp/foo --certname localhost --server localhost --test --report

# Terminal 3, actual testing
$ puppet catalog find localhost --certname localhost --server localhost --mode master --confdir /tmp/foo --vardir /tmp/foo --trace --terminus rest

This compiles a test catalog (assuming that ~/bin/test.pp exists) and returns it. With the right auth setup, you can also get facts:

$ puppet facts find localhost --certname localhost --server localhost --mode master --confdir /tmp/foo --vardir /tmp/foo --trace --terminus rest

Or use IRB to do the same thing:

$ irb
>> require 'puppet/interface'
=> true
>> interface = Puppet::Interface.interface(:facts).new
=> #<Puppet::Interface::Facts:0x1024a1390 @format=:yaml>
>> facts = interface.find("myhost"); nil

Like I said, a prototype, but I'd love it if people would play it with some and make some recommendations.

Extending

Like most parts of Puppet, these are easy to extend. Just drop a new action into a given interface's directory. E.g.:

$ cat lib/puppet/interface/catalog/select.rb 
# Select and show a list of resources of a given type.
Puppet::Interface.interface(:catalog) do
  action :select do
    invoke do |host,type|
      catalog = Puppet::Resource::Catalog.indirection.find(host)

      catalog.resources.reject { |res| res.type != type }.each { |res| puts res }
    end
  end
end
$ puppet catalog select localhost Class
Class[main]
Class[Settings]
$

Notice that this gets loaded automatically when you try to use it. So, if you have a simple command you've written, such as for cleaning up nodes or diffing catalogs, you an port it to this framework and it should fit cleanly.

puppet-interfaces's People

Contributors

bodepd avatar nicklewis avatar rcrowley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

puppet-interfaces's Issues

cannot pass more than one command line argument

I get the following error when I try to pass more than one argument through my application.

# puppet diff catalog /var/lib/puppet/tests/motd-init.pp.pson /var/lib/puppet/tests/motd-init.pp2.pson  --trace
/usr/local/dev/puppet-interface-utils/lib/puppet/interface/diff.rb:9:in `catalog': undefined method `shift' for "/var/lib/puppet/tests/motd-init.pp.pson":String (NoMethodError)
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `send'
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `main'
    from /usr/local/dev/puppet/lib/puppet/application.rb:312:in `run_command'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/application.rb:410:in `exit_on_fail'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/util/command_line.rb:59:in `execute'
    from /usr/local/dev/puppet//bin/puppet:4

assumes that all terminus actions return results with render method

puppet resource_type search '*'

/usr/local/dev/puppet-interfaces/lib/puppet/application/data_baseclass.rb:50:in main': undefined methodrender' for #Array:0xb7b03724 (NoMethodError)
from /usr/local/dev/puppet//lib/puppet/application.rb:312:in run_command' from /usr/local/dev/puppet//lib/puppet/application.rb:304:inrun'
from /usr/local/dev/puppet//lib/puppet/application.rb:410:in exit_on_fail' from /usr/local/dev/puppet//lib/puppet/application.rb:304:inrun'
from /usr/local/dev/puppet//lib/puppet/util/command_line.rb:59:in `execute'
from /usr/local/dev/puppet//bin/puppet:4

data_baseclass should be renamed and have indirector code moved to a child class

I need to refactor the application code to allow non-indirector applications

  • data_baseclass should have its name changed since the name of the project has changed from data to interface.
  • * I changed it to InterfaceBase
  • There should be a baseclass that is not specific to indirectors (InterfaceBase)
  • The indirector specific methods/functionality should be moved to a class that inherits from InterfaceBase (InterfaceIndirectorBase)
  • all of the indirector specific apps should inherit from InterfaceIndirectorBase

should be able to render custom interface actions

Hi Luke,

We talked about moving some of my actions from their own custom interfaces to just be plugins of one of your existing interface. This is problematic b/c my actions have custom rendering that would need to be added as a plugin to the application.

If we support plugin actions, then we should also have a way to customize rendering of those applications.

expand documentation capabilities

Hi Luke,

The most important thing to figure out next is documentation, this will make adoption a lot easer.

  • we should be able to write inline documentation associated with interfaces/actions

we should be able to do something like:

puppet interface catalog --help
puppet interface catalog find --help

and get back the relevent docs

facts upload returns an error

I get the following error when I try to upload facts

[root@mypuppetmaster tests]# puppet agent -t
info: Loading facts in iscsi_initiatorname
info: Loading facts in iscsi_initiatorname
info: Loading facts in iscsi_initiatorname
info: Loading facts in iscsi_initiatorname
info: Caching catalog for puppetclient
info: Applying configuration version '1299064057'
notice: CentOS
notice: /Stage[main]//Node[default]/Notify[CentOS]/message: defined 'message' as 'CentOS'
notice: Finished catalog run in 0.05 seconds
[root@mypuppetmaster tests]# puppet facts upload
err: Cached facts for mypuppetmaster.localdomain failed: certificate verify failed
/usr/lib/ruby/1.8/net/http.rb:586:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)
    from /usr/lib/ruby/1.8/net/http.rb:586:in `connect'
    from /usr/lib/ruby/1.8/net/http.rb:553:in `do_start'
    from /usr/lib/ruby/1.8/net/http.rb:542:in `start'
    from /usr/lib/ruby/1.8/net/http.rb:1035:in `request'
    from /usr/lib/ruby/1.8/net/http.rb:857:in `put'
    from /usr/local/dev/puppet/lib/puppet/indirector/rest.rb:107:in `save'
    from /usr/local/dev/puppet/lib/puppet/indirector/indirection.rb:192:in `find'
    from /usr/local/dev/puppet-interfaces/lib/puppet/interface/facts.rb:11:in `upload'
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `send'
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `main'
    from /usr/local/dev/puppet/lib/puppet/application.rb:312:in `run_command'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/application.rb:410:in `exit_on_fail'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/util/command_line.rb:59:in `execute'
    from /usr/local/dev/puppet//bin/puppet:4

should not store actions in global namespace

The fact that actions are defined globally bothers me, this appears to make it extremely difficult to write helper methods associated with actions (or should I store all of my helper methods somewhere else?).

Did you have something in mind for this?

puppet interface list fails with 2.6.5

# puppet interface list
catalog:
    Terminuses: active_record, compiler, queue, rest, yaml
    Actions: destroy, find, save, search, select, showconfig
certificate:
    Terminuses: ca, file, rest
    Actions: destroy, find, save, search, showconfig
certificate_request:
    Terminuses: ca, file, rest
    Actions: destroy, find, save, search, showconfig
certificate_revocation_list:
    Terminuses: ca, file, rest
    Actions: destroy, find, save, search, showconfig
facts:
    Terminuses: active_record, couch, facter, memory, rest, yaml
    Actions: destroy, find, save, search, showconfig, upload
Unable to find interface 'file_bucket_file': no such file to load -- puppet/interface/file_bucket_file.

there are two issues with this:

  • should be able to list interfaces even if an indirector is missing
  • 2.6.5 introduces a new indirector which needs to have an interface.

assumes that all interfaces are indirectors

as discussed, I am going to patch this by creating a new class

Puppet::Interface::Indirector < Puppet::Interface

this way interfaces that are not backed by indirectors can just inherit from Puppet::Interface

showconfig does not work for things that are not indirectors

puppet interface list
...
test:
    Terminuses: 
    Actions: check_tests, compile_tests, showconfig
...
# puppet test showconfig
/usr/local/dev/puppet-interfaces/lib/puppet/interface.rb:87:in `showconfig': undefined local variable or method `indirection' for # (NameError)
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `send'
    from /usr/local/dev/puppet-interfaces/lib/puppet/application/interface_base.rb:46:in `main'
    from /usr/local/dev/puppet/lib/puppet/application.rb:312:in `run_command'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/application.rb:410:in `exit_on_fail'
    from /usr/local/dev/puppet/lib/puppet/application.rb:304:in `run'
    from /usr/local/dev/puppet/lib/puppet/util/command_line.rb:59:in `execute'
    from /usr/local/dev/puppet//bin/puppet:4

should be able to custom how results of interfaces are rendered by the application

I found that I want to customize how the application renders results from interfaces for every application that I am working on.

the following code:

    render_method = Puppet::Network::FormatHandler.format(format).render_method
    puts result.send(render_method) if result

cannot handle the rendering of whatever arbitrary data types actions may return.

As a general rule

  • all interfaces should return objects (so that they can be used as APIs)
  • the application should be able to customize how any results for any actions are rendered.

List of tested/failed files should be sorted

Currently it is completely unsorted (hash keys ordering?). It would be nice (if not possible to sort in the order they were tested) for them to be at least alphabetically sorted so you can find files in the output a bit easier.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.