salthiera 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +158 -13
- data/lib/salt_hiera/plugins/efiles.rb +59 -0
- data/lib/salt_hiera/plugins/eyaml.rb +1 -2
- data/lib/salt_hiera/salt_hiera.rb +1 -1
- data/salt/pillar/salthiera.py +44 -0
- data/tools/regem.sh +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
|
4
|
-
|
3
|
+
data.tar.gz: 9bd3abfbe7c895386dfe61fd6811503276f7c2f1
|
4
|
+
metadata.gz: 6d925891be35b8f2cbac96e83c8adbf9c5cbeeb6
|
5
5
|
SHA512:
|
6
|
-
|
7
|
-
|
6
|
+
data.tar.gz: e249fd728cd2c32c1acdea9d2c9bd9cbf6ee5ce95f107634c0bdb0d2a6d9de9b107d59922403c8cc2f12479f44a888eacb00a67a68a0a5cdc6ab9d9329185566
|
7
|
+
metadata.gz: 89cfaa09056892f404cccc8474b5d8400a40f13cc6b54e895cf8e430246f3c7c9457fc1b362c6e34c92d22a513a8c8745852c29c47d392eadac3195d0ab034d3
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
SaltHiera
|
2
2
|
=========
|
3
3
|
|
4
|
-
[![Build Status](https://travis-ci.org/Gtmtechltd/salthiera.png?branch=master)](https://travis-ci.org/gtmtechltd/salthiera)
|
5
|
-
|
6
4
|
salthiera is a hiera-like tool which is designed to work with SaltStack Pillars via the ext_pillar option.
|
7
5
|
|
8
6
|
Background
|
@@ -17,25 +15,172 @@ Initially this project is written in Ruby as a gem, however I intend to port to
|
|
17
15
|
Setup
|
18
16
|
-----
|
19
17
|
|
20
|
-
|
18
|
+
#### Installing salthiera
|
19
|
+
|
20
|
+
(on saltmaster only)
|
21
21
|
|
22
22
|
$ gem install salthiera
|
23
23
|
|
24
|
-
### Define a salthiera.yaml configuration file
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
#### Define a /etc/salt/salthiera.yaml configuration file
|
26
|
+
|
27
|
+
---
|
28
|
+
hierarchy:
|
29
|
+
- yaml:/srv/salt/environments/%{saltenvironment}/*.yaml.%{id} # e.g. production/haproxy.yaml.dmzserver01
|
30
|
+
- yaml:/srv/salt/environments/%{saltenvironment}/*.yaml # e.g. production/haproxy.yaml
|
31
|
+
- yaml:/srv/salt/environments/common/*.yaml # e.g. common/haproxy.yaml
|
32
|
+
- files:/srv/salt/environments/%{saltenvironment}/files/**/*
|
33
|
+
- files:/srv/salt/environments/common/files/**/*
|
34
|
+
- eyaml:/srv/salt/environments/%{saltenvironment}/**/*.eyaml
|
35
|
+
- eyaml:/srv/salt/environments/common/**/*.eyaml
|
36
|
+
- efiles:/srv/salt/environments/%{saltenvironment}/efiles/**/*
|
37
|
+
- efiles:/srv/salt/environments/common/efiles/**/*
|
38
|
+
|
39
|
+
Items that appear earlier in the hierarchy override items that appear later in the hierarchy.
|
40
|
+
|
41
|
+
In the above hierarchy (defined in salthiera.yaml), the specific environment YAML (parameterised as %{saltenvironment} always overrides the common environment YAML, because it is referenced earlier in the hierarchy section.
|
42
|
+
|
43
|
+
The hierarchy supports YAML files (prefixed with yaml:), EYAML files which are encrypted yaml files (prefixed with eyaml:), and raw files (which might contain public SSL certs, prefixed with files:), and encrypted raw files (which might contain private SSL keys, prefixed with efiles:).
|
44
|
+
|
45
|
+
#### Put some example YAML files together (representing your environment-based data)
|
46
|
+
|
47
|
+
/srv/salt/environments/production/example.yaml
|
48
|
+
|
49
|
+
---
|
50
|
+
my_string: I am the production value
|
51
|
+
|
52
|
+
/srv/salt/environments/common/example.yaml
|
53
|
+
|
54
|
+
---
|
55
|
+
my_string: I am the common value
|
56
|
+
default_string: I am the common default value
|
57
|
+
|
58
|
+
#### Use salthiera on the saltmaster to lookup data on the commandline!
|
59
|
+
|
60
|
+
(saltmaster)
|
61
|
+
|
62
|
+
$ salthiera -c /etc/salt/salthiera.yaml key1=value1 key2=value
|
63
|
+
|
64
|
+
e.g.
|
65
|
+
|
66
|
+
$ salthiera -c /etc/salt/salthiera.yaml saltenvironment=production id=dmzserver01
|
67
|
+
|
68
|
+
(the keys and values you supply relate directly to the %{} delimeters in your salthiera.yaml config file (above)
|
69
|
+
|
70
|
+
In reality when salt runs, it will run the salthiera command, and supply a whole bunch of grain data as key-value pairs to the salthiera command. You get things like %{id} for free - (which is the hostname of the minion), but for the saltenvironment, we need to add this grain data to the salt minion itself.
|
71
|
+
|
72
|
+
#### Configure salt to do this automatically as part of its external pillar processes:
|
73
|
+
|
74
|
+
/etc/salt/master configuration file for saltmaster
|
75
|
+
|
76
|
+
...
|
77
|
+
ext_pillar:
|
78
|
+
- salthiera: /etc/salt/salthiera.yaml
|
79
|
+
...
|
80
|
+
|
81
|
+
#pillar_roots: (comment this out unless you want to use pillar in conjunction with salthiera)
|
82
|
+
|
83
|
+
#### Copy the salthiera.py file in this repos salt/pillar directory into salts pymodules (will depend on your python version and install location)
|
84
|
+
|
85
|
+
$ cp salt/pillar/salthiera.py /usr/share/pyshared/salt/pillar/salthiera.py
|
86
|
+
$ ln -s /usr/share/pyshared/salt/pillar/salthiera.py /usr/lib/pymodules/python2.7/salt/pillar/salthiera.py
|
87
|
+
|
88
|
+
#### Configure a salt minion with its environment
|
89
|
+
|
90
|
+
# /etc/salt/minion config file
|
91
|
+
|
92
|
+
...
|
93
|
+
grains:
|
94
|
+
saltenvironment: production # different on different environments
|
95
|
+
...
|
96
|
+
|
97
|
+
#### Test on the minion
|
98
|
+
|
99
|
+
$ salt-call pillar.get my_string
|
100
|
+
> I am the production value
|
101
|
+
|
102
|
+
$ salt-call pillar.get default_string
|
103
|
+
> I am the common default value
|
104
|
+
|
105
|
+
In this way you can manage key-value pairs, using YAML, or entire files which makes it easier to manage keys, binary files etc.
|
106
|
+
|
107
|
+
Encryption
|
108
|
+
==========
|
109
|
+
|
110
|
+
Salthiera support encrypting using the PKCS7 encryption format. Salthiera has a "sister" project for puppet called hiera-eyaml, which we will use on our local machine to manage the encryption. Hiera-eyaml does not need to be installed anywhere else.
|
111
|
+
|
112
|
+
#### Generate keys for encrypting stuff LOCALLY (if you dont want to do this, then bypass this section)
|
113
|
+
|
114
|
+
(on your local desktop)
|
115
|
+
|
116
|
+
$ gem install hiera-eyaml
|
117
|
+
$ cd /tmp
|
118
|
+
$ eyaml createkeys # keys will be created in a keys/ subdirectory
|
119
|
+
$ ls keys/
|
120
|
+
private_key.pkcs7.pem public_key.pkcs7.pem
|
121
|
+
|
122
|
+
#### Encrypt a sensitive password like this
|
123
|
+
|
124
|
+
$ eyaml encrypt --pkcs7-public-key keys/public_key.pkcs7.pem -s "SOME STRING TO ENCRYPT"
|
125
|
+
ENC[PKCS7,..........]
|
126
|
+
|
127
|
+
Copy this ENC string into any .eyaml file in your salt git repo (environments data)
|
128
|
+
|
129
|
+
/srv/salt/environments/production/database.eyaml
|
130
|
+
|
131
|
+
---
|
132
|
+
database_password: ENC[PKCS7,............]
|
133
|
+
|
134
|
+
#### EYAML files
|
135
|
+
|
136
|
+
Eyaml files in your data hierarchy are exactly the same as YAML files, they just have the ENC[PKCS7,.....] blocks in place of values. Note that you can mix and match ENC[] blocks with plaintext values in the same .eyaml file, that's up to you. But salthiera will not decrypt ENC[] blocks, unless there is a matching eyaml: line in the hierarchy section of salthiera.yaml config file
|
137
|
+
|
138
|
+
#### EFILES
|
139
|
+
|
140
|
+
Salthiera also supports encrypted entire files, which is useful for sensitive binary files (e.g. .DER private keys), or even "plaintext" .PEM private keys that need encrypting.
|
141
|
+
|
142
|
+
To encrypt an entire file:
|
143
|
+
|
144
|
+
$ eyaml encrypt --pkcs7-public-key keys/public_key.pkcs7.pem -f file -o string > encryptedfile
|
145
|
+
|
146
|
+
In the above salthiera.yaml config example, you would then copy encryptedfile into the "efiles" section of your data hierarchy
|
147
|
+
|
148
|
+
#### Encryption Notes
|
149
|
+
|
150
|
+
You would typically generate different keys for different environments and use the correct environments keys to generate encrypted data for that environment.
|
151
|
+
|
152
|
+
Hiera-eyaml toolset allows you to do a lot of things, for example you can interactively edit an .eyaml file using vi, replacing the encrypted tokens in realtime. For further information see the hiera-eyaml project to see all the possibilities available to you
|
153
|
+
|
154
|
+
When done, copy the public_key.pkcs7.pem into your salt git repo somewhere nice (you can publish this to your dev team)
|
155
|
+
|
156
|
+
#### Set up the salt-master to decrypt the values
|
157
|
+
|
158
|
+
Copy the public and private keys you generated above into your saltmaster in a secure place:
|
159
|
+
|
160
|
+
(on your saltmaster)
|
161
|
+
|
162
|
+
$ mkdir -p /etc/salt/salthiera/keys
|
163
|
+
$ chown -R root:root /etc/salt/salthiera/keys
|
164
|
+
$ chmod -R 0500 /etc/salt/salthiera/keys
|
165
|
+
|
166
|
+
Edit /etc/salt/salthiera.yaml and add:
|
167
|
+
|
168
|
+
eyaml_public_key: /etc/salt/salthiera/keys/public_key.pkcs7.pem
|
169
|
+
eyaml_private_key: /etc/salt/salthiera/keys/private_key.pkcs7.pem
|
32
170
|
|
33
|
-
|
171
|
+
Ensure keys directory exists
|
172
|
+
|
173
|
+
$ chmod 0400 /etc/salt/salthiera/keys/*.pem
|
174
|
+
$ ls -lha /etc/salt/salthiera/keys
|
175
|
+
-r-------- 1 root root 1.7K Sep 24 16:24 private_key.pkcs7.pem
|
176
|
+
-r-------- 1 root root 1.1K Sep 24 16:24 public_key.pkcs7.pem
|
34
177
|
|
35
|
-
|
178
|
+
You need a public key and a private key to decrypt a value, but only a public to encrypt a value. In this way, you can distribute your public key to your dev team so they are able to encrypt values and commit them to your salt git repo, and only the saltmaster itself can decrypt the value. This allows you to commit production data alongside your vagrant/dev/staging data in the same repo in safe way.
|
36
179
|
|
37
|
-
|
180
|
+
TROUBLESHOOTING
|
181
|
+
---------------
|
38
182
|
|
183
|
+
If for some reason salt isnt returning ANY values (either plaintext or encyrpted), but salthiera commandline lookups executed properly as explained above is, then the chances are that salt cannot find the "salthiera" binary that comes with this gem. If so, alter the salt.utils.which value in /usr/share/pyshared/salt/pillar/salthiera.py that refers to the salthiera binary and supply the fully qualified path to the salthiera binary (and likewise lower in the code too). This will fix this problem.
|
39
184
|
|
40
185
|
Authors
|
41
186
|
-------
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SaltHiera
|
2
|
+
module Plugins
|
3
|
+
class Efiles
|
4
|
+
|
5
|
+
def self.process_file file
|
6
|
+
|
7
|
+
key = file.split("/").last
|
8
|
+
value = File.read file
|
9
|
+
returnhash = { key => value }
|
10
|
+
returnhash = self.recurse returnhash
|
11
|
+
returnhash
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.recurse obj
|
16
|
+
if obj.is_a? Array
|
17
|
+
obj.each.with_index do |element, index|
|
18
|
+
obj[index] = self.recurse element
|
19
|
+
end
|
20
|
+
elsif obj.is_a? Hash
|
21
|
+
obj.each do |k, v|
|
22
|
+
obj[k] = self.recurse v
|
23
|
+
end
|
24
|
+
elsif obj.is_a? String
|
25
|
+
obj = obj.gsub(/ENC\[PKCS7,(.*?)\]/) {|x| self.decrypt($1) }
|
26
|
+
else
|
27
|
+
obj
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.decrypt cipherbinary
|
32
|
+
|
33
|
+
public_key = Configuration.get "eyaml_public_key"
|
34
|
+
private_key = Configuration.get "eyaml_private_key"
|
35
|
+
|
36
|
+
raise StandardError, "pkcs7_public_key is not defined" unless public_key
|
37
|
+
raise StandardError, "pkcs7_private_key is not defined" unless private_key
|
38
|
+
|
39
|
+
private_key_pem = File.read private_key
|
40
|
+
|
41
|
+
private_key_rsa = OpenSSL::PKey::RSA.new( private_key_pem )
|
42
|
+
|
43
|
+
public_key_pem = File.read public_key
|
44
|
+
|
45
|
+
public_key_x509 = OpenSSL::X509::Certificate.new( public_key_pem )
|
46
|
+
|
47
|
+
ciphertext = Base64.decode64(cipherbinary)
|
48
|
+
pkcs7 = OpenSSL::PKCS7.new( ciphertext )
|
49
|
+
|
50
|
+
pkcs7.decrypt(private_key_rsa, public_key_x509)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
'''
|
3
|
+
Take in a salthiera configuration file location and execute it.
|
4
|
+
Adds the salthiera data to pillar
|
5
|
+
'''
|
6
|
+
|
7
|
+
# Import python libs
|
8
|
+
import logging
|
9
|
+
|
10
|
+
# Import salt libs
|
11
|
+
import salt.utils
|
12
|
+
from salt._compat import string_types
|
13
|
+
|
14
|
+
# Import third party libs
|
15
|
+
import yaml
|
16
|
+
|
17
|
+
|
18
|
+
# Set up logging
|
19
|
+
log = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
def __virtual__():
|
23
|
+
'''
|
24
|
+
Only return if salthiera is installed
|
25
|
+
'''
|
26
|
+
return 'salthiera' if salt.utils.which('salthiera') else False
|
27
|
+
|
28
|
+
|
29
|
+
def ext_pillar(minion_id, pillar, conf):
|
30
|
+
'''
|
31
|
+
Execute salthiera and return the data
|
32
|
+
'''
|
33
|
+
cmd = 'salthiera -c {0}'.format(conf)
|
34
|
+
for key, val in __grains__.items():
|
35
|
+
if isinstance(val, string_types):
|
36
|
+
cmd += ' {0}=\'{1}\''.format(key, val)
|
37
|
+
try:
|
38
|
+
data = yaml.safe_load(__salt__['cmd.run'](cmd))
|
39
|
+
except Exception:
|
40
|
+
log.critical(
|
41
|
+
'SaltHiera YAML data failed to parse from conf {0}'.format(conf)
|
42
|
+
)
|
43
|
+
return {}
|
44
|
+
return data
|
data/tools/regem.sh
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salthiera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geoff Meakin
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-30 00:00:00 Z
|
13
13
|
dependencies: []
|
14
14
|
|
15
15
|
description: Hiera like tool for use as an external pillar with SaltStack
|
@@ -36,11 +36,13 @@ files:
|
|
36
36
|
- lib/salt_hiera/CLI.rb
|
37
37
|
- lib/salt_hiera/configuration.rb
|
38
38
|
- lib/salt_hiera/logger.rb
|
39
|
+
- lib/salt_hiera/plugins/efiles.rb
|
39
40
|
- lib/salt_hiera/plugins/eyaml.rb
|
40
41
|
- lib/salt_hiera/plugins/files.rb
|
41
42
|
- lib/salt_hiera/plugins/no_plugin.rb
|
42
43
|
- lib/salt_hiera/plugins/yaml.rb
|
43
44
|
- lib/salt_hiera/salt_hiera.rb
|
45
|
+
- salt/pillar/salthiera.py
|
44
46
|
- salthiera.gemspec
|
45
47
|
- tools/regem.sh
|
46
48
|
homepage: http://github.com/gtmtechltd/salthiera
|