PUPPET FACESStreamlining Workflows
Kelsey Hightower
AgendaFirst World Problems
Puppet Faces
Familiar Faces
A New Face
Core Components
Why?
puppet dashboard
Puppet DashboardVisualize Your Infrastructure: Status, Graphs, and Reports
External Node Classifier (ENC)
Puppet DashboardVisualize Your Infrastructure: Status, Graphs, and Reports
External Node Classifier (ENC)
manage parameters, groups and classes
First World Problems
First World ProblemsOne key/value pair at a time
First World ProblemsOne key/value pair at a time
Time consuming
First World ProblemsOne key/value pair at a time
Time consuming
Managing ENC data in dashboard could be better
First World Problems
First World ProblemsClick Chrome icon
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
Click add new parameter
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
Click add new parameter
Click save
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
Click add new parameter
Click save
Click on each group
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
Click add new parameter
Click save
Click on each group
Click edit
First World ProblemsClick Chrome icon
Click on Puppet Dashboard bookmark
Click on each system
Click edit
Click add new parameter
Click save
Click on each group
Click edit
Click some more.
Lots of clicking!!
Puppet?
parameters: node: - "el6.puppetize.me": "domain": "puppetize.me"
group: - "webservers": "apache_version": "2.2.16"
puppet cool-subcommand import data.yaml
Puppet Faces
What are Puppet Faces?
What are Puppet Faces?API for extending existing Puppet functionality
What are Puppet Faces?API for extending existing Puppet functionality
API for creating Puppet subcommands and actions
Familiar Facescatalog
certificate
certificate_request
config
facts
file
man
node
report
resource
status
catalog
catalogpuppet catalog select puppet.testing.org package
catalogpuppet catalog select puppet.testing.org package
Package[openssh-server]
catalog
puppet catalog download
puppet catalog select puppet.testing.org package
Package[openssh-server]
catalog
puppet catalog download
notice: Saved catalog for puppet.testing.org to yaml
puppet catalog select puppet.testing.org package
Package[openssh-server]
catalog
puppet catalog download
notice: Saved catalog for puppet.testing.org to yaml
puppet catalog select puppet.testing.org package
Package[openssh-server]
puppet catalog apply
catalog
puppet catalog download
notice: Saved catalog for puppet.testing.org to yaml
puppet catalog select puppet.testing.org package
Package[openssh-server]
puppet catalog apply
notice: Finished catalog run in 0.39 seconds"#<Puppet::Transaction::Report:0x98eafcc>"
config
configpuppet config print server --mode agent
configpuppet config print server --mode agent
puppet.testing.org
configpuppet config print server --mode agent
puppet.testing.org
puppet config print all --mode agent
configpuppet config print server --mode agent
puppet.testing.org
puppet config print all --mode agent
allow_duplicate_certs = falsearchive_file_server = puppet.testing.orgarchive_files = falseasync_storeconfigs = falseauthconfig = /etc/puppet/namespaceauth.confautoflush = falseautosign = /etc/puppet/autosign.confbindaddress = ""bucketdir = /var/lib/puppet/bucket...
certificate
certificatepuppet certificate find puppet.testing.org --ca-location=remote
certificatepuppet certificate find puppet.testing.org --ca-location=remote
-----BEGIN CERTIFICATE-----MIIClzCCAgCgAwIBAgIBBjANBgkqhkiG9w0BAQUFADAoMSYwJAYDVQQDDB1QdXBwZXQgQ0E6IHB1cHBldC50ZXN0aW5nLm9yZzAeFw0xMTA5MDcxNzE1MjJaFw0xNjA5MDUxNzE1MjJaMB0xGzAZBgNVBAMMEnB1cHBldC50ZXN0aW5nLm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0C8WqEYaZiYRGb0mY1LFSEp7M3NIpugcmhJ1eZ9gck0gEtYrk2FetOqBqwF45df3FDXUvHKovcNaJeJ05Gn0XFrAZ8Y7IQsboX993Dd3d+7yq0T4gK1myjnizzqPaa/cgJrAtc1caByoxe1fYL1SJKnm+/u9z6YOT4OI8UtfYskCAwEAAaOB2zCB2DA4BglghkgBhvhCAQ0EKxYpUHVwcGV0IFJ1YnkvT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUaBiSUyQXKLtAj+cNlcEAsVwjRNkwCwYDVR0PBAQDAgWgMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwQwOQYDVR0RBDIwMIIGcHVwcGV0ghJwdXBwZXQudGVzdGluZy5vcmeCEnB1cHBldC50ZXN0aW5nLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBgOYHKMehXRba77I0zOLmnZMh0Y0HvyuSX843e++pXrje/+fCBIqvVai7wCrElLB6pdLsFYVyeLkONGRB6eGGeHr9yRWwSVhEPPySdh2uRER3M530JxCG+tkz4BNtnGGQB+wI12p8EL47axxP/OiCMGCdS8Xi21+FIg2/dwQnsPA==-----END CERTIFICATE-----
resource
resourcepuppet resource package telnet ensure=present
resourcepuppet resource package telnet ensure=present
notice: /Package[telnet]/ensure: created
resourcepuppet resource package telnet ensure=present
notice: /Package[telnet]/ensure: created
package { 'telnet': ensure => '0.17-36',}
dashboard face
dashboard
dashboardQuery Puppet Dashboard
dashboardQuery Puppet Dashboard
Import/Export data
How?
Programming Motherfu*ker
Project LayoutLICENSE
README
lib/puppet/application/dashboard.rb
lib/puppet/face/dashboard.rb
lib/puppet/face/dashboard/*.rb
Core Componentsapplication
options
arguments
actions
Only limited by your imagination.
Only limited by your imagination.
Dragon Face
puppet dashboard import data.yaml
puppet dashboard import data.yaml
application
Applicationcopyright
license
summary
description
short_description
action
Application Class
require 'puppet/face'require 'puppet/application/face_base'
class Puppet::Application::Dashboard < Puppet::Application::FaceBaseend
dashboard-puppet-face/lib/puppet/application/dashboard.rb
Application Class
require 'puppet/face'require 'puppet/application/face_base'
class Puppet::Application::Dashboard < Puppet::Application::FaceBaseend
dashboard-puppet-face/lib/puppet/application/dashboard.rb
inherit FaceBase
Applicationpuppet-dashboard-face/lib/puppet/face/dashboard.rb
require 'puppet'require 'puppet/face'
Puppet::Face.define(:dashboard, '0.0.1') do summary "Puppet Dashboard Integration" copyright "Kelsey Hightower", 2011 license "Apache 2 license" description "Puppet Dashboard Integration"end
Applicationpuppet-dashboard-face/lib/puppet/face/dashboard.rb
require 'puppet'require 'puppet/face'
Puppet::Face.define(:dashboard, '0.0.1') do summary "Puppet Dashboard Integration" copyright "Kelsey Hightower", 2011 license "Apache 2 license" description "Puppet Dashboard Integration"end
subcommand
Applicationpuppet-dashboard-face/lib/puppet/face/dashboard.rb
require 'puppet'require 'puppet/face'
Puppet::Face.define(:dashboard, '0.0.1') do summary "Puppet Dashboard Integration" copyright "Kelsey Hightower", 2011 license "Apache 2 license" description "Puppet Dashboard Integration"end
api version
puppet dashboard import data.yaml\--adapter=mysql --host=127.0.0.1
puppet dashboard import data.yaml\--adapter=mysql --host=127.0.0.1
options
Optionsadapter
username
password
host
database
Optionspuppet-dashboard-face/lib/puppet/face/dashboard.rb
require 'puppet'require 'puppet/face'
Puppet::Face.define(:dashboard, '0.0.1') do ... option "--adapter ADAPTER" do summary "Active Record database adapter" description <<-'EOT' The adapter for to use when accessing the Puppet Dashboard database. EOT end ...end
Optionspuppet-dashboard-face/lib/puppet/face/dashboard.rb
require 'puppet'require 'puppet/face'
Puppet::Face.define(:dashboard, '0.0.1') do ... option "--adapter ADAPTER" do summary "Active Record database adapter" description <<-'EOT' The adapter for to use when accessing the Puppet Dashboard database. EOT end ...end
define options
puppet dashboard import data.yaml
puppet dashboard import data.yaml
arguments
ArgumentsFaces can accept positional arguments
Argumentspuppet-dashboard-face/lib/puppet/face/dashboard/import.rb
Puppet::Face.define(:dashboard, '0.0.1') do action :import do summary "Import ENC paramters" arguments "<data>" description <<-'EOT' Bulk import external nodes configuration data into dashboard EOT endend
puppet dashboard import data.yaml
puppet dashboard import data.yaml
action
Actionssummary
arguments
returns
description
notes
examples
when_invoked
when_rendering
Actionspuppet-dashboard-face/lib/puppet/face/dashboard/import.rb
Puppet::Face.define(:dashboard, '0.0.1') do action :import do summary "Import ENC paramters" arguments "<data>" description <<-'EOT' Bulk import external nodes configuration data into dashboard EOT
when_invoked do |data, options| ... end endend
Actionspuppet-dashboard-face/lib/puppet/face/dashboard/import.rb
Puppet::Face.define(:dashboard, '0.0.1') do action :import do summary "Import ENC paramters" arguments "<data>" description <<-'EOT' Bulk import external nodes configuration data into dashboard EOT
when_invoked do |data, options| ... end endend
Action
Actionspuppet-dashboard-face/lib/puppet/face/dashboard/import.rb
Puppet::Face.define(:dashboard, '0.0.1') do action :import do summary "Import ENC paramters" arguments "<data>" description <<-'EOT' Bulk import external nodes configuration data into dashboard EOT
when_invoked do |data, options| ... end endend This is where the
works gets done.
Almost ready to solve this problem.
Deploying our Face
Deployment
Deploymentrsync -av puppet-dashboard-face/lib/puppet/ \/opt/ruby/lib/ruby/gems/1.8/gems/puppet-2.7.3/lib/puppet/
Deploymentrsync -av puppet-dashboard-face/lib/puppet/ \/opt/ruby/lib/ruby/gems/1.8/gems/puppet-2.7.3/lib/puppet/
sending incremental file list./application/application/dashboard.rbface/face/dashboard.rbface/dashboard/face/dashboard/import.rbface/dashboard/list.rbface/dashboard/models.rbface/dashboard/report.rbface/dashboard/search.rb
sent 9069 bytes received 160 bytes 18458.00 bytes/sectotal size is 8546 speedup is 0.93
Deployment
Deploymentpuppet help
Deploymentpuppet help
Usage: puppet <subcommand> [options] <action> [options]
Available subcommands, from Puppet Faces: catalog Compile, save, view, and convert catalogs. facts Retrieve and store facts. help Display Puppet help. dashboard Puppet Dashboard Integration. man Display Puppet manual pages. node View and manage node definitions. parser Interact directly with the parser.
Help
Helppuppet help dashboard
Helppuppet help dashboard
USAGE: puppet dashboard <action> [--host HOST] ...
Interact with Puppet Dashboard
OPTIONS: ... --adapter ADAPTER - Active Record Database Adapter --host HOST - Database Hostname
ACTIONS: import Import data into Puppet Dashboard.
See 'puppet man dashboard' or 'man puppet-dashboard' for full help.
RTFM
Read The Face Manual
Read The Face Manualpuppet man dashboard
Read The Face Manualpuppet man dashboard
PUPPET-DASHBOARD(8) Puppet Manual PUPPET-DASHBOARD(8)
NAME puppet-dashboard - Interact with Puppet Dashboard
SYNOPSIS puppet dashboard action [--adapter ADAPTER] [--database DATBASE] [--username USER] [--password PASSWORD] [--host HOST]
OPTIONS Note that any configuration parameter that's valid in the configuration file is also a valid long argument, although it may or may not be rele- vant to the present action. For example, server is a valid configura- tion parameter, so you can specify --server <servername> as an argu- ment.
Putting it all together
parameters: node: - "master.lab.org": "domain": "puppetize.me"
group: - "webservers": "apache_version": "2.2.16"
puppet dashboard import data.yaml
Problem solved!
Better for the environment
75% less batteries
Why Puppet Faces?
Consolidation
Consolidation/usr/sbin/dashboard_importer
Consolidation/usr/sbin/dashboard_importer
/usr/sbin/dashboard_importer.bak
Consolidation/usr/sbin/dashboard_importer
/usr/sbin/dashboard_importer.bak
/usr/sbin/dashboardImporter
Consolidation/usr/sbin/dashboard_importer
/usr/sbin/dashboard_importer.bak
/usr/sbin/dashboardImporter
/usr/sbin/dashboard_importer.new
Consolidation/usr/sbin/dashboard_importer
/usr/sbin/dashboard_importer.bak
/usr/sbin/dashboardImporter
/usr/sbin/dashboard_importer.new
puppet dashboard importer
Free Documentationpuppet man dashboard
puppet help dashboard
Free Ruby API
Free Ruby APIirb
Free Ruby APIirb
irb> require 'rubygems'
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'irb> arguments = '/tmp/data.yaml'
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'irb> arguments = '/tmp/data.yaml'irb> options = {:adapter => 'mysql', :password => ..
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'irb> arguments = '/tmp/data.yaml'irb> options = {:adapter => 'mysql', :password => ..irb> dashboard = Puppet::Face[:dashboard,'0.0.1']
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'irb> arguments = '/tmp/data.yaml'irb> options = {:adapter => 'mysql', :password => ..irb> dashboard = Puppet::Face[:dashboard,'0.0.1']irb> dashboard.import(arguments, options)
Free Ruby APIirb
irb> require 'rubygems'irb> require 'puppet/face'irb> arguments = '/tmp/data.yaml'irb> options = {:adapter => 'mysql', :password => ..irb> dashboard = Puppet::Face[:dashboard,'0.0.1']irb> dashboard.import(arguments, options)
puppet dashboard import /tmp/data.yaml --adapter=mysql ...
Good Investment
The FutureReference custom parameters from puppet.conf
Expose Faces to external REST API
khightower/puppet-dashboard-face
github
@kelseyhightowertwitter
puppetize.meweb
Questions?