require 'thor' module Muchkeys class CLI < Thor include Thor::Actions map %w[--version -v] => :__version class_option :consul_url, type: :string, default: 'http://localhost:8500' desc "encrypt FILE", "encrypt keys from a file to put in consul" method_option :public_key, type: :string, required: true def encrypt(file) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.encrypt(file, options[:public_key]) end desc "decrypt KEY", "decrypt keys from consul" method_option :public_key, type: :string, required: true method_option :private_key, type: :string, required: true def decrypt(consul_key) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.decrypt(consul_key, options[:public_key], options[:private_key]) end desc "check", "ensure that all keys in .env in CWD are present in consul" def check(app_name) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.check(app_name) end desc "list", "list all keys in Application" def list(app_name) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.list(app_name) end desc "fetch KEY", "fetch plaintext key from consul" def fetch(consul_key) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.fetch(consul_key) end desc "store DATA KEY", "store data a particular key" method_option :public_key, type: :string method_option :private_key, type: :string def store(data, consul_key) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.store(consul_key, data, public_key: options[:public_key], private_key: options[:private_key]) end desc "wipeout", "clear Consul" method_option :app_name, type: :string def wipeout Muchkeys.configure { |c| c.consul_url = options[:consul_url] } unless yes?("Really clear consul instance at #{Muchkeys.config.consul_url}?", Thor::Shell::Color::RED) say "Nothing done!" else say MuchkeysExecutor.wipeout(app_name: options[:app_name]) end end desc "delete", "remove key" def delete(key) Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say MuchkeysExecutor.delete(key) end desc "--version", "Print the version" def __version Muchkeys.configure { |c| c.consul_url = options[:consul_url] } say Muchkeys::VERSION end module MuchkeysExecutor extend self def encrypt(file, public_key) string_to_encrypt = File.read(file) Muchkeys::ApplicationClient.new.secret_adapter.encrypt_string(string_to_encrypt.chomp, public_key) end def decrypt(consul_key, public_key, private_key) Muchkeys::ApplicationClient.new.fetch_key(consul_key, public_key: public_key, private_key: private_key) end def store(consul_key, data, public_key: nil, private_key: nil) Muchkeys.configure { |c| c.public_key = public_key; c.private_key = private_key } app = Muchkeys::ApplicationClient.new(Muchkeys.config) if data == "-" data = $stdin.read end app.allow_unsafe_operation do if public_key && private_key app.set_key(consul_key, data, type: :secret) "Secret '#{data}' stored in #{consul_key}" else app.set_key(consul_key, data) "'#{data}' stored in #{consul_key}" end end end def list(app_name) Muchkeys.configure { |c| c.application_name = app_name } keys = Muchkeys::ApplicationClient.new(Muchkeys.config).known_keys keys.join("\n") end def check(app_name) Muchkeys.configure { |c| c.application_name = app_name } Muchkeys::ApplicationClient.new(Muchkeys.config).verify_keys(*Muchkeys.env_keys) "All keys present and accounted for." end def wipeout(app_name: nil) Muchkeys.configure { |c| c.application_name = app_name } app = Muchkeys::ApplicationClient.new app.allow_unsafe_operation do app.each_path do |path| app.delete_key(path) end end "Everything deleted!" end def delete(consul_key) app = Muchkeys::ApplicationClient.new app.allow_unsafe_operation do app.delete_key(consul_key) end "Key #{consul_key} deleted" end def fetch(consul_key) Muchkeys::ApplicationClient.new.fetch_key(consul_key) end end end end