remodel bash and shell wrappers

This commit is contained in:
Dominik Richter 2016-04-18 08:47:27 -04:00
parent 703e77563b
commit 9da23f9cbc
6 changed files with 102 additions and 65 deletions

View file

@ -54,6 +54,7 @@ require 'resources/apt'
require 'resources/audit_policy'
require 'resources/auditd_conf'
require 'resources/auditd_rules'
require 'resources/bash'
require 'resources/bond'
require 'resources/bridge'
require 'resources/command'

36
lib/resources/bash.rb Normal file
View file

@ -0,0 +1,36 @@
# encoding: utf-8
# author: Dominik Richter
# author: Christoph Hartmann
require 'utils/command_wrapper'
require 'resources/command'
module Inspec::Resources
class Bash < Cmd
name 'bash'
desc 'Run a command or script in BASH.'
example "
describe bash('ls -al /') do
its('stdout') { should match /bin/ }
its('stderr') { should eq '' }
its('exit_status') { should eq 0 }
end
# Specify the path of the executable:
bash('...', path: '/bin/bash')
# Specify arguments (defaults to -c)
bash('...', args: '-x -c')
"
def initialize(command, options = {})
@raw_command = command
options[:shell] = 'bash' if options.is_a?(Hash)
super(CommandWrapper.wrap(command, options))
end
def to_s
"Bash command #{@raw_command}"
end
end
end

View file

@ -4,8 +4,6 @@
# author: Christoph Hartmann
# license: All rights reserved
require 'shellwords'
module Inspec::Resources
class Cmd < Inspec.resource(1)
name 'command'
@ -13,31 +11,20 @@ module Inspec::Resources
example "
describe command('ls -al /') do
it { should exist }
its(:stdout) { should match /bin/ }
its('stdout') { should match /bin/ }
its('stderr') { should eq '' }
its(:exit_status) { should eq 0 }
its('exit_status') { should eq 0 }
end
"
SHELLS = {
'sh' => ->(x, path = 'sh') { path + ' -c ' + Shellwords.escape(x) },
'bash' => ->(x, path = 'bash') { path + ' -c ' + Shellwords.escape(x) },
'zsh' => ->(x, path = 'zsh') { path + ' -c ' + Shellwords.escape(x) },
}.freeze
attr_reader :command
def initialize(cmd, opts = {})
def initialize(cmd)
@command = cmd
unless opts.is_a?(Hash)
skip_resource "Called #{self} with invalid command options. See the resource help for valid examples."
opts = {}
end
@opts = opts
end
def result
@result ||= inspec.backend.run_command(wrap_cmd)
@result ||= inspec.backend.run_command(@command)
end
def stdout
@ -72,18 +59,5 @@ module Inspec::Resources
def to_s
"Command #{@command}"
end
private
def wrap_cmd
shell = @opts[:shell]
return @command if shell.nil?
wrapper = SHELLS[shell]
# TODO: fail with an error if the command isn't found
return @command if wrapper.nil?
wrapper.call(@command)
end
end
end

View file

@ -0,0 +1,32 @@
# encoding: utf-8
# author: Dominik Richter
# author: Christoph Hartmann
require 'shellwords'
class CommandWrapper
UNIX_SHELLS = %w{sh bash zsh}.freeze
def self.wrap(cmd, options)
unless options.is_a?(Hash)
fail 'All options for the command wrapper must be provided as a hash. '\
"You entered: #{options.inspect}. Please consult the documentation."
end
wrap = options[:wrap]
if !wrap.nil? && !wrap.is_a?(Proc)
fail "Called command wrapper with wrap: #{wrap.inspect}. It must be called with a Proc."
elsif !wrap.nil?
return wrap.call(cmd)
end
shell = options[:shell]
unless UNIX_SHELLS.include?(shell)
fail "Don't know how to wrap commands for shell: #{shell.inspect}."
end
path = options[:path] || shell
args = options[:args] || '-c'
path.to_s + ' ' + args + ' ' + Shellwords.escape(cmd)
end
end

View file

@ -0,0 +1,29 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'helper'
require 'inspec/resource'
describe Inspec::Resources::Bash do
let(:x) { rand.to_s }
let(:resource) { load_resource('bash', '$("'+x+'")') }
it 'prints as a bash command' do
resource.to_s.must_equal 'Bash command $("'+x+'")'
end
it 'wraps the command' do
resource.command.must_equal "bash -c \\$\\(\\\"#{x}\\\"\\)"
end
it 'can specify an executable path' do
resource = load_resource('bash', '$("'+x+'")', path: '/bin/bash')
resource.command.must_equal "/bin/bash -c \\$\\(\\\"#{x}\\\"\\)"
end
it 'can specify a arguments' do
resource = load_resource('bash', '$("'+x+'")', args: '-x -c')
resource.command.must_equal "bash -x -c \\$\\(\\\"#{x}\\\"\\)"
end
end

View file

@ -1,35 +0,0 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter
require 'helper'
require 'inspec/resource'
describe Inspec::Resources::Cmd do
it 'runs regular commands' do
x = rand.to_s
load_resource('command', x).method(:wrap_cmd).call
.must_equal x
end
it 'runs sh commands' do
x = rand.to_s
load_resource('command', '$("'+x+'")', {shell: 'sh'})
.method(:wrap_cmd).call
.must_equal "sh -c \\$\\(\\\"#{x}\\\"\\)"
end
it 'runs bash commands' do
x = rand.to_s
load_resource('command', '$("'+x+'")', {shell: 'bash'})
.method(:wrap_cmd).call
.must_equal "bash -c \\$\\(\\\"#{x}\\\"\\)"
end
it 'runs zsh commands' do
x = rand.to_s
load_resource('command', '$("'+x+'")', {shell: 'zsh'})
.method(:wrap_cmd).call
.must_equal "zsh -c \\$\\(\\\"#{x}\\\"\\)"
end
end