hiera-http-eyaml 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a59eab7214ebf3882c2cfad48b54e3369053f05
4
+ data.tar.gz: 56535a0f8f1e1d223519c63902b2148d3e8b9450
5
+ SHA512:
6
+ metadata.gz: da31505c73f8802e65b2789deaea72f5bc6e404fda129df4cb58dab27c971f84897893d4fa32bc8705d75fe6b0bb33182cc279416d39fbac9fdd331de746dced
7
+ data.tar.gz: c265b5415a6e799f4cd24af064abdbe49b4ab750521866e093535f4f63b24988a6fb6568d8282be251a48b626d9d949351cce3f4e978b92146d8374428cecd7c
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Ben P
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Hiera HTTP+eYAML Backend
2
+
3
+ This is a fork of the hiera-http backend that decrypts hiera-eyaml blobs.
4
+
5
+ - https://github.com/crayfishx/hiera-http/
6
+ - https://github.com/voxpupuli/hiera-eyaml/
7
+
8
+ ## Configuration
9
+
10
+ The configuration is the same as hiera-http's configuration, plus any
11
+ hiera-eyaml encryption options; at minimum you will need to set
12
+ `pkcs7_private_key` and `pkcs7_public_key`.
13
+
14
+ An example configuration for Hiera 3:
15
+
16
+ ```
17
+ ---
18
+ :backends:
19
+ - http_eyaml
20
+
21
+ :http_eyaml:
22
+ :host: 127.0.0.1
23
+ :port: 5984
24
+ :output: json
25
+ :cache_timeout: 10
26
+ :pkcs7_private_key: /path/to/private_key.pkcs7.pem
27
+ :pkcs7_public_key: /path/to/public_key.pkcs7.pem
28
+ :headers:
29
+ :X-Token: my-token
30
+ :paths:
31
+ - /configuration/%{fqdn}
32
+ - /configuration/%{env}
33
+ - /configuration/common
34
+ ```
35
+
36
+ ## Installation
37
+
38
+ Add this line to your puppet repo's Gemfile:
39
+
40
+ ```ruby
41
+ gem 'hiera-http-eyaml'
42
+ ```
43
+
44
+ Or install it with gem:
45
+
46
+ $ gem install hiera-http-eyaml
47
+
48
+ ## License
49
+
50
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
51
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hiera/backend/http_eyaml.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hiera-http-eyaml"
8
+ spec.version = Hiera::Backend::Http_eyaml::VERSION
9
+ spec.authors = ["benwtr"]
10
+ spec.email = ["ben@g.megatron.org"]
11
+
12
+ spec.summary = 'hiera-http-eyaml'
13
+ spec.description = %q{Fork of the Hiera HTTP backend with eYAML support}
14
+ spec.homepage = "https://github.com/benwtr/hiera-http-eyaml"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency('hiera-eyaml', '~>2.1.0')
24
+ spec.add_dependency('lookup_http', '>=1.0.0')
25
+ end
@@ -0,0 +1,9 @@
1
+ class Hiera
2
+ module Backend
3
+ module Http_eyaml
4
+
5
+ VERSION = "0.9.0"
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,201 @@
1
+ require 'hiera/backend/eyaml/encryptor'
2
+ require 'hiera/backend/eyaml/utils'
3
+ require 'hiera/backend/eyaml/options'
4
+ require 'hiera/backend/eyaml/parser/parser'
5
+
6
+ class Hiera
7
+ module Backend
8
+ class Http_eyaml_backend
9
+
10
+ def initialize
11
+ debug("Hiera HTTP-eYAML backend starting")
12
+
13
+ require 'lookup_http'
14
+ @config = Config[:http_eyaml]
15
+
16
+ lookup_supported_params = [
17
+ :host,
18
+ :port,
19
+ :output,
20
+ :failure,
21
+ :ignore_404,
22
+ :headers,
23
+ :http_connect_timeout,
24
+ :http_read_timeout,
25
+ :use_ssl,
26
+ :ssl_ca_cert,
27
+ :ssl_cert,
28
+ :ssl_key,
29
+ :ssl_verify,
30
+ :use_auth,
31
+ :auth_user,
32
+ :auth_pass,
33
+ ]
34
+ lookup_params = @config.select { |p| lookup_supported_params.include?(p) }
35
+
36
+ @lookup = LookupHttp.new(lookup_params.merge( { :debug_log => "Hiera.debug" } ))
37
+
38
+
39
+ @cache = {}
40
+ @cache_timeout = @config[:cache_timeout] || 10
41
+ @cache_clean_interval = @config[:cache_clean_interval] || 3600
42
+
43
+ @regex_key_match = nil
44
+
45
+ if confine_keys = @config[:confine_to_keys]
46
+ confine_keys.map! { |r| Regexp.new(r) }
47
+ @regex_key_match = Regexp.union(confine_keys)
48
+ end
49
+
50
+ end
51
+
52
+ def lookup(key, scope, order_override, resolution_type)
53
+
54
+ parse_eyaml_options(scope)
55
+
56
+ debug("Looking up #{key} in HTTP-eYAML backend")
57
+
58
+ require 'uri'
59
+
60
+ # if confine_to_keys is configured, then only proceed if one of the
61
+ # regexes matches the lookup key
62
+ #
63
+ if @regex_key_match
64
+ return nil unless key[@regex_key_match] == key
65
+ end
66
+
67
+
68
+ answer = nil
69
+
70
+ paths = @config[:paths].map { |p| Backend.parse_string(p, scope, { 'key' => key }) }
71
+ paths.insert(0, order_override) if order_override
72
+
73
+
74
+ paths.each do |path|
75
+
76
+ debug("Lookup #{key} from #{@config[:host]}:#{@config[:port]}#{path}")
77
+
78
+ result = http_get_and_parse_with_cache(URI.escape(path))
79
+ result = result[key] if result.is_a?(Hash)
80
+ next if result.nil?
81
+
82
+ parsed_result = parse_answer(result, scope)
83
+
84
+ case resolution_type
85
+ when :array
86
+ answer ||= []
87
+ answer << parsed_result
88
+ when :hash
89
+ answer ||= {}
90
+ answer = Backend.merge_answer(parsed_result, answer)
91
+ else
92
+ answer = parsed_result
93
+ break
94
+ end
95
+ end
96
+ answer
97
+ end
98
+
99
+
100
+ private
101
+
102
+
103
+ def debug(message)
104
+ Hiera.debug("[hiera-http_eyaml_backend]: #{message}")
105
+ end
106
+
107
+
108
+ def http_get_and_parse_with_cache(path)
109
+ return @lookup.get_parsed(path) if @cache_timeout <= 0
110
+
111
+ now = Time.now.to_i
112
+ expired_at = now + @cache_timeout
113
+
114
+ # Deleting all stale cache entries can be expensive. Do not do it every time
115
+ periodically_clean_cache(now) unless @cache_clean_interval == 0
116
+
117
+ # Just refresh the entry being requested for performance
118
+ if !@cache[path] || @cache[path][:expired_at] < now
119
+ @cache[path] = {
120
+ :expired_at => expired_at,
121
+ :result => @lookup.get_parsed(path)
122
+ }
123
+ end
124
+ @cache[path][:result]
125
+ end
126
+
127
+
128
+ def periodically_clean_cache(now)
129
+ return if now < @clean_cache_at.to_i
130
+
131
+ @clean_cache_at = now + @cache_clean_interval
132
+ @cache.delete_if do |_, entry|
133
+ entry[:expired_at] < now
134
+ end
135
+ end
136
+
137
+
138
+ def decrypt(data)
139
+ if encrypted?(data)
140
+ debug("Attempting to decrypt")
141
+
142
+ parser = Eyaml::Parser::ParserFactory.hiera_backend_parser
143
+ tokens = parser.parse(data)
144
+ decrypted = tokens.map{ |token| token.to_plain_text }
145
+ plaintext = decrypted.join
146
+
147
+ plaintext.chomp
148
+ else
149
+ data
150
+ end
151
+ end
152
+
153
+
154
+ def encrypted?(data)
155
+ /.*ENC\[.*?\]/ =~ data ? true : false
156
+ end
157
+
158
+
159
+ def parse_answer(data, scope, extra_data={})
160
+ if data.is_a?(Numeric) or data.is_a?(TrueClass) or data.is_a?(FalseClass)
161
+ return data
162
+ elsif data.is_a?(String)
163
+ return parse_string(data, scope, extra_data)
164
+ elsif data.is_a?(Hash)
165
+ answer = {}
166
+ data.each_pair do |key, val|
167
+ interpolated_key = Backend.parse_string(key, scope, extra_data)
168
+ answer[interpolated_key] = parse_answer(val, scope, extra_data)
169
+ end
170
+
171
+ return answer
172
+ elsif data.is_a?(Array)
173
+ answer = []
174
+ data.each do |item|
175
+ answer << parse_answer(item, scope, extra_data)
176
+ end
177
+
178
+ return answer
179
+ end
180
+ end
181
+
182
+
183
+ def parse_eyaml_options(scope)
184
+ Config[:http_eyaml].each do |key, value|
185
+ parsed_value = Backend.parse_string(value, scope)
186
+ Eyaml::Options[key] = parsed_value
187
+ debug("Set option: #{key} = #{parsed_value}")
188
+ end
189
+
190
+ Eyaml::Options[:source] = "hiera"
191
+ end
192
+
193
+
194
+ def parse_string(data, scope, extra_data={})
195
+ decrypted_data = decrypt(data)
196
+ Backend.parse_string(decrypted_data, scope, extra_data)
197
+ end
198
+
199
+ end
200
+ end
201
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hiera-http-eyaml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - benwtr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hiera-eyaml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.0
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.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: lookup_http
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
41
+ description: Fork of the Hiera HTTP backend with eYAML support
42
+ email:
43
+ - ben@g.megatron.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - hiera-http-eyaml.gemspec
54
+ - lib/hiera/backend/http_eyaml.rb
55
+ - lib/hiera/backend/http_eyaml_backend.rb
56
+ homepage: https://github.com/benwtr/hiera-http-eyaml
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.2.5
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: hiera-http-eyaml
80
+ test_files: []