Upload
bodepd
View
709
Download
2
Tags:
Embed Size (px)
Citation preview
Dan Bode| Puppet Labs
[email protected] bodepd <on> [twitter,freenode]
Puppet as DataTransformations
# puppetcamp # puppetize @ puppetlabs
What is it about?
• Deconstructing Puppet to data
• Why you should care
Dissecting a Puppet Run
Part One
# puppetconf # puppetize @ puppetlabs
Facter, who am I?
Agent
Hi! your facts are:
kernel=linuxipaddress=10.0.0.3macaddress=…
# puppetconf # puppetize @ puppetlabs
Hi Mr. Master, I need a catalog. Here are my facts
http://www.dgcomputers.org/testimonials.php
Agent
facts
# puppetconf # puppetize @ puppetlabs
facts
AgentThanks for you
facts.I’ll just store them
in PuppetDBPuppetDB
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
ENCENC
Agent
Mr. ENC, is this host defined as
an external node?Yep, he should be an apache server.
Here is the definition
nodes
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
AgentJust compiled
your catalog. One sec while I store it
in PuppetDB.
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agent
catalog
Here is your catalog. Send me a report and let me know how it
went!
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agent
catalog
I hate to be a bother, but
can you compute the md5sums of
this file?
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agent
catalog
Oh, I need that one!
Can I get the file.
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agent
catalog
Thanks, now let’s just do that 1000
more times.
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agent
catalog
You know ‘content’ will embed the contents in the catalog?
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
AgentJust finished
applying. Here are the results.
report
catalog
Puppet’s internal data language (indirectory/termini)
Part Two
# puppetconf # puppetize @ puppetlabs
facts find from terminus facter
Agent
# puppetconf # puppetize @ puppetlabs
catalog find from terminus rest
http://www.dgcomputers.org/testimonials.php
Agent
facts
# puppetconf # puppetize @ puppetlabs
facts
Agentfacts save to
terminus puppetdb
PuppetDB
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
ENCENC
Agent
node find from terminus exec (or
ldap)
nodes
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agentcatalog find from terminus compiler
catalog
# puppetconf # puppetize @ puppetlabs
PuppetDBPuppetDB
facts
Agentcatalog save to
terminus puppetdb
catalog
# puppetconf # puppetize @ puppetlabs
FacterFacter ENCENC
Disecting a Puppet Run
Com
pil
er
Com
pil
er
Config Catalogs
Nodes/Manife
st
Reports
Facts
# puppetconf # puppetize @ puppetlabs
CLI commands
# puppetcamp # puppetize @ puppetlabs
CLI Puppet Facts
# mkdir –p /tmp/yaml/facts
# puppet facts find node_name --render-as yaml \
> /tmp/yaml/facts/node_name.yaml
# puppetcamp # puppetize @ puppetlabs
Creating a node (optional):
# mkdir –p /tmp/yaml/nodes
# puppet node find node_name \
--node_terminus=exec \
--external_nodes=/etc/puppet/nodes.sh \
--facts_terminus=yaml \
--clientyamldir=/tmp/yaml/ --render-as=yaml \
> /tmp/yaml/nodes/node_name.yaml
# puppetcamp # puppetize @ puppetlabs
Applying a catalog:
# puppet catalog find node_name \
/tmp/catalog.yaml
# puppetcamp # puppetize @ puppetlabs
Creating a catalog:
# puppet apply –catalog /tmp/catalog.yaml
(its easy assuming you are not using file sources)
# puppetconf # puppetize @ puppetlabs
Fun with IRB
# puppetcamp # puppetize @ puppetlabs
IRB Facts
irb:> require ‘puppet/face’
> Puppet.parse_config # required Puppet > 3.0
> facts=Puppet::Face[:facts, :current].find('node_name')
# puppetcamp # puppetize @ puppetlabs
Access a Fact value (irb):
…
> facts.values['ipaddress']
=> "10.0.2.15"
# puppetcamp # puppetize @ puppetlabs
Creating a node (from irb):
…
> node=Puppet::Node.new('node_name',
{:classes => {:foo => {:bar => :baz}}})
>node.merge(facts.values)
# puppetcamp # puppetize @ puppetlabs
Creating a catalog:
…
irb> catalog=Puppet::Face[:catalog, :current].\
find('node_name', :extra => { :node => node})
Interacting with Puppet’s Data
Use Cases
# puppetcamp # puppetize @ puppetlabs
Inspecting the catalog:
• What types are in the catalog?
irb> catalog.resources.collect {|r| r.type }.uniq
• Gimme a resource:
irb>catalog.resource(‘Package[httpd]’)
# puppetcamp # puppetize @ puppetlabs
Rspec Puppet:
let :facts do
{:operatingsystem => ‘Redhat’}
end
let :params do
{:bind_address => ‘0.0.0.0’
end
it { should contain_file(‘/tmp/foo.conf’) }
# puppetcamp # puppetize @ puppetlabs
Thundering Herd
Pre-compile catalogs for faster auto-scaling
# puppetcamp # puppetize @ puppetlabs
Applying pre-compiled catalogs:
• Gather facts from an ec2 instance
• Generate a single catalog
• Apply that catalog to all hosts
puppet apply --catalog /tmp/catalog.json –
server puppet-fileserver
# puppetcamp # puppetize @ puppetlabs
DMZ
tcp over USB
Interacting with Puppet’s Data
Use Cases
# puppetcamp # puppetize @ puppetlabs
Hacking reports
Everything in Puppet is a state transition
User[‘dan’] : absent -> present
User[‘dan’][‘shell’] -> ‘/sbin/nologin’ -> /bin/bash
# puppetcamp # puppetize @ puppetlabs
Setting up the agent:
[agent]
report=true
# puppetcamp # puppetize @ puppetlabs
Archive reports in your yamldir
[master]
reports = store
# puppetcamp # puppetize @ puppetlabs
Puppet reports
$ cd `puppet config print reportdir`
$ ls
node1 node2 node3
$ ls node1
# puppetcamp # puppetize @ puppetlabs
Every report from every run ever
$ ls node1
201206060256.yaml 201206060303.yaml 201206060519.yaml 201206122349.yaml 201206122354.yaml 201206130002.yaml
# puppetcamp # puppetize @ puppetlabs
Lets crack one open!
Irb > require ‘yaml’
>reports=YAML.load_file('201206130002.yaml')
# puppetcamp # puppetize @ puppetlabs
Have a look
>(reports.methods - Object.methods).sort
Notice the following methods:
# puppetcamp # puppetize @ puppetlabs
High level data
> reports.exit_status
0
> reports.status
=> "unchanged"
> reports.host
”node1”
# puppetcamp # puppetize @ puppetlabs
metrics
> reports.metrics.keys
["resources", "events", "changes", "time"]
> reports.metrics['resources']
[‘failed’, 0],[ ‘changed’, ‘7’]
# puppetcamp # puppetize @ puppetlabs
And the awesome sauce
> reports.resource_statuses.keys
=> ["Package[xinetd]", "File[/srv/node/1]", "Package[swift]", "Exec[compile fragments]", "Package[swift-container]", "File[/var/opt/lib/pe-puppet/concat/_etc_swift_object-server.conf]", "File[/etc/rsync.d/frag-account]”]
# puppetcamp # puppetize @ puppetlabs
And the awesome sauce
> status = reports.resource_statuses
> status.keys
=> ["Package[xinetd]", "File[/srv/node/1]", "Package[swift]", "Exec[compile fragments]", "Package[swift-container]", "File[/var/opt/lib/pe-puppet/concat/_etc_swift_object-server.conf]", "File[/etc/rsync.d/frag-account]”]
# puppetcamp # puppetize @ puppetlabs
And the awesome sauce>events = status["File[/etc/swift/swift.conf]"].events
> events.first.status
"success”
> events.first.desired_value
:present
> events.first.previous_value
=> :absent
amp
Thank YouDan Bode| Puppet Labs [email protected]