Назад | Перейти на главную страницу

Как сгенерировать хорошие сериалы для зон DNS с помощью Puppet?

Моя традиция заключается в установке всех серийных номеров зон на отметку времени при модификации. Теперь, когда Puppet - это моя новая религия, я хочу установить серийные временные метки при создании файлов зон из экспортированных ресурсов. Несколько упрощенный пример может выглядеть так:

file { "/tmp/dafile": content = inline_template("<%= Time.now.to_i %>"), }

Проблема с этим подходом заключается в том, что контент будет все время отличаться, что (в конечном итоге) вызовет перестройку файлов зоны при каждом опросе конфигурации марионетки.

Есть ли способ вставить метку времени без включения ее в данные, которые сравниваются с предыдущим состоянием?

Не используйте шаблон, если вы попытаетесь использовать там серийный номер, проблема в том, что вы будете каждый раз вносить изменения.

У меня есть две идеи:

  1. Создайте подходящий тип, который может управлять DNS с помощью обновлений DNS через стандартный API. Затем позвольте BIND самому увеличить серийный номер.
  2. Используйте шаблон фрагмента файла для каждого элемента в вашей зоне DNS и сделайте так, чтобы файл основной зоны обновлялся только при их изменении. Вы делаете это с помощью exec «обновления зоны», который объединяет ваши части в последнюю зону, включая заголовок. Разница между большинством решений для фрагментов файлов будет заключаться в том, что вы генерируете серийный номер своей зоны на основе временной метки или чего-то подобного, который должен срабатывать только при изменении частей, что позволяет избежать изменений постоянного серийного номера, которые вы можете получить из шаблона.

Вот несколько примеров шаблона фрагмента файла:

http://projects.puppetlabs.com/projects/puppet/wiki/Generating_a_config_file_from_fragments

https://github.com/ripienaar/puppet-concat

Как насчет использования метки времени файла:

file { "/tmp/dafile": content = inline_template("<%= File.mtime("/tmp/dafile").to_i %>"), }

Единственное, что это, вероятно, будет запускаться на каждом клиенте и может обновлять временную метку файла для каждого запуска. Если нет, то это должно соответствовать вашим требованиям.

Как насчет следующего,

$utime_serial = inline_template("<%= Time.now.to_i %>")

file { "/var/named/$domain.hosts":
          content => template("named/$domain.hosts.erb"),
          owner => root,
          group => named,
          mode => 0640,
}

где файл шаблона erb содержит,

$TTL 1D
@             IN      SOA       galaxy.example.com.  sysadmin.example.com.  (
                               <%=utime_serial %>       ; Serial
                                8H             ; Refresh
                                2H             ; Retry
                                4W             ; Expire
                                1D )           ; Minimum

Можете ли вы запускать внешние команды из марионетки (я использую cfengine, не знаю марионетку) Что об этом /bin/date '+%Y%m%d00'

Для этого я использовал следующее:

file {"${zone['zoneName']}.db":
        name            => "/var/lib/bind/.temp/${zone['zoneName']}.db",
        ensure          => file,
        content         => template('dns/bind/zone.db.erb'),
        owner           => 'root',
        group           => 'bind',
        mode            => 'ug=r,o=',
        require         => File['/var/lib/bind/.temp'],
        notify          => Exec["updateSerial-${zone['zoneName']}"]
}

exec {"updateSerial-${zone['zoneName']}":
        command         => "/bin/sed \"s/#SERIAL#/$(/bin/date '+%s')/\" '/var/lib/bind/.temp/${zone['zoneName']}.db' > '/var/lib/bind/${zone['zoneName']}.db'",
        refreshonly     => true,
        require         => File["${zone['zoneName']}.db"],
        notify          => Service['bind']
}

В шаблоне есть #SERIAL# в качестве заполнителя, после создания временного файла Exec получает уведомление, которое затем использует sed и date чтобы заменить заполнитель текущей меткой времени unix, наконец, записав файл в правильное место.

Я обычно использовал время модификации манифест или файл hiera, в котором вы объявляете записи хоста и преобразовать это в подходящую метку времени для сериала. (Вы также можете использовать самый новый из набора файлов, если он разделен на несколько файлов, или отметку времени для самого последнего изменения, если оно осуществляется по другому маршруту, например, к базе данных)

К сожалению, максимальный серийный номер представляет собой 32-битное целое число без знака, поэтому вы можете использовать только числа до 2147483647. К сожалению, это не позволяет нам просто использовать секунды с эпохи unix в качестве серийного номера.. Вместо этого по умолчанию используется формат YYYYMMDDxx, но для этого необходимо иметь текущий серийный номер в качестве состояния, если вы уже установили его на ту же дату.

В качестве альтернативы, не требующей чтения файла и увеличения числа, я использую следующий встроенный шаблон:

$serial_mtime_file = '/etc/puppetlabs/code/environments/production/site/profile/manifests/dns_dhcp_pxe.pp'
$serial_secs = inline_template("<%= File.mtime(@serial_mtime_file).strftime(\"%y%j\").to_s + (File.mtime(@serial_mtime_file).to_i % 86400).to_s %>")

notify { "Created magical serial number ${serial_secs}": }
validate_numeric($serial_secs)

Это дает вам формат YYDDDsssss (2 цифры года, 3 цифры дня в году, 5 цифр секунды в день), который будет работать до 2099 года (если вы начнете с 2000, как я сделал выше) и позволяет обновлять каждую секунду до тех пор. Это позволяет использовать эту переменную в качестве аргумента для любого существующего модуля, который вы хотите использовать для создания конфигураций привязки, вместо того, чтобы использовать шаблон, из которого вы можете считывать существующий серийный номер (для увеличения).

Так что с шаблонами все в порядке, если вы проявите немного изобретательности в отношении того, где вы получаете время для установки серийного номера с помощью :)

Я использовал вышеуказанное с модулем camptocamp / bind puppetforge, и это работает правильно