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
# 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
  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)


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

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



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

def exit_status
  result.exit_status.to_i
end

#resultObject



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

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



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

def stderr
  result.stderr
end

#stdoutObject



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

def stdout
  result.stdout
end

#to_sObject



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

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