SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
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
Configuration Surgery with Augeas

Contenu connexe

Tendances

Kubernetes: An Introduction to the Open Source Container Orchestration Platform
Kubernetes: An Introduction to the Open Source Container Orchestration PlatformKubernetes: An Introduction to the Open Source Container Orchestration Platform
Kubernetes: An Introduction to the Open Source Container Orchestration PlatformMichael O'Sullivan
 
Secrets in Kubernetes
Secrets in KubernetesSecrets in Kubernetes
Secrets in KubernetesJerry Jalava
 
How to build your containerization strategy
How to build your containerization strategyHow to build your containerization strategy
How to build your containerization strategyDocker, Inc.
 
Learning Docker from Square One
Learning Docker from Square OneLearning Docker from Square One
Learning Docker from Square OneDocker, Inc.
 
Docker: From Zero to Hero
Docker: From Zero to HeroDocker: From Zero to Hero
Docker: From Zero to Herofazalraja
 
Comprehensive Terraform Training
Comprehensive Terraform TrainingComprehensive Terraform Training
Comprehensive Terraform TrainingYevgeniy Brikman
 
Deep Dive - Infrastructure as Code
Deep Dive - Infrastructure as CodeDeep Dive - Infrastructure as Code
Deep Dive - Infrastructure as CodeAmazon Web Services
 
KubeCon EU 2016: Kubernetes Storage 101
KubeCon EU 2016: Kubernetes Storage 101KubeCon EU 2016: Kubernetes Storage 101
KubeCon EU 2016: Kubernetes Storage 101KubeAcademy
 
Infrastructure as Code with Terraform and Ansible
Infrastructure as Code with Terraform and AnsibleInfrastructure as Code with Terraform and Ansible
Infrastructure as Code with Terraform and AnsibleDevOps Meetup Bern
 
Reusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesReusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesYevgeniy Brikman
 
Performance Tuning Oracle Weblogic Server 12c
Performance Tuning Oracle Weblogic Server 12cPerformance Tuning Oracle Weblogic Server 12c
Performance Tuning Oracle Weblogic Server 12cAjith Narayanan
 
Kubernetes - introduction
Kubernetes - introductionKubernetes - introduction
Kubernetes - introductionSparkbit
 
Terraform Introduction
Terraform IntroductionTerraform Introduction
Terraform Introductionsoniasnowfrog
 
Creating AWS infrastructure using Terraform
Creating AWS infrastructure using TerraformCreating AWS infrastructure using Terraform
Creating AWS infrastructure using TerraformKnoldus Inc.
 
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)Adin Ermie
 
Terraform: An Overview & Introduction
Terraform: An Overview & IntroductionTerraform: An Overview & Introduction
Terraform: An Overview & IntroductionLee Trout
 

Tendances (20)

Docker & kubernetes
Docker & kubernetesDocker & kubernetes
Docker & kubernetes
 
Terraform Basics
Terraform BasicsTerraform Basics
Terraform Basics
 
Terraform
TerraformTerraform
Terraform
 
Kubernetes: An Introduction to the Open Source Container Orchestration Platform
Kubernetes: An Introduction to the Open Source Container Orchestration PlatformKubernetes: An Introduction to the Open Source Container Orchestration Platform
Kubernetes: An Introduction to the Open Source Container Orchestration Platform
 
Secrets in Kubernetes
Secrets in KubernetesSecrets in Kubernetes
Secrets in Kubernetes
 
How to build your containerization strategy
How to build your containerization strategyHow to build your containerization strategy
How to build your containerization strategy
 
Learning Docker from Square One
Learning Docker from Square OneLearning Docker from Square One
Learning Docker from Square One
 
Docker: From Zero to Hero
Docker: From Zero to HeroDocker: From Zero to Hero
Docker: From Zero to Hero
 
Comprehensive Terraform Training
Comprehensive Terraform TrainingComprehensive Terraform Training
Comprehensive Terraform Training
 
Deep Dive - Infrastructure as Code
Deep Dive - Infrastructure as CodeDeep Dive - Infrastructure as Code
Deep Dive - Infrastructure as Code
 
KubeCon EU 2016: Kubernetes Storage 101
KubeCon EU 2016: Kubernetes Storage 101KubeCon EU 2016: Kubernetes Storage 101
KubeCon EU 2016: Kubernetes Storage 101
 
Infrastructure as Code with Terraform and Ansible
Infrastructure as Code with Terraform and AnsibleInfrastructure as Code with Terraform and Ansible
Infrastructure as Code with Terraform and Ansible
 
Reusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesReusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modules
 
Performance Tuning Oracle Weblogic Server 12c
Performance Tuning Oracle Weblogic Server 12cPerformance Tuning Oracle Weblogic Server 12c
Performance Tuning Oracle Weblogic Server 12c
 
Terraform on Azure
Terraform on AzureTerraform on Azure
Terraform on Azure
 
Kubernetes - introduction
Kubernetes - introductionKubernetes - introduction
Kubernetes - introduction
 
Terraform Introduction
Terraform IntroductionTerraform Introduction
Terraform Introduction
 
Creating AWS infrastructure using Terraform
Creating AWS infrastructure using TerraformCreating AWS infrastructure using Terraform
Creating AWS infrastructure using Terraform
 
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
 
Terraform: An Overview & Introduction
Terraform: An Overview & IntroductionTerraform: An Overview & Introduction
Terraform: An Overview & Introduction
 

Similaire à Configuration Surgery with Augeas

Configuration surgery with Augeas (OggCamp 12)
Configuration surgery with Augeas (OggCamp 12)Configuration surgery with Augeas (OggCamp 12)
Configuration surgery with Augeas (OggCamp 12)Dominic Cleal
 
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
 
Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shellsascha_klein
 
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
 

Similaire à Configuration Surgery with Augeas (20)

Configuration surgery with Augeas (OggCamp 12)
Configuration surgery with Augeas (OggCamp 12)Configuration surgery with Augeas (OggCamp 12)
Configuration surgery with Augeas (OggCamp 12)
 
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
 
Groovy on the Shell
Groovy on the ShellGroovy on the Shell
Groovy on the Shell
 
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
 

Plus de Puppet

Puppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet
 
Puppetcamp r10kyaml
Puppetcamp r10kyamlPuppetcamp r10kyaml
Puppetcamp r10kyamlPuppet
 
2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)Puppet
 
Puppet camp vscode
Puppet camp vscodePuppet camp vscode
Puppet camp vscodePuppet
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twentiesPuppet
 
Applying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codeApplying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codePuppet
 
KGI compliance as-code approach
KGI compliance as-code approachKGI compliance as-code approach
KGI compliance as-code approachPuppet
 
Enforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationEnforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationPuppet
 
Keynote: Puppet camp compliance
Keynote: Puppet camp complianceKeynote: Puppet camp compliance
Keynote: Puppet camp compliancePuppet
 
Automating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowAutomating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowPuppet
 
Puppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet
 
Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Puppet
 
Accelerating azure adoption with puppet
Accelerating azure adoption with puppetAccelerating azure adoption with puppet
Accelerating azure adoption with puppetPuppet
 
Puppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet
 
ServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkPuppet
 
Take control of your dev ops dumping ground
Take control of your  dev ops dumping groundTake control of your  dev ops dumping ground
Take control of your dev ops dumping groundPuppet
 
100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy SoftwarePuppet
 
Puppet User Group
Puppet User GroupPuppet User Group
Puppet User GroupPuppet
 
Continuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsContinuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsPuppet
 
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyThe Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyPuppet
 

Plus de Puppet (20)

Puppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepo
 
Puppetcamp r10kyaml
Puppetcamp r10kyamlPuppetcamp r10kyaml
Puppetcamp r10kyaml
 
2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)
 
Puppet camp vscode
Puppet camp vscodePuppet camp vscode
Puppet camp vscode
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twenties
 
Applying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codeApplying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance code
 
KGI compliance as-code approach
KGI compliance as-code approachKGI compliance as-code approach
KGI compliance as-code approach
 
Enforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationEnforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automation
 
Keynote: Puppet camp compliance
Keynote: Puppet camp complianceKeynote: Puppet camp compliance
Keynote: Puppet camp compliance
 
Automating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowAutomating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNow
 
Puppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet: The best way to harden Windows
Puppet: The best way to harden Windows
 
Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020
 
Accelerating azure adoption with puppet
Accelerating azure adoption with puppetAccelerating azure adoption with puppet
Accelerating azure adoption with puppet
 
Puppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael Pinson
 
ServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin Reeuwijk
 
Take control of your dev ops dumping ground
Take control of your  dev ops dumping groundTake control of your  dev ops dumping ground
Take control of your dev ops dumping ground
 
100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software
 
Puppet User Group
Puppet User GroupPuppet User Group
Puppet User Group
 
Continuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsContinuous Compliance and DevSecOps
Continuous Compliance and DevSecOps
 
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyThe Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
 

Dernier

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
🐬 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
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
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
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
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
 
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
 
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
 
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
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 

Dernier (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
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
 
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
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
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...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
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
 
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
 
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
 
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
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Configuration Surgery with Augeas

  • 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