From 2877c1975bee30ef0b83b11c652e052c0001fd55 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 10 Feb 2014 00:08:46 -0800 Subject: different secrets for each environment --- bin/leap | 5 +++ lib/leap_cli/commands/pre.rb | 3 ++ lib/leap_cli/config/macros.rb | 4 +- lib/leap_cli/config/manager.rb | 2 +- lib/leap_cli/config/object.rb | 93 +++++++++++++++++++++++------------------- lib/leap_cli/config/secrets.rb | 20 +++++---- 6 files changed, 73 insertions(+), 54 deletions(-) diff --git a/bin/leap b/bin/leap index 5dbf046..75c14c7 100755 --- a/bin/leap +++ b/bin/leap @@ -1,4 +1,9 @@ #!/usr/bin/env ruby + +if ARGV.include?('--debug') + require 'debugger' +end + begin require 'leap_cli' rescue LoadError diff --git a/lib/leap_cli/commands/pre.rb b/lib/leap_cli/commands/pre.rb index cedce7f..318282d 100644 --- a/lib/leap_cli/commands/pre.rb +++ b/lib/leap_cli/commands/pre.rb @@ -20,6 +20,9 @@ module LeapCli; module Commands desc 'Skip prompts and assume "yes"' switch :yes, :negatable => false + desc 'Enable debugging library (leap_cli development only)' + switch :debug, :negatable => false + pre do |global,command,options,args| # # set verbosity diff --git a/lib/leap_cli/config/macros.rb b/lib/leap_cli/config/macros.rb index 386bce3..ad91245 100644 --- a/lib/leap_cli/config/macros.rb +++ b/lib/leap_cli/config/macros.rb @@ -119,7 +119,7 @@ module LeapCli; module Config # +length+ is the character length of the generated password. # def secret(name, length=32) - @manager.secrets.set(name, Util::Secret.generate(length)) + @manager.secrets.set(name, Util::Secret.generate(length), @node[:environment]) end # @@ -128,7 +128,7 @@ module LeapCli; module Config # +bit_length+ is the bits in the secret, (ie length of resulting hex string will be bit_length/4) # def hex_secret(name, bit_length=128) - @manager.secrets.set(name, Util::Secret.generate_hex(bit_length)) + @manager.secrets.set(name, Util::Secret.generate_hex(bit_length), @node[:environment]) end # diff --git a/lib/leap_cli/config/manager.rb b/lib/leap_cli/config/manager.rb index 9f05713..90c4db0 100644 --- a/lib/leap_cli/config/manager.rb +++ b/lib/leap_cli/config/manager.rb @@ -100,7 +100,7 @@ module LeapCli node_list.each_node do |node| filepath = Path.named_path([:node_files_dir, node.name], @provider_dir) hierapath = Path.named_path([:hiera, node.name], @provider_dir) - Util::write_file!(hierapath, node.dump) + Util::write_file!(hierapath, node.dump_yaml) updated_files << filepath updated_hiera << hierapath end diff --git a/lib/leap_cli/config/object.rb b/lib/leap_cli/config/object.rb index 47800d5..3b34e78 100644 --- a/lib/leap_cli/config/object.rb +++ b/lib/leap_cli/config/object.rb @@ -33,24 +33,29 @@ module LeapCli @node = node || self end + # + # export YAML # # We use pure ruby yaml exporter ya2yaml instead of SYCK or PSYCH because it # allows us greater compatibility regardless of installed ruby version and # greater control over how the yaml is exported (sorted keys, in particular). # - def dump - evaluate + def dump_yaml + evaluate(@node) ya2yaml(:syck_compatible => true) end + # + # export JSON + # def dump_json - evaluate + evaluate(@node) JSON.sorted_generate(self) end - def evaluate - evaluate_everything - late_evaluate_everything + def evaluate(context) + evaluate_everything(context) + late_evaluate_everything(context) end ## @@ -204,13 +209,13 @@ module LeapCli # # walks the object tree, eval'ing all the attributes that are dynamic ruby (e.g. value starts with '= ') # - def evaluate_everything + def evaluate_everything(context) keys.each do |key| - obj = fetch_value(key) + obj = fetch_value(key, context) if is_required_value_not_set?(obj) Util::log 0, :warning, "required key \"#{key}\" is not set in node \"#{node.name}\"." elsif obj.is_a? Config::Object - obj.evaluate_everything + obj.evaluate_everything(context) end end end @@ -218,10 +223,10 @@ module LeapCli # # some keys need to be evaluated 'late', after all the other keys have been evaluated. # - def late_evaluate_everything + def late_evaluate_everything(context) if @late_eval_list @late_eval_list.each do |key, value| - self[key] = evaluate_now(key, value) + self[key] = context.evaluate_ruby(key, value) if is_required_value_not_set?(self[key]) Util::log 0, :warning, "required key \"#{key}\" is not set in node \"#{node.name}\"." end @@ -229,44 +234,24 @@ module LeapCli end values.each do |obj| if obj.is_a? Config::Object - obj.late_evaluate_everything + obj.late_evaluate_everything(context) end end end - private - # - # fetches the value for the key, evaluating the value as ruby if it begins with '=' + # evaluates the string `value` as ruby in the context of self. + # (`key` is just passed for debugging purposes) # - def fetch_value(key) - value = fetch(key, nil) - if value.is_a?(String) && value =~ /^=/ - if value =~ /^=> (.*)$/ - value = evaluate_later(key, $1) - elsif value =~ /^= (.*)$/ - value = evaluate_now(key, $1) - end - self[key] = value - end - return value - end - - def evaluate_later(key, value) - @late_eval_list ||= [] - @late_eval_list << [key, value] - '' - end - - def evaluate_now(key, value) + def evaluate_ruby(key, value) result = nil if LeapCli.log_level >= 2 - result = @node.instance_eval(value) + result = self.instance_eval(value) else begin - result = @node.instance_eval(value) + result = self.instance_eval(value) rescue SystemStackError => exc - Util::log 0, :error, "while evaluating node '#{@node.name}'" + Util::log 0, :error, "while evaluating node '#{self.name}'" Util::log 0, "offending key: #{key}", :indent => 1 Util::log 0, "offending string: #{value}", :indent => 1 Util::log 0, "STACK OVERFLOW, BAILING OUT. There must be an eval loop of death (variables with circular dependencies).", :indent => 1 @@ -274,9 +259,9 @@ module LeapCli rescue FileMissing => exc Util::bail! do if exc.options[:missing] - Util::log :missing, exc.options[:missing].gsub('$node', @node.name) + Util::log :missing, exc.options[:missing].gsub('$node', self.name) else - Util::log :error, "while evaluating node '#{@node.name}'" + Util::log :error, "while evaluating node '#{self.name}'" Util::log "offending key: #{key}", :indent => 1 Util::log "offending string: #{value}", :indent => 1 Util::log "error message: no file '#{exc}'", :indent => 1 @@ -284,13 +269,13 @@ module LeapCli end rescue AssertionFailed => exc Util.bail! do - Util::log :failed, "assertion while evaluating node '#{@node.name}'" + Util::log :failed, "assertion while evaluating node '#{self.name}'" Util::log 'assertion: %s' % exc.assertion, :indent => 1 Util::log "offending key: #{key}", :indent => 1 end rescue SyntaxError, StandardError => exc Util::bail! do - Util::log :error, "while evaluating node '#{@node.name}'" + Util::log :error, "while evaluating node '#{self.name}'" Util::log "offending key: #{key}", :indent => 1 Util::log "offending string: #{value}", :indent => 1 Util::log "error message: #{exc.inspect}", :indent => 1 @@ -300,6 +285,30 @@ module LeapCli return result end + private + + # + # fetches the value for the key, evaluating the value as ruby if it begins with '=' + # + def fetch_value(key, context=@node) + value = fetch(key, nil) + if value.is_a?(String) && value =~ /^=/ + if value =~ /^=> (.*)$/ + value = evaluate_later(key, $1) + elsif value =~ /^= (.*)$/ + value = context.evaluate_ruby(key, $1) + end + self[key] = value + end + return value + end + + def evaluate_later(key, value) + @late_eval_list ||= [] + @late_eval_list << [key, value] + '' + end + # # when merging, we raise an error if this method returns true for the two values. # diff --git a/lib/leap_cli/config/secrets.rb b/lib/leap_cli/config/secrets.rb index 491870d..45a57e1 100644 --- a/lib/leap_cli/config/secrets.rb +++ b/lib/leap_cli/config/secrets.rb @@ -1,8 +1,6 @@ # -# # A class for the secrets.json file # -# module LeapCli; module Config @@ -14,10 +12,13 @@ module LeapCli; module Config @discovered_keys = {} end - def set(key, value) + def set(key, value, environment=nil) + environment ||= 'default' key = key.to_s - @discovered_keys[key] = true - self[key] ||= value + @discovered_keys[environment] ||= {} + @discovered_keys[environment][key] = true + self[environment] ||= {} + self[environment][key] ||= value end # @@ -27,12 +28,13 @@ module LeapCli; module Config # this should only be triggered when all nodes have been processed, otherwise # secrets that are actually in use will get mistakenly removed. # - # def dump_json(only_discovered_keys=false) if only_discovered_keys - self.each_key do |key| - unless @discovered_keys[key] - self.delete(key) + self.each_key do |environment| + self[environment].each_key do |key| + unless @discovered_keys[environment][key] + self[environment].delete(key) + end end end end -- cgit v1.2.3