inspec-core 4.31.1 → 4.37.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +14 -1
- data/inspec-core.gemspec +2 -2
- data/lib/inspec/base_cli.rb +5 -3
- data/lib/inspec/cli.rb +12 -4
- data/lib/inspec/control_eval_context.rb +1 -0
- data/lib/inspec/fetcher/local.rb +1 -1
- data/lib/inspec/input.rb +39 -4
- data/lib/inspec/input_registry.rb +1 -0
- data/lib/inspec/objects/input.rb +1 -1
- data/lib/inspec/plugin/v2/loader.rb +9 -0
- data/lib/inspec/profile_context.rb +1 -1
- data/lib/inspec/reporters/cli.rb +63 -0
- data/lib/inspec/resources.rb +1 -0
- data/lib/inspec/resources/command.rb +3 -9
- data/lib/inspec/resources/groups.rb +21 -6
- data/lib/inspec/resources/http.rb +1 -1
- data/lib/inspec/resources/mssql_session.rb +1 -1
- data/lib/inspec/resources/mysql_session.rb +1 -1
- data/lib/inspec/resources/pip.rb +1 -1
- data/lib/inspec/resources/registry_key.rb +1 -1
- data/lib/inspec/resources/selinux.rb +154 -0
- data/lib/inspec/resources/users.rb +1 -1
- data/lib/inspec/resources/windows_feature.rb +2 -1
- data/lib/inspec/resources/windows_firewall_rule.rb +1 -1
- data/lib/inspec/rule.rb +9 -1
- data/lib/inspec/runner.rb +1 -1
- data/lib/inspec/utils/erlang_parser.rb +2 -2
- data/lib/inspec/utils/filter.rb +7 -7
- data/lib/inspec/utils/nginx_parser.rb +3 -3
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-compliance/README.md +125 -2
- data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +5 -0
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +18 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +23 -8
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +24 -25
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +5 -4
- metadata +11 -4
| @@ -58,7 +58,7 @@ module Inspec::Resources | |
| 58 58 | 
             
                end
         | 
| 59 59 |  | 
| 60 60 | 
             
                def query(q) # rubocop:disable Metrics/PerceivedComplexity
         | 
| 61 | 
            -
                  escaped_query = q.gsub(/\\/,  | 
| 61 | 
            +
                  escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '""').gsub(/\$/, '\\$')
         | 
| 62 62 | 
             
                  # surpress 'x rows affected' in SQLCMD with 'set nocount on;'
         | 
| 63 63 | 
             
                  cmd_string = "sqlcmd -Q \"set nocount on; #{escaped_query}\" -W -w 1024 -s ','"
         | 
| 64 64 | 
             
                  cmd_string += " -U '#{@user}' -P '#{@password}'" unless @user.nil? || @password.nil?
         | 
| @@ -75,7 +75,7 @@ module Inspec::Resources | |
| 75 75 | 
             
                def create_mysql_cmd(q, db = "")
         | 
| 76 76 | 
             
                  # TODO: simple escape, must be handled by a library
         | 
| 77 77 | 
             
                  # that does this securely
         | 
| 78 | 
            -
                  escaped_query = q.gsub(/\\/,  | 
| 78 | 
            +
                  escaped_query = q.gsub(/\\/, "\\\\").gsub(/"/, '\\"').gsub(/\$/, '\\$')
         | 
| 79 79 |  | 
| 80 80 | 
             
                  # construct the query
         | 
| 81 81 | 
             
                  command = "mysql"
         | 
    
        data/lib/inspec/resources/pip.rb
    CHANGED
    
    | @@ -117,7 +117,7 @@ module Inspec::Resources | |
| 117 117 | 
             
                    if defined?(windows_paths["Python"]) && pipcmd.nil?
         | 
| 118 118 | 
             
                      return nil if windows_paths["Pip"].nil?
         | 
| 119 119 |  | 
| 120 | 
            -
                      pipdir = windows_paths["Python"].split( | 
| 120 | 
            +
                      pipdir = windows_paths["Python"].split("\\")
         | 
| 121 121 | 
             
                      # remove python.exe
         | 
| 122 122 | 
             
                      pipdir.pop
         | 
| 123 123 | 
             
                      pipcmd = pipdir.push("Scripts").push("pip.exe").join("/")
         | 
| @@ -0,0 +1,154 @@ | |
| 1 | 
            +
            require "inspec/resources/command"
         | 
| 2 | 
            +
            require "inspec/utils/filter"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Inspec::Resources
         | 
| 5 | 
            +
              class SelinuxModuleFilter
         | 
| 6 | 
            +
                # use filtertable for SELinux Modules
         | 
| 7 | 
            +
                filter = FilterTable.create
         | 
| 8 | 
            +
                filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
         | 
| 9 | 
            +
                filter.register_column(:names, field: :name)
         | 
| 10 | 
            +
                filter.register_column(:status, field: :status)
         | 
| 11 | 
            +
                filter.register_column(:states, field: :state)
         | 
| 12 | 
            +
                filter.register_column(:priorities , field: :priority)
         | 
| 13 | 
            +
                filter.register_custom_matcher(:enabled?) { |x| x.states[0] == "enabled" }
         | 
| 14 | 
            +
                filter.register_custom_matcher(:installed?) { |x| x.status[0] == "installed" }
         | 
| 15 | 
            +
                filter.install_filter_methods_on_resource(self, :modules)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                attr_reader :modules
         | 
| 18 | 
            +
                def initialize(modules)
         | 
| 19 | 
            +
                  @modules = modules
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def to_s
         | 
| 23 | 
            +
                  "SELinux modules"
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              class SelinuxBooleanFilter
         | 
| 28 | 
            +
                # use filtertable for SELinux Booleans
         | 
| 29 | 
            +
                filter = FilterTable.create
         | 
| 30 | 
            +
                filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
         | 
| 31 | 
            +
                filter.register_column(:names, field: :name)
         | 
| 32 | 
            +
                filter.register_column(:states, field: :state)
         | 
| 33 | 
            +
                filter.register_column(:defaults, field: :default)
         | 
| 34 | 
            +
                filter.register_custom_matcher(:on?) { |x| x.states[0] == "on" }
         | 
| 35 | 
            +
                filter.install_filter_methods_on_resource(self, :booleans)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                attr_reader :booleans
         | 
| 38 | 
            +
                def initialize(booleans)
         | 
| 39 | 
            +
                  @booleans = booleans
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def to_s
         | 
| 43 | 
            +
                  "SELinux booleans"
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              class Selinux < Inspec.resource(1)
         | 
| 48 | 
            +
                name "selinux"
         | 
| 49 | 
            +
                supports platform: "linux"
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                desc "Use the selinux Chef InSpec resource to test the configuration data of the SELinux policy, SELinux modules, and SELinux booleans."
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                example <<~EXAMPLE
         | 
| 54 | 
            +
                  describe selinux do
         | 
| 55 | 
            +
                    it { should be_installed }
         | 
| 56 | 
            +
                    it { should be_disabled }
         | 
| 57 | 
            +
                    it { should be_permissive }
         | 
| 58 | 
            +
                    it { should be_enforcing }
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  describe selinux do
         | 
| 62 | 
            +
                    its('policy') { should eq "targeted"}
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  describe selinux.modules.where("zebra") do
         | 
| 66 | 
            +
                    it { should exist }
         | 
| 67 | 
            +
                    it { should be_installed }
         | 
| 68 | 
            +
                    it { should be_enabled }
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  describe selinux.modules.where(status: "installed") do
         | 
| 72 | 
            +
                    it { should exist }
         | 
| 73 | 
            +
                    its('count') { should cmp 404 }
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  describe selinux.booleans.where(name: "xend_run_blktap") do
         | 
| 77 | 
            +
                    it { should be_on }
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  describe selinux.booleans.where { name == "xend_run_blktap" && state == "on" } do
         | 
| 81 | 
            +
                   it { should exist }
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                EXAMPLE
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def initialize(selinux_path = "/etc/selinux/config")
         | 
| 86 | 
            +
                  @path = selinux_path
         | 
| 87 | 
            +
                  cmd = inspec.command("sestatus")
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  if cmd.exit_status != 0
         | 
| 90 | 
            +
                    # `sestatus` command not found error message comes in stdout so handling both here
         | 
| 91 | 
            +
                    out = cmd.stdout + "\n" + cmd.stderr
         | 
| 92 | 
            +
                    return skip_resource "Skipping resource: #{out}"
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  result = cmd.stdout.delete(" ").gsub(/\n/, ",").gsub(/\r/, "").downcase
         | 
| 96 | 
            +
                  @data = Hash[result.scan(/([^:]+):([^,]+)[,$]/)]
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                def installed?
         | 
| 100 | 
            +
                  inspec.file(@path).exist?
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                def disabled?
         | 
| 104 | 
            +
                  @data["selinuxstatus"] == "disabled"
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                def enforcing?
         | 
| 108 | 
            +
                  @data["currentmode"] == "enforcing"
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                def permissive?
         | 
| 112 | 
            +
                  @data["currentmode"] == "permissive"
         | 
| 113 | 
            +
                end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                def policy
         | 
| 116 | 
            +
                  @data["loadedpolicyname"]
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                def modules
         | 
| 120 | 
            +
                  SelinuxModuleFilter.new(parse_modules)
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                def booleans
         | 
| 124 | 
            +
                  SelinuxBooleanFilter.new(parse_booleans)
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                def to_s
         | 
| 128 | 
            +
                  "SELinux"
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                private
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                def parse_modules
         | 
| 134 | 
            +
                  raw_modules = inspec.command("semodule -lfull").stdout
         | 
| 135 | 
            +
                  r_modules = []
         | 
| 136 | 
            +
                  raw_modules.each_line do |entry|
         | 
| 137 | 
            +
                    data = entry.split.map(&:strip)
         | 
| 138 | 
            +
                    state = data.length == 4 ? data[3] : "enabled"
         | 
| 139 | 
            +
                    r_modules.push({ name: data[1], status: "installed", state: state, priority: data[0] })
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
                  r_modules
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                def parse_booleans
         | 
| 145 | 
            +
                  raw_booleans = inspec.command("semanage boolean -l -n").stdout
         | 
| 146 | 
            +
                  r_booleans = []
         | 
| 147 | 
            +
                  raw_booleans.each_line do |entry|
         | 
| 148 | 
            +
                    data = entry.scan(/([^(,)]+)/).flatten.map(&:strip)
         | 
| 149 | 
            +
                    r_booleans.push({ name: data[0], state: data[1], default: data[2] })
         | 
| 150 | 
            +
                  end
         | 
| 151 | 
            +
                  r_booleans
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
              end
         | 
| 154 | 
            +
            end
         | 
| @@ -611,7 +611,7 @@ module Inspec::Resources | |
| 611 611 | 
             
              # @see https://msdn.microsoft.com/en-us/library/aa394153(v=vs.85).aspx
         | 
| 612 612 | 
             
              class WindowsUser < UserInfo
         | 
| 613 613 | 
             
                def parse_windows_account(username)
         | 
| 614 | 
            -
                  account = username.split( | 
| 614 | 
            +
                  account = username.split("\\")
         | 
| 615 615 | 
             
                  name = account.pop
         | 
| 616 616 | 
             
                  domain = account.pop unless account.empty?
         | 
| 617 617 | 
             
                  [name, domain]
         | 
| @@ -79,10 +79,11 @@ module Inspec::Resources | |
| 79 79 | 
             
                    result = cmd.stdout
         | 
| 80 80 | 
             
                    feature_name_regex = /Feature Name : (.*)(\r\n|\n)/
         | 
| 81 81 | 
             
                    description_regex = /Description : (.*)(\r\n|\n)/
         | 
| 82 | 
            +
                    state_regex = /State : (.*)(\r\n|\n)/
         | 
| 82 83 | 
             
                    feature_info = {
         | 
| 83 84 | 
             
                      name: result.match(feature_name_regex).captures[0].chomp,
         | 
| 84 85 | 
             
                      description: result.match(description_regex).captures[0].chomp,
         | 
| 85 | 
            -
                      installed:  | 
| 86 | 
            +
                      installed: result.match(state_regex).captures[0].chomp == 'Enabled',
         | 
| 86 87 | 
             
                    }
         | 
| 87 88 | 
             
                  end
         | 
| 88 89 |  | 
| @@ -105,7 +105,7 @@ module Inspec::Resources | |
| 105 105 | 
             
                # @see https://github.com/chef/chef/blob/master/lib/chef/resource/windows_firewall_rule.rb
         | 
| 106 106 | 
             
                def load_firewall_state(rule_name)
         | 
| 107 107 | 
             
                  <<-EOH
         | 
| 108 | 
            -
                     | 
| 108 | 
            +
                    Get-TypeData -TypeName System.Array | Remove-TypeData # workaround for PS bug here: https://bit.ly/2SRMQ8M
         | 
| 109 109 | 
             
                    $rule = Get-NetFirewallRule -Name "#{rule_name}"
         | 
| 110 110 | 
             
                    $addressFilter = $rule | Get-NetFirewallAddressFilter
         | 
| 111 111 | 
             
                    $portFilter = $rule | Get-NetFirewallPortFilter
         | 
    
        data/lib/inspec/rule.rb
    CHANGED
    
    | @@ -180,7 +180,15 @@ module Inspec | |
| 180 180 | 
             
                    options[:priority] ||= 20
         | 
| 181 181 | 
             
                    options[:provider] = :inline_control_code
         | 
| 182 182 | 
             
                    evt = Inspec::Input.infer_event(options)
         | 
| 183 | 
            -
                    Inspec::InputRegistry.find_or_register_input( | 
| 183 | 
            +
                    Inspec::InputRegistry.find_or_register_input(
         | 
| 184 | 
            +
                      input_name,
         | 
| 185 | 
            +
                      __profile_id,
         | 
| 186 | 
            +
                      type: options[:type],
         | 
| 187 | 
            +
                      required: options[:required],
         | 
| 188 | 
            +
                      description: options[:description],
         | 
| 189 | 
            +
                      pattern: options[:pattern],
         | 
| 190 | 
            +
                      event: evt
         | 
| 191 | 
            +
                    ).value
         | 
| 184 192 | 
             
                  end
         | 
| 185 193 | 
             
                end
         | 
| 186 194 |  | 
    
        data/lib/inspec/runner.rb
    CHANGED
    
    | @@ -243,7 +243,7 @@ module Inspec | |
| 243 243 | 
             
                  # to provide access to local profiles that add resources.
         | 
| 244 244 | 
             
                  @depends.each do |dep|
         | 
| 245 245 | 
             
                    # support for windows paths
         | 
| 246 | 
            -
                    dep = dep.tr( | 
| 246 | 
            +
                    dep = dep.tr("\\", "/")
         | 
| 247 247 | 
             
                    Inspec::Profile.for_path(dep, { profile_context: ctx }).load_libraries
         | 
| 248 248 | 
             
                  end
         | 
| 249 249 |  | 
| @@ -52,13 +52,13 @@ class ErlangParser < Parslet::Parser | |
| 52 52 |  | 
| 53 53 | 
             
              rule(:stringS) do
         | 
| 54 54 | 
             
                str("'") >> (
         | 
| 55 | 
            -
                  str( | 
| 55 | 
            +
                  str("\\") >> any | str("'").absent? >> any
         | 
| 56 56 | 
             
                ).repeat.as(:string) >> str("'") >> filler?
         | 
| 57 57 | 
             
              end
         | 
| 58 58 |  | 
| 59 59 | 
             
              rule(:stringD) do
         | 
| 60 60 | 
             
                str('"') >> (
         | 
| 61 | 
            -
                  str( | 
| 61 | 
            +
                  str("\\") >> any | str('"').absent? >> any
         | 
| 62 62 | 
             
                ).repeat.as(:string) >> str('"') >> filler?
         | 
| 63 63 | 
             
              end
         | 
| 64 64 |  | 
    
        data/lib/inspec/utils/filter.rb
    CHANGED
    
    | @@ -375,13 +375,13 @@ module FilterTable | |
| 375 375 | 
             
                  methods_to_install_on_resource_class = @filter_methods + @custom_properties.keys
         | 
| 376 376 | 
             
                  methods_to_install_on_resource_class.each do |method_name|
         | 
| 377 377 | 
             
                    resource_class.send(:define_method, method_name) do |*args, &block|
         | 
| 378 | 
            -
             | 
| 379 | 
            -
             | 
| 380 | 
            -
             | 
| 381 | 
            -
             | 
| 382 | 
            -
             | 
| 383 | 
            -
             | 
| 384 | 
            -
             | 
| 378 | 
            +
             | 
| 379 | 
            +
                      # self here is the resource instance
         | 
| 380 | 
            +
                      filter_table_instance = table_class.new(self, send(raw_data_fetcher_method_name), " with")
         | 
| 381 | 
            +
                      filter_table_instance.send(method_name, *args, &block)
         | 
| 382 | 
            +
                    rescue Inspec::Exceptions::ResourceFailed, Inspec::Exceptions::ResourceSkipped => e
         | 
| 383 | 
            +
                      FilterTable::ExceptionCatcher.new(resource_class, e)
         | 
| 384 | 
            +
             | 
| 385 385 | 
             
                    end
         | 
| 386 386 | 
             
                  end
         | 
| 387 387 | 
             
                end
         | 
| @@ -31,19 +31,19 @@ class NginxParser < Parslet::Parser | |
| 31 31 |  | 
| 32 32 | 
             
              rule(:standard_value) do
         | 
| 33 33 | 
             
                ((match(/[#;{'"]/).absent? >> any) >> (
         | 
| 34 | 
            -
                  str( | 
| 34 | 
            +
                  str("\\") >> any | match('[#;{]|\s').absent? >> any
         | 
| 35 35 | 
             
                ).repeat).as(:value) >> space.repeat
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 38 | 
             
              rule(:single_quoted_value) do
         | 
| 39 39 | 
             
                str("'") >> (
         | 
| 40 | 
            -
                  str( | 
| 40 | 
            +
                  str("\\") >> any | str("'").absent? >> any
         | 
| 41 41 | 
             
                ).repeat.as(:value) >> str("'") >> space.repeat
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 44 | 
             
              rule(:double_quoted_value) do
         | 
| 45 45 | 
             
                str('"') >> (
         | 
| 46 | 
            -
                  str( | 
| 46 | 
            +
                  str("\\") >> any | str('"').absent? >> any
         | 
| 47 47 | 
             
                ).repeat.as(:value) >> str('"') >> space.repeat
         | 
| 48 48 | 
             
              end
         | 
| 49 49 |  | 
    
        data/lib/inspec/version.rb
    CHANGED
    
    
| @@ -6,24 +6,50 @@ This extensions offers the following features: | |
| 6 6 | 
             
             - execute profiles directly from Chef Automate/Chef Compliance locally
         | 
| 7 7 | 
             
             - upload a local profile to Chef Automate/Chef Compliance
         | 
| 8 8 |  | 
| 9 | 
            +
            `inspec compliance` is a backwards compatible alias for `inspec automate` and works the same way.
         | 
| 10 | 
            +
             | 
| 9 11 | 
             
            To use the CLI, this InSpec add-on adds the following commands:
         | 
| 10 12 |  | 
| 13 | 
            +
             * `$ inspec automate login` - authentication of the API token against Chef Automate/Chef Compliance
         | 
| 14 | 
            +
             * `$ inspec automate profiles` - list all available Compliance profiles
         | 
| 15 | 
            +
             * `$ inspec exec compliance://profile` - runs a Compliance profile
         | 
| 16 | 
            +
             * `$ inspec automate upload path/to/local/profile` - uploads a local profile to Chef Automate/Chef Compliance
         | 
| 17 | 
            +
             * `$ inspec automate logout` - logout of Chef Automate/Chef Compliance
         | 
| 18 | 
            +
             
         | 
| 19 | 
            +
             Similar to these CLI commands are:
         | 
| 20 | 
            +
             | 
| 11 21 | 
             
             * `$ inspec compliance login` - authentication of the API token against Chef Automate/Chef Compliance
         | 
| 12 22 | 
             
             * `$ inspec compliance profiles` - list all available Compliance profiles
         | 
| 13 | 
            -
             * `$ inspec exec compliance://profile` - runs a Compliance profile
         | 
| 14 23 | 
             
             * `$ inspec compliance upload path/to/local/profile` - uploads a local profile to Chef Automate/Chef Compliance
         | 
| 15 24 | 
             
             * `$ inspec compliance logout` - logout of Chef Automate/Chef Compliance
         | 
| 16 25 |  | 
| 17 26 | 
             
            Compliance profiles can be executed in two ways:
         | 
| 18 27 |  | 
| 19 | 
            -
            - via compliance exec: `inspec compliance exec profile`
         | 
| 28 | 
            +
            - via compliance exec: `inspec automate exec profile` or `inspec compliance exec profile`
         | 
| 20 29 | 
             
            - via compliance scheme: `inspec exec compliance://profile`
         | 
| 21 30 |  | 
| 22 31 |  | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 23 34 | 
             
            ## Usage
         | 
| 24 35 |  | 
| 25 36 | 
             
            ### Command options
         | 
| 26 37 |  | 
| 38 | 
            +
            ```
         | 
| 39 | 
            +
            $ inspec automate
         | 
| 40 | 
            +
            Commands:
         | 
| 41 | 
            +
              inspec automate download PROFILE  # downloads a profile from Chef Compliance
         | 
| 42 | 
            +
              inspec automate exec PROFILE      # executes a Chef Compliance profile
         | 
| 43 | 
            +
              inspec automate help [COMMAND]    # Describe subcommands or one specific subcommand
         | 
| 44 | 
            +
              inspec automate login SERVER      # Log in to a Chef Automate/Chef Compliance SERVER
         | 
| 45 | 
            +
              inspec automate logout            # user logout from Chef Compliance
         | 
| 46 | 
            +
              inspec automate profiles          # list all available profiles in Chef Compliance
         | 
| 47 | 
            +
              inspec automate upload PATH       # uploads a local profile to Chef Compliance
         | 
| 48 | 
            +
              inspec automate version           # displays the version of the Chef Compliance server
         | 
| 49 | 
            +
            ```
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            or
         | 
| 52 | 
            +
             | 
| 27 53 | 
             
            ```
         | 
| 28 54 | 
             
            $ inspec compliance
         | 
| 29 55 | 
             
            Commands:
         | 
| @@ -41,6 +67,12 @@ Commands: | |
| 41 67 |  | 
| 42 68 | 
             
            You will need an API token for authentication. You can retrieve one via the admin section of your A2 web gui.
         | 
| 43 69 |  | 
| 70 | 
            +
            ```
         | 
| 71 | 
            +
            $ inspec automate login https://automate2.compliance.test --insecure --user 'admin' --token 'zuop..._KzE'
         | 
| 72 | 
            +
            ```
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            or
         | 
| 75 | 
            +
             | 
| 44 76 | 
             
            ```
         | 
| 45 77 | 
             
            $ inspec compliance login https://automate2.compliance.test --insecure --user 'admin' --token 'zuop..._KzE'
         | 
| 46 78 | 
             
            ```
         | 
| @@ -63,6 +95,12 @@ Example: | |
| 63 95 |  | 
| 64 96 | 
             
            You will need an access token for authentication. You can retrieve one via [UI](https://docs.chef.io/api_delivery.html) or [CLI](https://docs.chef.io/ctl_delivery.html#delivery-token).
         | 
| 65 97 |  | 
| 98 | 
            +
            ```
         | 
| 99 | 
            +
            $ inspec automate login https://automate.compliance.test --insecure --user 'admin' --ent 'brewinc' --token 'zuop..._KzE'
         | 
| 100 | 
            +
            ```
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            or
         | 
| 103 | 
            +
             | 
| 66 104 | 
             
            ```
         | 
| 67 105 | 
             
            $ inspec compliance login https://automate.compliance.test --insecure --user 'admin' --ent 'brewinc' --token 'zuop..._KzE'
         | 
| 68 106 | 
             
            ```
         | 
| @@ -75,12 +113,42 @@ You will need an access token for authentication. You can retrieve one via: | |
| 75 113 |  | 
| 76 114 | 
             
            You can choose the access token (`--token`) or the refresh token (`--refresh_token`)
         | 
| 77 115 |  | 
| 116 | 
            +
            ```
         | 
| 117 | 
            +
            $ inspec automate login https://compliance.test --user admin --insecure --token '...'
         | 
| 118 | 
            +
            ```
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            or
         | 
| 121 | 
            +
             | 
| 78 122 | 
             
            ```
         | 
| 79 123 | 
             
            $ inspec compliance login https://compliance.test --user admin --insecure --token '...'
         | 
| 80 124 | 
             
            ```
         | 
| 81 125 |  | 
| 82 126 | 
             
            ### List available profiles via Chef Compliance / Automate
         | 
| 83 127 |  | 
| 128 | 
            +
            ```
         | 
| 129 | 
            +
             $ inspec automate profiles
         | 
| 130 | 
            +
            Available profiles:
         | 
| 131 | 
            +
            -------------------
         | 
| 132 | 
            +
             * base/apache
         | 
| 133 | 
            +
             * base/linux
         | 
| 134 | 
            +
             * base/mysql
         | 
| 135 | 
            +
             * base/postgres
         | 
| 136 | 
            +
             * base/ssh
         | 
| 137 | 
            +
             * base/windows
         | 
| 138 | 
            +
             * cis/cis-centos6-level1
         | 
| 139 | 
            +
             * cis/cis-centos6-level2
         | 
| 140 | 
            +
             * cis/cis-centos7-level1
         | 
| 141 | 
            +
             * cis/cis-centos7-level2
         | 
| 142 | 
            +
             * cis/cis-rhel7-level1
         | 
| 143 | 
            +
             * cis/cis-rhel7-level2
         | 
| 144 | 
            +
             * cis/cis-ubuntu12.04lts-level1
         | 
| 145 | 
            +
             * cis/cis-ubuntu12.04lts-level2
         | 
| 146 | 
            +
             * cis/cis-ubuntu14.04lts-level1
         | 
| 147 | 
            +
             * cis/cis-ubuntu14.04lts-level2
         | 
| 148 | 
            +
            ```
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            or
         | 
| 151 | 
            +
             | 
| 84 152 | 
             
            ```
         | 
| 85 153 | 
             
            $ inspec compliance profiles
         | 
| 86 154 | 
             
            Available profiles:
         | 
| @@ -105,6 +173,47 @@ Available profiles: | |
| 105 173 |  | 
| 106 174 | 
             
            ### Upload a profile to Chef Compliance / Automate
         | 
| 107 175 |  | 
| 176 | 
            +
            ```
         | 
| 177 | 
            +
            $ inspec automate version
         | 
| 178 | 
            +
            Chef Compliance version: 1.0.11
         | 
| 179 | 
            +
            ➜  inspec git:(chris-rock/cc-error-not-loggedin) ✗ b inspec automate upload examples/profile
         | 
| 180 | 
            +
            I, [2016-05-06T14:27:20.907547 #37592]  INFO -- : Checking profile in examples/profile
         | 
| 181 | 
            +
            I, [2016-05-06T14:27:20.907668 #37592]  INFO -- : Metadata OK.
         | 
| 182 | 
            +
            I, [2016-05-06T14:27:20.968584 #37592]  INFO -- : Found 4 controls.
         | 
| 183 | 
            +
            I, [2016-05-06T14:27:20.968638 #37592]  INFO -- : Control definitions OK.
         | 
| 184 | 
            +
            Profile is valid
         | 
| 185 | 
            +
            Generate temporary profile archive at /var/folders/jy/2bnrfb4s36jbjtzllvhhyqhw0000gn/T/profile20160506-37592-1tf326f.tar.gz
         | 
| 186 | 
            +
            I, [2016-05-06T14:27:21.020017 #37592]  INFO -- : Generate archive /var/folders/jy/2bnrfb4s36jbjtzllvhhyqhw0000gn/T/profile20160506-37592-1tf326f.tar.gz.
         | 
| 187 | 
            +
            I, [2016-05-06T14:27:21.024837 #37592]  INFO -- : Finished archive generation.
         | 
| 188 | 
            +
            Start upload to admin/profile
         | 
| 189 | 
            +
            Uploading to Chef Compliance
         | 
| 190 | 
            +
            Successfully uploaded profile
         | 
| 191 | 
            +
             | 
| 192 | 
            +
            # display all profiles
         | 
| 193 | 
            +
            $ inspec automate profiles
         | 
| 194 | 
            +
            Available profiles:
         | 
| 195 | 
            +
            -------------------
         | 
| 196 | 
            +
             * admin/profile
         | 
| 197 | 
            +
             * base/apache
         | 
| 198 | 
            +
             * base/linux
         | 
| 199 | 
            +
             * base/mysql
         | 
| 200 | 
            +
             * base/postgres
         | 
| 201 | 
            +
             * base/ssh
         | 
| 202 | 
            +
             * base/windows
         | 
| 203 | 
            +
             * cis/cis-centos6-level1
         | 
| 204 | 
            +
             * cis/cis-centos6-level2
         | 
| 205 | 
            +
             * cis/cis-centos7-level1
         | 
| 206 | 
            +
             * cis/cis-centos7-level2
         | 
| 207 | 
            +
             * cis/cis-rhel7-level1
         | 
| 208 | 
            +
             * cis/cis-rhel7-level2
         | 
| 209 | 
            +
             * cis/cis-ubuntu12.04lts-level1
         | 
| 210 | 
            +
             * cis/cis-ubuntu12.04lts-level2
         | 
| 211 | 
            +
             * cis/cis-ubuntu14.04lts-level1
         | 
| 212 | 
            +
             * cis/cis-ubuntu14.04lts-level2
         | 
| 213 | 
            +
            ```
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            or
         | 
| 216 | 
            +
             | 
| 108 217 | 
             
            ```
         | 
| 109 218 | 
             
            $ inspec compliance version
         | 
| 110 219 | 
             
            Chef Compliance version: 1.0.11
         | 
| @@ -168,17 +277,31 @@ $ inspec exec compliance://admin/apache-baseline#2.0.1 | |
| 168 277 | 
             
            ```
         | 
| 169 278 |  | 
| 170 279 | 
             
            Download a specific version(2.0.2) of a profile when logged in with Automate:
         | 
| 280 | 
            +
            ```
         | 
| 281 | 
            +
            $ inspec automate download compliance://admin/apache-baseline#2.0.2
         | 
| 282 | 
            +
            ```
         | 
| 283 | 
            +
             | 
| 284 | 
            +
            or
         | 
| 285 | 
            +
             | 
| 171 286 | 
             
            ```
         | 
| 172 287 | 
             
            $ inspec compliance download compliance://admin/apache-baseline#2.0.2
         | 
| 173 288 | 
             
            ```
         | 
| 174 289 |  | 
| 175 290 | 
             
            ### To Logout from Chef Compliance
         | 
| 176 291 |  | 
| 292 | 
            +
            ```
         | 
| 293 | 
            +
            $ inspec automate logout
         | 
| 294 | 
            +
            Successfully logged out
         | 
| 295 | 
            +
            ```
         | 
| 296 | 
            +
             | 
| 297 | 
            +
            or
         | 
| 298 | 
            +
             | 
| 177 299 | 
             
            ```
         | 
| 178 300 | 
             
            $ inspec compliance logout
         | 
| 179 301 | 
             
            Successfully logged out
         | 
| 180 302 | 
             
            ```
         | 
| 181 303 |  | 
| 304 | 
            +
             | 
| 182 305 | 
             
            ## Integration Tests
         | 
| 183 306 |  | 
| 184 307 | 
             
            At this point of time, InSpec is not able to pick up the token directly, therefore the integration test is semi-automatic at this point of time:
         |