Назад | Перейти на главную страницу

Как настроить параметризованные классы с массивами в марионетке?

Моя цель - определить класс, который принимает в качестве входных данных массив пар. Поскольку я не уверен, как определять массив пар, я просто собираюсь использовать вместо этого пару массивов.

class student($username, $full_name){
  notify {"user":  message => "username: ${username}\n"}
  notify {"fullname":  message => "fullname: ${full_name}\n"}
  exec {'finger': command => "/usr/bin/finger ${username}", logoutput => true }
}

$users = ['elion', 'azee', 'root']
$names = ['El Lion', 'Avery Zee', "Rooty Root"]

class { 'student':
  username => $users,
  full_name => $names
}

После выполнения 'puppet apply file.pp' я ожидаю, что вывод будет проходить через два массива, распечатывая уведомления и перебирая учеников (что звучит ужасно) в порядке, заданном массивами. Я попробовал это, и в итоге произошло то, что марионетка объединила массивы в одну строку, поэтому значение $ users оказалось таким: elionazeeroot и значение $ names оказалось El Lion Avery Zee Rooty Root.

Два вопроса:

  1. Есть ли способ определить класс для обработки группы данных, как я пытаюсь сделать здесь?
  2. Я подозреваю, что использую неправильную конструкцию для достижения своей цели. Что мне делать вместо этого?

Естественным способом представления ваших данных на языке программирования был бы такой хэш:

$users = {
  elion => 'El Lion',
  azee  => 'Avery Zee',
  root  => 'Rooty Root,
}

Хотя сделать это в Puppet возможно, я обнаружил, что лучше решить, каким будет определение ресурса для одной записи, а затем структурировать хеш как что-то, что вы можете передать create_resources (). В данном случае это будет означать примерно следующее:

define student ($full_name) {
  notify { "user ${title}":
    message => "username: ${title}\n",
  }
  notify { "fullname ${title}":
    message => "fullname: ${full_name}\n",
  }
  exec { "finger ${title}":
    command   => "/usr/bin/finger ${title}",
    logoutput => true,
  }
}

$users = {
  elion => { full_name => 'El Lion'   },
  azee  => { full_name => 'Avery Zee' },
  root  => { full_name => 'Rooty Root },
}

create_resources(student, $users)

тем не мение, как отмечает Гер, вам будет лучше, если вы будете использовать Hiera. Hiera позволяет вам отделить ваш код (определения манифеста) от ваших данных (в данном случае от конкретных имен студентов). В целом, вот что я бы сделал для вашей установки:

  • Поместите данные ученика в файл hiera. Вы можете использовать JSON или YAML; Мне нравится YAML. Это было бы примерно так:

    classroom::users:
      elion:
        full_name: El Lion
      azee:
        full_name: Avery Zee
      root:
        full_name: Rooty Root
    
  • Определите тип ресурса для студентов и вставьте его classroom/manifests/student.pp в кукольном $modulepath. Это выглядело бы так student тип ресурса выше, но будет назван classroom::student.

  • Определить classroom класс в classroom/manifests/init.pp со следующим содержанием:

    class classroom (
      $users = hiera('classroom::users', undef),
    ) {
      create_resources(classroom::student, $users)
    }
    

Если вы используете Puppet 3.x, hiera() вызов в параметрах класса является избыточным, но он вам понадобится, если вы все еще используете Puppet 2.7.