При работе с puppet одна из полезностей - роли. Т.е. при описании ноды присваиваем ей роль, а уже в манифестах в зависимости от роли описываем конфигурацию. MCollective же позволяет получить ту или иную информацию о ноде, базируясь на ряде признаков.
Например, той же роли: сколько у нас вторичных серверов БД, какие версии БД установлены и т.д. Можно, конечно, воспользоваться простым regexp фильтром. Но в данном случае он не очень удобен - имена ролей, в принципе, могут частично пересекаться. К примеру, роль у нас прописана в puppet манифесте для одного хоста
role = "db-master,puppet-master"
а на втором
role= "db2-master"
уже имеем сложность отличить при помощи regexp db от db2
Поэтому логично сделать простой data plugin, который самостоятельно распарсит роль и выдаст результат
В документации к mcollective процедура создания плагина описана неплохо, но пропущены несколько подводных камней, которые основательно мне потрепали нервы.
Приступим к процедуре. Сразу оговорюсь: описанная процедура касается mcollective версии старше 2.2.1 (я проверял на последней на данный момент, mcollective 2.3.1). Также следует учитывать, что пути к файлам будут указаны для CentOS (RedHat, OracleLinux) ES.
Переходим в каталог /usr/libexec/mcollective/mcollective/data . Да, это не опечатка - почему-то авторы mcollective сделали двойное вложение. Пусть эта непонятка остается на их совести :).
Нам необходимо создать два файла: руби-код плагина .rb и описание .ddl.
Назовем новую функцию has_role, в качестве параметра будем передавать regexp или строку, возвращаться будет boolean true или false, в зависимости от того, имеет ли нода указанную роль или нет.
Важный момент (грабли номер раз)! Имя файлов строго определено (это касается data plugin'ов): <classname>_data.rb и <classname>_data.ddl. Строго говоря, <classname> не обязательно должен совпадать с реальным именем класса, но лучше это делать так, чтобы не путаться потом. А вот суффикс _data обязателен, иначе плагин нормально не инициализируется.
Содержимое has_role-data.rb :
module MCollective
module Data
class Has_role_data<Base
query do |arg|
roles = Facts["role"]
ret = false
if roles.nil? or roles == false
ret = false
else
# check is argument regexp
arg = Regexp.new(arg.gsub("\/", "")) if arg.match("^/")
# convert roles to array
roles = roles.split(",") if (roles.is_a? String)
# trim spaces
roles = roles.collect{|x| x.strip}
if arg.is_a?(Regexp)
roles.each do |role|
ret = true if role.grep(arg).size > 0
end
else
ret = roles.include?(arg)
end
end
result[:value] = ret
end
end
end
end
Некоторые пояснение по коду. Первые две строки - стандартные для дата-модуля.
Третья строка - описание класса. Имя класса должно быть с заглавной буквы!
Четвертая - вычитываем аргументы. Тут два замечания. Хотя и вычитывается массив, согласно документации принимается только один аргумент. Второе. Я бы очень не рекомендовал выносить перед этим циклом вообще какие-либо действия, могут возникать ошибки на голом месте :(
Строка 24 - возврат результата выполнения функции.
Теперь создадим описание плагина. Оно должно находиться в том же каталоге и иметь то же имя, но другое расширение.
metadata :name => "Has role",
:description => "Check is node has role",
:author => "PAL ",
:license => "GPL 3.0",
:version => "0.1",
:url => "http://",
:timeout => 1
requires :mcollective => "2.2.1"
dataquery :description => "Has role" do
input :query,
:prompt => "Role",
:description => "Check role name",
:type => :string,
:validation => /^.+$/,
:maxlength => 120
output :value,
:description => "True if node has role, false if has not",
:display_as => "Has role"
end
В принципе, тут все понятно. Буквально пару замечаний. В разделах input и output описываются имена (для input еще и тип) переменных, используемых для ввода и вывода. Разумеется, эти имена должны совпадать с теми. которые используются в руби-коде :)
Теперь очень важный момент (грабли №2). Нужно обязательно перезапустить mcollective:
# /sbin/service mcollective restart
Иначе плагин будет совсем как настоящий (и даже отображаться в выводе mco plugin doc) но не будет работать! Причем при каждом исправлении кода - обязательно нужно перезапускать.
Все, наш плагин готов :)
Использовать можно, к примеру, вот так:
# mco find -S 'has_role("database-master").value=true'
Немає коментарів:
Дописати коментар