Изменение дефолтных значений в Chef recipe

Продолжая улучшать код на примере Chef-рецепта для установки AWS-логгера, когда мы сначала стали использовать custom JSON для передачи своих переменных в скрипт, после добавили дефолтные значения для хэша непосредственно в rb-рецепте, теперь добавим возможность изменять сами дефолтные возможность через такой же Custom JSON.

Это сделать не только просто, но и идеологически правильно - все реально используемые переменные правильно держать в файле атрибутов. Потому перенесём дефолтный хэш default_aws_log из папки рецептов в папку атрибутов, например, в таком виде:

default['awslogs_conf_default']['datetime_format'] = "%b %d %H:%M:%S"
default['awslogs_conf_default']['file'] = "/var/log/syslog"
default['awslogs_conf_default']['buffer_duration'] = "5000"
default['awslogs_conf_default']['log_stream_name'] = "linuxcmd.ru"
default['awslogs_conf_default']['initial_position'] = "start_of_file"
default['awslogs_conf_default']['log_group_name'] = "SysLog"

Это позволит в рецепте сделать просто:

default_aws_log = node['awslogs_conf_default']

Теперь можно будет просто запустить рецепт с JSON вида:

{
    "awslogs_conf_default": {
        "datetime_format": "%b %d %H:%M:%S",
        "file": "/var/log/recipe.log",
        "buffer_duration": "5000",
        "log_stream_name": "linuxcmd.ru",
        "initial_position": "start_of_file",
        "log_group_name": "Ruby",
        "encoding": "utf-8"
    }
}

И всё отлично отработает:

При чём, если заметить, в JSON переданы дополнительный параметр, отсутствующий изначально в Chef-скрипте, однако он отлично отработал:

Единственное, для этого пришлось доработать и erb-шаблон.

Код template:

[general]
state_file = <%= @state_file %>

<% @awslogs_conf_data.each do |log_conf_name, cur_log| %>
[<%= log_conf_name %> ]
<% cur_log.each do |key, value| %>
<%= key %> = <%= value %>
<% end %>


<% end %>

Он стал в результате ещё более компактным (изменённое выделено жирным) и принимающим любое количество параметров.

Сам же кусок рецепта стал таким:

Код:

default_aws_log = node['awslogs_conf_default']

if defined?(node['awslogs_conf'])
    Chef::Log.info("*** node['awslogs_conf'] defined and is '#{node['awslogs_conf']}' ***")
    awslogs_conf_data = JSON.parse(JSON.generate(node['awslogs_conf']))
else
    Chef::Log.info("*** node['awslogs_conf'] is not defined - set awslogs_conf_data to default ***")
    awslogs_conf_data = { 'default_aws_log': default_aws_log}
end

if awslogs_conf_data.nil?
    Chef::Log.info("*** node['awslogs_conf'] is nil - set awslogs_conf_data to default ***")
    awslogs_conf_data = { 'default_aws_log': default_aws_log}
else
    Chef::Log.info("*** check awslogs_conf_data = '#{awslogs_conf_data}' ***")
    awslogs_conf_data.each do |log_conf_name, cur_log|
        default_aws_log.each do |key, value|
            if not defined?(awslogs_conf_data[log_conf_name][key])
                Chef::Log.info("*** #{log_conf_name}[#{key}] is not defined, set to '#{value}' ***")
                awslogs_conf_data[log_conf_name][key] = value
            elsif awslogs_conf_data[log_conf_name][key].nil?
                Chef::Log.info("*** #{log_conf_name}[#{key}] is nil, set to '#{value}' ***")
                awslogs_conf_data[log_conf_name][key] = value
            end    
        end
    end
end

 

Tags: 

Если вам помогла или просто понравилась статья - плюсаните/поделитесь, пожалуйста.

Добавить комментарий