8 votes

Ressources exportées par Puppet pour les variables des fichiers .erb ?

Scénario : mon fichier de configuration est défini par un fichier .erb qui contient l'extrait ci-dessous.

<% backupclients.each do |backup_files| -%>
Job {
  Name = "Server"
  JobDefs = "DefaultJob"
  Client = <%= backup_files %>-fd
  Pool = TeraMonth
  Write Bootstrap = "/var/lib/bacula/<%= backup_files %>.bsr"
}
<% end -%>

Le fichier de configuration du serveur doit contenir une entrée répétée pour chaque hôte client. Si je devais créer un simple tableau, cela fonctionnerait sans problème. Ce que je veux faire, cependant, c'est que chaque hôte s'enregistre lui-même et collecte ensuite les données à l'aide de la fonction <<| |>> similaire à ce que l'on ferait avec le pragma nagios_* types.

En exemple type pour cela, il faut exporter un type.

class ssh {
  @@sshkey { $hostname: type => dsa, key => $sshdsakey }
  Sshkey <<| |>>
}

Cependant, je n'arrive pas à comprendre comment écrire un type ou le référencer d'une manière qui me permettrait de lire ce tableau de valeurs à partir de l'élément .erb modèle. Existe-t-il un moyen d'utiliser les ressources exportées en combinaison avec une boucle variable dans un modèle .erb fichier ?

5voto

Kyle Smith Points 9443

Donc, pour répondre directement à votre question, je ne pense pas que l'obtention d'une liste des ressources exportées soit une bonne chose. directement de l'erb est possible. Cela est dû à la nature des ressources exportées. Pour Puppet, ce ne sont que des ressources supplémentaires qui doivent être créées sur l'hôte.

Mais il existe un moyen d'accomplir ce que vous cherchez à faire. Je le fais à plusieurs endroits dans mon environnement.

Nous créons ici un répertoire de fichiers, un pour chaque hôte que nous voulons marquer comme "bacula_client". Nous utilisons le fichier purge , force y recurse pour supprimer les fichiers qui ne sont pas gérés par Puppet (c'est-à-dire si vous voulez supprimer un système de cette "liste").

class bacula::client {

  @@file { "/etc/bacula_clients/$fqdn":
    ensure => present,
    content => "",
    require => File['/etc/bacula_clients'],
    tag => "bacula_client",
  }

}

class bacula::server {

  #
  # .. include whatever else the server requires, like package {} file {} service {}
  #

  file { "/etc/bacula_clients":
    ensure => directory,
    purge => true,
    recurse => true,
    force => true,
  }

  # Populate directory of client files.
  File <<| tag == "bacula_client" |>>

}

Ensuite, nous utilisons du code Ruby dans le fichier .erb pour rechercher des fichiers dans ce répertoire et agir en conséquence :

<% 
bacula_clients_dir = '/etc/bacula_clients'
d = Dir.open(bacula_clients_dir)

# Remove directories from the list of entries in the directory (specifically '.' and '..'):
backupclients = d.entries.delete_if { |e| File.directory? "#{bacula_clients_dir}/#{e}" }

backupclients.each do |backup_files| 
-%>
Job {
  Name = "Server"
  JobDefs = "DefaultJob"
  Client = <%= backup_files %>-fd
  Pool = TeraMonth
  Write Bootstrap = "/var/lib/bacula/<%= backup_files %>.bsr"
}
<% end -%>

4voto

Tom Points 720

Eh bien, j'ai d'abord renoncé et j'ai mis mon @@ sur le type de fichier. L'avantage est que cela utilise toujours les variables sur l'hôte du client.

class bacula-client ($database = false) {
    @@file { "${hostname}-bacula-client.conf":
            mode => 600,
            owner => bacula,
            group => root,
            path => "/etc/bacula/conf.d/${hostname}-client.conf",
            content => template("bacula-dir-cliententry.erb"),
            tag => 'bacula-client',
            notify => Service[bacula-director]
    }

    ...
}

Cela me permet d'utiliser des entrées dans le fichier erb telles que :

<% if has_variable?("database") and database== "true" %>
    ...
<% end -%>

et des déclarations dans mes fichiers site.pp telles que : class { bacula-client: database => "true" }

Pour gérer le répertoire lui-même :

class bacula-director {
        file { '/etc/bacula/conf.d':
            ensure => directory,
            owner => bacula,
            group => root,
            mode => 600,
            purge => true,
            recurse => true
        }

        ...
}

La purge et la récursivité permettent d'éliminer tout ce qui n'est pas défini. Lorsque je mets un hôte hors ligne, puppetstoredconfigclean $hostname nettoiera les faits et la prochaine exécution de Puppet sur l'administrateur réinitialisera la configuration de manière appropriée.

Enfin, le logiciel Bacula Director lui-même me permet de faire ce qui suit à la fin de mon fichier bacula-dir.conf :

@|"sh -c 'for f in /etc/bacula/conf.d/*.conf ; do echo @${f} ; done'"

Il ne semble donc pas y avoir de moyen direct d'utiliser un modèle ERB pour un ensemble de ressources collectées, mais il est possible de collecter des types de ressources. Cela peut inclure des types Augeas pour tout mettre dans un seul fichier, ou un hack de collecte de fichiers dans une configuration. Cela n'inclut pas encore ce que je cherchais dans la question, cependant.

1voto

Zzzach... Points 3379

J'ai trouvé une méthode utilisant le service PuppetDB qui fonctionne assez bien dans cette situation, bien qu'elle soit un peu bricolée. Pour utiliser cette méthode, il faut que PuppetDB soit opérationnel (ce que vous devriez déjà avoir puisque vous utilisez des ressources exportées) et que l'API de PuppetDB puisse être interrogée depuis le puppetmaster (localhost).

Ensuite, vous devrez exporter toutes les ressources que vous souhaitez rassembler dans votre tableau dans un répertoire dédié du système de fichiers. Ce chemin de répertoire sera utilisé pour identifier de manière unique les ressources cibles.

Ensuite, dans votre modèle, faites quelque chose comme ceci :

    require 'rest_client'
    require 'json'
    resources=JSON.parse(RestClient.get("http://localhost:8080/v2/nodes/#{nodename}/resources", {:accept => :json}))

    retVal = Array.new
    resources.each do |resource|
       if resource["title"] =~ /^#{pathRegex}$/
           retVal.push(resource["title"])
       end
    end

Où nodename est le FQDN du serveur, pathRegex est le chemin de recherche mentionné ci-dessus, formaté comme une Regex Ruby, et retVal est le tableau complété. Cela permet de tirer parti du fait que le modèle est traité sur le puppetmaster, de sorte que des identifiants API spéciaux ne sont pas nécessaires. Cela suppose également que la ressource namevar est le chemin pleinement qualifié des fichiers cibles, si vous avez des namevars complexes et que vous utilisez l'attribut path, une logique plus complexe sera nécessaire. Notez également que toutes les ressources sont renvoyées, qu'elles soient exportées ou locales. Les données renvoyées ont de nombreux attributs qui peuvent être utilisés pour une logique plus complexe si nécessaire.

C'est un peu bricolé, mais cela fonctionne bien.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X