aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2012-11-04 11:30:16 -0800
committerelijah <elijah@riseup.net>2012-11-04 11:30:16 -0800
commit08b03669c262fd7ea67c7e2e5e5448a98db4ceef (patch)
tree6d08a0ae0fe6e7f8baf49fa58c52e7c0a23911cd
parentb561a3eadd43218a59650b6255f8d12266b38884 (diff)
downloadleap_cli-08b03669c262fd7ea67c7e2e5e5448a98db4ceef.tar.gz
leap_cli-08b03669c262fd7ea67c7e2e5e5448a98db4ceef.tar.bz2
added automatic secret generation in secrets.json
-rw-r--r--lib/leap_cli.rb2
-rw-r--r--lib/leap_cli/commands/compile.rb8
-rw-r--r--lib/leap_cli/config/manager.rb18
-rw-r--r--lib/leap_cli/config/object.rb13
-rw-r--r--lib/leap_cli/path.rb1
-rw-r--r--lib/leap_cli/util/secret.rb37
6 files changed, 75 insertions, 4 deletions
diff --git a/lib/leap_cli.rb b/lib/leap_cli.rb
index 4dccec2..728e501 100644
--- a/lib/leap_cli.rb
+++ b/lib/leap_cli.rb
@@ -8,6 +8,8 @@ require 'core_ext/nil'
require 'leap_cli/init'
require 'leap_cli/path'
require 'leap_cli/util'
+require 'leap_cli/util/secret'
+
require 'leap_cli/log'
require 'leap_cli/ssh_key'
require 'leap_cli/config/object'
diff --git a/lib/leap_cli/commands/compile.rb b/lib/leap_cli/commands/compile.rb
index c5bb93e..9882e6a 100644
--- a/lib/leap_cli/commands/compile.rb
+++ b/lib/leap_cli/commands/compile.rb
@@ -5,8 +5,12 @@ module LeapCli
desc 'Compile json files to hiera configs'
command :compile do |c|
c.action do |global_options,options,args|
- update_compiled_ssh_configs # this must come first, hiera configs import these files.
- manager.export Path.named_path(:hiera_dir) # generate a hiera .yaml config for each node
+ # these must come first
+ update_compiled_ssh_configs
+
+ # export generated files
+ manager.export_nodes
+ manager.export_secrets
end
end
diff --git a/lib/leap_cli/config/manager.rb b/lib/leap_cli/config/manager.rb
index 2eda7a4..8a4a617 100644
--- a/lib/leap_cli/config/manager.rb
+++ b/lib/leap_cli/config/manager.rb
@@ -8,7 +8,7 @@ module LeapCli
#
class Manager
- attr_reader :services, :tags, :nodes, :provider, :common
+ attr_reader :services, :tags, :nodes, :provider, :common, :secrets
##
## IMPORT EXPORT
@@ -18,11 +18,13 @@ module LeapCli
# load .json configuration files
#
def load(provider_dir=Path.provider)
+ @provider_dir = provider_dir
@services = load_all_json(Path.named_path([:service_config, '*'], provider_dir))
@tags = load_all_json(Path.named_path([:tag_config, '*'], provider_dir))
@nodes = load_all_json(Path.named_path([:node_config, '*'], provider_dir))
@common = load_json(Path.named_path(:common_config, provider_dir))
@provider = load_json(Path.named_path(:provider_config, provider_dir))
+ @secrets = load_json(Path.named_path(:secrets_config, provider_dir))
Util::assert!(@provider, "Failed to load provider.json")
Util::assert!(@common, "Failed to load common.json")
@@ -35,7 +37,8 @@ module LeapCli
#
# save compiled hiera .yaml files
#
- def export(dir=Path.named_path(:hiera_dir))
+ def export_nodes(destination_directory = nil)
+ dir = destination_directory || Path.named_path(:hiera_dir, @provider_dir)
existing_files = Dir.glob(dir + '/*.yaml')
updated_files = []
@nodes.each do |name, node|
@@ -48,6 +51,13 @@ module LeapCli
end
end
+ def export_secrets(destination_file = nil)
+ if @secrets.any?
+ file_path = destination_file || Path.named_path(:secrets_config, @provider_dir)
+ Util.write_file!(file_path, @secrets.dump_json + "\n")
+ end
+ end
+
##
## FILTERING
##
@@ -119,6 +129,10 @@ module LeapCli
end
def load_json(filename)
+ if !File.exists?(filename)
+ return Config::Object.new(self)
+ end
+
#
# read file, strip out comments
# (File.read(filename) would be faster, but we like ability to have comments)
diff --git a/lib/leap_cli/config/object.rb b/lib/leap_cli/config/object.rb
index 8b14c49..ad32f54 100644
--- a/lib/leap_cli/config/object.rb
+++ b/lib/leap_cli/config/object.rb
@@ -39,6 +39,10 @@ module LeapCli
self.ya2yaml(:syck_compatible => true)
end
+ def dump_json
+ generate_json(self)
+ end
+
##
## FETCHING VALUES
##
@@ -169,6 +173,15 @@ module LeapCli
end
end
+ #
+ # inserts a named secret, generating it if needed.
+ #
+ # manager.export_secrets should be called later to capture any newly generated secrets.
+ #
+ def secret(name, length=32)
+ @manager.secrets[name.to_s] ||= Util::Secret.generate(length)
+ end
+
private
#
diff --git a/lib/leap_cli/path.rb b/lib/leap_cli/path.rb
index aa20e17..88288d0 100644
--- a/lib/leap_cli/path.rb
+++ b/lib/leap_cli/path.rb
@@ -13,6 +13,7 @@ module LeapCli; module Path
# input config files
:common_config => 'common.json',
:provider_config => 'provider.json',
+ :secrets_config => 'secrets.json',
:node_config => 'nodes/#{arg}.json',
:service_config => 'services/#{arg}.json',
:tag_config => 'tags/#{arg}.json',
diff --git a/lib/leap_cli/util/secret.rb b/lib/leap_cli/util/secret.rb
new file mode 100644
index 0000000..4833caa
--- /dev/null
+++ b/lib/leap_cli/util/secret.rb
@@ -0,0 +1,37 @@
+#
+# A simple alphanumeric secret generator, with no ambiguous characters.
+#
+# It also includes symbols that are treated as word characters by most
+# terminals (so you can still double click to select the entire secret).
+#
+# Uses OpenSSL random number generator instead of Ruby's rand function
+#
+
+require 'openssl'
+
+module LeapCli; module Util
+
+ class Secret
+
+ CHARS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + "_-&@%~=+".split(//u) - "io01lO".split(//u)
+
+ def self.generate(length = 10)
+ seed
+ OpenSSL::Random.random_bytes(length).bytes.to_a.collect { |byte|
+ CHARS[ byte % CHARS.length ]
+ }.join
+ end
+
+ def self.seed
+ @pid ||= 0
+ pid = $$
+ if @pid != pid
+ now = Time.now
+ OpenSSL::Random.seed( [now.to_i, now.nsec, @pid, pid].join )
+ @pid = pid
+ end
+ end
+
+ end
+
+end; end