Почему я должен использовать параметризованный класс puppet?

12

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

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,
  }
}

Как / когда / почему параметризованные классы помогают в этой ситуации? Как вы используете параметризованные классы для структурирования ваших кукольных модулей?

robbyt
источник
2
Примечание для всех, кто находит этот пример, этот код показывает поиск глобальных переменных, которые были разрешены в версии Puppet <3.0. В Puppet> 3.0 вы не можете получить доступ к переменным вне области и должны использовать пространство имен для доступа к переменным. В этом примере вам придется использовать $bar::file_nameи $::file_ownerобращаться к этим соответствующим переменным. Однако при использовании параметризованных классов переменные, передаваемые в класс через параметры, становятся переменными локальной области видимости.
Роббыт

Ответы:

12

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

Представьте, что вы включили еще 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 и, конечно же, руководство по языку предоставляют несколько хороших примеров того, как использовать параметризованные классы и обоснование этой языковой конструкции:

Joschi
источник
8

Лучший способ подумать об этом - прийти к этому с самого начала, а не начинать с уже знакомых с марионетками идиом.

В первую очередь вы пытаетесь передать параметры в класс - вы даете ему необходимую информацию, чтобы решить, как себя вести, как передавая аргументы в функцию. Скажем, это был Perl, и у вас была функция multiply_squares. Вы бы назвали это как multiply_squares(3, 4), не устанавливая некоторые глобальные переменные в 3 и 4, а затем читайте их изнутри функции!

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

nfagerlund
источник