diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/leap_cli/commands/pre.rb | 3 | ||||
| -rw-r--r-- | lib/leap_cli/config/macros.rb | 4 | ||||
| -rw-r--r-- | lib/leap_cli/config/manager.rb | 2 | ||||
| -rw-r--r-- | lib/leap_cli/config/object.rb | 93 | ||||
| -rw-r--r-- | lib/leap_cli/config/secrets.rb | 20 | 
5 files changed, 68 insertions, 54 deletions
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 @@ -34,23 +34,28 @@ module LeapCli        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  | 
