Usando o hiera para acessar fatos de outro nó

2

O que estamos tentando fazer é gerar regras de firewall (puppetlabs / firewall) para o iptables. Nossos nós são agrupados de maneira conceitual:

-- site1
---- shared1
------ specific1
------ specific2
---- shared2
------ specific3
------ specific4

O nó "specific4" sempre precisará acessar a porta 8080 em "shared2" e a porta 10000 em "site1". "specific1" também precisará acessar o 8080 em "shared1". As regras sempre serão as mesmas por nó, mas elas dependerão de qual grupo elas são separadas.

Eu estou lutando para encontrar uma maneira de representar isso no hiera sem duplicação. É possível obter fatos de um nó completamente separado?

Acho que quero fazer algo assim (simplificado):

--
hosts:
  host specific4:
    rules:
      rule:
        port: 8080
        ip: get_ip(get_my_shared())

Mas, obviamente, você não pode chamar funções de um arquivo yaml . A melhor maneira de fazer isso seria usar fatos personalizados? Eu ainda não usei hiera - então não tenho certeza das melhores práticas e quais não. Qualquer gentil empurra na direção certa seria mais apreciada.

Editar:

Esta é a solução que eu usei, mas se eu puder usar recursos exportados, eu posso remover a dependência do comando puppetdb-query.

# helper for creating rules from an array
define firewall_rules($port, $service_type) {
    $source = $name
    firewall { "$port $service_type $source":
        proto       => 'tcp',
        dport       => $port,
        state       => 'NEW',
        source      => "$source",
        action      => 'accept'
    }
}

class profile::specific inherits profile {
    $site = hiera('site')
    $shared = hiera('shared')
    $query = "site=\"$site\" and shared=\"$shared\""
    $shared_hosts = query_nodes($query)
    $specific_port = hiera('specific_ports', '8080')
    firewall_rules { $shared_hosts:
        port           => $specific_port,
        service_type   => 'SPECIFIC'
    }
}

Eu, então, exporto os fatos site e shared com base em dados hiera e usando puppet-stdlib para carregá-los de file resources no host.

class profile::facts {

    $site       = hiera('site', 'none')
    $shared     = hiera('shared', 'none')
    $specific   = hiera('specific', 'none')
    $role       = hiera('role', 'none')
    $grouping   = "site=$site\nshared=$shared\nspecific=$specific\nrole=$role"

    notify { "facts being set: $grouping ": }

    file { ['/etc/facter/', '/etc/facter/facts.d/']:
        ensure  => directory,
        owner   => 'root',
        group   => 'root'
    }->
    file { '/etc/facter/facts.d/grouping.txt':
        ensure  => file,
        owner   => 'root',
        group   => 'root',
        mode    => '0775',
        content => $grouping
    }
}

Como eu disse, isso funciona, mas eu prefiro usar recursos exportados, se possível. O problema que eu encontrei foi que o recurso que está fazendo a exportação também não pôde exportar seu próprio IP / Host para coleta. Talvez eu tenha perdido alguma coisa, mas não acho que seja possível, já que a exportação acontece quando o recurso é analisado, não quando o nó que contém esse recurso é realizado.

    
por Josh Smeaton 30.04.2013 / 12:11

2 respostas

3

Assim, você deseja que determinados hosts obtenham informações dos fatos de outro host, mas os anfitriões dos quais os fatos vêm variam dependendo da configuração do host específico. Isso está correto?

Em caso afirmativo, recomendo também o uso de recursos exportados e o uso de tags para especificar o recurso específico a ser usado. A razão para isso é que existem basicamente duas maneiras de um host obter os dados de outro host. Ambos requerem a ativação de storeconfigs. Uma é para o mestre de marionetes fazer pesquisas explícitas em qualquer que seja o seu backend storeconfigs; Eu não sei de nenhum módulo que encapsule isso, então você pode ter que escrever o seu próprio. A outra é que o host de origem exporte recursos que contenham seus fatos; isso é mais fácil e eu vou descrever abaixo.

Isso será mais fácil se você criar seu próprio tipo de recurso para agrupar as regras de firewall. Isso evita colisões com quaisquer outras classes que estejam exportando regras de firewall.

define site_firewall ($ipaddr) {
  firewall { '500 allow site access':
    chain       => 'OUTPUT',
    destination => $ipaddr,
    proto       => 'tcp',
    port        => 10000,
  }
}

Em seguida, cada um dos seus sites deve exportar sua própria definição para site_firewall :

@@site_firewall { $hostname:
  ipaddr => $ipaddress,
}

Em hiera, você define em algum lugar em sua hierarquia o site do qual cada host é membro:

sitename: site1

Em seguida, nas suas classes de host, você instancia a definição site_firewall apropriada:

Site_firewall <<| name == hiera('sitename', 'default') |>>

Uma configuração semelhante seria aplicada aos hosts compartilhados.

Se você precisar de regras de firewall no site e em hosts compartilhados, deverá usar tags em vez de nomes, pois haverá várias regras de firewall para um determinado host. Nos anfitriões específicos:

@@firewall { "500 allow site traffic from ${hostname}":
  tag    => hiera('sitename', 'default-site'),
  source => $ipaddress,
  proto  => 'tcp',
  port   => 10000,
}
@@firewall { "500 allow shared traffic from ${hostname}":
  tag    => hiera('sharedname', 'default-shared'),
  source => $ipaddress,
  proto  => 'tcp',
  port   => 8080,
}

Nos hosts do site, você só precisa coletar as regras de firewall para esses hosts:

Firewall <<| tag == $hostname |>>

Editar: Aha. Acho que encontrei o problema que você estava enfrentando com recursos exportados. No mínimo, isso é uma pegadinha que documentarei aqui para uma boa medida.

Se você tiver um recurso com parâmetros padrão e exportar esse recurso sem definir explicitamente esses parâmetros, os padrões de parâmetro serão fornecidos pelo host realizando o recurso, não o exportando.

Em outras palavras, se você tiver essa definição de tipo de recurso:

define foo ($bar = $fqdn) {
  notice($bar)
}

E você o exporta do host baz.example.com:

@@foo { 'title': }

E você percebe isso no host quux.example.com:

Foo <<| |>>

Em seguida, o valor de $bar será "quux.example.com".

Se, em vez disso, você exportá-lo de baz.example.com assim:

@@foo { 'title': bar => $fqdn }

Em seguida, o valor de $bar será de fato "baz.example.com".

    
por 08.05.2013 / 20:37
2

Bem, eu acho que uma boa opção para o seu uso é habilitar "storeconfigs" e então usar "recursos exportados". Aqui você pode encontrar alguma documentação sobre este tópico, incluindo alguns exemplos: link

link

    
por 30.04.2013 / 12:15

Tags