Управление марионеточной зависимостью - PullRequest
0 голосов
/ 28 августа 2018

Предположим, у меня есть класс, который устанавливает пакеты (profile::base::tools), и другой класс, который определяет yumrepos (profile::base::yum), требуемый для этих пакетов.

tools.pp:

class profile::base::tools {
   $packages = [
      'package1',
      'package2'
   ]

   package { $packages:
     ensure => present,
   }
}

В настоящее время он запускается через base.pp:

base.pp:

include profile::base::yum 
include profile::base::tools

Class['profile::base::yum'] -> [
    Class['profile::base::tools']]     

Поэтому, когда я запускаю base.pp, он сначала создает репозитории yum, а затем устанавливает пакеты. В настоящее время зависимость, что tools.pp требует yumrepos, определенного первым, упоминается только в base.pp.

У меня вопрос: если я запускаю tools.pp в одиночку (для целей тестирования), он не будет знать о зависимости и, следовательно, не сможет. Я могу добавить include profile::base::yum в класс tools.pp, но хотел бы знать, является ли стандарт для каждого класса знать о зависимостях, даже если он уже определен в другом месте (как в base.pp)

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

У меня вопрос: если я запускаю tools.pp самостоятельно (для целей тестирования), знать о зависимости и, следовательно, потерпеть неудачу. Я могу добавить включить profile :: base :: yum в классе tools.pp, но хотел знать, стандарт для каждого класса, чтобы знать о зависимостях, даже если его уже определено в другом месте (как в base.pp)

Это одно из ключевых отличий между публичными и частными классами. Открытые классы - это те, которые предназначены для того, чтобы пользователи вашего модуля объявляли напрямую, тогда как закрытые классы - это те, которые должны быть объявлены только другими классами, принадлежащими к тому же модулю. Само по себе это публичное / частное различие является в первую очередь вопросом документации и соглашения, но, хотя язык не имеет прямой поддержки конфиденциальности классов, модуль puppet/stdlib имеет функцию assert_private , которая может помочь вам реализовать намеченное шаблон использования.

Для частных занятий все эти детали зависят от вас. Такие классы не предназначены для непосредственного объявления, поэтому не имеет большого значения, устанавливают ли они свои собственные зависимости и отношения. Важно то, что все необходимые зависимости и отношения устанавливаются, когда закрытый класс объявляется одним из открытых классов его модуля.

Публичные классы, с другой стороны, должны объявлять все свои зависимости и организовывать для себя любые требования к порядку приложения, которые должны быть установлены. Это гарантирует, что все, что вам нужно сделать, чтобы использовать их, это объявить их сами. Есть много вариантов того, как это можно сделать. В вашем конкретном случае именно то отношение, которое вы в настоящее время устанавливаете в своем классе profile::base, может быть установлено (или дополнительно) в profile::base::tools с помощью оператора require:

class profile::base::tools {
   # 'require' does everything 'include' does, plus establishes a relationship:
   require profile::base::yum

   # ...

}

Поскольку обычно хорошей идеей является быть как можно более конкретным с вашими отношениями, вы также можете подумать о том, чтобы быть немного более детализированным:

class profile::base::tools {
   include profile::base::yum

   $packages = [
      'package1',
      'package2'
   ]

   package { $packages:
     ensure  => present,
     require => Class['profile::base::yum'],
   }
}

Это не имеет практического значения в данном конкретном случае, но может быть полезно в других случаях. Обратите внимание, что это все еще уместно для include yum::profile::base, чтобы гарантировать, что оно фактически объявлено, даже если отношения с ним выражены на уровне ресурса.

0 голосов
/ 28 августа 2018

Непонятно, как вы на самом деле проводите тестирование, но если вы используете Rspec, то вы можете использовать pre_condition и post_condition для этого, например:

describe 'profile::base::tools' do
  let(:pre_condition) {
    """
    include profile::base::yum
    """
  }

  let(:post_condition) {
    """
    Class['profile::base::yum'] -> [
      Class['profile::base::tools']]
    """
  }

  it { is_expected.to contain_package('package1') }
  it { is_expected.to contain_package('package2') }
end

Затем Rspec внутренне создает манифест с классом, который вы объявляете / тестируете, заключенным между условием pre и post.

Конечно, вам действительно не нужно почтовое условие; поместить оба в pre_condition хорошо, так как порядок кода не имеет значения, например:

  let(:pre_condition) {
    """
    include profile::base::yum

    Class['profile::base::yum'] -> [
      Class['profile::base::tools']]
    """
  }

Однако, если вы не используете Rspec и хотите проверить это вручную или другим автоматическим способом, принцип тот же: всякий раз, когда вы объявляете класс tools, также объявляйте вспомогательный код, включая зависимый класс и декларации отношений.

...