cem_acpt 0.7.3 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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