mirror of
https://github.com/inspec/inspec
synced 2024-11-15 09:27:20 +00:00
91403d8c81
* Merge `login` and `login_automate` commands This provides a single interface for logging into either Chef Automate or Chef Compliance servers. Server type is evaluated at run time via HTTP responses from designated endpoints. This also moves the login logic from `Compliance::ComplianceCLI` to a separate set of modules in `Compliance::API`. This removes logic from Thor and allows for more in depth Unit testing. Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Remove empty line below class definition Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Add message to `raise CannotDetermineServerType` Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Refactor `token_info` assignment Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Remove unnecessary rubocop disable Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Modify `Login` module namespacing Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Remove mentions of login_automate and --usertoken Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Modify `determine_server_type` to return a symbol Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Add support for `login_automate` and `--usertoken` Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Fix encoding typo Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com> * Address PR feedback This does the following: - Moves `CannotDetermineServerType` error to `.login` - Changes methods that store configuration to return the configuration - Moves user output to one location in `.login` - Makes other small improvements Signed-off-by: Jerry Aldrich <jerryaldrichiii@gmail.com>
98 lines
3.4 KiB
Ruby
98 lines
3.4 KiB
Ruby
# encoding: utf-8
|
|
# author: Christoph Hartmann
|
|
# author: Dominik Richter
|
|
|
|
require 'uri'
|
|
require 'inspec/fetcher'
|
|
require 'inspec/errors'
|
|
|
|
# InSpec Target Helper for Chef Compliance
|
|
# reuses UrlHelper, but it knows the target server and the access token already
|
|
# similar to `inspec exec http://localhost:2134/owners/%base%/compliance/%ssh%/tar --user %token%`
|
|
module Compliance
|
|
class Fetcher < Fetchers::Url
|
|
name 'compliance'
|
|
priority 500
|
|
def self.resolve(target) # rubocop:disable PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
uri = if target.is_a?(String) && URI(target).scheme == 'compliance'
|
|
URI(target)
|
|
elsif target.respond_to?(:key?) && target.key?(:compliance)
|
|
URI("compliance://#{target[:compliance]}")
|
|
end
|
|
|
|
return nil if uri.nil?
|
|
|
|
# we have detailed information available in our lockfile, no need to ask the server
|
|
if target.respond_to?(:key?) && target.key?(:url)
|
|
profile_fetch_url = target[:url]
|
|
config = {}
|
|
else
|
|
# check if we have a compliance token
|
|
config = Compliance::Configuration.new
|
|
if config['token'].nil? && config['refresh_token'].nil?
|
|
if config['server_type'] == 'automate'
|
|
server = 'automate'
|
|
msg = 'inspec compliance login https://your_automate_server --user USER --ent ENT --dctoken DCTOKEN or --token USERTOKEN'
|
|
else
|
|
server = 'compliance'
|
|
msg = "inspec compliance login https://your_compliance_server --user admin --insecure --token 'PASTE TOKEN HERE' "
|
|
end
|
|
raise Inspec::FetcherFailure, <<EOF
|
|
|
|
Cannot fetch #{uri} because your #{server} token has not been
|
|
configured.
|
|
|
|
Please login using
|
|
|
|
#{msg}
|
|
EOF
|
|
end
|
|
|
|
# verifies that the target e.g base/ssh exists
|
|
profile = Compliance::API.sanitize_profile_name(uri)
|
|
if !Compliance::API.exist?(config, profile)
|
|
raise Inspec::FetcherFailure, "The compliance profile #{profile} was not found on the configured compliance server"
|
|
end
|
|
profile_fetch_url = Compliance::API.target_url(config, profile)
|
|
end
|
|
# We need to pass the token to the fetcher
|
|
config['token'] = Compliance::API.get_token(config)
|
|
new(profile_fetch_url, config)
|
|
rescue URI::Error => _e
|
|
nil
|
|
end
|
|
|
|
# We want to save compliance: in the lockfile rather than url: to
|
|
# make sure we go back through the Compliance API handling.
|
|
def resolved_source
|
|
@resolved_source ||= {
|
|
compliance: compliance_profile_name,
|
|
url: @target,
|
|
sha256: sha256,
|
|
}
|
|
end
|
|
|
|
def to_s
|
|
'Chef Compliance Profile Loader'
|
|
end
|
|
|
|
private
|
|
|
|
# determine the owner_id and the profile name from the url
|
|
def compliance_profile_name
|
|
m = if Compliance::API.is_automate_server_pre_080?(@config)
|
|
%r{^#{@config['server']}/(?<owner>[^/]+)/(?<id>[^/]+)/tar$}
|
|
elsif 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)
|
|
|
|
raise 'Unable to determine compliance profile name. This can be caused by ' \
|
|
'an incorrect server in your configuration. Try to login to compliance ' \
|
|
'via the `inspec compliance login` command.' if m.nil?
|
|
|
|
"#{m[:owner]}/#{m[:id]}"
|
|
end
|
|
end
|
|
end
|