container_config 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config"
4
+ require "container_config/coercer/base"
5
+ require "container_config/coercer/boolean"
6
+ require "container_config/coercer/float"
7
+ require "container_config/coercer/integer"
8
+ require "container_config/coercer/string"
9
+ require "container_config/coercer/symbol"
10
+ require "container_config/coercer/ssl_verify_mode"
11
+ require "container_config/coercer/ssl_certificate"
12
+ require "container_config/coercer/ssl_key"
13
+
14
+ module ContainerConfig
15
+ # Contains classes and methods for type coercion
16
+ module Coercer
17
+ #
18
+ # Coerces a given value into a requested type
19
+ #
20
+ # @param [Object] value value to coerce
21
+ # @param [Symbol] value_type requested type such as :boolean, :integer, :string, :symbol,
22
+ # :ssl_verify_mode, :ssl_certificate, or :ssl_key
23
+ # @param [Hash] options Options Hash
24
+ # @option options [Boolean] :coerce_nil where to coerce nil values (defaults to true)
25
+ #
26
+ # @return [Object] coerced value
27
+ #
28
+ def self.coerce_value(value, value_type = nil, options = {})
29
+ return value unless value_type
30
+
31
+ return value if options[:coerce_nil] == false && value.nil?
32
+
33
+ value_type = value_type.to_sym
34
+
35
+ ContainerConfig.coercers.each do |coercer|
36
+ return coercer.coerce(value) if coercer.type == value_type
37
+ end
38
+
39
+ ContainerConfig.logger.warn { "Could not find valid coercion type for #{value_type}" }
40
+ value
41
+ end
42
+
43
+ #
44
+ # Array of default coercers
45
+ #
46
+ # @return [Array<ContainerConfig::Coercer::Base>] default coercers
47
+ #
48
+ def self.default_coercers
49
+ [
50
+ ContainerConfig::Coercer::Boolean.new,
51
+ ContainerConfig::Coercer::Float.new,
52
+ ContainerConfig::Coercer::Integer.new,
53
+ ContainerConfig::Coercer::SslCertificate.new,
54
+ ContainerConfig::Coercer::SslKey.new,
55
+ ContainerConfig::Coercer::SslVerifyMode.new,
56
+ ContainerConfig::Coercer::String.new,
57
+ ContainerConfig::Coercer::Symbol.new
58
+ ]
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ContainerConfig
4
+ module Coercer
5
+ # Base type coercer
6
+ class Base
7
+ #
8
+ # Returns name of the coercer
9
+ #
10
+ # @return [String] coercer name
11
+ #
12
+ def name
13
+ raise ContainerConfig::MissingOverride, "Must override name method in derived class #{self.class}"
14
+ end
15
+
16
+ #
17
+ # Returns the type of the coercer
18
+ # This is used by the ContainerConfig::Coercer.coerce_value method to determine
19
+ # whether this coercer should be used for a given type
20
+ #
21
+ # @return [Symbol] coercer type
22
+ #
23
+ def type
24
+ raise ContainerConfig::MissingOverride, "Must override type method in derived class #{self.class}"
25
+ end
26
+
27
+ #
28
+ # Coerces the given value into the coercer type
29
+ #
30
+ # @param [Object] _value given value
31
+ #
32
+ # @return [Object] coerced value
33
+ #
34
+ def coerce(_value)
35
+ raise ContainerConfig::MissingOverride, "Must override coerce method in derived class #{self.class}"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config/coercer/base"
4
+
5
+ module ContainerConfig
6
+ module Coercer
7
+ # Boolean type coercer
8
+ class Boolean < Base
9
+ # @see ContainerConfig::Coercer::Base#name
10
+ def name
11
+ "Boolean"
12
+ end
13
+
14
+ # @see ContainerConfig::Coercer::Base#type
15
+ def type
16
+ :boolean
17
+ end
18
+
19
+ #
20
+ # Coerces the given value into a boolean
21
+ #
22
+ # @param [Object] value given value
23
+ #
24
+ # @return [Boolean] coerced value
25
+ #
26
+ def coerce(value)
27
+ # If a digit is passed, check if it is non-zero and return true for non-zero values
28
+ return value.to_i != 0 if value.respond_to?(:to_i) && value.to_i.to_s == value.to_s
29
+
30
+ value.to_s.casecmp?("true")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config/coercer/base"
4
+
5
+ module ContainerConfig
6
+ module Coercer
7
+ # Float type coercer
8
+ class Float < Base
9
+ # @see ContainerConfig::Coercer::Base#name
10
+ def name
11
+ "Float"
12
+ end
13
+
14
+ # @see ContainerConfig::Coercer::Base#type
15
+ def type
16
+ :float
17
+ end
18
+
19
+ #
20
+ # Coerces the given value into a float
21
+ #
22
+ # @param [Object] value given value
23
+ #
24
+ # @return [Float] coerced value
25
+ #
26
+ def coerce(value)
27
+ return 0.0 unless value.respond_to?(:to_f)
28
+
29
+ value.to_f
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config/coercer/base"
4
+
5
+ module ContainerConfig
6
+ module Coercer
7
+ # Integer type coercer
8
+ class Integer < Base
9
+ # @see ContainerConfig::Coercer::Base#name
10
+ def name
11
+ "Integer"
12
+ end
13
+
14
+ # @see ContainerConfig::Coercer::Base#type
15
+ def type
16
+ :integer
17
+ end
18
+
19
+ #
20
+ # Coerces the given value into an integer
21
+ #
22
+ # @param [Object] value given value
23
+ #
24
+ # @return [Integer] coerced value
25
+ #
26
+ def coerce(value)
27
+ return 0 unless value.respond_to?(:to_i)
28
+
29
+ value.to_i
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config"
4
+ require "container_config/coercer/base"
5
+ require "openssl"
6
+
7
+ module ContainerConfig
8
+ module Coercer
9
+ # SSL certificate type coercer
10
+ class SslCertificate < Base
11
+ # @see ContainerConfig::Coercer::Base#name
12
+ def name
13
+ "SSL Certificate"
14
+ end
15
+
16
+ # @see ContainerConfig::Coercer::Base#type
17
+ def type
18
+ :ssl_certificate
19
+ end
20
+
21
+ #
22
+ # Coerces the given value into an SSL certificate
23
+ #
24
+ # @param [Object] value SSL certificate path
25
+ #
26
+ # @return [OpenSSL::X509::Certificate] coerced value
27
+ #
28
+ def coerce(value)
29
+ return if value.nil?
30
+
31
+ return value if value.is_a?(OpenSSL::X509::Certificate)
32
+
33
+ cert_path = value.to_s
34
+
35
+ unless File.exist?(cert_path)
36
+ ContainerConfig.logger.warn { "Could not find SSL certificate at #{cert_path}" }
37
+ return nil
38
+ end
39
+
40
+ OpenSSL::X509::Certificate.new(File.read(cert_path))
41
+ rescue OpenSSL::X509::CertificateError => e
42
+ ContainerConfig.logger.warn { "Could not parse SSL certificate #{cert_path} successfully: #{e}" }
43
+ nil
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config"
4
+ require "container_config/coercer/base"
5
+ require "openssl"
6
+
7
+ module ContainerConfig
8
+ module Coercer
9
+ # SSL key type coercer
10
+ class SslKey < Base
11
+ # @see ContainerConfig::Coercer::Base#name
12
+ def name
13
+ "SSL Private Key"
14
+ end
15
+
16
+ # @see ContainerConfig::Coercer::Base#type
17
+ def type
18
+ :ssl_key
19
+ end
20
+
21
+ #
22
+ # Coerces the given value into an SSL key
23
+ #
24
+ # @param [Object] value SSL key path
25
+ #
26
+ # @return [OpenSSL::PKey::RSA] coerced value
27
+ #
28
+ def coerce(value)
29
+ return if value.nil?
30
+
31
+ key_path = value.to_s
32
+
33
+ unless File.exist?(key_path)
34
+ ContainerConfig.logger.warn { "Could not find SSL key at #{key_path}" }
35
+ return
36
+ end
37
+
38
+ OpenSSL::PKey::RSA.new(File.read(key_path))
39
+ rescue OpenSSL::PKey::RSAError => e
40
+ ContainerConfig.logger.warn { "Could not parse SSL key #{key_path} successfully: #{e}" }
41
+ nil
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config"
4
+ require "container_config/coercer/base"
5
+ require "openssl"
6
+
7
+ module ContainerConfig
8
+ module Coercer
9
+ # SSL verification mode type coercer
10
+ class SslVerifyMode < Base
11
+ # Array of valid SSL verification modes
12
+ VALID_MODES = OpenSSL::SSL.constants.select { |c| c.to_s.start_with?("VERIFY") }.map(&:to_s)
13
+
14
+ # @see ContainerConfig::Coercer::Base#name
15
+ def name
16
+ "SSL Verification Mode"
17
+ end
18
+
19
+ # @see ContainerConfig::Coercer::Base#type
20
+ def type
21
+ :ssl_verify_mode
22
+ end
23
+
24
+ #
25
+ # Coerces the given value into an SSL verification mode
26
+ #
27
+ # @param [Object] value SSL verification mode string ("VERIFY_NONE", "VERIFY_PEER", etc.)
28
+ #
29
+ # @return [Integer] coerced value
30
+ #
31
+ def coerce(value)
32
+ value = value.to_s
33
+ return Object.const_get("OpenSSL::SSL::#{value}") if VALID_MODES.include?(value)
34
+
35
+ ContainerConfig.logger.warn do
36
+ "Could not convert #{value.inspect} into a valid OpenSSL verification mode.\nValid modes: #{VALID_MODES.join(", ")}"
37
+ end
38
+ nil
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config/coercer/base"
4
+
5
+ module ContainerConfig
6
+ module Coercer
7
+ # String type coercer
8
+ class String < Base
9
+ # @see ContainerConfig::Coercer::Base#name
10
+ def name
11
+ "String"
12
+ end
13
+
14
+ # @see ContainerConfig::Coercer::Base#type
15
+ def type
16
+ :string
17
+ end
18
+
19
+ #
20
+ # Coerces the given value into a string
21
+ #
22
+ # @param [Object] value given value
23
+ #
24
+ # @return [String] coerced value
25
+ #
26
+ def coerce(value)
27
+ value.to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config/coercer/base"
4
+
5
+ module ContainerConfig
6
+ module Coercer
7
+ # Symbol type coercer
8
+ class Symbol < Base
9
+ # @see ContainerConfig::Coercer::Base#name
10
+ def name
11
+ "Symbol"
12
+ end
13
+
14
+ # @see ContainerConfig::Coercer::Base#type
15
+ def type
16
+ :symbol
17
+ end
18
+
19
+ #
20
+ # Coerces the given value into a symbol
21
+ #
22
+ # @param [Object] value given value
23
+ #
24
+ # @return [Symbol] coerced value
25
+ #
26
+ def coerce(value)
27
+ return if value.nil?
28
+
29
+ value.to_s.to_sym
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+
5
+ module ContainerConfig
6
+ # ContainerConfig Logging class
7
+ class Logger < ::Logger
8
+ end
9
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "container_config"
4
+ require "container_config/provider/base"
5
+ require "container_config/provider/default"
6
+ require "container_config/provider/env"
7
+ require "container_config/provider/rails_credential"
8
+ require "container_config/provider/secret_volume"
9
+
10
+ module ContainerConfig
11
+ # Contains classes and methods for config value providers
12
+ module Provider
13
+ #
14
+ # Loads a value from the config value providers
15
+ #
16
+ # @param [String] key Configuration key to load
17
+ # @param [Array] dig_keys Variable keys to use to load from providers that accept a dig structure
18
+ # defaults to the lowercase key split by underscores
19
+ # "MY_PASSWORD" => ["my", "password"]
20
+ # @param [Hash] options Options Hash
21
+ # @option options [String] :default default value if the configuration setting cannot be found
22
+ # @option options [String] :secret_mount_directory directory where secret files are mounted
23
+ # @option options [Symbol] :type type to use such as :boolean, :integer, :string, :symbol,
24
+ # :ssl_verify_mode, :ssl_certificate, or :ssl_key
25
+ #
26
+ # @return [Object] configuration setting value
27
+ #
28
+ def self.load_value(key, *dig_keys, **options)
29
+ value = nil
30
+ ContainerConfig.providers.each do |p|
31
+ value = p.load(key, *dig_keys, **options)
32
+ break unless value.nil?
33
+ end
34
+
35
+ value
36
+ end
37
+
38
+ #
39
+ # Array of default providers
40
+ #
41
+ # @return [Array<ContainerConfig::Provider::Base>] default providers
42
+ #
43
+ def self.default_providers
44
+ defaults = [
45
+ ContainerConfig::Provider::Env.new,
46
+ ContainerConfig::Provider::SecretVolume.new
47
+ ]
48
+
49
+ defaults |= rails_providers if ContainerConfig.rails_app?
50
+ defaults << ContainerConfig::Provider::Default.new
51
+
52
+ defaults
53
+ end
54
+
55
+ #
56
+ # Array of Rails providers
57
+ # These are only included in the default providers when this gem is included
58
+ # as part of a rails application
59
+ #
60
+ # @return [Array<ContainerConfig::Provider::Base>] default providers
61
+ #
62
+ def self.rails_providers
63
+ [ContainerConfig::Provider::RailsCredential.new]
64
+ end
65
+ end
66
+ end