kichi 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39626d63d4bfa5a2dc6bf730be34c7c2f6649f24
4
+ data.tar.gz: db73efece42506cde24e7751b8496ac3d6cba0d7
5
+ SHA512:
6
+ metadata.gz: ee71404a51c8625fc09f23db1fe61d82e4dc7c43dd0990a6ba11197f638c85213dc80cfa7d624f56336b3e248fb32eb8d9f8c657ab14e9fa4b596a2053a5a76d
7
+ data.tar.gz: 0fe0698693d9729d2659e59e7013f709314805019f2d8af61104788e12c45a3e8df33a0bf48f0e197d7ad16ad73c27a6c470209ca61bf5f2090ae8bc680be005
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.5
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kichi.gemspec
4
+ gemspec
@@ -0,0 +1,106 @@
1
+ # Kichi
2
+
3
+ Kichi is a simple commandline tool to manage application secrets for your applications using AWS.
4
+
5
+ Often you have shell scripts like:
6
+
7
+ ```
8
+ USERNAME=mytzypdlk \
9
+ PASSWORD=aliceinwonderland1923 \
10
+ SENDGRID_USER=koouser \
11
+ SENDGRID_PASSWORD=koolpassword \
12
+ bash deploy.sh
13
+ ```
14
+
15
+ Which are your base things.
16
+
17
+ Sometimes you might even commit them by accident.
18
+
19
+ To test different environments with different environment variables that contain sensitive information, it is a pain to keep having to export them, and keeping files and updating them with your secrets around is a manual step no one needs to have. Even worse, sending them over chat programs and giving third parties access to your info.
20
+
21
+ Kichi reduces this to:
22
+
23
+ $ kichi in my_env run bash deploy.sh
24
+
25
+ And you can provide your colleagues with AWS keys access to your secrets bucket and have them run this instead, without having to send secrets to them over third party services.
26
+
27
+ ## Installation
28
+
29
+ Add this line to your application's Gemfile:
30
+
31
+ ```ruby
32
+ gem 'kichi'
33
+ ```
34
+
35
+ And then execute:
36
+
37
+ $ bundle
38
+
39
+ Or install it yourself as:
40
+
41
+ $ gem install kichi
42
+
43
+ ## Usage
44
+
45
+ To use kichi with an S3 bucket, you need to have your aws credentials set up with `aws configure`
46
+
47
+ $ kichi use s3
48
+
49
+ To set environment variables
50
+
51
+ $ kichi set USERNAME pikachu
52
+ $ kichi set PASSWORD youwashock
53
+
54
+ To view environment variables
55
+
56
+ $ kichi get USERNAME
57
+
58
+ To set files
59
+
60
+ $ kichi cp key.pem PRIVATE_KEY
61
+
62
+ > when you set a file, the env var will come up as PRIVATE_KEY_PATH. This env var will be your path to the actual file that was downloaded
63
+
64
+ To get files
65
+
66
+ $ kichi dl PRIVATE_KEY
67
+
68
+ > this will download to a file called PRIVATE_KEY on your current directory.
69
+
70
+ To create a new environment
71
+
72
+ $ kichi create my_env
73
+
74
+ To add environment variables to an environment
75
+
76
+ $ kichi add USERNAME my_env
77
+ $ kichi add PASSWORD my_env
78
+
79
+ To add a file to an environment
80
+
81
+ $ kichi addfile PRIVATE_KEY my_env
82
+
83
+ To list the variable names in an environment
84
+
85
+ $ kichi list my_env
86
+
87
+ To run a program using an environment
88
+
89
+ $ kichi in my_env run ./server
90
+
91
+
92
+ ## Kichi
93
+
94
+ Kichi means "base" as in "military base" in Japanese. I chose the word because military bases generally have lots of secrets.
95
+
96
+ ## Development
97
+
98
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
99
+
100
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
101
+
102
+
103
+ ## Contributing
104
+
105
+ Bug reports and pull requests are welcome on GitHub at https://github.com/davidsiaw/kichi.
106
+
@@ -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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kichi"
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
@@ -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,161 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "kichi"
4
+ require "aws-sdk-core"
5
+ require "yaml"
6
+ require "fileutils"
7
+ require 'shellwords'
8
+
9
+ module Kichi
10
+
11
+ subcommand = ARGV.shift
12
+
13
+ class Commands
14
+ def initialize
15
+ @settings_dir = File.join(Dir.home, ".kichi")
16
+ end
17
+
18
+ def use
19
+ what = ARGV.shift
20
+ case what
21
+ when "s3"
22
+ sts = Aws::STS::Client.new
23
+ s3 = Aws::S3::Client.new
24
+
25
+ account_id = sts.get_caller_identity.account
26
+ begin
27
+ bucket_name = "kichi-store-#{account_id}"
28
+ s3.head_bucket(bucket: bucket_name)
29
+ rescue Aws::S3::Errors::NotFound => e
30
+ puts "Bucket not found, creating..."
31
+ s3.create_bucket(bucket: bucket_name)
32
+ rescue => e
33
+ puts "You may not have permission to view the kichi bucket"
34
+ end
35
+
36
+ FileUtils.mkdir_p @settings_dir
37
+ File.write(File.join(@settings_dir, "settings"), {s3_bucket: bucket_name}.to_yaml)
38
+
39
+ else
40
+ puts "Unknown store '#{what}'"
41
+ end
42
+ end
43
+
44
+ def set
45
+ var_name = ARGV.shift
46
+ var_content = ARGV.join(" ")
47
+ kichi.set_var(var_name, var_content)
48
+ end
49
+
50
+ def get
51
+ var_name = ARGV.shift
52
+ var_content = kichi.get_var(var_name)
53
+ puts "#{var_name}=#{Shellwords.escape(var_content)}"
54
+ end
55
+
56
+ def create
57
+ var_name = ARGV.shift
58
+ kichi.create_env(var_name)
59
+ end
60
+
61
+ def add
62
+ var_name = ARGV.shift
63
+ env_name = ARGV.shift
64
+ alias_name = ARGV.shift
65
+ kichi.add_to_env(env_name, var_name, alias_name)
66
+ end
67
+
68
+ def addfile
69
+ var_name = ARGV.shift
70
+ env_name = ARGV.shift
71
+ alias_name = ARGV.shift
72
+ kichi.add_to_env(env_name, var_name, alias_name, true)
73
+ end
74
+
75
+ def remove
76
+ var_name = ARGV.shift
77
+ env_name = ARGV.shift
78
+ kichi.remove_from_env(env_name, var_name)
79
+ end
80
+
81
+ def list
82
+ env_name = ARGV.shift
83
+ kichi.get_env(env_name).each do |k,v|
84
+ if v[:type] == :file
85
+ if v[:alias]
86
+ puts "#{v[:alias]} (#{k}_PATH)"
87
+ else
88
+ puts "#{k}_PATH"
89
+ end
90
+ else
91
+ if v[:alias]
92
+ puts "#{v[:alias]} (#{k})"
93
+ else
94
+ puts "#{k}"
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ def in
101
+ env_name = ARGV.shift
102
+ action = ARGV.shift
103
+ if action != "run"
104
+ throw "Expected run command after env_name"
105
+ end
106
+ file_dir = File.join(@settings_dir, "files")
107
+ FileUtils.mkdir_p file_dir
108
+ envs = kichi.get_env(env_name).map do |k,v|
109
+ key = k
110
+ if v[:type] == :envvar
111
+ value = kichi.get_var(k)
112
+ if v[:alias]
113
+ key = v[:alias]
114
+ end
115
+ [key, value]
116
+ elsif v[:type] == :file
117
+ contents = kichi.download(k)
118
+ location = File.join(file_dir, k)
119
+ File.write(location, contents)
120
+ if v[:alias]
121
+ key = v[:alias]
122
+ end
123
+ ["#{key}_PATH", location]
124
+
125
+ end
126
+ end.to_h
127
+ exec(envs, ARGV.join(" "))
128
+ end
129
+
130
+ def cp
131
+ filename = ARGV.shift
132
+ var_name = ARGV.shift
133
+ kichi.upload(var_name, filename)
134
+ end
135
+
136
+ def dl
137
+ var_name = ARGV.shift
138
+ content = kichi.download(var_name)
139
+ File.write(var_name, content)
140
+ puts "File saved to #{var_name}"
141
+ end
142
+
143
+ def method_missing(name,*args,&block)
144
+ puts "Unknown command '#{name}'"
145
+ end
146
+
147
+ private
148
+
149
+ def kichi
150
+ if !File.exists?(File.join(@settings_dir, "settings"))
151
+ puts "Please setup kichi by calling kichi use s3"
152
+ exit!
153
+ end
154
+ settings = YAML.load_file(File.join(@settings_dir, "settings"))
155
+ Kichi.new settings
156
+ end
157
+ end
158
+
159
+ Commands.new.send(:"#{subcommand}")
160
+
161
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kichi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kichi"
8
+ spec.version = Kichi::VERSION
9
+ spec.authors = ["David Siaw"]
10
+ spec.email = ["davidsiaw@gmail.com"]
11
+
12
+ spec.summary = %q{Simple commandline key management system}
13
+ spec.description = %q{Kichi is a simple commandline tool that allows you to store secrets and retrieve them as environment variables for working with them}
14
+ spec.homepage = "https://github.com/davidsiaw/kichi"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.12"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ spec.add_development_dependency "rspec", "~> 3.0"
32
+
33
+ spec.add_dependency "aws-sdk", "~> 2.6"
34
+
35
+ end
@@ -0,0 +1,97 @@
1
+ require "kichi/version"
2
+
3
+ module Kichi
4
+ class Kichi
5
+ def initialize(settings)
6
+ @settings = settings
7
+ @s3 = Aws::S3::Client.new
8
+ end
9
+
10
+ def s3
11
+ @s3
12
+ end
13
+
14
+ def is_valid_env_name?(env_name)
15
+ /[a-z0-9\-_]+/.match(env_name) != nil
16
+ end
17
+
18
+ def is_valid_var_name?(var_name)
19
+ /[A-Z][A-Z0-9_]+/.match(var_name) != nil
20
+ end
21
+
22
+ def set_var(var_name, var_content)
23
+ if !is_valid_var_name?(var_name)
24
+ throw "Variable name must contain only capital letters, numbers and underscores"
25
+ end
26
+ s3.put_object(bucket: @settings[:s3_bucket], key: "variables/#{var_name}", body: var_content)
27
+ end
28
+
29
+ def get_var(var_name)
30
+ begin
31
+ s3.get_object(bucket: @settings[:s3_bucket], key: "variables/#{var_name}").body.read
32
+ rescue Aws::S3::Errors::NoSuchKey
33
+ throw "Variable #{var_name} does not exist"
34
+ end
35
+ end
36
+
37
+ def create_env(env_name)
38
+ if !is_valid_env_name?(env_name)
39
+ throw "Environment name must contain only letters, numbers, hypens and underscores"
40
+ end
41
+ begin
42
+ s3.head_object(bucket: @settings[:s3_bucket], key: "environments/#{env_name}")
43
+ throw "Environment #{env_name} already exists"
44
+ rescue Aws::S3::Errors::NotFound
45
+ s3.put_object(bucket: @settings[:s3_bucket], key: "environments/#{env_name}", body: {}.to_yaml)
46
+ end
47
+ end
48
+
49
+ def get_env(env_name)
50
+ begin
51
+ YAML.load(s3.get_object(bucket: @settings[:s3_bucket], key: "environments/#{env_name}").body.read)
52
+ rescue Aws::S3::Errors::NoSuchKey
53
+ throw "Environment #{env_name} does not exist"
54
+ end
55
+ end
56
+
57
+ def add_to_env(env_name, var_name, alias_name=nil, is_file=false)
58
+ env = get_env(env_name)
59
+
60
+ if is_file
61
+ download(var_name)
62
+ env[var_name] = {alias: alias_name, type: :file}
63
+ else
64
+ get_var(var_name)
65
+ env[var_name] = {alias: alias_name, type: :envvar}
66
+ end
67
+
68
+ s3.put_object(bucket: @settings[:s3_bucket], key: "environments/#{env_name}", body: env.to_yaml)
69
+ end
70
+
71
+ def remove_from_env(env_name, var_name)
72
+ env = get_env(env_name)
73
+ if env[var_name]
74
+ env.delete(var_name)
75
+ s3.put_object(bucket: @settings[:s3_bucket], key: "environments/#{env_name}", body: env.to_yaml)
76
+ end
77
+ end
78
+
79
+ def upload(var_name, filename)
80
+ if !File.exists? filename
81
+ throw "File #{filename} does not exist"
82
+ end
83
+ if !is_valid_var_name?(var_name)
84
+ throw "Variable name must contain only capital letters, numbers and underscores"
85
+ end
86
+ s3.put_object(bucket: @settings[:s3_bucket], key: "files/#{var_name}", body: File.read(filename))
87
+ end
88
+
89
+ def download(var_name)
90
+ begin
91
+ s3.get_object(bucket: @settings[:s3_bucket], key: "files/#{var_name}").body.read
92
+ rescue Aws::S3::Errors::NoSuchKey
93
+ throw "File #{var_name} does not exist"
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module Kichi
2
+ VERSION = "0.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kichi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - David Siaw
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-05-23 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.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.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.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-sdk
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.6'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.6'
69
+ description: Kichi is a simple commandline tool that allows you to store secrets and
70
+ retrieve them as environment variables for working with them
71
+ email:
72
+ - davidsiaw@gmail.com
73
+ executables:
74
+ - kichi
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - ".rspec"
80
+ - ".travis.yml"
81
+ - Gemfile
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - exe/kichi
87
+ - kichi.gemspec
88
+ - lib/kichi.rb
89
+ - lib/kichi/version.rb
90
+ homepage: https://github.com/davidsiaw/kichi
91
+ licenses: []
92
+ metadata:
93
+ allowed_push_host: https://rubygems.org
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.6.11
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: Simple commandline key management system
114
+ test_files: []