simp-rake-helpers 5.11.6 → 5.12.0

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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +1 -1
  5. data/lib/simp/command_utils.rb +21 -0
  6. data/lib/simp/local_gpg_signing_key.rb +128 -79
  7. data/lib/simp/rake.rb +3 -17
  8. data/lib/simp/rake/build/pkg.rb +102 -40
  9. data/lib/simp/rake/helpers/version.rb +1 -1
  10. data/lib/simp/rake/pkg.rb +5 -1
  11. data/lib/simp/rake/pupmod/helpers.rb +2 -0
  12. data/lib/simp/rake/rubygem.rb +5 -1
  13. data/lib/simp/rpm.rb +10 -127
  14. data/lib/simp/rpm_signer.rb +321 -0
  15. data/spec/acceptance/00_pkg_rpm_custom_scriptlets_spec.rb +18 -19
  16. data/spec/acceptance/10_pkg_rpm_spec.rb +46 -48
  17. data/spec/acceptance/50_local_gpg_signing_key_spec.rb +7 -3
  18. data/spec/acceptance/55_build_pkg_signing_spec.rb +293 -42
  19. data/spec/acceptance/files/testpackage/README +8 -0
  20. data/spec/acceptance/files/testpackage/spec/classes/init_spec.rb +1 -0
  21. data/spec/acceptance/files/testpackage/spec/files/mock_something.rb +3 -0
  22. data/spec/acceptance/files/testpackage/utils/convert_v1_to_v2.rb +3 -0
  23. data/spec/acceptance/nodesets/default.yml +15 -2
  24. data/spec/acceptance/support/build_project_helpers.rb +32 -8
  25. data/spec/lib/simp/command_utils_spec.rb +29 -0
  26. data/spec/lib/simp/local_gpg_signing_key_spec.rb.beaker-only +115 -18
  27. data/spec/lib/simp/rake/pupmod/fixtures/simpmod/README.md +2 -2
  28. data/spec/lib/simp/rpm_signer_spec.rb +98 -0
  29. data/spec/lib/simp/rpm_spec.rb +0 -6
  30. metadata +12 -67
  31. data/.travis.yml +0 -41
  32. data/spec/acceptance/20_pkg_rpm_upgrade_spec.rb +0 -236
  33. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/CHANGELOG +0 -2
  34. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/Rakefile +0 -3
  35. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/custom/overrides +0 -14
  36. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/requires +0 -1
  37. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/metadata.json +0 -33
  38. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/CHANGELOG +0 -2
  39. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/Rakefile +0 -3
  40. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/custom/overrides +0 -14
  41. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/requires +0 -1
  42. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/metadata.json +0 -33
  43. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/CHANGELOG +0 -2
  44. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/Rakefile +0 -3
  45. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/build/rpm_metadata/requires +0 -1
  46. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/metadata.json +0 -33
  47. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/CHANGELOG +0 -2
  48. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/Rakefile +0 -3
  49. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/build/rpm_metadata/requires +0 -1
  50. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/metadata.json +0 -33
  51. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/CHANGELOG +0 -2
  52. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/Rakefile +0 -3
  53. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/custom/overrides +0 -14
  54. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/requires +0 -1
  55. data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/metadata.json +0 -33
  56. data/spec/acceptance/files/mock_packages/pupmod-puppetlabs-stdlib.spec +0 -32
  57. data/spec/acceptance/files/mock_packages/pupmod-simp-foo.spec +0 -32
  58. data/spec/acceptance/files/mock_packages/pupmod-simp-simplib.spec +0 -32
  59. data/spec/acceptance/files/mock_packages/rpmbuild.sh +0 -25
  60. data/spec/acceptance/files/mock_packages/simp-adapter.spec +0 -43
  61. data/spec/acceptance/files/mock_packages/simp-adapter/etc/simp/adapter_config.yaml +0 -3
  62. data/spec/acceptance/files/mock_packages/simp-adapter/usr/local/sbin/simp_rpm_helper +0 -495
  63. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/CHANGELOG +0 -2
  64. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/Rakefile +0 -3
  65. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/build/rpm_metadata/requires +0 -2
  66. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/data/os/CentOS.yaml +0 -2
  67. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/data/os/RedHat.yaml +0 -2
  68. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/hiera.yaml +0 -14
  69. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/manifests/init.pp +0 -2
  70. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/metadata.json +0 -37
  71. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/CHANGELOG +0 -5
  72. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/Rakefile +0 -3
  73. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/build/rpm_metadata/requires +0 -2
  74. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/data/os/CentOS.yaml +0 -2
  75. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/data/os/RedHat.yaml +0 -2
  76. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/hiera.yaml +0 -14
  77. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/manifests/init.pp +0 -3
  78. data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/metadata.json +0 -37
  79. data/spec/lib/simp/ci/files/job_broken_link_nodeset/spec/acceptance/suites/default/nodesets +0 -1
  80. data/spec/lib/simp/ci/files/job_invalid_nodeset/spec/acceptance/suites/default/nodesets +0 -1
  81. data/spec/lib/simp/ci/files/job_invalid_suite/spec/acceptance/suites/default/nodesets +0 -1
  82. data/spec/lib/simp/ci/files/job_missing_nodeset/spec/acceptance/suites/default/nodesets +0 -1
  83. data/spec/lib/simp/ci/files/job_missing_suite_and_nodeset/spec/acceptance/suites/default/nodesets +0 -1
  84. data/spec/lib/simp/ci/files/multiple_invalid_jobs/spec/acceptance/suites/default/nodesets +0 -1
  85. data/spec/lib/simp/ci/files/multiple_valid_jobs/spec/acceptance/suites/default/nodesets +0 -1
  86. data/spec/lib/simp/ci/files/no_gitlab_config_with_tests/spec/acceptance/suites/default/nodesets +0 -1
  87. data/spec/lib/simp/ci/files/no_gitlab_config_without_tests/spec/acceptance/suites/default/nodesets +0 -1
  88. data/spec/lib/simp/ci/files/suite_skeleton_only/spec/acceptance/nodesets/default.yml +0 -1
  89. data/spec/lib/simp/ci/files/suite_skeleton_only/spec/acceptance/suites/default/nodesets +0 -1
  90. data/spec/lib/simp/ci/files/valid_job_nodeset_dir_link/spec/acceptance/suites/default/nodesets +0 -1
  91. data/spec/lib/simp/ci/files/valid_job_nodeset_link/spec/acceptance/suites/default/nodesets/default.yml +0 -1
  92. data/spec/lib/simp/files/build/testpackage.spec +0 -1
  93. data/spec/lib/simp/rake/pupmod/fixtures/simpmod/spec/acceptance/nodesets/default.yml +0 -1
  94. data/spec/lib/simp/rake/pupmod/fixtures/simpmod/spec/acceptance/suites/default/nodesets +0 -1
@@ -0,0 +1,8 @@
1
+ The following scripts with problematic shebangs have their execute bits set in
2
+ order to trigger the brp-mangle-shebangs script during an RPM build in EL8:
3
+
4
+ * spec/classes/init_spec.rb: #!/usr/bin/env rspec => #!/usr/bin/rspec
5
+ * spec/files/mock_something.rb: #!/usr/bin/env ruby => #!/usr/bin/ruby
6
+ * utils/convert_v1_to_v2.rb: #!/usr/bin/env ruby => #!/usr/bin/ruby
7
+
8
+ *** Do not change their execute bits in Git! ***
@@ -0,0 +1 @@
1
+ #!/usr/bin/env rspec
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ #This is a mock executable for something
3
+ puts 'hello world'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ # convert from version 1 to version 2
3
+ puts "Running #{File.basename(__FILE__)}"
@@ -29,11 +29,24 @@ CONFIG:
29
29
  password: root
30
30
  auth_methods:
31
31
  - password
32
+ docker_preserve_image: true
33
+ # This is necessary for pretty much all containers
32
34
  docker_cap_add:
33
35
  - AUDIT_WRITE
34
- docker_preserve_image: true
35
36
  mount_folders:
36
37
  host_files:
37
38
  host_path: ./
38
39
  container_path: /host_files
39
- opts: 'z'
40
+ # All items below this point are required for systemd
41
+ cgroup:
42
+ host_path: /sys/fs/cgroup
43
+ container_path: /sys/fs/cgroup
44
+ opts: 'ro'
45
+ dockeropts:
46
+ HostConfig:
47
+ Tmpfs:
48
+ '/run': 'rw,noexec,nosuid,nodev,size=65536k'
49
+ '/run/lock': 'rw,noexec,nosuid,nodev,size=65536k'
50
+ '/tmp': 'rw,exec,nosuid,nodev,size=65536k'
51
+ '/sys/fs/cgroup/systemd': 'rw,size=65536k'
52
+ '/var/log/journal': 'rw,noexec,nodev,nosuid,size=65536k'
@@ -57,16 +57,40 @@ module Simp::BeakerHelpers::SimpRakeHelpers::BuildProjectHelpers
57
57
  # Scans a host path for the 'SIMP Development' GPG key and returns its Key ID
58
58
  #
59
59
  # @param [Host, String, Symbol] host Beaker host
60
- # @param [Hash{Symbol=>String}] opts Beaker options Hash for `#on` ({})
61
- # @param [String] proj_dir Absolute path to the parent project directory
60
+ # @param [String] key_dir Absolute path to GPG key dir
62
61
  # @param [Hash{Symbol=>String}] opts Beaker options Hash for `#on` ({})
63
62
  # @return [String] GPG dev signing Key ID
64
63
  #
65
- def dev_signing_key_id(host, proj_dir, opts = {})
66
- key_dir = distribution_dir(host, proj_dir, opts) + '/build_keys/dev'
67
- res = on(host, %(#{run_cmd} "gpg --list-keys --fingerprint --homedir='#{key_dir}' 'SIMP Development'"))
68
- lines = res.stdout.lines.select { |x| x =~ %r{Key fingerprint =} }
69
- raise "No 'SIMP Development' GPG keys found under ''" if lines.empty?
70
- lines.first.strip.split(%r{\s+})[-4..-1].join.downcase
64
+ def dev_signing_key_id(host, key_dir, opts = {})
65
+ # NOTE: This search uses a substring match on 'SIMP Development'.
66
+ res = on(host, %(#{run_cmd} "gpg --with-colons --fingerprint --homedir='#{key_dir}' 'SIMP Development'"), opts)
67
+ pub_lines = res.stdout.lines.select { |x| x.start_with?('pub') }
68
+ raise "No 'SIMP Development' GPG keys found in '#{key_dir}'" if pub_lines.empty?
69
+ pub_lines.first.split(':')[4].downcase
70
+ end
71
+
72
+ # Returns true when a gpg-agent daemon using the specified GPG home directory
73
+ # (aka key directory) is running.
74
+ #
75
+ # @param [Host, String, Symbol] host Beaker host
76
+ # @param [String] gpg_homedir Absolute path to GPG home dir
77
+ def gpg_agent_running?(host, gpg_homedir)
78
+
79
+ # This check is being used in tests to verify no gpg-agent for gpg_homedir
80
+ # is running. On slow VMs, the gpg-agent can take some time to shutdown.
81
+ # So wait up to 20 seconds for gpg-agent to shutdown before finalizing
82
+ # gpg-agent status to be reported.
83
+
84
+ retries = 20
85
+ agent_exists = true
86
+ while (agent_exists || (retries > 0))
87
+ result = on(host, "pgrep -c -f 'gpg-agent.*homedir.*#{gpg_homedir}'", :accept_all_exit_codes => true)
88
+ agent_exists = (result.stdout.strip != '0')
89
+ break unless agent_exists
90
+ sleep 1
91
+ retries -= 1
92
+ end
93
+
94
+ agent_exists
71
95
  end
72
96
  end
@@ -0,0 +1,29 @@
1
+ require 'simp/command_utils'
2
+ require 'spec_helper'
3
+
4
+ describe Simp::CommandUtils do
5
+ RSpec.configure do |c|
6
+ c.include Simp::CommandUtils
7
+ end
8
+
9
+ describe '.which' do
10
+ it 'should return location of command that exists' do
11
+ expect(Facter::Core::Execution).to receive(:which).with('ls').and_return('/usr/bin/ls')
12
+ expect( which('ls') ).to eq('/usr/bin/ls')
13
+ end
14
+
15
+ it 'should return nil if command does not exist by default' do
16
+ expect( which('/does/not/exist/command') ).to be nil
17
+ end
18
+
19
+ it 'should fail if command does not exist if fail=true' do
20
+ expect{ which('/does/not/exist/command', true) }.to raise_error(
21
+ RuntimeError, /Warning: Command \/does\/not\/exist\/command not found/)
22
+ end
23
+
24
+ it 'should cache commands' do
25
+ allow(Facter::Core::Execution).to receive(:which).with('ls').and_return('/path1/ls', '/path2/ls')
26
+ expect( which('ls') ).to eq('/path1/ls')
27
+ end
28
+ end
29
+ end
@@ -1,14 +1,24 @@
1
1
  require 'simp/local_gpg_signing_key'
2
2
  require 'spec_helper'
3
3
  require 'fileutils'
4
+ require 'timeout'
4
5
  require 'tmpdir'
5
6
 
7
+
8
+ def get_key_id(keydir, key_email)
9
+ key_id = nil
10
+ key_info = `gpg --with-colons --homedir=#{keydir} --list-keys '<#{key_email}>' 2>&1 | grep ^pub:`
11
+ unless key_info.strip.empty?
12
+ key_id = key_info.split(':')[4]
13
+ end
14
+ end
15
+
6
16
  describe Simp::LocalGpgSigningKey do
7
17
  include FileUtils
8
18
 
9
19
  before :all do
10
20
  TMP_DIR = Dir.mktmpdir('spec_test__simp_local_gpg_signing_key')
11
- TMP_DEV_DIR = File.join(TMP_DIR, 'dev')
21
+ TMP_DEV_KEYDIR = File.join(TMP_DIR, 'dev')
12
22
  OPTS = {verbose: ENV['VERBOSE'].to_s =~ /^(yes|true)$/ }
13
23
 
14
24
  mkdir_p TMP_DIR
@@ -24,9 +34,17 @@ describe Simp::LocalGpgSigningKey do
24
34
  ENV['GPG_AGENT_INFO'] = ORIGINAL_GPG_AGENT_INFO
25
35
  end
26
36
 
37
+ let(:gpg_keydir) { TMP_DEV_KEYDIR }
38
+ let(:gpg_email_name) { 'gatekeeper@simp.development.key' }
39
+ let(:opts) { OPTS }
40
+
27
41
  shared_examples_for 'it just generated a local gpg signing key' do
28
- it 'creates a local gpg-agent' do
29
- expect(agent_info.reject{|x| x.nil?}.keys).to include(:info, :socket, :pid)
42
+ it 'has the key in the keyring' do
43
+ expect(get_key_id(gpg_keydir, gpg_email_name)).to_not be_nil
44
+ end
45
+
46
+ it 'had created a local gpg-agent' do
47
+ expect(agent_info.reject{|x| x.nil?}.keys).to include(:socket, :pid)
30
48
  end
31
49
 
32
50
  it 'had a gpg-agent socket' do
@@ -35,62 +53,141 @@ describe Simp::LocalGpgSigningKey do
35
53
  end
36
54
 
37
55
  it 'has killed the local gpg-agent' do
56
+ begin
57
+ # it may take some time for the local gpg-agent to die
58
+ Timeout::timeout(30) do
59
+ done = !File.exist?(agent_info[:socket])
60
+ until(done)
61
+ sleep(2)
62
+ done = !File.exist?(agent_info[:socket])
63
+ end
64
+ end
65
+ rescue Timeout::Error
66
+ puts "agent_info = #{agent_info}"
67
+ puts "gpg-agent processes running:\n#{`pgrep -f gpg-agent`}"
68
+ end
69
+
38
70
  expect(File.exist?(agent_info[:socket])).to be false
39
71
  end
40
72
  end
41
73
 
42
-
43
74
  shared_examples_for 'a valid gpg signing key environment' do
44
- it 'has a local GPG signing key' do
45
- Dir.chdir(TMP_DEV_DIR) { expect(Dir['*']).to include('RPM-GPG-KEY-SIMP-Dev') }
75
+ it 'has an exported local GPG signing key' do
76
+ Dir.chdir(gpg_keydir) { expect(Dir['*']).to include('RPM-GPG-KEY-SIMP-Dev') }
46
77
  end
47
78
 
48
- it 'has a populated a gpg-agent directory' do
49
- Dir.chdir(TMP_DEV_DIR) do |_dir|
50
- expect(Dir['*'].sort).to include(
51
- 'gengpgkey',
52
- 'pubring.gpg',
53
- )
54
- end
79
+ it 'has a keygen params file with info required for package signing' do
80
+ params_file = File.join(gpg_keydir, 'gengpgkey')
81
+ expect(File.exist?(params_file)).to be true
82
+
83
+ content = File.read(params_file)
84
+ expect(content).to match(/^Passphrase: .*$/)
85
+ expect(content).to match(/^Name-Email: #{gpg_email_name}$/)
55
86
  end
56
87
  end
57
88
 
58
89
  shared_examples_for 'it encountered an unexpired local gpg signing key' do
59
90
  it 'reuses an unexpired local gpg signing key' do
60
- expect{described_class.new(TMP_DEV_DIR,OPTS).ensure_key}.to output(
91
+ expect{described_class.new(gpg_keydir,opts).ensure_key}.to output(
61
92
  /^GPG key \(gatekeeper@simp\.development\.key\) will expire in 14 days\./
62
93
  ).to_stdout
94
+
95
+ expect(get_key_id(gpg_keydir, gpg_email_name)).to eq original_key_id
63
96
  end
64
97
 
65
98
  it 'reuses an unexpired local gpg signing key' do
66
- expect{described_class.new(TMP_DEV_DIR,OPTS).ensure_key}.to output(
99
+ expect{described_class.new(gpg_keydir,opts).ensure_key}.to output(
67
100
  /^GPG key \(gatekeeper@simp\.development\.key\) will expire in 14 days\./
68
101
  ).to_stdout
102
+
103
+ expect(get_key_id(gpg_keydir, gpg_email_name)).to eq original_key_id
69
104
  end
70
105
  end
71
106
 
72
107
  context '#ensure_key' do
73
108
  before :all do
74
- rm_rf TMP_DEV_DIR
109
+ rm_rf TMP_DEV_KEYDIR
75
110
  ENV['GPG_AGENT_INFO'] = nil
76
111
  end
77
112
 
113
+
78
114
  context 'when run from scratch' do
79
115
  before :all do
80
- FIRST_RUN_AGENT_INFO = described_class.new(TMP_DEV_DIR,OPTS).ensure_key
116
+ FIRST_RUN_AGENT_INFO = described_class.new(TMP_DEV_KEYDIR,OPTS).ensure_key
81
117
  end
118
+
82
119
  let(:agent_info){ FIRST_RUN_AGENT_INFO }
120
+
83
121
  it_behaves_like 'it just generated a local gpg signing key'
84
122
  it_behaves_like 'a valid gpg signing key environment'
85
123
  end
86
124
 
87
125
  context 'when run again' do
88
126
  before :all do
89
- SECOND_RUN_AGENT_INFO = described_class.new(TMP_DEV_DIR,OPTS).ensure_key
127
+ SECOND_RUN_AGENT_INFO = described_class.new(TMP_DEV_KEYDIR,OPTS).ensure_key
90
128
  end
129
+
91
130
  let(:agent_info){ SECOND_RUN_AGENT_INFO }
131
+ let(:original_key_id) { get_key_id(gpg_keydir, gpg_email_name) }
132
+
92
133
  it_behaves_like 'it encountered an unexpired local gpg signing key'
93
134
  it_behaves_like 'a valid gpg signing key environment'
94
135
  end
95
136
  end
137
+
138
+ context '#gpg_agent_info' do
139
+ before :all do
140
+ rm_rf TMP_DEV_KEYDIR
141
+ end
142
+
143
+ # other use cases already tested in ensure_key tests
144
+ it 'returns nil when no gpg agent env file exists' do
145
+ expect(described_class.new(gpg_keydir,opts).gpg_agent_info).to be_nil
146
+ end
147
+ end
148
+
149
+ context '#dev_key_days_left' do
150
+ before :all do
151
+ rm_rf TMP_DEV_KEYDIR
152
+ end
153
+
154
+ let(:gpg_cmd) { "gpg --with-colons --homedir=#{gpg_keydir} --list-keys '<#{gpg_email_name}>' 2>&1" }
155
+
156
+ it 'returns 0 when key is not found' do
157
+ expect(described_class.new(gpg_keydir,opts).dev_key_days_left).to eq 0
158
+ end
159
+
160
+ it 'returns 0 when key is expired' do
161
+ generator = described_class.new(gpg_keydir,opts)
162
+ output = <<~EOM
163
+ tru::1:1521838828:0:3:1:5
164
+ pub:e:4096:1:722B97A808E7DAEA:1521838554:1523048154::-:::sc::::::23::0:
165
+ fpr:::::::::5DD3E8D45C99780DCA7D0B83722B97A808E7DAEA:
166
+ uid:e::::1521838554::773C55CA511CCE31244D86D4AB70F6499024695F::SIMP Development (Development key 1521838554) <gatekeeper@simp.development.key>::::::::::0:
167
+ EOM
168
+ expect(generator).to receive(:`).with(gpg_cmd).and_return(output)
169
+
170
+ expect(generator.dev_key_days_left).to eq 0
171
+ end
172
+
173
+ it 'returns # days left when unexpired key is found with ISO 8601 date' do
174
+ generator = described_class.new(gpg_keydir,opts)
175
+
176
+ require 'date'
177
+ creation_date = DateTime.now - 5
178
+ expiration_date = creation_date + 14
179
+ creation_str = creation_date.iso8601.gsub(/:|-/,'')
180
+ expiration_str = expiration_date.iso8601.gsub(/:|-/,'')
181
+
182
+ output = <<~EOM
183
+ tru::1:1521838828:0:3:1:5
184
+ pub:u:4096:1:722B97A808E7DAEA:#{creation_str}:#{expiration_str}::-:::sc::::::23::0:
185
+ fpr:::::::::5DD3E8D45C99780DCA7D0B83722B97A808E7DAEA:
186
+ uid:e::::1521838554::773C55CA511CCE31244D86D4AB70F6499024695F::SIMP Development (Development key 1521838554) <gatekeeper@simp.development.key>::::::::::0:
187
+ EOM
188
+ expect(generator).to receive(:`).with(gpg_cmd).and_return(output)
189
+
190
+ expect(generator.dev_key_days_left).to eq 9
191
+ end
192
+ end
96
193
  end
@@ -21,7 +21,7 @@
21
21
 
22
22
  Start with a one- or two-sentence summary of what the module does and/or what
23
23
  problem it solves. This is your 30-second elevator pitch for your module.
24
- Consider including OS and Puppet version compatability, and any other
24
+ Consider including OS and Puppet version compatibility, and any other
25
25
  information users will need to quickly assess the module's viability within
26
26
  their environment.
27
27
 
@@ -33,7 +33,7 @@ management, etc.), this is the time to mention it.
33
33
  ### This is a SIMP module
34
34
 
35
35
  This module is a component of the [System Integrity Management
36
- Platform](https://github.com/NationalSecurityAgency/SIMP), a
36
+ Platform](https://simp-project.com), a
37
37
  compliance-management framework built on Puppet.
38
38
 
39
39
  If you find any issues, they may be submitted to our [bug
@@ -0,0 +1,98 @@
1
+ require 'simp/rpm_signer'
2
+ require 'spec_helper'
3
+ require 'fileutils'
4
+ require 'tmpdir'
5
+
6
+
7
+ describe Simp::RpmSigner do
8
+
9
+ before :all do
10
+ @tmp_dir = Dir.mktmpdir('spec_test__rpm_signer')
11
+ @gpg_keydir = File.join(@tmp_dir, 'dev')
12
+ end
13
+
14
+ after :all do
15
+ FileUtils.remove_entry_secure(@tmp_dir)
16
+ end
17
+
18
+ let(:verbose) { ENV['VERBOSE'].to_s =~ /^(yes|true)$/ }
19
+ let(:gpg_email_name) { 'gatekeeper@simp.development.key' }
20
+ let(:passphrase) { 'dev_passphrase' }
21
+ let(:key_id) { '722B97A808E7DAEA' }
22
+ let(:key_size) { 4096 }
23
+ let(:key_info) { {
24
+ :dir => @gpg_keydir,
25
+ :name => gpg_email_name,
26
+ :key_id => key_id,
27
+ :key_size => key_size,
28
+ :password => passphrase
29
+ } }
30
+
31
+ let(:gpg_cmd) { "gpg --with-colons --homedir=#{@gpg_keydir} --list-keys '<#{gpg_email_name}>' 2>&1" }
32
+ let(:key_list_output) { <<~EOM
33
+ tru::1:1521838828:0:3:1:5
34
+ pub:e:4096:1:722B97A808E7DAEA:1521838554:1523048154::-:::sc::::::23::0:
35
+ fpr:::::::::5DD3E8D45C99780DCA7D0B83722B97A808E7DAEA:
36
+ uid:e::::1521838554::773C55CA511CCE31244D86D4AB70F6499024695F::SIMP Development (Development key 1521838554) <gatekeeper@simp.development.key>::::::::::0:
37
+ EOM
38
+ }
39
+
40
+ # The bulk of load_key is tested in the acceptance test. These tests are
41
+ # a few edge cases.
42
+ context '.load_key' do
43
+ context 'key info missing from files' do
44
+ before :each do
45
+ allow(Simp::RpmSigner).to receive(:which).with('gpg').and_return('/usr/bin/gpg')
46
+ FileUtils.mkdir_p(@gpg_keydir)
47
+ end
48
+
49
+ after :each do
50
+ FileUtils.rm_rf(@gpg_keydir)
51
+ Simp::RpmSigner.clear_gpg_keys_cache
52
+ end
53
+
54
+ it 'should prompt user for key email and passphrase when not in files' do
55
+ expect($stdin).to receive(:gets).and_return(gpg_email_name, passphrase)
56
+ expect(Simp::RpmSigner).to receive(:`).with(gpg_cmd).and_return(key_list_output)
57
+
58
+ expect(Simp::RpmSigner.load_key(@gpg_keydir, verbose)).to eq (key_info)
59
+
60
+ # verifies returning info from the cache, otherwise user would be prompted again
61
+ # and expectation on $stdin would fail
62
+ expect(Simp::RpmSigner.load_key(@gpg_keydir, verbose)).to eq (key_info)
63
+ end
64
+
65
+ it "should read the passphrase from the 'password' file" do
66
+ File.open(File.join(@gpg_keydir, 'password'),'w') { |file| file.puts passphrase }
67
+ expect($stdin).to receive(:gets).and_return(gpg_email_name)
68
+ expect(Simp::RpmSigner).to receive(:`).with(gpg_cmd).and_return(key_list_output)
69
+
70
+ expect(Simp::RpmSigner.load_key(@gpg_keydir, verbose)).to eq (key_info)
71
+ end
72
+ end
73
+
74
+ context 'errors' do
75
+ it 'should fail when gpg does not exist' do
76
+ expect(Simp::RpmSigner).to receive(:which).with('gpg').and_return(nil)
77
+ expect { Simp::RpmSigner.load_key(@gpg_keydir, verbose) }.to raise_error(
78
+ /Cannot sign RPMs without 'gpg'/)
79
+ end
80
+
81
+ it 'should fail when keydir does not exist' do
82
+ expect(Simp::RpmSigner).to receive(:which).with('gpg').and_return('/usr/bin/gpg')
83
+ expect { Simp::RpmSigner.load_key(@gpg_keydir, verbose) }.to raise_error(
84
+ /Could not find GPG keydir/)
85
+ end
86
+
87
+ it 'should fail when key info cannot be retrieved via gpg' do
88
+ FileUtils.mkdir_p(@gpg_keydir)
89
+ expect(Simp::RpmSigner).to receive(:which).with('gpg').and_return('/usr/bin/gpg')
90
+ expect($stdin).to receive(:gets).and_return(gpg_email_name, passphrase)
91
+ expect(Simp::RpmSigner).to receive(:`).with(gpg_cmd).and_return('')
92
+
93
+ expect { Simp::RpmSigner.load_key(@gpg_keydir, verbose) }.to raise_error(
94
+ /Error getting GPG key ID or Key size metadata/)
95
+ end
96
+ end
97
+ end
98
+ end