hiera-eyaml 3.4.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +2 -2
  3. data/.github/workflows/test.yml +18 -28
  4. data/.rubocop.yml +8 -0
  5. data/.rubocop_todo.yml +416 -0
  6. data/CHANGELOG.md +33 -1
  7. data/Gemfile +13 -14
  8. data/README.md +32 -8
  9. data/Rakefile +11 -4
  10. data/hiera-eyaml.gemspec +17 -15
  11. data/lib/hiera/backend/eyaml/CLI.rb +12 -19
  12. data/lib/hiera/backend/eyaml/commands.rb +2 -6
  13. data/lib/hiera/backend/eyaml/edithelper.rb +24 -19
  14. data/lib/hiera/backend/eyaml/encrypthelper.rb +17 -19
  15. data/lib/hiera/backend/eyaml/encryptor.rb +40 -43
  16. data/lib/hiera/backend/eyaml/encryptors/pkcs7.rb +79 -105
  17. data/lib/hiera/backend/eyaml/highlinehelper.rb +3 -5
  18. data/lib/hiera/backend/eyaml/logginghelper.rb +27 -29
  19. data/lib/hiera/backend/eyaml/options.rb +13 -16
  20. data/lib/hiera/backend/eyaml/parser/encrypted_tokens.rb +2 -2
  21. data/lib/hiera/backend/eyaml/parser/parser.rb +35 -36
  22. data/lib/hiera/backend/eyaml/parser/token.rb +15 -6
  23. data/lib/hiera/backend/eyaml/plugins.rb +13 -18
  24. data/lib/hiera/backend/eyaml/subcommand.rb +72 -74
  25. data/lib/hiera/backend/eyaml/subcommands/createkeys.rb +2 -6
  26. data/lib/hiera/backend/eyaml/subcommands/decrypt.rb +52 -52
  27. data/lib/hiera/backend/eyaml/subcommands/edit.rb +57 -58
  28. data/lib/hiera/backend/eyaml/subcommands/encrypt.rb +65 -69
  29. data/lib/hiera/backend/eyaml/subcommands/help.rb +17 -22
  30. data/lib/hiera/backend/eyaml/subcommands/recrypt.rb +13 -20
  31. data/lib/hiera/backend/eyaml/subcommands/unknown_command.rb +10 -14
  32. data/lib/hiera/backend/eyaml/subcommands/version.rb +4 -9
  33. data/lib/hiera/backend/eyaml/utils.rb +27 -28
  34. data/lib/hiera/backend/eyaml.rb +7 -9
  35. data/lib/hiera/backend/eyaml_backend.rb +33 -27
  36. metadata +62 -14
  37. data/tools/git_tag_release.rb +0 -98
  38. data/tools/regem.sh +0 -11
@@ -6,64 +6,63 @@ class Hiera
6
6
  module Backend
7
7
  module Eyaml
8
8
  class Utils
9
-
10
- def self.camelcase string
9
+ def self.camelcase(string)
11
10
  return string if string !~ /_/ && string =~ /[A-Z]+.*/
12
- string.split('_').map{|e| e.capitalize}.join
11
+
12
+ string.split('_').map { |e| e.capitalize }.join
13
13
  end
14
14
 
15
- def self.snakecase string
16
- return string if string !~ /[A-Z]/
17
- string.split(/(?=[A-Z])/).collect {|x| x.downcase}.join("_")
15
+ def self.snakecase(string)
16
+ return string unless /[A-Z]/.match?(string)
17
+
18
+ string.split(/(?=[A-Z])/).collect { |x| x.downcase }.join('_')
18
19
  end
19
20
 
20
- def self.find_closest_class args
21
- parent_class = args[ :parent_class ]
22
- class_name = args[ :class_name ]
21
+ def self.find_closest_class(args)
22
+ parent_class = args[:parent_class]
23
+ class_name = args[:class_name]
23
24
  constants = parent_class.constants
24
25
  candidates = []
25
- constants.each do | candidate |
26
+ constants.each do |candidate|
26
27
  candidates << candidate.to_s if candidate.to_s.downcase == class_name.downcase
27
28
  end
28
- if candidates.count > 0
29
- parent_class.const_get candidates.first
30
- else
31
- nil
32
- end
29
+ return unless candidates.count > 0
30
+
31
+ parent_class.const_get candidates.first
33
32
  end
34
33
 
35
- def self.require_dir classdir
36
- num_class_hierarchy_levels = self.to_s.split("::").count - 1
37
- root_folder = File.dirname(__FILE__) + "/" + Array.new(num_class_hierarchy_levels).fill("..").join("/")
38
- class_folder = root_folder + "/" + classdir
34
+ def self.require_dir(classdir)
35
+ num_class_hierarchy_levels = to_s.split('::').count - 1
36
+ root_folder = File.dirname(__FILE__) + '/' + Array.new(num_class_hierarchy_levels).fill('..').join('/')
37
+ class_folder = root_folder + '/' + classdir
39
38
  Dir[File.expand_path("#{class_folder}/*.rb")].uniq.each do |file|
40
39
  LoggingHelper.trace "Requiring file: #{file}"
41
40
  require file
42
41
  end
43
42
  end
44
43
 
45
- def self.find_all_subclasses_of args
46
- parent_class = args[ :parent_class ]
44
+ def self.find_all_subclasses_of(args)
45
+ parent_class = args[:parent_class]
47
46
  constants = parent_class.constants
48
47
  candidates = []
49
- constants.each do | candidate |
50
- candidates << candidate.to_s.split('::').last if parent_class.const_get(candidate).class.to_s == "Class"
48
+ constants.each do |candidate|
49
+ candidates << candidate.to_s.split('::').last if parent_class.const_get(candidate).instance_of?(::Class)
51
50
  end
52
51
  candidates
53
52
  end
54
53
 
55
54
  def self.hiera?
56
- "hiera".eql? Eyaml::Options[:source]
55
+ 'hiera'.eql? Eyaml::Options[:source]
57
56
  end
58
57
 
59
- def self.convert_to_utf_8 string
58
+ def self.convert_to_utf_8(string)
60
59
  orig_encoding = string.encoding
61
60
  return string if orig_encoding == Encoding::UTF_8
62
61
 
63
- return string.dup.force_encoding(Encoding::UTF_8)
64
- rescue EncodingError => detail
62
+ string.dup.force_encoding(Encoding::UTF_8)
63
+ rescue EncodingError => e
65
64
  warn "Unable to encode to \"Encoding::UTF_8\" using the original \"#{orig_encoding}\""
66
- return string
65
+ string
67
66
  end
68
67
  end
69
68
  end
@@ -1,14 +1,13 @@
1
1
  class Hiera
2
2
  module Backend
3
3
  module Eyaml
4
-
5
- VERSION = "3.4.0"
6
- DESCRIPTION = "Hiera-eyaml is a backend for Hiera which provides OpenSSL encryption/decryption for Hiera properties"
4
+ VERSION = '4.0.0'
5
+ DESCRIPTION = 'Hiera-eyaml is a backend for Hiera which provides OpenSSL encryption/decryption for Hiera properties'
7
6
 
8
7
  class RecoverableError < StandardError
9
8
  end
10
9
 
11
- def self.subcommand= command
10
+ def self.subcommand=(command)
12
11
  @@subcommand = command
13
12
  end
14
13
 
@@ -16,16 +15,16 @@ class Hiera
16
15
  @@subcommand
17
16
  end
18
17
 
19
- def self.default_encryption_scheme= new_encryption
18
+ def self.default_encryption_scheme=(new_encryption)
20
19
  @@default_encryption_scheme = new_encryption
21
20
  end
22
21
 
23
22
  def self.default_encryption_scheme
24
- @@default_encryption_scheme ||= "PKCS7"
23
+ @@default_encryption_scheme ||= 'PKCS7'
25
24
  @@default_encryption_scheme
26
25
  end
27
26
 
28
- def self.verbosity_level= new_verbosity_level
27
+ def self.verbosity_level=(new_verbosity_level)
29
28
  @@debug_level = new_verbosity_level
30
29
  end
31
30
 
@@ -34,14 +33,13 @@ class Hiera
34
33
  @@debug_level
35
34
  end
36
35
 
37
- def self.subcommands= commands
36
+ def self.subcommands=(commands)
38
37
  @@subcommands = commands
39
38
  end
40
39
 
41
40
  def self.subcommands
42
41
  @@subcommands
43
42
  end
44
-
45
43
  end
46
44
  end
47
45
  end
@@ -9,15 +9,14 @@ require 'yaml'
9
9
  class Hiera
10
10
  module Backend
11
11
  class Eyaml_backend
12
-
13
12
  attr_reader :extension
14
13
 
15
14
  def initialize(cache = nil)
16
- debug("Hiera eYAML backend starting")
15
+ debug('Hiera eYAML backend starting')
17
16
 
18
17
  @decrypted_cache = {}
19
18
  @cache = cache || Filecache.new
20
- @extension = Config[:eyaml][:extension] || "eyaml"
19
+ @extension = Config[:eyaml][:extension] || 'eyaml'
21
20
  end
22
21
 
23
22
  def lookup(key, scope, order_override, resolution_type)
@@ -54,20 +53,28 @@ class Hiera
54
53
  new_answer = parse_answer(data[key], scope)
55
54
  case resolution_type
56
55
  when :array
57
- raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
56
+ unless new_answer.is_a? Array or new_answer.is_a? String
57
+ raise Exception,
58
+ "Hiera type mismatch: expected Array and got #{new_answer.class}"
59
+ end
60
+
58
61
  answer ||= []
59
62
  answer << new_answer
60
63
  when :hash
61
- raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
64
+ unless new_answer.is_a? Hash
65
+ raise Exception,
66
+ "Hiera type mismatch: expected Hash and got #{new_answer.class}"
67
+ end
68
+
62
69
  answer ||= {}
63
- answer = Backend.merge_answer(new_answer,answer)
70
+ answer = Backend.merge_answer(new_answer, answer)
64
71
  else
65
72
  answer = new_answer
66
73
  break
67
74
  end
68
75
  end
69
76
 
70
- return answer
77
+ answer
71
78
  end
72
79
 
73
80
  private
@@ -78,19 +85,18 @@ class Hiera
78
85
 
79
86
  def decrypt(data)
80
87
  if encrypted?(data)
81
- debug("Attempting to decrypt")
88
+ debug('Attempting to decrypt')
82
89
  begin
83
90
  parser = Eyaml::Parser::ParserFactory.hiera_backend_parser
84
91
  tokens = parser.parse(data)
85
- decrypted = tokens.map{ |token| token.to_plain_text }
92
+ decrypted = tokens.map { |token| token.to_plain_text }
86
93
  plaintext = decrypted.join
87
94
  rescue OpenSSL::PKCS7::PKCS7Error => e
88
- debug("Caught exception: #{e.class}, #{e.message}\n"\
95
+ debug("Caught exception: #{e.class}, #{e.message}\n" \
89
96
  "#{e.backtrace.join("\n")}")
90
- raise "Hiera-eyaml decryption failed, check the "\
91
- "encrypted data matches the key you are using.\n"\
92
- "Raw message from system: #{e.message}"
93
-
97
+ raise 'Hiera-eyaml decryption failed, check the ' \
98
+ "encrypted data matches the key you are using.\n" \
99
+ "Raw message from system: #{e.message}"
94
100
  end
95
101
  plaintext.chomp
96
102
  else
@@ -99,14 +105,14 @@ class Hiera
99
105
  end
100
106
 
101
107
  def encrypted?(data)
102
- /.*ENC\[.*\]/ =~ data ? true : false
108
+ /.*ENC\[.*\]/.match?(data) ? true : false
103
109
  end
104
110
 
105
- def parse_answer(data, scope, extra_data={})
111
+ def parse_answer(data, scope, extra_data = {})
106
112
  if data.is_a?(Numeric) or data.is_a?(TrueClass) or data.is_a?(FalseClass)
107
- return data
113
+ data
108
114
  elsif data.is_a?(String)
109
- return parse_string(data, scope, extra_data)
115
+ parse_string(data, scope, extra_data)
110
116
  elsif data.is_a?(Hash)
111
117
  answer = {}
112
118
  data.each_pair do |key, val|
@@ -114,14 +120,14 @@ class Hiera
114
120
  answer[interpolated_key] = parse_answer(val, scope, extra_data)
115
121
  end
116
122
 
117
- return answer
123
+ answer
118
124
  elsif data.is_a?(Array)
119
125
  answer = []
120
126
  data.each do |item|
121
127
  answer << parse_answer(item, scope, extra_data)
122
128
  end
123
129
 
124
- return answer
130
+ answer
125
131
  end
126
132
  end
127
133
 
@@ -132,18 +138,18 @@ class Hiera
132
138
  debug("Set option: #{key} = #{parsed_value}")
133
139
  end
134
140
 
135
- Eyaml::Options[:source] = "hiera"
141
+ Eyaml::Options[:source] = 'hiera'
136
142
  end
137
143
 
138
- def parse_string(data, scope, extra_data={})
144
+ def parse_string(data, scope, extra_data = {})
139
145
  if Eyaml::Options[:cache_decrypted]
140
- if not @decrypted_cache.include?(data)
146
+ if @decrypted_cache.include?(data)
147
+ debug('Retrieving data from decrypted cache')
148
+ decrypted_data = @decrypted_cache[data]
149
+ else
141
150
  decrypted_data = decrypt(data)
142
- debug("Adding data to decrypted cache")
151
+ debug('Adding data to decrypted cache')
143
152
  @decrypted_cache[data] = decrypted_data
144
- else
145
- debug("Retrieving data from decrypted cache")
146
- decrypted_data = @decrypted_cache[data]
147
153
  end
148
154
  else
149
155
  decrypted_data = decrypt(data)
metadata CHANGED
@@ -1,43 +1,91 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiera-eyaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vox Pupuli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-26 00:00:00.000000000 Z
11
+ date: 2024-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: highline
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: optimist
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ">="
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '0'
33
+ version: '3.1'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ">="
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '0'
40
+ version: '3.1'
27
41
  - !ruby/object:Gem::Dependency
28
- name: highline
42
+ name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.2'
31
48
  - - ">="
32
49
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
50
+ version: 13.2.1
51
+ type: :development
35
52
  prerelease: false
36
53
  version_requirements: !ruby/object:Gem::Requirement
37
54
  requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '13.2'
38
58
  - - ">="
39
59
  - !ruby/object:Gem::Version
40
- version: '0'
60
+ version: 13.2.1
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec-expectations
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.13'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.13'
75
+ - !ruby/object:Gem::Dependency
76
+ name: voxpupuli-rubocop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '='
80
+ - !ruby/object:Gem::Version
81
+ version: 2.6.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '='
87
+ - !ruby/object:Gem::Version
88
+ version: 2.6.0
41
89
  description: Hiera backend for decrypting encrypted yaml properties
42
90
  email: voxpupuli@groups.io
43
91
  executables:
@@ -49,6 +97,8 @@ files:
49
97
  - ".github/workflows/release.yml"
50
98
  - ".github/workflows/test.yml"
51
99
  - ".gitignore"
100
+ - ".rubocop.yml"
101
+ - ".rubocop_todo.yml"
52
102
  - CHANGELOG.md
53
103
  - Gemfile
54
104
  - HISTORY.md
@@ -86,8 +136,6 @@ files:
86
136
  - sublime_text/README.md
87
137
  - sublime_text/eyaml.sublime-package
88
138
  - sublime_text/eyaml.syntax_definition.json
89
- - tools/git_tag_release.rb
90
- - tools/regem.sh
91
139
  homepage: https://github.com/voxpupuli/hiera-eyaml/
92
140
  licenses:
93
141
  - MIT
@@ -100,7 +148,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
148
  requirements:
101
149
  - - ">="
102
150
  - !ruby/object:Gem::Version
103
- version: 2.5.0
151
+ version: '2.7'
104
152
  - - "<"
105
153
  - !ruby/object:Gem::Version
106
154
  version: '4'
@@ -110,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
158
  - !ruby/object:Gem::Version
111
159
  version: '0'
112
160
  requirements: []
113
- rubygems_version: 3.3.26
161
+ rubygems_version: 3.3.27
114
162
  signing_key:
115
163
  specification_version: 4
116
164
  summary: OpenSSL Encryption backend for Hiera
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9')
5
- $stderr.puts "This script requires Ruby >= 1.9"
6
- exit 1
7
- end
8
-
9
- require 'open3'
10
- result = Open3.capture3('git rev-parse --show-toplevel')
11
- unless result[2].exitstatus == 0
12
- $stderr.puts "You do not appear to be in a git repository. This script must be run from inside a git repository."
13
- exit 2
14
- end
15
- filename = result[0].lines.first.chomp + '/CHANGES.md'
16
- unless File.exist?(filename)
17
- $stderr.puts "CHANGES.md not found. Please ensure that CHANGES.md exists."
18
- exit 3
19
- end
20
- contents = IO.read(filename)
21
-
22
- lines = contents.lines.drop(3).map(&:chomp).reject(&:empty?)
23
- versions = Hash.new
24
- currentversion = nil
25
- versions[nil] = []
26
- lines.each_with_index do |line, index|
27
- if line =~ /\A-+\z/
28
- versions[currentversion].pop
29
- currentversion = lines[index-1]
30
- versions[currentversion] = []
31
- else
32
- versions[currentversion] << line
33
- end
34
- end
35
- versions.delete(nil)
36
-
37
- def prompt(*args)
38
- print(*args)
39
- gets.chomp
40
- end
41
-
42
- newest = versions.first[0]
43
- version = prompt "Version [#{newest}]: "
44
- version = newest if version.empty?
45
-
46
- unless versions[version]
47
- $stderr.puts "Version #{version} is invalid. Valid versions are: #{versions.keys.join(', ')}"
48
- exit 4
49
- end
50
-
51
- tagname = "v#{version}"
52
-
53
-
54
-
55
- result = Open3.capture3("git rev-parse #{tagname}")
56
- if result[2].exitstatus == 0
57
- $stderr.puts "Tag #{tagname} already exists."
58
- exit 5
59
- end
60
-
61
- commit = prompt "Commit: "
62
-
63
- result = Open3.capture3("git --no-pager log -1 #{commit} --format='%ci'")
64
- unless result[2].exitstatus == 0
65
- $stderr.puts "Commit '#{commit}' is not valid."
66
- exit result[2].exitstatus
67
- end
68
- commitdate = result[0].lines.first.chomp
69
-
70
- def word_wrap(line, width)
71
- first_prefix = line.match(/([ -]*)/)[1]
72
- prefix = ' ' * first_prefix.size
73
- real_width = width - (prefix.size * 2)
74
- line[prefix.size..-1].gsub(/(^)?(.{1,#{real_width}})(?: +|$)/) { |s| $1 ? "#{first_prefix}#{s}\n" : "#{prefix}#{s}\n" }
75
- end
76
-
77
- require 'tempfile'
78
- begin
79
- tf = Tempfile.new('tag-message')
80
- tf.puts "Version #{version} release"
81
- tf.puts ""
82
- tf.puts "Changes:"
83
- versions[version].each do |line|
84
- tf.puts word_wrap(line, 80)
85
- end
86
- tf.flush
87
-
88
- result = Open3.capture3({'GIT_COMMITTER_DATE' => commitdate}, "git tag -a #{tagname} #{commit} -F #{tf.path}")
89
- $stderr.puts result[1]
90
- if result[2].exitstatus == 0
91
- system "git --no-pager show #{tagname} --no-patch"
92
- puts ""
93
- puts "Tag created. Please push to GitHub with `git push origin #{tagname}`."
94
- end
95
- exit result[2].exitstatus
96
- ensure
97
- tf.close!
98
- end
data/tools/regem.sh DELETED
@@ -1,11 +0,0 @@
1
- #!/bin/sh
2
-
3
- # ToDo: Remove as 'rake install' task will build and install the latest gem?
4
-
5
- gem uninstall hiera-eyaml --executables
6
- RAKE_OUT=`rake build`
7
- echo ${RAKE_OUT}
8
- VERSION=`echo ${RAKE_OUT} | awk '{print $2}'`
9
- echo Installing version: ${VERSION} ...
10
- gem install pkg/hiera-eyaml-${VERSION}.gem
11
- eyaml version