Class: ConfigurationService::Provider::Vault

Inherits:
Object
  • Object
show all
Defined in:
lib/configuration_service/provider/vault.rb,
lib/configuration_service/provider/vault/version.rb,
lib/configuration_service/provider/vault/path_helper.rb

Overview

Vault configuration service provider

Instances of this class are intended to be composed into a ConfigurationService::Base, usually by a ConfigurationService::Factory.

Defined Under Namespace

Modules: PathHelper

Constant Summary collapse

VERSION =
"2.0.15"

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Vault

Returns a new instance of Vault.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):



28
29
30
31
32
33
34
35
36
# File 'lib/configuration_service/provider/vault.rb', line 28

def initialize(options = {})
  address = options[:address] or raise ArgumentError, "missing required argument: address"
  @vault = ::Vault::Client.new(address: address)
  @vault.ssl_ciphers = SSL_CIPHERS
  if options.include?(:ca_cert)
    @vault.ssl_ca_cert = options[:ca_cert]
  end
  @mutex = Mutex.new
end

Instance Method Details

#publish_configuration(configuration, token) ⇒ ConfigurationService::Configuration

TODO:

make revision history queryable (blocked by github.com/hashicorp/vault/issues/111)

Publish configuration

The configuration data and metadata is written to a Vault path composed from the configuration’s identifier and metadata revision by PathHelper. That path is then written to another path, composed from +identifier and the string “latest”.

This allows the current configuration to always be retrieved from a predictable path in Vault, but preserves revision history of configuration.

Parameters:

  • configuration (ConfigurationService::Configuration)

    the configuration to publish

  • token (String)

    Vault token with write permission on the composed secret path

Returns:

  • (ConfigurationService::Configuration)

    the published configuration

Raises:

  • (ConfigurationService::AuthorizationError)

    if the request was not allowed

  • (ConfigurationService::Error)

    if the request was allowed but failed



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/configuration_service/provider/vault.rb', line 94

def publish_configuration(configuration, token)
  @mutex.synchronize do
    authenticate(token)

    identifier, data,  = configuration.identifier, configuration.data, configuration.
    revision = ["revision"] or raise "can't publish configuration without revision in metadata"

    adapt_exceptions do
      path = build_path(identifier, revision)
      @vault.logical.write(path, data: JSON.generate(data), metadata: JSON.generate(), format: "json")
      set_latest_revision(identifier, ["revision"])
      ConfigurationService::Configuration.new(identifier, data, )
    end
  end
end

#request_configuration(identifier, token) ⇒ ConfigurationService::Configuration?

Request configuration

The Vault secret path is composed by from the identifier and the string “latest” using PathHelper.

Parameters:

  • identifier (String)

    the unique identity of the configuration

  • token (String)

    Vault token with read permission on the composed secret path

Returns:

  • (ConfigurationService::Configuration)

    the configuration if found

  • (nil)

    if the configuration for +identifier was not found

Raises:

  • (ConfigurationService::AuthorizationError)

    if the request was not allowed

  • (ConfigurationService::Error)

    if the request was allowed but failed

See Also:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/configuration_service/provider/vault.rb', line 56

def request_configuration(identifier, token)
  @mutex.synchronize do
    authenticate(token)

    adapt_exceptions do
      if revision = get_latest_revision(identifier)
        path = build_path(identifier, revision)
        if response = @vault.logical.read(path)
          data,  = JSON.parse(response.data[:data]), JSON.parse(response.data[:metadata])
          ConfigurationService::Configuration.new(identifier, data, )
        end
      end
    end
  end
end