class InspecPlugins::Compliance::CLI

Public Instance Methods

download(profile_name) click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 94
def download(profile_name)
  o = options.dup
  configure_logger(o)

  config = InspecPlugins::Compliance::Configuration.new
  return unless loggedin(config)

  profile_name = InspecPlugins::Compliance::API.sanitize_profile_name(profile_name)
  if InspecPlugins::Compliance::API.exist?(config, profile_name)
    puts "Downloading `#{profile_name}`"

    fetcher = InspecPlugins::Compliance::Fetcher.resolve(
      {
        compliance: profile_name,
      }
    )

    # we provide a name, the fetcher adds the extension
    _owner, id = profile_name.split("/")
    file_name = fetcher.fetch(o.name || id)
    puts "Profile stored to #{file_name}"
  else
    puts "Profile #{profile_name} is not available in #{AUTOMATE_PRODUCT_NAME}."
    exit 1
  end
end
exec(*tests) click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 71
def exec(*tests)
  compliance_config = InspecPlugins::Compliance::Configuration.new
  return unless loggedin(compliance_config)

  o = config # o is an Inspec::Config object, provided by a helper method from Inspec::BaseCLI
  diagnose(o)
  configure_logger(o)

  # iterate over tests and add compliance scheme
  tests = tests.map { |t| "compliance://" + InspecPlugins::Compliance::API.sanitize_profile_name(t) }

  runner = Inspec::Runner.new(o)
  tests.each { |target| runner.add_target(target) }

  exit runner.run
rescue ArgumentError, RuntimeError, Train::UserError => e
  $stderr.puts e.message
  exit 1
end
login(server) click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 34
def login(server)
  options["server"] = server
  login_response = InspecPlugins::Compliance::API.login(options)
  puts login_response
end
logout() click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 235
def logout
  config = InspecPlugins::Compliance::Configuration.new
  unless config.supported?(:oidc) || config["token"].nil? || config["server_type"] == "automate"
    config = InspecPlugins::Compliance::Configuration.new
    url = "#{config["server"]}/logout"
    InspecPlugins::Compliance::HTTP.post(url, config["token"], config["insecure"], !config.supported?(:oidc))
  end
  success = config.destroy

  if success
    puts "Successfully logged out"
  else
    puts "Could not log out"
  end
end
profiles() click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 43
def profiles
  config = InspecPlugins::Compliance::Configuration.new
  return unless loggedin(config)

  # set owner to config
  config["owner"] = options["owner"] || config["user"]

  msg, profiles = InspecPlugins::Compliance::API.profiles(config)
  profiles.sort_by! { |hsh| hsh["title"] }
  if !profiles.empty?
    # iterate over profiles
    headline("Available profiles:")
    profiles.each do |profile|
      owner = profile["owner_id"] || profile["owner"]
      li("#{profile["title"]} v#{profile["version"]} (#{mark_text(owner + "/" + profile["name"])})")
    end
  else
    puts msg if msg != "success"
    puts "Could not find any profiles"
    exit 1
  end
rescue InspecPlugins::Compliance::ServerConfigurationMissing
  $stderr.puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
  exit 1
end
upload(path) click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 126
def upload(path) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
  config = InspecPlugins::Compliance::Configuration.new
  return unless loggedin(config)

  # set owner to config
  config["owner"] = options["owner"] || config["user"]

  unless File.exist?(path)
    puts "Directory #{path} does not exist."
    exit 1
  end

  vendor_deps(path, options) if File.directory?(path)

  o = options.dup
  configure_logger(o)

  # only run against the mock backend, otherwise we run against the local system
  o[:backend] = Inspec::Backend.create(Inspec::Config.mock)
  o[:check_mode] = true
  o[:vendor_cache] = Inspec::Cache.new(o[:vendor_cache])

  # check the profile, we only allow to upload valid profiles
  profile = Inspec::Profile.for_target(path, o)

  # start verification process
  error_count = 0
  error = lambda { |msg|
    error_count += 1
    puts msg
  }

  result = profile.check
  unless result[:summary][:valid]
    error.call("Profile check failed. Please fix the profile before upload.")
  else
    puts("Profile is valid")
  end

  # determine user information
  if (config["token"].nil? && config["refresh_token"].nil?) || config["user"].nil?
    error.call("Please login via `#{EXEC_NAME} #{subcommand_name} login`")
  end

  # read profile name from inspec.yml
  profile_name = profile.params[:name]

  # read profile version from inspec.yml
  profile_version = profile.params[:version]

  # check that the profile is not uploaded already,
  # confirm upload to the user (overwrite with --force)
  if InspecPlugins::Compliance::API.exist?(config, "#{config["owner"]}/#{profile_name}##{profile_version}") && !options["overwrite"]
    error.call("Profile exists on the server, use --overwrite")
  end

  # abort if we found an error
  if error_count > 0
    puts "Found #{error_count} error(s)"
    exit 1
  end

  # if it is a directory, tar it to tmp directory
  generated = false
  if File.directory?(path)
    generated = true
    archive_path = Dir::Tmpname.create([profile_name, ".tar.gz"]) {}
    puts "Generate temporary profile archive at #{archive_path}"
    profile.archive({ output: archive_path, ignore_errors: false, overwrite: true })
  else
    archive_path = path
  end

  puts "Start upload to #{config["owner"]}/#{profile_name}"
  pname = ERB::Util.url_encode(profile_name)

  puts "Uploading to #{AUTOMATE_PRODUCT_NAME}"

  success, msg = InspecPlugins::Compliance::API.upload(config, config["owner"], pname, archive_path)

  # delete temp file if it was temporary generated
  File.delete(archive_path) if generated && File.exist?(archive_path)

  if success
    puts "Successfully uploaded profile"
  else
    puts "Error during profile upload:"
    puts msg
    exit 1
  end
end
version() click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 219
def version
  config = InspecPlugins::Compliance::Configuration.new
  info = InspecPlugins::Compliance::API.version(config)
  if !info.nil? && info["version"]
    puts "Name:    #{info["api"]}"
    puts "Version: #{info["version"]}"
  else
    puts "Could not determine server version."
    exit 1
  end
rescue InspecPlugins::Compliance::ServerConfigurationMissing
  puts "\nServer configuration information is missing. Please login using `#{EXEC_NAME} #{subcommand_name} login`"
  exit 1
end

Private Instance Methods

loggedin(config) click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 253
def loggedin(config)
  serverknown = !config["server"].nil?
  puts "You need to login first with `#{EXEC_NAME} #{subcommand_name} login`" unless serverknown
  serverknown
end
subcommand_name() click to toggle source
# File lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb, line 259
def subcommand_name
  @_invocations[Inspec::InspecCLI]&.first || "automate"
end