Ошибка объявления дубликата марионетки с условным оператором - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь настроить глобальные параметры для ресурса Puppet postgresql. Я хочу сделать это условно. Я использую оператор if для его настройки в зависимости от содержимого переменной.

define setup_postgresql_globals (
  $datadir,
) {
  if $datadir {
    class { 'postgresql::globals':
      datadir         => "${datadir}",
      needs_initdb    => true,
      version         => '9.3',
    }
  }
  else {
    class { 'postgresql::globals':
      needs_initdb    => true,
      version         => '9.3',
    }
  }
}

Я получаю эту ошибку.

Error: Duplicate declaration: Class[Postgresql::Globals] is already declared

Я хочу передать datadir аргумент postgresql::globals, только если он содержит значение.

Как я могу использовать условный оператор, а не получить ошибку повторного объявления?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Я хочу передать аргумент datadir в postgresql :: globals, только если он содержит значение.

Вам не нужно беспокоиться о том, чтобы не передавать datadir, если оно не содержит значения. Просто передайте параметр в postgresql::globals вместе с другими вашими параметрами. Если datadir имеет значение, то класс будет использовать его, а если нет, postgresql::globals будет обрабатывать его просто отлично и использовать свои собственные значения по умолчанию. Вам нужно изменить способ передачи параметра, но это не сработает: datadir => "${datadir}", вы должны передать его следующим образом datadir => $datadir,. Ваше определение может быть таким простым:

define setup_postgresql_globals (
  $datadir = undef,
) {
  class { 'postgresql::globals':
    datadir         => $datadir,
    needs_initdb    => true,
    version         => '9.3',
  }
}

Причина, по которой вы получаете Error: Duplicate declaration: Class[Postgresql::Globals] is already declared, заключается в том, что вы запускаете определенное количество раз. По своей природе определение может быть создано несколько раз, поэтому может быть проблематично сделать класс, такой как include, внутри одного, поскольку вы можете включить класс, подобный этому, только один раз. Есть несколько способов решить эту проблему.

1) Оцените вашу потребность в этом определении вообще. Он выглядит так, как будто вы создали это определение только для обработки параметра datadir, являющегося значением undef. Как я показал выше, вам может не понадобиться это определение, так как ваша логика не нужна.

2) Вы должны делать только базовые включения классов в пределах определения. Вы можете включить такой класс несколько раз. Вам придется обрабатывать настройку datadir с помощью автоматической системы поиска параметров от hiera. Например:

define setup_postgresql_globals (
  $datadir = undef,
) {
  include 'postgresql::globals'
}

Опять же, вам, вероятно, следует удалить это определение и дескриптор, включая postgresql::globals, из которого создается экземпляр setup_postgresql_globals.

0 голосов
/ 03 мая 2018

Как я могу использовать условный оператор, а не получить ошибку повторного объявления?

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

Частично по этой причине плохая форма помещения ресурсного объявления класса в определенный тип. Это напрашивается на неприятности. Если вам нужно использовать объявление класса, похожее на ресурс, поместите его в другой класс. Это, возможно, решает проблему в целом, но в худшем случае поднимает ее на более высокий уровень. Похоже, что это, вероятно, разумный подход в вашем случае, потому что setup_postgresql_globals наверняка звучит как нечто, что само по себе должно быть идемпотентным.

Учтите также, что классы - но не определения - могут использовать автоматическое связывание данных. Использование внешних данных для автоматической привязки к параметрам вашего класса часто является хорошим способом замены ресурсных объявлений классов включаемыми. При применении в соответствующей умеренности, это может привести к более чистым, простым, легким в использовании и сохранении манифестов.

...