SlideShare una empresa de Scribd logo
1 de 38
Descargar para leer sin conexión
Configuration surgery with Augeas
                         Raphaël Pinson

                            @raphink
                     LSM 2012, Geneva
                          2012-07-11
https://github.com/raphink/augeas-talks/
Tired of ugly sed and awk one liners?




  or of using tons of different parsing libraries or
               common::line tricks?




           www.camptocamp.com /                        2/38
Become a configuration surgeon with




                        Augeas


        www.camptocamp.com /          3/38
What is the need?




●   A lot of different syntaxes
●   Securely editing configuration files with a
    unified API




            www.camptocamp.com /                  4/38
A tree




Augeas turns configuration files into a tree
structure:
/etc/hosts -> /files/etc/hosts




             www.camptocamp.com /              5/38
Its branches and leaves



... and their parameters into branches and leaves:
augtool> print /files/etc/hosts
  /files/etc/hosts
  /files/etc/hosts/1
  /files/etc/hosts/1/ipaddr = "127.0.0.1"
  /files/etc/hosts/1/canonical = "localhost"




             www.camptocamp.com /               6/38
Augeas provides many stock parsers

They are called lenses:
Access             Cron                Host_Conf
Aliases            Crypttab            Hostname
Anacron            debctrl             Hosts_Access
Approx             Desktop             IniFile
AptConf            Dhcpd               Inputrc
Automaster         Dpkg                Iptables
Automounter        Exports             Kdump
BackupPCHosts      FAI_DiskConfig      Keepalived
cgconfig           Fonts               Keepalived
cgrules            Fuse                Login_defs
Channels           Grub                Mke2fs
...




                www.camptocamp.com /                  7/38
... as well as generic lenses




available to build new parsers:
Build        Sep                  Simplelines
IniFile      Shellvars            Simplevars
Rx           Shellvars_list       Util




           www.camptocamp.com /                 8/38
augtool lets you inspect the tree
$ augtool

augtool> ls /
 augeas/ = (none)
 files/ = (none)

augtool> print /files/etc/passwd/root/
 /files/etc/passwd/root
 /files/etc/passwd/root/password = "x"
 /files/etc/passwd/root/uid = "0"
 /files/etc/passwd/root/gid = "0"
 /files/etc/passwd/root/name = "root"
 /files/etc/passwd/root/home = "/root"
 /files/etc/passwd/root/shell = "/bin/bash"




             www.camptocamp.com /             9/38
The tree can be queried using XPath


augtool> print /files/etc/passwd/*[uid='0'][1]
 /files/etc/passwd/root
 /files/etc/passwd/root/password = "x"
 /files/etc/passwd/root/uid = "0"
 /files/etc/passwd/root/gid = "0"
 /files/etc/passwd/root/name = "root"
 /files/etc/passwd/root/home = "/root"
 /files/etc/passwd/root/shell = "/bin/bash"




             www.camptocamp.com /                10/38
But also modified
$ getent passwd root
root:x:0:0:root:/root:/bin/bash

$ augtool

augtool> set /files/etc/passwd/*[uid='0']/shell /bin/sh
augtool> match /files/etc/passwd/*[uid='0']/shell
/files/etc/passwd/root/shell = "/bin/sh"
augtool> save
Saved 1 file(s)
augtool> exit

$ getent passwd root
root:x:0:0:root:/root:/bin/sh




             www.camptocamp.com /                         11/38
Puppet has a native provider


augeas {'export foo':
    context => '/files/etc/exports',
    changes => [
        "set dir[. = '/foo'] /foo",
        "set dir[. = '/foo']/client weeble",
        "set dir[. = '/foo']/client/option[1] ro",
        "set dir[. = '/foo']/client/option[2] all_squash",
    ],
}




             www.camptocamp.com /                            12/38
It is better to wrap things up

define kmod::generic(
  $type, $module, $ensure=present,
  $command='', $file='/etc/modprobe.d/modprobe.conf'
) {
  augeas {"${type} module ${module}":
    context => "/files${file}",
    changes => [
       "set ${type}[. = '${module}'] ${module}",
       "set ${type}[. = '${module}']/command '${command}'",
    ],
  }
}




              www.camptocamp.com /                            13/38
mcollective has an agent

$ mco augeas match /files/etc/passwd/rpinson/shell

 * [ ======================================> ] 196 / 196

...
wrk1
saja-map-dev
     /files/etc/passwd/rpinson/shell = /bin/bash
wrk3
wrk4
     /files/etc/passwd/rpinson/shell = /bin/bash
...




              www.camptocamp.com /                         14/38
... and uses it for discovery




$ mco find -S "augeas_match(/files/etc/passwd/rip).size = 0"




             www.camptocamp.com /                              15/38
Bindings include Perl, Python, Java,
       PHP, Haskell, Ruby...

require 'augeas'
aug = Augeas.open
if aug.match('/augeas/load'+lens).length > 0
    aug.set('/augeas/load/'+lens+'incl[last()+1]', path)
else
    aug.set('/augeas/load/'+lens+'/lens', lens+'.lns')
end
                              (From the mcollective agent)




              www.camptocamp.com /                           16/38
The Ruby bindings can be used in Facter
Facter.add(:augeasversion) do
  setcode do
    begin
      require 'augeas'
      aug = Augeas::open('/', nil, Augeas::NO_MODL_AUTOLOAD)
      ver = aug.get('/augeas/version')
      aug.close
      ver
    rescue Exception
      Facter.debug('ruby-augeas not available')
    end
  end
end
                            (From the augeasversion fact)




             www.camptocamp.com /                              17/38
Or to write native types

def ip
    aug = nil
    path = "/files#{self.class.file(resource)}"
    begin
       aug = self.class.augopen(resource)
       aug.get("#{path}/*[canonical =
          '#{resource[:name]}']/ipaddr")
    ensure
       aug.close if aug
    end
end
              (See https://github.com/domcleal/augeasproviders)




             www.camptocamp.com /                                 18/38
The case of sshd_config
Custom type:
define ssh::config::sshd ($ensure='present', $value='') {

    case $ensure {
      'present': { $changes = "set ${name} ${value}" }

        'absent': { $changes = "rm ${name}" }

        'default': { fail("Wrong value for ensure: ${ensure}") }
    }

    augeas {"Set ${name} in /etc/ssh/sshd_config":
      context => '/files/etc/ssh/sshd_config',
      changes => $changes,
    }
}



                 www.camptocamp.com /                              19/38
Using the custom type for sshd_config




ssh::config::sshd {'PasswordAuthenticator':
  value => 'yes',
}




             www.camptocamp.com /             20/38
The problem with sshd_config


Match groups:
Match Host example.com
  PermitRootLogin no

=> Not possible with ssh::config::sshd, requires
insertions and looping through the configuration
parameters.




             www.camptocamp.com /             21/38
A native provider for sshd_config (1)
The type:
Puppet::Type.newtype(:sshd_config) do
  ensurable

  newparam(:name) do
    desc "The name of the entry."
    isnamevar
  end

  newproperty(:value) do
    desc "Entry value."
  end

  newproperty(:target) do
    desc "File target."
  end

  newparam(:condition) do
    desc "Match group condition for the entry."
  end
end


                 www.camptocamp.com /             22/38
A native provider for sshd_config (2)

The provider:
require 'augeas' if Puppet.features.augeas?

Puppet::Type.type(:sshd_config).provide(:augeas) do
  desc "Uses Augeas API to update an sshd_config parameter"

  def self.file(resource = nil)
    file = "/etc/ssh/sshd_config"
    file = resource[:target] if resource and resource[:target]
    file.chomp("/")
  end

  confine :true   => Puppet.features.augeas?
  confine :exists => file




                 www.camptocamp.com /                            23/38
A native provider for sshd_config (3)
def self.augopen(resource = nil)
 aug = nil
 file = file(resource)
 begin
   aug = Augeas.open(nil, nil, Augeas::NO_MODL_AUTOLOAD)
   aug.transform(
     :lens => "Sshd.lns",
     :name => "Sshd",
     :incl => file
   )
   aug.load!

    if aug.match("/files#{file}").empty?
      message = aug.get("/augeas/files#{file}/error/message")
      fail("Augeas didn't load #{file}: #{message}")
    end
  rescue
    aug.close if aug
    raise
  end
  aug
end


                 www.camptocamp.com /                           24/38
A native provider for sshd_config (4)
def self.instances
  aug = nil
  path = "/files#{file}"
  entry_path = self.class.entry_path(resource)
  begin
    resources = []
    aug = augopen
    aug.match(entry_path).each do |hpath|
      entry = {}
      entry[:name] = resource[:name]
      entry[:conditions] = Hash[*resource[:condition].split(' ').flatten(1)]
      entry[:value] = aug.get(hpath)

      resources << new(entry)
    end
    resources
  ensure
    aug.close if aug
  end
end



                 www.camptocamp.com /                                      25/38
A native provider for sshd_config (5)
def self.match_conditions(resource=nil)
  if resource[:condition]
    conditions = Hash[*resource[:condition].split(' ').flatten(1)]
    cond_keys = conditions.keys.length
    cond_str = "[count(Condition/*)=#{cond_keys}]"
    conditions.each { |k,v| cond_str += "[Condition/#{k}="#{v}"]" }
    cond_str
  else
    ""
  end
end

def self.entry_path(resource=nil)
  path = "/files#{self.file(resource)}"
  if resource[:condition]
    cond_str = self.match_conditions(resource)
    "#{path}/Match#{cond_str}/Settings/#{resource[:name]}"
  else
    "#{path}/#{resource[:name]}"
  end
end



                 www.camptocamp.com /                                   26/38
A native provider for sshd_config (6)

def self.match_exists?(resource=nil)
  aug = nil
  path = "/files#{self.file(resource)}"
  begin
    aug = self.augopen(resource)
    if resource[:condition]
      cond_str = self.match_conditions(resource)
    else
      false
    end
    not aug.match("#{path}/Match#{cond_str}").empty?
  ensure
    aug.close if aug
  end
end




                 www.camptocamp.com /                  27/38
A native provider for sshd_config (7)
def exists?
  aug = nil
  entry_path = self.class.entry_path(resource)
  begin
    aug = self.class.augopen(resource)
    not aug.match(entry_path).empty?
  ensure
    aug.close if aug
  end
end

def self.create_match(resource=nil, aug=nil)
  path = "/files#{self.file(resource)}"
  begin
    aug.insert("#{path}/*[last()]", "Match", false)
    conditions = Hash[*resource[:condition].split(' ').flatten(1)]
    conditions.each do |k,v|
      aug.set("#{path}/Match[last()]/Condition/#{k}", v)
    end
    aug
  end
end


                 www.camptocamp.com /                                28/38
A native provider for sshd_config (8)
def create
  aug = nil
  path = "/files#{self.class.file(resource)}"
  entry_path = self.class.entry_path(resource)
  begin
    aug = self.class.augopen(resource)
    if resource[:condition]
      unless self.class.match_exists?(resource)
         aug = self.class.create_match(resource, aug)
      end
    else
      unless aug.match("#{path}/Match").empty?
         aug.insert("#{path}/Match[1]", resource[:name], true)
      end
    end
    aug.set(entry_path, resource[:value])
    aug.save!
  ensure
    aug.close if aug
  end
end



                 www.camptocamp.com /                            29/38
A native provider for sshd_config (9)
def destroy
  aug = nil
  path = "/files#{self.class.file(resource)}"
  begin
    aug = self.class.augopen(resource)
    entry_path = self.class.entry_path(resource)
    aug.rm(entry_path)
    aug.rm("#{path}/Match[count(Settings/*)=0]")
    aug.save!
  ensure
    aug.close if aug
  end
end

def target
  self.class.file(resource)
end




                 www.camptocamp.com /              30/38
A native provider for sshd_config (10)


def value
  aug = nil
  path = "/files#{self.class.file(resource)}"
  begin
    aug = self.class.augopen(resource)
    entry_path = self.class.entry_path(resource)
    aug.get(entry_path)
  ensure
    aug.close if aug
  end
end




                 www.camptocamp.com /              31/38
A native provider for sshd_config (11)


def value=(thevalue)
  aug = nil
  path = "/files#{self.class.file(resource)}"
  begin
    aug = self.class.augopen(resource)
    entry_path = self.class.entry_path(resource)
    aug.set(entry_path, thevalue)
    aug.save!
  ensure
    aug.close if aug
  end
end




                 www.camptocamp.com /              32/38
Using the native provider for
        sshd_config


sshd_config   {'PermitRootLogin':
  ensure      => present,
  condition   => 'Host example.com',
  value       => 'yes',
}




               www.camptocamp.com /    33/38
Errors are reported in the /augeas tree


augtool> print /augeas//error
 /augeas/files/etc/mke2fs.conf/error = "parse_failed"
 /augeas/files/etc/mke2fs.conf/error/pos = "82"
 /augeas/files/etc/mke2fs.conf/error/line = "3"
 /augeas/files/etc/mke2fs.conf/error/char = "0"
 /augeas/files/etc/mke2fs.conf/error/lens = 
    "/usr/share/augeas/lenses/dist/mke2fs.aug:132.10-.49:"
 /augeas/files/etc/mke2fs.conf/error/message = 
    "Get did not match entire input"




             www.camptocamp.com /                            34/38
Other projects using Augeas


●   libvirt
●   rpm
●   Nut
●   guestfs
●   ZYpp
●   Config::Model
●   Augeas::Validator



            www.camptocamp.com /   35/38
Future projects
●   more API calls
●   improved XPath syntax
●   more lenses
●   more native providers
●   DBUS provider
●   content validation in Puppet (validator)
●   integration in package managers
●   finish the Augeas book
●   ...
●   your idea/project here...

            www.camptocamp.com /               36/38
Questions?




              http://augeas.net
         augeas-devel@redhat.com
            freenode: #augeas




       www.camptocamp.com /        37/38
Augeas @RMLL 2012

Más contenido relacionado

La actualidad más candente

Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shellsascha_klein
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii명철 강
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesPuppet
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0Tim Bunce
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodesnihiliad
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetWalter Heck
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to doPuppet
 
Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証ME iBotch
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaStephen Vance
 
Perl at SkyCon'12
Perl at SkyCon'12Perl at SkyCon'12
Perl at SkyCon'12Tim Bunce
 
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationWorkhorse Computing
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptIngvar Stepanyan
 

La actualidad más candente (20)

Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shell
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet Modules
 
C99[2]
C99[2]C99[2]
C99[2]
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0
 
dotCloud and go
dotCloud and godotCloud and go
dotCloud and go
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodes
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with Puppet
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to do
 
Codeigniter4の比較と検証
Codeigniter4の比較と検証Codeigniter4の比較と検証
Codeigniter4の比較と検証
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
 
Perl at SkyCon'12
Perl at SkyCon'12Perl at SkyCon'12
Perl at SkyCon'12
 
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 

Similar a Augeas @RMLL 2012

On secure application of PHP wrappers
On secure application  of PHP wrappersOn secure application  of PHP wrappers
On secure application of PHP wrappersPositive Hack Days
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Puppet
 
ELK: a log management framework
ELK: a log management frameworkELK: a log management framework
ELK: a log management frameworkGiovanni Bechis
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkBen Scofield
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?Tushar Sharma
 
KubeCon EU 2016: Custom Volume Plugins
KubeCon EU 2016: Custom Volume PluginsKubeCon EU 2016: Custom Volume Plugins
KubeCon EU 2016: Custom Volume PluginsKubeAcademy
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and PracticeBo-Yi Wu
 
Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))Michele Orselli
 
Terraform in deployment pipeline
Terraform in deployment pipelineTerraform in deployment pipeline
Terraform in deployment pipelineAnton Babenko
 
Augeas
AugeasAugeas
Augeaslutter
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013grim_radical
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for realCodemotion
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Michele Orselli
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStackBram Vogelaar
 
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...Puppet
 
Challenges of container configuration
Challenges of container configurationChallenges of container configuration
Challenges of container configurationlutter
 
eZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedeZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedBertrand Dunogier
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebookguoqing75
 

Similar a Augeas @RMLL 2012 (20)

On secure application of PHP wrappers
On secure application  of PHP wrappersOn secure application  of PHP wrappers
On secure application of PHP wrappers
 
EC2
EC2EC2
EC2
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014
 
ELK: a log management framework
ELK: a log management frameworkELK: a log management framework
ELK: a log management framework
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?
 
KubeCon EU 2016: Custom Volume Plugins
KubeCon EU 2016: Custom Volume PluginsKubeCon EU 2016: Custom Volume Plugins
KubeCon EU 2016: Custom Volume Plugins
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))
 
Terraform in deployment pipeline
Terraform in deployment pipelineTerraform in deployment pipeline
Terraform in deployment pipeline
 
Augeas
AugeasAugeas
Augeas
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)Vagrant for real (codemotion rome 2016)
Vagrant for real (codemotion rome 2016)
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
 
Challenges of container configuration
Challenges of container configurationChallenges of container configuration
Challenges of container configuration
 
eZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedeZ Publish Cluster Unleashed
eZ Publish Cluster Unleashed
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook
 

Más de Raphaël PINSON

Explore the World of Cilium, Tetragon & eBPF
Explore the World of Cilium, Tetragon & eBPFExplore the World of Cilium, Tetragon & eBPF
Explore the World of Cilium, Tetragon & eBPFRaphaël PINSON
 
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...Raphaël PINSON
 
ContainerDays Hamburg 2023 — Cilium Workshop.pdf
ContainerDays Hamburg 2023 — Cilium Workshop.pdfContainerDays Hamburg 2023 — Cilium Workshop.pdf
ContainerDays Hamburg 2023 — Cilium Workshop.pdfRaphaël PINSON
 
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdf
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdfKCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdf
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdfRaphaël PINSON
 
Cloud Native Bern 05.2023 — Zero Trust Visibility
Cloud Native Bern 05.2023 — Zero Trust VisibilityCloud Native Bern 05.2023 — Zero Trust Visibility
Cloud Native Bern 05.2023 — Zero Trust VisibilityRaphaël PINSON
 
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...Raphaël PINSON
 
Révolution eBPF - un noyau dynamique
Révolution eBPF - un noyau dynamiqueRévolution eBPF - un noyau dynamique
Révolution eBPF - un noyau dynamiqueRaphaël PINSON
 
Cfgmgmtcamp 2023 — eBPF Superpowers
Cfgmgmtcamp 2023 — eBPF SuperpowersCfgmgmtcamp 2023 — eBPF Superpowers
Cfgmgmtcamp 2023 — eBPF SuperpowersRaphaël PINSON
 
Cloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFCloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFRaphaël PINSON
 
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdfRaphaël PINSON
 
The Hare and the Tortoise: Open Source, Standards & Technological Debt
The Hare and the Tortoise: Open Source, Standards & Technological DebtThe Hare and the Tortoise: Open Source, Standards & Technological Debt
The Hare and the Tortoise: Open Source, Standards & Technological DebtRaphaël PINSON
 
YAML Engineering: why we need a new paradigm
YAML Engineering: why we need a new paradigmYAML Engineering: why we need a new paradigm
YAML Engineering: why we need a new paradigmRaphaël PINSON
 
Container Security: a toolchain for automatic image rebuilds
Container Security: a toolchain for automatic image rebuildsContainer Security: a toolchain for automatic image rebuilds
Container Security: a toolchain for automatic image rebuildsRaphaël PINSON
 
K9s - Kubernetes CLI To Manage Your Clusters In Style
K9s - Kubernetes CLI To Manage Your Clusters In StyleK9s - Kubernetes CLI To Manage Your Clusters In Style
K9s - Kubernetes CLI To Manage Your Clusters In StyleRaphaël PINSON
 
Bivac - Container Volumes Backup
Bivac - Container Volumes BackupBivac - Container Volumes Backup
Bivac - Container Volumes BackupRaphaël PINSON
 
Automating Puppet Certificates Renewal
Automating Puppet Certificates RenewalAutomating Puppet Certificates Renewal
Automating Puppet Certificates RenewalRaphaël PINSON
 
Running the Puppet Stack in Containers
Running the Puppet Stack in ContainersRunning the Puppet Stack in Containers
Running the Puppet Stack in ContainersRaphaël PINSON
 

Más de Raphaël PINSON (20)

Explore the World of Cilium, Tetragon & eBPF
Explore the World of Cilium, Tetragon & eBPFExplore the World of Cilium, Tetragon & eBPF
Explore the World of Cilium, Tetragon & eBPF
 
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...
Cfgmgmtcamp 2024 — eBPF-based Security Observability & Runtime Enforcement wi...
 
ContainerDays Hamburg 2023 — Cilium Workshop.pdf
ContainerDays Hamburg 2023 — Cilium Workshop.pdfContainerDays Hamburg 2023 — Cilium Workshop.pdf
ContainerDays Hamburg 2023 — Cilium Workshop.pdf
 
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdf
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdfKCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdf
KCD Zurich 2023 — Bridge Dev & Ops with eBPF.pdf
 
Cloud Native Bern 05.2023 — Zero Trust Visibility
Cloud Native Bern 05.2023 — Zero Trust VisibilityCloud Native Bern 05.2023 — Zero Trust Visibility
Cloud Native Bern 05.2023 — Zero Trust Visibility
 
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...
DevOpsDays Zurich 2023 — Bridging Dev and Ops with eBPF: Extending Observabil...
 
Révolution eBPF - un noyau dynamique
Révolution eBPF - un noyau dynamiqueRévolution eBPF - un noyau dynamique
Révolution eBPF - un noyau dynamique
 
Cfgmgmtcamp 2023 — eBPF Superpowers
Cfgmgmtcamp 2023 — eBPF SuperpowersCfgmgmtcamp 2023 — eBPF Superpowers
Cfgmgmtcamp 2023 — eBPF Superpowers
 
Cloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPFCloud Native Networking & Security with Cilium & eBPF
Cloud Native Networking & Security with Cilium & eBPF
 
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf
2022 DevOpsDays Geneva — The Hare and the Tortoise.pdf
 
SKS in git ops mode
SKS in git ops modeSKS in git ops mode
SKS in git ops mode
 
The Hare and the Tortoise: Open Source, Standards & Technological Debt
The Hare and the Tortoise: Open Source, Standards & Technological DebtThe Hare and the Tortoise: Open Source, Standards & Technological Debt
The Hare and the Tortoise: Open Source, Standards & Technological Debt
 
Devops stack
Devops stackDevops stack
Devops stack
 
YAML Engineering: why we need a new paradigm
YAML Engineering: why we need a new paradigmYAML Engineering: why we need a new paradigm
YAML Engineering: why we need a new paradigm
 
Container Security: a toolchain for automatic image rebuilds
Container Security: a toolchain for automatic image rebuildsContainer Security: a toolchain for automatic image rebuilds
Container Security: a toolchain for automatic image rebuilds
 
K9s - Kubernetes CLI To Manage Your Clusters In Style
K9s - Kubernetes CLI To Manage Your Clusters In StyleK9s - Kubernetes CLI To Manage Your Clusters In Style
K9s - Kubernetes CLI To Manage Your Clusters In Style
 
Argocd up and running
Argocd up and runningArgocd up and running
Argocd up and running
 
Bivac - Container Volumes Backup
Bivac - Container Volumes BackupBivac - Container Volumes Backup
Bivac - Container Volumes Backup
 
Automating Puppet Certificates Renewal
Automating Puppet Certificates RenewalAutomating Puppet Certificates Renewal
Automating Puppet Certificates Renewal
 
Running the Puppet Stack in Containers
Running the Puppet Stack in ContainersRunning the Puppet Stack in Containers
Running the Puppet Stack in Containers
 

Último

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 

Último (20)

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 

Augeas @RMLL 2012

  • 1. Configuration surgery with Augeas Raphaël Pinson @raphink LSM 2012, Geneva 2012-07-11 https://github.com/raphink/augeas-talks/
  • 2. Tired of ugly sed and awk one liners? or of using tons of different parsing libraries or common::line tricks? www.camptocamp.com / 2/38
  • 3. Become a configuration surgeon with Augeas www.camptocamp.com / 3/38
  • 4. What is the need? ● A lot of different syntaxes ● Securely editing configuration files with a unified API www.camptocamp.com / 4/38
  • 5. A tree Augeas turns configuration files into a tree structure: /etc/hosts -> /files/etc/hosts www.camptocamp.com / 5/38
  • 6. Its branches and leaves ... and their parameters into branches and leaves: augtool> print /files/etc/hosts /files/etc/hosts /files/etc/hosts/1 /files/etc/hosts/1/ipaddr = "127.0.0.1" /files/etc/hosts/1/canonical = "localhost" www.camptocamp.com / 6/38
  • 7. Augeas provides many stock parsers They are called lenses: Access Cron Host_Conf Aliases Crypttab Hostname Anacron debctrl Hosts_Access Approx Desktop IniFile AptConf Dhcpd Inputrc Automaster Dpkg Iptables Automounter Exports Kdump BackupPCHosts FAI_DiskConfig Keepalived cgconfig Fonts Keepalived cgrules Fuse Login_defs Channels Grub Mke2fs ... www.camptocamp.com / 7/38
  • 8. ... as well as generic lenses available to build new parsers: Build Sep Simplelines IniFile Shellvars Simplevars Rx Shellvars_list Util www.camptocamp.com / 8/38
  • 9. augtool lets you inspect the tree $ augtool augtool> ls / augeas/ = (none) files/ = (none) augtool> print /files/etc/passwd/root/ /files/etc/passwd/root /files/etc/passwd/root/password = "x" /files/etc/passwd/root/uid = "0" /files/etc/passwd/root/gid = "0" /files/etc/passwd/root/name = "root" /files/etc/passwd/root/home = "/root" /files/etc/passwd/root/shell = "/bin/bash" www.camptocamp.com / 9/38
  • 10. The tree can be queried using XPath augtool> print /files/etc/passwd/*[uid='0'][1] /files/etc/passwd/root /files/etc/passwd/root/password = "x" /files/etc/passwd/root/uid = "0" /files/etc/passwd/root/gid = "0" /files/etc/passwd/root/name = "root" /files/etc/passwd/root/home = "/root" /files/etc/passwd/root/shell = "/bin/bash" www.camptocamp.com / 10/38
  • 11. But also modified $ getent passwd root root:x:0:0:root:/root:/bin/bash $ augtool augtool> set /files/etc/passwd/*[uid='0']/shell /bin/sh augtool> match /files/etc/passwd/*[uid='0']/shell /files/etc/passwd/root/shell = "/bin/sh" augtool> save Saved 1 file(s) augtool> exit $ getent passwd root root:x:0:0:root:/root:/bin/sh www.camptocamp.com / 11/38
  • 12. Puppet has a native provider augeas {'export foo': context => '/files/etc/exports', changes => [ "set dir[. = '/foo'] /foo", "set dir[. = '/foo']/client weeble", "set dir[. = '/foo']/client/option[1] ro", "set dir[. = '/foo']/client/option[2] all_squash", ], } www.camptocamp.com / 12/38
  • 13. It is better to wrap things up define kmod::generic( $type, $module, $ensure=present, $command='', $file='/etc/modprobe.d/modprobe.conf' ) { augeas {"${type} module ${module}": context => "/files${file}", changes => [ "set ${type}[. = '${module}'] ${module}", "set ${type}[. = '${module}']/command '${command}'", ], } } www.camptocamp.com / 13/38
  • 14. mcollective has an agent $ mco augeas match /files/etc/passwd/rpinson/shell * [ ======================================> ] 196 / 196 ... wrk1 saja-map-dev /files/etc/passwd/rpinson/shell = /bin/bash wrk3 wrk4 /files/etc/passwd/rpinson/shell = /bin/bash ... www.camptocamp.com / 14/38
  • 15. ... and uses it for discovery $ mco find -S "augeas_match(/files/etc/passwd/rip).size = 0" www.camptocamp.com / 15/38
  • 16. Bindings include Perl, Python, Java, PHP, Haskell, Ruby... require 'augeas' aug = Augeas.open if aug.match('/augeas/load'+lens).length > 0 aug.set('/augeas/load/'+lens+'incl[last()+1]', path) else aug.set('/augeas/load/'+lens+'/lens', lens+'.lns') end (From the mcollective agent) www.camptocamp.com / 16/38
  • 17. The Ruby bindings can be used in Facter Facter.add(:augeasversion) do setcode do begin require 'augeas' aug = Augeas::open('/', nil, Augeas::NO_MODL_AUTOLOAD) ver = aug.get('/augeas/version') aug.close ver rescue Exception Facter.debug('ruby-augeas not available') end end end (From the augeasversion fact) www.camptocamp.com / 17/38
  • 18. Or to write native types def ip aug = nil path = "/files#{self.class.file(resource)}" begin aug = self.class.augopen(resource) aug.get("#{path}/*[canonical = '#{resource[:name]}']/ipaddr") ensure aug.close if aug end end (See https://github.com/domcleal/augeasproviders) www.camptocamp.com / 18/38
  • 19. The case of sshd_config Custom type: define ssh::config::sshd ($ensure='present', $value='') { case $ensure { 'present': { $changes = "set ${name} ${value}" } 'absent': { $changes = "rm ${name}" } 'default': { fail("Wrong value for ensure: ${ensure}") } } augeas {"Set ${name} in /etc/ssh/sshd_config": context => '/files/etc/ssh/sshd_config', changes => $changes, } } www.camptocamp.com / 19/38
  • 20. Using the custom type for sshd_config ssh::config::sshd {'PasswordAuthenticator': value => 'yes', } www.camptocamp.com / 20/38
  • 21. The problem with sshd_config Match groups: Match Host example.com PermitRootLogin no => Not possible with ssh::config::sshd, requires insertions and looping through the configuration parameters. www.camptocamp.com / 21/38
  • 22. A native provider for sshd_config (1) The type: Puppet::Type.newtype(:sshd_config) do ensurable newparam(:name) do desc "The name of the entry." isnamevar end newproperty(:value) do desc "Entry value." end newproperty(:target) do desc "File target." end newparam(:condition) do desc "Match group condition for the entry." end end www.camptocamp.com / 22/38
  • 23. A native provider for sshd_config (2) The provider: require 'augeas' if Puppet.features.augeas? Puppet::Type.type(:sshd_config).provide(:augeas) do desc "Uses Augeas API to update an sshd_config parameter" def self.file(resource = nil) file = "/etc/ssh/sshd_config" file = resource[:target] if resource and resource[:target] file.chomp("/") end confine :true => Puppet.features.augeas? confine :exists => file www.camptocamp.com / 23/38
  • 24. A native provider for sshd_config (3) def self.augopen(resource = nil) aug = nil file = file(resource) begin aug = Augeas.open(nil, nil, Augeas::NO_MODL_AUTOLOAD) aug.transform( :lens => "Sshd.lns", :name => "Sshd", :incl => file ) aug.load! if aug.match("/files#{file}").empty? message = aug.get("/augeas/files#{file}/error/message") fail("Augeas didn't load #{file}: #{message}") end rescue aug.close if aug raise end aug end www.camptocamp.com / 24/38
  • 25. A native provider for sshd_config (4) def self.instances aug = nil path = "/files#{file}" entry_path = self.class.entry_path(resource) begin resources = [] aug = augopen aug.match(entry_path).each do |hpath| entry = {} entry[:name] = resource[:name] entry[:conditions] = Hash[*resource[:condition].split(' ').flatten(1)] entry[:value] = aug.get(hpath) resources << new(entry) end resources ensure aug.close if aug end end www.camptocamp.com / 25/38
  • 26. A native provider for sshd_config (5) def self.match_conditions(resource=nil) if resource[:condition] conditions = Hash[*resource[:condition].split(' ').flatten(1)] cond_keys = conditions.keys.length cond_str = "[count(Condition/*)=#{cond_keys}]" conditions.each { |k,v| cond_str += "[Condition/#{k}="#{v}"]" } cond_str else "" end end def self.entry_path(resource=nil) path = "/files#{self.file(resource)}" if resource[:condition] cond_str = self.match_conditions(resource) "#{path}/Match#{cond_str}/Settings/#{resource[:name]}" else "#{path}/#{resource[:name]}" end end www.camptocamp.com / 26/38
  • 27. A native provider for sshd_config (6) def self.match_exists?(resource=nil) aug = nil path = "/files#{self.file(resource)}" begin aug = self.augopen(resource) if resource[:condition] cond_str = self.match_conditions(resource) else false end not aug.match("#{path}/Match#{cond_str}").empty? ensure aug.close if aug end end www.camptocamp.com / 27/38
  • 28. A native provider for sshd_config (7) def exists? aug = nil entry_path = self.class.entry_path(resource) begin aug = self.class.augopen(resource) not aug.match(entry_path).empty? ensure aug.close if aug end end def self.create_match(resource=nil, aug=nil) path = "/files#{self.file(resource)}" begin aug.insert("#{path}/*[last()]", "Match", false) conditions = Hash[*resource[:condition].split(' ').flatten(1)] conditions.each do |k,v| aug.set("#{path}/Match[last()]/Condition/#{k}", v) end aug end end www.camptocamp.com / 28/38
  • 29. A native provider for sshd_config (8) def create aug = nil path = "/files#{self.class.file(resource)}" entry_path = self.class.entry_path(resource) begin aug = self.class.augopen(resource) if resource[:condition] unless self.class.match_exists?(resource) aug = self.class.create_match(resource, aug) end else unless aug.match("#{path}/Match").empty? aug.insert("#{path}/Match[1]", resource[:name], true) end end aug.set(entry_path, resource[:value]) aug.save! ensure aug.close if aug end end www.camptocamp.com / 29/38
  • 30. A native provider for sshd_config (9) def destroy aug = nil path = "/files#{self.class.file(resource)}" begin aug = self.class.augopen(resource) entry_path = self.class.entry_path(resource) aug.rm(entry_path) aug.rm("#{path}/Match[count(Settings/*)=0]") aug.save! ensure aug.close if aug end end def target self.class.file(resource) end www.camptocamp.com / 30/38
  • 31. A native provider for sshd_config (10) def value aug = nil path = "/files#{self.class.file(resource)}" begin aug = self.class.augopen(resource) entry_path = self.class.entry_path(resource) aug.get(entry_path) ensure aug.close if aug end end www.camptocamp.com / 31/38
  • 32. A native provider for sshd_config (11) def value=(thevalue) aug = nil path = "/files#{self.class.file(resource)}" begin aug = self.class.augopen(resource) entry_path = self.class.entry_path(resource) aug.set(entry_path, thevalue) aug.save! ensure aug.close if aug end end www.camptocamp.com / 32/38
  • 33. Using the native provider for sshd_config sshd_config {'PermitRootLogin': ensure => present, condition => 'Host example.com', value => 'yes', } www.camptocamp.com / 33/38
  • 34. Errors are reported in the /augeas tree augtool> print /augeas//error /augeas/files/etc/mke2fs.conf/error = "parse_failed" /augeas/files/etc/mke2fs.conf/error/pos = "82" /augeas/files/etc/mke2fs.conf/error/line = "3" /augeas/files/etc/mke2fs.conf/error/char = "0" /augeas/files/etc/mke2fs.conf/error/lens = "/usr/share/augeas/lenses/dist/mke2fs.aug:132.10-.49:" /augeas/files/etc/mke2fs.conf/error/message = "Get did not match entire input" www.camptocamp.com / 34/38
  • 35. Other projects using Augeas ● libvirt ● rpm ● Nut ● guestfs ● ZYpp ● Config::Model ● Augeas::Validator www.camptocamp.com / 35/38
  • 36. Future projects ● more API calls ● improved XPath syntax ● more lenses ● more native providers ● DBUS provider ● content validation in Puppet (validator) ● integration in package managers ● finish the Augeas book ● ... ● your idea/project here... www.camptocamp.com / 36/38
  • 37. Questions? http://augeas.net augeas-devel@redhat.com freenode: #augeas www.camptocamp.com / 37/38