Я хотел бы написать марионеточный манифест для установки и настройки приложения на целевых серверах.
Части этого манифеста подлежат повторному использованию. Таким образом я использовал define
для определения моей многоразовой функциональности. При этом у меня всегда проблема с тем, что есть части определения, которые нельзя использовать повторно.
Простой пример - это набор файлов конфигурации, которые необходимо создать. Эти файлы должны быть помещены в тот же каталог. Этот каталог необходимо создать только один раз.
Пример:
node.pp
node 'myNode.in.a.domain' {
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
}
}
mymodule.pp
define mymodule::addconfig ($param) {
$config_dir = "/the/directory/"
#ensure that directory exits:
file { $config_dir:
ensure => directory,
}
#create the configuration file:
file { $name:
path => "${config_dir}/${name}"
content => template('a_template.erb'),
require => File[$config_dir],
}
}
Этот пример будет потерпеть поражение, потому что теперь ресурс file {$config_dir:
определяется дважды.
Насколько я понял, требуется извлечь эти части в class
. Тогда это выглядит так:
node.pp
node 'myNode.in.a.domain' {
class { 'mymodule::createConfigurationDirectory':
}
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
}
Но это затрудняет использование моего интерфейса. Каждый пользователь моего модуля должен знать, что есть дополнительный класс. Для этого простого случая использования дополнительный класс может быть приемлемым. Но с ростом сложности модуля (много определений) я немного боюсь запутать пользователя модуля.
Итак, я хотел бы знать, есть ли лучший способ справиться с этими зависимостями. В идеале классы вроде createConfigurationDirectory
скрыты от пользователя модулей api.
Или есть какие-то другие "лучшие практики" / шаблоны для обработки таких зависимостей?
Разбейте весь функционал на отдельные файлы внутри модуля каждый файл, содержащий один класс или определенный тип. Использовать ресурс заказ управлять ресурсами в правильном порядке.
В определении вашего узла:
class {'mymodule':
conffile => 'file_name',
}
В каталоге манифеста вашего модуля:
init.pp:
# This class does basic setup,
# and optionally allows you to define a config file
class mymodule ( $conffile = undef ) {
include mymodule::confdir
if $conffile {
mymodule::conffile { $conffile: }
}
}
params.pp:
# This class defines variables
class mymodule::params {
$confdir = '/path/to/dir'
}
confdir.pp:
# This class creates a conf dir
class mymodule::confdir {
include mymodule::params
file { $mymodule::params::confdir:
ensure = directory,
}
}
conffile.pp:
# This define creates a config file
define mymodule::conffile($file=$title) {
include mymodule::params
file { "${mymodule::params::confdir}/${file}":
ensure => present,
require => Class['mymodule::confdir'],
}
}
Лучше всего, если вы можете вынуть каталог config из файла define. Это пример
class def($config_dir) {
file { $config_dir:
ensure => directory
}
}
define def::template($file_location) {
file { $file_location:
path => "${def::config_dir}/${file_location}",
content => 'hi',
require => Class['def'],
}
}
if $fqdn == 'my_host' {
class { 'def':
config_dir => '/tmp/d1'
}
def::template { 'f1.txt':
file_location => "f1.txt"
}
def::template { 'f2.txt':
file_location => "f2.txt"
}
}
ls /tmp/d1/
f1.txt f2.txt