Merge pull request #5534 from inspec/nm/compliance-remove-support

Removed support for compliance and a1 server from InSpec compliance
This commit is contained in:
Clinton Wolfe 2021-05-31 18:38:13 -04:00 committed by GitHub
commit e198120cf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 760 deletions

View file

@ -24,16 +24,8 @@ module InspecPlugins
# the username of the account is used that is logged in
def self.profiles(config, profile_filter = nil) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
owner = config["owner"] || config["user"]
# Chef Compliance
if is_compliance_server?(config)
url = "#{config["server"]}/user/compliance"
# Chef Automate2
elsif is_automate2_server?(config)
if is_automate2_server?(config)
url = "#{config["server"]}/compliance/profiles/search"
# Chef Automate
elsif is_automate_server?(config)
url = "#{config["server"]}/profiles/#{owner}"
else
raise ServerConfigurationMissing
end
@ -45,12 +37,9 @@ module InspecPlugins
id, ver = nil
end
if is_automate2_server?(config)
body = { owner: owner, name: id }.to_json
response = InspecPlugins::Compliance::HTTP.post_with_headers(url, headers, body, config["insecure"])
else
response = InspecPlugins::Compliance::HTTP.get(url, headers, config["insecure"])
end
body = { owner: owner, name: id }.to_json
response = InspecPlugins::Compliance::HTTP.post_with_headers(url, headers, body, config["insecure"])
data = response.body
response_code = response.code
case response_code
@ -58,25 +47,12 @@ module InspecPlugins
msg = "success"
profiles = JSON.parse(data)
# iterate over profiles
if is_compliance_server?(config)
mapped_profiles = []
profiles.values.each do |org|
mapped_profiles += org.values
end
# Chef Automate pre 0.8.0
elsif is_automate_server_pre_080?(config)
mapped_profiles = profiles.values.flatten
elsif is_automate2_server?(config)
mapped_profiles = []
profiles["profiles"].each do |p|
mapped_profiles << p
end
else
mapped_profiles = profiles.map do |e|
e["owner_id"] = owner
e
end
mapped_profiles = []
profiles["profiles"].each do |p|
mapped_profiles << p
end
# filter by name and version if they were specified in profile_filter
mapped_profiles.select! do |p|
(!ver || p["version"] == ver) && (!id || p["name"] == id)
@ -120,26 +96,9 @@ module InspecPlugins
end
def self.upload(config, owner, profile_name, archive_path)
# Chef Compliance
if is_compliance_server?(config)
url = "#{config["server"]}/owners/#{owner}/compliance/#{profile_name}/tar"
# Chef Automate pre 0.8.0
elsif is_automate_server_pre_080?(config)
url = "#{config["server"]}/#{owner}"
elsif is_automate2_server?(config)
url = "#{config["server"]}/compliance/profiles?owner=#{owner}"
# Chef Automate
else
url = "#{config["server"]}/profiles/#{owner}"
end
url = "#{config["server"]}/compliance/profiles?owner=#{owner}"
headers = get_headers(config)
if is_automate2_server?(config)
res = InspecPlugins::Compliance::HTTP.post_multipart_file(url, headers, archive_path, config["insecure"])
else
res = InspecPlugins::Compliance::HTTP.post_file(url, headers, archive_path, config["insecure"])
end
res = InspecPlugins::Compliance::HTTP.post_multipart_file(url, headers, archive_path, config["insecure"])
[res.is_a?(Net::HTTPSuccess), res.body]
end
@ -210,16 +169,12 @@ module InspecPlugins
def self.get_headers(config)
token = get_token(config)
if is_automate_server?(config) || is_automate2_server?(config)
headers = { "chef-delivery-enterprise" => config["automate"]["ent"] }
if config["automate"]["token_type"] == "dctoken"
headers["x-data-collector-token"] = token
else
headers["chef-delivery-user"] = config["user"]
headers["chef-delivery-token"] = token
end
headers = { "chef-delivery-enterprise" => config["automate"]["ent"] }
if config["automate"]["token_type"] == "dctoken"
headers["x-data-collector-token"] = token
else
headers = { "Authorization" => "Bearer #{token}" }
headers["chef-delivery-user"] = config["user"]
headers["chef-delivery-token"] = token
end
headers
end
@ -232,16 +187,7 @@ module InspecPlugins
end
def self.target_url(config, profile)
owner, id, ver = profile_split(profile)
return "#{config["server"]}/compliance/profiles/tar" if is_automate2_server?(config)
return "#{config["server"]}/owners/#{owner}/compliance/#{id}/tar" unless is_automate_server?(config)
if ver.nil?
"#{config["server"]}/profiles/#{owner}/#{id}/tar"
else
"#{config["server"]}/profiles/#{owner}/#{id}/version/#{ver}/tar"
end
"#{config["server"]}/compliance/profiles/tar"
end
def self.profile_split(profile)
@ -260,33 +206,6 @@ module InspecPlugins
uri.to_s.sub(%r{^compliance:\/\/}, "")
end
def self.is_compliance_server?(config)
config["server_type"] == "compliance"
end
def self.is_automate_server_pre_080?(config)
# Automate versions before 0.8.x do not have a valid version in the config
return false unless config["server_type"] == "automate"
server_version_from_config(config).nil?
end
def self.is_automate_server_080_and_later?(config)
# Automate versions 0.8.x and later will have a "version" key in the config
# that is properly parsed out via server_version_from_config below
return false unless config["server_type"] == "automate"
!server_version_from_config(config).nil?
end
def self.is_automate2_server?(config)
config["server_type"] == "automate2"
end
def self.is_automate_server?(config)
config["server_type"] == "automate"
end
def self.server_version_from_config(config)
# Automate versions 0.8.x and later will have a "version" key in the config
# that looks like: "version":{"api":"compliance","version":"0.8.24"}
@ -296,87 +215,8 @@ module InspecPlugins
config["version"]["version"]
end
def self.determine_server_type(url, insecure)
if target_is_automate2_server?(url, insecure)
:automate2
elsif target_is_automate_server?(url, insecure)
:automate
elsif target_is_compliance_server?(url, insecure)
:compliance
else
Inspec::Log.debug("Could not determine server type using known endpoints")
nil
end
end
def self.target_is_automate2_server?(url, insecure)
automate_endpoint = "/dex/auth"
response = InspecPlugins::Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
if response.code == "400"
Inspec::Log.debug(
"Received 400 from #{url}#{automate_endpoint} - " \
"assuming target is a #{AUTOMATE_PRODUCT_NAME}2 instance"
)
true
else
Inspec::Log.debug(
"Received #{response.code} from #{url}#{automate_endpoint} - " \
"assuming target is not an #{AUTOMATE_PRODUCT_NAME}2 instance"
)
false
end
end
def self.target_is_automate_server?(url, insecure)
automate_endpoint = "/compliance/version"
response = InspecPlugins::Compliance::HTTP.get(url + automate_endpoint, nil, insecure)
case response.code
when "401"
Inspec::Log.debug(
"Received 401 from #{url}#{automate_endpoint} - " \
"assuming target is a #{AUTOMATE_PRODUCT_NAME} instance"
)
true
when "200"
# Chef Automate currently returns 401 for `/compliance/version` but some
# versions of OpsWorks Chef Automate return 200 and a Chef Manage page
# when unauthenticated requests are received.
if response.body.include?("Are You Looking For the #{SERVER_PRODUCT_NAME}?")
Inspec::Log.debug(
"Received 200 from #{url}#{automate_endpoint} - " \
"assuming target is an #{AUTOMATE_PRODUCT_NAME} instance"
)
true
else
Inspec::Log.debug(
"Received 200 from #{url}#{automate_endpoint} " \
"but did not receive the Chef Manage page - " \
"assuming target is not a #{AUTOMATE_PRODUCT_NAME} instance"
)
false
end
else
Inspec::Log.debug(
"Received unexpected status code #{response.code} " \
"from #{url}#{automate_endpoint} - " \
"assuming target is not a #{AUTOMATE_PRODUCT_NAME} instance"
)
false
end
end
def self.target_is_compliance_server?(url, insecure)
# All versions of Chef Compliance return 200 for `/api/version`
compliance_endpoint = "/api/version"
response = InspecPlugins::Compliance::HTTP.get(url + compliance_endpoint, nil, insecure)
return false unless response.code == "200"
Inspec::Log.debug(
"Received 200 from #{url}#{compliance_endpoint} - " \
"assuming target is a #{AUTOMATE_PRODUCT_NAME} server"
)
true
def self.is_automate2_server?(config)
config["server_type"] == "automate2"
end
end
end

View file

@ -11,20 +11,10 @@ module InspecPlugins
def login(options)
raise ArgumentError, "Please specify a server using `#{EXEC_NAME} automate login https://SERVER` or `#{EXEC_NAME} compliance login https://SERVER`" unless options["server"]
options["server_type"] = "automate2"
options["server"] = URI("https://#{options["server"]}").to_s if URI(options["server"]).scheme.nil?
options["server_type"] = InspecPlugins::Compliance::API.determine_server_type(options["server"], options["insecure"])
case options["server_type"]
when :automate2
Login::Automate2Server.login(options)
when :automate
Login::AutomateServer.login(options)
when :compliance
Login::ComplianceServer.login(options)
else
raise CannotDetermineServerType, "Unable to determine if #{options["server"]} is a #{AUTOMATE_PRODUCT_NAME} or #{COMPLIANCE_PRODUCT_NAME} server"
end
Login::Automate2Server.login(options)
end
module Automate2Server
@ -48,7 +38,7 @@ module InspecPlugins
config["user"] = options["user"]
config["owner"] = options["user"]
config["insecure"] = options["insecure"] || false
config["server_type"] = options["server_type"].to_s
config["server_type"] = options["server_type"]
config["token"] = token
config["version"] = "0"
@ -69,133 +59,6 @@ module InspecPlugins
end
end
module AutomateServer
def self.login(options)
verify_thor_options(options)
options["url"] = options["server"] + "/compliance"
token = options["dctoken"] || options["token"]
success, msg = API::Login.authenticate_login(options)
success ? store_access_token(options, token) : msg
end
def self.store_access_token(options, token)
token_type = if options["token"]
"usertoken"
else
"dctoken"
end
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["automate"] = {}
config["automate"]["ent"] = options["ent"]
config["automate"]["token_type"] = token_type
config["server"] = options["url"]
config["user"] = options["user"]
config["insecure"] = options["insecure"] || false
config["server_type"] = options["server_type"].to_s
config["token"] = token
config["version"] = InspecPlugins::Compliance::API.version(config)
config.store
API::Login.configuration_stored_message(config)
end
# Automate login requires `--ent`, `--user`, and either `--token` or `--dctoken`
def self.verify_thor_options(o)
error_msg = []
error_msg.push("Please specify a user using `--user='USER'`") if o["user"].nil?
error_msg.push("Please specify an enterprise using `--ent='automate'`") if o["ent"].nil?
if o["token"].nil? && o["dctoken"].nil?
error_msg.push("Please specify a token using `--token='AUTOMATE_TOKEN'` or `--dctoken='DATA_COLLECTOR_TOKEN'`")
end
raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
end
end
module ComplianceServer
include Inspec::Dist
def self.login(options)
compliance_verify_thor_options(options)
options["url"] = options["server"] + "/api"
if options["user"] && options["token"]
success, msg = API::Login.authenticate_login(options)
success ? compliance_store_access_token(options, options["token"]) : msg
elsif options["user"] && options["password"]
compliance_login_user_pass(options)
elsif options["refresh_token"]
compliance_login_refresh_token(options)
end
end
def self.compliance_login_user_pass(options)
success, msg, token = InspecPlugins::Compliance::API.get_token_via_password(
options["url"],
options["user"],
options["password"],
options["insecure"]
)
raise msg unless success
compliance_store_access_token(options, token)
end
def self.compliance_login_refresh_token(options)
success, msg, token = InspecPlugins::Compliance::API.get_token_via_refresh_token(
options["url"],
options["refresh_token"],
options["insecure"]
)
raise msg unless success
compliance_store_access_token(options, token)
end
def self.compliance_store_access_token(options, token)
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["user"] = options["user"] if options["user"]
config["server"] = options["url"]
config["insecure"] = options["insecure"] || false
config["server_type"] = options["server_type"].to_s
config["token"] = token
config["version"] = InspecPlugins::Compliance::API.version(config)
config.store
API::Login.configuration_stored_message(config)
end
# Compliance login requires `--user` or `--refresh_token`
# If `--user` then either `--password`, `--token`, or `--refresh-token`, is required
def self.compliance_verify_thor_options(o)
error_msg = []
error_msg.push("Please specify a server using `#{EXEC_NAME} automate login https://SERVER` or `#{EXEC_NAME} compliance login https://SERVER`") if o["server"].nil?
if o["user"].nil? && o["refresh_token"].nil?
error_msg.push("Please specify a `--user='USER'` or a `--refresh-token='TOKEN'`")
end
if o["user"] && o["password"].nil? && o["token"].nil? && o["refresh_token"].nil?
error_msg.push("Please specify either a `--password`, `--token`, or `--refresh-token`")
end
raise ArgumentError, error_msg.join("\n") unless error_msg.empty?
end
end
def self.authenticate_login(options)
InspecPlugins::Compliance::API.authenticate_login_using_version_api(
options["url"],

View file

@ -32,16 +32,8 @@ module InspecPlugins
def self.check_compliance_token(uri, config)
if config["token"].nil? && config["refresh_token"].nil?
if config["server_type"] == "automate"
server = "automate"
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate_server --user USER --ent ENT --dctoken DCTOKEN or --token USERTOKEN"
elsif config["server_type"] == "automate2"
server = "automate2"
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate2_server --user USER --token APITOKEN"
else
server = "compliance"
msg = "#{EXEC_NAME} [automate|compliance] login https://your_compliance_server --user admin --insecure --token 'PASTE TOKEN HERE' "
end
server = "automate2"
msg = "#{EXEC_NAME} [automate|compliance] login https://your_automate2_server --user USER --token APITOKEN"
raise Inspec::FetcherFailure, <<~EOF
Cannot fetch #{uri} because your #{server} token has not been
@ -119,19 +111,9 @@ module InspecPlugins
# determine the owner_id and the profile name from the url
def compliance_profile_name
m = if InspecPlugins::Compliance::API.is_automate_server_pre_080?(@config)
%r{^#{@config['server']}/(?<owner>[^/]+)/(?<id>[^/]+)/tar$}
elsif InspecPlugins::Compliance::API.is_automate_server_080_and_later?(@config)
%r{^#{@config['server']}/profiles/(?<owner>[^/]+)/(?<id>[^/]+)/tar$}
else
%r{^#{@config['server']}/owners/(?<owner>[^/]+)/compliance/(?<id>[^/]+)/tar$}
end.match(@target)
if InspecPlugins::Compliance::API.is_automate2_server?(@config)
m = {}
m[:owner] = @config["profile"][0]
m[:id] = @config["profile"][1]
end
m = {}
m[:owner] = @config["profile"][0]
m[:id] = @config["profile"][1]
if m.nil?
raise "Unable to determine compliance profile name. This can be caused by " \

View file

@ -13,16 +13,6 @@ describe InspecPlugins::Compliance::API do
}
end
let(:compliance_options) do
{
"server" => "https://compliance.example.com",
"user" => "someone",
"password" => "password",
"token" => "token",
"refresh_token" => "refresh_token",
}
end
let(:fake_config) do
class FakeConfig
def initialize
@ -51,9 +41,6 @@ describe InspecPlugins::Compliance::API do
describe ".login" do
describe "when target is a Chef Automate2 server" do
before do
InspecPlugins::Compliance::API.expects(:determine_server_type).returns(:automate2)
end
it "raises an error if `--user` is missing" do
options = automate_options
@ -99,114 +86,6 @@ describe InspecPlugins::Compliance::API do
end
end
describe "when target is a Chef Automate server" do
before do
InspecPlugins::Compliance::API.expects(:determine_server_type).returns(:automate)
end
it "raises an error if `--user` is missing" do
options = automate_options
options.delete("user")
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
_(err.message).must_match(/Please specify a user.*/)
_(err.message.lines.length).must_equal(1)
end
it "raises an error if `--ent` is missing" do
options = automate_options
options.delete("ent")
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
_(err.message).must_match(/Please specify an enterprise.*/)
_(err.message.lines.length).must_equal(1)
end
it "raises an error if `--token` and `--dctoken` are missing" do
options = automate_options
options.delete("token")
options.delete("dctoken")
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
_(err.message).must_match(/Please specify a token.*/)
_(err.message.lines.length).must_equal(1)
end
it "stores an access token" do
stub_request(:get, automate_options["server"] + "/compliance/version")
.to_return(status: 200, body: "", headers: {})
options = automate_options
InspecPlugins::Compliance::Configuration.expects(:new).returns(fake_config)
InspecPlugins::Compliance::API.login(options)
_(fake_config["automate"]["ent"]).must_equal("automate")
_(fake_config["automate"]["token_type"]).must_equal("usertoken")
_(fake_config["user"]).must_equal("someone")
_(fake_config["server"]).must_equal("https://automate.example.com/compliance")
_(fake_config["server_type"]).must_equal("automate")
_(fake_config["token"]).must_equal("token")
end
it "puts error message when api-token is invalid" do
stub_body = { "error": "request not authenticated", "code": 16, "message": "request not authenticated", "details": [] }.to_json
stub_request(:get, automate_options["server"] + "/compliance/version")
.to_return(status: 401, body: stub_body, headers: {})
options = automate_options
res = InspecPlugins::Compliance::API.login(options)
_(res).must_equal(
"Failed to authenticate to https://automate.example.com/compliance \n"\
"Response code: 401\nBody: {\"error\":\"request not authenticated\",\"code\":16,\"message\":\"request not authenticated\",\"details\":[]}"
)
end
end
describe "when target is a Chef Compliance server" do
before do
InspecPlugins::Compliance::API.expects(:determine_server_type).returns(:compliance)
end
it "raises an error if `--user` and `--refresh-token` are missing" do
options = automate_options
options.delete("user")
options.delete("refresh_token")
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
_(err.message).must_match(/Please specify a.*--user.*--refresh-token.*/)
_(err.message.lines.length).must_equal(1)
end
it "raises an error if `--user` is present but authentication method missing" do
options = automate_options
options.delete("password")
options.delete("token")
options.delete("refresh_token")
err = _ { InspecPlugins::Compliance::API.login(options) }.must_raise(ArgumentError)
_(err.message).must_match(/Please specify.*--password.*--token.*--refresh-token.*/)
_(err.message.lines.length).must_equal(1)
end
it "stores an access token" do
stub_request(:get, compliance_options["server"] + "/api/version")
.to_return(status: 200, body: "", headers: {})
options = compliance_options
InspecPlugins::Compliance::Configuration.expects(:new).returns(fake_config)
InspecPlugins::Compliance::API.login(options)
_(fake_config["user"]).must_equal("someone")
_(fake_config["server"]).must_equal("https://compliance.example.com/api")
_(fake_config["server_type"]).must_equal("compliance")
_(fake_config["token"]).must_equal("token")
end
it "puts error message when api-token is invalid" do
stub_body = { "error": "request not authenticated", "code": 16, "message": "request not authenticated", "details": [] }.to_json
stub_request(:get, automate_options["server"] + "/api/version")
.to_return(status: 401, body: stub_body, headers: {})
options = automate_options
res = InspecPlugins::Compliance::API.login(options)
_(res).must_equal(
"Failed to authenticate to https://automate.example.com/api \n"\
"Response code: 401\nBody: {\"error\":\"request not authenticated\",\"code\":16,\"message\":\"request not authenticated\",\"details\":[]}"
)
end
end
describe "when target is neither a Chef Compliance nor Chef Automate server" do
it "raises an error if `https://SERVER` is missing" do
options = {}
@ -214,12 +93,6 @@ describe InspecPlugins::Compliance::API do
_(err.message).must_match(/Please specify a server.*/)
_(err.message.lines.length).must_equal(1)
end
it "rasies a `CannotDetermineServerType` error" do
InspecPlugins::Compliance::API.expects(:determine_server_type).returns(nil)
err = _ { InspecPlugins::Compliance::API.login(automate_options) }.must_raise(StandardError)
_(err.message).must_match(/Unable to determine/)
end
end
end
end

View file

@ -5,41 +5,43 @@ require_relative "../../lib/inspec-compliance/api"
describe InspecPlugins::Compliance::API do
let(:profiles_response) do
[{ "name" => "apache-baseline",
"title" => "DevSec Apache Baseline",
"maintainer" => "DevSec Hardening Framework Team",
"copyright" => "DevSec Hardening Framework Team",
"copyright_email" => "hello@dev-sec.io",
"license" => "Apache 2 license",
"summary" => "Test-suite for best-practice apache hardening",
"version" => "2.0.2",
"supports" => [{ "os-family" => "unix" }],
"depends" => nil,
"owner_id" => "admin" },
{ "name" => "apache-baseline",
"title" => "DevSec Apache Baseline",
"maintainer" => "Hardening Framework Team",
"copyright" => "Hardening Framework Team",
"copyright_email" => "hello@dev-sec.io",
"license" => "Apache 2 license",
"summary" => "Test-suite for best-practice apache hardening",
"version" => "2.0.1",
"supports" => [{ "os-family" => "unix" }],
"depends" => nil,
"latest_version" => "2.0.2",
"owner_id" => "admin" },
{ "name" => "cis-aix-5.3-6.1-level1",
"title" => "CIS AIX 5.3 and AIX 6.1 Benchmark Level 1",
"maintainer" => "Chef Software, Inc.",
"copyright" => "Chef Software, Inc.",
"copyright_email" => "support@chef.io",
"license" => "Proprietary, All rights reserved",
"summary" => "CIS AIX 5.3 and AIX 6.1 Benchmark Level 1 translated from SCAP",
"version" => "1.1.0",
"supports" => nil,
"depends" => nil,
"latest_version" => "1.1.0-3",
"owner_id" => "admin" }]
{ "profiles":
[{ "name" => "apache-baseline",
"title" => "DevSec Apache Baseline",
"maintainer" => "DevSec Hardening Framework Team",
"copyright" => "DevSec Hardening Framework Team",
"copyright_email" => "hello@dev-sec.io",
"license" => "Apache 2 license",
"summary" => "Test-suite for best-practice apache hardening",
"version" => "2.0.2",
"supports" => [{ "os-family" => "unix" }],
"depends" => nil,
"owner_id" => "admin" },
{ "name" => "apache-baseline",
"title" => "DevSec Apache Baseline",
"maintainer" => "Hardening Framework Team",
"copyright" => "Hardening Framework Team",
"copyright_email" => "hello@dev-sec.io",
"license" => "Apache 2 license",
"summary" => "Test-suite for best-practice apache hardening",
"version" => "2.0.1",
"supports" => [{ "os-family" => "unix" }],
"depends" => nil,
"latest_version" => "2.0.2",
"owner_id" => "admin" },
{ "name" => "cis-aix-5.3-6.1-level1",
"title" => "CIS AIX 5.3 and AIX 6.1 Benchmark Level 1",
"maintainer" => "Chef Software, Inc.",
"copyright" => "Chef Software, Inc.",
"copyright_email" => "support@chef.io",
"license" => "Proprietary, All rights reserved",
"summary" => "CIS AIX 5.3 and AIX 6.1 Benchmark Level 1 translated from SCAP",
"version" => "1.1.0",
"supports" => nil,
"depends" => nil,
"latest_version" => "1.1.0-3",
"owner_id" => "admin" }],
}
end
describe ".version" do
@ -115,87 +117,6 @@ describe InspecPlugins::Compliance::API do
end
end
describe "automate/compliance is? checks" do
describe "when the config has a compliance server_type" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "compliance"
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate2_server?(config)).must_equal false
end
end
describe "when the config has a automate2 server_type" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate2"
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate2_server?(config)).must_equal true
end
end
describe "when the config has an automate server_type and no version key" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate"
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate2_server?(config)).must_equal false
end
end
describe "when the config has an automate server_type and a version key that is not a hash" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate"
config["version"] = "1.2.3"
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate2_server?(config)).must_equal false
end
end
describe "when the config has an automate server_type and a version hash with no version" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate"
config["version"] = {}
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal false
end
end
describe "when the config has an automate server_type and a version hash with a version" do
it "automate/compliance server is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate"
config["version"] = { "version" => "0.8.1" }
_(InspecPlugins::Compliance::API.is_compliance_server?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server?(config)).must_equal true
_(InspecPlugins::Compliance::API.is_automate_server_pre_080?(config)).must_equal false
_(InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config)).must_equal true
end
end
end
describe ".server_version_from_config" do
it "returns nil when the config has no version key" do
config = {}
@ -229,29 +150,19 @@ describe InspecPlugins::Compliance::API do
end
describe "target_url" do
it "handles a automate profile with and without version" do
it "handles a automate2 profile with and without version" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate"
config["server"] = "https://myautomate"
config["server_type"] = "automate2"
config["server"] = "https://myautomate2"
config["version"] = "1.6.99"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline")).must_equal "https://myautomate/profiles/admin/apache-baseline/tar"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline#2.0.2")).must_equal "https://myautomate/profiles/admin/apache-baseline/version/2.0.2/tar"
end
it "handles a chef-compliance profile with and without version" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "compliance"
config["server"] = "https://mychefcompliance"
config["version"] = "1.1.2"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline")).must_equal "https://mychefcompliance/owners/admin/compliance/apache-baseline/tar"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline#2.0.2")).must_equal "https://mychefcompliance/owners/admin/compliance/apache-baseline/tar"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline")).must_equal "https://myautomate2/compliance/profiles/tar"
_(InspecPlugins::Compliance::API.target_url(config, "admin/apache-baseline#2.0.2")).must_equal "https://myautomate2/compliance/profiles/tar"
end
end
describe "exist?" do
it "works with profiles returned by Automate" do
it "works with profiles returned by Automate 2" do
# ruby 2.3.3 has issues running stub_requests properly
# skipping for that specific version
return if RUBY_VERSION == "2.3.3"
@ -259,14 +170,36 @@ describe InspecPlugins::Compliance::API do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["owner"] = "admin"
config["server_type"] = "automate"
config["server"] = "https://myautomate"
config["server_type"] = "automate2"
config["server"] = "https://myautomate2"
config["version"] = "1.6.99"
config["automate"] = { "ent" => "automate", "token_type" => "dctoken" }
config["version"] = { "api" => "compliance", "version" => "0.8.24" }
stub_request(:get, "https://myautomate/profiles/admin")
.with(headers: { "Accept" => "*/*", "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", "Chef-Delivery-Enterprise" => "automate", "User-Agent" => "Ruby", "X-Data-Collector-Token" => "" })
stub_request(:post, "https://myautomate2/compliance/profiles/search")
.with(
body: "{\"owner\":\"admin\",\"name\":\"apache-baseline\"}",
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"Chef-Delivery-Enterprise" => "automate",
"User-Agent" => "Ruby",
"X-Data-Collector-Token" => "",
}
)
.to_return(status: 200, body: profiles_response.to_json, headers: {})
stub_request(:post, "https://myautomate2/compliance/profiles/search")
.with(
body: "{\"owner\":\"admin\",\"name\":\"missing-in-action\"}",
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"Chef-Delivery-Enterprise" => "automate",
"User-Agent" => "Ruby",
"X-Data-Collector-Token" => "",
}
)
.to_return(status: 200, body: profiles_response.to_json, headers: {})
_(InspecPlugins::Compliance::API.exist?(config, "admin/apache-baseline")).must_equal true
@ -276,111 +209,12 @@ describe InspecPlugins::Compliance::API do
end
end
describe ".determine_server_type" do
let(:url) { "https://someserver.onthe.net/" }
let(:compliance_endpoint) { "/api/version" }
let(:automate_endpoint) { "/compliance/version" }
let(:automate2_endpoint) { "/dex/auth" }
let(:headers) { nil }
let(:insecure) { true }
let(:good_response) { mock }
let(:bad_response) { mock }
it "returns `:automate2` when a 400 is received from `https://URL/dex/auth`" do
good_response.stubs(:code).returns("400")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(good_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_equal(:automate2)
end
it "returns `:automate` when a 401 is received from `https://URL/compliance/version`" do
good_response.stubs(:code).returns("401")
bad_response.stubs(:code).returns("404")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(good_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_equal(:automate)
end
# Chef Automate currently returns 401 for `/compliance/version` but some
# versions of OpsWorks Chef Automate return 200 and a Chef Manage page when
# unauthenticated requests are received.
it "returns `:automate` when a 200 is received from `https://URL/compliance/version`" do
bad_response.stubs(:code).returns("404")
good_response.stubs(:code).returns("200")
good_response.stubs(:body).returns("Are You Looking For the Chef Server?")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(good_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_equal(:automate)
end
it "returns `nil` if a 200 is received from `https://URL/compliance/version` but not redirected to Chef Manage" do
bad_response.stubs(:code).returns("200")
bad_response.stubs(:body).returns("No Chef Manage here")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
mock_compliance_response = mock
mock_compliance_response.stubs(:code).returns("404")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(mock_compliance_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_be_nil
end
it "returns `:compliance` when a 200 is received from `https://URL/api/version`" do
good_response.stubs(:code).returns("200")
bad_response.stubs(:code).returns("404")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(good_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_equal(:compliance)
end
it "returns `nil` if it cannot determine the server type" do
bad_response.stubs(:code).returns("404")
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(bad_response)
_(InspecPlugins::Compliance::API.determine_server_type(url, insecure)).must_be_nil
describe "when the config has a automate2 server_type" do
it "automate server 2 is? methods return correctly" do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config["server_type"] = "automate2"
_(InspecPlugins::Compliance::API.is_automate2_server?(config)).must_equal true
end
end
end

View file

@ -15,12 +15,11 @@ describe InspecPlugins::Compliance::Fetcher do
it "returns an error when token is not set" do
ex = assert_raises(Inspec::FetcherFailure) { fetcher.class.check_compliance_token("http://test.com", config) }
_(ex.message).must_include "Cannot fetch http://test.com because your compliance token has not been\nconfigured."
_(ex.message).must_include "Cannot fetch http://test.com because your automate2 token has not been\nconfigured."
end
end
describe "when the server is an automate2 server" do
before { InspecPlugins::Compliance::API.expects(:is_automate2_server?).with(config).returns(true) }
it "returns the correct owner and profile name" do
config["profile"] = ["admin", "ssh-baseline", nil]
@ -29,54 +28,6 @@ describe InspecPlugins::Compliance::Fetcher do
end
end
describe "when the server is an automate server pre-0.8.0" do
before { InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(true) }
it "returns the correct profile name when the url is correct" do
fetcher = InspecPlugins::Compliance::Fetcher.new("myserver/myowner/myprofile/tar", config)
_(fetcher.send(:compliance_profile_name)).must_equal "myowner/myprofile"
end
it "raises an exception if the url is malformed" do
fetcher = InspecPlugins::Compliance::Fetcher.new("a/bad/url", config)
_(proc { fetcher.send(:compliance_profile_name) }).must_raise RuntimeError
end
end
describe "when the server is an automate server 0.8.0-or-later" do
before do
InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(false)
InspecPlugins::Compliance::API.expects(:is_automate_server_080_and_later?).with(config).returns(true)
end
it "returns the correct profile name when the url is correct" do
fetcher = InspecPlugins::Compliance::Fetcher.new("myserver/profiles/myowner/myprofile/tar", config)
_(fetcher.send(:compliance_profile_name)).must_equal "myowner/myprofile"
end
it "raises an exception if the url is malformed" do
fetcher = InspecPlugins::Compliance::Fetcher.new("a/bad/url", config)
_(proc { fetcher.send(:compliance_profile_name) }).must_raise RuntimeError
end
end
describe "when the server is not an automate server (likely a compliance server)" do
before do
InspecPlugins::Compliance::API.expects(:is_automate_server_pre_080?).with(config).returns(false)
InspecPlugins::Compliance::API.expects(:is_automate_server_080_and_later?).with(config).returns(false)
end
it "returns the correct profile name when the url is correct" do
fetcher = InspecPlugins::Compliance::Fetcher.new("myserver/owners/myowner/compliance/myprofile/tar", config)
_(fetcher.send(:compliance_profile_name)).must_equal "myowner/myprofile"
end
it "raises an exception if the url is malformed" do
fetcher = InspecPlugins::Compliance::Fetcher.new("a/bad/url", config)
_(proc { fetcher.send(:compliance_profile_name) }).must_raise RuntimeError
end
end
describe "when the server calls an automate profile" do
let(:profiles_result) do
[{ "name" => "ssh-baseline",