Sha256: 628aab68297114b6f83bb12f5e52d81d143e22485bf94826d2c1645f5e75e136

Contents?: true

Size: 1.72 KB

Versions: 5

Compression:

Stored size: 1.72 KB

Contents

require 'strscan'

module Kashi
  class ExpansionError < StandardError
  end

  class SecretExpander
    Literal = Struct.new(:literal)
    Variable = Struct.new(:name)

    def initialize(provider_name)
      @provider = load_provider(provider_name)
      @asked_variables = {}
    end

    def expand(str)
      return str unless str
      tokens = parse(str)
      variables = Set.new
      tokens.each do |token|
        if token.is_a?(Variable)
          unless @asked_variables.include?(token.name)
            variables << token.name
          end
        end
      end

      unless variables.empty?
        @provider.ask(variables).each do |k, v|
          @asked_variables[k] = v
        end
      end

      tokens.map do |token|
        case token
        when Literal
          token.literal
        when Variable
          @asked_variables.fetch(token.name)
        else
          raise ExpansionError.new("Unknown token type: #{token.class}")
        end
      end.join
    end

    private

    def parse(value)
      s = StringScanner.new(value)
      tokens = []
      pos = 0
      while s.scan_until(/\$\{(.*?)\}/)
        pre = s.string.byteslice(pos...(s.pos - s.matched.size))
        var = s[1]
        unless pre.empty?
          tokens << Literal.new(pre)
        end
        if var.empty?
          raise ExpansionError.new('Empty interpolation is not allowed')
        else
          tokens << Variable.new(var)
        end
        pos = s.pos
      end
      unless s.rest.empty?
        tokens << Literal.new(s.rest)
      end
      tokens
    end

    def load_provider(name)
      require "kashi/secret_providers/#{name}"
      Kashi::SecretProviders.const_get(name.split('_').map(&:capitalize).join('')).new
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
kashi-0.1.4 lib/kashi/secret_expander.rb
kashi-0.1.3 lib/kashi/secret_expander.rb
kashi-0.1.2 lib/kashi/secret_expander.rb
kashi-0.1.1 lib/kashi/secret_expander.rb
kashi-0.1.0 lib/kashi/secret_expander.rb