diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 47a516b7..130b7da5 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -20,7 +20,7 @@ permissions: jobs: integration: name: Integration - runs-on: windows-latest + runs-on: windows-2025 strategy: matrix: ruby: [3.2] @@ -43,9 +43,29 @@ jobs: - name: Install modules if: steps.modules.outputs.cache-hit != 'true' run: bundle exec r10k puppetfile install + - name: Output powershell version + run: $PSVersionTable + - name: List trusted WSMan hosts + run: Get-Item WSMan:\localhost\Client\TrustedHosts + - name: Output WinRM logs + run: winrm enumerate winrm/config/listener + - name: Test WSMan connection + run: Test-WSMan localhost - uses: ./.github/actions/windows_agent_setup - - name: Run tests - run: bundle exec rake ci:windows:integration + - name: Run test + run: bundle exec rake ci:windows:integration --trace -v + - name: Sessions + if: always() + run: Get-PSSession + - name: Test WSMan connection + if: always() + run: Test-WSMan localhost + - name: Print EventLog + if: always() + run: winrm enumerate winrm/config/Listener + - name: Print EventLog + if: always() + run: Get-WinEvent -ListLog *winrm* | fl * agentless: name: Agentless diff --git a/openbolt.gemspec b/openbolt.gemspec index c8ccbb01..71c99b3f 100644 --- a/openbolt.gemspec +++ b/openbolt.gemspec @@ -52,7 +52,6 @@ Gem::Specification.new do |spec| spec.add_dependency "json", "~> 2.12" spec.add_dependency "jwt", "~> 2.2" spec.add_dependency "logging", "~> 2.2" - spec.add_dependency "minitar", ">= 0.6", "< 2.0" spec.add_dependency "net-scp", ">= 1.2", "< 5.0" spec.add_dependency "net-ssh", ">= 4.0", "< 8.0" spec.add_dependency "net-ssh-krb", "~> 0.5" @@ -71,4 +70,11 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake", ">= 12.0", "< 14" spec.add_development_dependency "rspec", ">= 3.0", "< 4" spec.add_development_dependency 'voxpupuli-rubocop', '~> 4.2.0' + + platform = RUBY_PLATFORM + if platform =~ /mingw|mswin/ + spec.add_dependency('minitar', '~> 0.9') + else + spec.add_dependency "minitar", ">= 0.6", "< 2.0" + end end diff --git a/rakelib/tests.rake b/rakelib/tests.rake index b7e2ae9e..a9cc83c8 100644 --- a/rakelib/tests.rake +++ b/rakelib/tests.rake @@ -131,8 +131,7 @@ begin desc '' RSpec::Core::RakeTask.new(:integration) do |t| - t.pattern = "spec/integration/**/*_spec.rb" - t.exclude_pattern = "spec/integration/transport/*" + t.pattern = "spec/integration/lookup_spec.rb" exclude = %w[apply bash docker puppetdb ssh sudo winrm_agentless] t.rspec_opts = generate_opts(exclude_tags: exclude) end diff --git a/scripts/ci.ps1 b/scripts/ci.ps1 index 85cdff43..939f271a 100644 --- a/scripts/ci.ps1 +++ b/scripts/ci.ps1 @@ -155,4 +155,5 @@ Enable-PSRemoting Set-WSManQuickConfig -Force Set-WinRMHostConfiguration Test-WinRMConfiguration @User | Out-Null +winrm enumerate winrm/config/Listener Add-Content -Path $ENV:GITHUB_ENV -Value "BOLT_WINRM_PASSWORD=$pass" diff --git a/spec/integration/apply_spec.rb b/spec/integration/apply_spec.rb index aad2c2e9..2872875e 100644 --- a/spec/integration/apply_spec.rb +++ b/spec/integration/apply_spec.rb @@ -34,7 +34,8 @@ # The following are run with both *nix and Windows targets. shared_examples 'agentful tests' do |targets| - it 'runs a ruby task' do + it 'lists all modules & runs a ruby task' do + run_cli_json(%w[module show], project: project) results = run_cli_json(%W[task run basic::ruby_task -t #{targets}], project: project) results['items'].each do |result| diff --git a/spec/integration/lookup_spec.rb b/spec/integration/lookup_spec.rb index cfef94d1..d696828e 100644 --- a/spec/integration/lookup_spec.rb +++ b/spec/integration/lookup_spec.rb @@ -24,128 +24,14 @@ %W[plan run #{plan} --project #{project} --hiera-config #{hiera_config}] } - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=environment]) - expect(result).to eq('environment data/common.yaml') - end - - it 'accepts a default value' do - options = { 'default_value' => 'default' }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default') - end - - it 'accepts a default values hash' do - options = { 'default_values_hash' => { 'foo::bar::baz' => 'default' } }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default') - end - - it 'searches the module hierarchy' do - result = run_cli_json(cli_command + %w[key=test::module]) - expect(result).to eq('test::module modules/test/data/common.yaml') - end - - it 'does not search the module hierarchy in a different namespace' do - result = run_cli_json(cli_command + %w[key=foo::namespace]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Function lookup\(\) did not find a value for the name 'foo::namespace'/ - ) - end - - it 'does not search for global keys in the module hierarchy' do - result = run_cli_json(cli_command + %w[key=global]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Function lookup\(\) did not find a value for the name 'global'/ - ) - end - - it 'merges values' do - options = { 'merge' => 'deep' }.to_json - result = run_cli_json(cli_command + %W[key=test::merge options=#{options}]) - expect(result).to match( - 'bolt' => { 'key1' => 'value1', 'key2' => 'value1' }, - 'puppet' => { 'key1' => 'value1' } - ) - end - - context 'with a lambda' do - let(:plan) { 'test::lookup_lambda' } - - it 'returns a value from the lambda' do - result = run_cli_json(cli_command + %w[key=foo::bar::baz]) - expect(result).to eq('foo bar baz lambda') - end - - it 'returns a value from the lambda over the default value' do - options = { 'default_value' => 'default' }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('foo bar baz lambda') - end - - it 'returns a value from the default values hash over the lambda' do - options = { 'default_values_hash' => { 'foo::bar::baz' => 'default values hash' } }.to_json - result = run_cli_json(cli_command + %W[key=foo::bar::baz options=#{options}]) - expect(result).to eq('default values hash') - end - end - - context 'when context is not available' do - let(:hiera_config) { File.join(project, 'hiera_interpolations.yaml') } - - it 'returns the default value' do - result = run_cli_json(cli_command + %w[key=test::interpolations]) - expect(result).to eq('test::interpolations data/common.yaml') - end - end - - context 'with a builtin backend' do - # Load pkcs7 keys as environment variables - around(:each) do |example| - env_vars = { - 'BOLT_PKCS7_PUBLIC_KEY' => File.read(File.expand_path('../keys/public_key.pkcs7.pem', project)), - 'BOLT_PKCS7_PRIVATE_KEY' => File.read(File.expand_path('../keys/private_key.pkcs7.pem', project)) - } - - with_env_vars(env_vars) do - example.run - end - end - - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=test::secret]) - expect(result).to eq('test::secret data/secret.eyaml') - end - end - - context 'with a custom backend' do - it 'returns a value' do - result = run_cli_json(cli_command + %w[key=test::custom]) - expect(result).to eq('test::custom data/custom.txt') - end - end - - context 'with a missing backend' do - let(:hiera_config) { File.join(project, 'hiera_missing_backend.yaml') } - - it 'returns an error' do - result = run_cli_json(cli_command + %w[key=test::backends]) - expect(result).to include( - 'kind' => 'bolt/pal-error', - 'msg' => /Unable to find 'data_hash' function named 'missing_backend'/ - ) - end - end - context 'with plan_hiera' do let(:hiera_config) { File.join(project, 'plan_hiera.yaml') } let(:plan) { 'test::plan_lookup' } let(:uri) { 'localhost' } it 'uses plan_hierarchy outside apply block, and hierarchy in apply block' do - result = run_cli_json(cli_command + %W[-t #{uri}]) + result = run_cli_json(cli_command + %W[-t #{uri} --log-level debug --trace --verbose]) + pp result expect(result['outside_apply']).to eq('goes the weasel') expect(result['in_apply'].keys).to include('Notify[tarts]') end @@ -165,155 +51,4 @@ end end end - - context 'command', ssh: true do - include BoltSpec::Conn - - context 'without --plan-hierarchy' do - let(:opts) { %W[--project #{project} --hiera-config #{hiera_config} -t #{target}] } - let(:target) { 'puppet_7_node' } - - around(:each) do |example| - inventory = docker_inventory.merge('vars' => { 'lookup' => 'var' }).to_json - - env_vars = { - 'BOLT_INVENTORY' => inventory, - 'BOLT_PKCS7_PUBLIC_KEY' => File.read(File.expand_path('../keys/public_key.pkcs7.pem', project)), - 'BOLT_PKCS7_PRIVATE_KEY' => File.read(File.expand_path('../keys/private_key.pkcs7.pem', project)) - } - - with_env_vars(env_vars) do - example.run - end - end - - it 'looks up a value' do - result, = run_cli_json(%w[lookup environment] + opts) - expect(result).to include( - 'object' => 'environment', - 'value' => { 'value' => 'environment data/common.yaml' } - ) - end - - context 'with interpolations' do - let(:hiera_config) { File.join(project, 'hiera_interpolations.yaml') } - - it 'looks up a value with facts' do - result, = run_cli_json(%w[lookup os] + opts) - expect(result).to include( - 'object' => 'os', - 'value' => { 'value' => 'os data/os/Ubuntu.yaml' } - ) - end - - it 'looks up a value with vars' do - result, = run_cli_json(%w[lookup var] + opts) - expect(result).to include( - 'object' => 'var', - 'value' => { 'value' => 'var data/var.yaml' } - ) - end - - it 'looks up a value with a trusted fact' do - result, = run_cli_json(%w[lookup certname] + opts) - expect(result).to include( - 'object' => 'certname', - 'value' => { 'value' => 'certname data/puppet_7_node.yaml' } - ) - end - - context 'with plan vars interpolated' do - let(:hiera_config) { File.join(project, 'hiera_plan_var.yaml') } - - it 'looks up a value with plan vars interpolated' do - result = run_cli_json(%w[lookup plan_var plan_var=plan_var] + opts) - expect(result.first['value']['value']).to eq("plan_var data/plan_var.yaml") - end - end - end - - it 'looks up a value in the module hierarchy' do - result, = run_cli_json(%w[lookup test::module] + opts) - expect(result).to include( - 'object' => 'test::module', - 'value' => { 'value' => 'test::module modules/test/data/common.yaml' } - ) - end - - it 'errors with a missing key' do - result, = run_cli_json(%w[lookup fizzbuzz] + opts) - - expect(result.dig('value', '_error', 'msg')).to eq( - "Function lookup() did not find a value for the name 'fizzbuzz'" - ) - end - - it 'looks up a value with a built-in backend' do - result, = run_cli_json(%w[lookup test::secret] + opts) - expect(result).to include( - 'object' => 'test::secret', - 'value' => { 'value' => 'test::secret data/secret.eyaml' } - ) - end - - it 'looks up a value with a custom backend' do - result, = run_cli_json(%w[lookup test::custom] + opts) - expect(result).to include( - 'object' => 'test::custom', - 'value' => { 'value' => 'test::custom data/custom.txt' } - ) - end - - context 'with a missing backend' do - let(:hiera_config) { File.join(project, 'hiera_missing_backend.yaml') } - - it 'returns an error' do - result, = run_cli_json(%w[lookup test::backends] + opts) - expect(result.dig('value', '_error', 'msg')).to match( - /Unable to find 'data_hash' function named 'missing_backend'/ - ) - end - end - - it 'looks up the same value as a plan lookup' do - plan_result = run_cli_json(%W[plan run #{plan} key=environment] + opts) - command_result, = run_cli_json(%w[lookup environment] + opts) - - expect(command_result.dig('value', 'value')).to eq(plan_result) - end - end - - context 'with --plan-hierarchy' do - let(:hiera_config) { File.join(project, 'plan_hiera.yaml') } - let(:opts) { %W[--project #{project} --hiera-config #{hiera_config} --plan-hierarchy] } - - it 'looks up a value' do - result = run_cli_json(%w[lookup pop] + opts) - expect(result).to eq("goes the weasel") - end - - context 'with plan variable interpolations interpolations' do - let(:hiera_config) { File.join(project, 'plan_hiera_var.yaml') } - - it 'looks up a value with vars interpolated' do - result = run_cli_json(%w[lookup var interpolate=var] + opts) - expect(result).to eq("var data/var.yaml") - end - end - - context 'with invalid plan_hierarchy' do - let(:hiera_config) { File.join(project, 'plan_hiera_facts.yaml') } - - it 'returns the default value' do - result = run_cli_json(%w[lookup environment] + opts) - expect(result).to eq("environment data/common.yaml") - end - end - - it 'errors with a missing key' do - expect { run_cli_json(%w[lookup fizzbuzz] + opts) } - .to raise_error(Bolt::PAL::PALError, "Function lookup() did not find a value for the name 'fizzbuzz'") - end - end - end end