Я пытаюсь создать два профиля Puppet для DCS Hashicorp Consul. Consul может работать как клиентский или серверный агент, при этом серверный режим является надмножеством клиентского режима. Это прямо отражено в конфигурации:
Агентам сервера Consul обычно требуется расширенный набор настроек, необходимых для клиентских агентов Consul.
Мой подход к дизайну Puppet основан на следующем шаблоне: https://puppet.com/docs/pe/2018.1/the_roles_and_profiles_method.html
Согласно документации Puppet, должно быть возможно (и, скорее всего, желательно) включить профиль consul_client
в профиль consul_server
, чтобы избежать дублирования кода:
Профили могут включать в себя другие профили.
Пытаясь реализовать это, я использовал некоторые обязательные параметры в обоих профилях и столкнулся с проблемами во время выполнения автоматических модульных тестов rspec.
В файле модульного теста consul_client
consul_client_spec.rb
я просто указал необходимые параметры следующим образом:
let(:params) { {
'datacenter' => 'unit-test',
'encrypt' => 'DUMMY',
'server_agent_nodes' => [ '1.2.3.4' ]
} }
Возникли проблемы при попытке запустить модульный тест consul_server_spec.rb
. По наивности я просто передал один дополнительный обязательный параметр профиля consul_server
:
let(:params) { {
'bootstrap_expect' => 3,
} }
Поскольку профиль consul_client
является include
ed/require
ed профилем consul_server
, тест не прошел с отсутствующими параметрами для класса профиля consul_client
. Кажется, это указывает на некоторую общую структурную проблему с этим подходом.
Теперь я не уверен, должен ли я повторно объявлять все параметры класса профиля consul_client
в классе профиля consul_server
, что, на мой взгляд, нарушит принцип DRY. Кроме того, при использовании данных Hiera в будущем это может привести к ситуации, когда profile::consul_client::*
и profile::consul_server::*
будут содержать одни и те же дублирующиеся данные, поскольку клиентскую часть данных придется повторять для обоих профилей.
Добавленное примечание: И дублирование параметров в классе consul_server
, вероятно, даже не сработает, поскольку параметры нельзя передавать явно, а только через данные, чтобы включить подобные определения ресурсов, поэтому эти дублированные параметры не могут быть перешел в consul_client
класс.
Напротив, в документации указано следующее, но я не уверен, что это относится и к включенным классам профилей (поскольку они могут не быть классами компонентов?):
Профили владеют всеми параметрами класса для своих классов компонентов. Если в профиле отсутствует один, это означает, что вам определенно нужно значение по умолчанию; класс компонента не должен использовать значение из данных Hiera. Если вам нужно установить параметр класса, который ранее был опущен, проведите рефакторинг профиля.
В дополнение к этим мыслям можно также увидеть, как два класса профилей рефакторингуются в обычные классы отдельного модуля, что может помочь увидеть последствия различных подходов к проектированию.
В заключение возникают следующие вопросы:
- Как должны обрабатываться параметры во вложенных профилях, задаваться исключительно данными hiera отдельно для каждого класса профиля?
- Как передать параметры вложенным профилям во время модульных тестов? Было бы правильно каким-то образом предоставить фиктивные данные hiera как часть тестового приспособления?
- Будет ли насмешка над классом профиля
consul_client
лучшим вариантом?