Spec-Zone.ru › Chef 16

Общие возможности ресурсов

[править на GitHub]

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

Действия

Следующие действия могут использоваться с любым ресурсом:

:nothing

Этот блок ресурса не выполняется, пока не будет уведомлен другим ресурсом о необходимости действия. После уведомления, этот блок ресурса либо выполняется немедленно, либо помещается в очередь для выполнения в конце выполнения Клиента Chef Infra.

Примеры

Следующие примеры показывают, как использовать общие действия в рецепте.

Использование действия :nothing

service 'memcached' do
  action :nothing
end

Свойства

Следующие свойства являются общими для каждого ресурса:

compile_time

Тип Ruby: true, false | Значение по умолчанию: false

Управляет фазой, в которой ресурс выполняется на узле. Установите в true, чтобы выполнить во время построения коллекции ресурсов (compile phase). Установите в false, чтобы выполнить во время конфигурации узла Клиентом Chef Infra (converge phase).

ignore_failure

Тип Ruby: true, false, :quiet | Значение по умолчанию: false

Продолжать выполнение рецепта, если ресурс завершился неудачей по любой причине. :quiet не будет отображать полный стек вызовов, и рецепт продолжит выполнение, если ресурс завершится неудачей.

retries

Тип Ruby: Целое число | Значение по умолчанию: 0

Количество попыток перехватить исключения и повторить ресурс.

retry_delay

Тип Ruby: Целое число | Значение по умолчанию: 2

Задержка повтора (в секундах).

sensitive

Тип Ruby: true, false | Значение по умолчанию: false

Убедитесь, что конфиденциальные данные ресурса не регистрируются Клиентом Chef Infra.

Примеры

Следующие примеры показывают, как использовать общие свойства в рецепте.

Использование общего свойства ignore_failure

gem_package 'syntax' do
  action :install
  ignore_failure true
end

Использование общего свойства retries

service 'apache' do
  action [ :enable, :start ]
  retries 3
end

Защиты

Свойство защиты может использоваться для оценки состояния узла во время фазы выполнения Клиента Chef Infra. Основываясь на результатах этой оценки, свойство защиты затем используется для указания Клиенту Chef Infra, следует ли продолжать выполнение ресурса. Свойство защиты принимает либо строковое значение, либо значение блока Ruby:

  • Строка выполняется как команда оболочки. Если команда возвращает 0, защита применяется. Если команда возвращает любое другое значение, то свойство защиты не применяется. Строковые защиты в блоке powershell_script выполняют команды Windows PowerShell и могут возвращать true в дополнение к 0.
  • Блок выполняется как код Ruby, который должен вернуть либо true, либо false. Если блок возвращает true, свойство защиты применяется. Если блок возвращает false, свойство защиты не применяется.

Свойство защиты полезно для обеспечения идемпотентности ресурса, позволяя этому ресурсу проверять желаемое состояние во время выполнения, а затем, если желаемое состояние присутствует, Клиенту Chef Infra ничего не делать.

Примечание

При использовании защит not_if и only_if с ресурсом execute среда защиты наследуется из среды ресурса. Например:

execute 'bundle install' do
  cwd '/myapp'
  not_if 'bundle check' # This is run from /myapp
end

Свойства

Следующие свойства могут использоваться для определения защиты, которая оценивается во время фазы выполнения Клиента Chef Infra:

not_if

Запрещает выполнение ресурса, когда условие возвращает true.

only_if

Разрешает выполнение ресурса только в том случае, если условие возвращает true.

Аргументы

Следующие аргументы могут использоваться со свойствами защиты not_if или only_if:

:user

Укажите пользователя, от имени которого будет выполняться команда. Например:

not_if 'grep adam /etc/passwd', user: 'adam'
:group

Укажите группу, от имени которой будет выполняться команда. Например:

not_if 'grep adam /etc/passwd', group: 'adam'
:environment

Укажите хеш переменных среды, которые нужно установить. Например:

not_if 'grep adam /etc/passwd', environment: {
  'HOME' => '/home/adam',
}
:cwd

Установите текущую рабочую директорию перед запуском команды. Например:

not_if 'grep adam passwd', cwd: '/etc'
:timeout

Установите таймаут для команды. Например:

not_if 'sleep 10000', timeout: 10

Примеры not_if

Обновить, если не обновлено

Следующий пример показывает, как использовать not_if для предотвращения выполнения команды apt-get-update , когда файл уже существует и идентичен обновленному:

execute 'apt-get-update' do
  command 'apt-get update'
  ignore_failure true
  not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end

Обеспечение возможности узла резолвить хост

Следующий пример показывает, как использовать пользовательский блок кода Ruby для обеспечения возможности узла резолвить хост. Если узел может резолвить хост, Клиент Chef Infra ничего не делает. Если узел не может резолвить хост, Клиент Chef Infra конфигурирует хост:

ruby_block 'ensure node can resolve API FQDN' do
  block do
    fe = Chef::Util::FileEdit.new('/etc/hosts')
    fe.insert_line_if_no_match(/#{node['chef-server']['api_fqdn']}/,
                               "127.0.0.1 #{node['chef-server']['api_fqdn']}")
    fe.write_file
  end
  not_if { Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false }
end

Предотвращение установок на старых версиях

Следующий пример показывает, как использовать not_if для предотвращения установки ZeroMQ, когда узел, на котором должна быть установка, имеет версию Red Hat Enterprise Linux, более старую, чем 6.0:

ark 'test_autogen' do
  url 'https://github.com/zeromq/libzmq/tarball/master'
  extension 'tar.gz'
  action :configure
  not_if { platform_family?('rhel') && node['platform_version'].to_f < 6.0 }
end

Установка администратора, если он ещё не установлен

Следующий пример показывает, как установить администратора для Nagios на нескольких узлах, за исключением случаев, когда пакет уже существует на узле:

%w(adminpassword adminpassword-repeat).each do |setting|
  execute "debconf-set-selections::#{node['nagios']['server']['vname']}-cgi::#{node['nagios']['server']['vname']}/#{setting}" do
    command "echo #{node['nagios']['server']['vname']}-cgi #{node['nagios']['server']['vname']}/#{setting} password #{random_initial_password} | debconf-set-selections"
    not_if "dpkg -l #{node['nagios']['server']['vname']}"
  end
end

Примеры only_if

Установка пакетов только по необходимости

Следующий пример показывает, как использовать only_if с одним (или несколькими) атрибутами кулинарной книги, чтобы убедиться, что пакеты устанавливаются только по необходимости. В данном случае в файле /attributes/default.rb существуют три атрибута: use_openssl, use_pcre, и use_zlib. Каждый из этих атрибутов по умолчанию определен как false. Атрибуты only_if используются для проверки наличия этих пакетов на целевом узле перед тем, как попросить Клиент Chef Infra выполнить процесс установки этих пакетов. Если пакеты уже присутствуют, Клиент Chef Infra ничего не делает.

package 'libpcre3-dev' do
  only_if { node['haproxy']['source']['use_pcre'] }
end

package 'libssl-dev' do
  only_if { node['haproxy']['source']['use_openssl'] }
end

package 'zlib1g-dev' do
  only_if { node['haproxy']['source']['use_zlib'] }
end

Удаление рецепта, если он принадлежит к определённому списку выполнения

Следующий пример показывает, как использовать only_if для удаления только рецепта с именем recipe[ntp::undo], но только тогда, когда этот рецепт является частью списка выполнения recipe[ntp::default]:

ruby_block 'remove ntp::undo from run list' do
  block do
    node.run_list.remove('recipe[ntp::undo]')
  end
  only_if { node.run_list.include?('recipe[ntp::default]') }
end

Перерегистрация ASP.Net, если она уже установлена

Следующий пример показывает, как использовать only_if для обеспечения того, что Клиент Chef Infra попытается зарегистрировать ASP.NET только в том случае, если исполняемый файл установлен в системе, как на 32-битных, так и на 64-битных системах:

aspnet_regiis = "#{ENV['WinDir']}\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4' do
  command "#{aspnet_regiis} -i"
  only_if { ::File.exist?(aspnet_regiis) }
  action :nothing
end

aspnet_regiis64 = "#{ENV['WinDir']}\\Microsoft.NET\\Framework64\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4 (x64)' do
  command "#{aspnet_regiis64} -i"
  only_if { ::File.exist?(aspnet_regiis64) }
  action :nothing
end

Интерпретаторы защит

Любой ресурс, который передаёт строковую команду, также может указать интерпретатор, который будет использоваться для оценки этой строковой команды. Это делается с помощью свойства guard_interpreter для указания ресурса на основе script.

Атрибуты

Свойство guard_interpreter может быть установлено в любое из следующих значений:

:bash

Оценивает строковую команду с помощью ресурса bash.

:batch

Оценивает строковую команду с помощью ресурса batch. Значение по умолчанию (внутри блока ресурса batch): :batch.

:csh

Оценивает строковую команду с помощью ресурса csh.

:default

По умолчанию. Выполняет интерпретатор по умолчанию, определённый Клиентом Chef Infra.

:perl

Оценивает строковую команду с помощью ресурса perl.

:powershell_script

Оценивает строковую команду с помощью ресурса powershell_script. Значение по умолчанию (внутри блока ресурса powershell_script): :powershell_script.

:python

Оценивает строковую команду с помощью ресурса python.

:ruby

Оценивает строковую команду с помощью ресурса ruby.

Наследование

Свойство guard_interpreter установлено в :default по умолчанию для ресурсов bash, csh, perl, python и ruby. Когда свойство guard_interpreter установлено в :default, not_if или only_if операторы защиты не наследуют свойства, определённые ресурсом на основе script.

Предупреждение

Ресурсы batch и powershell_script наследуют свойства по умолчанию. Свойство guard_interpreter установлено в :batch или :powershell_script автоматически при использовании оператора защиты not_if или only_if внутри ресурса batch или powershell_script соответственно.

Например, оператор защиты not_if в следующем примере ресурса не наследует свойство environment:

bash 'javatooling' do
  environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
  code 'java-based-daemon-ctl.sh -start'
  not_if 'java-based-daemon-ctl.sh -test-started'
end

и требует добавления свойства environment к оператору защиты not_if для того, чтобы он мог использовать путь JAVA_HOME в своей оценке:

bash 'javatooling' do
  environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
  code 'java-based-daemon-ctl.sh -start'
  not_if 'java-based-daemon-ctl.sh -test-started', :environment => 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
end

Чтобы унаследовать свойства, добавьте свойство guard_interpreter в блок ресурса и установите его в нужное значение:

  • :bash для bash
  • :csh для csh
  • :perl для perl
  • :python для python
  • :ruby для ruby

Например, используя тот же пример, что и выше, но на этот раз добавляя свойство guard_interpreter и устанавливая его в значение :bash.

bash 'javatooling' do
  guard_interpreter :bash
  environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
  code 'java-based-daemon-ctl.sh -start'
  not_if 'java-based-daemon-ctl.sh -test-started'
end

Оператор not_if теперь наследует свойство environment и будет использовать путь JAVA_HOME в рамках своего вычисления.

Примеры

Например, следующий блок кода гарантирует, что команда будет вычислена с использованием интерпретатора по умолчанию, определенного клиентом Chef Infra:

resource 'name' do
  guard_interpreter :default
  # code
end

Ленивое вычисление

В некоторых случаях значение свойства может быть неизвестно до фазы выполнения выполнения клиента Chef Infra. В этой ситуации ленивое вычисление значений свойств может быть полезным. Вместо того, чтобы свойству было присвоено значение, оно может быть присвоено блоку кода. Синтаксис использования ленивого вычисления следующий:

property_name lazy { code_block }

где lazy используется для того, чтобы указать клиенту Chef Infra Client, что содержимое блока кода следует вычислить позже в процессе оценки ресурса (а не немедленно), а { code_block } — произвольный код Ruby, который предоставляет значение.

Например, ресурс, который не выполняет ленивое вычисление:

template 'template_name' do
  # some properties
  path '/foo/bar'
end

и блок ресурса, который выполняет ленивое вычисление:

template 'template_name' do
  # some properties
  path lazy { ' some Ruby code ' }
end

В предыдущих примерах первый ресурс использует значение /foo/bar, а второй ресурс использует значение, предоставленное блоком кода, при условии, что содержимое этого блока кода является допустимым свойством ресурса.

Следующий пример демонстрирует использование ленивого вычисления с переменными шаблонов:

template '/tmp/canvey_island.txt' do
  source 'canvey_island.txt.erb'
  variables(
    lazy do
      { canvey_island: node.run_state['sea_power'] }
    end
  )
end

Уведомления

Уведомление — это свойство ресурса, которое следит за другими ресурсами в коллекции ресурсов и затем выполняет действия на основе типа уведомления (notifies или subscribes).

Таймеры

Таймер определяет момент во время выполнения клиента Chef Infra, в котором выполняется уведомление. Доступны следующие таймеры:

:before

Указывает, что действие над уведомлённым ресурсом должно быть выполнено до обработки блока ресурса, в котором находится уведомление.

:delayed

По умолчанию. Указывает, что уведомление должно быть помещено в очередь и выполнено в конце выполнения клиента Chef Infra.

:immediate, :immediately

Указывает, что уведомление должно быть выполнено немедленно, для каждого уведомлённого ресурса.

Уведомления

Ресурс может уведомлять другой ресурс о выполнении действия при изменении его состояния. Укажите 'resource[name]', действие, которое должен выполнить ресурс, и :timer для этого действия. Ресурс может уведомлять несколько ресурсов; используйте оператор notifies для каждого уведомляемого ресурса.

Если указанный ресурс не существует, возникает ошибка. В отличие от этого, subscribes не завершится ошибкой, если исходный ресурс не найден.

Синтаксис для notifies:

notifies :action, 'resource[name]', :timer

Изменено в Chef Client 12.6 для использования таймера :before с свойствами notifies и subscribes для указания того, что действие над уведомлённым ресурсом должно выполняться до обработки блока ресурса, в котором находится уведомление.

Примеры

Следующие примеры показывают, как использовать уведомление notifies в рецепте.

Задержка уведомлений

template '/etc/nagios3/configures-nagios.conf' do
  # other parameters
  notifies :run, 'execute[test-nagios-config]', :delayed
end

Немедленное уведомление

По умолчанию уведомления :delayed, то есть они помещаются в очередь по мере возникновения, а затем выполняются в самом конце выполнения клиента Chef Infra. Для немедленного выполнения действия используйте :immediately:

template '/etc/nagios3/configures-nagios.conf' do
  # other parameters
  notifies :run, 'execute[test-nagios-config]', :immediately
end

и тогда клиент Chef Infra немедленно выполнит следующее:

execute 'test-nagios-config' do
  command 'nagios3 --verify-config'
  action :nothing
end

Уведомление нескольких ресурсов

template '/etc/chef/server.rb' do
  source 'server.rb.erb'
  owner 'root'
  group 'root'
  mode '0755'
  notifies :restart, 'service[chef-elasticsearch]', :delayed
  notifies :restart, 'service[chef-server]', :delayed
end

Уведомление в определённом порядке

Для уведомления нескольких ресурсов и последующего выполнения этих ресурсов в определённом порядке выполните следующее:

execute 'foo' do
  command '...'
  notifies :create, 'template[baz]', :immediately
  notifies :install, 'package[bar]', :immediately
  notifies :run, 'execute[final]', :immediately
end

template 'baz' do
  ...
  notifies :run, 'execute[restart_baz]', :immediately
end

package 'bar'

execute 'restart_baz'

execute 'final' do
  command '...'
end

где упорядочивание будет соответствовать порядку перечисления ресурсов в рецепте: execute 'foo', template 'baz', execute [restart_baz], package 'bar', и execute 'final'.

Перезагрузка службы

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  notifies :reload, 'service[apache]', :immediately
end

Перезапуск службы при изменении шаблона

template '/etc/www/configures-apache.conf' do
  notifies :restart, 'service[apache]', :immediately
end

Отправка уведомлений нескольким ресурсам

Для отправки уведомлений нескольким ресурсам просто используйте несколько атрибутов. Несколько атрибутов будут отправлены уведомлённым ресурсам в указанном порядке.

template '/etc/netatalk/netatalk.conf' do
  notifies :restart, 'service[afpd]', :immediately
  notifies :restart, 'service[cnid]', :immediately
end

service 'afpd'
service 'cnid'

Выполнение команды с использованием шаблона

Следующий пример показывает, как настроить IPv4 пакетную передачу с помощью ресурса execute для выполнения команды forward_ipv4, которая использует шаблон, определённый ресурсом template:

execute 'forward_ipv4' do
  command 'echo > /proc/.../ipv4/ip_forward'
  action :nothing
end

template '/etc/file_name.conf' do
  source 'routing/file_name.conf.erb'
  notifies :run, 'execute[forward_ipv4]', :delayed
end

где свойство command ресурса execute содержит команду, которая должна быть выполнена, а свойство source ресурса template указывает, какой шаблон использовать. Свойство notifies для template указывает, что execute[forward_ipv4] (которое определено ресурсом execute) должно быть помещено в очередь и выполнено в конце выполнения клиента Chef Infra.

Перезапуск службы и уведомление другой службы

Следующий пример показывает, как запустить службу example_service и немедленно уведомить службу Nginx о перезапуске.

service 'example_service' do
  action :start
  notifies :restart, 'service[nginx]', :immediately
end

Перезапуск одной службы перед перезапуском другой

В этом примере используется уведомление :before для перезапуска службы php-fpm перед перезапуском nginx:

service 'nginx' do
  action :restart
  notifies :restart, 'service[php-fpm]', :before
end

С уведомлением :before действие, указанное для ресурса nginx будет выполнено только после выполнения действия над уведомлённым ресурсом (php-fpm).

Уведомление об изменениях в удалённом источнике

remote_file '/tmp/couch.png' do
  source 'http://couchdb.apache.org/img/sketch.png'
  action :nothing
end

http_request 'HEAD http://couchdb.apache.org/img/sketch.png' do
  message ''
  url 'http://couchdb.apache.org/img/sketch.png'
  action :head
  if ::File.exist?('/tmp/couch.png')
    headers 'If-Modified-Since' => File.mtime('/tmp/couch.png').httpdate
  end
  notifies :create, 'remote_file[/tmp/couch.png]', :immediately
end

Подписки

Ресурс может следить за другим ресурсом и выполнять действия, если состояние отслеживаемого ресурса изменится. Укажите 'resource[name]', действие, которое будет выполнено, и :timer для этого действия.

Обратите внимание, что subscribes не применяет указанное действие к ресурсу, за которым он следит — например:

file '/etc/nginx/ssl/example.crt' do
  mode '0600'
  owner 'root'
end

service 'nginx' do
  subscribes :reload, 'file[/etc/nginx/ssl/example.crt]', :immediately
end

В этом случае свойство subscribes перезагружает службу nginx всякий раз, когда обновляется её сертификат файл, расположенный по адресу /etc/nginx/ssl/example.crt. subscribes не вносит никаких изменений в сам файл сертификата, он просто следит за изменениями в файле и выполняет действие :reload для своего ресурса (в данном случае nginx) при обнаружении изменения.

Если другой ресурс не существует, подписка не вызовет ошибку. В отличие от этого, notifies, которая вызовет ошибку, если другой ресурс не существует.

Синтаксис для subscribes:

subscribes :action, 'resource[name]', :timer

Примеры

Следующие примеры демонстрируют использование уведомления subscribes в рецепте.

Проверка обновления конфигурации

Используйте действие :nothing (общее для всех ресурсов) для предотвращения автоматического запуска теста, а затем используйте уведомление subscribes для запуска теста конфигурации при обнаружении изменений в шаблоне:

execute 'test-nagios-config' do
  command 'nagios3 --verify-config'
  action :nothing
  subscribes :run, 'template[/etc/nagios3/configures-nagios.conf]', :immediately
end

Перезагрузка службы при обновлении шаблона

Для перезагрузки службы, основанной на шаблоне, используйте ресурсы template и service вместе в одном рецепте, аналогично следующему:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
end

service 'apache' do
  action :enable
  subscribes :reload, 'template[/tmp/somefile]', :immediately
end

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

Относительные пути

Следующие относительные пути могут быть использованы с любым ресурсом:

#{ENV['HOME']}

Используется для возвращения пути ~ в Linux и macOS или пути %HOMEPATH% в Microsoft Windows.

Примеры

template "#{ENV['HOME']}/chef-getting-started.txt" do
  source 'chef-getting-started.txt.erb'
  mode '0755'
end

Выполнение на стадии компиляции

Клиент Chef Infra обрабатывает рецепты в двух фазах:

  1. Сначала каждый ресурс в объекте узла идентифицируется, и создаётся коллекция ресурсов. Все рецепты загружаются в определённом порядке, а затем идентифицируются указанные в них действия. Это также называется «фазой компиляции».
  2. Далее, клиент Chef Infra настраивает систему на основе порядка ресурсов в коллекции ресурсов. Каждый ресурс затем анализирует узел и выполняет необходимые действия для завершения действия. Это также называется «фазой выполнения».

Обычно действия обрабатываются во время фазы выполнения выполнения клиента Chef Infra. Однако иногда необходимо выполнить действие во время фазы компиляции. Например, ресурс может быть настроен на установку пакета во время фазы компиляции, чтобы гарантировать, что приложение доступно другим ресурсам во время фазы выполнения.

Примечание

Используйте ресурс chef_gem для установки драгоценных камней, необходимых клиенту Chef Infra во время фазы выполнения.

Использование свойства compile_time

Используйте .run_action(:some_action) в конце блока ресурса, чтобы выполнить указанное действие во время фазы компиляции. Например:

build_essential 'Install compilers' do
  action :nothing
end.run_action(:install)

где action установлено в :nothing для обеспечения того, что run_action выполняется во время фазы компиляции, а не позднее во время фазы выполнения.

Это можно упростить, используя флаг compile_time в Chef Infra Client 16 и более поздних версиях:

build_essential 'Install compilers' do
  compile_time true
end

Этот флаг как принудительно выполняет ресурс во время компиляции, так и устанавливает действие слияния в :nothing.

Следующие примеры показывают, когда (и когда не следует) использовать run_action.

Использование пользовательских ресурсов предпочтительнее принудительного выполнения во время компиляции

Выполнение во время компиляции часто используется для установки gem перед использованием их в коде рецепта.

Это плохой подход, поскольку gem могут зависеть от родных gem, которые могут потребовать установки компиляторов во время компиляции.

build_essential 'Install compilers' do
  compile_time true
end

chef_gem 'aws-dsk' do
  compile_time true
end

require 'aws-sdk'

Лучшая стратегия — переместить код, требующий gem, в пользовательский ресурс. Поскольку все действия пользовательских ресурсов выполняются во время слияния, это откладывает требование gem до более позднего этапа выполнения Chef Infra Client. Режим унификации также можно использовать в ресурсе для полного устранения проблем с режимами компиляции/слияния:

unified_mode true

action :run do
  build_essential 'Install compilers'

  chef_gem 'aws-sdk'

  require 'aws-sdk'
end

Загрузка и парсинг файла конфигурации

Распространённый случай использования — загрузка файла конфигурации, его парсинг и затем использование значений в шаблонах и для управления другими настройками.

Важное различие заключается в том, что загруженный файл конфигурации существует только во временном состоянии, чтобы использоваться Chef Infra Client. Он не будет использоваться напрямую системой или приложениями, которые управляются Chef Infra Client.

Для загрузки и парсинга JSON-файла и его рендеринга в шаблоне имеет смысл загрузить файл во время компиляции:

  # the remote_file is being downloaded to a temporary file
  remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
    source "https://jsonplaceholder.typicode.com/users"
    compile_time true
  end

  # this parsing needs to happen after the remote_file is downloaded, but will
  # be executed at compile time.
  array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")

  # the `array.last["phone"]` expression here will also be evaluated at compile
  # time and must be lazied via wrapping the expresssion in `lazy {}`
  file "/tmp/phone_number.txt" do
    content array.last["phone"]
  end

Это значительно чище, чем альтернатива — ленивая оценка как парсинга JSON, так и рендеринга данных в шаблон файла, что произойдёт, если ресурс remote_file не выполняется во время компиляции:

  # the execution of this is now deferred
  remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
    source "https://jsonplaceholder.typicode.com/users"
  end

  # it is necessary due to lexical scoping issues to create this variable here
  array = nil

  # the parsing of the JSON is now deferred due to the ruby_block
  ruby_block "parse JSON" do
    block do
      array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")
    end
  end

  # the argument to the content property must now also be deferred
  file "/tmp/phone_number.txt" do
    content lazy { array.last["phone"] }
  end

Это пример кода, который чрезмерно использует отложенное выполнение, использует больше «ленивой» оценки и значительно сложнее понять и правильно написать.

Уведомления не будут работать

Ресурсы, выполняемые во время фазы компиляции, не могут уведомлять другие ресурсы. Например:

execute 'ifconfig'

package 'vim-enhanced' do
  compile_time true
  notifies :run, 'execute[ifconfig]', :immediately
end

Лучший подход в этом случае — установить пакет перед созданием коллекции ресурсов, чтобы убедиться, что он доступен другим ресурсам позже.

Лучший подход к этой проблеме — использовать unified mode, который устраняет различие между фазами компиляции и слияния, позволяя уведомлениям работать правильно.

Ресурсы, которые по умолчанию принудительно выполняются во время компиляции

Ресурсы ohai_hint и hostname по умолчанию выполняются во время компиляции.

Это связано с тем, что последующие ресурсы могут использовать атрибуты узла, которые задаются этими ресурсами, что приводит к чрезмерному использованию lazy в последующих ресурсах (и аналогичным проблемам с примером remote_file выше).

Ресурс chef_gem раньше выполнялся по умолчанию во время компиляции, но сейчас рекомендуется перемещать код, который выполняется во время компиляции, в пользовательские ресурсы.

Безопасность файлов Windows

Для поддержки безопасности Microsoft Windows ресурсы шаблон, файл, удаленный_файл, файл_кулинарии, каталог и удаленный_каталог поддерживают использование наследования и списков управления доступом (ACL) в рецептах.

Списки управления доступом (ACL)

Свойство rights может использоваться в рецепте для управления списками управления доступом (ACL), которые позволяют предоставлять права множеству пользователей и групп. Свойство rights можно использовать любое количество раз; Chef Infra Client будет применять их к файлу или каталогу по мере необходимости. Синтаксис свойства rights следующий:

rights permission, principal, option_type => value

где

permission

Используется для указания прав, предоставляемых principal. Возможные значения: :read, :write, read_execute, :modify и :full_control.

Эти права суммируются. Если указано :write, то оно включает в себя :read. Если указано :full_control, то оно включает в себя как :write, так и :read.

(Для тех, кто знаком с API Microsoft Windows: :read соответствует GENERIC_READ; :write соответствует GENERIC_WRITE; :read_execute соответствует GENERIC_READ и GENERIC_EXECUTE; :modify соответствует GENERIC_WRITE, GENERIC_READ, GENERIC_EXECUTE и DELETE; :full_control соответствует GENERIC_ALL, что позволяет пользователю изменять владельца и другие метаданные файла.)

principal

Используется для указания группы или пользователя. Сущность может быть указана по имени или SID. При использовании имени это идентично тому, что вводится в поле входа Microsoft Windows, например user_name, domain\user_name или user_name@fully_qualified_domain_name. При использовании SID вы можете использовать как стандартное строковое представление SID (S-R-I-S-S), так и один из констант строк SDDL. Chef Infra Client не нужно знать, является ли сущность пользователем или группой.

option_type

Хэш, содержащий расширенные параметры прав. Например, права на каталог, которые применяются только к первому уровню потомков, могут выглядеть примерно так: rights :write, 'domain\group_name', :one_level_deep => true. Возможные типы опций:

Тип опции Описание
:applies_to_children Указывает, как права применяются к потомкам. Возможные значения: true для наследования как подкаталогов, так и файлов; false для не наследования никаких подкаталогов или файлов; :containers_only для наследования только подкаталогов (и не файлов); :objects_only для рекурсивного наследования файлов (и не подкаталогов).
:applies_to_self Указывает, применяется ли право к родительскому каталогу. Возможные значения: true для применения к родительскому каталогу или файлу и его потомкам; false для применения только к подкаталогам и файлам.
:one_level_deep Указывает глубину, до которой будут применяться права. Возможные значения: true для применения только к первому уровню потомков; false для применения ко всем потомкам.

Например:

resource 'x.txt' do
  rights :read, 'S-1-1-0'
  rights :write, 'domain\group'
  rights :full_control, 'group_name_or_user_name'
  rights :full_control, 'user_name', applies_to_children: true
end

или:

rights :read, %w(Administrators Everyone)
rights :full_control, 'Users', applies_to_children: true
rights :write, 'Sally', applies_to_children: :containers_only, applies_to_self: false, one_level_deep: true

Некоторые другие важные моменты при использовании атрибута rights:

  • Остаются только унаследованные права. Все существующие явные права на объект удаляются и заменяются.
  • Если права не указаны, ничего не изменится. Chef Infra Client не очищает права на файл или каталог, если права не указаны.
  • Изменение унаследованных прав может быть дорогостоящим. Microsoft Windows будет рекурсивно распространять права на всех потомков из-за наследования. Это нормальный аспект Microsoft Windows, поэтому подумайте о частоте необходимости этого типа действия и примите меры для управления этим типом действия, если производительность является основным фактором.

Используйте свойство deny_rights для отказа конкретным пользователям в предоставлении определенных прав. Порядок не зависит от использования свойства rights. Например, неважно, если права на всех указаны до или после deny_rights :read, ['Julian', 'Lewis'], оба Джулиан и Левис не смогут прочитать документ. Например:

resource 'x.txt' do
  rights :read, 'Everyone'
  rights :write, 'domain\group'
  rights :full_control, 'group_name_or_user_name'
  rights :full_control, 'user_name', applies_to_children: true
  deny_rights :read, %w(Julian Lewis)
end

или:

deny_rights :full_control, ['Sally']

Наследование

По умолчанию файл или каталог наследуют права от родительского каталога. В большинстве случаев это предпочтительное поведение, но иногда может потребоваться принять меры для более точного управления правами. Свойство inherits может использоваться, чтобы явно указать Chef Infra Client на применение (или не применение) унаследованных прав от родительского каталога.

Например, следующий пример указывает права для каталога:

directory 'C:\mordor' do
  rights :read, 'MORDOR\Minions'
  rights :full_control, 'MORDOR\Sauron'
end

а следующий пример показывает, как использовать наследование для отказа в доступе к подкаталогу:

directory 'C:\mordor\mount_doom' do
  rights :full_control, 'MORDOR\Sauron'
  inherits false # Sauron is the only person who should have any sort of access
end

Если вместо права deny_rights использовалось бы другое, что-то могло бы проскользнуть, если бы все пользователи и группы не были бы запрещены.

Еще один пример также показывает, как указать права для каталога:

directory 'C:\mordor' do
  rights :read, 'MORDOR\Minions'
  rights :full_control, 'MORDOR\Sauron'
  rights :write, 'SHIRE\Frodo' # Who put that there I didn't put that there
end

но затем не использовать свойство inherits для отказа в этих правах для подкаталога:

directory 'C:\mordor\mount_doom' do
  deny_rights :read, 'MORDOR\Minions' # Oops, not specific enough
end

Поскольку свойство inherits не указано, Chef Infra Client установит его по умолчанию в true, что гарантирует, что настройки безопасности для существующих файлов останутся неизменными.

© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/resource_common/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API