cipherpipe 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 15b425e50ef35bf3fc0b593f4c4c7e8b356704fb00e8319e635e05062c8f5fc5
4
+ data.tar.gz: 66aaa053fc30dd29b72552bfd1374143ce300a8da80d716fdd870e65a8553d20
5
+ SHA512:
6
+ metadata.gz: c1c251974d2c8b78835b568c3b9174e7d5e603e3f345a91b801c9d24e7929a0612f6043dd16be6135da6e3038f50055081275c29fdc71256923dcbb9a0297c56
7
+ data.tar.gz: b703b2dd774baeead92f5f713c1436503c56d1ca80ebbeed0436366375450ce71f73f1f0a3109ed518c04c9db9e05844f9d68fc3c6739d8080a4a3a047ce4043
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.7
5
+ - 2.4.4
6
+ - 2.5.1
7
+ notifications:
8
+ slack:
9
+ secure: VjoVsvjoV0CT/QhdqMTiyDPzl3+9GxFaqT84clrj/UjgYCHCt09xnnBm28PpLjCjGGgwbio/K7+pRGtHqQGOONwtgjTOqvj6cge90TYDe7cXvxYANZYOBELvvObDIIwKx72ry9pnu+otWNKYGMjqpJvTVL3o+Sm7XY5OFHyr/LDWtRhaGHCJV2jXuiVUnkKXacWOLjX5lo+tEK6G1vYmRXOAmhp6Ip9hL1NPz//TYz08oO1fc54JgrI+pBKMU84j2no5o3eE/bv4Qex8rAxuwhaHkqw5X/E3JMhVBcKomt1FuHOLd39Eb0RTsYDLSmOkRvKIVBI/jsLupTDGr54X8VuAVGoOzWt/OtGS3z586DWXy1ZinNCunSHnVi5d9X8bWnxq57KHS5Vp6f8aBxcVCDq/h2hNaD1oCkIvfTqgstbbcILbRGxve7vvHgOOXAZg4f4LIg652S3JqiA5sTdHz6nGCH2aNsirRuzRCqBfXUAn72q+aKwfNwSbkPz7LVumFSuyvRrXua+ZQ8YY+KTcumLwlCPwnVstcvYWjGx7BsGOvgBLBpMjo985Hkq0dYgBe7mWJmqX8Xb5/1lLQO5GCitrOVSMye/GkTEQT5kizMQr17T63vmx+lUJkTshbnJZZRGEL70dwM8N090jEkXIbDit1oejbFZ0fRwoFoNzSpk=
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at pat@freelancing-gods.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "vault", "~> 0.11"
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cipherpipe (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.5.2)
10
+ public_suffix (>= 2.0.2, < 4.0)
11
+ aws-sigv4 (1.0.2)
12
+ crack (0.4.3)
13
+ safe_yaml (~> 1.0.0)
14
+ diff-lcs (1.3)
15
+ hashdiff (0.3.7)
16
+ public_suffix (3.0.2)
17
+ rake (12.3.1)
18
+ rspec (3.7.0)
19
+ rspec-core (~> 3.7.0)
20
+ rspec-expectations (~> 3.7.0)
21
+ rspec-mocks (~> 3.7.0)
22
+ rspec-core (3.7.1)
23
+ rspec-support (~> 3.7.0)
24
+ rspec-expectations (3.7.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.7.0)
27
+ rspec-mocks (3.7.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.7.0)
30
+ rspec-support (3.7.1)
31
+ safe_yaml (1.0.4)
32
+ vault (0.11.0)
33
+ aws-sigv4
34
+ webmock (3.4.2)
35
+ addressable (>= 2.3.6)
36
+ crack (>= 0.3.2)
37
+ hashdiff
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ bundler (~> 1.16)
44
+ cipherpipe!
45
+ rake (~> 12.0)
46
+ rspec (~> 3.7)
47
+ vault (~> 0.11)
48
+ webmock (~> 3.4)
49
+
50
+ BUNDLED WITH
51
+ 1.16.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Pat Allan
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.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # Cipherpipe
2
+
3
+ Cipherpipe transfers secrets from stores (such as Vault) onto your local machine, or into the `ENV` of a Ruby app. You can then make changes and upload these back into the store - all of which is done only when you have valid access.
4
+
5
+ ## Why?
6
+
7
+ App and infrastructure secrets - API keys and other sensitive information - should be managed very carefully. Reading and writing these secrets must happen, though: developers will add new values in, production servers will retrieve values, and potentially so will CI services.
8
+
9
+ Cipherpipe makes the transferring of this data predictable and reliable. It doesn't take care of managing authentication - you'll need to do that yourself (for example, with Vault via the appropriate tokens) - but it provides an executable to send and retrieve secrets as determined by a configuration file that can be checked in to the appropriate version control repositories.
10
+
11
+ ## Installation
12
+
13
+ To use Cipherpipe on your machine, you'll need to install the gem:
14
+
15
+ $ gem install cipherpipe
16
+
17
+ There are additional gems you may need, depending on what formats and which secret storage services you're dealing with.
18
+
19
+ $ gem install vault # if you're interacting with Vault
20
+ $ gem install rhcl # if you're storing data as HCL variables (e.g. Terraform)
21
+ $ gem install dotenv # if you're storing data as a bash env file.
22
+
23
+ If you want to access secrets within your Rails/Ruby app, then add it to your Gemfile:
24
+
25
+ ```ruby
26
+ gem 'cipherpipe'
27
+ ```
28
+
29
+ And add the following to an initializer to load the secrets:
30
+
31
+ ```ruby
32
+ Cipherpipe::Commands::Load.call
33
+ ```
34
+
35
+ ## Configuration
36
+
37
+ Everything for Cipherpipe is managed in a YAML configuration file `.cipherpipe.yml` which you should place in the root of your project. You'll need to specify at least one source (and mark it as the primary). Having an output file/format is optional, but likely useful.
38
+
39
+ When setting a Vault source, the destination is a key-value store (v2) and the `secret/` prefix is added automatically.
40
+
41
+ Here's an example for a Rails application using `dotenv` (and `ENVIRONMENT` is automatically translated to the appropriate Rails environment, as based on the RAILS_ENV variable):
42
+
43
+ ```yml
44
+ file: .env.ENVIRONMENT
45
+ format: env
46
+ sources:
47
+ - type: vault
48
+ destination: apps/myapp/ENVIRONMENT
49
+ primary: true
50
+ ```
51
+
52
+ Another example, for use with a Terraform project:
53
+
54
+ ```yml
55
+ file: terraform.tfvars
56
+ format: hcl
57
+ sources:
58
+ - type: vault
59
+ destination: infrastructure/myapp
60
+ primary: true
61
+ ```
62
+
63
+ Or, for use with Packer:
64
+
65
+ ```yml
66
+ file: variables.json
67
+ format: json
68
+ sources:
69
+ - type: vault
70
+ destination: images/myserver
71
+ primary: true
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ Once you've got things configured, you can use the `cipherpipe` executable to download or upload configuration.
77
+
78
+ Downloading takes data from the primary secret storage service, and copies it into the specified file, in the specified format:
79
+
80
+ $ cipherpipe download
81
+
82
+ Uploading will take the data from the configured file and send it to all of the configured secret sources.
83
+
84
+ $ cipherpipe upload
85
+
86
+ Make sure that the configured secrets file is _not_ stored in version control. The `.cipherpipe.yml` file, however, should definitely be stored.
87
+
88
+ ## Dependencies
89
+
90
+ If you're using Vault (which is likely, given it's currently the only supported secret storage service), you'll need to make sure it's using the V2 kv secrets engine.
91
+
92
+ ## Contributing
93
+
94
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/limbrapp/cipherpipe](https://github.com/limbrapp/cipherpipe). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
95
+
96
+ ## License
97
+
98
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
99
+
100
+ ## Code of Conduct
101
+
102
+ Everyone interacting in the Cipherpipe project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pat/cipherpipe/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cipherpipe"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "cipherpipe"
3
+ spec.version = "0.1.0"
4
+ spec.authors = ["Pat Allan"]
5
+ spec.email = ["pat@freelancing-gods.com"]
6
+
7
+ spec.summary = %q{Interact with secret stores and transfer data between them}
8
+ spec.homepage = "https://github.com/limbrapp/cipherpipe"
9
+ spec.license = "MIT"
10
+
11
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
12
+ f.match(%r{^(test|spec|features)/})
13
+ end
14
+ spec.bindir = "exe"
15
+ spec.executables = spec.files.grep(%r{^exe/}) { |file| File.basename(file) }
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_development_dependency "bundler", "~> 1.16"
19
+ spec.add_development_dependency "rake", "~> 12.0"
20
+ spec.add_development_dependency "rspec", "~> 3.7"
21
+ spec.add_development_dependency "webmock", "~> 3.4"
22
+ end
data/exe/cipherpipe ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+ # frozen_string_literal: true
4
+
5
+ require "cipherpipe"
6
+
7
+ Cipherpipe::CLI.call ARGV
@@ -0,0 +1,12 @@
1
+ class Cipherpipe::CLI
2
+ def self.call(arguments = [], configuration = nil)
3
+ case arguments.first
4
+ when "upload"
5
+ Cipherpipe::Commands::Upload.call configuration
6
+ when "download"
7
+ Cipherpipe::Commands::Download.call configuration
8
+ else
9
+ Cipherpipe::Commands::Help.call configuration
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ class Cipherpipe::Commands::Download
2
+ def self.call(configuration = nil)
3
+ new(configuration).call
4
+ end
5
+
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ end
9
+
10
+ def call
11
+ puts "Downloading from #{external_source.type}"
12
+ configuration.variables = external_source.download
13
+ end
14
+
15
+ private
16
+
17
+ def configuration
18
+ @configuration ||= Cipherpipe::Configuration.new
19
+ end
20
+
21
+ def external_source
22
+ @external_source ||= configuration.external_sources.detect { |source|
23
+ source.primary?
24
+ }
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ class Cipherpipe::Commands::Help
2
+ def self.call(configuration = nil)
3
+ puts <<~TXT
4
+ cipherpipe
5
+
6
+ Command-line tool for interacting with secret stores and transferring
7
+ data between them and with local environments.
8
+
9
+ Configuration for secret stores and any local copies are managed via a
10
+ .cipherpipe.yml file in the project's directory. Once that is in place,
11
+ the following commands can be used:
12
+
13
+ cipherpipe download # loads the secrets from the primary source
14
+ cipherpipe upload # uploads secrets to all sources
15
+
16
+ TXT
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ class Cipherpipe::Commands::Load
2
+ def self.call(configuration = nil)
3
+ new(configuration).call
4
+ end
5
+
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ end
9
+
10
+ def call
11
+ Cipherpipe::ENV.call external_source.download
12
+ end
13
+
14
+ private
15
+
16
+ def configuration
17
+ @configuration ||= Cipherpipe::Configuration.new
18
+ end
19
+
20
+ def external_source
21
+ @external_source ||= configuration.external_sources.detect { |source|
22
+ source.primary?
23
+ }
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ class Cipherpipe::Commands::Upload
2
+ def self.call(configuration = nil)
3
+ new(configuration).call
4
+ end
5
+
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ end
9
+
10
+ def call
11
+ configuration.external_sources.each do |source|
12
+ puts "Uploading to #{source.type}"
13
+ source.upload configuration.variables
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def configuration
20
+ @configuration ||= Cipherpipe::Configuration.new
21
+ end
22
+ end
@@ -0,0 +1,62 @@
1
+ require "yaml"
2
+
3
+ class Cipherpipe::Configuration
4
+ FILENAME = ".cipherpipe.yml"
5
+
6
+ UnknownFormatterError = Class.new Cipherpipe::Error
7
+
8
+ attr_reader :external_sources, :format, :file
9
+
10
+ def initialize(filename = FILENAME)
11
+ @filename = filename
12
+
13
+ parse!
14
+ end
15
+
16
+ def variables
17
+ formatter.read File.read(file)
18
+ end
19
+
20
+ def variables=(hash)
21
+ File.write file, formatter.write(hash) if file
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :filename
27
+
28
+ def environment
29
+ ENV["CIPHERPIPE_ENV"] || ENV["RAILS_ENV"] || "development"
30
+ end
31
+
32
+ def formatter
33
+ case format
34
+ when "json"
35
+ Cipherpipe::Formatters::JSON
36
+ when "hcl"
37
+ Cipherpipe::Formatters::HCL
38
+ when "env"
39
+ Cipherpipe::Formatters::Env
40
+ else
41
+ raise UnknownFormatterError, "unknown format #{format}"
42
+ end
43
+ end
44
+
45
+ def parse!
46
+ @external_sources = yaml["sources"].collect { |source| parse_source source }
47
+ @format = yaml["format"]
48
+ @file = yaml["file"].gsub("ENVIRONMENT", environment)
49
+ end
50
+
51
+ def parse_source(hash)
52
+ Cipherpipe::ExternalSource.new(
53
+ hash["type"],
54
+ hash["destination"].gsub("ENVIRONMENT", environment),
55
+ hash["primary"]
56
+ )
57
+ end
58
+
59
+ def yaml
60
+ @yaml ||= YAML.load File.read(filename)
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ class Cipherpipe::ENV
2
+ def self.call(variables)
3
+ variables.each { |key, value| ENV[key] ||= value }
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ class Cipherpipe::ExternalSource
2
+ UnknownProviderError = Class.new Cipherpipe::Error
3
+
4
+ attr_reader :type, :destination, :primary
5
+
6
+ def initialize(type, destination, primary = false)
7
+ @type = type
8
+ @destination = destination
9
+ @primary = primary
10
+ end
11
+
12
+ def download
13
+ if provider.available?
14
+ provider.download self
15
+ else
16
+ puts "#{type} is not available, download is being skipped."
17
+ end
18
+ end
19
+
20
+ def primary?
21
+ primary
22
+ end
23
+
24
+ def upload(variables)
25
+ if provider.available?
26
+ provider.upload self, variables
27
+ else
28
+ puts "#{type} is not available, upload is being skipped."
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def provider
35
+ @provider ||= case type
36
+ when "vault"
37
+ require_relative "vault"
38
+ Cipherpipe::Vault
39
+ else
40
+ raise UnknownProviderError, "unknown provider #{type}"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ class Cipherpipe::Formatters::Env
2
+ def self.read(input)
3
+ require "dotenv"
4
+ Dotenv::Parser.call input
5
+ end
6
+
7
+ def self.write(input)
8
+ input.each { |key, value|
9
+ "#{key}=\"#{value}\""
10
+ }.join("\n")
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class Cipherpipe::Formatters::HCL
2
+ def self.read(input)
3
+ require "rhcl"
4
+ ::Rhcl.parse input
5
+ end
6
+
7
+ def self.write(input)
8
+ require "rhcl"
9
+ ::Rhcl.dump input
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class Cipherpipe::Formatters::JSON
2
+ def self.read(input)
3
+ require "json"
4
+ ::JSON.load input
5
+ end
6
+
7
+ def self.write(input)
8
+ require "json"
9
+ ::JSON.pretty_generate input
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ class Cipherpipe::Vault::API < ::Vault::Request
2
+ def read(path, options = {})
3
+ headers = extract_headers! options
4
+ json = client.get("/v1/secret/data/#{encode_path(path)}", {}, headers)
5
+
6
+ ::Vault::Secret.decode json[:data]
7
+ rescue ::Vault::HTTPError => error
8
+ return nil if error.code == 404
9
+ raise error
10
+ end
11
+
12
+ def write(path, data = {}, options = {})
13
+ headers = extract_headers! options
14
+ json = Vault.logical.client.post(
15
+ "/v1/secret/data/#{encode_path path}",
16
+ JSON.fast_generate(:data => data),
17
+ headers
18
+ )
19
+
20
+ json.nil? ? true : ::Vault::Secret.decode(json)
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require "vault"
2
+ require_relative "api"
3
+
4
+ class Cipherpipe::Vault::Download
5
+ def self.call(external_source)
6
+ new(external_source).call
7
+ end
8
+
9
+ def initialize(external_source)
10
+ @external_source = external_source
11
+ end
12
+
13
+ def call
14
+ Cipherpipe::Vault::API.new(Vault.client).read(
15
+ external_source.destination
16
+ ).data
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :external_source
22
+ end
@@ -0,0 +1,23 @@
1
+ require "vault"
2
+ require_relative "api"
3
+
4
+ class Cipherpipe::Vault::Upload
5
+ def self.call(external_source, variables)
6
+ new(external_source, variables).call
7
+ end
8
+
9
+ def initialize(external_source, variables)
10
+ @external_source = external_source
11
+ @variables = variables
12
+ end
13
+
14
+ def call
15
+ Cipherpipe::Vault::API.new(Vault.client).write(
16
+ external_source.destination, variables
17
+ )
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :external_source, :variables
23
+ end
@@ -0,0 +1,17 @@
1
+ class Cipherpipe::Vault
2
+ def self.available?
3
+ true
4
+ end
5
+
6
+ def self.download(external_source)
7
+ require_relative "vault/download"
8
+
9
+ Cipherpipe::Vault::Download.call external_source
10
+ end
11
+
12
+ def self.upload(external_source, settings)
13
+ require_relative "vault/upload"
14
+
15
+ Cipherpipe::Vault::Upload.call external_source, settings
16
+ end
17
+ end
data/lib/cipherpipe.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Cipherpipe
2
+ Commands = Module.new
3
+ Error = Class.new StandardError
4
+ Formatters = Module.new
5
+ end
6
+
7
+ require_relative "cipherpipe/commands/download"
8
+ require_relative "cipherpipe/commands/help"
9
+ require_relative "cipherpipe/commands/load"
10
+ require_relative "cipherpipe/commands/upload"
11
+ require_relative "cipherpipe/cli"
12
+ require_relative "cipherpipe/configuration"
13
+ require_relative "cipherpipe/env"
14
+ require_relative "cipherpipe/external_source"
15
+ require_relative "cipherpipe/formatters/env"
16
+ require_relative "cipherpipe/formatters/hcl"
17
+ require_relative "cipherpipe/formatters/json"
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cipherpipe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Pat Allan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-06-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ description:
70
+ email:
71
+ - pat@freelancing-gods.com
72
+ executables:
73
+ - cipherpipe
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - CODE_OF_CONDUCT.md
80
+ - Gemfile
81
+ - Gemfile.lock
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/console
86
+ - bin/setup
87
+ - cipherpipe.gemspec
88
+ - exe/cipherpipe
89
+ - lib/cipherpipe.rb
90
+ - lib/cipherpipe/cli.rb
91
+ - lib/cipherpipe/commands/download.rb
92
+ - lib/cipherpipe/commands/help.rb
93
+ - lib/cipherpipe/commands/load.rb
94
+ - lib/cipherpipe/commands/upload.rb
95
+ - lib/cipherpipe/configuration.rb
96
+ - lib/cipherpipe/env.rb
97
+ - lib/cipherpipe/external_source.rb
98
+ - lib/cipherpipe/formatters/env.rb
99
+ - lib/cipherpipe/formatters/hcl.rb
100
+ - lib/cipherpipe/formatters/json.rb
101
+ - lib/cipherpipe/vault.rb
102
+ - lib/cipherpipe/vault/api.rb
103
+ - lib/cipherpipe/vault/download.rb
104
+ - lib/cipherpipe/vault/upload.rb
105
+ homepage: https://github.com/limbrapp/cipherpipe
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.7.6
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Interact with secret stores and transfer data between them
129
+ test_files: []