Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions .github/workflows/windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ permissions:
jobs:
integration:
name: Integration
runs-on: windows-latest
runs-on: windows-2025
strategy:
matrix:
ruby: [3.2]
Expand All @@ -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
Expand Down
8 changes: 7 additions & 1 deletion openbolt.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
3 changes: 1 addition & 2 deletions rakelib/tests.rake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions scripts/ci.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
3 changes: 2 additions & 1 deletion spec/integration/apply_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand All @@ -52,7 +53,7 @@
end
end

it 'succeeds with an empty hiera config' do

Check failure on line 56 in spec/integration/apply_spec.rb

View workflow job for this annotation

GitHub Actions / bolt apply (windows-2025, 3.4)

apply over winrm on Windows with Puppet Agents with puppet8 installed succeeds with an empty hiera config Failure/Error: expect(result['status']).to eq('success') TypeError: no implicit conversion of String into Integer Shared Example Group: "agentful tests" called from ./spec/integration/apply_spec.rb:447
results = run_cli_json(%W[plan run prep -t #{targets}], project: project)

results.each do |result|
Expand Down
269 changes: 2 additions & 267 deletions spec/integration/lookup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Loading