From 2877c1975bee30ef0b83b11c652e052c0001fd55 Mon Sep 17 00:00:00 2001
From: elijah <elijah@riseup.net>
Date: Mon, 10 Feb 2014 00:08:46 -0800
Subject: different secrets for each environment

---
 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 +++++----
 4 files changed, 65 insertions(+), 54 deletions(-)

(limited to 'lib/leap_cli/config')

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]
-        '<evaluate later>'
-      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]
+        '<evaluate later>'
+      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