From 08b03669c262fd7ea67c7e2e5e5448a98db4ceef Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 4 Nov 2012 11:30:16 -0800 Subject: added automatic secret generation in secrets.json --- lib/leap_cli/commands/compile.rb | 8 ++++++-- lib/leap_cli/config/manager.rb | 18 ++++++++++++++++-- lib/leap_cli/config/object.rb | 13 +++++++++++++ lib/leap_cli/path.rb | 1 + lib/leap_cli/util/secret.rb | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 lib/leap_cli/util/secret.rb (limited to 'lib/leap_cli') 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 -- cgit v1.2.3