Class: Dev::Vault

Inherits:
Object
  • Object
show all
Extended by:
Helpers
Defined in:
lib/dev/vault.rb,
lib/dev/vault/build.rb,
lib/dev/vault/helpers.rb,
lib/dev/vault/version.rb

Overview

Helpers to fetch and run a development-instance of vault

Defined Under Namespace

Modules: Build, Helpers

Constant Summary collapse

DEFAULT_PORT =
8200
RANDOM_PORT =
'RANDOM_PORT'.freeze
RELEASE =
'1'.freeze
VERSION =
'0.5.2'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

architecture, bin, bindir, platform

Constructor Details

#initialize(**options) ⇒ Vault

Returns a new instance of Vault.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dev/vault.rb', line 32

def initialize(**options)
  @dev = options.fetch(:dev, true)
  @token = dev ? SecureRandom.uuid : options[:token]

  @port = case options[:port]
          when Fixnum then options[:port]
          when RANDOM_PORT then 10_000 + rand(10_000)
          else DEFAULT_PORT
          end

  @command = [self.class.bin, 'server']
  @command.push(*['-dev', "-dev-root-token-id=#{token}", "-dev-listen-address=127.0.0.1:#{port}"]) if dev?
  @output = options.fetch(:output, $stdout)

  ## Non-development mode server
  unless dev?
    @config = Tempfile.new('dev-vault')
    @command << "-config=#{config.path}"
  end

  @client = ::Vault::Client.new(:address => "http://localhost:#{port}",
                                :token => token)
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



26
27
28
# File 'lib/dev/vault.rb', line 26

def client
  @client
end

#commandObject (readonly)

Returns the value of attribute command.



19
20
21
# File 'lib/dev/vault.rb', line 19

def command
  @command
end

#configObject (readonly)

Returns the value of attribute config.



20
21
22
# File 'lib/dev/vault.rb', line 20

def config
  @config
end

#devObject (readonly) Also known as: dev?

Returns the value of attribute dev.



23
24
25
# File 'lib/dev/vault.rb', line 23

def dev
  @dev
end

#keysObject (readonly)

Returns the value of attribute keys.



29
30
31
# File 'lib/dev/vault.rb', line 29

def keys
  @keys
end

#outputObject (readonly)

Returns the value of attribute output.



21
22
23
# File 'lib/dev/vault.rb', line 21

def output
  @output
end

#portObject (readonly)

Returns the value of attribute port.



27
28
29
# File 'lib/dev/vault.rb', line 27

def port
  @port
end

#tokenObject (readonly)

Returns the value of attribute token.



30
31
32
# File 'lib/dev/vault.rb', line 30

def token
  @token
end

Instance Method Details

#blockObject



158
159
160
# File 'lib/dev/vault.rb', line 158

def block
  @thread.join unless @thread.nil?
end

#configureObject

Write configuration to tempfile



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/dev/vault.rb', line 67

def configure
  raise 'Cannot configure a Vault server in development mode' if dev?

  config.write(
    JSON.pretty_generate(
      :backend => {
        :inmem => {}
      },
      :listener => {
        :tcp => {
          :address => "127.0.0.1:#{port}",
          :tls_disable => 'true'
        }
      }
    )
  )

  config.rewind
end

#init(**options) ⇒ Object

Helper to initialize a non-development Vault server and store the new token



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/dev/vault.rb', line 90

def init(**options)
  raise 'Cannot initialize a Vault server in development mode' if dev?

  options[:shares] ||= 1
  options[:threshold] ||= 1

  result = client.sys.init(options)

  ## Capture the new keys and token
  @keys = result.keys
  @token = result.root_token
end

#log(*message) ⇒ Object

Logging helper



57
58
59
60
61
62
# File 'lib/dev/vault.rb', line 57

def log(*message)
  return unless output.is_a?(IO)

  output.write(message.join(' ') + "\n")
  output.flush
end

#runObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/dev/vault.rb', line 103

def run
  configure unless dev?
  log "Running #{command.join(' ')}"

  ## Fork a child process for Vault from a thread
  @stopped = false
  @thread = Thread.new do
    IO.popen(command + [:err => [:child, :out]], 'r+') do |io|
      Thread.current[:process] = io.pid

      ## Stream output
      loop do
        break if io.eof?
        chunk = io.readpartial(1024)

        next unless output.is_a?(IO)
        output.write(chunk)
        output.flush
      end
    end
  end

  self
end

#stopObject



162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/dev/vault.rb', line 162

def stop
  unless @thread.nil?
    unless @thread[:process].nil?
      log "Stop #{command.join(' ')} (#{@thread[:process]})"
      Process.kill('TERM', @thread[:process])
    end

    @thread.join
  end

  config.unlink unless dev?
  @thread = nil
  @stopped = true
end

#waitObject

Wait for the service to become ready



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/dev/vault.rb', line 131

def wait
  loop do
    break if @stopped || @thread.nil? || !@thread.alive?

    begin
      client.sys.init_status
    rescue ::Vault::HTTPConnectionError
      log 'Waiting for Vault HTTP API to be ready'
      sleep 1

      next
    end

    if dev? && !client.sys.init_status.initialized?
      log 'Waiting for Vault development server to initialize'
      sleep 1

      next
    end

    log 'Vault is ready!'
    break
  end

  self
end