consul_application_settings 3.0.1 → 4.0.0.pre.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +9 -2
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +11 -1
- data/Gemfile.lock +7 -0
- data/README.md +100 -59
- data/bin/benchmark +1 -2
- data/consul_application_settings.gemspec +3 -1
- data/docker-compose.yml +17 -0
- data/lib/consul_application_settings/configuration.rb +7 -2
- data/lib/consul_application_settings/providers/abstract.rb +4 -3
- data/lib/consul_application_settings/providers/consul.rb +10 -2
- data/lib/consul_application_settings/providers/consul_preloaded.rb +22 -4
- data/lib/consul_application_settings/providers/local_storage.rb +1 -1
- data/lib/consul_application_settings/reader.rb +31 -6
- data/lib/consul_application_settings/resolvers/abstract.rb +14 -0
- data/lib/consul_application_settings/resolvers/env.rb +19 -0
- data/lib/consul_application_settings/resolvers/erb.rb +18 -0
- data/lib/consul_application_settings/resolvers/vault.rb +24 -0
- data/lib/consul_application_settings/utils.rb +12 -0
- data/lib/consul_application_settings/version.rb +1 -1
- data/lib/consul_application_settings.rb +3 -1
- metadata +40 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 709d93b5794a39ed2f78eb61462cc07ff0ed77dccd66343ad22fc13abc45c267
         | 
| 4 | 
            +
              data.tar.gz: 6daa5f0e9266fad7baee4e44efe8ed49ac5451744bd3abb60667afb1afb1a132
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 399c74e1bed212dea80f9b5d3f0f202c702b2e7704824214703f8003841b35792b66e3c6707ec7594d4b6860acbdd1b341c65e85312448d9fef3e2aa4a1c6c16
         | 
| 7 | 
            +
              data.tar.gz: 4b04c272e96bc975d0cae6984dc6c44e4d442b0dc1a78a51b9d6ca772b4d5b09bcc10ce6155113a955210e9abe4d91ccb446224fd881f0a79f29da55aebb6fc7
         | 
    
        data/.github/workflows/main.yml
    CHANGED
    
    | @@ -14,12 +14,19 @@ jobs: | |
| 14 14 | 
             
                runs-on: ubuntu-latest
         | 
| 15 15 | 
             
                strategy:
         | 
| 16 16 | 
             
                  matrix:
         | 
| 17 | 
            -
                    ruby: [ '2.5.x', '2.6.x' ]
         | 
| 17 | 
            +
                    ruby: [ '2.5.x', '2.6.x', '2.7.x', '3.0.x' ]
         | 
| 18 18 | 
             
                services:
         | 
| 19 | 
            -
                   | 
| 19 | 
            +
                  consul:
         | 
| 20 20 | 
             
                    image: consul:1.6
         | 
| 21 21 | 
             
                    ports:
         | 
| 22 22 | 
             
                      - '8500:8500'
         | 
| 23 | 
            +
                  vault:
         | 
| 24 | 
            +
                    image: vault
         | 
| 25 | 
            +
                    ports:
         | 
| 26 | 
            +
                      - "8200:8200"
         | 
| 27 | 
            +
                    env:
         | 
| 28 | 
            +
                      VAULT_DEV_ROOT_TOKEN_ID: root_token
         | 
| 29 | 
            +
                      SKIP_SETCAP: true
         | 
| 23 30 | 
             
                steps:
         | 
| 24 31 | 
             
                  - name: Checkout
         | 
| 25 32 | 
             
                    uses: actions/checkout@v1
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -2,6 +2,7 @@ AllCops: | |
| 2 2 | 
             
              TargetRubyVersion: 2.5
         | 
| 3 3 | 
             
              Exclude:
         | 
| 4 4 | 
             
                - 'tmp/**/*'
         | 
| 5 | 
            +
                - 'bin/**/*'
         | 
| 5 6 |  | 
| 6 7 | 
             
            Metrics/LineLength:
         | 
| 7 8 | 
             
              Max: 120
         | 
| @@ -10,4 +11,4 @@ Style/FrozenStringLiteralComment: | |
| 10 11 | 
             
              Enabled: false
         | 
| 11 12 |  | 
| 12 13 | 
             
            Metrics/BlockLength:
         | 
| 13 | 
            -
              ExcludedMethods: ['describe', 'context']
         | 
| 14 | 
            +
              ExcludedMethods: ['describe', 'context', 'shared_examples']
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,14 @@ | |
| 1 1 | 
             
            ## [Unreleased]
         | 
| 2 2 |  | 
| 3 | 
            +
            ## [4.0.0-alpha]
         | 
| 4 | 
            +
            ### Breaking Changes
         | 
| 5 | 
            +
            - When using `settings.get` to retrieve object - exception is raised 
         | 
| 6 | 
            +
            ### New features
         | 
| 7 | 
            +
            - Introduce resolvers concept
         | 
| 8 | 
            +
            - Add environment resolver
         | 
| 9 | 
            +
            - Add erb resolver
         | 
| 10 | 
            +
            - Add vault alpha resolver
         | 
| 11 | 
            +
             | 
| 3 12 | 
             
            ## [3.0.1]
         | 
| 4 13 | 
             
            ### Fixes
         | 
| 5 14 | 
             
            - Fix exception when preloading settings without consul 
         | 
| @@ -59,7 +68,8 @@ | |
| 59 68 | 
             
            - Support deep settings search
         | 
| 60 69 | 
             
            - Support nested configs
         | 
| 61 70 |  | 
| 62 | 
            -
            [Unreleased]: https://github.com/matic-insurance/consul_application_settings/compare/ | 
| 71 | 
            +
            [Unreleased]: https://github.com/matic-insurance/consul_application_settings/compare/4.0.0-alpha...HEAD
         | 
| 72 | 
            +
            [4.0.0-alpha]: https://github.com/matic-insurance/consul_application_settings/compare/3.0.1...4.0.0-alpha
         | 
| 63 73 | 
             
            [3.0.1]: https://github.com/matic-insurance/consul_application_settings/compare/3.0.0...3.0.1
         | 
| 64 74 | 
             
            [3.0.0]: https://github.com/matic-insurance/consul_application_settings/compare/2.0.0...3.0.0
         | 
| 65 75 | 
             
            [2.1.1]: https://github.com/matic-insurance/consul_application_settings/compare/2.1.0...2.1.1
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -2,12 +2,16 @@ PATH | |
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 4 | 
             
                consul_application_settings (0.0.0)
         | 
| 5 | 
            +
                  deep_merge (~> 1.2)
         | 
| 5 6 | 
             
                  diplomat (~> 2.5.1)
         | 
| 6 7 |  | 
| 7 8 | 
             
            GEM
         | 
| 8 9 | 
             
              remote: https://rubygems.org/
         | 
| 9 10 | 
             
              specs:
         | 
| 10 11 | 
             
                ast (2.4.0)
         | 
| 12 | 
            +
                aws-eventstream (1.2.0)
         | 
| 13 | 
            +
                aws-sigv4 (1.4.0)
         | 
| 14 | 
            +
                  aws-eventstream (~> 1, >= 1.0.2)
         | 
| 11 15 | 
             
                codecov (0.4.3)
         | 
| 12 16 | 
             
                  simplecov (>= 0.15, < 0.22)
         | 
| 13 17 | 
             
                deep_merge (1.2.1)
         | 
| @@ -61,6 +65,8 @@ GEM | |
| 61 65 | 
             
                  simplecov-html (~> 0.10.0)
         | 
| 62 66 | 
             
                simplecov-html (0.10.2)
         | 
| 63 67 | 
             
                unicode-display_width (1.5.0)
         | 
| 68 | 
            +
                vault (0.16.0)
         | 
| 69 | 
            +
                  aws-sigv4
         | 
| 64 70 |  | 
| 65 71 | 
             
            PLATFORMS
         | 
| 66 72 | 
             
              ruby
         | 
| @@ -74,6 +80,7 @@ DEPENDENCIES | |
| 74 80 | 
             
              rubocop (~> 0.66)
         | 
| 75 81 | 
             
              rubocop-rspec (~> 1.32.0)
         | 
| 76 82 | 
             
              simplecov (~> 0.16)
         | 
| 83 | 
            +
              vault (~> 0.16)
         | 
| 77 84 |  | 
| 78 85 | 
             
            BUNDLED WITH
         | 
| 79 86 | 
             
               2.1.2
         | 
    
        data/README.md
    CHANGED
    
    | @@ -3,26 +3,16 @@ | |
| 3 3 | 
             
            
         | 
| 4 4 | 
             
            [](https://codecov.io/gh/matic-insurance/consul_application_settings)
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
            to host application settings.  | 
| 8 | 
            -
            to simplify storage and control of application with Consul KV storage.
         | 
| 6 | 
            +
            This gem that simplifies usage of Consul (via [Diplomat gem](https://github.com/WeAreFarmGeek/diplomat)) 
         | 
| 7 | 
            +
            to host application settings. 
         | 
| 9 8 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
            Except reading value from Consul the gem also:
         | 
| 10 | 
            +
            - Fallbacks to YAML if value is missing in consul
         | 
| 11 | 
            +
            - Resolve actual value from other sources to facilitate overriding via ENV, storing secret values in Vault,  
         | 
| 12 | 
            +
              or executing small ERB snippets 
         | 
| 12 13 |  | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
            - One engineer has created a new feature that depend on consul key/value. 
         | 
| 16 | 
            -
              
         | 
| 17 | 
            -
              How enginner can notify other engineers that they need to set this value in their consul environments?
         | 
| 18 | 
            -
             | 
| 19 | 
            -
            - DevOps team responsible to configure and maintain deployment. 
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              How do they learn (have reference) of what settings and structure application expect? 
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            Gem reads any particular setting from consul and if it is missing tries to find value in YAML defaults file
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            **NOTE** Consul is requested every time you query the settings. Defaults YAML file is loaded in memory and is not changing.
         | 
| 14 | 
            +
            Default values in YAML also can be considered as a way to communicate structure of settings to other engineers.
         | 
| 15 | 
            +
            Default values also support local settings to allow override on local environment or deployment in production.
         | 
| 26 16 |  | 
| 27 17 | 
             
            ## Installation
         | 
| 28 18 |  | 
| @@ -39,22 +29,27 @@ gem 'consul_application_settings' | |
| 39 29 | 
             
            At the load of application: 
         | 
| 40 30 | 
             
            ```ruby
         | 
| 41 31 | 
             
            ConsulApplicationSettings.configure do |config|
         | 
| 42 | 
            -
              # Specify path to the base settings YML. Default: 'config/ | 
| 43 | 
            -
              config.base_file_path = Rails.root.join('config/ | 
| 44 | 
            -
              # Specify path to the local settings YML, which overrides the base file. Default: 'config/ | 
| 45 | 
            -
              config.local_file_path = Rails.root.join('config/ | 
| 46 | 
            -
              # Specify whether  | 
| 32 | 
            +
              # Specify path to the base settings YML. Default: 'config/app_settings.yml' 
         | 
| 33 | 
            +
              config.base_file_path = Rails.root.join('config/app_settings.yml')
         | 
| 34 | 
            +
              # Specify path to the local settings YML, which overrides the base file. Default: 'config/app_settings.local.yml'
         | 
| 35 | 
            +
              config.local_file_path = Rails.root.join('config/app_settings.local.yml')
         | 
| 36 | 
            +
              # Specify whether exception should be thrown on Consul connection errors. Default: false
         | 
| 47 37 | 
             
              config.disable_consul_connection_errors = true
         | 
| 48 38 | 
             
              # Specify setting providers. Default: [ConsulApplicationSettings::Providers::ConsulPreloaded, ConsulApplicationSettings::Providers::LocalStorage]
         | 
| 49 39 | 
             
              config.settings_providers = [
         | 
| 50 40 | 
             
                ConsulApplicationSettings::Providers::Consul,          
         | 
| 51 41 | 
             
                ConsulApplicationSettings::Providers::LocalStorage          
         | 
| 52 42 | 
             
              ]
         | 
| 43 | 
            +
              # Specify how values will be additionally resolved. Default: [ConsulApplicationSettings::Resolvers::Env] 
         | 
| 44 | 
            +
              config.value_resolvers = [
         | 
| 45 | 
            +
                ConsulApplicationSettings::Resolvers::Erb,
         | 
| 46 | 
            +
                ConsulApplicationSettings::Resolvers::Env,
         | 
| 47 | 
            +
              ]
         | 
| 53 48 | 
             
            end
         | 
| 54 49 |  | 
| 55 | 
            -
            APP_SETTINGS = ConsulApplicationSettings.load
         | 
| 56 50 | 
             
            # Specify path to settings both in YML files and Consul
         | 
| 57 | 
            -
            AUTH_SETTIGNS = ConsulApplicationSettings.load(' | 
| 51 | 
            +
            AUTH_SETTIGNS = ConsulApplicationSettings.load('my_cool_app')
         | 
| 52 | 
            +
            # Load at root without any prefix: APP_SETTINGS = ConsulApplicationSettings.load
         | 
| 58 53 | 
             
            ```
         | 
| 59 54 |  | 
| 60 55 | 
             
            **NOTE** For rails you can add this code to custom initializer `console_application_settings.rb` in `app/config/initializers`
         | 
| @@ -65,35 +60,32 @@ AUTH_SETTIGNS = ConsulApplicationSettings.load('authentication') | |
| 65 60 |  | 
| 66 61 | 
             
            Assuming your defaults file in repository `config/application_settings.yml` looks like:
         | 
| 67 62 | 
             
            ```yaml
         | 
| 68 | 
            -
             | 
| 69 | 
            -
               | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
                 | 
| 74 | 
            -
                   | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
                   | 
| 79 | 
            -
             | 
| 80 | 
            -
                    webhook_url: 'https://hooks.slack.com/services/XXXXXX/XXXXX/XXXXXXX'
         | 
| 63 | 
            +
            my_cool_app:
         | 
| 64 | 
            +
              app_name: 'MyCoolApp'
         | 
| 65 | 
            +
              hostname: 'http://localhost:3001'
         | 
| 66 | 
            +
              
         | 
| 67 | 
            +
              integrations:
         | 
| 68 | 
            +
                database:
         | 
| 69 | 
            +
                  domain: localhost
         | 
| 70 | 
            +
                  user: app
         | 
| 71 | 
            +
                  password: password1234
         | 
| 72 | 
            +
                slack:
         | 
| 73 | 
            +
                  enabled: false
         | 
| 74 | 
            +
                  webhook_url: 'https://hooks.slack.com/services/XXXXXX/XXXXX/XXXXXXX'
         | 
| 81 75 | 
             
            ```
         | 
| 82 76 |  | 
| 83 77 | 
             
            And consul has following settings
         | 
| 84 78 | 
             
            ```json
         | 
| 85 79 | 
             
            {
         | 
| 86 | 
            -
              " | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                    " | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
                    " | 
| 95 | 
            -
                      "enabled": "true"
         | 
| 96 | 
            -
                    }
         | 
| 80 | 
            +
              "my_cool_app": {
         | 
| 81 | 
            +
               "hostname": "https://mycoolapp.com",
         | 
| 82 | 
            +
               "integrations": {
         | 
| 83 | 
            +
                  "database": {
         | 
| 84 | 
            +
                    "domain": "194.78.92.19",
         | 
| 85 | 
            +
                    "password": "*************"
         | 
| 86 | 
            +
                  },
         | 
| 87 | 
            +
                  "slack": {
         | 
| 88 | 
            +
                    "enabled": "true"
         | 
| 97 89 | 
             
                  }
         | 
| 98 90 | 
             
                }
         | 
| 99 91 | 
             
              }
         | 
| @@ -120,10 +112,60 @@ gem provides interface to avoid duplicating absolute path | |
| 120 112 |  | 
| 121 113 | 
             
            ```ruby
         | 
| 122 114 | 
             
            # You can load subsettings from root object
         | 
| 123 | 
            -
            db_settings = APP_SETTINGS.load('integrations/database')
         | 
| 115 | 
            +
            db_settings = APP_SETTINGS.load('integrations/database') # ConsulApplicationSettings::Reader
         | 
| 124 116 | 
             
            db_settings.get(:domain)                  # "194.78.92.19"
         | 
| 125 117 | 
             
            db_settings['user']                       # "app"
         | 
| 126 | 
            -
             | 
| 118 | 
            +
             | 
| 119 | 
            +
            #if you try to get subsettings via get - error is raised
         | 
| 120 | 
            +
            APP_SETTINGS.get('integrations/database') # raise ConsulApplicationSettings::Error
         | 
| 121 | 
            +
            ```
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            ## Advanced Configurations
         | 
| 124 | 
            +
             | 
| 125 | 
            +
            ### Setting Providers
         | 
| 126 | 
            +
            Providers controls how and in which order settings are retrieved. 
         | 
| 127 | 
            +
            When application asks for specific setting - gem retrieves them from every provider in order of configuration
         | 
| 128 | 
            +
            until one returns not nil value.
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            Default order for providers is:
         | 
| 131 | 
            +
            1. `ConsulApplicationSettings::Providers::ConsulPreloaded`
         | 
| 132 | 
            +
            2. `ConsulApplicationSettings::Providers::LocalStorage`
         | 
| 133 | 
            +
             | 
| 134 | 
            +
            List of built in providers:
         | 
| 135 | 
            +
            - `ConsulApplicationSettings::Providers::ConsulPreloaded` - Retrieves all settings from consul on every `.load`
         | 
| 136 | 
            +
            - `ConsulApplicationSettings::Providers::Consul` - Retrieves setting every time `.get` method is called
         | 
| 137 | 
            +
            - `ConsulApplicationSettings::Providers::LocalStorage` - Retrieves all settings from local files on every `.load`
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            Custom provider can be added as long as it support following interface:
         | 
| 140 | 
            +
            ```ruby
         | 
| 141 | 
            +
            class CustomProvider
         | 
| 142 | 
            +
              #constructor
         | 
| 143 | 
            +
              def initialize(base_path, config)
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
              
         | 
| 146 | 
            +
              # get value by `base_path + '/' + path`
         | 
| 147 | 
            +
              def get(path)
         | 
| 148 | 
            +
              end
         | 
| 149 | 
            +
            end
         | 
| 150 | 
            +
            ```
         | 
| 151 | 
            +
             | 
| 152 | 
            +
            ### Resolvers
         | 
| 153 | 
            +
            Once value is retrieved - it will be additionally processed by resolvers. 
         | 
| 154 | 
            +
            This allows for additional flexibility like getting values from external sources. 
         | 
| 155 | 
            +
            While every resolver can be implemented in a form of a provider - one will be limited by the structure of settings, 
         | 
| 156 | 
            +
            while other system might not be compatible with this.
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            When value is retrieved - gem finds **first** provider that can resolve value and resolves it. 
         | 
| 159 | 
            +
            Resolved value is returned to application.
         | 
| 160 | 
            +
             | 
| 161 | 
            +
            Default list of resolvers:
         | 
| 162 | 
            +
            - `ConsulApplicationSettings::Resolvers::Env`
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            List of built in resolvers
         | 
| 165 | 
            +
            - `ConsulApplicationSettings::Resolvers::Env` - resolves any value by looking up environment variable. 
         | 
| 166 | 
            +
              Matching any value that starts with `env://`. Value like `env://TEST_URL` will be resolved as `ENV['TEST_URL']`
         | 
| 167 | 
            +
            - `ConsulApplicationSettings::Resolvers::Erb` - resolves value by rendering it via ERB. 
         | 
| 168 | 
            +
              Matching any value that contains `<%` and `%>` in it. Value like `<%= 2 + 2 %>` will be resolved as `4`
         | 
| 127 169 |  | 
| 128 170 | 
             
            ### Gem Configuration
         | 
| 129 171 | 
             
            You can configure gem with block:
         | 
| @@ -145,18 +187,17 @@ All Gem configurations | |
| 145 187 | 
             
            | local_file_path                  | no       | 'config/application_settings.local.yml' | String  | Path to the file with local settings overriding the base settings            |
         | 
| 146 188 | 
             
            | disable_consul_connection_errors | no       | true                                    | Boolean | Do not raise exception when consul is not available (useful for development) |
         | 
| 147 189 | 
             
            | settings_providers               | no       | Array(Provider)                         | Array   | Specify custom setting provider lists                                        |
         | 
| 148 | 
            -
             | 
| 149 | 
            -
            ### Performance vs Consistency
         | 
| 150 | 
            -
            To be defined in future iterations on Consul Providers
         | 
| 190 | 
            +
            | value_resolvers                  | no       | Array(Resolver)                         | Array   | Specify custom value resolvers lists                                         |
         | 
| 151 191 |  | 
| 152 192 | 
             
            ## Development
         | 
| 153 193 |  | 
| 154 | 
            -
            1. [Install Consul](https://www.consul.io/docs/install/index.html)
         | 
| 155 194 | 
             
            1. Run `bin/setup` to install dependencies
         | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 195 | 
            +
            2. Run `docker-compose up` to spin up dependencies (Consul)
         | 
| 196 | 
            +
            3. Run tests `rspec`
         | 
| 197 | 
            +
            4. Add new test
         | 
| 198 | 
            +
            5. Add new code
         | 
| 199 | 
            +
            6. Go to step 3
         | 
| 200 | 
            +
            7. Create PR
         | 
| 160 201 |  | 
| 161 202 | 
             
            ## Contributing
         | 
| 162 203 |  | 
    
        data/bin/benchmark
    CHANGED
    
    
| @@ -29,13 +29,15 @@ Gem::Specification.new do |spec| | |
| 29 29 | 
             
              spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 30 30 | 
             
              spec.require_paths = ['lib']
         | 
| 31 31 |  | 
| 32 | 
            +
              spec.add_dependency 'deep_merge', '~> 1.2'
         | 
| 32 33 | 
             
              spec.add_dependency 'diplomat', '~> 2.5.1'
         | 
| 33 34 |  | 
| 34 35 | 
             
              spec.add_development_dependency 'bundler', '~> 2.0'
         | 
| 36 | 
            +
              spec.add_development_dependency 'codecov', '~> 0.4'
         | 
| 35 37 | 
             
              spec.add_development_dependency 'rake', '~> 13.0'
         | 
| 36 38 | 
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         | 
| 37 39 | 
             
              spec.add_development_dependency 'rubocop', '~> 0.66'
         | 
| 38 40 | 
             
              spec.add_development_dependency 'rubocop-rspec', '~> 1.32.0'
         | 
| 39 41 | 
             
              spec.add_development_dependency 'simplecov', '~> 0.16'
         | 
| 40 | 
            -
              spec.add_development_dependency ' | 
| 42 | 
            +
              spec.add_development_dependency 'vault', '~> 0.16'
         | 
| 41 43 | 
             
            end
         | 
    
        data/docker-compose.yml
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # dependencies needed for development environment
         | 
| 2 | 
            +
            version: '3'
         | 
| 3 | 
            +
            services:
         | 
| 4 | 
            +
              vault:
         | 
| 5 | 
            +
                image: vault
         | 
| 6 | 
            +
                ports:
         | 
| 7 | 
            +
                  - "8200:8200"
         | 
| 8 | 
            +
                cap_add:
         | 
| 9 | 
            +
                  - IPC_LOCK
         | 
| 10 | 
            +
                environment:
         | 
| 11 | 
            +
                  VAULT_DEV_ROOT_TOKEN_ID: root_token
         | 
| 12 | 
            +
              consul:
         | 
| 13 | 
            +
                image: consul
         | 
| 14 | 
            +
                ports:
         | 
| 15 | 
            +
                  - "8500:8500"
         | 
| 16 | 
            +
                environment:
         | 
| 17 | 
            +
                  CONSUL_BIND_INTERFACE: eth0
         | 
| @@ -6,14 +6,19 @@ module ConsulApplicationSettings | |
| 6 6 | 
             
                DEFAULT_PROVIDERS = [
         | 
| 7 7 | 
             
                  ConsulApplicationSettings::Providers::ConsulPreloaded,
         | 
| 8 8 | 
             
                  ConsulApplicationSettings::Providers::LocalStorage
         | 
| 9 | 
            -
                ]
         | 
| 10 | 
            -
                 | 
| 9 | 
            +
                ].freeze
         | 
| 10 | 
            +
                DEFAULT_RESOLVERS = [
         | 
| 11 | 
            +
                  ConsulApplicationSettings::Resolvers::Env
         | 
| 12 | 
            +
                ].freeze
         | 
| 13 | 
            +
                attr_accessor :base_file_path, :local_file_path, :disable_consul_connection_errors,
         | 
| 14 | 
            +
                              :settings_providers, :value_resolvers
         | 
| 11 15 |  | 
| 12 16 | 
             
                def initialize
         | 
| 13 17 | 
             
                  @base_file_path = DEFAULT_BASE_FILE_PATH
         | 
| 14 18 | 
             
                  @local_file_path = DEFAULT_LOCAL_FILE_PATH
         | 
| 15 19 | 
             
                  @disable_consul_connection_errors = true
         | 
| 16 20 | 
             
                  @settings_providers = DEFAULT_PROVIDERS
         | 
| 21 | 
            +
                  @value_resolvers = DEFAULT_RESOLVERS
         | 
| 17 22 | 
             
                end
         | 
| 18 23 | 
             
              end
         | 
| 19 24 | 
             
            end
         | 
| @@ -3,10 +3,11 @@ module ConsulApplicationSettings | |
| 3 3 | 
             
                # Abstract class with basic functionality
         | 
| 4 4 | 
             
                class Abstract
         | 
| 5 5 | 
             
                  def initialize(base_path, config)
         | 
| 6 | 
            -
                    @base_path | 
| 6 | 
            +
                    @base_path = base_path
         | 
| 7 | 
            +
                    @config = config
         | 
| 7 8 | 
             
                  end
         | 
| 8 9 |  | 
| 9 | 
            -
                  def get( | 
| 10 | 
            +
                  def get(_path)
         | 
| 10 11 | 
             
                    raise NotImplementedError
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 |  | 
| @@ -22,4 +23,4 @@ module ConsulApplicationSettings | |
| 22 23 | 
             
                  end
         | 
| 23 24 | 
             
                end
         | 
| 24 25 | 
             
              end
         | 
| 25 | 
            -
            end
         | 
| 26 | 
            +
            end
         | 
| @@ -7,18 +7,26 @@ module ConsulApplicationSettings | |
| 7 7 | 
             
                  def get(path)
         | 
| 8 8 | 
             
                    full_path = absolute_key_path(path)
         | 
| 9 9 | 
             
                    value = get_from_consul(full_path)
         | 
| 10 | 
            +
                    value = resolve_tree_response(value, full_path)
         | 
| 10 11 | 
             
                    ConsulApplicationSettings::Utils.cast_consul_value(value)
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 |  | 
| 13 14 | 
             
                  private
         | 
| 14 15 |  | 
| 15 16 | 
             
                  def get_from_consul(path)
         | 
| 16 | 
            -
                    Diplomat::Kv.get(path,  | 
| 17 | 
            +
                    Diplomat::Kv.get(path, recurse: true)
         | 
| 17 18 | 
             
                  rescue Diplomat::KeyNotFound
         | 
| 18 | 
            -
                     | 
| 19 | 
            +
                    nil
         | 
| 19 20 | 
             
                  rescue SystemCallError, Faraday::ConnectionFailed, Diplomat::PathNotFound => e
         | 
| 20 21 | 
             
                    raise e unless @config.disable_consul_connection_errors
         | 
| 21 22 | 
             
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def resolve_tree_response(value, full_path)
         | 
| 25 | 
            +
                    return value unless value.is_a?(Array)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    value.each { |item| item[:key] = item[:key].delete_prefix("#{full_path}/") }
         | 
| 28 | 
            +
                    value
         | 
| 29 | 
            +
                  end
         | 
| 22 30 | 
             
                end
         | 
| 23 31 | 
             
              end
         | 
| 24 32 | 
             
            end
         | 
| @@ -4,24 +4,42 @@ module ConsulApplicationSettings | |
| 4 4 | 
             
                class ConsulPreloaded < Abstract
         | 
| 5 5 | 
             
                  def initialize(base_path, config)
         | 
| 6 6 | 
             
                    super
         | 
| 7 | 
            -
                    @data =  | 
| 7 | 
            +
                    @data = read_all_from_consul
         | 
| 8 8 | 
             
                  end
         | 
| 9 9 |  | 
| 10 10 | 
             
                  def get(path)
         | 
| 11 11 | 
             
                    value = get_value_from_hash(absolute_key_path(path), @data)
         | 
| 12 | 
            +
                    value = resolve_tree_response(value)
         | 
| 12 13 | 
             
                    ConsulApplicationSettings::Utils.cast_consul_value(value)
         | 
| 13 14 | 
             
                  end
         | 
| 14 15 |  | 
| 15 16 | 
             
                  protected
         | 
| 16 17 |  | 
| 17 | 
            -
                  def  | 
| 18 | 
            -
                    Diplomat::Kv.get_all(@base_path,  | 
| 18 | 
            +
                  def read_all_from_consul
         | 
| 19 | 
            +
                    Diplomat::Kv.get_all(@base_path, convert_to_hash: true)
         | 
| 19 20 | 
             
                  rescue Diplomat::KeyNotFound
         | 
| 20 21 | 
             
                    {}
         | 
| 21 22 | 
             
                  rescue SystemCallError, Faraday::ConnectionFailed, Diplomat::PathNotFound => e
         | 
| 22 23 | 
             
                    raise e unless @config.disable_consul_connection_errors
         | 
| 24 | 
            +
             | 
| 23 25 | 
             
                    {}
         | 
| 24 26 | 
             
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def resolve_tree_response(value)
         | 
| 29 | 
            +
                    return value unless value.is_a?(Hash)
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    deep_cast(value)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def deep_cast(hash)
         | 
| 35 | 
            +
                    hash.each_pair do |k, v|
         | 
| 36 | 
            +
                      if v.is_a?(Hash)
         | 
| 37 | 
            +
                        deep_cast(v)
         | 
| 38 | 
            +
                      else
         | 
| 39 | 
            +
                        hash[k] = ConsulApplicationSettings::Utils.cast_consul_value(v)
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 25 43 | 
             
                end
         | 
| 26 44 | 
             
              end
         | 
| 27 | 
            -
            end
         | 
| 45 | 
            +
            end
         | 
| @@ -19,7 +19,7 @@ module ConsulApplicationSettings | |
| 19 19 | 
             
                    base_yml = read_yml(base_file_path)
         | 
| 20 20 | 
             
                    local_yml = read_yml(local_file_path)
         | 
| 21 21 | 
             
                    DeepMerge.deep_merge!(local_yml, base_yml, preserve_unmergeables: false, overwrite_arrays: true,
         | 
| 22 | 
            -
             | 
| 22 | 
            +
                                                               merge_nil_values: true)
         | 
| 23 23 | 
             
                  end
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def base_file_path
         | 
| @@ -1,18 +1,16 @@ | |
| 1 1 | 
             
            module ConsulApplicationSettings
         | 
| 2 | 
            -
              #  | 
| 2 | 
            +
              # Orchestrates fetching values from provider and resolving them
         | 
| 3 3 | 
             
              class Reader
         | 
| 4 4 | 
             
                def initialize(base_path, config)
         | 
| 5 5 | 
             
                  @base_path = base_path
         | 
| 6 6 | 
             
                  @config = config
         | 
| 7 7 | 
             
                  @providers = config.settings_providers.map { |provider| provider.new(base_path, config) }
         | 
| 8 | 
            +
                  @resolvers = config.value_resolvers.map(&:new)
         | 
| 8 9 | 
             
                end
         | 
| 9 10 |  | 
| 10 11 | 
             
                def get(path)
         | 
| 11 | 
            -
                   | 
| 12 | 
            -
             | 
| 13 | 
            -
                    return value unless value.nil?
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                  nil
         | 
| 12 | 
            +
                  value = fetch_value(path)
         | 
| 13 | 
            +
                  resolve_value(value, path)
         | 
| 16 14 | 
             
                end
         | 
| 17 15 |  | 
| 18 16 | 
             
                alias [] get
         | 
| @@ -21,5 +19,32 @@ module ConsulApplicationSettings | |
| 21 19 | 
             
                  new_path = ConsulApplicationSettings::Utils.generate_path(@base_path, sub_path)
         | 
| 22 20 | 
             
                  self.class.new(new_path, @config)
         | 
| 23 21 | 
             
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                protected
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def check_deep_structure(value, path)
         | 
| 26 | 
            +
                  return unless value.is_a?(Hash)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  message = "Getting value of complex object at path: '#{path}'. Use #load method to get new scoped instance"
         | 
| 29 | 
            +
                  raise ConsulApplicationSettings::Error, message if value.is_a?(Hash)
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def fetch_value(path)
         | 
| 33 | 
            +
                  @providers.each do |provider|
         | 
| 34 | 
            +
                    value = provider.get(path)
         | 
| 35 | 
            +
                    check_deep_structure(value, path)
         | 
| 36 | 
            +
                    return value unless value.nil?
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  nil
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def resolve_value(value, path)
         | 
| 42 | 
            +
                  resolver = @resolvers.detect { |r| r.resolvable?(value, path) }
         | 
| 43 | 
            +
                  if resolver
         | 
| 44 | 
            +
                    resolver.resolve(value, path)
         | 
| 45 | 
            +
                  else
         | 
| 46 | 
            +
                    value
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 24 49 | 
             
              end
         | 
| 25 50 | 
             
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module ConsulApplicationSettings
         | 
| 2 | 
            +
              module Resolvers
         | 
| 3 | 
            +
                # Resolve values in environment
         | 
| 4 | 
            +
                class Env
         | 
| 5 | 
            +
                  IDENTIFIER = 'env://'.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def resolvable?(value, _path)
         | 
| 8 | 
            +
                    return unless value.respond_to?(:start_with?)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    value.start_with?(IDENTIFIER)
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def resolve(value, _path)
         | 
| 14 | 
            +
                    env_path = value.to_s.delete_prefix(IDENTIFIER)
         | 
| 15 | 
            +
                    ENV[env_path]
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module ConsulApplicationSettings
         | 
| 2 | 
            +
              module Resolvers
         | 
| 3 | 
            +
                # Run values through ERB
         | 
| 4 | 
            +
                class Erb
         | 
| 5 | 
            +
                  IDENTIFIER = /(<%).*(%>)/.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def resolvable?(value, _path)
         | 
| 8 | 
            +
                    return unless value.is_a?(String)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    IDENTIFIER.match?(value)
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def resolve(value, _path)
         | 
| 14 | 
            +
                    ERB.new(value.to_s).result
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module ConsulApplicationSettings
         | 
| 2 | 
            +
              module Resolvers
         | 
| 3 | 
            +
                # Resolve values using vault
         | 
| 4 | 
            +
                class Vault
         | 
| 5 | 
            +
                  IDENTIFIER = 'vault://'.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def resolvable?(value, _path)
         | 
| 8 | 
            +
                    return unless value.respond_to?(:start_with?)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    value.start_with?(IDENTIFIER)
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  # Expect value in format `vault://mount/path/to/secret?attribute_name`
         | 
| 14 | 
            +
                  def resolve(value, _path)
         | 
| 15 | 
            +
                    value = value.delete_prefix(IDENTIFIER)
         | 
| 16 | 
            +
                    mount, secret = value.split('/', 2)
         | 
| 17 | 
            +
                    secret, attribute = secret.split('?')
         | 
| 18 | 
            +
                    attribute ||= 'value'
         | 
| 19 | 
            +
                    secret = ::Vault.kv(mount).read(secret)
         | 
| 20 | 
            +
                    secret && secret.data[attribute.to_sym]
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -9,6 +9,8 @@ module ConsulApplicationSettings | |
| 9 9 | 
             
                    return nil if value.nil?
         | 
| 10 10 | 
             
                    return false if value == 'false'
         | 
| 11 11 | 
             
                    return true if value == 'true'
         | 
| 12 | 
            +
                    return value if value.is_a?(Hash)
         | 
| 13 | 
            +
                    return convert_to_hash(value) if value.is_a?(Array)
         | 
| 12 14 |  | 
| 13 15 | 
             
                    cast_complex_value(value)
         | 
| 14 16 | 
             
                  end
         | 
| @@ -34,6 +36,16 @@ module ConsulApplicationSettings | |
| 34 36 | 
             
                    end
         | 
| 35 37 | 
             
                    value.to_s
         | 
| 36 38 | 
             
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def convert_to_hash(data)
         | 
| 41 | 
            +
                    data_h = data.map do |item|
         | 
| 42 | 
            +
                      value = cast_consul_value(item[:value])
         | 
| 43 | 
            +
                      item[:key].split('/').reverse.reduce(value) { |h, v| { v => h } }
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    data_h.reduce({}) do |dest, source|
         | 
| 46 | 
            +
                      DeepMerge.deep_merge!(source, dest, preserve_unmergeables: true)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 37 49 | 
             
                end
         | 
| 38 50 | 
             
              end
         | 
| 39 51 | 
             
            end
         | 
| @@ -3,6 +3,9 @@ require 'consul_application_settings/providers/abstract' | |
| 3 3 | 
             
            require 'consul_application_settings/providers/consul'
         | 
| 4 4 | 
             
            require 'consul_application_settings/providers/consul_preloaded'
         | 
| 5 5 | 
             
            require 'consul_application_settings/providers/local_storage'
         | 
| 6 | 
            +
            require 'consul_application_settings/resolvers/abstract'
         | 
| 7 | 
            +
            require 'consul_application_settings/resolvers/env'
         | 
| 8 | 
            +
            require 'consul_application_settings/resolvers/erb'
         | 
| 6 9 | 
             
            require 'consul_application_settings/configuration'
         | 
| 7 10 | 
             
            require 'consul_application_settings/reader'
         | 
| 8 11 | 
             
            require 'consul_application_settings/utils'
         | 
| @@ -13,7 +16,6 @@ module ConsulApplicationSettings | |
| 13 16 |  | 
| 14 17 | 
             
              class << self
         | 
| 15 18 | 
             
                attr_accessor :config
         | 
| 16 | 
            -
                attr_accessor :defaults
         | 
| 17 19 | 
             
              end
         | 
| 18 20 |  | 
| 19 21 | 
             
              self.config ||= ConsulApplicationSettings::Configuration.new
         | 
    
        metadata
    CHANGED
    
    | @@ -1,15 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: consul_application_settings
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 4.0.0.pre.alpha
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Volodymyr Mykhailyk
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021- | 
| 11 | 
            +
            date: 2021-12-06 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: deep_merge
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.2'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.2'
         | 
| 13 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 28 | 
             
              name: diplomat
         | 
| 15 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -38,6 +52,20 @@ dependencies: | |
| 38 52 | 
             
                - - "~>"
         | 
| 39 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 54 | 
             
                    version: '2.0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: codecov
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - "~>"
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0.4'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - "~>"
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '0.4'
         | 
| 41 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 70 | 
             
              name: rake
         | 
| 43 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -109,19 +137,19 @@ dependencies: | |
| 109 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 138 | 
             
                    version: '0.16'
         | 
| 111 139 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            -
              name:  | 
| 140 | 
            +
              name: vault
         | 
| 113 141 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 142 | 
             
                requirements:
         | 
| 115 143 | 
             
                - - "~>"
         | 
| 116 144 | 
             
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            -
                    version: '0. | 
| 145 | 
            +
                    version: '0.16'
         | 
| 118 146 | 
             
              type: :development
         | 
| 119 147 | 
             
              prerelease: false
         | 
| 120 148 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 149 | 
             
                requirements:
         | 
| 122 150 | 
             
                - - "~>"
         | 
| 123 151 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            -
                    version: '0. | 
| 152 | 
            +
                    version: '0.16'
         | 
| 125 153 | 
             
            description: |-
         | 
| 126 154 | 
             
              Gem that simplifies usage of Consul (via Diplomat gem) to host application settings.
         | 
| 127 155 | 
             
                                    Gem provides defaults and utilities
         | 
| @@ -148,6 +176,7 @@ files: | |
| 148 176 | 
             
            - bin/rspec
         | 
| 149 177 | 
             
            - bin/setup
         | 
| 150 178 | 
             
            - consul_application_settings.gemspec
         | 
| 179 | 
            +
            - docker-compose.yml
         | 
| 151 180 | 
             
            - lib/consul_application_settings.rb
         | 
| 152 181 | 
             
            - lib/consul_application_settings/configuration.rb
         | 
| 153 182 | 
             
            - lib/consul_application_settings/providers/abstract.rb
         | 
| @@ -155,6 +184,10 @@ files: | |
| 155 184 | 
             
            - lib/consul_application_settings/providers/consul_preloaded.rb
         | 
| 156 185 | 
             
            - lib/consul_application_settings/providers/local_storage.rb
         | 
| 157 186 | 
             
            - lib/consul_application_settings/reader.rb
         | 
| 187 | 
            +
            - lib/consul_application_settings/resolvers/abstract.rb
         | 
| 188 | 
            +
            - lib/consul_application_settings/resolvers/env.rb
         | 
| 189 | 
            +
            - lib/consul_application_settings/resolvers/erb.rb
         | 
| 190 | 
            +
            - lib/consul_application_settings/resolvers/vault.rb
         | 
| 158 191 | 
             
            - lib/consul_application_settings/utils.rb
         | 
| 159 192 | 
             
            - lib/consul_application_settings/version.rb
         | 
| 160 193 | 
             
            homepage: https://github.com/matic-insurance/consul_application_settings
         | 
| @@ -175,9 +208,9 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 175 208 | 
             
                  version: '0'
         | 
| 176 209 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 177 210 | 
             
              requirements:
         | 
| 178 | 
            -
              - - " | 
| 211 | 
            +
              - - ">"
         | 
| 179 212 | 
             
                - !ruby/object:Gem::Version
         | 
| 180 | 
            -
                  version:  | 
| 213 | 
            +
                  version: 1.3.1
         | 
| 181 214 | 
             
            requirements: []
         | 
| 182 215 | 
             
            rubygems_version: 3.0.3.1
         | 
| 183 216 | 
             
            signing_key: 
         |