puppet-crypt 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +3 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +21 -0
  6. data/ChangeLog.md +36 -0
  7. data/Gemfile +18 -0
  8. data/LICENSE.txt +16 -0
  9. data/Modulefile +13 -0
  10. data/README.md +172 -0
  11. data/Rakefile +12 -0
  12. data/bundles/puppet_2_7.gemfile +6 -0
  13. data/bundles/puppet_3_0.gemfile +5 -0
  14. data/bundles/puppet_edge.gemfile +5 -0
  15. data/features/fixtures/data/overridden_secret_key.yaml +4 -0
  16. data/features/fixtures/data/simple.yaml +2 -0
  17. data/features/fixtures/hiera.yaml +8 -0
  18. data/features/fixtures/manifests/overridden_secret_key.pp.bak +5 -0
  19. data/features/fixtures/manifests/simple.pp +6 -0
  20. data/features/fixtures/other_secretkeys/secondary_key +11 -0
  21. data/features/fixtures/secretkeys/alt_key +1 -0
  22. data/features/fixtures/secretkeys/encryptor_secret_key +11 -0
  23. data/features/hiera.feature +56 -0
  24. data/features/step_definitions/puppet_steps.rb +31 -0
  25. data/features/support/env.rb +10 -0
  26. data/lib/puppet-decrypt.rb +13 -0
  27. data/lib/puppet-decrypt/decryptor.rb +99 -0
  28. data/lib/puppet-decrypt/key_loader.rb +28 -0
  29. data/lib/puppet-decrypt/version.rb +5 -0
  30. data/lib/puppet/application/crypt.rb +5 -0
  31. data/lib/puppet/face/crypt.rb +63 -0
  32. data/lib/puppet/functions/decrypt.rb +24 -0
  33. data/lib/puppet/functions/encrypt.rb +44 -0
  34. data/puppet-crypt.gemspec +36 -0
  35. data/spec/faces/crypt_spec.rb +67 -0
  36. data/spec/functions/decrypt_spec.rb +53 -0
  37. data/spec/functions/encrypt_spec.rb +63 -0
  38. data/spec/puppet-decrypt/fake_key_loader.rb +24 -0
  39. data/spec/spec_helper.rb +24 -0
  40. metadata +187 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0514f4e010774d12e7bdff47d66954b0c7f0211b814194788db5bf4bcbf73196
4
+ data.tar.gz: c8e4ce1fa1ad3de7e69545560e63a44318eb5fdb15b74a0ec17cd5e5b5efc186
5
+ SHA512:
6
+ metadata.gz: 9b2cc0f2a8cef27949f15888b88a6a0ea25d29e35ce15fad0aad98942bb43704f2bd3f1607fc41d8121ac03729b73a94f1e0e01c1615472dd31bdd6e390dda4f
7
+ data.tar.gz: c9b1df191e25a392521f2f337894a6c0f2231655699d04c32a8ee77029632dd9b3d2fe26f8b3a8a235a1ded503de993b5d561cc3b1b54d2660c3b967ba376733
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
19
+ vendor
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --backtrace
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3@puppet-decrypt
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ bundler_args: --without debugging
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.3
6
+ - jruby-19mode
7
+ - 2.0.0
8
+ - 2.1.0
9
+ gemfile:
10
+ - Gemfile
11
+ - bundles/puppet_3_0.gemfile
12
+ - bundles/puppet_2_7.gemfile
13
+ - bundles/puppet_edge.gemfile
14
+ matrix:
15
+ exclude:
16
+ - rvm: 1.8.7
17
+ gemfile: bundles/puppet_edge.gemfile
18
+ - rvm: 2.1.0
19
+ gemfile: bundles/puppet_3_0.gemfile
20
+ - rvm: 2.1.0
21
+ gemfile: bundles/puppet_2_7.gemfile
@@ -0,0 +1,36 @@
1
+ ## 0.2.0 (Aug 07, 2014)
2
+
3
+ Enhancements:
4
+ - Added an encrypt function (thanks @tioteath!)
5
+
6
+ Bugfixes:
7
+ - Fixed handling of absolute paths for to the secret key file (thanks @tioteath!)
8
+ - Removed unnecessary puts (thanks @tioteath!)
9
+ - Improved error handling (thanks @tioteath!)
10
+
11
+ ## 0.1.1 (Jan 24, 2014)
12
+
13
+ Enhancements:
14
+ - Salting to protect against dictionary and rainbow table attacks.
15
+
16
+ Bugfixes:
17
+ - Fix Ruby 1.8.7 support.
18
+
19
+ ## 0.1.0 (July 10, 2013)
20
+
21
+ Features:
22
+
23
+ - support alternate secret keys
24
+ - override the key as part of the string in the format ENC:another_key[...]
25
+ - override the key by passing a hash containing value and secret_key
26
+
27
+ Bugfixes:
28
+
29
+ - Explicitly remove Ruby 1.8.7 support. Previously it would install but not work with Ruby 1.8.7.
30
+
31
+ ## 0.0.4 (March 8, 2013)
32
+
33
+ Features:
34
+
35
+ - puppet face for encrypting/decrypting secrets
36
+ - basic puppet function for decrypting a secret, using a master key
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "puppet-crypt", :git => "https://github.com/wgsateam/puppet-decrypt"
4
+
5
+ # Specify your gem's dependencies in puppet-crypt.gemspec
6
+ gemspec
7
+
8
+ # Not in the gemspec because we're testing multiple versions with appraisal.
9
+ gem 'puppet'
10
+
11
+ # Things we don't want on Travis
12
+ group :debugging do
13
+ # just for pushing documentation, requires ruby 1.9+
14
+ gem 'relish'
15
+ gem 'pry'
16
+ gem 'pry-nav'
17
+ end
18
+
@@ -0,0 +1,16 @@
1
+ Puppet-Decrypt
2
+
3
+ Copyright (c) 2013 mlincoln
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
@@ -0,0 +1,13 @@
1
+ name 'devopsy/puppet_decrypt'
2
+ version '0.1.1'
3
+ source 'https://github.com/maxlinc/puppet-decrypt'
4
+ author 'Max Lincoln'
5
+ license 'Apache License, Version 2.0'
6
+ summary 'Simple encryption/decryption of secret data for Puppet'
7
+ description 'Simple encryption/decryption of secret data for Puppet'
8
+ project_page 'https://github.com/maxlinc/puppet-decrypt'
9
+
10
+ ## Add dependencies, if any:
11
+ # don't think gem dependencies can be declared...
12
+ # dependency gem 'encryptor'
13
+
@@ -0,0 +1,172 @@
1
+ **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
2
+
3
+ - [Puppet-Decrypt](#puppet-decrypt)
4
+ - [Comparison with Hiera-GPG](#comparison-with-hiera-gpg)
5
+ - [Installation](#installation)
6
+ - [Via Gem](#via-gem)
7
+ - [Installing as a Module](#installing-as-a-module)
8
+ - [Usage](#usage)
9
+ - [Basic Usage](#basic-usage)
10
+ - [Overriding the secret key](#overriding-the-secret-key)
11
+ - [Contributing](#contributing)
12
+
13
+ [![Build Status](https://secure.travis-ci.org/maxlinc/puppet-decrypt.png?branch=master)](http://travis-ci.org/maxlinc/puppet-decrypt)
14
+ [![Dependency Status](https://gemnasium.com/maxlinc/puppet-decrypt.png?travis)](https://gemnasium.com/maxlinc/puppet-decrypt)
15
+ [![Code Climate](https://codeclimate.com/github/maxlinc/puppet-decrypt.png)](https://codeclimate.com/github/maxlinc/puppet-decrypt)
16
+
17
+ # Puppet-Decrypt
18
+
19
+ *Notice: The default secret key location is now /etc/puppet-decrypt/encryptor_secret_key*
20
+
21
+ Puppet Decrypt is a gem that gives puppet the ability to encrypt and decrypt strings. This is useful for making sure secret data - like database passwords - remains secret. It uses a model similar to [jasypt Encrypting Application Configuration Files](http://www.jasypt.org/encrypting-configuration.html) or [Maven Password Encryption](http://maven.apache.org/guides/mini/guide-encryption.html). It is a simple alternative to the [Secret variables in Puppet with Hiera and GPG](http://www.craigdunn.org/2011/10/secret-variables-in-puppet-with-hiera-and-gpg/) approach.
22
+
23
+ ## Comparison with Hiera-GPG
24
+
25
+ Advantages:
26
+
27
+ * Store encrypted secret variables and related non-secret variables in the same file.
28
+ * Version control friendly - you can easily see when a variable was added, changed, or removed even if you don't know the exact value.
29
+ * Works with any data source. Combine it with Hiera, extlookup, external node classifiers, exported resources, or any other source of data.
30
+ * Simple administration - no keyring management.
31
+
32
+ Disadvantages:
33
+
34
+ * Uses a shared secret instead of asymetric keypairs. This means that the "master password" is shared by all admins. It is also shared by all machines that need to decrypt the same value (usually machines in the same environment).
35
+ * Less integrated with Hiera. You need to wrap calls as decrypt(hiera('my_db_password')).
36
+
37
+ The shared secret "master password" may seem more difficult to grant and revoke access than the asymetric keypair approach used by hiera-gpg. However both systems are protecting shared secret data! So if you want to fully revoke someone's access you need to change or revoke their decryption key (which is easier with hiera-gpg) *AND* to change any secrets that key protected (e.g.: your production database passwords).
38
+
39
+ ## Installation
40
+
41
+ ### Via Gem
42
+
43
+ It should be possible to install via a Gem in Puppet 3+. However, this method is easier, but does seem to have some quirks. If you have any issues, try installing as a module instead.
44
+
45
+ Add this line to your application's Gemfile:
46
+
47
+ gem 'puppet-decrypt'
48
+
49
+ And then execute:
50
+
51
+ $ bundle
52
+
53
+ Or install it yourself as:
54
+
55
+ $ gem install puppet-decrypt
56
+
57
+ ### Installing as a Module
58
+
59
+ If installing as a module, you'll need to deal with the Gem prerequisites manually.
60
+
61
+ ``` shell
62
+ $ gem install encryptor
63
+ ```
64
+
65
+ Puppet Decrypt can be installed with the puppet module subcommand, which is included in Puppet 2.7.14 and later.
66
+
67
+ ``` shell
68
+ $ sudo puppet module install devopsy-puppet_decrypt
69
+ ```
70
+ The command will tell you where it is installing the module; take note:
71
+
72
+ ``` shell
73
+ $ sudo puppet module install devopsy/puppet_decrypt
74
+ warning: iconv couldn't be loaded, which is required for UTF-8/UTF-16 conversions
75
+ Preparing to install into /etc/puppet/modules ...
76
+ Downloading from http://forge.puppetlabs.com ...
77
+ Installing -- do not interrupt ...
78
+ /etc/puppet/modules
79
+ └── devopsy-puppet_decrypt (v0.1.0)
80
+ ```
81
+
82
+ After installing it, you must add the lib directory of the module to your $RUBYLIB. Add the following to your .profile file (replacing /etc/puppet/modules with the directory from the install command, if necessary), then run source ~/.profile to re-load it in the current shell:
83
+
84
+ ``` shell
85
+ export RUBYLIB=/etc/puppet/modules/puppet_decrypt/lib:$RUBYLIB
86
+ ```
87
+
88
+ You can verify that it is installed and usable by running:
89
+
90
+ ``` shell
91
+ # puppet help crypt
92
+ ```
93
+
94
+ ## Usage
95
+
96
+ ### Basic Usage
97
+ Put the secret key in /etc/puppet-decrypt/encryptor_secret_key on machines where puppet needs to decrypt the value. Make sure the file's read permissions are restricted!
98
+
99
+ Use the puppet face to encrypt a value
100
+
101
+ ``` shell
102
+ $ puppet crypt encrypt my_secret_value
103
+ ENC[ANN3I3AWxXWmr5QAW3qgxw==]
104
+ ```
105
+
106
+ Or to decrypt a value
107
+ ``` shell
108
+ $ puppet crypt decrypt ENC[ANN3I3AWxXWmr5QAW3qgxw==]
109
+ my_secret_value
110
+ ```
111
+
112
+ Put that value into hiera, extlookup, or any other data source you want. Hiera example:
113
+ ``` yaml
114
+ database_password: ENC[ANN3I3AWxXWmr5QAW3qgxw==]
115
+ ```
116
+
117
+ In your puppet code, load the value normally and then pass it to decrypt.
118
+ ``` ruby
119
+ decrypt(hiera('database_password'))
120
+ ```
121
+
122
+ Or encrypt a secret passing it to encrypt, if you need to save the secret to
123
+ external storage, for example.
124
+ ``` ruby
125
+ $encrypted_secret_to_save = encrypt($data)
126
+ ```
127
+
128
+ ### Overriding the secret key
129
+
130
+ Puppet Decrypt now supports using more than just the default secret key location. You can easily use multiple secret keys for the same project.
131
+
132
+ For the Puppet face, you just use the --secretkey option to pass an alternate secret key location.
133
+
134
+ ``` shell
135
+ $ echo 'example' > alt_key.txt
136
+ $ puppet crypt encrypt abc123 --secretkey alt_key
137
+ ENC[c4S4hMCDv1b7FkZgOBRTOA==]
138
+ $ puppet crypt decrypt ENC[c4S4hMCDv1b7FkZgOBRTOA==] --secretkey alt_key
139
+ abc123
140
+ ```
141
+
142
+ There are two ways to use the alternate keys from the function. You can pass it it as part of the string in this format:
143
+ ``` yaml
144
+ database_password: ENC:alt_key[c4S4hMCDv1b7FkZgOBRTOA==]
145
+ ```
146
+
147
+ If you do that, instead of using the default secret key, it will look for alt_key in the same directory. So instead of
148
+ /etc/puppet-decrypt/encryptor_secret_key it will use /etc/puppet-decrypt/alt_key.
149
+
150
+ Alternately, you can pass a hash to the function, containing a value and a secret key, like this:
151
+ ``` yaml
152
+ db_password:
153
+ value: 'ENC[G6MjBDDFcapYLaKBFJvPSg==]'
154
+ secretkey: '/any/path/you/another/key'
155
+ ```
156
+
157
+ This has the advantage of letting you place keys in alternate directories, not just /etc/puppet-decrypt.
158
+
159
+ If you use this alongside hiera, you can just switch the lookup from hiera to hiera-hash:
160
+ ``` ruby
161
+ decrypt(hiera_hash('db_password'))
162
+ ```
163
+
164
+ See [features/hiera.feature](features/hiera.feature) for complete examples.
165
+
166
+ ## Contributing
167
+
168
+ 1. Fork it
169
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
170
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
171
+ 4. Push to the branch (`git push origin my-new-feature`)
172
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => [:spec, :integration]
9
+
10
+ Cucumber::Rake::Task.new(:integration) do |t|
11
+ t.cucumber_opts = "features --format pretty"
12
+ end
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in puppet-decrypt.gemspec
4
+ gem 'puppet', '~> 2.7.0'
5
+ gem 'hiera-puppet'
6
+ gemspec(:path => '../')
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in puppet-decrypt.gemspec
4
+ gem 'puppet', '~> 3.0.0'
5
+ gemspec(:path => '../')
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in puppet-decrypt.gemspec
4
+ gem 'puppet', :git => 'https://github.com/puppetlabs/puppet'
5
+ gemspec(:path => '../')
@@ -0,0 +1,4 @@
1
+ ---
2
+ db_password:
3
+ value: 'ENC[blablabla==]'
4
+ secretkey: '/etc/some_other_key'
@@ -0,0 +1,2 @@
1
+ ---
2
+ db_password: 'ENC[okoNBVDGyHQaQQPKnTTJvA==]'
@@ -0,0 +1,8 @@
1
+ ---
2
+ :backends: yaml
3
+ :yaml:
4
+ :datadir: features/fixtures/data
5
+ :hierarchy:
6
+ - '%{::hiera_file}'
7
+ - common
8
+ :logger: console
@@ -0,0 +1,5 @@
1
+ $decrypted = decrypt(hiera('db_password'))
2
+ notice($decrypted)
3
+ unless($decrypted == 'expected') {
4
+ fail("Expected 'expected', found $unexpected")
5
+ }
@@ -0,0 +1,6 @@
1
+ $decrypted = decrypt(hiera('db_password'))
2
+ notice($decrypted)
3
+ $expected = 'blablabla'
4
+ unless($decrypted == $expected) {
5
+ fail("Expected '$expected', found $unexpected")
6
+ }
@@ -0,0 +1,11 @@
1
+ 1ExtSQ4kg4a4rsp7J0RlquK5Y+h5b4TeEzHX24sDxURY4LLX6J5bwTZueg1PBhiI
2
+ EenV11LGhRvUDrw53dG7j+UuMxGJv/R2cdnGxq1ztjN1ozp8xSRUTcbzpd9uijLe
3
+ FhEZHVjAIzBNj9RLl13Dw5zVPvxRuPcQBsnRIyG8YMMCgZMgZ90yBMhJmp5M3hw/
4
+ q88nDZGlZeclkIg+9QTtjywz4crvHpnQrC1ViyaIVT+lZfHPMg4TipXlDXPrlFea
5
+ x/X7v/EYXvSvY6gSVs7/ZAfFnC1K30nCaPnAbIiwsdjh7t3dV7ymHY/TvXfZQHGO
6
+ BXMFu9jdJl+nptZZp/4x4xb569s0do1Y/Z6DHqeIi31pS4hwjw8j6zHWpPrnTgRw
7
+ vcv0Di3iCjFAbTbSadgFuuybUCeZQArRYO0J03IKHNqW9UWim7tN08LOmvGuoQKf
8
+ 6IAhKT0Yc4y1Mk6jtDsPlkxJvdVzTRlv07FnWWi3R2kkLWqdeFz6YB8PDCSLMXL0
9
+ qNDDOfv1MuUfKlGgqigIkbMpbqd6KUU1qLQ0js1RTq9iO6XR8wHIXqKX5r0Mp0D6
10
+ aMO1a7gvjHJFqr3nkeZvDAbGeJMJtx99OrfuUH8FImvJZ22jOP4plcC1U1u2VZGp
11
+ Rx2AoLYyiWuzP948FmvruvXMn7WxvDrU7N/wF52L3/Q=
@@ -0,0 +1 @@
1
+ example
@@ -0,0 +1,11 @@
1
+ idZdWf3d7s97FVG0iytPj03c2LhrumdUqk4T+aa1VVzp8vFmtQb7Vyy7SbjV4v4y
2
+ CLEat8x8jFb7IBl2yjW3KmC0TW1q1cKaeP8eHuYeqm9ZIQoUtDH+q+8KM5xso358
3
+ PAkDtxJcFmcRvD2SL47WYTd+xFjYEW5VxWhGCcNi/FRlmRSLL29sBcRGfJNhPBit
4
+ j3PiXxPrNIu4E1Ikm94C911x4YD/PO5yNOuhDQW5rs1z8G8TGmzXV64Vxg7rYcXc
5
+ 8XK0auzDm+qTdSpP6vaLhFROcGgFVzFu5WWHZ0dpRL1UfDdjlQbHojRCfb4jZB+I
6
+ bXTS5BQFzClttcPYSwf44am3zwYCuLeZ5oWif2sxPBwUIubzPIoBObcdj/uIjljx
7
+ BBPcoPDW+zIbghVWxjoHkLinRdqtXQzMCS0pp8znRsT7v5mp7FZvzMLDO6belz+Q
8
+ LEd3YefLkOFU6B7kJq7XDrVP18G691SwhY08rSq0LyNlwEZ4E9ZD6hrUduHd3Bs7
9
+ yGNhGjvAEItfDv7MBcavkLZSO/q1QElbz5B7/3aiu2HPRfUmS/hiywJ3S1cxZp8Y
10
+ wVr0kqIxRxMoNfl4IqCaRsvlwGBeTHmpXqkcviQsQOuddMStGXKKptrXKxvhn4ca
11
+ 72SUKYg7mvyCWD44mAxJyTfTso93Pkn95klRtyBunu0=
@@ -0,0 +1,56 @@
1
+ Feature: Puppet works
2
+
3
+ Scenario: Unsalted (legacy) key
4
+ Given I have the following hiera data:
5
+ """
6
+ ---
7
+ db_password: ENC[wx0qTorBqPrTrgkbzYirlA==]
8
+ """
9
+ When I execute this puppet manifest:
10
+ """
11
+ $password = decrypt(hiera('db_password'))
12
+ notice("Decrypted: $password")
13
+ """
14
+ Then the output should include "Decrypted: max"
15
+
16
+ Scenario: Default test
17
+ Given I have the following hiera data:
18
+ """
19
+ ---
20
+ db_password: ENC[HOz0/aHCjJTAUlEbM/pqMQ==:QZy2oTvQNhwFMmOARn+Jlw==:aUY1NjBqamp6RWs1UkYvVjVULzNvdz09]
21
+ """
22
+ When I execute this puppet manifest:
23
+ """
24
+ $password = decrypt(hiera('db_password'))
25
+ notice("Decrypted: $password")
26
+ """
27
+ Then the output should include "Decrypted: max"
28
+
29
+ Scenario: Overriden key (string)
30
+ Given I have the following hiera data:
31
+ """
32
+ ---
33
+ db_password: ENC:alt_key[KgLJnDVF9VeTGGU/vG2KjQ==:NiLhgUn4JL07DI9trGSK8g==:YlVhZDhDSEZsSDV6RnBOdm1FMmVtQT09]
34
+ """
35
+ When I execute this puppet manifest:
36
+ """
37
+ $password = decrypt(hiera('db_password'))
38
+ notice("Decrypted: $password")
39
+ """
40
+ Then the output should include "Decrypted: abc123"
41
+
42
+ Scenario: Overridden key (hash)
43
+ Given I have the following hiera data:
44
+ """
45
+ ---
46
+ db_password:
47
+ value: 'ENC[AVdi08NXUveKStMSAH4kMQ==:EAHeMe3TvK33gjnDDHV5rQ==:cndoVVBhMWdXQW5HVSsxWDN4OUtRZz09]'
48
+ secretkey: 'features/fixtures/other_secretkeys/secondary_key'
49
+ """
50
+ When I execute this puppet manifest:
51
+ """
52
+ notice(hiera_hash('db_password'))
53
+ $password = decrypt(hiera_hash('db_password'))
54
+ notice("Decrypted: $password")
55
+ """
56
+ Then the output should include "Decrypted: overridden"
@@ -0,0 +1,31 @@
1
+ require 'tempfile'
2
+
3
+ Given /^I have the following hiera data:$/ do |hieradata|
4
+ hierafile = Thread.current[:hierafile]
5
+ hierafile.write(hieradata)
6
+ hierafile.close
7
+ end
8
+
9
+ When /^I execute this puppet manifest:$/ do |manifest|
10
+ hierafile = Thread.current[:hierafile]
11
+ file = Tempfile.new('test_manifest')
12
+ begin
13
+ file.write(manifest)
14
+ file.close
15
+ ENV['FACTER_HIERA_FILE'] = File.basename(hierafile.path, '.yaml')
16
+ ENV['PUPPET_DECRYPT_KEYDIR'] = 'features/fixtures/secretkeys'
17
+ puppet_version = `bundle exec puppet --version`
18
+ puppet_command = "bundle exec puppet apply --noop #{file.path}"
19
+ puppet_command = "#{puppet_command} --hiera_config=features/fixtures/hiera.yaml" if puppet_version.match /^3/
20
+ puppet_command = "#{puppet_command} --confdir=features/fixtures" if puppet_version.match /^2/
21
+ @output = `#{puppet_command}`
22
+ puts @output
23
+ ensure
24
+ file.unlink
25
+ end
26
+ $?.success?
27
+ end
28
+
29
+ Then /^the output should include "([^"]*)"$/ do |content|
30
+ @output.should include content
31
+ end
@@ -0,0 +1,10 @@
1
+ Around do | scenario, block |
2
+ hierafile = Tempfile.new(['hierafile', '.yaml'], 'features/fixtures/data')
3
+ Thread.current[:hierafile] = hierafile
4
+ begin
5
+ block.call
6
+ ensure
7
+ hierafile.close
8
+ hierafile.unlink
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ require 'puppet-decrypt/version'
2
+ require 'puppet-decrypt/key_loader'
3
+ require 'puppet-decrypt/decryptor'
4
+ require 'encryptor'
5
+ require 'base64'
6
+
7
+ module Puppet
8
+ module Decrypt
9
+ def self.key_loader
10
+ @key_loader ||= Puppet::Decrypt::KeyLoader.new
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,99 @@
1
+ module Puppet
2
+ module Decrypt
3
+
4
+ class Decryptor
5
+ ENCRYPTED_PATTERN = /^ENC:?(\w*)\[(.*)\]$/
6
+ KEY_DIR = ENV['PUPPET_DECRYPT_KEYDIR'] || '/etc/puppet-decrypt'
7
+ DEFAULT_KEY = 'encryptor_secret_key'
8
+ DEFAULT_FILE = File.join(KEY_DIR, DEFAULT_KEY)
9
+
10
+ def initialize(options = {})
11
+ @raw = options[:raw] || false
12
+ end
13
+
14
+ def decrypt_hash(hash)
15
+ decrypt(hash['value'], hash['secretkey'] || hash['secret_key'])
16
+ end
17
+
18
+ def encrypt_hash(hash)
19
+ secret_key = hash['secretkey'] || hash['secret_key'] ||
20
+ File.join(KEY_DIR, DEFAULT_KEY)
21
+ salt = hash['salt'] || SecureRandom.base64
22
+ iv = hash['iv'] || OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
23
+
24
+ encrypt(hash['value'], secret_key, salt, iv)
25
+ end
26
+
27
+ def decrypt(value, secret_key_file)
28
+ secret_key_file ||= secret_key_for value
29
+ secret_key_digest = digest_from secret_key_file
30
+ if @raw
31
+ match = true
32
+ else
33
+ match = value.match(ENCRYPTED_PATTERN)
34
+ if match
35
+ value = match[2]
36
+ end
37
+ end
38
+ if match
39
+ value, iv, salt = value.split(':').map{|s| strict_decode64 s }
40
+ if iv && salt
41
+ value = value.decrypt(:key => secret_key_digest, :iv => iv, :salt => salt)
42
+ else
43
+ $stderr.puts "Warning: re-encrypt with puppet-crypt to use salted passwords"
44
+ value = value.decrypt(:key => secret_key_digest)
45
+ end
46
+ end
47
+ value
48
+ end
49
+
50
+ def encrypt(value, secret_key_file, salt, iv)
51
+ secret_key_file ||= secret_key_for value
52
+ secret_key_digest = digest_from secret_key_file
53
+ result = value.encrypt(:key => secret_key_digest, :iv => iv, :salt => salt)
54
+ encrypted_value = [result, iv, salt].map{|v| strict_encode64(v).strip }.join ':'
55
+ encrypted_value = "ENC[#{encrypted_value}]" unless @raw
56
+ raise "Value can't be encrypted properly with salt #{salt}" unless decrypt(encrypted_value, secret_key_file) == value
57
+ encrypted_value
58
+ end
59
+
60
+ private
61
+ def load_key(secret_key_file)
62
+ Puppet::Decrypt.key_loader.load_key secret_key_file
63
+ end
64
+
65
+ def secret_key_for(value)
66
+ match = value.match(ENCRYPTED_PATTERN)
67
+ if match
68
+ key = match[1]
69
+ key = DEFAULT_KEY if key.empty?
70
+ end
71
+ key ||= DEFAULT_KEY
72
+ File.join(KEY_DIR, key)
73
+ end
74
+
75
+ def digest_from(secret_key_file)
76
+ secret_key = load_key secret_key_file
77
+ Digest::SHA256.hexdigest(secret_key)
78
+ end
79
+
80
+ # Backported for ruby 1.8.7
81
+ def strict_decode64(str)
82
+ return Base64.strict_decode64(str) if Base64.respond_to? :strict_decode64
83
+
84
+ unless str.include?("\n")
85
+ Base64.decode64(str)
86
+ else
87
+ raise(ArgumentError,"invalid base64")
88
+ end
89
+ end
90
+
91
+ # Backported for ruby 1.8.7
92
+ def strict_encode64(bin)
93
+ return Base64.strict_encode64(bin) if Base64.respond_to? :strict_encode64
94
+ Base64.encode64(bin).tr("\n",'')
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,28 @@
1
+ require 'pathname'
2
+ module Puppet
3
+ module Decrypt
4
+ class KeyLoader
5
+ def load_key(secret_key_file)
6
+
7
+ # Dot not add directory if absolute path provided
8
+ if Pathname.new(secret_key_file).absolute?
9
+ full_path = secret_key_file
10
+ else
11
+ full_path = File.join(ENV['PUPPET_DECRYPT_KEYDIR'] ||
12
+ Puppet::Decrypt::Decryptor::KEY_DIR, secret_key_file)
13
+ end
14
+
15
+ # Assume key file is specified as basename
16
+ if File.readable? full_path
17
+ secret_key_file = full_path
18
+ else
19
+ # Assume key file is specifed as full path
20
+ raise "Secret key file: #{secret_key_file} is not readable!" unless
21
+ File.readable? secret_key_file
22
+ end
23
+
24
+ File.open(secret_key_file, &:readline).chomp
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Puppet
2
+ module Decrypt
3
+ VERSION = "0.2.0"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'puppet/face'
2
+ require 'puppet/application/face_base'
3
+
4
+ class Puppet::Application::Crypt < Puppet::Application::FaceBase
5
+ end
@@ -0,0 +1,63 @@
1
+ require 'puppet-decrypt'
2
+ require 'puppet/face'
3
+ require 'stringio'
4
+
5
+ Puppet::Face.define(:crypt, Puppet::Decrypt::VERSION) do
6
+ copyright "Max Lincoln", 2013
7
+ license "MIT; see LICENSE"
8
+
9
+ summary "Encrypt or decrypt secret values."
10
+ description <<-EOT
11
+ This subcommand provides a command line interface to encrypt or decrypt values
12
+ that are intended for use with the puppet decrypt function.
13
+ EOT
14
+
15
+ option "--raw" do
16
+ summary "Use raw parse/display"
17
+ description <<-EOT
18
+ Parse or display the value in raw format, instead of using ENC[...] block
19
+ EOT
20
+ end
21
+
22
+ option "--secretkey SECRET_KEY_PATH" do
23
+ summary "The path to the secret key file (default: #{Puppet::Decrypt::Decryptor::DEFAULT_FILE}"
24
+ end
25
+
26
+ option "--iv IV" do
27
+ summary "The initialization vector to use during encryption (default is random)"
28
+ end
29
+
30
+ option "--salt SALT" do
31
+ summary "The salt to use during encryption (default is random)"
32
+ end
33
+
34
+ action :encrypt do
35
+ summary 'Encrypt a secret value.'
36
+ arguments "<plaintext_secret>"
37
+ description <<-EOT
38
+ This action encrypts a value using the secret key.
39
+ EOT
40
+ when_invoked do |plaintext_secret, options|
41
+ iv = options.delete(:iv) || OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
42
+ salt = options.delete(:salt) || SecureRandom.base64
43
+ secretkey = options[:secretkey]
44
+ unless secretkey.nil?
45
+ secretkey = File.expand_path(secretkey) if secretkey.start_with? '.'
46
+ end
47
+
48
+ Puppet::Decrypt::Decryptor.new(options).encrypt(plaintext_secret, secretkey, salt, iv)
49
+ end
50
+ end
51
+
52
+ action :decrypt do
53
+ summary 'Decrypt a secret value.'
54
+ arguments "<encrypted_secret>"
55
+ description <<-EOT
56
+ This action decrypts a value using the secret key.
57
+ EOT
58
+ when_invoked do |encrypted_secret, options|
59
+ secretkey = options[:secretkey]
60
+ Puppet::Decrypt::Decryptor.new(options).decrypt(encrypted_secret, secretkey)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ require 'puppet-decrypt'
2
+
3
+ Puppet::Functions.create_function(:'decrypt') do
4
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
5
+
6
+ dispatch :main do
7
+ required_param 'Variant[String, Hash]', :value
8
+ required_param 'String', :secret_key
9
+ end
10
+
11
+ def main(value, secret_key)
12
+ options = {}
13
+ decrypt_args = {}
14
+
15
+ if value.is_a? String
16
+ decrypt_args['value'] = value
17
+ decrypt_args['secret_key'] = secret_key
18
+ else
19
+ decrypt_args = value
20
+ end
21
+
22
+ Puppet::Decrypt::Decryptor.new(options).decrypt_hash(decrypt_args)
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ require 'puppet-decrypt'
2
+
3
+ Puppet::Functions.create_function(:'encrypt') do
4
+ # Encrypt data, using Decryptor.
5
+ #
6
+ # This function expects four arguments:
7
+ # - Data to encrypt.
8
+ # - Secret key file path,
9
+ # Puppet::Decrypt::Decryptor::DEFAULT_KEY by default.
10
+ # Can be specified as basename in Puppet::Decrypt::Decryptor::KEY_DIR.
11
+ # - Salt (optional), randomly generated by default.
12
+ # - Initialization vector (optional), randomly generated by default,
13
+ # mainly useful for tests.
14
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
15
+
16
+ dispatch :main do
17
+ required_param 'Variant[String,Hash]', :value
18
+ required_param 'String', :secret_key
19
+ optional_param 'String', :salt
20
+ optional_param 'String', :iv
21
+ end
22
+
23
+ def main(value, secret_key, salt, iv)
24
+ encrypt_args = {}
25
+ unless salt
26
+ salt = Puppet::Util::Execution.execute("pwgen -s -1 14")
27
+ end
28
+
29
+ unless iv
30
+ iv = Puppet::Util::Execution.execute("head -c 10 /dev/random | base64")
31
+ end
32
+
33
+ if value.is_a? String
34
+ encrypt_args['value'] = value
35
+ encrypt_args['secret_key'] = secret_key
36
+ encrypt_args['salt'] = salt
37
+ encrypt_args['iv'] = iv
38
+ else
39
+ encrypt_args = value
40
+ end
41
+
42
+ Puppet::Decrypt::Decryptor.new.encrypt_hash(encrypt_args)
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'puppet-decrypt/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "puppet-crypt"
8
+ gem.version = "0.2.0"
9
+ gem.authors = ["mlincoln"]
10
+ gem.email = ["max@devopsy.com"]
11
+ gem.description = %q{A gem for encrypting/decrypting secret values for use with Puppet}
12
+ gem.summary = %q{A shared secret strategy that works with any data source}
13
+ gem.homepage = "https://github.com/wgsateam/puppet-decrypt"
14
+ gem.required_ruby_version = '>= 1.8.7'
15
+ notice = """
16
+
17
+ Notice: The default master key location is now /etc/puppet-decrypt/encryptor_secret_key
18
+
19
+ This was done to more easily support multiple keys. If you are upgrading from a version older than
20
+ 0.1.0 you should move /etc/encryptor_secret_key to /etc/puppet-decrypt/encryptor_secret_key.
21
+
22
+ """
23
+ gem.post_install_message = notice
24
+
25
+ gem.files = `git ls-files`.split("\n")
26
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
27
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
28
+ gem.require_paths = ["lib"]
29
+
30
+ gem.add_dependency('encryptor')
31
+ gem.add_development_dependency('rake')
32
+ gem.add_development_dependency('cucumber')
33
+ gem.add_development_dependency('rspec', '~> 2.14.1')
34
+ gem.add_development_dependency('rspec-puppet')
35
+ gem.add_development_dependency('puppetlabs_spec_helper')
36
+ end
@@ -0,0 +1,67 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'puppet/face'
4
+
5
+ MINIMUM_IV_LENGTH = 20
6
+ describe Puppet::Face[:crypt, :current] do
7
+ let(:insecure_opts) do
8
+ { :salt => '1234567890', :iv => '5'*20 }
9
+ end
10
+ # Values above, encoded
11
+ let(:base64_salt) { 'MTIzNDU2Nzg5MA==' }
12
+ let(:base64_iv) { 'NTU1NTU1NTU1NTU1NTU1NTU1NTU=' }
13
+ before :all do
14
+ mock_secret_key(Puppet::Decrypt::Decryptor::DEFAULT_FILE, 'masterkey')
15
+ end
16
+
17
+ describe 'encrypt' do
18
+ describe 'should encrypt a value' do
19
+ it 'is decryptable with minimum args' do
20
+ encrypted = subject.encrypt('flabberghaster')
21
+ subject.decrypt(encrypted).should == 'flabberghaster'
22
+ end
23
+ it 'is decryptable with minimum args with a salt' do
24
+ salt = SecureRandom.base64
25
+ encrypted = subject.encrypt('flabberghaster', {:salt => salt})
26
+ subject.decrypt(encrypted).should == 'flabberghaster'
27
+ end
28
+ it 'is decryptable with problematic salt (regexp chars)' do
29
+ salt = 'R8STny+9cq03ujQGiKDd9w=='
30
+ encrypted = subject.encrypt('flabberghaster', {:salt => salt})
31
+ subject.decrypt(encrypted).should == 'flabberghaster'
32
+ end
33
+ it 'with ENC[...]' do
34
+ expected_value = "ENC[7u523Z+PpqSm58+BeiN4qw==:#{base64_iv}:#{base64_salt}]"
35
+ subject.encrypt('flabberghaster', insecure_opts).should == expected_value
36
+ end
37
+
38
+ it 'with --raw' do
39
+ expected_value = "7u523Z+PpqSm58+BeiN4qw==:#{base64_iv}:#{base64_salt}"
40
+ subject.encrypt('flabberghaster', {:raw => true}.merge(insecure_opts)).should == expected_value
41
+ end
42
+
43
+ it 'with --secretkey' do
44
+ mock_secret_key('/etc/another_key', 'anotherkey')
45
+ expected_value = "ENC[81crlXmuzSnld3+4YUkQYg==:#{base64_iv}:#{base64_salt}]"
46
+ subject.encrypt('flabberghaster', {:secretkey => '/etc/another_key'}.merge(insecure_opts)).should == expected_value
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'decrypt' do
52
+ describe 'should decrypt a value' do
53
+ it 'with ENC[...]' do
54
+ subject.decrypt('ENC[3xzy8fiXlaJqv3m+aXIJNA==]').should == 'flabberghaster'
55
+ end
56
+
57
+ it 'with --raw' do
58
+ subject.decrypt('3xzy8fiXlaJqv3m+aXIJNA==', {:raw => true}).should == 'flabberghaster'
59
+ end
60
+
61
+ it 'with --secretkey' do
62
+ mock_secret_key('/etc/another_key', 'anotherkey')
63
+ subject.decrypt('ENC[8MaZYHPdj9IpnzcuBLlMdg==]', {:secretkey => '/etc/another_key'}).should == 'flabberghaster'
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,53 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'decrypt' do
5
+ before(:all) do
6
+ mock_secret_key(Puppet::Decrypt::Decryptor::DEFAULT_FILE, 'masterkey')
7
+ end
8
+
9
+ let(:node) { 'testhost.example.com' }
10
+ extdata_path = File.expand_path(File.join(File.dirname(__FILE__), '../../puppet/manifests/extdata'))
11
+ let(:pre_condition) { "$extlookup_datadir = '#{extdata_path}' $extlookup_precedence = ['common', 'env_vagrant']" }
12
+
13
+ context "unencrypted key" do
14
+ it { should run.with_params('blah').and_return("blah") }
15
+ end
16
+
17
+ context "encrypted key" do
18
+ it "should decrypt exact matches" do
19
+ should run.with_params('ENC[3xzy8fiXlaJqv3m+aXIJNA==]').and_return("flabberghaster")
20
+ end
21
+
22
+ it "should not decrypt partial matches" do
23
+ should run.with_params('fooENC[3xzy8fiXlaJqv3m+aXIJNA==]bar').and_return('fooENC[3xzy8fiXlaJqv3m+aXIJNA==]bar')
24
+ end
25
+ end
26
+
27
+ context "with secret key in string" do
28
+ it "should decrypt exact matches" do
29
+ mock_secret_key('/etc/puppet-decrypt/another_key', 'anotherkey')
30
+ should run.with_params('ENC:another_key[8MaZYHPdj9IpnzcuBLlMdg==]').and_return('flabberghaster')
31
+ end
32
+
33
+ it "should not decrypt partial matches" do
34
+ should run.with_params('fooENC:max[3xzy8fiXlaJqv3m+aXIJNA==]bar').and_return('fooENC:max[3xzy8fiXlaJqv3m+aXIJNA==]bar')
35
+ end
36
+ end
37
+
38
+ context "with secret key file" do
39
+ it "should decrypt exact matches" do
40
+ mock_secret_key('/etc/another_key', 'anotherkey')
41
+ should run.with_params({ 'value' => 'ENC[8MaZYHPdj9IpnzcuBLlMdg==]', 'secretkey' => '/etc/another_key'}).and_return('flabberghaster')
42
+ end
43
+
44
+ it "should override a key in the string" do
45
+ mock_secret_key('/etc/another_key', 'anotherkey')
46
+ should run.with_params({ 'value' => 'ENC:max[8MaZYHPdj9IpnzcuBLlMdg==]', 'secretkey' => '/etc/another_key'}).and_return('flabberghaster')
47
+ end
48
+
49
+ it "should not decrypt partial matches" do
50
+ should run.with_params({ 'value' => 'fooENC[3xzy8fiXlaJqv3m+aXIJNA==]bar', 'secretkey' => '/etc/another_key'}).and_return('fooENC[3xzy8fiXlaJqv3m+aXIJNA==]bar')
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe 'encrypt' do
5
+ before(:all) do
6
+ mock_secret_key(Puppet::Decrypt::Decryptor::DEFAULT_FILE, 'masterkey')
7
+ end
8
+
9
+ let(:node) { 'testhost.example.com' }
10
+ extdata_path = File.expand_path(File.join(File.dirname(__FILE__),
11
+ '../../puppet/manifests/extdata'))
12
+
13
+ let :pre_condition do
14
+ "$extlookup_datadir = '#{extdata_path}' $extlookup_precedence = ['common', 'env_vagrant']"
15
+ end
16
+
17
+ let :salt do
18
+ 'test_salt'
19
+ end
20
+
21
+ let :iv do
22
+ "YS7nvbPsLP+pIJQ0waxV0w=="
23
+ end
24
+
25
+ context "unencrypted key" do
26
+ it "should encrypt plain string" do
27
+ subject.call(['blah']).should =~
28
+ Puppet::Decrypt::Decryptor::ENCRYPTED_PATTERN
29
+ end
30
+ end
31
+
32
+ context "encrypted key" do
33
+ it "should encrypt exact matches" do
34
+ subject.call(["flabberghaster", nil, salt, iv]).should ==
35
+ 'ENC[WnA7ezNPSZx2S01T67TCfA==:WVM3bnZiUHNMUCtwSUpRMHdheFYwdz09:dGVzdF9zYWx0]'
36
+ end
37
+ end
38
+
39
+ context "with secret key file" do
40
+ it "should encrypt exact matches" do
41
+ mock_secret_key('/etc/another_key', 'anotherkey')
42
+ subject.call(['value' => 'flabberghaster', 'secretkey' =>
43
+ '/etc/another_key', 'iv' => iv, 'salt' => salt]) =~
44
+ Puppet::Decrypt::Decryptor::ENCRYPTED_PATTERN
45
+
46
+ _, iv_hash, salt_hash = Regexp.last_match[2].split(':')
47
+ strict_decode64(iv_hash).should == iv
48
+ strict_decode64(salt_hash).should == salt
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ # Backported for ruby 1.8.7
55
+ def strict_decode64(str)
56
+ return Base64.strict_decode64(str) if Base64.respond_to? :strict_decode64
57
+
58
+ if str.include?("\n")
59
+ raise(ArgumentError,"invalid base64")
60
+ else
61
+ Base64.decode64(str)
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ module Puppet
2
+ module Decrypt
3
+ def self.key_loader=(key_loader)
4
+ @key_loader = key_loader
5
+ end
6
+
7
+ class FakeKeyLoader
8
+ def initialize
9
+ @secrets = {}
10
+ end
11
+
12
+ def add_secret(secret_key_file, secret_key)
13
+ @secrets[secret_key_file] = secret_key
14
+ end
15
+
16
+ def load_key(secret_key_file)
17
+ raise "Secret key file: #{secret_key_file} is not readable!" unless @secrets.has_key? secret_key_file
18
+ secret_key = @secrets[secret_key_file]
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ Puppet::Decrypt.key_loader = Puppet::Decrypt::FakeKeyLoader.new
@@ -0,0 +1,24 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rspec-puppet'
3
+ require 'puppet-decrypt/fake_key_loader'
4
+ require 'puppet-decrypt'
5
+ require 'rspec/mocks'
6
+
7
+ Puppet::Decrypt.key_loader = Puppet::Decrypt::FakeKeyLoader.new
8
+
9
+ module SecretKeyHelper
10
+ def mock_secret_key(filename, secret)
11
+ Puppet::Decrypt.key_loader.add_secret(filename, secret)
12
+ end
13
+ end
14
+
15
+ RSpec::Mocks::setup(self)
16
+
17
+ RSpec.configure do |c|
18
+ c.include SecretKeyHelper
19
+ end
20
+
21
+ if ENV['PUPPET_DEBUG']
22
+ Puppet::Util::Log.level = :debug
23
+ Puppet::Util::Log.newdestination(:console)
24
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-crypt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - mlincoln
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: encryptor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cucumber
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.14.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.14.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-puppet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: puppetlabs_spec_helper
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: A gem for encrypting/decrypting secret values for use with Puppet
98
+ email:
99
+ - max@devopsy.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".rvmrc"
107
+ - ".travis.yml"
108
+ - ChangeLog.md
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - Modulefile
112
+ - README.md
113
+ - Rakefile
114
+ - bundles/puppet_2_7.gemfile
115
+ - bundles/puppet_3_0.gemfile
116
+ - bundles/puppet_edge.gemfile
117
+ - features/fixtures/data/overridden_secret_key.yaml
118
+ - features/fixtures/data/simple.yaml
119
+ - features/fixtures/hiera.yaml
120
+ - features/fixtures/manifests/overridden_secret_key.pp.bak
121
+ - features/fixtures/manifests/simple.pp
122
+ - features/fixtures/other_secretkeys/secondary_key
123
+ - features/fixtures/secretkeys/alt_key
124
+ - features/fixtures/secretkeys/encryptor_secret_key
125
+ - features/hiera.feature
126
+ - features/step_definitions/puppet_steps.rb
127
+ - features/support/env.rb
128
+ - lib/puppet-decrypt.rb
129
+ - lib/puppet-decrypt/decryptor.rb
130
+ - lib/puppet-decrypt/key_loader.rb
131
+ - lib/puppet-decrypt/version.rb
132
+ - lib/puppet/application/crypt.rb
133
+ - lib/puppet/face/crypt.rb
134
+ - lib/puppet/functions/decrypt.rb
135
+ - lib/puppet/functions/encrypt.rb
136
+ - puppet-crypt.gemspec
137
+ - spec/faces/crypt_spec.rb
138
+ - spec/functions/decrypt_spec.rb
139
+ - spec/functions/encrypt_spec.rb
140
+ - spec/puppet-decrypt/fake_key_loader.rb
141
+ - spec/spec_helper.rb
142
+ homepage: https://github.com/wgsateam/puppet-decrypt
143
+ licenses: []
144
+ metadata: {}
145
+ post_install_message: |2+
146
+
147
+
148
+ Notice: The default master key location is now /etc/puppet-decrypt/encryptor_secret_key
149
+
150
+ This was done to more easily support multiple keys. If you are upgrading from a version older than
151
+ 0.1.0 you should move /etc/encryptor_secret_key to /etc/puppet-decrypt/encryptor_secret_key.
152
+
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 1.8.7
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubygems_version: 3.0.3
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: A shared secret strategy that works with any data source
171
+ test_files:
172
+ - features/fixtures/data/overridden_secret_key.yaml
173
+ - features/fixtures/data/simple.yaml
174
+ - features/fixtures/hiera.yaml
175
+ - features/fixtures/manifests/overridden_secret_key.pp.bak
176
+ - features/fixtures/manifests/simple.pp
177
+ - features/fixtures/other_secretkeys/secondary_key
178
+ - features/fixtures/secretkeys/alt_key
179
+ - features/fixtures/secretkeys/encryptor_secret_key
180
+ - features/hiera.feature
181
+ - features/step_definitions/puppet_steps.rb
182
+ - features/support/env.rb
183
+ - spec/faces/crypt_spec.rb
184
+ - spec/functions/decrypt_spec.rb
185
+ - spec/functions/encrypt_spec.rb
186
+ - spec/puppet-decrypt/fake_key_loader.rb
187
+ - spec/spec_helper.rb