ruby_vault 0.1.0.pre.3 → 0.1.0.pre.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19e8aadca9a6285c7decb702603d6a0ef61aa6b644a46c236ac96ce3ad9a6310
4
- data.tar.gz: 8bff21c678170fb4187d171c859756cec283e3d546d0b1ae3a02248f76d6393a
3
+ metadata.gz: 4acec404ddce5a052368e45f94bfc2680d6abe076f791a595b5a4a0c912daa75
4
+ data.tar.gz: 597d76b4adab3af5e998f16d83e43f0a9d103f9d85a12b00de6f63a1b8c82487
5
5
  SHA512:
6
- metadata.gz: 81c23a4e58bb4954f769c3dda63196fa7af0b06736cbf79f566cd1b88555eb31a55f2635a3d8961067d265bc8245350bb8e4f513d5a3479d6d4c3aa8439fd74b
7
- data.tar.gz: 209e56bdf568f52332287e19c9190694995482a35c1fa5c79186f81e3fe920edad50cbd2bbdf2bd4499f7c9c1417b9e805f1e99495e4307665daa35c8203be2e
6
+ metadata.gz: b4e537621c4d2a78bf36117e68c729529cb0bb156a8761acc9ee417a7978ed01e1895772badc3c6b8b76afbcf5aac57b7837763480e002acb4f176ce6ee37f19
7
+ data.tar.gz: 28a4fe8456d6e1ac25e5e9bc3bb00971739e17a06a1caf167f521a233fc171e7c8a303186a9ab56c88dc494f8e160bdd4577495f24eaf472d962471d774846e5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_vault (0.1.0.pre.3)
4
+ ruby_vault (0.1.0.pre.4)
5
5
  immutable-struct (~> 2.4)
6
6
  lino (~> 3.0)
7
7
 
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lino'
4
+
5
+ require_relative '../errors'
6
+
7
+ module RubyVault
8
+ module Commands
9
+ class Base
10
+ # rubocop:disable Metrics/AbcSize
11
+
12
+ # Constructs an instance of the command.
13
+ #
14
+ def initialize(**opts)
15
+ @binary = opts[:binary] || RubyVault.configuration.binary
16
+ @logger = opts[:logger] || RubyVault.configuration.logger
17
+ @options = opts[:options] || RubyVault.configuration.options
18
+ @stdin = opts[:stdin] || RubyVault.configuration.stdin
19
+ @stdout = opts[:stdout] || RubyVault.configuration.stdout
20
+ @stderr = opts[:stderr] || RubyVault.configuration.stderr
21
+ end
22
+
23
+ # rubocop:enable Metrics/AbcSize
24
+
25
+ # Executes the command instance.
26
+ #
27
+ # @param [Hash<String, Object>] parameters The parameters used to
28
+ # invoke the command. See subclass documentation for details of
29
+ # supported options.
30
+ # @param [Hash<String, Object>] invocation_options Additional options
31
+ # controlling the invocation of the command.
32
+ # @option invocation_options [Hash<String, String>] :environment A map
33
+ # of environment variables to expose at command invocation time.
34
+ def execute(parameters = {}, invocation_options = {})
35
+ do_before(parameters)
36
+ build_and_execute_command(parameters, invocation_options)
37
+ do_after(parameters)
38
+ rescue Open4::SpawnError
39
+ message = "Failed while running '#{command_name}'."
40
+ logger.error(message)
41
+ raise Errors::ExecutionError, message
42
+ end
43
+
44
+ protected
45
+
46
+ attr_reader :binary, :logger, :stdin, :stdout, :stderr
47
+
48
+ def build_and_execute_command(parameters, invocation_options)
49
+ command = build_command(parameters, invocation_options)
50
+
51
+ logger.debug("Running '#{command}'.")
52
+ command.execute(
53
+ stdin: stdin,
54
+ stdout: stdout,
55
+ stderr: stderr
56
+ )
57
+ end
58
+
59
+ def command_name
60
+ self.class.to_s.split('::')[-1].downcase
61
+ end
62
+
63
+ def do_before(_parameters); end
64
+
65
+ def do_after(_parameters); end
66
+
67
+ private
68
+
69
+ def build_command(parameters, invocation_options)
70
+ parameters = resolve_parameters(parameters)
71
+ environment = invocation_options[:environment] || {}
72
+
73
+ Lino::CommandLineBuilder
74
+ .for_command(@binary)
75
+ .with_environment_variables(environment)
76
+ .with_options_after_subcommands
77
+ .with_option_separator('=')
78
+ .with_appliables(@options.resolve(options, parameters))
79
+ .with_subcommands(subcommands)
80
+ .with_arguments(arguments(parameters).compact.flatten).build
81
+ end
82
+
83
+ def resolve_parameters(parameters)
84
+ parameter_defaults(parameters)
85
+ .merge(parameters)
86
+ .merge(parameter_overrides(parameters))
87
+ end
88
+
89
+ def parameter_defaults(_parameters)
90
+ {}
91
+ end
92
+
93
+ def parameter_overrides(_parameters)
94
+ {}
95
+ end
96
+
97
+ def subcommands
98
+ []
99
+ end
100
+
101
+ def options
102
+ []
103
+ end
104
+
105
+ def arguments(_parameters)
106
+ []
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module RubyVault
6
+ module Commands
7
+ class Login < Base
8
+ # @!visibility private
9
+ def subcommands
10
+ %w[login]
11
+ end
12
+
13
+ # @!visibility private
14
+ def options
15
+ %w[
16
+ -method
17
+ ] + super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'commands/login'
4
+
5
+ module RubyVault
6
+ module Commands
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyVault
4
+ module Errors
5
+ class ExecutionError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors/execution_error'
4
+
5
+ module RubyVault
6
+ module Errors
7
+ end
8
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'immutable-struct'
4
+
5
+ require_relative 'name'
6
+ require_relative 'types'
7
+ require_relative 'values'
8
+
9
+ module RubyVault
10
+ module Options
11
+ # rubocop:disable Metrics/ClassLength
12
+ class Definition < ImmutableStruct.new(
13
+ :name,
14
+ :option_type,
15
+ :value_type,
16
+ :override_keys,
17
+ :extra_keys,
18
+ :separator,
19
+ :placement,
20
+ :repeatable?
21
+ )
22
+ # rubocop:disable Metrics/MethodLength
23
+ def initialize(opts)
24
+ raise 'Missing name.' unless opts[:name]
25
+
26
+ super(
27
+ name: Name.new(opts[:name]),
28
+ option_type: Types.resolve(opts[:option_type]) || Types::Standard,
29
+ value_type: Values.resolve(opts[:value_type]) || Values::String,
30
+ repeatable: opts[:repeatable] || false,
31
+ separator: opts[:separator],
32
+ placement: opts[:placement],
33
+ extra_keys:
34
+ { singular: [], plural: [] }
35
+ .merge(opts[:extra_keys] || {}),
36
+ override_keys:
37
+ { singular: nil, plural: nil }
38
+ .merge(opts[:override_keys] || {})
39
+ )
40
+ end
41
+ # rubocop:enable Metrics/MethodLength
42
+
43
+ def matches?(name)
44
+ @name == Name.new(name)
45
+ end
46
+
47
+ def build(parameters)
48
+ build_singular_options(parameters) + build_plural_options(parameters)
49
+ end
50
+
51
+ private
52
+
53
+ def resolved_singular_key
54
+ if override_keys[:singular] == false
55
+ nil
56
+ else
57
+ override_keys[:singular] || name.as_singular_key
58
+ end
59
+ end
60
+
61
+ def all_singular_keys
62
+ ([resolved_singular_key] + extra_keys[:singular]).compact
63
+ end
64
+
65
+ def resolved_plural_key
66
+ if override_keys[:plural] == false
67
+ nil
68
+ else
69
+ override_keys[:plural] || name.as_plural_key
70
+ end
71
+ end
72
+
73
+ def all_plural_keys
74
+ ([resolved_plural_key] + extra_keys[:plural]).compact
75
+ end
76
+
77
+ def too_many_values?(values)
78
+ !repeatable? && values.length > 1
79
+ end
80
+
81
+ def values(parameters, keys)
82
+ keys.map { |k| parameters[k] }.compact
83
+ end
84
+
85
+ def needs_plural?(value)
86
+ repeatable? && !value.nil?
87
+ end
88
+
89
+ def only_singular?(value)
90
+ !needs_plural?(value)
91
+ end
92
+
93
+ def key_valued?(value)
94
+ value.respond_to?(:keys)
95
+ end
96
+
97
+ def multi_valued?(value)
98
+ value.respond_to?(:each)
99
+ end
100
+
101
+ def build_option(value)
102
+ option_type.new(name, value, separator: separator, placement: placement)
103
+ end
104
+
105
+ def build_value(value)
106
+ value_type.new(value)
107
+ end
108
+
109
+ def build_key_value(key, value)
110
+ Values::KeyValue.new(key, build_value(value))
111
+ end
112
+
113
+ def build_singular(value)
114
+ build_single_option(value)
115
+ end
116
+
117
+ def build_singulars(values)
118
+ values.map { |p| build_singular(p) }.flatten
119
+ end
120
+
121
+ def build_singular_options(parameters)
122
+ keys = all_singular_keys
123
+ values = values(parameters, keys)
124
+
125
+ if too_many_values?(values)
126
+ raise "Multiple values provided for '#{name}' " \
127
+ "(with keys #{keys}) and option not repeatable."
128
+ end
129
+
130
+ build_singulars(values)
131
+ end
132
+
133
+ def build_plural(value)
134
+ if only_singular?(value)
135
+ build_no_options
136
+ elsif key_valued?(value)
137
+ build_key_value_options(value)
138
+ elsif multi_valued?(value)
139
+ build_multiple_options(value)
140
+ else
141
+ build_single_option(value)
142
+ end
143
+ end
144
+
145
+ def build_plurals(values)
146
+ values.map { |p| build_plural(p) }.flatten
147
+ end
148
+
149
+ def build_plural_options(parameters)
150
+ keys = all_plural_keys
151
+ values = values(parameters, keys)
152
+
153
+ build_plurals(values)
154
+ end
155
+
156
+ def build_key_value_options(value)
157
+ value.map { |k, v| build_option(build_key_value(k, v)) }
158
+ end
159
+
160
+ def build_multiple_options(value)
161
+ value.map { |v| build_option(build_value(v)) }
162
+ end
163
+
164
+ def build_single_option(value)
165
+ [build_option(build_value(value))]
166
+ end
167
+
168
+ def build_no_options
169
+ []
170
+ end
171
+ end
172
+ # rubocop:enable Metrics/ClassLength
173
+ end
174
+ end
@@ -2,6 +2,13 @@
2
2
 
3
3
  module RubyVault
4
4
  module Options
5
- DEFINITIONS = [].freeze
5
+ DEFINITIONS = [
6
+ # string options
7
+ %w[
8
+ -method
9
+ ].map do |o|
10
+ definition(name: o, option_type: :standard, value_type: :string)
11
+ end
12
+ ].flatten.freeze
6
13
  end
7
14
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyVault
4
+ module Options
5
+ module Types
6
+ class Flag < ImmutableStruct.new(
7
+ :name,
8
+ :value
9
+ )
10
+ def initialize(name, value, **_opts)
11
+ super(name: name, value: value)
12
+ end
13
+
14
+ def apply(builder)
15
+ value.resolve ? builder.with_flag(name) : builder
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyVault
4
+ module Options
5
+ module Types
6
+ class Standard < ImmutableStruct.new(
7
+ :name,
8
+ :value,
9
+ :separator,
10
+ :placement
11
+ )
12
+ def initialize(name, value, **opts)
13
+ super(
14
+ name: name, value: value,
15
+ separator: opts[:separator],
16
+ placement: opts[:placement]
17
+ )
18
+ end
19
+
20
+ def apply(builder)
21
+ builder.with_option(
22
+ name,
23
+ value.render,
24
+ separator: separator,
25
+ placement: placement
26
+ )
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'types/standard'
4
+ require_relative 'types/flag'
5
+
6
+ module RubyVault
7
+ module Options
8
+ module Types
9
+ def self.standard(name, value, **opts)
10
+ Standard.new(name, value, **opts)
11
+ end
12
+
13
+ def self.flag(name, value)
14
+ Flag.new(name, value)
15
+ end
16
+
17
+ def self.resolve(type)
18
+ case type
19
+ when :standard then Types::Standard
20
+ when :flag then Types::Flag
21
+ else type
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'immutable-struct'
4
+
5
+ module RubyVault
6
+ module Options
7
+ module Values
8
+ class Base < ImmutableStruct.new(:value)
9
+ def initialize(value)
10
+ super(value: value)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module RubyVault
6
+ module Options
7
+ module Values
8
+ class Boolean < Base
9
+ def resolve
10
+ return nil if @value.nil?
11
+ return @value if a_boolean?(@value)
12
+ return true if true_as_string?(@value)
13
+
14
+ false
15
+ end
16
+
17
+ def render
18
+ resolve.nil? ? nil : resolve.to_s
19
+ end
20
+
21
+ private
22
+
23
+ def a_boolean?(value)
24
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
25
+ end
26
+
27
+ def true_as_string?(value)
28
+ value.respond_to?(:downcase) && value.downcase == 'true'
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ require_relative 'base'
6
+
7
+ module RubyVault
8
+ module Options
9
+ module Values
10
+ class Complex < Base
11
+ def resolve
12
+ @value
13
+ end
14
+
15
+ def render
16
+ @value.is_a?(::String) ? @value : JSON.generate(value)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'immutable-struct'
4
+
5
+ module RubyVault
6
+ module Options
7
+ module Values
8
+ class KeyValue < ImmutableStruct.new(:key, :value)
9
+ def initialize(key, value)
10
+ super(key: key, value: value)
11
+ end
12
+
13
+ def resolve
14
+ { key => value.resolve }
15
+ end
16
+
17
+ def render
18
+ "'#{key}=#{value.render}'"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module RubyVault
6
+ module Options
7
+ module Values
8
+ class String < Base
9
+ def resolve
10
+ @value.to_s
11
+ end
12
+
13
+ alias render resolve
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'values/boolean'
4
+ require_relative 'values/string'
5
+ require_relative 'values/complex'
6
+ require_relative 'values/key_value'
7
+
8
+ module RubyVault
9
+ module Options
10
+ module Values
11
+ def self.boolean(value)
12
+ Boolean.new(value)
13
+ end
14
+
15
+ def self.string(value)
16
+ String.new(value)
17
+ end
18
+
19
+ def self.complex(value)
20
+ Complex.new(value)
21
+ end
22
+
23
+ def self.key_value(key, value)
24
+ KeyValue.new(key, value)
25
+ end
26
+
27
+ def self.resolve(type)
28
+ case type
29
+ when :string then Values::String
30
+ when :boolean then Values::Boolean
31
+ when :complex then Values::Complex
32
+ when :key_value then Values::KeyValue
33
+ else type
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,9 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'options/name'
4
+ require_relative 'options/types'
5
+ require_relative 'options/values'
6
+ require_relative 'options/definition'
3
7
  require_relative 'options/factory'
4
8
 
5
9
  module RubyVault
6
10
  module Options
11
+ def self.name(name)
12
+ Name.new(name)
13
+ end
14
+
15
+ def self.definition(opts)
16
+ Definition.new(opts)
17
+ end
18
+
19
+ def self.types
20
+ Types
21
+ end
22
+
23
+ def self.values
24
+ Values
25
+ end
7
26
  end
8
27
  end
9
28
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RubyVault
4
- VERSION = '0.1.0.pre.3'
4
+ VERSION = '0.1.0.pre.4'
5
5
  end
data/lib/ruby_vault.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ruby_vault/options'
4
- require 'ruby_vault/version'
3
+ require_relative 'ruby_vault/options'
4
+ require_relative 'ruby_vault/version'
5
+ require_relative 'ruby_vault/commands'
5
6
  require 'logger'
6
7
 
7
8
  module RubyVault
@@ -10,11 +11,34 @@ module RubyVault
10
11
  @configuration ||= Configuration.new
11
12
  end
12
13
 
14
+ def configure
15
+ yield(configuration)
16
+ end
17
+
13
18
  def reset!
14
19
  @configuration = nil
15
20
  end
16
21
  end
17
22
 
23
+ module ClassMethods
24
+ def login(parameters = {}, invocation_options = {})
25
+ exec(RubyVault::Commands::Login,
26
+ parameters, invocation_options)
27
+ end
28
+
29
+ private
30
+
31
+ def exec(command_class, parameters, invocation_options)
32
+ command_class.new.execute(parameters, invocation_options)
33
+ end
34
+ end
35
+
36
+ extend ClassMethods
37
+
38
+ def self.included(other)
39
+ other.extend(ClassMethods)
40
+ end
41
+
18
42
  class Configuration
19
43
  attr_accessor :binary, :logger, :options, :stdin, :stdout, :stderr
20
44
 
@@ -29,7 +53,7 @@ module RubyVault
29
53
  end
30
54
 
31
55
  def initialize
32
- @binary = 'terraform'
56
+ @binary = 'vault'
33
57
  @logger = default_logger
34
58
  @options = default_options
35
59
  @stdin = ''
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_vault
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.3
4
+ version: 0.1.0.pre.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - InfraBlocks Maintainers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-03 00:00:00.000000000 Z
11
+ date: 2022-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: immutable-struct
@@ -279,10 +279,25 @@ files:
279
279
  - bin/console
280
280
  - bin/setup
281
281
  - lib/ruby_vault.rb
282
+ - lib/ruby_vault/commands.rb
283
+ - lib/ruby_vault/commands/base.rb
284
+ - lib/ruby_vault/commands/login.rb
285
+ - lib/ruby_vault/errors.rb
286
+ - lib/ruby_vault/errors/execution_error.rb
282
287
  - lib/ruby_vault/options.rb
288
+ - lib/ruby_vault/options/definition.rb
283
289
  - lib/ruby_vault/options/definitions.rb
284
290
  - lib/ruby_vault/options/factory.rb
285
291
  - lib/ruby_vault/options/name.rb
292
+ - lib/ruby_vault/options/types.rb
293
+ - lib/ruby_vault/options/types/flag.rb
294
+ - lib/ruby_vault/options/types/standard.rb
295
+ - lib/ruby_vault/options/values.rb
296
+ - lib/ruby_vault/options/values/base.rb
297
+ - lib/ruby_vault/options/values/boolean.rb
298
+ - lib/ruby_vault/options/values/complex.rb
299
+ - lib/ruby_vault/options/values/key_value.rb
300
+ - lib/ruby_vault/options/values/string.rb
286
301
  - lib/ruby_vault/version.rb
287
302
  - ruby_vault.gemspec
288
303
  homepage: https://github.com/infrablocks/ruby_vault