hiera-eyaml 2.0.0 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: a8965f033228e9d0c47c6ec9e7b2a399b76ead46
4
- data.tar.gz: 222599950c2668eb59e99f42ad0b19cf1693d0c1
5
- SHA512:
6
- metadata.gz: 8ed7968fd5f5cb756bebcdcf82c8e3cc7c2284feb0e10d37e68e03f09daf1935f4fe71c48868b4119fe5b8240661a61c92f13f4bbc2066333508bef6b0b39621
7
- data.tar.gz: a586ad0604541e2639c1e20f3fd1d72ac2099df0f57c962350536e43f0a97265456412a926651ca20592bbef1cd5a259488136ad12eaafe1de74924e1e2d6ec7
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 848cae1bca737c5e047b25c5fc409f62e1d4df8d
4
+ data.tar.gz: 4c9fddfcdc14727770af712e2cbef650b1f1a0b4
5
+ SHA512:
6
+ metadata.gz: a982f17533e5edae37c2579b320b6e94eaf15d4523dfa21e23d8e7b540bd7b461a09bac16e43d863c9ffa576f90417303fae25bd3ef7e4fd4b401195ae72b50f
7
+ data.tar.gz: 2453d8553a3c731033161ce7c8181d210912e20095882e426ae6f5e3b47c6e720d2e8fa6a51f61857cd23dc9384019bf6cee71761547a4b5479268c7107e7298
data/.gitignore CHANGED
@@ -6,3 +6,5 @@ pkg/
6
6
  tmp/
7
7
  .DS_Store
8
8
  .rvmrc
9
+ .ruby-version
10
+ .ruby-gemset
data/Gemfile.lock CHANGED
@@ -19,9 +19,9 @@ GEM
19
19
  ffi (1.9.3)
20
20
  gherkin (2.12.2)
21
21
  multi_json (~> 1.3)
22
- hiera (1.3.0)
22
+ hiera (1.2.1)
23
23
  json_pure
24
- hiera-eyaml-plaintext (0.6)
24
+ hiera-eyaml-plaintext (0.5)
25
25
  highline (1.6.20)
26
26
  json_pure (1.8.1)
27
27
  multi_json (1.8.2)
data/README.md CHANGED
@@ -233,6 +233,27 @@ things:
233
233
  - nested thing 2.1
234
234
  ```
235
235
 
236
+ Configuration file for eyaml
237
+ ----------------------------
238
+
239
+ Default parameters for the eyaml command line tool can be provided by creating a configuration YAML file.
240
+
241
+ The location of the file defaults to `~/.eyaml/config.yaml` but can be overriden by setting `EYAML_CONFIG` environment variable.
242
+
243
+ The file takes any long form argument that you can provide on the command line. For example, to override the pkcs7 keys:
244
+ ```yaml
245
+ ---
246
+ pkcs7_private_key: '~/keys/eyaml/private_key.pkcs7.pem'
247
+ pkcs7_public_key: '~/keys/eyaml/public_key.pkcs7.pem'
248
+ ```
249
+
250
+ Or to override to use GPG by default:
251
+ ```yaml
252
+ ---
253
+ encrypt_method: 'gpg'
254
+ gpg_gnupghome: '~/alternative_gnupghome'
255
+ gpg_recipients: 'sihil@example.com,gtmtech@example.com,tpoulton@example.com'
256
+ ```
236
257
 
237
258
  Pluggable Encryption
238
259
  --------------------
data/hiera-eyaml.gemspec CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_dependency('trollop', '>=2.0')
21
- gem.add_dependency('highline', '>=1.6.19')
20
+ gem.add_dependency('hiera', '>= 1.2.1')
21
+ gem.add_dependency('trollop', '>= 2.0')
22
+ gem.add_dependency('highline', '>= 1.6.19')
22
23
  end
@@ -2,7 +2,7 @@ class Hiera
2
2
  module Backend
3
3
  module Eyaml
4
4
 
5
- VERSION = "2.0.0"
5
+ VERSION = "2.0.1"
6
6
  DESCRIPTION = "Hiera-eyaml is a backend for Hiera which provides OpenSSL encryption/decryption for Hiera properties"
7
7
 
8
8
  class RecoverableError < StandardError
@@ -15,7 +15,7 @@ class Hiera
15
15
  def self.subcommand
16
16
  @@subcommand
17
17
  end
18
-
18
+
19
19
  def self.default_encryption_scheme= new_encryption
20
20
  @@default_encryption_scheme = new_encryption
21
21
  end
@@ -41,7 +41,7 @@ class Hiera
41
41
  def self.subcommands
42
42
  @@subcommands
43
43
  end
44
-
44
+
45
45
  end
46
46
  end
47
47
  end
@@ -11,12 +11,15 @@ class Hiera
11
11
  class Pkcs7 < Encryptor
12
12
 
13
13
  self.options = {
14
- :private_key => { :desc => "Private key directory",
14
+ :private_key => { :desc => "Path to private key",
15
15
  :type => :string,
16
16
  :default => "./keys/private_key.pkcs7.pem" },
17
- :public_key => { :desc => "Public key directory",
17
+ :public_key => { :desc => "Path to public key",
18
18
  :type => :string,
19
- :default => "./keys/public_key.pkcs7.pem" }
19
+ :default => "./keys/public_key.pkcs7.pem" },
20
+ :subject => { :desc => "Subject to use for certificate when creating keys",
21
+ :type => :string,
22
+ :default => "/" },
20
23
  }
21
24
 
22
25
  self.tag = "PKCS7"
@@ -59,14 +62,15 @@ class Hiera
59
62
 
60
63
  public_key = self.option :public_key
61
64
  private_key = self.option :private_key
65
+ subject = self.option :subject
62
66
 
63
67
  key = OpenSSL::PKey::RSA.new(2048)
64
68
  Utils.ensure_key_dir_exists private_key
65
69
  Utils.write_important_file :filename => private_key, :content => key.to_pem, :mode => 0600
66
70
 
67
- name = OpenSSL::X509::Name.parse("/")
68
71
  cert = OpenSSL::X509::Certificate.new()
69
- cert.serial = 0
72
+ cert.subject = OpenSSL::X509::Name.parse(subject)
73
+ cert.serial = 1
70
74
  cert.version = 2
71
75
  cert.not_before = Time.now
72
76
  cert.not_after = if 1.size == 8 # 64bit
@@ -24,7 +24,7 @@ class Hiera
24
24
  Utils::debug "Dump of eyaml tool options dict:"
25
25
  Utils::debug "--------------------------------"
26
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})"
27
+ Utils::debug sprintf "%18s %-18s = %18s %-18s", "(#{k.class.name})", k.to_s, "(#{v.class.name})", v.to_s
28
28
  end
29
29
  Utils::debug "--------------------------------"
30
30
  end
@@ -113,7 +113,7 @@ class Hiera
113
113
 
114
114
  class DecStringTokenType < TokenType
115
115
  def initialize
116
- @regex = /DEC(\(\d+\))?::(\w+)\[(.+?)\]\!/
116
+ @regex = /DEC(\(\d+\))?::(\w+)\[(.+?)\]\!/m
117
117
  end
118
118
  def create_token(string)
119
119
  md = @regex.match(string)
@@ -1,4 +1,5 @@
1
1
  require 'base64'
2
+ require 'yaml'
2
3
  # require 'hiera/backend/eyaml/subcommands/unknown_command'
3
4
 
4
5
  class Hiera
@@ -29,10 +30,32 @@ class Hiera
29
30
  :short => 'h'}
30
31
  ]
31
32
 
33
+ def self.load_config_file
34
+ config_file=ENV['EYAML_CONFIG'] || "#{ENV['HOME']}/.eyaml/config.yaml"
35
+ begin
36
+ config = YAML.load_file(config_file)
37
+ Utils::info "Loaded config from #{config_file}"
38
+ config
39
+ rescue Errno::ENOENT, IndexError
40
+ {}
41
+ end
42
+ end
43
+
32
44
  def self.all_options
33
45
  options = @@global_options.dup
34
46
  options += self.options if self.options
35
47
  options += Plugins.options
48
+ # merge in defaults from configuration file
49
+ config_file = self.load_config_file
50
+ options.map!{ | opt|
51
+ key_name = "#{opt[:name]}"
52
+ if config_file.has_key? key_name
53
+ opt[:default] = config_file[key_name]
54
+ opt
55
+ else
56
+ opt
57
+ end
58
+ }
36
59
  options
37
60
  end
38
61
 
@@ -140,7 +140,7 @@ class Hiera
140
140
  message = self.structure_message messageinfo
141
141
  message = "[#{message[:from]}] !!! #{message[:msg]}"
142
142
  if self.hiera?
143
- Hiera.warn format_message msg
143
+ Hiera.warn message
144
144
  else
145
145
  STDERR.puts message
146
146
  end
@@ -2,123 +2,134 @@ require 'hiera/backend/eyaml/encryptor'
2
2
  require 'hiera/backend/eyaml/utils'
3
3
  require 'hiera/backend/eyaml/options'
4
4
  require 'hiera/backend/eyaml/parser/parser'
5
+ require 'hiera/filecache'
6
+
5
7
  require 'yaml'
6
8
 
7
9
  class Hiera
8
10
  module Backend
9
11
  class Eyaml_backend
10
12
 
11
- def initialize
12
- @extension = Config[:eyaml][:extension] ? Config[:eyaml][:extension] : "eyaml"
13
+ attr_reader :extension
14
+
15
+ def initialize(cache = nil)
16
+ debug("Hiera eYAML backend starting")
17
+
18
+ @cache = cache || Filecache.new
19
+ @extension = Config[:eyaml][:extension] || "eyaml"
13
20
  end
14
21
 
15
22
  def lookup(key, scope, order_override, resolution_type)
16
-
17
- debug("Lookup called for key #{key}")
18
23
  answer = nil
19
24
 
20
- Backend.datasources(scope, order_override) do |source|
21
- eyaml_file = Backend.datafile(:eyaml, scope, source, @extension) || next
25
+ parse_options(scope)
22
26
 
23
- debug("Processing datasource: #{eyaml_file}")
27
+ debug("Looking up #{key} in eYAML backend")
24
28
 
25
- data = YAML.load(File.read( eyaml_file ))
29
+ Backend.datasources(scope, order_override) do |source|
30
+ debug("Looking for data source #{source}")
31
+ eyaml_file = Backend.datafile(:eyaml, scope, source, extension) || next
26
32
 
27
- next if data.nil? or data.empty?
28
- debug ("Data contains valid YAML")
33
+ next unless File.exists?(eyaml_file)
29
34
 
30
- next unless data.include?(key)
31
- debug ("Key #{key} found in YAML document")
32
-
33
- parsed_answer = parse_answer(key, data[key], scope)
34
-
35
- begin
36
- case resolution_type
37
- when :array
38
- debug("Appending answer array")
39
- raise Exception, "Hiera type mismatch: expected Array and got #{parsed_answer.class}" unless parsed_answer.kind_of? Array or parsed_answer.kind_of? String
40
- answer ||= []
41
- answer << parsed_answer
42
- when :hash
43
- debug("Merging answer hash")
44
- raise Exception, "Hiera type mismatch: expected Hash and got #{parsed_answer.class}" unless parsed_answer.kind_of? Hash
45
- answer ||= {}
46
- answer = Backend.merge_answer(parsed_answer,answer)
47
- else
48
- debug("Assigning answer variable")
49
- answer = parsed_answer
50
- break
51
- end
52
- rescue NoMethodError
53
- raise Exception, "Resolution type is #{resolution_type} but parsed_answer is a #{parsed_answer.class}"
35
+ data = @cache.read(eyaml_file, Hash) do |data|
36
+ YAML.load(data) || {}
54
37
  end
55
- end
56
38
 
57
- answer
58
- end
39
+ next if data.empty?
40
+ next unless data.include?(key)
59
41
 
60
- def parse_answer(key, data, scope, extra_data={})
61
- if data.is_a?(Numeric) or data.is_a?(TrueClass) or data.is_a?(FalseClass)
62
- # Can't be encrypted
63
- data
64
- elsif data.is_a?(String)
65
- parsed_string = Backend.parse_string(data, scope)
66
- decrypt(key, parsed_string, scope)
67
- elsif data.is_a?(Hash)
68
- answer = {}
69
- data.each_pair do |key, val|
70
- answer[key] = parse_answer(key, val, scope, extra_data)
42
+ # Extra logging that we found the key. This can be outputted
43
+ # multiple times if the resolution type is array or hash but that
44
+ # should be expected as the logging will then tell the user ALL the
45
+ # places where the key is found.
46
+ debug("Found #{key} in #{source}")
47
+
48
+ # for array resolution we just append to the array whatever
49
+ # we find, we then goes onto the next file and keep adding to
50
+ # the array
51
+ #
52
+ # for priority searches we break after the first found data item
53
+ new_answer = parse_answer(data[key], scope)
54
+ case resolution_type
55
+ when :array
56
+ raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
57
+ answer ||= []
58
+ answer << new_answer
59
+ when :hash
60
+ raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
61
+ answer ||= {}
62
+ answer = Backend.merge_answer(new_answer,answer)
63
+ else
64
+ answer = new_answer
65
+ break
71
66
  end
72
- answer
73
- elsif data.is_a?(Array)
74
- answer = []
75
- data.each do |item|
76
- answer << parse_answer(key, item, scope, extra_data)
77
- end
78
- answer
79
67
  end
80
- end
81
68
 
82
- def deblock block_string
83
- block_string.gsub(/[ \n]/, '')
69
+ return answer
84
70
  end
85
71
 
86
- def decrypt(key, value, scope)
87
-
88
- if encrypted? value
72
+ private
89
73
 
90
- debug "Attempting to decrypt: #{key}"
91
-
92
- Config[:eyaml].each do |config_key, config_value|
93
- config_value = Backend.parse_string(Config[:eyaml][config_key], scope)
94
- debug "Setting: #{config_key} = #{config_value}"
95
- Eyaml::Options[config_key] = config_value
96
- end
74
+ def debug(message)
75
+ Hiera.debug("[eyaml_backend]: #{message}")
76
+ end
97
77
 
98
- Eyaml::Options[:source] = "hiera"
78
+ def decrypt(data)
79
+ if encrypted?(data)
80
+ debug("Attempting to decrypt")
99
81
 
100
82
  parser = Eyaml::Parser::ParserFactory.hiera_backend_parser
101
- tokens = parser.parse(value)
83
+ tokens = parser.parse(data)
102
84
  decrypted = tokens.map{ |token| token.to_plain_text }
103
85
  plaintext = decrypted.join
104
86
 
105
87
  plaintext.chomp
106
-
107
88
  else
108
- value
89
+ data
109
90
  end
110
91
  end
111
92
 
112
- def encrypted?(value)
113
- if value.match(/.*ENC\[.*?\]/) then true else false end
93
+ def encrypted?(data)
94
+ /.*ENC\[.*?\]/ =~ data ? true : false
95
+ end
96
+
97
+ def parse_answer(data, scope, extra_data={})
98
+ if data.is_a?(Numeric) or data.is_a?(TrueClass) or data.is_a?(FalseClass)
99
+ return data
100
+ elsif data.is_a?(String)
101
+ return parse_string(data, scope, extra_data)
102
+ elsif data.is_a?(Hash)
103
+ answer = {}
104
+ data.each_pair do |key, val|
105
+ interpolated_key = Backend.parse_string(key, scope, extra_data)
106
+ answer[interpolated_key] = parse_answer(val, scope, extra_data)
107
+ end
108
+
109
+ return answer
110
+ elsif data.is_a?(Array)
111
+ answer = []
112
+ data.each do |item|
113
+ answer << parse_answer(item, scope, extra_data)
114
+ end
115
+
116
+ return answer
117
+ end
114
118
  end
115
119
 
116
- def debug(msg)
117
- Hiera.debug("[eyaml_backend]: #{msg}")
120
+ def parse_options(scope)
121
+ Config[:eyaml].each do |key, value|
122
+ parsed_value = Backend.parse_string(value, scope)
123
+ Eyaml::Options[key] = parsed_value
124
+ debug("Set option: #{key} = #{parsed_value}")
125
+ end
126
+
127
+ Eyaml::Options[:source] = "hiera"
118
128
  end
119
129
 
120
- def warn(msg)
121
- Hiera.warn("[eyaml_backend]: #{msg}")
130
+ def parse_string(data, scope, extra_data={})
131
+ decrypted_data = decrypt(data)
132
+ Backend.parse_string(decrypted_data, scope, extra_data)
122
133
  end
123
134
  end
124
135
  end
metadata CHANGED
@@ -1,50 +1,55 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hiera-eyaml
3
- version: !ruby/object:Gem::Version
4
- version: 2.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.1
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Tom Poulton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-05 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: trollop
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
11
+
12
+ date: 2014-03-07 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hiera
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 1.2.1
20
22
  type: :runtime
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: trollop
21
26
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: highline
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: 1.6.19
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "2.0"
34
32
  type: :runtime
33
+ version_requirements: *id002
34
+ - !ruby/object:Gem::Dependency
35
+ name: highline
35
36
  prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
37
+ requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
40
41
  version: 1.6.19
42
+ type: :runtime
43
+ version_requirements: *id003
41
44
  description: Hiera backend for decrypting encrypted yaml properties
42
45
  email:
43
- executables:
46
+ executables:
44
47
  - eyaml
45
48
  extensions: []
49
+
46
50
  extra_rdoc_files: []
47
- files:
51
+
52
+ files:
48
53
  - .gitignore
49
54
  - .travis.yml
50
55
  - Gemfile
@@ -81,27 +86,30 @@ files:
81
86
  - sublime_text/eyaml.syntax_definition.json
82
87
  - tools/regem.sh
83
88
  homepage: http://github.com/TomPoulton/hiera-eyaml
84
- licenses:
89
+ licenses:
85
90
  - MIT
86
91
  metadata: {}
92
+
87
93
  post_install_message:
88
94
  rdoc_options: []
89
- require_paths:
95
+
96
+ require_paths:
90
97
  - lib
91
- required_ruby_version: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - '>='
94
- - !ruby/object:Gem::Version
95
- version: '0'
96
- required_rubygems_version: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - '>='
99
- - !ruby/object:Gem::Version
100
- version: '0'
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - &id004
101
+ - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - *id004
101
107
  requirements: []
108
+
102
109
  rubyforge_project:
103
- rubygems_version: 2.0.11
110
+ rubygems_version: 2.0.14
104
111
  signing_key:
105
112
  specification_version: 4
106
113
  summary: OpenSSL Encryption backend for Hiera
107
114
  test_files: []
115
+