Ruby Inspec中如何用describe.one将两个describe合并为一个选项
解决Inspec中rsync检查的逻辑问题
你的需求是验证rsync要么未安装,要么已安装但同时处于非活跃(inactive)且已禁用(disabled)状态,但当前代码会把三个检查项当成独立选项,导致只要其中一个满足就通过,不符合预期。以下是两种正确的实现方式:
方式一:合并服务状态检查到单个it块
将两个systemctl命令的验证逻辑放到同一个describe块的it语句中,确保只有两个条件同时满足时,该选项才生效:
control "my control" do title "rsync 应未安装或已禁用" desc "验证 rsync 要么未安装,要么处于非活跃且已禁用状态" describe.one do # 选项1:rsync 未安装 describe package('rsync') do it { should_not be_installed } end # 选项2:rsync 已安装但同时满足非活跃和已禁用 describe "rsync 服务状态组合检查" do it "应处于非活跃且已禁用状态" do active_status = command('systemctl is-active rsync').stdout.strip enabled_status = command('systemctl is-enabled rsync').stdout.strip expect(active_status).to match('^inactive$') expect(enabled_status).to match('^disabled$') end end end end
方式二:使用Inspec的.and()组合检查块
利用Inspec内置的.and()方法,将两个command检查块组合成一个逻辑单元,只有两者都通过时,该选项才会被视为有效:
control "my control" do title "rsync 应未安装或已禁用" desc "验证 rsync 要么未安装,要么处于非活跃且已禁用状态" describe.one do describe package('rsync') do it { should_not be_installed } end # 组合两个服务状态检查,需同时满足 describe command('systemctl is-active rsync') do its('stdout.strip') { should match '^inactive$' } end.and(describe command('systemctl is-enabled rsync') do its('stdout.strip') { should match '^disabled$' } end) end end
注意事项
- 使用
stdout.strip去除命令输出的首尾空白(包括换行符),避免因输出格式问题导致匹配失败。 - 外层的
describe.one会依次检查选项,只要有一个选项满足,整个控制项就会通过。
内容的提问来源于stack exchange,提问作者Mo2
相关产品推荐
相关产品推荐

