Sha256: 1a552a3c54d915d1698e1caf996ef484da88fddbe807fc0a5c09f6e887a8bb9e

Contents?: true

Size: 1.69 KB

Versions: 4

Compression:

Stored size: 1.69 KB

Contents

require 'strscan'

module Simnos
  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)
      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 "simnos/secret_providers/#{name}"
      Simnos::SecretProviders.const_get(name.split('_').map(&:capitalize).join('')).new
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
simnos-0.1.3.beta1 lib/simnos/secret_expander.rb
simnos-0.1.2 lib/simnos/secret_expander.rb
simnos-0.1.1 lib/simnos/secret_expander.rb
simnos-0.1.1.beta2 lib/simnos/secret_expander.rb