puppet agent con variables

a veces necesitamos que una clase de puppet reciba variables desde el punto en el que se ejecuta el agente, desde el entorno. Por ejemplo, una clase de puppet encargada de comprobar si hay conectividad a un host remoto, a un puerto dado.

si antes de lanzar el agente fijamos variables de entorno con la forma FACTER_variable, luego serán visibles desde el manifest.

El problema es que este procedimiento implica “meter” el valor en la maquina de alguna forma (via ssh?), con lo que abrimos la puerta a otras vias de comprobación, mas allá de puppet agent

otra opcion, teniendo Foreman+Katello a mano es usar los smart class parameters, que se pueden definir con “matchers”, de forma que una asignacion del parametro solo aplique a un hostname (fqdn) determinado (!)

puppet class: check remote ports

probablemente utilizando este codigo en ruby como una funcion, seria suficiente?

aunque es mas sencillo utilizar los superpoderes de netcat:

nc -z <ip remota> <puerto remoto>

si nos devuelve 0, es que todo ha ido bien: hay alguien al otro lado escuchando. En cualquier otro caso, error.

la clase de puppet que hace el trabajo queda asi:

# check.pp

class checkport::check (

  $port         =       hiera('port'),
  $address      =       hiera('address'),

) {

#  notify { "/usr/bin/nc -z ${address} ${port}": }

  package { 'nc':
    ensure      =>      'present',
  }

  exec { 'checking remote port':
    command     =>      "/usr/bin/nc -z ${address} ${port}",
    require     =>      Package['nc'],
  }

}

Aunque si queremos comprobar varios puertos, mejor seria agrupar los datos en un hash, e iterar sobre ellos. Al viejo estilo:

# check.pp

class checkport::check (


) {

  $remotes      =       hiera_hash('remotes')

#  notify { "/usr/bin/nc -z ${address} ${port}": }
  notify { "destino: ${remotes} ": }

  package { 'nc':
    ensure      =>      'present',
  }

  define comprobador() {
    $remotes    =       $checkport::check::remotes
    $puerto     =       $remotes[$name]

    notify { "checking ${name} ${puerto}": }

    exec { "checking ${name}":
      command   =>      "/usr/bin/nc -z -w 2 ${name} ${puerto}",
#      command  =>      "/bin/echo '/usr/bin/nc -z ${name} ${puerto} \n' >>/tmp/exec.txt",
      require   =>      Package['nc'],
    }
  }


  $indexes = keys($remotes)

  comprobador { $indexes: }

}

Un hash de ejemplo seria:

---
remotes:
  172.17.0.2:
    80
  172.17.0.1:
    80

 

hiera, a vueltas con puppet apply

El caso de aplicación de puppet con hiera permite trasladar mucha de la información de los manifiestos a hiera, a la configuración. Con una jerarquía bien definida, podemos tener la configuración de cada nodo en un fichero, o solamente lo que le es especifico, en caso de usar hashes de variables, cargados con hiera_hash. El problema viene con la aplicación de puppet en local: tenemos que descargar el conjunto de módulos/manifiestos/configuraciones, y después lanzar el puppet apply en local. Teóricamente el hostname es la via de entrada única al catálogo (el catalogo es “el conjunto de propiedades que aplican sobre un host”).

Un ejemplo funcional incluye un hiera.yaml con los ficheros de hiera dentro de los módulos, y solamente un fichero por fqdn de host, más un fichero común.