hiera-ehttp 0.0.1 → 0.0.2
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.
- data/README.md +6 -2
- data/Rakefile +4 -4
- data/bin/couchrub.rb +149 -0
- data/bin/decrypt.rb +15 -0
- data/bin/encrypt.rb +16 -0
- data/bin/hiera-ehttp +29 -8
- data/bin/hiera-ehttp-couch.rb +72 -0
- data/lib/hiera/backend/ehttp_backend.rb +0 -4
- metadata +12 -4
data/README.md
CHANGED
@@ -33,6 +33,10 @@ Grab the hiera-ehttp gem and then add this to your hiera config file
|
|
33
33
|
Using the command line utility you can encrypt a value
|
34
34
|
|
35
35
|
hiera-ehttp encrypt -c cert.pem -s "secret value"
|
36
|
+
|
37
|
+
The command line utility also supports the rest api that
|
38
|
+
couch uses. All the other apis are sad, but I will try to
|
39
|
+
make them happier as time permits.
|
36
40
|
|
37
41
|
Configuration Parameters
|
38
42
|
------------------------
|
@@ -82,5 +86,5 @@ make an issue so I know, or create a fix and create a pull request.
|
|
82
86
|
Credits
|
83
87
|
-------
|
84
88
|
|
85
|
-
* Much of this code comes from the original hiera-http created by Craig Dunn <craig@craigdunn.org>
|
86
|
-
* SSL components contributed from Ben Ford <ben.ford@puppetlabs.com>
|
89
|
+
* Much of this code comes from the original hiera-http created by Craig Dunn <craig@craigdunn.org>
|
90
|
+
* SSL components contributed from Ben Ford <ben.ford@puppetlabs.com>
|
data/Rakefile
CHANGED
@@ -2,11 +2,11 @@ require 'rubygems'
|
|
2
2
|
require 'rubygems/package_task'
|
3
3
|
|
4
4
|
spec = Gem::Specification.new do |gem|
|
5
|
-
gem.name =
|
6
|
-
gem.version =
|
5
|
+
gem.name = File.basename(`git rev-parse --show-toplevel`).chop
|
6
|
+
gem.version = `gitver version`
|
7
7
|
|
8
|
-
gem.author =
|
9
|
-
gem.email =
|
8
|
+
gem.author = `git config --get user.name`
|
9
|
+
gem.email = `git config --get user.email`
|
10
10
|
gem.homepage = "http://github.com/floomby/hiera-ehttp"
|
11
11
|
gem.summary = "HTTP backend for Hiera supporting encrypted entries"
|
12
12
|
gem.description = "Hiera backend for looking up data over HTTP APIs with support for encrypted values"
|
data/bin/couchrub.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# TODO: ssl, better error handling, option parsing, improve everything
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'net/http'
|
7
|
+
require 'ostruct'
|
8
|
+
|
9
|
+
# I am creating a database class
|
10
|
+
# The idea is to grab the database from
|
11
|
+
# couch, preform whatever manipulation
|
12
|
+
# that you want on it and then sync it back
|
13
|
+
# up to couch with a new revision number
|
14
|
+
|
15
|
+
# the goal here is to abstract out the revisioning
|
16
|
+
# the merge strategy is to go with the most recent
|
17
|
+
# version. This introduce races, but I don't care
|
18
|
+
# right now in this case
|
19
|
+
|
20
|
+
class CouchDocument
|
21
|
+
# all documents will be created by json
|
22
|
+
# either from the database or internaly
|
23
|
+
|
24
|
+
attr_reader :id, :data
|
25
|
+
|
26
|
+
def initialize json
|
27
|
+
|
28
|
+
@data = json
|
29
|
+
|
30
|
+
@rev = @data['_rev']
|
31
|
+
@id = @data['_id']
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# If I inherite Hash then I get these for free
|
36
|
+
def [] key
|
37
|
+
@data[key]
|
38
|
+
end
|
39
|
+
|
40
|
+
def []= key, value
|
41
|
+
@data[key] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
class Couch
|
47
|
+
|
48
|
+
def initialize args
|
49
|
+
|
50
|
+
# set default host and port
|
51
|
+
@host = '127.0.0.1'
|
52
|
+
@port = '5984'
|
53
|
+
|
54
|
+
# set all the parameters
|
55
|
+
args.each do |key, val|
|
56
|
+
(instance_variable_set "@#{key}", val) unless val.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
@http = Net::HTTP.new @host, @port
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# The things that I want right here are:
|
64
|
+
# x create a db
|
65
|
+
# x delete a db
|
66
|
+
# - put new a document
|
67
|
+
# - get a document
|
68
|
+
# - put an updated document
|
69
|
+
|
70
|
+
|
71
|
+
# database manipulation
|
72
|
+
|
73
|
+
def create_db name
|
74
|
+
|
75
|
+
req = Net::HTTP::Put.new "/#{name}"
|
76
|
+
ret = @http.request req
|
77
|
+
|
78
|
+
puts "Creating Database #{name} => #{ret.msg} (#{ret.code})\n"
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_db name
|
83
|
+
|
84
|
+
req = Net::HTTP::Delete.new "/#{name}"
|
85
|
+
ret = @http.request req
|
86
|
+
|
87
|
+
puts "Deleting Database #{name} => #{ret.msg} (#{ret.code})\n"
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_doc db_name, doc_name
|
92
|
+
|
93
|
+
req = Net::HTTP::Get.new "/#{db_name}/#{doc_name}"
|
94
|
+
ret = @http.request req
|
95
|
+
|
96
|
+
if ret.code == '200'
|
97
|
+
puts "Successfuly Got Document #{db_name}/#{doc_name} => #{ret.msg} (#{ret.code})\n"
|
98
|
+
doc = CouchDocument.new JSON.parse ret.body
|
99
|
+
else
|
100
|
+
puts "Error Getting Document #{db_name}/#{doc_name} => #{ret.msg} (#{ret.code})\n"
|
101
|
+
doc = CouchDocument.new JSON.parse "{}"
|
102
|
+
end
|
103
|
+
|
104
|
+
doc
|
105
|
+
end
|
106
|
+
|
107
|
+
def put_doc db_name, doc_name, doc
|
108
|
+
|
109
|
+
req = Net::HTTP::Put.new "/#{db_name}/#{doc_name}"
|
110
|
+
req.add_field 'Content-Type', 'application/json'
|
111
|
+
req.body = JSON.dump doc.data
|
112
|
+
ret = @http.request req
|
113
|
+
|
114
|
+
if ret.code == '200'
|
115
|
+
|
116
|
+
puts "Succesfuly Putting Document #{db_name}/#{doc_name} => #{ret.msg} (#{ret.code})\n"
|
117
|
+
|
118
|
+
# lets delete the old revsion
|
119
|
+
delete_
|
120
|
+
|
121
|
+
else
|
122
|
+
puts "Error Putting Document #{db_name}/#{doc_name} => #{ret.msg} (#{ret.code})\n"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def delete_doc db_name, doc_name, doc
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
#couch = Couch.new :host => '127.0.0.1', :port => '5984'
|
135
|
+
|
136
|
+
|
137
|
+
#couch.delete_db 'blahness'
|
138
|
+
#couch.create_db 'blahness'
|
139
|
+
|
140
|
+
#test = CouchDocument.new JSON.parse File.read 'blah.json'
|
141
|
+
|
142
|
+
#couch.new_doc 'blahness', 'doc', test
|
143
|
+
|
144
|
+
#test = couch.get_doc 'testdb', 'dne'
|
145
|
+
|
146
|
+
#test['test'] = 'changed value'
|
147
|
+
#puts test.data
|
148
|
+
|
149
|
+
#couch.put_doc 'blahness', 'doc', test
|
data/bin/decrypt.rb
ADDED
data/bin/encrypt.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module HieraEhttp
|
5
|
+
class Encrypt
|
6
|
+
def initialize cert
|
7
|
+
@cert = cert
|
8
|
+
# We like AES 128 in CBC mode
|
9
|
+
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
10
|
+
end
|
11
|
+
|
12
|
+
def encryptPKCS7 value
|
13
|
+
"\"ENC[PKCS7," + (Base64.encode64 (OpenSSL::PKCS7::encrypt [@cert], value, @cipher, OpenSSL::PKCS7::BINARY).to_der).delete("\n\r") + "]\""
|
14
|
+
end
|
15
|
+
end # class Encrypt
|
16
|
+
end # module HieraEhttp
|
data/bin/hiera-ehttp
CHANGED
@@ -7,6 +7,11 @@ require 'ostruct'
|
|
7
7
|
require 'pp'
|
8
8
|
require 'time'
|
9
9
|
require 'date'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
require_relative 'encrypt.rb'
|
13
|
+
require_relative 'hiera-ehttp-couch.rb'
|
14
|
+
|
10
15
|
|
11
16
|
class HieraEhttpKeys
|
12
17
|
@banner = "Usage: hiera-ehttp keys [options]"
|
@@ -67,13 +72,14 @@ class HieraEhttpEncrypt
|
|
67
72
|
options = OpenStruct.new
|
68
73
|
|
69
74
|
options.strings = []
|
75
|
+
options.jsons = []
|
70
76
|
|
71
77
|
opt_parser = OptionParser.new do |opts|
|
72
78
|
opts.banner = @banner
|
73
79
|
|
74
|
-
opts.on("-c", "--certfile <certficate>", "Certificate to encrypt with")
|
75
|
-
opts.on("-s", "--string <value>", "String to encrypt")
|
76
|
-
#opts.on("-j", "--json <file>", "Encrypt all of the values in a json file")
|
80
|
+
opts.on("-c", "--certfile <certficate>", "Certificate to encrypt with") { |cert| options.certificate = cert }
|
81
|
+
opts.on("-s", "--string <value>", "String to encrypt") { |str| options.strings << str }
|
82
|
+
#opts.on("-j", "--json <file>", "Encrypt all of the values in a json file") { |file| options.jsons << file }
|
77
83
|
#opts.on("-y", "--yaml <file>", "Encrypt all of the values in a yaml file") do |file| options.yamls << file end
|
78
84
|
|
79
85
|
end
|
@@ -89,19 +95,28 @@ class HieraEhttpEncrypt
|
|
89
95
|
|
90
96
|
# encrypt strings, jsons, and yamls
|
91
97
|
strings options.strings, cert, cipher
|
92
|
-
|
98
|
+
jsons options.jsons, cert, cipher
|
93
99
|
#yamls options.yamls, cert, cipher
|
94
100
|
end
|
95
101
|
|
96
102
|
def self.strings(strings, cert, cipher)
|
97
103
|
encs = []
|
98
|
-
strings.each do |
|
99
|
-
puts
|
104
|
+
strings.each do |value|
|
105
|
+
puts "\"#{value}\":" + (enc value, cert, cipher) + "\n"
|
100
106
|
end
|
101
107
|
end
|
102
108
|
|
109
|
+
def self.enc(value, cert, cipher)
|
110
|
+
("\"ENC[PKCS7," + (Base64.encode64 (OpenSSL::PKCS7::encrypt [cert], value, cipher, OpenSSL::PKCS7::BINARY).to_der).delete("\n\r") + "]\"")
|
111
|
+
end
|
112
|
+
|
103
113
|
def self.jsons(jsons, cert, cipher)
|
104
|
-
|
114
|
+
jsons.each do |json|
|
115
|
+
doc = JSON.parse (File.read json)
|
116
|
+
|
117
|
+
|
118
|
+
File.open('enc.' + json, 'w') { |file| file.write JSON.dump doc }
|
119
|
+
end
|
105
120
|
end
|
106
121
|
|
107
122
|
def self.yamls(yamls, cert, cipher)
|
@@ -113,6 +128,9 @@ class HieraEhttpEncrypt
|
|
113
128
|
end
|
114
129
|
end
|
115
130
|
|
131
|
+
|
132
|
+
|
133
|
+
|
116
134
|
usage = "Usage: hiera-ehttp <action>"
|
117
135
|
|
118
136
|
action, *args = ARGV
|
@@ -131,7 +149,10 @@ when 'encrypt'
|
|
131
149
|
options = HieraEhttpEncrypt.parse args
|
132
150
|
HieraEhttpEncrypt.encrypt options
|
133
151
|
|
152
|
+
when 'couch'
|
153
|
+
options = HieraEhttp::HieraEhttpCouch.parse args
|
154
|
+
HieraEhttp::HieraEhttpCouch.go options
|
134
155
|
|
135
156
|
else
|
136
|
-
puts 'invalid action (valid actions: keys, encrypt)'
|
157
|
+
puts 'invalid action (valid actions: keys, encrypt, couch)'
|
137
158
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# This is probably outside of the scope that the gem should
|
2
|
+
# be doing, but I want this feture so I am putting it in here
|
3
|
+
# anyways
|
4
|
+
#
|
5
|
+
# It will probably be very hacky and barely work but I don't
|
6
|
+
# expect anyone but me to use it so no loss there
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'ostruct'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
require_relative 'couchrub.rb'
|
13
|
+
|
14
|
+
module HieraEhttp
|
15
|
+
class HieraEhttpCouch
|
16
|
+
|
17
|
+
@banner = "Usage: hiera-ehhtp couch [options]"
|
18
|
+
|
19
|
+
def self.parse args
|
20
|
+
options = OpenStruct.new
|
21
|
+
|
22
|
+
# The default host and port
|
23
|
+
options.host = '127.0.0.1'
|
24
|
+
options.port = '5984'
|
25
|
+
|
26
|
+
# The default database and document
|
27
|
+
options.database = 'hiera'
|
28
|
+
options.document = 'defaults'
|
29
|
+
|
30
|
+
options.items = []
|
31
|
+
|
32
|
+
opt_parser = OptionParser.new do |opts|
|
33
|
+
opts.banner = @banner
|
34
|
+
|
35
|
+
opts.on("-i", "--item <\"key\":\"value\">", "Key/value to add") { |item| options.items << item }
|
36
|
+
opts.on("-h", "--host <host>", "Host (defualt 127.0.0.1)") { |host| options.host = host }
|
37
|
+
opts.on("-p", "--port <port>", "Port (defualt 5984)") { |port| options.port = port }
|
38
|
+
opts.on("-c", "--cert <certificat>", "Encryption certificate") { |cert| options.cert = cert }
|
39
|
+
opts.on("-b", "--database <database>", "Database to use") { |db| options.database = db }
|
40
|
+
opts.on("-d", "--document <document>", "Document to use") { |doc| options.document = doc }
|
41
|
+
end
|
42
|
+
|
43
|
+
opt_parser.parse! args
|
44
|
+
options
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.go options
|
48
|
+
# Read in the certificate
|
49
|
+
cert = OpenSSL::X509::Certificate.new File.read options.cert
|
50
|
+
|
51
|
+
# create an encrypter to use
|
52
|
+
encrypter = Encrypt.new cert
|
53
|
+
|
54
|
+
couch = Couch.new :host => options.host, :port => options.port
|
55
|
+
|
56
|
+
# We can ensure the db exist by creating it
|
57
|
+
# If it alread exist nothing happens
|
58
|
+
couch.create_db options.database
|
59
|
+
doc = couch.get_doc options.database, options.document
|
60
|
+
|
61
|
+
# Now we update the document
|
62
|
+
options.items.each do |item|
|
63
|
+
a = /^\"(([^\"]|\\\")+)\":\"(([^\"]|\\\")+)\"$/.match item
|
64
|
+
doc[a[1]] = encrypter.encryptPKCS7 a[3]
|
65
|
+
end
|
66
|
+
|
67
|
+
couch.put_doc options.database, options.document, doc
|
68
|
+
end
|
69
|
+
|
70
|
+
end # class HieraEhttpCouch
|
71
|
+
end # module HieraEhttp
|
72
|
+
|
@@ -8,8 +8,6 @@ class Hiera
|
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
|
11
|
-
Hiera.debug "test"
|
12
|
-
|
13
11
|
@config = Config[:ehttp]
|
14
12
|
|
15
13
|
@http = Net::HTTP.new @config[:host], @config[:port]
|
@@ -43,8 +41,6 @@ class Hiera
|
|
43
41
|
|
44
42
|
def lookup(key, scope, order_override, resolution_type)
|
45
43
|
|
46
|
-
Hiera.debug "test"
|
47
|
-
|
48
44
|
answer = nil
|
49
45
|
|
50
46
|
paths = @config[:paths].map { |p| Backend.parse_string p, scope, { 'key' => key } }
|
metadata
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiera-ehttp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- ! 'floomby
|
9
|
+
|
10
|
+
'
|
9
11
|
autorequire:
|
10
12
|
bindir: bin
|
11
13
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
14
|
+
date: 2014-04-22 00:00:00.000000000 Z
|
13
15
|
dependencies:
|
14
16
|
- !ruby/object:Gem::Dependency
|
15
17
|
name: json
|
@@ -29,7 +31,9 @@ dependencies:
|
|
29
31
|
version: '0'
|
30
32
|
description: Hiera backend for looking up data over HTTP APIs with support for encrypted
|
31
33
|
values
|
32
|
-
email: floomby@nmt.edu
|
34
|
+
email: ! 'floomby@nmt.edu
|
35
|
+
|
36
|
+
'
|
33
37
|
executables:
|
34
38
|
- hiera-ehttp
|
35
39
|
extensions: []
|
@@ -38,7 +42,11 @@ files:
|
|
38
42
|
- .gitignore
|
39
43
|
- README.md
|
40
44
|
- Rakefile
|
45
|
+
- bin/couchrub.rb
|
46
|
+
- bin/decrypt.rb
|
47
|
+
- bin/encrypt.rb
|
41
48
|
- bin/hiera-ehttp
|
49
|
+
- bin/hiera-ehttp-couch.rb
|
42
50
|
- lib/hiera/backend/ehttp_backend.rb
|
43
51
|
homepage: http://github.com/floomby/hiera-ehttp
|
44
52
|
licenses: []
|