class NoradCli::SecTestContainer

Attributes

assessment_id[RW]
container[RW]
debug[RW]
results_server[RW]
sectest_image[RW]
sectest_options[R]

Public Class Methods

new(sectest_name, registry, version, options) click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 17
def initialize(sectest_name, registry, version, options)
  # Generate a random assessment id
  @assessment_id = SecureRandom.hex(32)

  @sectest_image = "#{registry}/#{sectest_name}:#{version}"

  # Set whether debugging is configured
  @debug = options[:debug]

  # Create a results server
  @results_server = NoradCli::ResultsServer.new('docker-images-test-results-server')

  ENV['ENABLE_LOGS'] = 'true'
  env = [
    'NORAD_ROOT=http://results:3000',
    %(ASSESSMENT_PATHS=[{"id":"singletest", "assessment": "/results/#{@assessment_id}"}]),
    'NORAD_SECRET=1234'
  ]

  # Create the container
  @container = Docker::Container.create(Image: @sectest_image,
                                        Cmd: prog_args(sectest_name, options),
                                        Env: env,
                                        HostConfig: { Links: ["#{@results_server.container.id}:results"] })
end

Public Instance Methods

output(target) click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 84
def output(target)
  # Output container logs for debugging
  @container.stop
  c_state = @container.json['State']

  # Print the entire state regardless of error or not to aid in debugging
  puts Rainbow("[DEBUG] Container #{@sectest_image}'s Final State").green
  puts Rainbow('-------------------------').green
  c_state.each do |key, value|
    puts Rainbow("#{key}: #{value}").green
  end

  puts Rainbow("\n[DEBUG] Logs for target #{@sectest_image} run against #{target}:").green

  # Print logs regardless of ExitCode
  puts Rainbow(@container.logs(stdout: true, stderr: true)).green
end
prog_args(sectest_name, options) click to toggle source

Format the prog_args appropriately for the container

# File lib/norad_cli/support/sectest_container.rb, line 44
def prog_args(sectest_name, options)
  # Grab the program arguments (minus other function options)
  # Options is a Thor::CoreExt::HashWithIndifferentAccess (except does not work)
  prog_arg_hash = options.each_with_object({}) do |(k, v), hsh|
    hsh[k.to_sym] = v unless k == 'debug'
  end

  # Load the prog_arg format
  @sectest_options ||= YAML.safe_load(File.read("sectests/#{sectest_name}/manifest.yml"))

  # Load an ssh key if necessary (default to Norad's key pair)
  prog_arg_hash[:ssh_user] = 'testuser' if !prog_arg_hash[:ssh_user] && progarg_present?('ssh_user')
  prog_arg_hash[:ssh_key] = load_ssh_key(prog_arg_hash[:ssh_key]) if progarg_present?('ssh_key')

  # Fill out the prog_args and return
  begin
    format(sectest_options['prog_args'], prog_arg_hash).split(' ')
  rescue KeyError
    puts Rainbow('Error: The containers required arguments were not set.').red
    puts Rainbow("Arguments in %{} should be set: #{sectest_options['prog_args']}").red
    puts Rainbow("Arguments given: #{prog_arg_hash}").red
    puts Rainbow("Run 'norad sectest execute #{sectest_name} -h' to see how to set arguments!").red
    puts Rainbow('Exiting...').red
    exit(1)
  end
end
progarg_present?(key) click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 71
def progarg_present?(key)
  sectest_options['prog_args'].include?("{#{key}}")
end
results() click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 102
def results
  # Get the results
  url = "http://localhost:#{@results_server.host_port}/results?assessment_id=#{@assessment_id}"
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  request = Net::HTTP::Get.new(uri)
  response = http.request(request)
  if response.code == '200'
    response.body
  else
    puts Rainbow('Error retrieving results\nExiting...').red
    shutdown
    exit(1)
  end
end
shutdown() click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 118
def shutdown
  # Stop the sectest image container and delete
  @container.stop

  # Delete the container only if not in debug mode
  @container.delete(force: true) unless @debug

  # Cleanup/Garbage collect the results server
  @results_server.shutdown
end
start() click to toggle source
# File lib/norad_cli/support/sectest_container.rb, line 75
def start
  # Start the results server container
  @results_server.start

  # Start the sectest container
  @container.start
  @container.wait(60 * 10)
end

Private Instance Methods

load_ssh_key(ssh_key_file) click to toggle source

Replace ssh key file with encoded ssh key

# File lib/norad_cli/support/sectest_container.rb, line 132
def load_ssh_key(ssh_key_file)
  # Check for no ssh_key specified
  if !ssh_key_file
    Base64.strict_encode64(File.read(NoradCli.ssh_key_path))
  elsif File.exist?(ssh_key_file)
    Base64.strict_encode64(File.read(ssh_key_file))
  else
    puts Rainbow("Error: SSH Key file: #{ssh_key_file} does not exist!\nExiting..\n").red
    exit(1)
  end
end