В Puppet стиль кодирования определяет все стандарты, которым необходимо следовать при попытке преобразовать инфраструктуру конфигурации машины в код. Puppet работает и выполняет все свои определенные задачи, используя ресурсы.
Определение языка Puppet помогает структурировать все ресурсы, что необходимо для управления любой целевой машиной, которой нужно управлять. Puppet использует Ruby в качестве языка кодирования, который имеет несколько встроенных функций, которые позволяют очень легко выполнить работу с помощью простой конфигурации на стороне кода.
Основные единицы
Puppet использует несколько основных стилей кодирования, которые просты для понимания и управления. Ниже приведен список немногих.
Ресурсы
В Puppet ресурсы известны как фундаментальный модуль моделирования, который используется для управления или изменения любой целевой системы. Ресурсы охватывают все аспекты системы, такие как файл, служба и пакет. Puppet имеет встроенную возможность, которая позволяет пользователям или разработчикам разрабатывать собственные ресурсы, которые помогают в управлении любым конкретным узлом машины.
В Puppet все ресурсы объединяются либо с помощью «define», либо «классы» . Эти функции агрегирования помогают в организации модуля. Ниже приведен пример ресурса, который состоит из нескольких типов, заголовка и списка атрибутов, с которыми Puppet может поддерживать несколько атрибутов. Каждый ресурс в Puppet имеет свое собственное значение по умолчанию, которое может быть переопределено при необходимости.
Образец кукольного ресурса для файла
В следующей команде мы пытаемся указать разрешение для определенного файла.
file { '/etc/passwd': owner => superuser, group => superuser, mode => 644, }
Всякий раз, когда вышеуказанная команда выполняется на любом компьютере, она проверяет, что файл passwd в системе настроен, как описано. Файл before: двоеточие — это заголовок ресурса, который может называться ресурсом в других частях конфигурации Puppet.
Указание локального имени в дополнение к заголовку
file { 'sshdconfig': name => $operaSystem ? { solaris => '/usr/local/etc/ssh/sshd_config', default => '/etc/ssh/sshd_config', }, owner => superuser, group => superuser, mode => 644, }
Используя заголовок, который всегда один и тот же, очень легко ссылаться на файловый ресурс в конфигурации без необходимости повторения логики, связанной с ОС.
Другим примером может быть использование службы, которая зависит от файла.
service { 'sshd': subscribe => File[sshdconfig], }
С этой зависимостью служба sshd всегда перезапускается после изменения файла sshdconfig . Следует помнить, что File [sshdconfig] является объявлением File, как в нижнем регистре, но если мы изменим его на FILE [sshdconfig], то это будет ссылка.
При объявлении ресурса следует помнить один фундаментальный момент: он может быть объявлен только один раз для каждого файла конфигурации. Повторное объявление одного и того же ресурса более одного раза вызовет ошибку. Благодаря этой фундаментальной концепции Puppet гарантирует, что конфигурация хорошо смоделирована.
У нас даже есть возможность управлять зависимостью от ресурсов, которая помогает управлять несколькими отношениями.
service { 'sshd': require => File['sshdconfig', 'sshconfig', 'authorized_keys'] }
Metaparameters
Метапараметры известны как глобальные параметры в Puppet. Одной из ключевых особенностей метапараметра является то, что он работает с любым типом ресурсов в Puppet.
Ресурс по умолчанию
Когда нужно определить значение атрибута ресурса по умолчанию, Puppet предоставляет набор синтаксиса для его архивирования, используя спецификацию ресурса с заглавной буквы, которая не имеет заголовка.
Например, если мы хотим установить путь по умолчанию для всех исполняемых файлов, это можно сделать с помощью следующей команды.
Exec { path => '/usr/bin:/bin:/usr/sbin:/sbin' } exec { 'echo Testing mataparamaters.': }
В приведенной выше команде первый оператор Exec установит значение по умолчанию для ресурса exec. Ресурсу Exec требуется полный путь или путь, который выглядит как исполняемый файл. При этом можно определить один путь по умолчанию для всей конфигурации. По умолчанию работает с любым типом ресурса в Puppet.
Значения по умолчанию не являются глобальными значениями, однако они влияют только на область, в которой они определены, или ближайшую к нему переменную. Если кто-то хочет определить default для полной конфигурации, тогда мы определим default и класс в следующем разделе.
Коллекции Ресурсов
Агрегация — это метод сбора вещей. Puppet поддерживает очень мощную концепцию агрегации. В Puppet агрегация используется для группировки ресурсов, которые являются фундаментальной единицей Puppet. Эта концепция агрегации в Puppet достигается с помощью двух мощных методов, известных как классы и определения .
Классы и определения
Классы отвечают за моделирование фундаментальных аспектов узла. Они могут сказать, что узел — это веб-сервер, и этот конкретный узел — один из них. В Puppet классы программирования являются одноэлементными, и их можно оценивать один раз для каждого узла.
Определение, с другой стороны, может использоваться много раз на одном узле. Они работают так же, как каждый создал свой собственный тип Puppet, используя язык. Они созданы для многократного использования с разными входами каждый раз. Это означает, что в определение можно передавать значения переменных.
Разница между классом и определением
Единственное ключевое различие между классом и определением заключается в том, что при определении структуры здания и распределении ресурсов класс оценивается только один раз на узел, а с другой стороны, определение используется несколько раз на одном и том же узле.
Классы
Классы в Puppet вводятся с использованием ключевого слова class, а содержимое этого конкретного класса заключено в фигурные скобки, как показано в следующем примере.
class unix { file { '/etc/passwd': owner => 'superuser', group => 'superuser', mode => 644; '/etc/shadow': owner => 'vipin', group => 'vipin', mode => 440; } }
В следующем примере мы использовали некоторую короткую руку, которая похожа на вышеприведенную.
class unix { file { '/etc/passwd': owner => 'superuser', group => 'superuser', mode => 644; } file {'/etc/shadow': owner => 'vipin', group => 'vipin', mode => 440; } }
Наследование в кукольных классах
В Puppet концепция ООП наследования поддерживается по умолчанию, в которой классы могут расширять функциональность предыдущего, не копируя и не вставляя бит полного кода снова во вновь созданный класс. Наследование позволяет подклассу переопределять настройки ресурса, определенные в родительском классе. При использовании наследования следует помнить о том, что класс может наследовать функции только от одного родительского класса, но не от одного.
class superclass inherits testsubclass { File['/etc/passwd'] { group => wheel } File['/etc/shadow'] { group => wheel } }
Если есть необходимость отменить некоторую логику, указанную в родительском классе, мы можем использовать команду undef .
class superclass inherits testsubcalss { File['/etc/passwd'] { group => undef } }
Альтернативный способ использования наследования
class tomcat { service { 'tomcat': require => Package['httpd'] } } class open-ssl inherits tomcat { Service[tomcat] { require +> File['tomcat.pem'] } }
Вложенный класс в кукольный
Puppet поддерживает концепцию вложенности классов, в которой он позволяет использовать вложенные классы, что означает один класс внутри другого. Это помогает в достижении модульности и объема.
class testclass { class nested { file { '/etc/passwd': owner => 'superuser', group => 'superuser', mode => 644; } } } class anotherclass { include myclass::nested }
Параметризованные классы
В Puppet классы могут расширять свои функциональные возможности, чтобы разрешить передачу параметров в класс.
Чтобы передать параметр в классе, можно использовать следующую конструкцию —
class tomcat($version) { ... class contents ... }
В Puppet следует помнить один ключевой момент: классы с параметрами не добавляются с помощью функции include, скорее результирующий класс можно добавить в качестве определения.
node webserver { class { tomcat: version => "1.2.12" } }
Значения по умолчанию как параметры в классе
class tomcat($version = "1.2.12",$home = "/var/www") { ... class contents ... }
Run Stages
Puppet поддерживает концепцию этапа выполнения, что означает, что пользователь может добавить несколько этапов в соответствии с требованием для управления любым конкретным ресурсом или несколькими ресурсами. Эта функция очень полезна, когда пользователь хочет разработать сложный каталог. В сложном каталоге имеется большое количество ресурсов, которые необходимо скомпилировать, помня о том, что не следует влиять на зависимости между определенными ресурсами.
Этап запуска очень полезен для управления зависимостями ресурсов. Это может быть сделано путем добавления классов на определенных этапах, где определенный класс содержит коллекцию ресурсов. С этапом выполнения Puppet гарантирует, что определенные этапы будут выполняться в указанном предсказуемом порядке каждый раз, когда каталог запускается и применяется к любому узлу Puppet.
Чтобы использовать это, нужно объявить дополнительные этапы помимо уже существующих этапов, и тогда Puppet может быть настроен для управления каждым этапом в указанном порядке, используя тот же синтаксис отношения ресурсов, прежде чем требовать «->» и «+>» . Отношения затем гарантируют порядок классов, связанных с каждым этапом.
Объявление дополнительных этапов с кукольным декларативным синтаксисом
stage { "first": before => Stage[main] } stage { "last": require => Stage[main] }
После того, как этапы были объявлены, класс может быть связан с этапом, отличным от основного, используя этап.
class { "apt-keys": stage => first; "sendmail": stage => main; "apache": stage => last; }
Все ресурсы, связанные с классом apt-key, будут запущены первыми. Все ресурсы в Sendmail будут основным классом, а ресурсы, связанные с Apache, будут последним этапом.
Определения
В Puppet сбор ресурсов в любом файле манифеста осуществляется с помощью классов или определений. Определения очень похожи на класс в Puppet, однако они вводятся с ключевым словом define (не class) и поддерживают аргумент, а не наследование. Они могут работать в одной системе несколько раз с разными параметрами.
Например, если кто-то хочет создать определение, управляющее репозиториями исходного кода, в которых он пытается создать несколько репозиториев в одной системе, то можно использовать определение, а не класс.
define perforce_repo($path) { exec { "/usr/bin/svnadmin create $path/$title": unless => "/bin/test -d $path", } } svn_repo { puppet_repo: path => '/var/svn_puppet' } svn_repo { other_repo: path => '/var/svn_other' }
Ключевой момент, который следует здесь отметить, заключается в том, как можно использовать переменную с определением. Мы используем ( $ ) переменную знака доллара. Выше мы использовали $ title. Определения могут иметь как $ title, так и $ name, которыми могут быть представлены имя и заголовок. По умолчанию $ title и $ name установлены на одно и то же значение, но можно установить атрибут title и передать другое имя в качестве параметра. $ title и $ name работают только в определении, а не в классе или другом ресурсе.
Модули
Модуль может быть определен как совокупность всех конфигураций, которые будут использоваться мастером Puppet для применения изменений конфигурации к любому конкретному узлу Puppet (агенту). Они также известны как переносимые коллекции различных видов конфигураций, которые необходимы для выполнения конкретной задачи. Например, модуль может содержать все ресурсы, необходимые для настройки Postfix и Apache.
Вершины
Узлы — это очень простой оставшийся шаг, который позволяет нам сопоставить то, что мы определили («так выглядит веб-сервер») с тем, какие машины выбраны для выполнения этих инструкций.
Определение узла в точности похоже на классы, включая вспомогательное наследование, однако они являются особыми, так что когда узел (управляемый компьютер, на котором работает клиент puppet) подключается к главному демону Puppet, его имя будет отображаться в определенном списке узлов. Определенная информация будет оценена для узла, а затем узел отправит эту конфигурацию.
Имя узла может быть коротким именем хоста или полным доменным именем (FQDN).
node 'www.vipin.com' { include common include apache, squid }
Приведенное выше определение создает узел с именем www.vipin.com и включает в себя общий, Apache и Squid.
Мы можем отправить одну и ту же конфигурацию разным узлам, разделяя их запятыми.
node 'www.testing.com', 'www.testing2.com', 'www3.testing.com' { include testing include tomcat, squid }
Регулярное выражение для совпадающих узлов
node /^www\d+$/ { include testing }
Наследование узлов
Узел поддерживает модель ограниченного наследования. Как и классы, узлы могут наследовать только от одного другого узла.
node 'www.testing2.com' inherits 'www.testing.com' { include loadbalancer }
В приведенном выше коде www.testing2.com наследует все функциональные возможности от www.testing.com в дополнение к дополнительному классу loadbalancer.
Расширенные поддерживаемые функции
Цитирование — В большинстве случаев нам не нужно цитировать строку в Puppet. Любая буквенно-цифровая строка, начинающаяся с буквы, должна быть оставлена без кавычек. Однако всегда лучше заключать в кавычки строку для любых неотрицательных значений.
Переменная интерполяция с кавычками
До сих пор мы упоминали переменную с точки зрения определения. Если нужно использовать эти переменные со строкой, используйте двойные кавычки, а не одинарные. Строка одинарных кавычек не будет выполнять никакой переменной интерполяции, строка двойных кавычек будет делать. Переменная может заключаться в квадратные скобки в {}, что упрощает их совместное использование и облегчает понимание.
$value = "${one}${two}"
Рекомендуется использовать одинарные кавычки для всех строк, которые не требуют интерполяции строк.
капитализация
Использование заглавных букв — это процесс, который используется для ссылки, наследования и установки атрибутов по умолчанию для конкретного ресурса. Есть два основных способа его использования.
-
Ссылки — это способ ссылки на уже созданный ресурс. Он в основном используется для целей зависимости, нужно использовать заглавную букву имени ресурса. Пример, require => file [sshdconfig]
-
Наследование — при переопределении параметра родительского класса из подкласса используйте версию имени ресурса в верхнем регистре. Использование строчной версии приведет к ошибке.
-
Установка значения атрибута по умолчанию — Использование заглавного ресурса без заголовка работает для установки ресурса по умолчанию.
Ссылки — это способ ссылки на уже созданный ресурс. Он в основном используется для целей зависимости, нужно использовать заглавную букву имени ресурса. Пример, require => file [sshdconfig]
Наследование — при переопределении параметра родительского класса из подкласса используйте версию имени ресурса в верхнем регистре. Использование строчной версии приведет к ошибке.
Установка значения атрибута по умолчанию — Использование заглавного ресурса без заголовка работает для установки ресурса по умолчанию.
Массивы
Puppet позволяет использовать массивы в нескольких областях [Один, два, три].
Несколько членов типа, таких как псевдоним в определении хоста, принимают массивы в своих значениях. Ресурс хоста с несколькими псевдонимами будет выглядеть примерно так:
host { 'one.vipin.com': alias => [ 'satu', 'dua', 'tiga' ], ip => '192.168.100.1', ensure => present, }
Приведенный выше код добавит хост ‘one.brcletest.com’ в список хостов с тремя псевдонимами ‘satu’ ‘dua’ ‘tiga’ . Если кто-то хочет добавить несколько ресурсов к одному ресурсу, это можно сделать, как показано в следующем примере.
resource { 'baz': require => [ Package['rpm'], File['testfile'] ], }
переменные
Puppet поддерживает несколько переменных, как и большинство других языков программирования. Переменные кукол обозначаются символом $ .
$content = 'some content\n' file { '/tmp/testing': content => $content }
Как указывалось ранее, Puppet является декларативным языком, что означает, что его область действия и правила назначения отличаются от императивного языка. Основное отличие состоит в том, что нельзя изменить переменную в одной области видимости, поскольку они определяют порядок в файле для определения значения переменной. Порядок не имеет значения на декларативном языке.
$user = root file { '/etc/passwd': owner => $user, } $user = bin file { '/bin': owner => $user, recurse => true, }
Переменная сфера
Область действия переменных определяет, являются ли все переменные, которые определены, действительными. Как и в случае с последними функциями, в настоящее время Puppet имеет динамическую область действия, что в терминах Puppet означает, что все определяемые переменные оцениваются по их области видимости, а не по месту, в котором они определены.
$test = 'top' class Testclass { exec { "/bin/echo $test": logoutput => true } } class Secondtestclass { $test = 'other' include myclass } include Secondtestclass
Квалифицированная переменная
Puppet поддерживает использование квалифицированных переменных внутри класса или определения. Это очень полезно, когда пользователь хочет использовать ту же переменную в других классах, которые он определил или собирается определить.
class testclass { $test = 'content' } class secondtestclass { $other = $myclass::test }
В приведенном выше коде значение переменной $ other оценивает содержимое.
Conditionals
Условия — это ситуации, когда пользователь желает выполнить набор операторов или кода, когда определенное условие или требуемое условие выполнены. Puppet поддерживает два типа условий.
Условие выбора, которое можно использовать только в пределах определенных ресурсов для выбора правильного значения машины.
Условия оператора — это более широко используемые условия в манифесте, которые помогают включать дополнительные классы, которые пользователь желает включить в тот же файл манифеста. Определите отдельный набор ресурсов внутри класса или примите другие структурные решения.
Селекторы
Селекторы полезны, когда пользователь желает указать атрибут ресурса и переменные, которые отличаются от значений по умолчанию на основе фактов или других переменных. В Puppet индекс селектора работает как многозначный трехсторонний оператор. Селекторы также могут определять пользовательские значения по умолчанию без значений, которые определены в манифесте и соответствуют условию.
$owner = $Sysoperenv ? { sunos => 'adm', redhat => 'bin', default => undef, }
В более поздних версиях Puppet 0.25.0 селекторы могут использоваться как регулярные выражения.
$owner = $Sysoperenv ? { /(Linux|Ubuntu)/ => 'bin', default => undef, }
В приведенном выше примере значение селектора $ Sysoperenv соответствует либо Linux, либо Ubuntu, тогда выбранным будет результат bin, в противном случае для пользователя будет задано значение undefined.
Состояние заявления
Условие оператора — это другой тип условного оператора в Puppet, который очень похож на условие переключения в сценарии Shell. При этом определяется несколько наборов регистров, и заданные входные значения сопоставляются с каждым условием.
Оператор case, который соответствует данному входному условию, выполняется. Это условие оператора case не имеет никакого возвращаемого значения. В Puppet очень распространенным случаем использования оператора условия является запуск набора битов кода, основанных на базовой операционной системе.
case $ Sysoperenv { sunos: { include solaris } redhat: { include redhat } default: { include generic} }
Оператор Case также может указывать несколько условий, разделяя их запятой.
case $Sysoperenv { development,testing: { include development } testing,production: { include production } default: { include generic } }
If-Else Заявление
Puppet поддерживает концепцию условной операции. Для этого оператор If / else предоставляет параметры ветвления, основанные на возвращаемом значении условия. Как показано в следующем примере —
if $Filename { file { '/some/file': ensure => present } } else { file { '/some/other/file': ensure => present } }
Последняя версия Puppet поддерживает переменное выражение, в котором оператор if также может переходить в зависимости от значения выражения.
if $machine == 'production' { include ssl } else { include nginx }
Чтобы добиться большего разнообразия в коде и выполнять сложные условные операции, Puppet поддерживает вложенный оператор if / else, как показано в следующем коде.
if $ machine == 'production' { include ssl } elsif $ machine == 'testing' { include nginx } else { include openssl }
Виртуальный ресурс
Виртуальные ресурсы — это те, которые не отправляются клиенту, если не реализованы.
Ниже приводится синтаксис использования виртуального ресурса в Puppet.
@user { vipin: ensure => present }
В приведенном выше примере пользователь vipin определен виртуально, чтобы реализовать определение, которое можно использовать в коллекции.
User <| title == vipin |>
Комментарии
Комментарии используются в любом бите кода для создания дополнительного узла о наборе строк кода и его функциональности. В Puppet в настоящее время поддерживаются два типа комментариев.
- Комментарии в стиле оболочки Unix. Они могут быть на своей или следующей строке.
- Многострочные комментарии в стиле c.
Ниже приведен пример комментария в стиле оболочки.
# this is a comment
Ниже приведен пример многострочного комментария.
/* This is a comment */
Приоритет оператора
Приоритет оператора Puppet соответствует стандартному приоритету в большинстве систем, от самого высокого до самого низкого.
Ниже приведен список выражений
- ! = нет
- / = раз и разделить
- — + = минус, плюс
- << >> = сдвиг влево и вправо
- ==! = = не равно, равно
- > = <=> <= больше равно, меньше или равно, больше чем, меньше чем
Выражение сравнения
Выражение сравнения используется, когда пользователь хочет выполнить набор операторов, когда данное условие удовлетворяется. Выражения сравнения включают тесты на равенство с использованием выражения ==.
if $environment == 'development' { include openssl } else { include ssl }
Не равный пример
if $environment != 'development' { $otherenvironment = 'testing' } else { $otherenvironment = 'production' }
Арифметическое выражение
$one = 1 $one_thirty = 1.30 $two = 2.034e-2 $result = ((( $two + 2) / $one_thirty) + 4 * 5.45) - (6 << ($two + 4)) + (0×800 + -9)
Логическое выражение
Логические выражения возможны с использованием или, и, & not.
$one = 1 $two = 2 $var = ( $one < $two ) and ( $one + 1 == $two )
Регулярное выражение
Puppet поддерживает сопоставление регулярных выражений, используя = ~ (совпадение) и! ~ (Не совпадение).
if $website =~ /^www(\d+)\./ { notice('Welcome web server #$1') }
Как в случае с регулярным выражением выбора, так и с помощью селектора создается ограниченная переменная области видимости для каждого регулярного выражения.
exec { "Test": command => "/bin/echo now we don’t have openssl installed on machine > /tmp/test.txt", unless => "/bin/which php" }
Точно так же мы можем использовать, если, если только не выполнить команду все время, кроме команды, если не завершается успешно.
exec { "Test": command => "/bin/echo now we don’t have openssl installed on machine > /tmp/test.txt", unless => "/bin/which php" }
Работа с шаблонами
Шаблоны используются, когда кто-то хочет иметь заранее заданную структуру, которая будет использоваться для нескольких модулей в Puppet, и эти модули будут распределены на нескольких машинах. Первый шаг для использования шаблона — создать тот, который отображает содержимое шаблона с помощью методов шаблона.
file { "/etc/tomcat/sites-available/default.conf": ensure => "present", content => template("tomcat/vhost.erb") }
Puppet делает несколько предположений при работе с локальными файлами, чтобы обеспечить организацию и модульность. Puppet ищет шаблон vhost.erb внутри папки apache / templates, внутри каталога модулей.
Определение и запуск сервисов
В Puppet у него есть ресурс под названием service, который способен управлять жизненным циклом всех сервисов, работающих на любой конкретной машине или среде. Сервисные ресурсы используются, чтобы убедиться, что сервисы инициализированы и включены. Они также используются для перезапуска службы.
Например, в предыдущем шаблоне tomcat, который у нас есть, где мы устанавливаем виртуальный хост apache. Если кто-то хочет убедиться, что apache перезапускается после смены виртуального хоста, нам нужно создать ресурс службы для службы apache, используя следующую команду.
service { 'tomcat': ensure => running, enable => true }
При определении ресурсов нам нужно включить опцию уведомления, чтобы запустить перезапуск.