hiera-eyaml 3.4.0 → 4.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/test.yml +18 -28
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +416 -0
- data/CHANGELOG.md +41 -1
- data/Gemfile +13 -14
- data/README.md +34 -10
- data/Rakefile +11 -4
- data/hiera-eyaml.gemspec +17 -15
- data/lib/hiera/backend/eyaml/CLI.rb +12 -19
- data/lib/hiera/backend/eyaml/commands.rb +2 -6
- data/lib/hiera/backend/eyaml/edithelper.rb +24 -19
- data/lib/hiera/backend/eyaml/encrypthelper.rb +17 -19
- data/lib/hiera/backend/eyaml/encryptor.rb +40 -43
- data/lib/hiera/backend/eyaml/encryptors/pkcs7.rb +81 -104
- data/lib/hiera/backend/eyaml/highlinehelper.rb +3 -5
- data/lib/hiera/backend/eyaml/logginghelper.rb +27 -29
- data/lib/hiera/backend/eyaml/options.rb +13 -16
- data/lib/hiera/backend/eyaml/parser/encrypted_tokens.rb +2 -2
- data/lib/hiera/backend/eyaml/parser/parser.rb +35 -36
- data/lib/hiera/backend/eyaml/parser/token.rb +15 -6
- data/lib/hiera/backend/eyaml/plugins.rb +13 -18
- data/lib/hiera/backend/eyaml/subcommand.rb +72 -74
- data/lib/hiera/backend/eyaml/subcommands/createkeys.rb +2 -6
- data/lib/hiera/backend/eyaml/subcommands/decrypt.rb +52 -52
- data/lib/hiera/backend/eyaml/subcommands/edit.rb +57 -58
- data/lib/hiera/backend/eyaml/subcommands/encrypt.rb +65 -69
- data/lib/hiera/backend/eyaml/subcommands/help.rb +17 -22
- data/lib/hiera/backend/eyaml/subcommands/recrypt.rb +13 -20
- data/lib/hiera/backend/eyaml/subcommands/unknown_command.rb +10 -14
- data/lib/hiera/backend/eyaml/subcommands/version.rb +4 -9
- data/lib/hiera/backend/eyaml/utils.rb +27 -28
- data/lib/hiera/backend/eyaml.rb +7 -9
- data/lib/hiera/backend/eyaml_backend.rb +33 -27
- metadata +62 -14
- data/tools/git_tag_release.rb +0 -98
- data/tools/regem.sh +0 -11
@@ -4,16 +4,15 @@ class Hiera
|
|
4
4
|
module Backend
|
5
5
|
module Eyaml
|
6
6
|
class Plugins
|
7
|
-
|
8
7
|
@@plugins = []
|
9
8
|
@@commands = []
|
10
9
|
@@options = []
|
11
10
|
|
12
|
-
def self.register_options
|
13
|
-
options = args[
|
14
|
-
plugin = args[
|
11
|
+
def self.register_options(args)
|
12
|
+
options = args[:options]
|
13
|
+
plugin = args[:plugin]
|
15
14
|
options.each do |name, option_hash|
|
16
|
-
new_option = {:
|
15
|
+
new_option = { name: "#{plugin}_#{name}" }
|
17
16
|
new_option.merge! option_hash
|
18
17
|
@@options << new_option
|
19
18
|
end
|
@@ -24,38 +23,35 @@ class Hiera
|
|
24
23
|
end
|
25
24
|
|
26
25
|
def self.find
|
27
|
-
|
28
26
|
gem_version = Gem::Version.new(Gem::VERSION)
|
29
27
|
this_version = Gem::Version.create(Hiera::Backend::Eyaml::VERSION)
|
30
|
-
index = gem_version >= Gem::Version.new(
|
28
|
+
index = (gem_version >= Gem::Version.new('1.8.0')) ? Gem::Specification : Gem.source_index
|
31
29
|
|
32
30
|
[index].flatten.each do |source|
|
33
|
-
specs = gem_version >= Gem::Version.new(
|
31
|
+
specs = (gem_version >= Gem::Version.new('1.6.0')) ? source.latest_specs(true) : source.latest_specs
|
34
32
|
|
35
33
|
specs.each do |spec|
|
36
34
|
spec = spec.to_spec if spec.respond_to?(:to_spec)
|
37
35
|
next if @@plugins.include? spec
|
38
36
|
|
39
|
-
dependency = spec.dependencies.find { |d| d.name ==
|
40
|
-
next if dependency && !dependency.requirement.satisfied_by?(
|
37
|
+
dependency = spec.dependencies.find { |d| d.name == 'hiera-eyaml' }
|
38
|
+
next if dependency && !dependency.requirement.satisfied_by?(this_version)
|
41
39
|
|
42
40
|
file = nil
|
43
|
-
if gem_version >= Gem::Version.new(
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
file = if gem_version >= Gem::Version.new('1.8.0')
|
42
|
+
spec.matches_for_glob('**/eyaml_init.rb').first
|
43
|
+
else
|
44
|
+
Gem.searcher.matching_files(spec, '**/eyaml_init.rb').first
|
45
|
+
end
|
48
46
|
|
49
47
|
next unless file
|
50
48
|
|
51
49
|
@@plugins << spec
|
52
50
|
load file
|
53
51
|
end
|
54
|
-
|
55
52
|
end
|
56
53
|
|
57
54
|
@@plugins
|
58
|
-
|
59
55
|
end
|
60
56
|
|
61
57
|
def self.plugins
|
@@ -65,7 +61,6 @@ class Hiera
|
|
65
61
|
def self.commands
|
66
62
|
@@commands
|
67
63
|
end
|
68
|
-
|
69
64
|
end
|
70
65
|
end
|
71
66
|
end
|
@@ -5,55 +5,69 @@ require 'yaml'
|
|
5
5
|
class Hiera
|
6
6
|
module Backend
|
7
7
|
module Eyaml
|
8
|
-
|
9
8
|
class Subcommand
|
10
|
-
|
11
9
|
class << self
|
12
10
|
attr_accessor :global_options, :options, :helptext
|
13
11
|
end
|
14
12
|
|
15
13
|
@@global_options = [
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
14
|
+
{ name: :encrypt_method,
|
15
|
+
description: 'Override default encryption and decryption method (default is PKCS7)',
|
16
|
+
short: 'n',
|
17
|
+
default: 'pkcs7', },
|
18
|
+
{ name: :version,
|
19
|
+
description: 'Show version information', },
|
20
|
+
{ name: :verbose,
|
21
|
+
description: 'Be more verbose',
|
22
|
+
short: 'v', },
|
23
|
+
{ name: :trace,
|
24
|
+
description: 'Enable trace debug',
|
25
|
+
short: 't', },
|
26
|
+
{ name: :quiet,
|
27
|
+
description: 'Be less verbose',
|
28
|
+
short: 'q', },
|
29
|
+
{ name: :help,
|
30
|
+
description: 'Information on how to use this command',
|
31
|
+
short: 'h', },
|
32
|
+
]
|
33
|
+
|
36
34
|
def self.load_config_file
|
37
|
-
config = { :
|
38
|
-
|
35
|
+
config = { options: {}, sources: [] }
|
36
|
+
|
37
|
+
config_paths = []
|
38
|
+
# Global
|
39
|
+
config_paths += ['/etc/eyaml/config.yaml']
|
40
|
+
# Home directory
|
41
|
+
env_home = ENV.fetch('HOME', nil)
|
42
|
+
config_paths += ["#{env_home}/.eyaml/config.yaml"] if env_home
|
43
|
+
# Relative to current directory
|
44
|
+
config_paths += ['.eyaml/config.yaml']
|
45
|
+
# Explicit ENV variable.
|
46
|
+
env_eyaml_config = ENV.fetch('EYAML_CONFIG', nil)
|
47
|
+
config_paths += [env_eyaml_config] if env_eyaml_config
|
48
|
+
|
49
|
+
# Load each path and stack configs.
|
50
|
+
config_paths.each do |config_file|
|
51
|
+
next unless config_file and File.file? config_file
|
52
|
+
|
39
53
|
begin
|
40
54
|
yaml_contents = YAML.load_file(config_file)
|
41
55
|
config[:options].merge! yaml_contents
|
42
56
|
config[:sources].push(config_file)
|
43
|
-
rescue
|
57
|
+
rescue StandardError
|
44
58
|
raise StandardError, "Could not open config file \"#{config_file}\" for reading"
|
45
|
-
end
|
59
|
+
end
|
46
60
|
end
|
47
61
|
config
|
48
62
|
end
|
49
63
|
|
50
|
-
def self.all_options
|
64
|
+
def self.all_options
|
51
65
|
options = @@global_options.dup
|
52
66
|
options += self.options if self.options
|
53
67
|
options += Plugins.options
|
54
68
|
# merge in defaults from configuration files
|
55
|
-
config_file =
|
56
|
-
options.map!
|
69
|
+
config_file = load_config_file
|
70
|
+
options.map! do |opt|
|
57
71
|
key_name = "#{opt[:name]}"
|
58
72
|
if config_file[:options].has_key? key_name
|
59
73
|
opt[:default] = config_file[:options][key_name]
|
@@ -61,106 +75,90 @@ class Hiera
|
|
61
75
|
else
|
62
76
|
opt
|
63
77
|
end
|
64
|
-
|
65
|
-
{ :
|
78
|
+
end
|
79
|
+
{ options: options, sources: config_file[:sources] || [] }
|
66
80
|
end
|
67
81
|
|
68
|
-
def self.attach_option
|
82
|
+
def self.attach_option(opt)
|
69
83
|
self.suboptions += opt
|
70
84
|
end
|
71
85
|
|
72
|
-
def self.find
|
86
|
+
def self.find(commandname = 'unknown_command')
|
73
87
|
begin
|
74
88
|
require "hiera/backend/eyaml/subcommands/#{commandname.downcase}"
|
75
89
|
rescue Exception => e
|
76
|
-
require
|
90
|
+
require 'hiera/backend/eyaml/subcommands/unknown_command'
|
77
91
|
return Hiera::Backend::Eyaml::Subcommands::UnknownCommand
|
78
|
-
end
|
79
|
-
command_module = Module.const_get(
|
80
|
-
command_class = Utils.find_closest_class :
|
92
|
+
end
|
93
|
+
command_module = Module.const_get(:Hiera).const_get(:Backend).const_get(:Eyaml).const_get(:Subcommands)
|
94
|
+
command_class = Utils.find_closest_class parent_class: command_module, class_name: commandname
|
81
95
|
command_class || Hiera::Backend::Eyaml::Subcommands::UnknownCommand
|
82
96
|
end
|
83
97
|
|
84
98
|
def self.parse
|
85
|
-
|
86
99
|
me = self
|
87
|
-
all =
|
100
|
+
all = all_options
|
88
101
|
|
89
|
-
options = Optimist
|
90
|
-
|
91
|
-
|
92
|
-
banner ["eyaml #{me.prettyname}: #{me.description}", me.helptext, "Options:"].compact.join("\n\n")
|
102
|
+
options = Optimist.options do
|
103
|
+
version 'Hiera-eyaml version ' + Hiera::Backend::Eyaml::VERSION.to_s
|
104
|
+
banner ["eyaml #{me.prettyname}: #{me.description}", me.helptext, 'Options:'].compact.join("\n\n")
|
93
105
|
|
94
106
|
all[:options].each do |available_option|
|
95
|
-
|
96
|
-
|
97
|
-
:short => :none}
|
107
|
+
skeleton = { description: '',
|
108
|
+
short: :none, }
|
98
109
|
|
99
110
|
skeleton.merge! available_option
|
100
|
-
opt skeleton[:name],
|
101
|
-
skeleton[:desc] || skeleton[:description],
|
102
|
-
:
|
103
|
-
:
|
104
|
-
:
|
105
|
-
|
111
|
+
opt skeleton[:name],
|
112
|
+
skeleton[:desc] || skeleton[:description], # legacy plugins
|
113
|
+
short: skeleton[:short],
|
114
|
+
default: skeleton[:default],
|
115
|
+
type: skeleton[:type]
|
106
116
|
end
|
107
117
|
|
108
118
|
stop_on Eyaml.subcommands
|
109
|
-
|
110
119
|
end
|
111
120
|
|
112
|
-
if options[:verbose]
|
113
|
-
Hiera::Backend::Eyaml.verbosity_level += 1
|
114
|
-
end
|
121
|
+
Hiera::Backend::Eyaml.verbosity_level += 1 if options[:verbose]
|
115
122
|
|
116
|
-
if options[:trace]
|
117
|
-
Hiera::Backend::Eyaml.verbosity_level += 2
|
118
|
-
end
|
123
|
+
Hiera::Backend::Eyaml.verbosity_level += 2 if options[:trace]
|
119
124
|
|
120
|
-
if options[:quiet]
|
121
|
-
Hiera::Backend::Eyaml.verbosity_level = 0
|
122
|
-
end
|
125
|
+
Hiera::Backend::Eyaml.verbosity_level = 0 if options[:quiet]
|
123
126
|
|
124
|
-
if options[:encrypt_method]
|
125
|
-
Hiera::Backend::Eyaml.default_encryption_scheme = options[:encrypt_method]
|
126
|
-
end
|
127
|
+
Hiera::Backend::Eyaml.default_encryption_scheme = options[:encrypt_method] if options[:encrypt_method]
|
127
128
|
|
128
129
|
if all[:sources]
|
129
130
|
all[:sources].each do |source|
|
130
|
-
LoggingHelper
|
131
|
+
LoggingHelper.debug "Loaded config from #{source}"
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
134
135
|
options
|
135
|
-
|
136
136
|
end
|
137
137
|
|
138
|
-
def self.validate
|
138
|
+
def self.validate(args)
|
139
139
|
args
|
140
140
|
end
|
141
141
|
|
142
142
|
def self.description
|
143
|
-
|
143
|
+
'no description'
|
144
144
|
end
|
145
145
|
|
146
146
|
def self.helptext
|
147
|
-
"Usage: eyaml #{
|
147
|
+
"Usage: eyaml #{prettyname} [options]"
|
148
148
|
end
|
149
149
|
|
150
150
|
def self.execute
|
151
|
-
raise StandardError, "This command is not implemented yet (#{
|
151
|
+
raise StandardError, "This command is not implemented yet (#{to_s.split('::').last})"
|
152
152
|
end
|
153
153
|
|
154
154
|
def self.prettyname
|
155
|
-
Utils.snakecase
|
155
|
+
Utils.snakecase to_s.split('::').last
|
156
156
|
end
|
157
157
|
|
158
158
|
def self.hidden?
|
159
159
|
false
|
160
160
|
end
|
161
|
-
|
162
161
|
end
|
163
|
-
|
164
162
|
end
|
165
163
|
end
|
166
164
|
end
|
@@ -4,15 +4,13 @@ class Hiera
|
|
4
4
|
module Backend
|
5
5
|
module Eyaml
|
6
6
|
module Subcommands
|
7
|
-
|
8
7
|
class Createkeys < Subcommand
|
9
|
-
|
10
|
-
def self.options
|
8
|
+
def self.options
|
11
9
|
[]
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.description
|
15
|
-
|
13
|
+
'create a set of keys with which to encrypt/decrypt eyaml data'
|
16
14
|
end
|
17
15
|
|
18
16
|
def self.execute
|
@@ -20,9 +18,7 @@ class Hiera
|
|
20
18
|
encryptor.create_keys
|
21
19
|
nil
|
22
20
|
end
|
23
|
-
|
24
21
|
end
|
25
|
-
|
26
22
|
end
|
27
23
|
end
|
28
24
|
end
|
@@ -8,48 +8,45 @@ class Hiera
|
|
8
8
|
module Backend
|
9
9
|
module Eyaml
|
10
10
|
module Subcommands
|
11
|
-
|
12
11
|
class Decrypt < Subcommand
|
13
|
-
|
14
12
|
def self.options
|
15
|
-
[{:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
{:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
{:
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
{:
|
28
|
-
|
29
|
-
|
30
|
-
]
|
13
|
+
[{ name: :string,
|
14
|
+
description: 'Source input is a string provided as an argument',
|
15
|
+
short: 's',
|
16
|
+
type: :string, },
|
17
|
+
{ name: :file,
|
18
|
+
description: 'Source input is a regular file',
|
19
|
+
short: 'f',
|
20
|
+
type: :string, },
|
21
|
+
{ name: :eyaml,
|
22
|
+
description: 'Source input is an eyaml file',
|
23
|
+
short: 'e',
|
24
|
+
type: :string, },
|
25
|
+
{ name: :stdin,
|
26
|
+
description: 'Source input is taken from stdin',
|
27
|
+
short: :none, },]
|
31
28
|
end
|
32
29
|
|
33
30
|
def self.description
|
34
|
-
|
31
|
+
'decrypt some data'
|
35
32
|
end
|
36
33
|
|
37
|
-
def self.validate
|
38
|
-
sources = [
|
39
|
-
Optimist
|
40
|
-
Optimist
|
34
|
+
def self.validate(options)
|
35
|
+
sources = %i[eyaml password string file stdin].collect { |x| x if options[x] }.compact
|
36
|
+
Optimist.die 'You must specify a source' if sources.count.zero?
|
37
|
+
Optimist.die "You can only specify one of (#{sources.join(', ')})" if sources.count > 1
|
41
38
|
options[:source] = sources.first
|
42
39
|
|
43
40
|
options[:input_data] = case options[:source]
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
41
|
+
when :stdin
|
42
|
+
STDIN.read
|
43
|
+
when :string
|
44
|
+
options[:string]
|
45
|
+
when :file
|
46
|
+
File.read options[:file]
|
47
|
+
when :eyaml
|
48
|
+
File.read options[:eyaml]
|
49
|
+
end
|
53
50
|
options
|
54
51
|
end
|
55
52
|
|
@@ -57,31 +54,34 @@ class Hiera
|
|
57
54
|
parser = Parser::ParserFactory.encrypted_parser
|
58
55
|
tokens = parser.parse(Eyaml::Options[:input_data])
|
59
56
|
case Eyaml::Options[:source]
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
57
|
+
when :eyaml
|
58
|
+
decrypted = tokens.map { |token| token.to_decrypted }
|
59
|
+
decrypted.join
|
60
|
+
else
|
61
|
+
yamled = false
|
62
|
+
decrypted = tokens.map do |token|
|
63
|
+
case token.class.name
|
64
|
+
when /::EncToken$/
|
65
|
+
if yamled
|
66
|
+
yamled = false
|
67
|
+
if /[\r\n]/.match?(token.to_plain_text)
|
68
|
+
"|\n " + token.to_plain_text.gsub(/([\r\n]+)/,
|
69
|
+
'\1 ')
|
74
70
|
else
|
75
|
-
|
76
|
-
|
71
|
+
token.to_plain_text
|
72
|
+
end
|
73
|
+
else
|
74
|
+
token.to_plain_text
|
77
75
|
end
|
78
|
-
|
79
|
-
|
76
|
+
else
|
77
|
+
yamled = true
|
78
|
+
token.match
|
79
|
+
end
|
80
|
+
end
|
81
|
+
decrypted.join
|
80
82
|
end
|
81
83
|
end
|
82
|
-
|
83
84
|
end
|
84
|
-
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|