Входные данные Chef InSpec
Что такое Входные данные?
Входные данные — это «ручки», которые можно использовать для настройки поведения профилей Chef InSpec. Если профиль поддерживает входные данные, вы можете задать их различными способами, обеспечивая гибкость. Профили, включающие другие профили, могут задавать входные данные в включенном профиле, что позволяет использовать многоуровневый подход к настройке профилей.
Простой пример
Предположим, у вас есть профиль с именем rock_critic. В его файле метаданных (inspec.yml):
# Optionally declare inputs in the profile metadata# This lets you set up things like type checking, etc.inputs:- name:amplifier_max_volumedescription:How loud the amplifiers can gotype:numeric# More options, including value: and priority: are possible hereВ коде управления профиля:
# Set a default value for an input. This is optional.
input('amplifier_max_volume', value: 10)
control 'Big Rock Show' do
describe input('amplifier_max_volume') do # This line reads the value of the input
it { should cmp 11 } # The UK'S LOUDEST BAND
end
end
Когда указанный выше профиль выполняется с помощью inspec exec rock_critic, вы увидите что-то вроде:
× Big Rock Show: 10
× 10 is expected to cmp == 11
expected: 11
got: 10
(compared using `cmp` matcher)
Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped
Этот результат явно не подходит. Давайте перезапишем значение по умолчанию входного параметра.
Теперь мы можем запустить этот профиль с помощью inspec exec rock_critic --input amplifier_max_volume=11:
✔ Big Rock Show: 11
✔ 11 is expected to cmp == 11
Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Какие профили поддерживают входные данные?
Лучший способ для профиля указать, что он поддерживает входные данные, — это перечислить их в файле метаданных inspec.yml. Любой профиль, имеющий раздел inputs (или устаревший раздел attributes) в файле метаданных inspec.yml, настраивает входные данные.
При этом любой профиль, использующий ключевое слово DSL input() (или устаревшее ключевое слово attribute()) в коде управления, поддерживает входные данные. Эти профили считывают (и, возможно, устанавливают) значения входных данных и используют их для принятия решений.
Как установить входные данные?
В стандартной установке (без специализированных плагинов) Chef InSpec поддерживает несколько способов задания входных данных:
- Прямо в коде управления, используя
input('input_name', value: 42). - В файлах метаданных профиля
inspec.yml - Используя параметр командной строки
--input name1=value1 name2=value2...для прямого считывания из командной строки - Используя параметр командной строки
--input-file somefile.yamlдля считывания входных данных из файлов - В kitchen-inspec, используя настройки
verifier/inputs - В книге аудита, используя
node[:audit][:inputs]
Кроме того, Chef InSpec поддерживает плагины для входных данных, которые могут предоставлять дополнительные интеграции со специфическими хранилищами пар ключ-значение.
Как работает приоритет входных данных?
Простой порядок приоритетов
Кратко:
DSL встраиваемый < метаданные < (файл-вход-командной-строки или kitchen-inspec или книга-аудита) < вход-командной-строки
Кроме того, для унаследованных профилей:
метаданные зависимого профиля < метаданные оболочечного профиля
Этот порядок приоритетов позволяет переопределять значения входных данных в командной строке, а также переопределять значения входных данных в дочернем профиле из родительского профиля. Это описание соответствует общему поведению InSpec v3, а также упрощает понимание некоторых крайних случаев.
Подробности порядка приоритетов входных данных
Всякий раз, когда поставщик входных данных устанавливает значение входного параметра, операции присваивается значение приоритета. В течение жизненного цикла входного параметра могут возникать несколько операций присваивания с различными значениями приоритета. При оценке входного параметра текущее значение определяется по событию задания с наивысшим приоритетом.
Обратите внимание, что этот подход не зависит от порядка выполнения и не использует несколько уровней приоритета с именами. Каждая операция задания сохраняется, что позволяет пользователю отладить историю значений входных данных.
Некоторые поставщики входных данных позволяют задавать приоритет при установке значения. Например, чтобы задать приоритет 50 в файле метаданных, используйте:
inputs:- name:very_important_inputvalue:12priority:50Чтобы задать приоритет в DSL, используйте:
input('also_important', value: 42, priority: 45)
В стандартной комплектации Chef InSpec используются следующие значения приоритетов:
| Поставщик входных данных | Приоритет | Можно изменить приоритет |
|---|---|---|
| Встраиваемый DSL | 20 | Да |
| Метаданные | 30 | Да |
| Метаданные в оболочечной книге рецептов | 35 | Да |
Параметр командной строки --input-file |
40 | Нет |
Раздел inspec-kitchen inputs: |
40 | Нет |
Книга рецептов аудита node[:audit][:inputs] |
40 | Нет |
Параметр командной строки --input |
50 | Нет |
Что случилось с «Атрибутами»?
При первоначальном введении механизм входных данных назывался Атрибутами. Это название вызывало проблемы, поскольку:
- Инструмент Chef Infra использует то же самое слово для описания своей системы параметризации.
- Атрибуты Chef Infra имеют совершенно другую и гораздо более сложную систему приоритетов.
- Это вызывало путаницу относительно передачи атрибутов Chef Infra в InSpec при использовании книги рецептов аудита и kitchen-inspec.
В связи с этими проблемами атрибуты InSpec были переименованы во входные данные InSpec в Chef InSpec v4.
Поддержка использования ключевого слова DSL attribute(), поля метаданных attributes:, и соответствующих значений kitchen-inspec и книги рецептов аудита ожидается в Chef InSpec v5.
Работа с входными данными в коде управления
Область действия входных данных
Входные данные доступны во всем DSL профиля InSpec. Вы можете использовать их где угодно.
# some_controls.rb
input('outer_input', value: 1) # here
control 'control-1' do
input('control_dsl_input', value: 2) # here too
describe some_resource do
input('test_dsl_input', value: 3) # even here
it { should cmp input('expectation_dsl_input') } # and yes here too
end
end
Установка входных данных в DSL управления
Когда вы пишете input('some_name', value: 'some_value'), вы устанавливаете значение входного параметра в DSL. Поскольку присутствует параметр value:, будет установлено новое значение. Вы также можете передать любые другие параметры, перечисленные в справочнике по параметрам входных данных.
Чтение входных данных в DSL управления
Когда вы вызываете input('some_name'), с дополнительными параметрами или без них, значение входного параметра будет разрешено и возвращено. Обратите внимание, что этот процесс может включать получение значения от другого поставщика, использование значения, заданного в DSL, или переопределение значения, указанного в том же вызове.
# You can use the value in a Ruby variable
some_var = input('some_input_name')
# Or more directly in a resource parameter
describe file(input('important_path')) do
it { should exist }
end
# Or as the resource itself (this could be a string, here)
describe input('some_setting') do
it { should cmp 'correct_value' }
end
# Or as the expected value
describe file('/etc/httpd/httpd.conf') do
its('owner') { should_not cmp input('webserver_user') }
end
Возвращаемое значение может быть использовано везде, где используется значение Ruby.
Настройка входных данных в метаданных профиля
Каждый профиль Chef InSpec имеет файл метаданных на верхнем уровне с именем inspec.yml. В этом файле вы можете добавить раздел для входных данных. Вы можете определить входные данные, четко задавая параметры, включая значения, проверку типов и является ли входной параметр обязательным.
name:my_profileinputs:- name:webserver_user # Name is the only required field- name:favorite_fruitvalue:banana # You can set a value; priority is 30 for metadata- name:meaning_of_lifetype:Numericvalue:42required:truepriority:70sensitive:trueВсе параметры входных данных поддерживаются в файлах метаданных.
Существуют два основных преимущества определения входных данных в метаданных профиля:
- Входные данные и их конфигурация явно перечислены в простом YAML в одном месте — потребитель вашего профиля не должен читать код управления, чтобы найти входные данные.
- Вы можете задавать входные данные в других профилях, от которых вы зависите, используя наследование профилей.
Использование входных данных с наследованием профилей
Когда ваш профиль зависит от другого профиля, используя ключ depends в файле метаданных, вы можете установить — то есть, переопределить — значение входного параметра в зависимом профиле, включив параметр profile и указав зависимый профиль.
# child inspec.ymlname:childinputs:- name:favorite_foodvalue:pizza# wrapper inspec.ymlname:wrapperdepends:- name:childpath:../childinputs:- name:favorite_foodvalue:broccoliprofile:child # <----- REQUIRED to override the value in InSpec 4В Chef InSpec 4+ каждый входной параметр имеет пространство имен. Например, у вас может быть входной параметр с именем wrapper/favorite_food и другой с именем child/favorite_food. Если в файле метаданных профиля wrapper не указан явный параметр профиля, то wrapper считается профилем.
Установка значений входных данных с помощью --input-file
Вы также можете указать входные данные и значения через файлы YAML в командной строке. Формат показан ниже:
an_input:a_valueanother_input:another_valueВходные данные, заданные файлом CLI, имеют приоритет 40.
По состоянию на Chef InSpec 4.3.2, этот механизм имеет следующие ограничения:
- Нельзя задавать параметры входных данных — только имя и значение.
- Поскольку командная строка находится вне области действия любого отдельного профиля, а входные данные не принимают параметры, входные данные неудобно копируются в каждый профиль, эффективно делая механизм командной строки глобальным.
Установка значений входных данных с помощью --input
Вы также можете указать входные данные и значения непосредственно в командной строке:
inspec exec my_profile --input input_name=input_valueДля задания нескольких входных данных, например:
inspec exec my_profile --input input_name1=input_value1 name2=value2Если значение входных данных CLI напоминает число, оно будет преобразовано в целое число или число с плавающей запятой. Научная запись в настоящее время не распознается.
inspec exec my_profile --input amplifier_volume=-11inspec exec my_profile --input water_depth=11.5Вы можете задавать входные данные со сложными значениями, такими как массивы и хэши, используя синтаксис YAML или JSON. Просто убедитесь, что вы защищаете строку от оболочки, используя одинарные кавычки.
inspec exec my_profile --input alphabet='[a,b,c]'inspec exec my_profile --input fruits='{a: apples, b: bananas, c: cantelopes}'inspec exec my_profile --input json_fruit='{"a": "apples", "g": ["grape01", "grape02"] }'Не повторяйте флаг --input; это переопределит предыдущее значение.
Входные данные, заданные в командной строке, имеют приоритет 50.
По состоянию на Chef InSpec 4.12, этот механизм имеет следующие ограничения:
- Нельзя задавать параметры входных данных — только имя и значение.
- Поскольку командная строка находится вне области действия любого отдельного профиля, а входные данные не принимают параметры, входные данные неудобно копируются в каждый профиль, эффективно делая механизм командной строки глобальным.
Установка значений входных данных с помощью плагинов
Входные данные также могут быть установлены пользовательскими плагинами входных данных, которые извлекают значения из внешних источников, таких как хранилища секретов или базы данных. Пожалуйста, проверьте RubyGems.org для доступных плагинов входных данных InSpec.
Отключение кэширования для входных данных
Особенно с плагинами может быть желательно повторно оценивать входные данные каждый раз, а не кэшировать их. По умолчанию используемое значение входного параметра повторно используется, что может привести к проблемам, если ожидается изменение извлекаемых значений. Примером этого является использование kitchen-inspec с плагинами входных данных для подключения к серверу Vault для извлечения паролей.
Чтобы отключить кэширование входных данных, вы можете отключить кэш из кода Ruby:
Inspec::InputRegistry.instance.cache_inputs = false
Справочник по параметрам входных данных
Имя
Обязательный String. Этот параметр идентифицирует входной параметр.
Допустимо во всех случаях. При использовании в DSL и метаданных имя уникально в текущем профиле. При использовании в файлах входных данных командной строки, книге рецептов аудита и kitchen-inspec входной параметр копируется во все профили с тем же именем.
Описание
Дополнительное String. Человекопонятное описание ввода.
Допустимо в: DSL, Метаданные
Значение
Необязательное, любой тип Ruby или YAML. Это значение, которое будет доступно при чтении ввода. Подробнее см. раздел Чтение ввода.
Допустимо во всех случаях
Тип
Необязательное, String. Это значение должно быть одним из String, Numeric, Regexp, Array, Hash, Boolean, или Any. Если указано, значение ввода будет проверено на соответствие указанному типу. Обратите внимание, что Regexp означает, что значение ввода должно быть регулярным выражением, а не что оно должно соответствовать какому-либо конкретному регулярному выражению.
Допустимо в: DSL, Метаданные
Обязательный
Необязательное, true или false. Если true, управление с использованием ввода будет неудачным, если оно прочитает значение, когда оно не задано.
Допустимо в: DSL, Метаданные
Приоритет
Необязательное, Integer, 0-100. Более высокие значения присваивают этому заданию более высокий приоритет. Это расширенная функция.
Допустимо в: DSL, Метаданные
Профиль
Необязательное, String. Позволяет установить входные данные в другом профиле, отличном от текущего.
Допустимо в: DSL, Метаданные
Конфиденциальный
Необязательное, true или false. Если true, значение ввода будет использоваться обычно во время выполнения exec, но значение будет скрыто как «***» в разделе «вводы» или «атрибуты» любого Отчета, который явно перечисляет вводы (отчёт json является одним из таких отчётов). Обратите внимание, что это не будет скрывать значения ввода, используемые в качестве результатов тестирования.
Допустимо в: Метаданные
Расширенные темы
Отладка ввода с помощью журнала событий
Если сложно определить, почему используется определенное значение, можно использовать журнал событий, чтобы понять, что происходит.
Во-первых, используйте метод DSL input_object(). Этот метод похож на input(), так как он ищет входные данные, но вместо оценки текущего значения возвращает базовый объект Inspec::Input.
puts input_object('troublesome_input').diagnostic_string
# Or
require 'pp'
pp input_object('troublesome_input').events
diagnostic_string собирает журнал событий в удобочитаемое сообщение для удобства.
Журнал событий содержит записи о каждом изменении значения, а также запись о первом создании ввода. По возможности используется поиск стека для определения номеров файла и строки. Самое важное — вы увидите номера приоритетов; помните, что приоритет выше всего; порядок важен только для разрыва ничьей.
© 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/inspec/inputs/