Class: NoradCli::SecTestContainer

Inherits:
Object
  • Object
show all
Defined in:
lib/norad_cli/support/sectest_container.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sectest_name, registry, version, options) ⇒ SecTestContainer

Returns a new instance of SecTestContainer.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 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

Instance Attribute Details

#assessment_idObject

Returns the value of attribute assessment_id.



11
12
13
# File 'lib/norad_cli/support/sectest_container.rb', line 11

def assessment_id
  @assessment_id
end

#containerObject

Returns the value of attribute container.



10
11
12
# File 'lib/norad_cli/support/sectest_container.rb', line 10

def container
  @container
end

#debugObject

Returns the value of attribute debug.



14
15
16
# File 'lib/norad_cli/support/sectest_container.rb', line 14

def debug
  @debug
end

#results_serverObject

Returns the value of attribute results_server.



13
14
15
# File 'lib/norad_cli/support/sectest_container.rb', line 13

def results_server
  @results_server
end

#sectest_imageObject

Returns the value of attribute sectest_image.



12
13
14
# File 'lib/norad_cli/support/sectest_container.rb', line 12

def sectest_image
  @sectest_image
end

#sectest_optionsObject (readonly)

Returns the value of attribute sectest_options.



15
16
17
# File 'lib/norad_cli/support/sectest_container.rb', line 15

def sectest_options
  @sectest_options
end

Instance Method Details

#output(target) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# 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) ⇒ Object

Format the prog_args appropriately for the container



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 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) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/norad_cli/support/sectest_container.rb', line 71

def progarg_present?(key)
  sectest_options['prog_args'].include?("{#{key}}")
end

#resultsObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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

#shutdownObject



118
119
120
121
122
123
124
125
126
127
# 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

#startObject



75
76
77
78
79
80
81
82
# 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