Как создать хорошие сериалы для зон DNS с Puppet?
Моя традиция состоит в том, чтобы установить все серийные номера зоны на метку времени при модификации. Теперь, когда Puppet - моя новая религия, я хочу установить серийные метки времени при создании файлов зон из экспортированных ресурсов. Несколько упрощенный пример может выглядеть так:
file { "/tmp/dafile": content = inline_template("<%= Time.now.to_i %>"), }
Проблема с этим подходом заключается в том, что содержимое будет все время отличаться, что (в конечном итоге) вызовет перестройку файлов зон при каждом опросе конфигурации марионеток.
Можно ли каким-то образом вставить временную метку, не добавляя ее в данные, которые сравниваются с предыдущим состоянием?
6 ответов
Не используйте шаблон, если вы попытаетесь использовать серийный номер, проблема заключается в том, что вы будете продолжать вносить изменения каждый раз.
У меня есть две идеи:
- Создайте правильный тип, который может управлять DNS с помощью обновлений DNS через стандартный API. Затем позвольте BIND самому увеличивать серийный номер.
- Используйте шаблон фрагмента файла для каждого элемента в вашей DNS-зоне и сделайте так, чтобы файл основной зоны обновлялся только при их изменении. Вы делаете это, выполняя exec 'zone refresh', который объединяет ваши детали в конечную зону, включая заголовок. Разница между большинством решений с фрагментами файлов заключается в том, что вы генерируете серийный номер своей зоны из временной отметки или чего-то подобного, которая должна срабатывать только при изменении частей, что позволяет избежать постоянных изменений серийного номера, которые вы получите из шаблона.
Некоторые примеры шаблона фрагмента файла приведены здесь:
http://projects.puppetlabs.com/projects/puppet/wiki/Generating_a_config_file_from_fragments
Как насчет использования метки времени файла:
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
Можете ли вы запускать внешние команды изнутри puppet (я использую cfengine, не знаю puppet) Что об этом /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 (год с двумя цифрами, день года с тремя цифрами, секунда в день с пятью цифрами), который будет работать до 2099 года (если вы начнете с 2000 года, как я делал выше) и позволяет обновлять каждую секунду до тех пор. Это позволяет использовать эту переменную в качестве аргумента для любого существующего модуля, который вы хотите использовать для создания конфигов связывания, вместо того, чтобы нуждаться в шаблоне, из которого вы можете считывать существующий последовательный (из приращения) из.
Так что шаблоны в порядке, если вы немного задумаетесь о том, откуда у вас время, чтобы установить серийный номер с помощью:)
Я использовал вышеописанное с модулем camptocamp/bind puppetforge, и это работает правильно