Class: Puppet::Provider::YumrepoMetadataKey
- Inherits:
-
Puppet::Provider
- Object
- Puppet::Provider
- Puppet::Provider::YumrepoMetadataKey
- Defined in:
- lib/puppet/provider/yumrepo_metadata_key.rb
Direct Known Subclasses
Class Method Summary collapse
-
.all_homes_for(_repo) ⇒ Array<String>
Includes stale homes from a repo’s previous source URL, which ‘destroy` sweeps too.
-
.canonical_key_digest(text) ⇒ Object
Canonicalise a key so semantically-equal keys hash equally: import ‘text` into a throwaway keyring, re-export it –armor, and SHA256 the result.
-
.export_key(_home, _fingerprint) ⇒ String?
The stored key, or nil if absent.
- .extract_armored_key(text, context) ⇒ Object
-
.fingerprints_in(_home) ⇒ Array<String>
Fingerprint of each primary key in ‘home`, ignoring subkeys.
- .gpg_at(home, *args) ⇒ Object
- .gpg_common_flags ⇒ Object
- .gpg_export_armored(home, fingerprint) ⇒ Object
- .instances ⇒ Object
-
.live_homes ⇒ Array<Array(String, String)>
‘[repo, home]` per configured repo.
-
.parse_primary_fprs(text) ⇒ Object
gpg –with-colons emits a ‘pub:` record for each primary key immediately followed by its `fpr:` record (fingerprint in field 10).
- .prefetch(resources) ⇒ Object
- .primary_fpr_of_content(text) ⇒ Object
- .remove_key(_home, _fingerprint) ⇒ Object
- .show_keys_args(path) ⇒ Object
- .store_key(_home, _fingerprint, _text) ⇒ Object
-
.trusted?(_home, _fingerprint) ⇒ Boolean
Whether the key is present and trusted to verify metadata.
- .url_hash(source) ⇒ Object
Instance Method Summary collapse
- #content ⇒ Object
- #content=(value) ⇒ Object
- #create ⇒ Object
-
#destroy ⇒ Object
Deletes the key not only in the ‘live’ keystore, but also in any others than might exist (from eg. when the baseurl for a repo was different).
- #exists? ⇒ Boolean
- #fingerprint ⇒ Object
-
#repo ⇒ Object
NOTE: mk_resource_methods can’t be used here.
- #trusted? ⇒ Boolean
Class Method Details
.all_homes_for(_repo) ⇒ Array<String>
Includes stale homes from a repo’s previous source URL, which ‘destroy` sweeps too.
18 19 20 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 18 def all_homes_for(_repo) raise NotImplementedError, "#{self} must implement .all_homes_for" end |
.canonical_key_digest(text) ⇒ Object
Canonicalise a key so semantically-equal keys hash equally: import ‘text` into a throwaway keyring, re-export it –armor, and SHA256 the result. This normalises armor formatting/packet ordering and captures expiry and subkey changes that a raw compare of the supplied ASCII would miss.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 90 def canonical_key_digest(text) ret = Dir.mktmpdir do |tmp| keyfile = File.join(tmp, 'k.asc') File.write(keyfile, text) gpg_at(tmp, '--import', keyfile) primary = parse_primary_fprs(gpg_at(tmp, '--with-colons', '--fingerprint', '--list-keys')).first exported = primary && gpg_export_armored(tmp, primary) exported ? Digest::SHA256.hexdigest(exported) : nil rescue Puppet::ExecutionFailure => e debug("canonical_key_digest failed: #{e..lines.first.to_s.strip}") nil end debug("canonical_key_digest -> #{ret.inspect}") ret end |
.export_key(_home, _fingerprint) ⇒ String?
Returns the stored key, or nil if absent.
28 29 30 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 28 def export_key(_home, _fingerprint) raise NotImplementedError, "#{self} must implement .export_key" end |
.extract_armored_key(text, context) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 74 def extract_armored_key(text, context) match = text.to_s.match(%r{-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----}m) unless match warning("#{context} did not contain an armored public key: #{text.to_s.lines.first.to_s.strip}") unless text.to_s.strip.empty? return nil end extra = text.to_s.sub(match[0], '').strip warning("#{context} included unexpected output: #{extra.lines.first.to_s.strip}") unless extra.empty? "#{match[0]}\n" end |
.fingerprints_in(_home) ⇒ Array<String>
Returns fingerprint of each primary key in ‘home`, ignoring subkeys.
23 24 25 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 23 def fingerprints_in(_home) raise NotImplementedError, "#{self} must implement .fingerprints_in" end |
.gpg_at(home, *args) ⇒ Object
130 131 132 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 130 def gpg_at(home, *args) gpg('--homedir', home, *gpg_common_flags, *args) end |
.gpg_common_flags ⇒ Object
134 135 136 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 134 def gpg_common_flags ['--batch', '--no-tty', '--no-autostart', '--no-permission-warning'] end |
.gpg_export_armored(home, fingerprint) ⇒ Object
120 121 122 123 124 125 126 127 128 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 120 def gpg_export_armored(home, fingerprint) out = begin gpg_at(home, '--export', '--armor', fingerprint) rescue Puppet::ExecutionFailure '' end extract_armored_key(out, "gpg export for #{fingerprint}") end |
.instances ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 45 def instances ret = live_homes.flat_map do |repo, home| next [] unless File.directory?(home) # home may not exist yet if dnf hasn't populated the cache for this repo fingerprints_in(home).map do |fpr| new(ensure: :present, name: "#{repo}:#{fpr}", repo: repo, fingerprint: fpr, home: home, content: export_key(home, fpr)) end end debug("instances -> #{ret.map(&:name).inspect}") ret end |
.live_homes ⇒ Array<Array(String, String)>
Returns ‘[repo, home]` per configured repo. A home may not exist yet; dnf only creates it on first fetch.
12 13 14 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 12 def live_homes raise NotImplementedError, "#{self} must implement .live_homes" end |
.parse_primary_fprs(text) ⇒ Object
gpg –with-colons emits a ‘pub:` record for each primary key immediately followed by its `fpr:` record (fingerprint in field 10). Pair adjacent records and keep the fpr after each `pub:`, ignoring `sub:` (subkey) fprs.
68 69 70 71 72 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 68 def parse_primary_fprs(text) text.lines.map { |line| line.split(':') }.each_cons(2).filter_map do |record, next_record| next_record[9] if record[0] == 'pub' && next_record[0] == 'fpr' end end |
.prefetch(resources) ⇒ Object
58 59 60 61 62 63 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 58 def prefetch(resources) instances.each do |prov| res = resources[prov.name] res.provider = prov if res end end |
.primary_fpr_of_content(text) ⇒ Object
106 107 108 109 110 111 112 113 114 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 106 def primary_fpr_of_content(text) ret = Dir.mktmpdir do |tmp| keyfile = File.join(tmp, 'k.asc') File.write(keyfile, text) parse_primary_fprs(gpg_at(tmp, *show_keys_args(keyfile))).first end debug("primary_fpr_of_content -> #{ret.inspect}") ret end |
.remove_key(_home, _fingerprint) ⇒ Object
36 37 38 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 36 def remove_key(_home, _fingerprint) raise NotImplementedError, "#{self} must implement .remove_key" end |
.show_keys_args(path) ⇒ Object
138 139 140 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 138 def show_keys_args(path) ['--with-colons', '--show-keys', path] end |
.store_key(_home, _fingerprint, _text) ⇒ Object
32 33 34 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 32 def store_key(_home, _fingerprint, _text) raise NotImplementedError, "#{self} must implement .store_key" end |
.trusted?(_home, _fingerprint) ⇒ Boolean
Returns whether the key is present and trusted to verify metadata.
41 42 43 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 41 def trusted?(_home, _fingerprint) raise NotImplementedError, "#{self} must implement .trusted?" end |
.url_hash(source) ⇒ Object
116 117 118 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 116 def url_hash(source) Digest::SHA256.digest(source)[0, 8].unpack1('H*') end |
Instance Method Details
#content ⇒ Object
169 170 171 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 169 def content @property_hash[:content] || :absent end |
#content=(value) ⇒ Object
173 174 175 176 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 173 def content=(value) debug("content= re-importing #{resource[:fingerprint]}") import_key(value) end |
#create ⇒ Object
147 148 149 150 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 147 def create import_key(resource[:content]) @property_hash[:ensure] = :present end |
#destroy ⇒ Object
Deletes the key not only in the ‘live’ keystore, but also in any others than might exist (from eg. when the baseurl for a repo was different)
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 153 def destroy homes = self.class.all_homes_for(resource[:repo]) debug("destroy sweeping #{resource[:fingerprint]} across #{homes.inspect}") homes.each do |home| next unless File.directory?(home) begin self.class.remove_key(home, resource[:fingerprint]) debug("destroy removed #{resource[:fingerprint]} from #{home.inspect}") rescue Puppet::ExecutionFailure => e debug("destroy skipped #{home.inspect}: #{e..lines.first.to_s.strip}") end end @property_hash[:ensure] = :absent end |
#exists? ⇒ Boolean
143 144 145 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 143 def exists? @property_hash[:ensure] == :present end |
#fingerprint ⇒ Object
192 193 194 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 192 def fingerprint @property_hash[:fingerprint] end |
#repo ⇒ Object
NOTE: mk_resource_methods can’t be used here. It needs a type-bound provider (this abstract parent has resource_type == nil), and running it in the concrete providers would regenerate a ‘content=` that just writes @property_hash, clobbering our importing content= below. These trivial getters are the mk_resource_methods equivalent, written by hand.
188 189 190 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 188 def repo @property_hash[:repo] end |
#trusted? ⇒ Boolean
178 179 180 181 |
# File 'lib/puppet/provider/yumrepo_metadata_key.rb', line 178 def trusted? home = live_home home && self.class.trusted?(home, resource[:fingerprint]) end |