clarenceb-hiera-eyaml 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.travis.yml +10 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +52 -0
- data/LICENSE.txt +21 -0
- data/PLUGINS.md +4 -0
- data/README.md +322 -0
- data/Rakefile +1 -0
- data/bin/eyaml +13 -0
- data/hiera-eyaml.gemspec +22 -0
- data/lib/hiera/backend/eyaml/CLI.rb +60 -0
- data/lib/hiera/backend/eyaml/commands.rb +21 -0
- data/lib/hiera/backend/eyaml/encryptor.rb +79 -0
- data/lib/hiera/backend/eyaml/encryptors/pkcs7.rb +107 -0
- data/lib/hiera/backend/eyaml/options.rb +35 -0
- data/lib/hiera/backend/eyaml/parser/encrypted_tokens.rb +138 -0
- data/lib/hiera/backend/eyaml/parser/parser.rb +82 -0
- data/lib/hiera/backend/eyaml/parser/token.rb +49 -0
- data/lib/hiera/backend/eyaml/plugins.rb +70 -0
- data/lib/hiera/backend/eyaml/subcommand.rb +126 -0
- data/lib/hiera/backend/eyaml/subcommands/createkeys.rb +29 -0
- data/lib/hiera/backend/eyaml/subcommands/decrypt.rb +81 -0
- data/lib/hiera/backend/eyaml/subcommands/edit.rb +105 -0
- data/lib/hiera/backend/eyaml/subcommands/encrypt.rb +100 -0
- data/lib/hiera/backend/eyaml/subcommands/help.rb +51 -0
- data/lib/hiera/backend/eyaml/subcommands/recrypt.rb +56 -0
- data/lib/hiera/backend/eyaml/subcommands/unknown_command.rb +48 -0
- data/lib/hiera/backend/eyaml/subcommands/version.rb +47 -0
- data/lib/hiera/backend/eyaml/utils.rb +172 -0
- data/lib/hiera/backend/eyaml.rb +48 -0
- data/lib/hiera/backend/eyaml_backend.rb +125 -0
- data/sublime_text/README.md +16 -0
- data/sublime_text/eyaml.sublime-package +0 -0
- data/sublime_text/eyaml.syntax_definition.json +288 -0
- data/tools/regem.sh +9 -0
- metadata +114 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'hiera/backend/eyaml/encryptor'
|
3
|
+
require 'hiera/backend/eyaml/utils'
|
4
|
+
require 'hiera/backend/eyaml/options'
|
5
|
+
|
6
|
+
class Hiera
|
7
|
+
module Backend
|
8
|
+
module Eyaml
|
9
|
+
module Encryptors
|
10
|
+
|
11
|
+
class Pkcs7 < Encryptor
|
12
|
+
|
13
|
+
self.options = {
|
14
|
+
:private_key => { :desc => "Path to private key",
|
15
|
+
:type => :string,
|
16
|
+
:default => "./keys/private_key.pkcs7.pem" },
|
17
|
+
:public_key => { :desc => "Path to public key",
|
18
|
+
:type => :string,
|
19
|
+
:default => "./keys/public_key.pkcs7.pem" }
|
20
|
+
}
|
21
|
+
|
22
|
+
self.tag = "PKCS7"
|
23
|
+
|
24
|
+
def self.encrypt plaintext
|
25
|
+
|
26
|
+
public_key = self.option :public_key
|
27
|
+
raise StandardError, "pkcs7_public_key is not defined" unless public_key
|
28
|
+
|
29
|
+
public_key_pem = File.read public_key
|
30
|
+
public_key_x509 = OpenSSL::X509::Certificate.new( public_key_pem )
|
31
|
+
|
32
|
+
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
|
33
|
+
OpenSSL::PKCS7::encrypt([public_key_x509], plaintext, cipher, OpenSSL::PKCS7::BINARY).to_der
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.decrypt ciphertext
|
38
|
+
|
39
|
+
public_key = self.option :public_key
|
40
|
+
private_key = self.option :private_key
|
41
|
+
raise StandardError, "pkcs7_public_key is not defined" unless public_key
|
42
|
+
raise StandardError, "pkcs7_private_key is not defined" unless private_key
|
43
|
+
|
44
|
+
private_key_pem = File.read private_key
|
45
|
+
private_key_rsa = OpenSSL::PKey::RSA.new( private_key_pem )
|
46
|
+
|
47
|
+
public_key_pem = File.read public_key
|
48
|
+
public_key_x509 = OpenSSL::X509::Certificate.new( public_key_pem )
|
49
|
+
|
50
|
+
pkcs7 = OpenSSL::PKCS7.new( ciphertext )
|
51
|
+
pkcs7.decrypt(private_key_rsa, public_key_x509)
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.create_keys
|
56
|
+
|
57
|
+
# Try to do equivalent of:
|
58
|
+
# openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout privatekey.pem -out publickey.pem -subj '/'
|
59
|
+
|
60
|
+
public_key = self.option :public_key
|
61
|
+
private_key = self.option :private_key
|
62
|
+
|
63
|
+
key = OpenSSL::PKey::RSA.new(2048)
|
64
|
+
Utils.ensure_key_dir_exists private_key
|
65
|
+
Utils.write_important_file :filename => private_key, :content => key.to_pem, :mode => 0600
|
66
|
+
|
67
|
+
name = OpenSSL::X509::Name.parse("/DC=org/DC=example/CN=eyaml")
|
68
|
+
cert = OpenSSL::X509::Certificate.new()
|
69
|
+
cert.serial = 0
|
70
|
+
cert.version = 2
|
71
|
+
cert.subject = name
|
72
|
+
cert.issuer = cert.subject
|
73
|
+
cert.not_before = Time.now
|
74
|
+
cert.not_after = if 1.size == 8 # 64bit
|
75
|
+
Time.now + 50 * 365 * 24 * 60 * 60
|
76
|
+
else # 32bit
|
77
|
+
Time.at(0x7fffffff)
|
78
|
+
end
|
79
|
+
cert.public_key = key.public_key
|
80
|
+
|
81
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
82
|
+
ef.subject_certificate = cert
|
83
|
+
ef.issuer_certificate = cert
|
84
|
+
cert.extensions = [
|
85
|
+
ef.create_extension("basicConstraints","CA:TRUE", true),
|
86
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
87
|
+
]
|
88
|
+
cert.add_extension ef.create_extension("authorityKeyIdentifier",
|
89
|
+
"keyid:always,issuer:always")
|
90
|
+
|
91
|
+
cert.sign key, OpenSSL::Digest::SHA1.new
|
92
|
+
|
93
|
+
Utils.ensure_key_dir_exists public_key
|
94
|
+
Utils.write_important_file :filename => public_key, :content => cert.to_pem
|
95
|
+
puts "Keys created OK"
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Hiera
|
2
|
+
module Backend
|
3
|
+
module Eyaml
|
4
|
+
class Options
|
5
|
+
|
6
|
+
def self.[]= key, value
|
7
|
+
@@options ||= {}
|
8
|
+
@@options[ key.to_sym ] = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.[] key
|
12
|
+
@@options ||= {}
|
13
|
+
@@options[ key.to_sym ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.set hash
|
17
|
+
@@options = {}
|
18
|
+
hash.each do |k, v|
|
19
|
+
@@options[ k.to_sym ] = v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.debug
|
24
|
+
Utils::debug "Dump of eyaml tool options dict:"
|
25
|
+
Utils::debug "--------------------------------"
|
26
|
+
@@options.each do |k, v|
|
27
|
+
Utils::debug sprintf "%18s %-18s = %-18s %-18s", "(#{k.class.name})", k.to_s, v.to_s, "(#{v.class.name})"
|
28
|
+
end
|
29
|
+
Utils::debug "--------------------------------"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'hiera/backend/eyaml/parser/token'
|
2
|
+
require 'hiera/backend/eyaml/utils'
|
3
|
+
require 'hiera/backend/eyaml/encryptor'
|
4
|
+
require 'hiera/backend/eyaml'
|
5
|
+
|
6
|
+
|
7
|
+
class Hiera
|
8
|
+
module Backend
|
9
|
+
module Eyaml
|
10
|
+
module Parser
|
11
|
+
class EncToken < Token
|
12
|
+
attr_reader :format, :cipher, :encryptor, :indentation, :plain_text, :id
|
13
|
+
def self.encrypted_value(format, encryption_scheme, cipher, match, indentation = '')
|
14
|
+
decryptor = Encryptor.find encryption_scheme
|
15
|
+
plain_text = decryptor.decrypt( decryptor.decode cipher )
|
16
|
+
EncToken.new(format, plain_text, decryptor, cipher, match, indentation)
|
17
|
+
end
|
18
|
+
def self.decrypted_value(format, plain_text, encryption_scheme, match, id, indentation = '')
|
19
|
+
encryptor = Encryptor.find encryption_scheme
|
20
|
+
cipher = encryptor.encode( encryptor.encrypt plain_text )
|
21
|
+
id_number = id.nil? ? nil : id.gsub(/\(|\)/, "").to_i
|
22
|
+
EncToken.new(format, plain_text, encryptor, cipher, match, indentation, id_number)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(format, plain_text, encryptor, cipher, match = '', indentation = '', id = nil)
|
26
|
+
@format = format
|
27
|
+
@plain_text = plain_text
|
28
|
+
@encryptor = encryptor
|
29
|
+
@cipher = cipher
|
30
|
+
@indentation = indentation
|
31
|
+
@id = id
|
32
|
+
super(match)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_encrypted(args={})
|
36
|
+
label = args[:label]
|
37
|
+
label_string = label.nil? ? '' : "#{label}: "
|
38
|
+
format = args[:format].nil? ? @format : args[:format]
|
39
|
+
case format
|
40
|
+
when :block
|
41
|
+
# strip any white space
|
42
|
+
@cipher = @cipher.gsub(/ /m, "")
|
43
|
+
# normalize indentation
|
44
|
+
ciphertext = @cipher.gsub(/\n/, "\n" + @indentation)
|
45
|
+
chevron = (args[:use_chevron].nil? || args[:use_chevron]) ? ">\n" : ''
|
46
|
+
"#{label_string}#{chevron}" + @indentation + "ENC[#{@encryptor.tag},#{ciphertext}]"
|
47
|
+
when :string
|
48
|
+
ciphertext = @cipher.gsub(/\n/, "")
|
49
|
+
"#{label_string}ENC[#{@encryptor.tag},#{ciphertext}]"
|
50
|
+
else
|
51
|
+
raise "#{@format} is not a valid format"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_decrypted(args={})
|
56
|
+
label = args[:label]
|
57
|
+
label_string = label.nil? ? '' : "#{label}: "
|
58
|
+
format = args[:format].nil? ? @format : args[:format]
|
59
|
+
index = args[:index].nil? ? '' : "(#{args[:index]})"
|
60
|
+
case format
|
61
|
+
when :block
|
62
|
+
chevron = (args[:use_chevron].nil? || args[:use_chevron]) ? ">\n" : ''
|
63
|
+
"#{label_string}#{chevron}" + indentation + "DEC#{index}::#{@encryptor.tag}[" + @plain_text + "]!"
|
64
|
+
when :string
|
65
|
+
"#{label_string}DEC#{index}::#{@encryptor.tag}[" + @plain_text + "]!"
|
66
|
+
else
|
67
|
+
raise "#{@format} is not a valid format"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_plain_text
|
72
|
+
@plain_text
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
class EncTokenType < TokenType
|
78
|
+
def create_enc_token(match, type, enc_comma, cipher, indentation = '')
|
79
|
+
encryption_scheme = enc_comma.nil? ? Eyaml.default_encryption_scheme : enc_comma.split(",").first
|
80
|
+
EncToken.encrypted_value(type, encryption_scheme, cipher, match, indentation)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class EncHieraTokenType < EncTokenType
|
85
|
+
def initialize
|
86
|
+
@regex = /ENC\[(\w+,)?([a-zA-Z0-9\+\/ =\n]+?)\]/
|
87
|
+
@string_token_type = EncStringTokenType.new()
|
88
|
+
end
|
89
|
+
def create_token(string)
|
90
|
+
@string_token_type.create_token(string.gsub(/[ \n]/, ''))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class EncStringTokenType < EncTokenType
|
95
|
+
def initialize
|
96
|
+
@regex = /ENC\[(\w+,)?([a-zA-Z0-9\+\/=]+?)\]/
|
97
|
+
end
|
98
|
+
def create_token(string)
|
99
|
+
md = @regex.match(string)
|
100
|
+
self.create_enc_token(string, :string, md[1], md[2])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class EncBlockTokenType < EncTokenType
|
105
|
+
def initialize
|
106
|
+
@regex = />\n(\s*)ENC\[(\w+,)?([a-zA-Z0-9\+\/ =\n]+?)\]/
|
107
|
+
end
|
108
|
+
def create_token(string)
|
109
|
+
md = @regex.match(string)
|
110
|
+
self.create_enc_token(string, :block, md[2], md[3], md[1])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class DecStringTokenType < TokenType
|
115
|
+
def initialize
|
116
|
+
@regex = /DEC(\(\d+\))?::(\w+)\[(.+?)\]\!/
|
117
|
+
end
|
118
|
+
def create_token(string)
|
119
|
+
md = @regex.match(string)
|
120
|
+
EncToken.decrypted_value(:string, md[3], md[2], string, md[1])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class DecBlockTokenType < TokenType
|
125
|
+
def initialize
|
126
|
+
@regex = />\n(\s*)DEC(\(\d+\))?::(\w+)\[(.+?)\]\!/m
|
127
|
+
end
|
128
|
+
def create_token(string)
|
129
|
+
md = @regex.match(string)
|
130
|
+
EncToken.decrypted_value(:block, md[4], md[3], string, md[2], md[1])
|
131
|
+
EncToken.decrypted_value(:block, md[4], md[3], string, md[2], md[1])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'hiera/backend/eyaml/parser/token'
|
3
|
+
require 'hiera/backend/eyaml/parser/encrypted_tokens'
|
4
|
+
|
5
|
+
class Hiera
|
6
|
+
module Backend
|
7
|
+
module Eyaml
|
8
|
+
module Parser
|
9
|
+
class ParserFactory
|
10
|
+
def self.encrypted_parser
|
11
|
+
enc_string = EncStringTokenType.new()
|
12
|
+
enc_block = EncBlockTokenType.new()
|
13
|
+
Parser.new([enc_string, enc_block])
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.decrypted_parser
|
17
|
+
dec_string = DecStringTokenType.new()
|
18
|
+
dec_block = DecBlockTokenType.new()
|
19
|
+
Parser.new([dec_string, dec_block])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.hiera_backend_parser
|
23
|
+
enc_hiera = EncHieraTokenType.new()
|
24
|
+
Parser.new([enc_hiera])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Parser
|
29
|
+
attr_reader :token_types
|
30
|
+
|
31
|
+
def initialize(token_types)
|
32
|
+
@token_types = token_types
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse text
|
36
|
+
parse_scanner(StringScanner.new(text)).reverse
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_scanner s
|
40
|
+
if s.eos?
|
41
|
+
[]
|
42
|
+
else
|
43
|
+
# Check if the scanner currently matches a regex
|
44
|
+
current_match = @token_types.find { |token_type|
|
45
|
+
s.match?(token_type.regex)
|
46
|
+
}
|
47
|
+
|
48
|
+
token =
|
49
|
+
if current_match.nil?
|
50
|
+
# No regex matches here. Find the earliest match.
|
51
|
+
next_match_indexes = @token_types.map { |token_type|
|
52
|
+
next_match = s.check_until(token_type.regex)
|
53
|
+
if next_match.nil?
|
54
|
+
nil
|
55
|
+
else
|
56
|
+
next_match.length - s.matched.length
|
57
|
+
end
|
58
|
+
}.reject { |i| i.nil? }
|
59
|
+
non_match_size =
|
60
|
+
if next_match_indexes.length == 0
|
61
|
+
s.rest_size
|
62
|
+
else
|
63
|
+
next_match_indexes.min
|
64
|
+
end
|
65
|
+
non_match = s.peek(non_match_size)
|
66
|
+
# advance scanner
|
67
|
+
s.pos = s.pos + non_match_size
|
68
|
+
NonMatchToken.new(non_match)
|
69
|
+
else
|
70
|
+
# A regex matches so create a token and do a recursive call with the advanced scanner
|
71
|
+
current_match.create_token s.scan(current_match.regex)
|
72
|
+
end
|
73
|
+
|
74
|
+
self.parse_scanner(s) << token
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Hiera
|
2
|
+
module Backend
|
3
|
+
module Eyaml
|
4
|
+
module Parser
|
5
|
+
class TokenType
|
6
|
+
attr_reader :regex
|
7
|
+
@regex
|
8
|
+
def create_token string
|
9
|
+
raise 'Abstract method called'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Token
|
14
|
+
attr_reader :match
|
15
|
+
def initialize(match)
|
16
|
+
@match = match
|
17
|
+
end
|
18
|
+
def to_encrypted(args={})
|
19
|
+
raise 'Abstract method called'
|
20
|
+
end
|
21
|
+
def to_decrypted(args={})
|
22
|
+
raise 'Abstract method called'
|
23
|
+
end
|
24
|
+
def to_plain_text
|
25
|
+
raise 'Abstract method called'
|
26
|
+
end
|
27
|
+
def to_s
|
28
|
+
"#{self.class.name}:#{@match}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class NonMatchToken < Token
|
33
|
+
def initialize(non_match)
|
34
|
+
super(non_match)
|
35
|
+
end
|
36
|
+
def to_encrypted(args={})
|
37
|
+
@match
|
38
|
+
end
|
39
|
+
def to_decrypted(args={})
|
40
|
+
@match
|
41
|
+
end
|
42
|
+
def to_plain_text
|
43
|
+
@match
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
class Hiera
|
4
|
+
module Backend
|
5
|
+
module Eyaml
|
6
|
+
class Plugins
|
7
|
+
|
8
|
+
@@plugins = []
|
9
|
+
@@commands = []
|
10
|
+
@@options = []
|
11
|
+
|
12
|
+
def self.register_options args
|
13
|
+
options = args[ :options ]
|
14
|
+
plugin = args[ :plugin ]
|
15
|
+
options.each do |name, option_hash|
|
16
|
+
new_option = {:name => "#{plugin}_#{name}"}
|
17
|
+
new_option.merge! option_hash
|
18
|
+
@@options << new_option
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.options
|
23
|
+
@@options
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.find
|
27
|
+
|
28
|
+
this_version = Gem::Version.create(Hiera::Backend::Eyaml::VERSION)
|
29
|
+
index = Gem::VERSION >= "1.8.0" ? Gem::Specification : Gem.source_index
|
30
|
+
|
31
|
+
[index].flatten.each do |source|
|
32
|
+
specs = Gem::VERSION >= "1.6.0" ? source.latest_specs(true) : source.latest_specs
|
33
|
+
|
34
|
+
specs.each do |spec|
|
35
|
+
next if @@plugins.include? spec
|
36
|
+
|
37
|
+
dependency = spec.dependencies.find { |d| d.name == "hiera-eyaml" }
|
38
|
+
next if dependency && !dependency.requirement.satisfied_by?( this_version )
|
39
|
+
|
40
|
+
file = nil
|
41
|
+
if Gem::VERSION >= "1.8.0"
|
42
|
+
file = spec.matches_for_glob("**/eyaml_init.rb").first
|
43
|
+
else
|
44
|
+
file = Gem.searcher.matching_files(spec, "**/eyaml_init.rb").first
|
45
|
+
end
|
46
|
+
|
47
|
+
next unless file
|
48
|
+
|
49
|
+
@@plugins << spec
|
50
|
+
load file
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
@@plugins
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.plugins
|
60
|
+
@@plugins
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.commands
|
64
|
+
@@commands
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'base64'
|
2
|
+
# require 'hiera/backend/eyaml/subcommands/unknown_command'
|
3
|
+
|
4
|
+
class Hiera
|
5
|
+
module Backend
|
6
|
+
module Eyaml
|
7
|
+
|
8
|
+
class Subcommand
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :global_options, :options, :helptext
|
12
|
+
end
|
13
|
+
|
14
|
+
@@global_options = [
|
15
|
+
{:name => :encrypt_method,
|
16
|
+
:description => "Override default encryption and decryption method (default is PKCS7)",
|
17
|
+
:short => 'n',
|
18
|
+
:default => "pkcs7"},
|
19
|
+
{:name => :version,
|
20
|
+
:description => "Show version information"},
|
21
|
+
{:name => :verbose,
|
22
|
+
:description => "Be more verbose",
|
23
|
+
:short => 'v'},
|
24
|
+
{:name => :quiet,
|
25
|
+
:description => "Be less verbose",
|
26
|
+
:short => 'q'},
|
27
|
+
{:name => :help,
|
28
|
+
:description => "Information on how to use this command",
|
29
|
+
:short => 'h'}
|
30
|
+
]
|
31
|
+
|
32
|
+
def self.all_options
|
33
|
+
options = @@global_options.dup
|
34
|
+
options += self.options if self.options
|
35
|
+
options += Plugins.options
|
36
|
+
options
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.attach_option opt
|
40
|
+
self.suboptions += opt
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.find commandname = "unknown_command"
|
44
|
+
begin
|
45
|
+
require "hiera/backend/eyaml/subcommands/#{commandname.downcase}"
|
46
|
+
rescue Exception => e
|
47
|
+
require "hiera/backend/eyaml/subcommands/unknown_command"
|
48
|
+
return Hiera::Backend::Eyaml::Subcommands::UnknownCommand
|
49
|
+
end
|
50
|
+
command_module = Module.const_get('Hiera').const_get('Backend').const_get('Eyaml').const_get('Subcommands')
|
51
|
+
command_class = Utils.find_closest_class :parent_class => command_module, :class_name => commandname
|
52
|
+
command_class || Hiera::Backend::Eyaml::Subcommands::UnknownCommand
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parse
|
56
|
+
|
57
|
+
me = self
|
58
|
+
|
59
|
+
options = Trollop::options do
|
60
|
+
|
61
|
+
version "Hiera-eyaml version " + Hiera::Backend::Eyaml::VERSION.to_s
|
62
|
+
banner ["eyaml #{me.prettyname}: #{me.description}", me.helptext, "Options:"].compact.join("\n\n")
|
63
|
+
|
64
|
+
me.all_options.each do |available_option|
|
65
|
+
|
66
|
+
skeleton = {:description => "",
|
67
|
+
:short => :none}
|
68
|
+
|
69
|
+
skeleton.merge! available_option
|
70
|
+
opt skeleton[:name],
|
71
|
+
skeleton[:desc] || skeleton[:description], #legacy plugins
|
72
|
+
:short => skeleton[:short],
|
73
|
+
:default => skeleton[:default],
|
74
|
+
:type => skeleton[:type]
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
stop_on Eyaml.subcommands
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
if options[:verbose]
|
83
|
+
Hiera::Backend::Eyaml.verbosity_level += 1
|
84
|
+
end
|
85
|
+
|
86
|
+
if options[:quiet]
|
87
|
+
Hiera::Backend::Eyaml.verbosity_level = 0
|
88
|
+
end
|
89
|
+
|
90
|
+
if options[:encrypt_method]
|
91
|
+
Hiera::Backend::Eyaml.default_encryption_scheme = options[:encrypt_method]
|
92
|
+
end
|
93
|
+
|
94
|
+
options
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.validate args
|
99
|
+
args
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.description
|
103
|
+
"no description"
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.helptext
|
107
|
+
"Usage: eyaml #{self.prettyname} [options]"
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.execute
|
111
|
+
raise StandardError, "This command is not implemented yet (#{self.to_s.split('::').last})"
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.prettyname
|
115
|
+
Utils.snakecase self.to_s.split('::').last
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.hidden?
|
119
|
+
false
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'hiera/backend/eyaml/subcommand'
|
2
|
+
|
3
|
+
class Hiera
|
4
|
+
module Backend
|
5
|
+
module Eyaml
|
6
|
+
module Subcommands
|
7
|
+
|
8
|
+
class Createkeys < Subcommand
|
9
|
+
|
10
|
+
def self.options
|
11
|
+
[]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.description
|
15
|
+
"create a set of keys with which to encrypt/decrypt eyaml data"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.execute
|
19
|
+
encryptor = Encryptor.find Eyaml.default_encryption_scheme
|
20
|
+
encryptor.create_keys
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|