Обычно при работе со сложными марионеточными модулями я устанавливаю переменные на уровне узла или внутри класса. например.,
node 'foo.com' {
$file_owner = "larry"
include bar
}
class bar {
$file_name = "larry.txt"
include do_stuff
}
class do_stuff {
file { $file_name:
ensure => file,
owner => $file_owner,
}
}
Как / когда / почему параметризованные классы помогают в этой ситуации? Как вы используете параметризованные классы для структурирования своих марионеточных модулей?
Параметризованные классы - это языковая конструкция, которая помогает лучше структурировать код. Это предотвращает чрезмерное использование глобальных переменных (как в вашем примере).
Представьте, что вы включили еще 20 классов в описание вашего узла, и для всех потребуется установить некоторые переменные в глобальной области манифеста или области узла. Также параметризованные классы позволяют легко иметь параметры по умолчанию, поэтому вы можете использовать значение по умолчанию для $file_owner
вместо того, чтобы указывать то же значение (например, larry
) в нескольких разных местах.
Ваш примерный фрагмент (с двумя дополнительными узлами) может быть записан следующим образом:
node 'example.com' {
class { bar: }
}
node 'example.net' {
class { bar: owner = "harry" }
}
node 'example.net' {
class { bar: file_name = "barry.txt" }
}
class bar($owner = "larry", $file_name = "larry.txt") {
class { do_stuff: owner => $owner, file_name => $file_name }
}
class do_stuff($owner, $file_name) {
file { $file_name:
ensure => file,
owner => $owner,
}
}
При использовании глобальных переменных вам нужно будет объявить переменную с именем $owner
в каждом узле, и вы не сможете перезаписать $file_name
переменная / параметр на узел. Вместо этого вам нужно будет объявить другой bar
класс для каждого узла.
В документе об эволюции языка Puppet и, конечно же, в руководстве по языку есть несколько хороших примеров использования параметризованных классов и обоснование этой языковой конструкции:
Лучший способ подумать об этом - начать с самого начала, а не начинать с уже знакомых идиом Puppet.
Что вы пытаетесь сделать в первую очередь - это передача параметров классу - вы даете ему информацию, необходимую для того, чтобы решить, как себя вести, точно так же, как передача аргументов функции. Скажем, это был Perl и у вас есть функция multiply_squares. Вы бы назвали это как multiply_squares(3, 4)
, а не устанавливать для некоторых глобальных переменных значения 3 и 4, а затем читать их изнутри функции!
Но исторически код Puppet должен был делать это с помощью глобальных переменных или динамической области видимости, потому что необходимость в этом возникла до того, как язык был разработан для этого. Лично я думаю, что когда параметризованные классы станут немного более развитыми и более широко развернутыми, они в основном сделают проблемы с переменной областью видимости делом прошлого, потому что наличие подходящего инструмента, доступного для работы, устранит целый слой пугающих хаков.