Spec-Zone.ru › Chef 18

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

[править на 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 и retry_delay

service 'apache' do
  action [ :enable, :start ]
  retries 3
  retry_delay 5
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 Client завершить процесс установки этих пакетов. Если пакеты уже присутствуют, Chef Infra Client ничего не сделает.

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 Client попытается зарегистрировать 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 для указания ресурса на основе скрипта.

Атрибуты

Свойство 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 операторы фильтра не наследуют свойства, определенные ресурсом на основе скрипта.

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

Ресурсы 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 Client. В этой ситуации может быть полезно использовать ленивое вычисление значений свойств. Вместо того, чтобы свойству было присвоено значение, ему может быть присвоен блок кода. Синтаксис для использования ленивого вычисления следующий:

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 Client, в который выполняется уведомление. Доступны следующие таймеры:

:before

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

:delayed

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

: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 Client. Чтобы выполнить действие немедленно, используйте :immediately:

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

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

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 Client.

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

Следующий пример показывает, как запустить службу под названием 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 Client обрабатывает рецепты в двух фазах:

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

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

Примечание

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

Использование свойства 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 могут зависеть от других native 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 ресурсы template, file, remote_file, cookbook_file, directory и remote_directory поддерживают использование наследования и списков управления доступом (ACL) в рецептах.

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

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

rights permission, principal, option_type => value

где

permission

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

Целые числа, используемые для разрешений, должны соответствовать следующему списку FileSystemRights Enum полей.

These permissions are cumulative. If `:write` is specified, then it
includes `:read`. If `:full_control` is specified, then it includes
both `:write` and `:read`.

(For those who know the Microsoft Windows API: `:read` corresponds
to `GENERIC_READ`; `:write` corresponds to `GENERIC_WRITE`;
`:read_execute` corresponds to `GENERIC_READ` and `GENERIC_EXECUTE`;
`:modify` corresponds to `GENERIC_WRITE`, `GENERIC_READ`,
`GENERIC_EXECUTE`, and `DELETE`; `:full_control` corresponds to
`GENERIC_ALL`, which allows a user to change the owner and other
metadata about a file.)
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