Acrescentar uma linha a um arquivo se ele não existir usando Puppet

1

Eu tenho um tipo de recurso definido para anexar uma linha a um arquivo, se ele não existir, conforme abaixo:

define appendLineToFile($file, $line, $user) {
    exec { "echo \"\n$line\" >> \"$file\"":
        path => '/bin',
        unless => "grep -Fx \"$line\" \"$file\"",
        user => $user,
    }
}

Funciona muito bem na maior parte do tempo, mas não em situações como abaixo, em que você tem aspas duplas que precisam ser escapadas duas vezes (o que é muito confuso para ler):

appendLineToFile { 'Add http_proxy & https_proxy to sudoers':
    file => '/etc/sudoers',
    line => "Defaults env_keep += \\"http_proxy https_proxy\\"",
    user => root,
}

Existe uma maneira de alterar o tipo de recurso definido que não requer escape como tal? por exemplo,

    line => "Defaults env_keep += \"http_proxy https_proxy\"",
    
por khoomeister 23.09.2011 / 16:19

3 respostas

3

Duas coisas:

Augeas

O Puppet integra-se bem com uma ferramenta chamada Augeas :

Augeas is a lovely tool that treats config files (well, anything really, but it’s mostly about config files) as trees of values. You then modify the tree as you like, and write the file back.

Para arquivos que o Augeas entende, é muito fácil fazer alterações programáticas sem ter que se preocupar com comentários, espaço em branco, análise ou qualquer outro detalhe. Além disso, o Augeas suporta o formato de arquivo sudoers .

Sudoers inclui

A partir do sudo versão 1.7.2, ele suporta uma diretiva includedir , que permite especificar um diretório para estender sudoers. Os arquivos nesse diretório devem conter snippets de código sudoers válidos, e o sudo os lerá e usará exatamente como se tivessem sido incluídos no arquivo original. Eu faço uso disso no Puppet com um recurso personalizado:

define sudo-include( content ) {
    file { "/etc/sudoers.d/$name":
        content => $content,
        mode => 0440,
        user => root,
        group => root,
    }
}

[...]

sudo-include { "moreusers":
    content => "\
joe   ALL=(ALL)  ALL
mike  ALL=(ALL)  NOPASSWD:ALL
"
}

Quando você usa o recurso sudo-include , ele cria automaticamente o arquivo no lugar certo com as permissões corretas e tudo o que você precisa fazer é fornecer um nome e um conteúdo.

    
por 24.09.2011 / 09:44
4

Handyman5 sugeriu o uso de Augeas . Aqui está um exemplo de como isso pode ser feito:

Se você quer ter ambas as entradas em uma linha usando += , você pode usar Augeas desta forma:

augeas { "Add http_proxy & https_proxy to sudoers":
   context => "/files/etc/sudoers",
   # Only if no node exists for http_proxy
   onlyif  => "match Defaults/env_keep/var[. = 'http_proxy'] size==0",
   changes => [
     # Create a new Defaults line for the two variables
     "ins Defaults after Defaults[last()]",
     # Make this Defaults line a += type
     "clear Defaults[last()]/env_keep/append",
     # assign values to the two variables
     "set Defaults[last()]/env_keep/var[1] http_proxy",
     "set Defaults[last()]/env_keep/var[2] https_proxy",
   ],
 }

No entanto, você pode querer evitar correlacionar as duas variáveis, para que ainda funcione se uma variável já estiver definida. Nesse caso, eu dividiria o problema em dois, criando um novo nó Padrões apenas para http_proxy e reutilizando-o (com uma dependência) para https_proxy.

    
por 12.12.2011 / 22:16
0

A menos que você esteja usando o Debian Squeeze, que usa dash em vez de bash como shell padrão, você pode usar aspas simples no parâmetro para echo e usar -e , que ativa caracteres de escape limitados.

Veja também os módulos comuns para pelo menos duas implementações do que você está fazendo.

    
por 23.09.2011 / 21:51

Tags