cem_acpt 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'core_extensions'
4
3
  require_relative 'goss'
5
4
  require_relative 'logging'
6
5
  require_relative 'platform'
@@ -39,27 +38,27 @@ module CemAcpt
39
38
  def run
40
39
  @run_data = {}
41
40
  @start_time = Time.now
42
- logger.info('CemAcpt') { "Starting CemAcpt v#{CemAcpt::VERSION}..." }
43
- logger.info('CemAcpt') { "Test suite started at #{@start_time}..." }
44
- logger.info('CemAcpt') { "Using module directory: #{config.get('module_dir')}..." }
45
- Dir.chdir(config.get('module_dir')) do
46
- keep_terminal_alive
47
- @run_data[:private_key], @run_data[:public_key], @run_data[:known_hosts] = new_ephemeral_ssh_keys
48
- logger.info('CemAcpt') { 'Created ephemeral SSH key pair...' }
49
- @run_data[:module_package_path] = build_module_package
50
- logger.info('CemAcpt') { "Created module package: #{@run_data[:module_package_path]}..." }
51
- @run_data[:test_data] = new_test_data
52
- logger.info('CemAcpt') { 'Created test data...' }
53
- logger.verbose('CemAcpt') { "Test data: #{@run_data[:test_data]}" }
54
- @run_data[:nodes] = new_node_data
55
- logger.info('CemAcpt') { 'Created node data...' }
56
- logger.verbose('CemAcpt') { "Node data: #{@run_data[:nodes]}" }
57
- @instance_names_ips = provision_test_nodes
58
- logger.info('CemAcpt') { 'Provisioned test nodes...' }
59
- logger.debug('CemAcpt') { "Instance names and IPs: #{@instance_names_ips}" }
60
- @results = run_tests(@instance_names_ips.map { |_, v| v['ip'] },
61
- config.get('actions.only'),
62
- config.get('actions.except'))
41
+ logger.with_ci_group("CemAcpt v#{CemAcpt::VERSION} run started at #{@start_time}") do
42
+ logger.info('CemAcpt') { "Using module directory: #{config.get('module_dir')}..." }
43
+ Dir.chdir(config.get('module_dir')) do
44
+ keep_terminal_alive
45
+ @run_data[:private_key], @run_data[:public_key], @run_data[:known_hosts] = new_ephemeral_ssh_keys
46
+ logger.info('CemAcpt') { 'Created ephemeral SSH key pair...' }
47
+ @run_data[:module_package_path] = build_module_package
48
+ logger.info('CemAcpt') { "Created module package: #{@run_data[:module_package_path]}..." }
49
+ @run_data[:test_data] = new_test_data
50
+ logger.info('CemAcpt') { 'Created test data...' }
51
+ logger.verbose('CemAcpt') { "Test data: #{@run_data[:test_data]}" }
52
+ @run_data[:nodes] = new_node_data
53
+ logger.info('CemAcpt') { 'Created node data...' }
54
+ logger.verbose('CemAcpt') { "Node data: #{@run_data[:nodes]}" }
55
+ @instance_names_ips = provision_test_nodes
56
+ logger.info('CemAcpt') { 'Provisioned test nodes...' }
57
+ logger.debug('CemAcpt') { "Instance names and IPs: #{@instance_names_ips}" }
58
+ @results = run_tests(@instance_names_ips.map { |_, v| v['ip'] },
59
+ config.get('actions.only'),
60
+ config.get('actions.except'))
61
+ end
63
62
  end
64
63
  ensure
65
64
  clean_up
@@ -105,7 +104,7 @@ module CemAcpt
105
104
  end
106
105
 
107
106
  def clean_ephemeral_ssh_keys
108
- return if config.get('no_ephemeral_ssh_key')
107
+ return if config.get('no_ephemeral_ssh_key') || config.get('no_destroy_nodes')
109
108
 
110
109
  CemAcpt::Utils::SSH::Ephemeral.clean
111
110
  end
@@ -124,13 +123,17 @@ module CemAcpt
124
123
  end
125
124
 
126
125
  def destroy_test_nodes
127
- @provisioner&.destroy if config.get('no_destroy_nodes')
126
+ return no_destroy if config.get('no_destroy_nodes')
127
+
128
+ logger.with_ci_group("CemAcpt v#{CemAcpt::VERSION} run finished at #{Time.now}") { @provisioner&.destroy }
128
129
  end
129
130
 
130
131
  def no_destroy
131
132
  logger.warn('CemAcpt') { 'Not destroying test nodes...' }
132
- @provisioner&.show
133
- logger.info('CemAcpt') { "Test SSH Keys:\n Private Key: #{@run_data[:private_key]}\n Public Key:#{@run_data[:public_key]}" }
133
+ logger.with_ci_group("CemAcpt v#{CemAcpt::VERSION} run finished at #{Time.now}") do
134
+ @provisioner&.show
135
+ logger.info('CemAcpt') { "Test SSH Keys:\n Private Key: #{@run_data[:private_key]}\n Public Key:#{@run_data[:public_key]}" }
136
+ end
134
137
  end
135
138
 
136
139
  def run_tests(hosts, only_actions, except_actions)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CemAcpt
4
- VERSION = '0.6.4'
4
+ VERSION = '0.7.0'
5
5
  end
data/lib/cem_acpt.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  module CemAcpt
4
4
  require_relative 'cem_acpt/config'
5
5
  require_relative 'cem_acpt/logging'
6
+ require_relative 'cem_acpt/image_builder'
6
7
  require_relative 'cem_acpt/test_runner'
7
8
  require_relative 'cem_acpt/version'
8
9
 
@@ -11,14 +12,8 @@ module CemAcpt
11
12
 
12
13
  attr_reader :config
13
14
 
14
- def version(as_str: false)
15
- return VERSION unless as_str
16
-
17
- "cem_acpt v#{VERSION}"
18
- end
19
-
20
- def print_config(options, format: :yaml)
21
- config = new_config(options)
15
+ def print_config(options, command: :cem_acpt, format: :yaml)
16
+ config = new_config(options, command: command)
22
17
  if format == :explain
23
18
  puts config.explain
24
19
  return
@@ -26,32 +21,34 @@ module CemAcpt
26
21
  puts config.send("to_#{format}".to_sym)
27
22
  end
28
23
 
29
- def run(options)
30
- # Set up config, logger, and helper
31
- @config = new_config(options)
32
- initialize_logger!
33
- runner = new_runner
34
-
35
- # Set up signal handlers
36
- Signal.trap('INT') do
37
- @trap_context = true
38
- logger.trap_context = @trap_context
39
- logger.fatal('Signal Handler') { 'Received interrupt signal. Cleaning up test suite...' }
40
- runner.clean_up(@trap_context)
41
- logger.fatal('Signal Handler') { 'Exiting due to interrupt signal' }
42
- exit 1
24
+ def run(command, original_command, options)
25
+ case command
26
+ when :version
27
+ puts "#{original_command} v#{CemAcpt::VERSION}"
28
+ when :print_yaml_config
29
+ print_config(options, command: original_command.to_sym, format: :yaml)
30
+ when :print_explain_config
31
+ print_config(options, command: original_command.to_sym, format: :explain)
32
+ when :cem_acpt
33
+ run_cem_acpt(options)
34
+ when :cem_acpt_image
35
+ run_cem_acpt_image(options)
36
+ else
37
+ raise "Command #{command} does not exist"
43
38
  end
44
-
45
- # Run the test suite
46
- runner.run
47
-
48
- exit runner.exit_code
49
39
  end
50
40
 
51
41
  private
52
42
 
53
- def new_config(options)
54
- CemAcpt::Config.new(opts: options, config_file: options[:config_file])
43
+ def new_config(options, command: :cem_acpt)
44
+ case command
45
+ when :cem_acpt
46
+ CemAcpt::Config::CemAcpt.new(opts: options, config_file: options[:config_file])
47
+ when :cem_acpt_image
48
+ CemAcpt::Config::CemAcptImage.new(opts: options, config_file: options[:config_file])
49
+ else
50
+ raise "Config does not exist for command: #{command}"
51
+ end
55
52
  end
56
53
 
57
54
  def new_runner
@@ -80,5 +77,43 @@ module CemAcpt
80
77
  new_log.set_verbose(!!config.get('verbose'))
81
78
  new_log
82
79
  end
80
+
81
+ def run_cem_acpt(options)
82
+ # Set up config, logger, and helper
83
+ @config = new_config(options)
84
+ initialize_logger!
85
+ runner = new_runner
86
+
87
+ # Set up signal handlers
88
+ Signal.trap('INT') do
89
+ @trap_context = true
90
+ logger.trap_context = @trap_context
91
+ logger.fatal('Signal Handler') { 'Received interrupt signal. Cleaning up test suite...' }
92
+ runner.clean_up(@trap_context)
93
+ logger.fatal('Signal Handler') { 'Exiting due to interrupt signal' }
94
+ exit 1
95
+ end
96
+
97
+ # Run the test suite
98
+ runner.run
99
+
100
+ exit runner.exit_code
101
+ end
102
+
103
+ def run_cem_acpt_image(options)
104
+ @config = new_config(options, command: :cem_acpt_image)
105
+ initialize_logger!
106
+
107
+ # Set up signal handlers
108
+ Signal.trap('INT') do
109
+ @trap_context = true
110
+ logger.trap_context = @trap_context
111
+ logger.fatal('Signal Handler') { 'Received interrupt signal. Cleaning up test suite...' }
112
+ exit 1
113
+ end
114
+
115
+ # Build the images
116
+ CemAcpt::ImageBuilder.build_images(@config)
117
+ end
83
118
  end
84
119
  end
@@ -0,0 +1,112 @@
1
+ terraform {
2
+ required_providers {
3
+ google = {
4
+ source = "hashicorp/google"
5
+ version = "4.59.0"
6
+ }
7
+ }
8
+ }
9
+
10
+ variable "credentials_file" {
11
+ type = string
12
+ }
13
+
14
+ variable "project" {
15
+ type = string
16
+ }
17
+
18
+ variable "region" {
19
+ type = string
20
+ }
21
+
22
+ variable "zone" {
23
+ type = string
24
+ }
25
+
26
+ variable "subnetwork" {
27
+ type = string
28
+ }
29
+
30
+ variable "username" {
31
+ type = string
32
+ }
33
+
34
+ variable "private_key" {
35
+ type = string
36
+ sensitive = true
37
+ }
38
+
39
+ variable "public_key" {
40
+ type = string
41
+ }
42
+
43
+ variable "node_data" {
44
+ type = map(object({
45
+ image_family = string
46
+ machine_type = string
47
+ base_image = string
48
+ disk_size = number
49
+ provision_commands = list(string)
50
+ }))
51
+ }
52
+
53
+ provider "google" {
54
+ credentials = file(var.credentials_file)
55
+ project = var.project
56
+ region = var.region
57
+ zone = var.zone
58
+ }
59
+
60
+ resource "google_compute_instance" "acpt-test-node" {
61
+ provider = google
62
+ for_each = var.node_data
63
+ name = each.key
64
+ machine_type = each.value.machine_type
65
+ zone = var.zone
66
+
67
+ boot_disk {
68
+ initialize_params {
69
+ image = each.value.base_image
70
+ size = each.value.disk_size
71
+ type = "pd-standard"
72
+ }
73
+ }
74
+
75
+ network_interface {
76
+ subnetwork = var.subnetwork
77
+ access_config {
78
+ network_tier = "STANDARD"
79
+ }
80
+ }
81
+
82
+ provisioner "remote-exec" {
83
+ connection {
84
+ type = "ssh"
85
+ user = "${var.username}"
86
+ timeout = "5m"
87
+ host = self.network_interface.0.access_config.0.nat_ip
88
+ port = 22
89
+ private_key = "${file(var.private_key)}"
90
+ agent = false
91
+ }
92
+ inline = each.value.provision_commands
93
+ }
94
+
95
+ metadata = {
96
+ "enable-oslogin" = "FALSE"
97
+ "ssh-keys" = "${var.username}:${file(var.public_key)}"
98
+ "for-image-family" = each.value.image_family
99
+ }
100
+
101
+ tags = [ "cem-acpt-test-node" ]
102
+ }
103
+
104
+ output "node-data" {
105
+ value = {
106
+ for k, v in google_compute_instance.acpt-test-node : v.name => {
107
+ ip = v.network_interface.0.access_config.0.nat_ip
108
+ image_family = v.metadata["for-image-family"]
109
+ disk_link = v.boot_disk.0.source
110
+ }
111
+ }
112
+ }
File without changes
data/sample_config.yaml CHANGED
@@ -36,7 +36,7 @@ actions:
36
36
  - 'acpt'
37
37
 
38
38
  node_data:
39
- machine_type: 'e2-small'
39
+ machine_type: 'e2-medium'
40
40
  disk_size: 40
41
41
 
42
42
  image_name_builder:
@@ -56,4 +56,91 @@ tests:
56
56
  # - cis_oel-8_firewalld_server_2
57
57
  # - cis_alma-8_firewalld_server_2
58
58
  # - stig_rhel-7_firewalld_public_3
59
- # - stig_rhel-8_firewalld_public_3
59
+ # - stig_rhel-8_firewalld_public_3
60
+
61
+ cem_acpt_image:
62
+ no_windows: true
63
+ no_linux: false
64
+
65
+ images:
66
+ cem-acpt-alma-8-puppet8-firewalld:
67
+ os: alma
68
+ os_major_version: 8
69
+ puppet_version: 8
70
+ base_image: 'almalinux-cloud/almalinux-8'
71
+ provision_commands:
72
+ - 'sudo systemctl enable firewalld'
73
+ - 'sudo systemctl start firewalld'
74
+ - 'sudo firewall-cmd --permanent --add-service=ssh'
75
+ - 'sudo firewall-cmd --reload'
76
+ - 'sudo useradd testuser1'
77
+ - "echo 'testuser1:P@s5W-rd$' | sudo chpasswd"
78
+ # cem-acpt-alma-8-puppet7-firewalld:
79
+ # os: alma
80
+ # os_major_version: 8
81
+ # puppet_version: 7
82
+ # base_image: 'almalinux-cloud/almalinux-8'
83
+ # provision_commands:
84
+ # - 'systemctl enable firewalld'
85
+ # - 'systemctl start firewalld'
86
+ # - 'firewall-cmd --permanent --add-service=ssh'
87
+ # - 'firewall-cmd --reload'
88
+ # - 'useradd testuser1'
89
+ # - "echo 'testuser1:P@s5W-rd$' | chpasswd"
90
+ cem-acpt-rhel-8-puppet8-firewalld:
91
+ os: rhel
92
+ os_major_version: 8
93
+ puppet_version: 8
94
+ base_image: 'rhel-cloud/rhel-8'
95
+ provision_commands:
96
+ - 'sudo systemctl enable firewalld'
97
+ - 'sudo systemctl start firewalld'
98
+ - 'sudo firewall-cmd --permanent --add-service=ssh'
99
+ - 'sudo firewall-cmd --reload'
100
+ - 'sudo useradd testuser1'
101
+ - "echo 'testuser1:P@s5W-rd$' | sudo chpasswd"
102
+ # cem-acpt-rhel-8-puppet7-firewalld:
103
+ # os: rhel
104
+ # os_major_version: 8
105
+ # puppet_version: 7
106
+ # base_image: 'rhel-cloud/rhel-8'
107
+ # provision_commands:
108
+ # - 'systemctl enable firewalld'
109
+ # - 'systemctl start firewalld'
110
+ # - 'firewall-cmd --permanent --add-service=ssh'
111
+ # - 'firewall-cmd --reload'
112
+ # - 'useradd testuser1'
113
+ # - "echo 'testuser1:P@s5W-rd$' | chpasswd"
114
+ cem-acpt-rhel-7-puppet8-firewalld:
115
+ os: rhel
116
+ os_major_version: 7
117
+ puppet_version: 8
118
+ base_image: 'rhel-cloud/rhel-7'
119
+ provision_commands:
120
+ - 'sudo systemctl enable firewalld'
121
+ - 'sudo systemctl start firewalld'
122
+ - 'sudo firewall-cmd --permanent --add-service=ssh'
123
+ - 'sudo firewall-cmd --reload'
124
+ - 'sudo useradd testuser1'
125
+ - "echo 'testuser1:P@s5W-rd$' | sudo chpasswd"
126
+ # cem-acpt-rhel-7-puppet7-firewalld:
127
+ # os: rhel
128
+ # os_major_version: 7
129
+ # puppet_version: 7
130
+ # base_image: 'rhel-cloud/rhel-7'
131
+ # provision_commands:
132
+ # - 'systemctl enable firewalld'
133
+ # - 'systemctl start firewalld'
134
+ # - 'firewall-cmd --permanent --add-service=ssh'
135
+ # - 'firewall-cmd --reload'
136
+ # - 'useradd testuser1'
137
+ # - "echo 'testuser1:P@s5W-rd$' | chpasswd"
138
+ # cem-acpt-windows-2019-puppet7-default:
139
+ # os: windows
140
+ # os_major_version: 2019
141
+ # puppet_version: 7
142
+ # base_image: 'windows-cloud/windows-server-2019-dc-core-v20210914'
143
+ # provision_commands:
144
+ # - powershell.exe -Command "Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False"
145
+ # - powershell.exe -Command "New-NetFirewallRule -DisplayName 'Allow SSH' -Direction Inbound -LocalPort 22 -Protocol TCP -Action Allow"
146
+ # - powershell.exe -Command "New-LocalUser -Name testuser1 -Password (ConvertTo-SecureString -AsPlainText 'P@s5W0rd$' -Force)"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cem_acpt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - puppetlabs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-25 00:00:00.000000000 Z
11
+ date: 2023-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http
@@ -151,6 +151,7 @@ email:
151
151
  - abide-team@puppet.com
152
152
  executables:
153
153
  - cem_acpt
154
+ - cem_acpt_image
154
155
  extensions: []
155
156
  extra_rdoc_files: []
156
157
  files:
@@ -167,12 +168,20 @@ files:
167
168
  - bin/setup
168
169
  - cem_acpt.gemspec
169
170
  - exe/cem_acpt
171
+ - exe/cem_acpt_image
170
172
  - lib/cem_acpt.rb
173
+ - lib/cem_acpt/cli.rb
171
174
  - lib/cem_acpt/config.rb
172
- - lib/cem_acpt/core_extensions.rb
175
+ - lib/cem_acpt/config/base.rb
176
+ - lib/cem_acpt/config/cem_acpt.rb
177
+ - lib/cem_acpt/config/cem_acpt_image.rb
178
+ - lib/cem_acpt/core_ext.rb
173
179
  - lib/cem_acpt/goss.rb
174
180
  - lib/cem_acpt/goss/api.rb
175
181
  - lib/cem_acpt/goss/api/action_response.rb
182
+ - lib/cem_acpt/image_builder.rb
183
+ - lib/cem_acpt/image_builder/exec.rb
184
+ - lib/cem_acpt/image_builder/provision_commands.rb
176
185
  - lib/cem_acpt/image_name_builder.rb
177
186
  - lib/cem_acpt/logging.rb
178
187
  - lib/cem_acpt/logging/formatter.rb
@@ -201,6 +210,8 @@ files:
201
210
  - lib/terraform/gcp/linux/systemd/goss-idempotent.service
202
211
  - lib/terraform/gcp/linux/systemd/goss-noop.service
203
212
  - lib/terraform/gcp/windows/.keep
213
+ - lib/terraform/image/gcp/linux/main.tf
214
+ - lib/terraform/image/gcp/windows/.keep
204
215
  - sample_config.yaml
205
216
  homepage: https://github.com/puppetlabs/cem_acpt
206
217
  licenses: