Class: Inspec::Resources::Cmd

Inherits:
Object
  • Object
show all
Defined in:
lib/inspec/resources/command.rb

Direct Known Subclasses

Bash, Ksh, Powershell

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cmd, options = {}) ⇒ Cmd

Returns a new instance of Cmd.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/inspec/resources/command.rb', line 28

def initialize(cmd, options = {})
  if cmd.nil?
    raise "InSpec `command` was called with `nil` as the argument. This is not supported. Please provide a valid command instead."
  end

  @command = cmd

  cli_timeout = Inspec::Config.cached["command_timeout"].to_i
  # Can access this via Inspec::InspecCLI.commands["exec"].options[:command_timeout].default,
  # but that may not be loaded for kitchen-inspec and other pure gem consumers
  default_cli_timeout = 3600
  cli_timeout = default_cli_timeout if cli_timeout == 0 # Under test-kitchen we get a 0 timeout, which can't be a resonable value
  if cli_timeout != default_cli_timeout
    @timeout = cli_timeout
  else
    @timeout = options[:timeout]&.to_i || default_cli_timeout
  end

  if options[:redact_regex]
    unless options[:redact_regex].is_a?(Regexp)
      # Make sure command is replaced so sensitive output isn't shown
      @command = "ERROR"
      raise Inspec::Exceptions::ResourceFailed,
            "The `redact_regex` option must be a regular expression"
    end
    @redact_regex = options[:redact_regex]
  end
end

Instance Attribute Details

#commandObject (readonly)

Returns the value of attribute command.



26
27
28
# File 'lib/inspec/resources/command.rb', line 26

def command
  @command
end

Instance Method Details

#exist?Boolean

rubocop:disable Metrics/AbcSize

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/inspec/resources/command.rb', line 81

def exist? # rubocop:disable Metrics/AbcSize
  # silent for mock resources
  return false if inspec.os.name.nil? || inspec.os.name == "mock"

  if inspec.os.linux?
    res = if inspec.platform.name == "alpine"
            inspec.backend.run_command("which \"#{@command}\"")
          else
            inspec.backend.run_command("sh -c 'type \"#{@command}\"'")
          end
  elsif inspec.os.windows?
    res = inspec.backend.run_command("Get-Command \"#{@command}\"")
  elsif inspec.os.unix?
    res = inspec.backend.run_command("type \"#{@command}\"")
  else
    warn "`command(#{@command}).exist?` is not supported on your OS: #{inspec.os[:name]}"
    return false
  end
  res.exit_status.to_i == 0
end

#exit_statusObject



77
78
79
# File 'lib/inspec/resources/command.rb', line 77

def exit_status
  result.exit_status.to_i
end

#resultObject



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/inspec/resources/command.rb', line 57

def result
  @result ||= begin
    inspec.backend.run_command(@command, timeout: @timeout)
              rescue Train::CommandTimeoutReached
                # Without a small sleep, the train connection gets broken
                # We've already timed out, so a small sleep is not likely to be painful here.
                sleep 0.1
                raise Inspec::Exceptions::ResourceFailed,
                      "Command `#{@command}` timed out after #{@timeout} seconds"
  end
end

#stderrObject



73
74
75
# File 'lib/inspec/resources/command.rb', line 73

def stderr
  result.stderr
end

#stdoutObject



69
70
71
# File 'lib/inspec/resources/command.rb', line 69

def stdout
  result.stdout
end

#to_sObject



102
103
104
105
106
107
108
# File 'lib/inspec/resources/command.rb', line 102

def to_s
  output = "Command: `#{@command}`"
  # Redact output if the `redact_regex` option is passed
  # If no capture groups are passed then `\1` and `\2` are ignored
  output.gsub!(@redact_regex, '\1REDACTED\2') unless @redact_regex.nil?
  output
end