cem_acpt 0.7.3 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'winrm'
4
+ require_relative '../logging'
5
+
6
+ module CemAcpt
7
+ module Utils
8
+ module WinRMRunner
9
+ class WinRMExecutionError < StandardError; end
10
+
11
+ # A wrapper class for executing commands on a windows node
12
+ # Provides error handling and logging on each command being executed
13
+ class RunnerWrapper
14
+ include CemAcpt::Logging
15
+
16
+ def initialize(shell)
17
+ @shell = shell
18
+ end
19
+
20
+ def run(command)
21
+ output = @shell.run(command) do |stdout, stderr|
22
+ puts stdout
23
+ puts stderr
24
+ end
25
+
26
+ # At any point, if the exit code is not 0, we will raise an error and stop the test
27
+ # Because if one command fails, it will effect the rest of the test.
28
+ if output.exitcode != 0
29
+ raise WinRMExecutionError, "Command #{command} failed with exit code #{output.exitcode}. Error: #{output.stderr}"
30
+ end
31
+ end
32
+ end
33
+
34
+ # A class for setting up windows nodes for testing
35
+ # Applies puppet manifest on nodes and installs the cem_windows module
36
+ class WinNode
37
+ include CemAcpt::Logging
38
+
39
+ attr_reader :mod_name
40
+
41
+ def initialize(login_info, mod_name)
42
+ @login_info = login_info
43
+ @mod_name = mod_name
44
+ end
45
+
46
+ def run_winrm
47
+ logger.info('CemAcpt') { 'Setting up Windows nodes for test...' }
48
+
49
+ cem_windows_mod_dir = "C:\\ProgramData\\PuppetLabs\\code\\environments\\production\\modules\\cem_windows"
50
+
51
+ @login_info.each do |node_name, node_info|
52
+ username = node_info['username']
53
+ password = node_info['password']
54
+ test_name = node_info['test_name']
55
+ ip = node_info['ip']
56
+
57
+ opts = {
58
+ endpoint: "https://#{ip}:5986/wsman",
59
+ user: username,
60
+ password: password,
61
+ transport: :ssl,
62
+ no_ssl_peer_verification: true,
63
+ retry_limit: 5,
64
+ retry_delay: 20,
65
+ }
66
+
67
+ conn = WinRM::Connection.new(opts)
68
+ conn.shell(:powershell) do |shell|
69
+ # Instantiate the wrapper class
70
+ winrm_runner = RunnerWrapper.new(shell)
71
+ # The below steps for enabling long paths, installing Puppet and make cem_acpt directory will be a part of making the custom image.
72
+ # Enable long paths
73
+ logger.debug('CemAcpt') { 'Enabling long paths...' }
74
+ winrm_runner.run('Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1')
75
+ # Download Puppet and Install it
76
+ logger.info('CemAcpt') { 'Downloading and installing Puppet...' }
77
+ winrm_runner.run('Invoke-WebRequest -URI http://downloads.puppetlabs.com/windows/puppet7/puppet-agent-7.25.0-x64.msi -OutFile "C:\puppet-agent-7.25.0-x64.msi"')
78
+ winrm_runner.run("Start-process msiexec.exe -Wait -ArgumentList '/I C:\\puppet-agent-7.25.0-x64.msi PUPPET_AGENT_STARTUP_MODE=Disabled /qn /norestart'")
79
+ # Create our cem_acpt parent directory
80
+ logger.debug('CemAcpt') { 'Creating cem_acpt directory and downloading necessary files...' }
81
+ winrm_runner.run("mkdir C:\\cem_acpt")
82
+ # Download the cem_windows module from the bucket to cem_acpt directory
83
+ winrm_runner.run("gcloud storage cp gs://win_cem_acpt/#{@mod_name} C:\\cem_acpt")
84
+ # Install the cem_windows module
85
+ logger.info('CemAcpt') { 'Installing cem_windows module...' }
86
+ winrm_runner.run("Start-Process -FilePath 'C:\\Program Files\\Puppet Labs\\Puppet\\bin\\puppet.bat' -ArgumentList 'module install C:\\cem_acpt\\#{@mod_name}' -Wait -NoNewWindow")
87
+ # Download Goss and set it to alpha mode since it's on alpha for windows
88
+ logger.info('CemAcpt') { 'Downloading Goss...' }
89
+ winrm_runner.run("Invoke-WebRequest -URI https://github.com/goss-org/goss/releases/download/v0.3.23/goss-alpha-windows-amd64.exe -OutFile 'C:\\goss.exe'")
90
+ # Since we already installed the cem_windows module, we can unpack it to get the goss.yaml and the manifest.pp in spec/acceptance dir
91
+ # Due to the pain in the ass of trying to parse a string that is yaml dumped in ruby through powershell, I'm just gonna create the yaml
92
+ # in the cem_windows module itself and then move them to the directory at C:/cem_acpt for ease of access and use. The location for these two
93
+ # files will be at spec/files
94
+ winrm_runner.run("Move-Item -Path #{cem_windows_mod_dir}\\spec\\files\\puppet_idempotent.yaml -Destination C:\\cem_acpt")
95
+ winrm_runner.run("Move-Item -Path #{cem_windows_mod_dir}\\spec\\files\\puppet_noop.yaml -Destination C:\\cem_acpt")
96
+ # Grab the goss.yaml and the manifest.pp from the cem_windows module using the test_name from run_data and move to top level of C:/cem_acpt/
97
+ winrm_runner.run("Move-Item -Path #{cem_windows_mod_dir}\\spec\\acceptance\\#{test_name}\\goss.yaml -Destination C:\\cem_acpt")
98
+ winrm_runner.run("Move-Item -Path #{cem_windows_mod_dir}\\spec\\acceptance\\#{test_name}\\manifest.pp -Destination C:\\cem_acpt")
99
+ # Open up firewall ports
100
+ logger.debug('CemAcpt') { 'Opening up firewall ports...' }
101
+ winrm_runner.run('netsh advfirewall firewall add rule name="Goss in" dir=in action=allow protocol=TCP localport=8080')
102
+ winrm_runner.run('netsh advfirewall firewall add rule name="Idempotent in" dir=in action=allow protocol=TCP localport=8081')
103
+ winrm_runner.run('netsh advfirewall firewall add rule name="Noop in" dir=in action=allow protocol=TCP localport=8082')
104
+ winrm_runner.run('netsh advfirewall firewall add rule name="Goss out" dir=out action=allow protocol=TCP localport=8080')
105
+ winrm_runner.run('netsh advfirewall firewall add rule name="Idempotent out" dir=out action=allow protocol=TCP localport=8081')
106
+ winrm_runner.run('netsh advfirewall firewall add rule name="Noop out" dir=out action=allow protocol=TCP localport=8082')
107
+ logger.info('CemAcpt') { 'Setting up NSSM and starting Goss services...' }
108
+ # Download NSSM into cem_acpt directory
109
+ # NSSM is a tool that allows us to create services on windows without having to create a Windows service project.
110
+ # NSSM works with almost any executable. In our case, it will work with goss.exe
111
+ winrm_runner.run("Invoke-WebRequest -URI http://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -OutFile 'C:\\cem_acpt\\nssm-2.24.zip'")
112
+ # Extract NSSM into cem_acpt directory
113
+ winrm_runner.run("Expand-Archive -Path C:\\cem_acpt\\nssm-2.24.zip -DestinationPath C:\\cem_acpt")
114
+ winrm_runner.run("Rename-Item -Path C:\\cem_acpt\\nssm-2.24-101-g897c7ad -NewName nssm-2.24")
115
+ # Install NSSM Goss server and start it
116
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe install goss-server C:\\goss.exe')
117
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set goss-server AppStdout C:\\cem_acpt\\goss-server.log')
118
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set goss-server AppStderr C:\\cem_acpt\\goss-server-stderr.log')
119
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set goss-server AppParameters "--use-alpha=1 -g C:\\cem_acpt\\goss.yaml serve -f json --endpoint /acpt --cache 10m"')
120
+ # There is a slight issue with starting through nssm, if the process took a bit too long, it will send an error but the process will still be running.
121
+ # winrm_runner.run(shell, 'C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe start goss-server')
122
+ winrm_runner.run('$GossServer= Get-Service "goss-server"')
123
+ winrm_runner.run('$GossServer.Start()')
124
+ winrm_runner.run('$WaitForGossServer = New-TimeSpan -Seconds 5')
125
+ winrm_runner.run('$GossServer.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, $WaitForGossServer)')
126
+ # Install NSSM Idempotent server and start it
127
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe install idempotent-server C:\\goss.exe')
128
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set idempotent-server AppStdout C:\\cem_acpt\\idempotent-server.log')
129
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set idempotent-server AppStderr C:\\cem_acpt\\idempotent-server-stderr.log')
130
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set idempotent-server AppParameters "--use-alpha=1 -g C:\\cem_acpt\\puppet_idempotent.yaml serve -f json -l :8081 --endpoint /idempotent --cache 10m"')
131
+ # winrm_runner.run(shell, 'C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe start idempotent-server')
132
+ winrm_runner.run('$IdmServer= Get-Service "idempotent-server"')
133
+ winrm_runner.run('$IdmServer.Start()')
134
+ winrm_runner.run('$WaitForIdmServer = New-TimeSpan -Seconds 5')
135
+ winrm_runner.run('$IdmServer.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, $WaitForIdmServer)')
136
+ # Install NSSM Noop server and start it
137
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe install noop-server C:\\goss.exe')
138
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set noop-server AppStdout C:\\cem_acpt\\noop-server.log')
139
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set noop-server AppStderr C:\\cem_acpt\\noop-server-stderr.log')
140
+ winrm_runner.run('C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe set noop-server AppParameters "--use-alpha=1 -g C:\\cem_acpt\\puppet_noop.yaml serve -f json -l :8082 --endpoint /noop --cache 10m"')
141
+ # winrm_runner.run(shell, 'C:\\cem_acpt\\nssm-2.24\\win64\\nssm.exe start noop-server')
142
+ winrm_runner.run('$NoopServer= Get-Service "noop-server"')
143
+ winrm_runner.run('$NoopServer.Start()')
144
+ winrm_runner.run('$WaitForNoopServer = New-TimeSpan -Seconds 5')
145
+ winrm_runner.run('$NoopServer.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running, $WaitForNoopServer)')
146
+ # Run puppet apply
147
+ logger.info('CemAcpt') { 'Running puppet apply...' }
148
+ winrm_runner.run("Start-Process -FilePath 'C:\\Program Files\\Puppet Labs\\Puppet\\bin\\puppet.bat' -ArgumentList 'apply --verbose C:\\cem_acpt\\manifest.pp' -Wait -NoNewWindow -PassThru")
149
+ logger.info('CemAcpt') { 'Puppet apply finished...' }
150
+ end
151
+ end
152
+ end
153
+
154
+ def run
155
+ run_winrm
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -1,10 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'utils/puppet'
4
+ require_relative 'utils/shell'
4
5
  require_relative 'utils/ssh'
5
6
  require_relative 'utils/terminal'
7
+ require_relative 'utils/winrm_runner'
8
+ require_relative 'logging'
6
9
 
7
10
  module CemAcpt
8
11
  # Utility methods and modules for CemAcpt.
9
- module Utils; end
12
+ module Utils
13
+ class << self
14
+ include CemAcpt::Logging
15
+
16
+ def package_win_module(module_dir)
17
+ # Path to the package file
18
+ package_file = File.join(module_dir, 'puppetlabs-cem_windows.tar.gz')
19
+
20
+ # Remove the old package file if it exists
21
+ FileUtils.rm_f(package_file)
22
+ `cd #{module_dir} && touch puppetlabs-cem_windows.tar.gz && tar -czf puppetlabs-cem_windows.tar.gz --exclude=puppetlabs-cem_windows.tar.gz *`
23
+ logger.info('CemAcpt') { "Windows module packaged at #{package_file}" }
24
+ package_file
25
+ end
26
+
27
+ def reset_password_readiness_polling(instance_name)
28
+ attempts = 0
29
+ last_error = nil
30
+ result = nil
31
+ begin
32
+ result = CemAcpt::Utils::Shell.run_cmd("echo Y | gcloud compute reset-windows-password #{instance_name} --zone=us-west1-b")
33
+ rescue StandardError => e
34
+ logger.debug('CemAcpt::Utils') { "Error polling for password readiness: #{e}" }
35
+ last_error = e
36
+ end
37
+ while result.nil? || result.empty?
38
+ raise "Instance not ready for password reset. Last error: #{last_error}" if attempts >= 60 # 10 minutes
39
+
40
+ logger.info('CemAcpt') { "Waiting for instance #{instance_name} to be ready for password reset..." }
41
+ sleep 10
42
+ begin
43
+ result = CemAcpt::Utils::Shell.run_cmd("echo Y | gcloud compute reset-windows-password #{instance_name} --zone=us-west1-b")
44
+ rescue StandardError => e
45
+ logger.debug('CemAcpt::Utils') { "Error polling for password readiness: #{e}" }
46
+ last_error = e
47
+ end
48
+ attempts += 1
49
+ end
50
+ result
51
+ end
52
+
53
+ def get_windows_login_info(instance_name, hash_of_instance)
54
+ password_and_username = {}
55
+ password_and_username[instance_name] = {}
56
+ info = reset_password_readiness_polling(instance_name).split(/\r?\n/)[1..2]
57
+ info.each do |line|
58
+ key_val = line.split(' ')
59
+ password_and_username[instance_name][key_val[0].strip.delete(':')] = key_val[1].strip
60
+ end
61
+
62
+ password_and_username[instance_name]['ip'] = hash_of_instance['ip']
63
+ password_and_username[instance_name]['test_name'] = hash_of_instance['test_name']
64
+ password_and_username
65
+ end
66
+ end
67
+ end
10
68
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CemAcpt
4
- VERSION = '0.7.3'
4
+ VERSION = '0.8.1'
5
5
  end
data/lib/cem_acpt.rb CHANGED
@@ -22,6 +22,7 @@ module CemAcpt
22
22
  end
23
23
 
24
24
  def run(command, original_command, options)
25
+ set_up_signal_handlers
25
26
  case command
26
27
  when :version
27
28
  puts "#{original_command} v#{CemAcpt::VERSION}"
@@ -30,9 +31,9 @@ module CemAcpt
30
31
  when :print_explain_config
31
32
  print_config(options, command: original_command.to_sym, format: :explain)
32
33
  when :cem_acpt
33
- run_cem_acpt(options)
34
+ trace_it(options[:trace], options[:trace_events]) { run_cem_acpt(options) }
34
35
  when :cem_acpt_image
35
- run_cem_acpt_image(options)
36
+ trace_it(options[:trace], options[:trace_events]) { run_cem_acpt_image(options) }
36
37
  else
37
38
  raise "Command #{command} does not exist"
38
39
  end
@@ -78,41 +79,70 @@ module CemAcpt
78
79
  new_log
79
80
  end
80
81
 
82
+ TRACE_EVENTS = %i[line call b_call thread_begin thread_end].freeze
83
+
84
+ def trace_it(should_trace = false, trace_events = nil)
85
+ if should_trace
86
+ trace_events ||= TRACE_EVENTS
87
+ tracer = TracePoint.new(*trace_events.map(&:to_sym)) do |tp|
88
+ if tp&.path&.include?('lib/cem_acpt') && !tp&.path&.include?('lib/cem_acpt/logging')
89
+ begin
90
+ logger << "## TRACE ## #{tp.path}:#{tp.lineno}: #{tp.event} #{tp.method_id}\n"
91
+ rescue StandardError
92
+ # Trace will often run into the trap context problem before the signal handler call back
93
+ logger.trap_context = true
94
+ logger << "## TRACE ## #{tp.path}:#{tp.lineno}: #{tp.event}\n"
95
+ end
96
+ end
97
+ end
98
+ tracer.enable do
99
+ yield
100
+ end
101
+ else
102
+ yield
103
+ end
104
+ end
105
+
106
+ def signal_handlers
107
+ {
108
+ 'INT' => proc do
109
+ @trap_context = true
110
+ logger.trap_context = @trap_context
111
+ logger.fatal('CemAcpt') { 'Received interrupt signal. Exiting.' }
112
+ exit 1
113
+ end,
114
+ }
115
+ end
116
+
117
+ def set_up_signal_handlers
118
+ signal_handlers.each do |signal, handler|
119
+ Signal.trap(signal, &handler)
120
+ logger.debug('CemAcpt') { "Signal handler set for #{signal}" }
121
+ end
122
+ end
123
+
81
124
  def run_cem_acpt(options)
82
125
  # Set up config, logger, and helper
83
126
  @config = new_config(options)
84
127
  initialize_logger!
128
+ logger.debug('CemAcpt') { 'Config set and logger initialized...' }
85
129
  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
130
+ logger.debug('CemAcpt') { 'Runner initialized...' }
96
131
 
97
132
  # Run the test suite
133
+ logger.debug('CemAcpt') { 'Running test suite...' }
98
134
  runner.run
99
-
135
+ logger.debug('CemAcpt') { "Test suite run complete, exiting with code #{runner.exit_code}" }
100
136
  exit runner.exit_code
101
137
  end
102
138
 
103
139
  def run_cem_acpt_image(options)
104
140
  @config = new_config(options, command: :cem_acpt_image)
105
141
  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
142
+ logger.debug('CemAcptImage') { 'Config set and logger initialized...' }
114
143
 
115
144
  # Build the images
145
+ logger.debug('CemAcptImage') { 'Building images...' }
116
146
  CemAcpt::ImageBuilder.build_images(@config)
117
147
  end
118
148
  end
@@ -27,6 +27,27 @@ variable "subnetwork" {
27
27
  type = string
28
28
  }
29
29
 
30
+ # Just stub this out for now
31
+ variable "username" {
32
+ type = string
33
+ }
34
+
35
+ # Just stub this out for now
36
+ variable "private_key" {
37
+ type = string
38
+ sensitive = true
39
+ }
40
+
41
+ # Just stub this out for now
42
+ variable "public_key" {
43
+ type = string
44
+ }
45
+
46
+ # Just stub this out for now
47
+ variable "puppet_module_package" {
48
+ type = string
49
+ }
50
+
30
51
  variable "node_data" {
31
52
  type = map(object({
32
53
  machine_type = string
@@ -71,6 +92,11 @@ resource "google_compute_instance" "acpt-test-node" {
71
92
  }
72
93
  }
73
94
 
95
+ service_account {
96
+ email = "cem-windows-acpt-test@team-sse.iam.gserviceaccount.com"
97
+ scopes = ["cloud-platform"]
98
+ }
99
+
74
100
  metadata = {
75
101
  "enable-oslogin" = "TRUE"
76
102
  "cem-acpt-test" = each.value.test_name
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.7.3
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - puppetlabs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-18 00:00:00.000000000 Z
11
+ date: 2023-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http
@@ -105,19 +105,25 @@ dependencies:
105
105
  - !ruby/object:Gem::Version
106
106
  version: 0.0.1
107
107
  - !ruby/object:Gem::Dependency
108
- name: ruby-terraform
108
+ name: winrm
109
109
  requirement: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - "~>"
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '2.3'
114
+ - - "<"
112
115
  - !ruby/object:Gem::Version
113
- version: '1.7'
116
+ version: '3.0'
114
117
  type: :runtime
115
118
  prerelease: false
116
119
  version_requirements: !ruby/object:Gem::Requirement
117
120
  requirements:
118
- - - "~>"
121
+ - - ">="
119
122
  - !ruby/object:Gem::Version
120
- version: '1.7'
123
+ version: '2.3'
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '3.0'
121
127
  - !ruby/object:Gem::Dependency
122
128
  name: pry
123
129
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +152,34 @@ dependencies:
146
152
  - - ">="
147
153
  - !ruby/object:Gem::Version
148
154
  version: '0'
155
+ - !ruby/object:Gem::Dependency
156
+ name: rubocop-performance
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ - !ruby/object:Gem::Dependency
170
+ name: rubocop-rspec
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
149
183
  description: Litmus-like library focusing on CEM Acceptance Tests
150
184
  email:
151
185
  - abide-team@puppet.com
@@ -170,6 +204,7 @@ files:
170
204
  - exe/cem_acpt
171
205
  - exe/cem_acpt_image
172
206
  - lib/cem_acpt.rb
207
+ - lib/cem_acpt/action_result.rb
173
208
  - lib/cem_acpt/cli.rb
174
209
  - lib/cem_acpt/config.rb
175
210
  - lib/cem_acpt/config/base.rb
@@ -192,16 +227,20 @@ files:
192
227
  - lib/cem_acpt/provision/terraform.rb
193
228
  - lib/cem_acpt/provision/terraform/linux.rb
194
229
  - lib/cem_acpt/provision/terraform/os_data.rb
230
+ - lib/cem_acpt/provision/terraform/terraform_cmd.rb
195
231
  - lib/cem_acpt/provision/terraform/windows.rb
196
232
  - lib/cem_acpt/puppet_helpers.rb
197
233
  - lib/cem_acpt/test_data.rb
198
234
  - lib/cem_acpt/test_runner.rb
199
235
  - lib/cem_acpt/test_runner/log_formatter.rb
236
+ - lib/cem_acpt/test_runner/log_formatter/error_formatter.rb
200
237
  - lib/cem_acpt/test_runner/log_formatter/goss_action_response.rb
201
238
  - lib/cem_acpt/utils.rb
202
239
  - lib/cem_acpt/utils/puppet.rb
240
+ - lib/cem_acpt/utils/shell.rb
203
241
  - lib/cem_acpt/utils/ssh.rb
204
242
  - lib/cem_acpt/utils/terminal.rb
243
+ - lib/cem_acpt/utils/winrm_runner.rb
205
244
  - lib/cem_acpt/version.rb
206
245
  - lib/terraform/gcp/linux/goss/puppet_idempotent.yaml
207
246
  - lib/terraform/gcp/linux/goss/puppet_noop.yaml
@@ -238,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
277
  - !ruby/object:Gem::Version
239
278
  version: '0'
240
279
  requirements: []
241
- rubygems_version: 3.4.6
280
+ rubygems_version: 3.4.18
242
281
  signing_key:
243
282
  specification_version: 4
244
283
  summary: CEM Acceptance Tests