s3crets 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in s3crets.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 John Dyer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # S3crets
2
+
3
+ s3crets looks for a YAML config file and performs a deep merge against a directory of json files but only if the top level yaml key is present in the destination JSON file. This ensures your secrets are only merged into the files you intended. The purpose of s3crets was to help us keep secrets out of configuration JSON, which is kept in source control.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 's3crets'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install s3crets
18
+
19
+ ## Usage
20
+
21
+ Secrets takes 3 arguments, of which only 2 are required `[:json_dir, :secrets_file]`
22
+
23
+ ```bash
24
+ -s, --secrets-file FILE Secret file to merge into JSON (required)
25
+ -j, --json-dir DIR Directory to search for json files (required)
26
+ -o, --overwrite Overwrite JSON, default is false which will add '.new' to the file name, eg: something.json -> something.new.json
27
+ ```
28
+
29
+ ### Example Secrets File:
30
+
31
+ ```json
32
+ mysql:
33
+ server_repl_password: 11111
34
+ server_root_password: 22222
35
+ server_debian_password: 33333
36
+ random:
37
+ config: something
38
+ ```
39
+
40
+ Example JSON File
41
+
42
+ ```json
43
+ {
44
+ "node_type": "management-slave_server",
45
+ "run_list": "recipe[management-slave_server]",
46
+ "mysql": {
47
+ "server_root_password": 22222,
48
+ "server_repl_password": 11111,
49
+ "server_debian_password": 33333
50
+ },
51
+ "prism": {
52
+ "console": {
53
+ "realm": "ProvisioningRealm"
54
+ }
55
+ },
56
+ "provisioning_api": {
57
+ "brokers": [
58
+ "management1.qa.voxeolabs.net",
59
+ "management2.qa.voxeolabs.net"
60
+ ],
61
+ "jdbc_url": "jdbc:mysql://management1.qa.voxeolabs.net:3306/provisioning"
62
+ }
63
+ }
64
+ ```
65
+
66
+ If the preceeding secrets file is applied against the JSON file above only the mysql key will be merged in, since s3crets assumes all top level keys in the JSON object are correct. This allows you to have one secrets file and apply it against multiple JSON templates and only the indended data will be merged in.
67
+
68
+ ## Examples
69
+
70
+ ##### Applying Secrets while perserving original JSON files
71
+ ```bash
72
+ s3crets --secrets-file ~/Projects/deployment_models/full_ha_deployment_model/.secrets --json-dir ~/Projects/deployment_models/full_ha_deployment_model/ec2_json
73
+ ```
74
+
75
+ ##### Applying Secrets to original JSON files
76
+ ```bash
77
+ s3crets --secrets-file ~/Projects/deployment_models/full_ha_deployment_model/.secrets --json-dir ~/Projects/deployment_models/full_ha_deployment_model/ec2_json --overwrite
78
+ ```
79
+ ## Contributing
80
+
81
+ 1. Fork it
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/s3crets ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 's3crets'
5
+ require "rainbow"
6
+ @options={
7
+ :overwrite => false
8
+ }
9
+
10
+ optparse = OptionParser.new do |opts|
11
+
12
+ opts.on('-s', '--secrets-file FILE', "Secret file to merge into JSON (required)") do |s|
13
+ @options[:secrets_file] = s
14
+ end
15
+
16
+ opts.on('-j', '--json-dir DIR', "Directory to search for json files (required)") do |j|
17
+ @options[:json_dir] = j
18
+ end
19
+
20
+ opts.on('-o', '--overwrite', "Overwrite JSON, default is false which will add '.new' to the file name, eg: something.json -> something.new.json") do |j|
21
+ @options[:overwrite] = true
22
+ end
23
+ end
24
+
25
+ begin
26
+ optparse.parse!
27
+ mandatory = [:json_dir,:secrets_file] # Enforce the presence of
28
+ missing = mandatory.select{ |param| @options[param].nil? } # the -j switch
29
+ if not missing.empty? #
30
+ puts "Missing options: #{missing.join(', ')}" #
31
+ puts optparse #
32
+ exit #
33
+ end
34
+
35
+ end
36
+
37
+ begin
38
+ c = Configuratron.new @options
39
+
40
+ puts "----------------------------------------".foreground(:blue)
41
+ puts "[Files Updated]: ".foreground(:green)
42
+ c.files_updated.each do |f|
43
+ puts " - #{f}".foreground(:green)
44
+ end
45
+ puts "[Finished] ".foreground(:green)
46
+ puts "----------------------------------------".foreground(:blue)
47
+ rescue Exception => e
48
+ puts "[ERROR] - Something bad happened [#{e}]".foreground(:red)
49
+ end
@@ -0,0 +1,3 @@
1
+ module S3crets
2
+ VERSION = "0.0.1"
3
+ end
data/lib/s3crets.rb ADDED
@@ -0,0 +1,15 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ module S3crets
4
+
5
+ require "s3crets/version"
6
+ require "json"
7
+ require "yaml"
8
+ require "optparse"
9
+ require "fileutils"
10
+ require "pathname"
11
+ require "pp"
12
+ require "s3crets_dig"
13
+ require "s3crets_merge"
14
+ require "rainbow"
15
+ end
@@ -0,0 +1,7 @@
1
+ class Hash
2
+ def dig(*path)
3
+ path.inject(self) do |location, key|
4
+ location.respond_to?(:keys) ? location[key] : nil
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,87 @@
1
+ class Configuratron
2
+
3
+ attr_reader :keys, :overwrite, :files_updated
4
+
5
+ def initialize(opts={})
6
+ if opts[:secrets_file]
7
+ begin
8
+ @secrets = YAML::load_file(opts[:secrets_file])
9
+ rescue Exception => e
10
+ raise RuntimeError, "Yaml config file not found"
11
+ end
12
+ else
13
+ @secrets = find_secrets
14
+ end
15
+
16
+ @files_updated = []
17
+
18
+ @overwrite = opts.has_key?(:overwrite) ? opts[:overwrite] : false
19
+
20
+ replace_config(opts[:json_dir])
21
+
22
+ end
23
+
24
+ def replace_config(dir)
25
+
26
+ search_folder = File.expand_path(dir)
27
+ files = Dir.glob(search_folder + "/*.json")
28
+
29
+ if files.empty?
30
+ puts "Was unable to find any JSON files [#{search_folder}]"
31
+ else
32
+ Dir.glob(File.expand_path(dir) + "/*.json") do |json_file|
33
+
34
+ next if json_file =~ /.new./
35
+
36
+ @secrets.keys.each do |k|
37
+
38
+ node_data = JSON.parse(File.read(json_file))
39
+
40
+ if node_data.dig(k)
41
+
42
+ json = node_data.merge({
43
+ k => node_data[k].merge!(@secrets[k])
44
+ })
45
+
46
+ file_to_write = get_file_name(json_file)
47
+ files_updated << file_to_write
48
+ File.open(file_to_write, 'w') do |fh|
49
+ fh.puts JSON.pretty_generate(json)
50
+ fh.close
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def get_file_name(json_file)
61
+ f = File.split(json_file)
62
+ path = f[0]
63
+ file = f[1]
64
+
65
+ if @overwrite
66
+ json_file
67
+ else
68
+ File.join(path , file.insert(file.index("."),".new"))
69
+ end
70
+ end
71
+
72
+ #Climb path looking for .secrets file
73
+ def find_secrets
74
+ secrets = nil
75
+ Pathname.new(Dir.pwd).ascend{ |dir|
76
+ config_file = dir + ".secrets"
77
+ secrets = YAML::load_file(config_file) if dir.children.include?(config_file)
78
+ }
79
+
80
+ if secrets.nil? or secrets.kind_of?(FalseClass)
81
+ raise RuntimeError, "[FATAL] - Unable to find or parse secrets file, giving up"
82
+ else
83
+ return secrets
84
+ end
85
+ end
86
+
87
+ end
data/s3crets.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 's3crets/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "s3crets"
8
+ gem.version = S3crets::VERSION
9
+ gem.authors = ["John Dyer"]
10
+ gem.email = ["jdyer@voxeolabs.com"]
11
+ gem.description = %q{Applys yaml secrets against Chef JSON files }
12
+ gem.summary = %q{s3crets looks for a YAML config file and performs a deep merge against a directory of json files but only if the top level yaml key is present in the destination JSON file. This ensures your secrets are only merged into the files you intended. The purpose of s3crets was to help us keep secrets out of configuration JSON, which is kept in source control.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib","bin"]
19
+
20
+ gem.add_dependency 'rake'
21
+ gem.add_dependency 'json'
22
+ gem.add_dependency 'rainbow'
23
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3crets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Dyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rainbow
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: ! 'Applys yaml secrets against Chef JSON files '
63
+ email:
64
+ - jdyer@voxeolabs.com
65
+ executables:
66
+ - s3crets
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/s3crets
76
+ - lib/s3crets.rb
77
+ - lib/s3crets/version.rb
78
+ - lib/s3crets_dig.rb
79
+ - lib/s3crets_merge.rb
80
+ - s3crets.gemspec
81
+ homepage: ''
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ - bin
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ segments:
95
+ - 0
96
+ hash: -3663029455517111644
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ segments:
104
+ - 0
105
+ hash: -3663029455517111644
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.23
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: s3crets looks for a YAML config file and performs a deep merge against a
112
+ directory of json files but only if the top level yaml key is present in the destination
113
+ JSON file. This ensures your secrets are only merged into the files you intended. The
114
+ purpose of s3crets was to help us keep secrets out of configuration JSON, which
115
+ is kept in source control.
116
+ test_files: []