Руководство по стилю профилей Chef InSpec
Это набор рекомендуемых правил Chef InSpec, которые следует использовать при написании проверок.
Файлы проверок
Размещайте файлы проверок в controls/ и заканчивайте их .rb
Большинство подсветчиков синтаксиса правильно отобразят файлы Chef InSpec в широком списке инструментов.
Избегайте:
controls/ssh_configcontrols/ssh/config.rb
Используйте:
controls/ssh_config.rbcontrols/ssh_config.rb
Избегайте controls/control в именах файлов проверок
Использование controls в имени файла создает ненужный беспорядок при чтении. Сохраняйте имена короткими и лаконичными.
Избегайте:
controls/ssh_controls.rb
Используйте:
controls/ssh.rb
Стиль кода
Избегайте ненужных скобок в матчерах
Добавление дополнительных скобок не требуется и обеспечивает лучшую читаемость, если их не использовать:
Избегайте:
it { should eq(value) }
Используйте:
it { should eq value }
Исключение составляют матчеры, требующие дополнительных аргументов или именованных аргументов.
Проверки
Избегайте обертывания проверок условными операторами
Это создаст динамические профили, чьи проверки зависят от выполнения. Проблема в том, что мы не можем отобразить профиль или предоставить его информацию до сканирования системы. Мы хотим иметь возможность информировать пользователей о содержимом своих профилей до их запуска. Допустимо пропускать проверки, которые не нужны для системы, но делайте это с помощью only_if условий. Внутренние условные операторы Ruby скрывают части профиля от статического анализа и поэтому следует избегать.
Избегайте:
if package('..').installed?
control "package-test1" do
..
end
end
Используйте:
control "package-test1" do
only_if { package('..').installed? }
end
Избегайте:
case inspec.platform.name
when /centos/
include_controls 'centos-profile'
...
Вместо этого используйте атрибут supports в inspec.yml профиля, который вы хотите включить:
supports:
- platform-name: centos
Теперь, когда вы запускаете базовый профиль, вы можете просто include_controls 'centos-profile'. Он будет запускать только включенные профили, если платформа соответствует поддерживаемой платформе.
Избегайте динамических элементов в идентификаторах проверок
Идентификаторы проверок используются для сопоставления результатов тестов с тестами и профилями. Динамические идентификаторы проверок делают невозможным сопоставление результатов обратно, так как идентификатор, который связывает тесты и результаты, может измениться в процессе.
Избегайте:
control "test-file-#{name}" do
..
end
Используйте:
control "test-all-files" do
..
end
Иногда вы можете создавать проверки из статического списка элементов. Если этот список остается неизменным независимо от того, какая система сканируется, это может быть нормально, и его можно использовать в качестве генератора статических проверок.
Избегайте вызовов Ruby system
Код Ruby выполняется на системе, на которой работает InSpec. Это позволяет Chef InSpec работать без Ruby и RubyGems на удаленных целевых системах (серверах или контейнерах). Вызовы system часто используются для взаимодействия с локальной ОС или удаленными конечными точками из локальной установки.
Однако тесты Chef InSpec предназначены для универсального выполнения на всех типах сред выполнения, включая локальное и удаленное выполнение. Мы хотим предоставить пользователям возможность взять профиль ОС и выполнить его удаленно или локально.
Избегайте вызовов оболочки
Избегайте:
`ls`system("ls")IO.popen("ls")
Используйте:
-
command("ls")илиpowershell("Get-ChildItem")
Исполнители команд Ruby будут выполняться только локально. Представьте тест такого вида:
describe `whoami` do
it { should cmp "bob\n" }
end
Если вы запустите этот тест на своей локальной системе и используете учетную запись Боба, он пройдет успешно. Но если вы запустите его на --target alice@remote-host.com, он все равно будет сообщать, что пользователь bob, а не alice.
Вместо этого сделайте так:
describe command('whoami') do
its('stdout') { should cmp "bob\n" }
end
Если профиль указывает на удаленный конечный пункт, использование ресурса command запустит его на удаленной ОС.
Избегайте использования Ruby IO для файлов
Аналогично взаимодействию с командами, эти файлы будут читаться только локально с помощью внутренних вызовов Ruby. Если вы запустите этот тест на удаленной цели, он не будет читать файл из удаленного конечного пункта, а из локальной ОС. Используйте ресурс file для чтения файлов на целевой системе.
Избегайте:
File.new("filename").readFile.read("filename")IO.read("filename")
Используйте:
file("filename")
В общем, старайтесь избегать вызовов Ruby IO внутри проверок Chef InSpec и используйте ресурсы Chef InSpec вместо этого.
Избегайте зависимостей от gem Ruby в проверках
В дополнение к избеганию системных gem и модулей, вы также должны ограничить использование внешних зависимостей для пакетов ресурсов или плагинов. Gem необходимо разрешить, установить, добавить в вендор и защитить от конфликтов. Мы стремимся избежать этой сложности для пользователей InSpec, чтобы сделать его отличным инструментом, даже если вы не разработчик.
Плагины должны объявлять зависимости gem в своем gemspec и затем полагаться на механизм установки плагинов для установки и управления зависимостями.
Избегайте вызовов отладки (в рабочей среде)
Один из лучших способов разработки и исследования тестов — интерактивная оболочка отладки pry (см. [Интерактивная отладка с Pry] (/inspec/dsl_inspec/#interactive-debugging-with-pry) в конце этой страницы). Однако после завершения профиля убедитесь, что вы больше не включаете интерактивные инструкции. Иногда интерактивные вызовы скрываются за условными операторами (if операторы), которые сложнее обнаружить. Эти вызовы могут легко вызвать проблемы, когда автоматизированный профиль сталкивается с интерактивным pry вызовом, который останавливает выполнение и ожидает ввода пользователя.
Избегайте:
binding.pryв производственных профилях
Используйте:
- Используйте вызовы отладки только во время разработки
Кроме того, вам может быть полезен интерфейс ведения журнала Chef InSpec:
Inspec::Log.info('Hi')
9. Предпочитайте cmp вместо eq
Матчер cmp обрабатывает преобразования типов, регистронезависимые сравнения, преобразование строк в версии (например, «7.35.0-1ubuntu2.10») и многие другие сложные вещи. Если вам не нужно точное совпадение (в таком случае используйте матчер eq), то следует использовать матчер cmp.
Например, это:
describe passwd.uids(0) do
its('users') { should cmp 'root' }
end
предпочтительнее, чем:
describe passwd.uids(0) do
its('users') { should eq ['root'] }
end
См. cmp документацию по матчеру для получения дополнительных примеров.
© 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/style/