global 1.1.0 → 2.0.0
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/.rubocop.yml +29 -10
- data/.ruby-version +1 -1
- data/.travis.yml +4 -10
- data/CODE_OF_CONDUCT.md +74 -0
- data/README.md +217 -68
- data/bin/console +15 -0
- data/global.gemspec +5 -10
- data/lib/global.rb +1 -1
- data/lib/global/backend/aws_parameter_store.rb +110 -0
- data/lib/global/backend/filesystem.rb +88 -0
- data/lib/global/backend/gcp_secret_manager.rb +137 -0
- data/lib/global/base.rb +38 -84
- data/lib/global/configuration.rb +9 -2
- data/lib/global/version.rb +1 -1
- data/spec/global/backend/aws_parameter_store_spec.rb +48 -0
- data/spec/global/backend/gcp_secret_manager_spec.rb +39 -0
- data/spec/global_spec.rb +5 -35
- data/spec/merge_backends_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -2
- metadata +48 -29
- data/app/assets/javascripts/global-js.js.erb +0 -2
- data/lib/global/engine.rb +0 -84
- data/spec/global/global_js_spec.rb +0 -116
- data/spec/support/javascript_helper.rb +0 -27
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d82e24b3a7c94f65e370d1b16142e028d3acf1ce3fe8064e9e9fcb9e4683d46e
         | 
| 4 | 
            +
              data.tar.gz: 809e1b6ac4e2f0ada443202b1d80ec7d663488515f682079cd07bc02335983c4
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b290b4951da9d199d64ec8a27bdf630be5691ec1af0829d31e01872c1260893e2a3626fcc55a70f9ac816192279fbf04a4a2823dd770127808bd63b62ad8016d
         | 
| 7 | 
            +
              data.tar.gz: afa4586a51919a0d483dbcd01e5fd027cd6a79aebaea070c544c53f4838ccbbece9312536d40ed475adf1cc207ef7864937639baa60de7bab1918de3a081944a
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            Metrics/MethodLength:
         | 
| 2 | 
            +
              Enabled: true
         | 
| 3 | 
            +
              Max: 11
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            Layout/EmptyLinesAroundBlockBody:
         | 
| 2 6 | 
             
              Enabled: false
         | 
| 3 7 |  | 
| @@ -29,10 +33,16 @@ Layout/MultilineMethodCallIndentation: | |
| 29 33 | 
             
              Enabled: true
         | 
| 30 34 | 
             
              EnforcedStyle: indented
         | 
| 31 35 |  | 
| 32 | 
            -
            Layout/ | 
| 36 | 
            +
            Layout/HashAlignment:
         | 
| 33 37 | 
             
              Enabled: true
         | 
| 34 38 | 
             
              EnforcedLastArgumentHashStyle: always_ignore
         | 
| 35 39 |  | 
| 40 | 
            +
            Lint/RaiseException:
         | 
| 41 | 
            +
              Enabled: true
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            Lint/StructNewOverride:
         | 
| 44 | 
            +
              Enabled: true
         | 
| 45 | 
            +
             | 
| 36 46 | 
             
            Style/RaiseArgs:
         | 
| 37 47 | 
             
              EnforcedStyle: compact
         | 
| 38 48 |  | 
| @@ -43,12 +53,21 @@ Style/FrozenStringLiteralComment: | |
| 43 53 | 
             
              Enabled: true
         | 
| 44 54 | 
             
              EnforcedStyle: always
         | 
| 45 55 |  | 
| 56 | 
            +
            Style/HashEachMethods:
         | 
| 57 | 
            +
              Enabled: true
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            Style/HashTransformKeys:
         | 
| 60 | 
            +
              Enabled: true
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            Style/HashTransformValues:
         | 
| 63 | 
            +
              Enabled: true
         | 
| 64 | 
            +
             | 
| 46 65 | 
             
            Style/RegexpLiteral:
         | 
| 47 66 | 
             
              Enabled: true
         | 
| 48 67 | 
             
              EnforcedStyle: slashes
         | 
| 49 68 | 
             
              AllowInnerSlashes: false
         | 
| 50 69 |  | 
| 51 | 
            -
            Layout/ | 
| 70 | 
            +
            Layout/FirstHashElementIndentation:
         | 
| 52 71 | 
             
              EnforcedStyle: consistent
         | 
| 53 72 |  | 
| 54 73 | 
             
            Style/Documentation:
         | 
| @@ -56,36 +75,36 @@ Style/Documentation: | |
| 56 75 |  | 
| 57 76 | 
             
            Style/SafeNavigation:
         | 
| 58 77 | 
             
              Enabled: true
         | 
| 59 | 
            -
               | 
| 78 | 
            +
              AllowedMethods:
         | 
| 60 79 | 
             
                - present?
         | 
| 61 80 | 
             
                - blank?
         | 
| 62 81 | 
             
                - presence
         | 
| 63 82 |  | 
| 64 83 | 
             
            Lint/AmbiguousBlockAssociation:
         | 
| 65 84 | 
             
              Exclude:
         | 
| 66 | 
            -
                -  | 
| 85 | 
            +
                - "spec/**/*"
         | 
| 67 86 |  | 
| 68 87 | 
             
            Naming/PredicateName:
         | 
| 69 88 | 
             
              Exclude:
         | 
| 70 | 
            -
                -  | 
| 89 | 
            +
                - "spec/**/*"
         | 
| 71 90 |  | 
| 72 91 | 
             
            Style/NumericPredicate:
         | 
| 73 92 | 
             
              Exclude:
         | 
| 74 | 
            -
                -  | 
| 93 | 
            +
                - "spec/**/*"
         | 
| 75 94 |  | 
| 76 95 | 
             
            Metrics/BlockLength:
         | 
| 77 96 | 
             
              Exclude:
         | 
| 78 | 
            -
                -  | 
| 97 | 
            +
                - "spec/**/*"
         | 
| 79 98 |  | 
| 80 | 
            -
             | 
| 99 | 
            +
            Layout/LineLength:
         | 
| 81 100 | 
             
              Max: 120
         | 
| 82 101 | 
             
              Exclude:
         | 
| 83 | 
            -
                -  | 
| 102 | 
            +
                - "spec/**/*"
         | 
| 84 103 |  | 
| 85 104 | 
             
            Metrics/AbcSize:
         | 
| 86 105 | 
             
              Max: 22
         | 
| 87 106 | 
             
              Exclude:
         | 
| 88 | 
            -
                -  | 
| 107 | 
            +
                - "spec/**/*"
         | 
| 89 108 |  | 
| 90 109 | 
             
            Style/ModuleFunction:
         | 
| 91 110 | 
             
              EnforcedStyle: extend_self
         | 
    
        data/.ruby-version
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            2. | 
| 1 | 
            +
            2.6.6
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -1,27 +1,21 @@ | |
| 1 1 | 
             
            language: ruby
         | 
| 2 | 
            +
            os: linux
         | 
| 3 | 
            +
            dist: bionic
         | 
| 2 4 |  | 
| 3 5 | 
             
            cache:
         | 
| 4 6 | 
             
              bundler: true
         | 
| 5 7 |  | 
| 6 8 | 
             
            rvm:
         | 
| 7 | 
            -
              - 2.2
         | 
| 8 | 
            -
              - 2.3
         | 
| 9 9 | 
             
              - 2.4
         | 
| 10 10 | 
             
              - 2.5
         | 
| 11 | 
            -
              -  | 
| 11 | 
            +
              - 2.6
         | 
| 12 | 
            +
              - 2.7
         | 
| 12 13 | 
             
              - ruby-head
         | 
| 13 14 | 
             
              - jruby-head
         | 
| 14 15 |  | 
| 15 16 | 
             
            notifications:
         | 
| 16 17 | 
             
              email: false
         | 
| 17 18 |  | 
| 18 | 
            -
            sudo: false
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            branches:
         | 
| 21 | 
            -
              only:
         | 
| 22 | 
            -
                - master
         | 
| 23 | 
            -
                - development
         | 
| 24 | 
            -
             | 
| 25 19 | 
             
            matrix:
         | 
| 26 20 | 
             
              allow_failures:
         | 
| 27 21 | 
             
                - rvm: ruby-head
         | 
    
        data/CODE_OF_CONDUCT.md
    ADDED
    
    | @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            # Contributor Covenant Code of Conduct
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Our Pledge
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            In the interest of fostering an open and welcoming environment, we as
         | 
| 6 | 
            +
            contributors and maintainers pledge to making participation in our project and
         | 
| 7 | 
            +
            our community a harassment-free experience for everyone, regardless of age, body
         | 
| 8 | 
            +
            size, disability, ethnicity, gender identity and expression, level of experience,
         | 
| 9 | 
            +
            nationality, personal appearance, race, religion, or sexual identity and
         | 
| 10 | 
            +
            orientation.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ## Our Standards
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Examples of behavior that contributes to creating a positive environment
         | 
| 15 | 
            +
            include:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            * Using welcoming and inclusive language
         | 
| 18 | 
            +
            * Being respectful of differing viewpoints and experiences
         | 
| 19 | 
            +
            * Gracefully accepting constructive criticism
         | 
| 20 | 
            +
            * Focusing on what is best for the community
         | 
| 21 | 
            +
            * Showing empathy towards other community members
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            Examples of unacceptable behavior by participants include:
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            * The use of sexualized language or imagery and unwelcome sexual attention or
         | 
| 26 | 
            +
            advances
         | 
| 27 | 
            +
            * Trolling, insulting/derogatory comments, and personal or political attacks
         | 
| 28 | 
            +
            * Public or private harassment
         | 
| 29 | 
            +
            * Publishing others' private information, such as a physical or electronic
         | 
| 30 | 
            +
              address, without explicit permission
         | 
| 31 | 
            +
            * Other conduct which could reasonably be considered inappropriate in a
         | 
| 32 | 
            +
              professional setting
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ## Our Responsibilities
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            Project maintainers are responsible for clarifying the standards of acceptable
         | 
| 37 | 
            +
            behavior and are expected to take appropriate and fair corrective action in
         | 
| 38 | 
            +
            response to any instances of unacceptable behavior.
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            Project maintainers have the right and responsibility to remove, edit, or
         | 
| 41 | 
            +
            reject comments, commits, code, wiki edits, issues, and other contributions
         | 
| 42 | 
            +
            that are not aligned to this Code of Conduct, or to ban temporarily or
         | 
| 43 | 
            +
            permanently any contributor for other behaviors that they deem inappropriate,
         | 
| 44 | 
            +
            threatening, offensive, or harmful.
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            ## Scope
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            This Code of Conduct applies both within project spaces and in public spaces
         | 
| 49 | 
            +
            when an individual is representing the project or its community. Examples of
         | 
| 50 | 
            +
            representing a project or community include using an official project e-mail
         | 
| 51 | 
            +
            address, posting via an official social media account, or acting as an appointed
         | 
| 52 | 
            +
            representative at an online or offline event. Representation of a project may be
         | 
| 53 | 
            +
            further defined and clarified by project maintainers.
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            ## Enforcement
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            Instances of abusive, harassing, or otherwise unacceptable behavior may be
         | 
| 58 | 
            +
            reported by contacting the project team at leopard.not.a@gmail.com. All
         | 
| 59 | 
            +
            complaints will be reviewed and investigated and will result in a response that
         | 
| 60 | 
            +
            is deemed necessary and appropriate to the circumstances. The project team is
         | 
| 61 | 
            +
            obligated to maintain confidentiality with regard to the reporter of an incident.
         | 
| 62 | 
            +
            Further details of specific enforcement policies may be posted separately.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            Project maintainers who do not follow or enforce the Code of Conduct in good
         | 
| 65 | 
            +
            faith may face temporary or permanent repercussions as determined by other
         | 
| 66 | 
            +
            members of the project's leadership.
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            ## Attribution
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
         | 
| 71 | 
            +
            available at [https://contributor-covenant.org/version/1/4][version]
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            [homepage]: https://contributor-covenant.org
         | 
| 74 | 
            +
            [version]: https://contributor-covenant.org/version/1/4/
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            # Global [](https://travis-ci.org/railsware/global) [](https://codeclimate.com/github/railsware/global)
         | 
| 2 2 |  | 
| 3 | 
            -
            The 'global' gem provides accessor methods for your configuration data and share configuration across backend and frontend. | 
| 3 | 
            +
            The 'global' gem provides accessor methods for your configuration data and share configuration across backend and frontend.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            The data can be stored in [YAML](https://yaml.org) files on disk, or in the [AWS SSM Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html).
         | 
| 4 6 |  | 
| 5 7 | 
             
            ## Installation
         | 
| 6 8 |  | 
| @@ -10,41 +12,73 @@ Add to Gemfile: | |
| 10 12 | 
             
            gem 'global'
         | 
| 11 13 | 
             
            ```
         | 
| 12 14 |  | 
| 15 | 
            +
            Refer to the documentation on your chosen backend class for other dependencies.
         | 
| 16 | 
            +
             | 
| 13 17 | 
             
            ## Configuration
         | 
| 14 18 |  | 
| 19 | 
            +
            Refer to the documentation on your chosen backend class for configuration options.
         | 
| 20 | 
            +
             | 
| 15 21 | 
             
            ```ruby
         | 
| 16 | 
            -
            > Global.environment  | 
| 17 | 
            -
            > Global.config_directory = "PATH_TO_DIRECTORY_WITH_FILES"
         | 
| 18 | 
            -
            > Global.yaml_whitelist_classes = [] # optional configuration
         | 
| 22 | 
            +
            > Global.backend(:filesystem, environment: "YOUR_ENV_HERE", directory: "PATH_TO_DIRECTORY_WITH_FILES")
         | 
| 19 23 | 
             
            ```
         | 
| 20 24 |  | 
| 21 25 | 
             
            Or you can use `configure` block:
         | 
| 22 26 |  | 
| 23 27 | 
             
            ```ruby
         | 
| 24 28 | 
             
            Global.configure do |config|
         | 
| 25 | 
            -
              config.environment  | 
| 26 | 
            -
               | 
| 27 | 
            -
              config. | 
| 29 | 
            +
              config.backend :filesystem, environment: "YOUR_ENV_HERE", directory: "PATH_TO_DIRECTORY_WITH_FILES"
         | 
| 30 | 
            +
              # set up multiple backends and have them merged together:
         | 
| 31 | 
            +
              config.backend :aws_parameter_store, prefix: '/prod/MyApp/'
         | 
| 32 | 
            +
              config.backend :gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example'
         | 
| 28 33 | 
             
            end
         | 
| 29 34 | 
             
            ```
         | 
| 30 35 |  | 
| 31 | 
            -
             | 
| 36 | 
            +
            ### Using multiple backends
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            Sometimes it is practical to store some configuration data on disk (and perhaps, commit it to source control), but
         | 
| 39 | 
            +
            keep some other data in a secure remote location. Which is why you can use more than one backend with Global.
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            You can declare as many backends as you want; the configuration trees from the backends are deep-merged together,
         | 
| 42 | 
            +
            so that the backend declared later overwrites specific keys in the backend declared prior:
         | 
| 32 43 |  | 
| 33 44 | 
             
            ```ruby
         | 
| 34 45 | 
             
            Global.configure do |config|
         | 
| 35 | 
            -
              config. | 
| 36 | 
            -
              config. | 
| 37 | 
            -
              config.yaml_whitelist_classes = [] # optional configuration
         | 
| 46 | 
            +
              config.backend :foo # loads tree { credentials: { hostname: 'api.com', username: 'dev', password: 'dev' } }
         | 
| 47 | 
            +
              config.backend :bar # loads tree { credentials: { username: 'xxx', password: 'yyy' } }
         | 
| 38 48 | 
             
            end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            Global.credentials.hostname # => 'api.com'
         | 
| 51 | 
            +
            Global.credentials.username # => 'xxx'
         | 
| 52 | 
            +
            Global.credentials.password # => 'yyy'
         | 
| 39 53 | 
             
            ```
         | 
| 40 54 |  | 
| 55 | 
            +
            For Rails, put initialization into `config/initializers/global.rb`.
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            There are some sensible defaults, check your backend class for documentation.
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            ```ruby
         | 
| 60 | 
            +
            Global.configure do |config|
         | 
| 61 | 
            +
              config.backend :filesystem
         | 
| 62 | 
            +
            end
         | 
| 63 | 
            +
            ```
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            ### Filesystem storage
         | 
| 66 | 
            +
             | 
| 41 67 | 
             
            The `yaml_whitelist_classes` configuration allows you to deserialize other classes from your `.yml`
         | 
| 42 68 |  | 
| 69 | 
            +
            ### AWS Parameter Store
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            The `aws_options` configuration allows you to customize the AWS credentials and connection.
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            ### Google Cloud Secret Manager
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            The `gcp_options` configuration allows you to customize the Google Cloud credentials and timeout.
         | 
| 76 | 
            +
             | 
| 43 77 | 
             
            ## Usage
         | 
| 44 78 |  | 
| 45 | 
            -
            ###  | 
| 79 | 
            +
            ### Filesystem
         | 
| 46 80 |  | 
| 47 | 
            -
             | 
| 81 | 
            +
            For file `config/global/hosts.yml`:
         | 
| 48 82 |  | 
| 49 83 | 
             
            ```yml
         | 
| 50 84 | 
             
            test:
         | 
| @@ -84,9 +118,11 @@ Global.validations.regexp.email === 'mail@example.com' | |
| 84 118 | 
             
            => true
         | 
| 85 119 | 
             
            ```
         | 
| 86 120 |  | 
| 87 | 
            -
             | 
| 121 | 
            +
            #### Per-environment sections
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            You can define environment sections at the top level of every individual YAML file
         | 
| 88 124 |  | 
| 89 | 
            -
             | 
| 125 | 
            +
            For example, having a config file `config/global/web/basic_auth.yml` with:
         | 
| 90 126 |  | 
| 91 127 | 
             
            ```yml
         | 
| 92 128 | 
             
            test:
         | 
| @@ -100,7 +136,7 @@ production: | |
| 100 136 | 
             
              password: supersecret
         | 
| 101 137 | 
             
            ```
         | 
| 102 138 |  | 
| 103 | 
            -
             | 
| 139 | 
            +
            You get the correct configuration in development
         | 
| 104 140 |  | 
| 105 141 | 
             
            ```ruby
         | 
| 106 142 | 
             
            > Global.web.basic_auth
         | 
| @@ -109,7 +145,7 @@ After that in development environment we have: | |
| 109 145 | 
             
            => "development_user"
         | 
| 110 146 | 
             
            ```
         | 
| 111 147 |  | 
| 112 | 
            -
             | 
| 148 | 
            +
            #### Default section
         | 
| 113 149 |  | 
| 114 150 | 
             
            Config file example:
         | 
| 115 151 |  | 
| @@ -124,9 +160,10 @@ production: | |
| 124 160 |  | 
| 125 161 | 
             
            Data from the default section is used until it's overridden in a specific environment.
         | 
| 126 162 |  | 
| 127 | 
            -
             | 
| 163 | 
            +
            #### Nested configurations
         | 
| 128 164 |  | 
| 129 165 | 
             
            Config file `global/nested.yml` with:
         | 
| 166 | 
            +
             | 
| 130 167 | 
             
            ```yml
         | 
| 131 168 | 
             
            test:
         | 
| 132 169 | 
             
              group:
         | 
| @@ -146,7 +183,7 @@ Nested options can then be accessed as follows: | |
| 146 183 | 
             
            => "development value"
         | 
| 147 184 | 
             
            ```
         | 
| 148 185 |  | 
| 149 | 
            -
             | 
| 186 | 
            +
            #### Environment files
         | 
| 150 187 |  | 
| 151 188 | 
             
            Config file `global/aws.yml` with:
         | 
| 152 189 | 
             
            ```yml
         | 
| @@ -180,7 +217,7 @@ Provide such configuration on `Global.environment = 'production'` environment: | |
| 180 217 |  | 
| 181 218 | 
             
            **Warning**: files with dot(s) in name will be skipped by Global (except this env files).
         | 
| 182 219 |  | 
| 183 | 
            -
             | 
| 220 | 
            +
            #### ERB support
         | 
| 184 221 |  | 
| 185 222 | 
             
            Config file `global/file_name.yml` with:
         | 
| 186 223 |  | 
| @@ -200,79 +237,185 @@ As a result, in the development environment we have: | |
| 200 237 | 
             
            => 4
         | 
| 201 238 | 
             
            ```
         | 
| 202 239 |  | 
| 203 | 
            -
            ###  | 
| 240 | 
            +
            ### AWS Parameter Store
         | 
| 241 | 
            +
             | 
| 242 | 
            +
            Parameter Store is a secure configuration storage with at-rest encryption. Access is controlled through AWS IAM. You do not need to be hosted on AWS to use Parameter Store.
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            Refer to the [official documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) to set up the store.
         | 
| 245 | 
            +
             | 
| 246 | 
            +
            Some steps you will need to follow:
         | 
| 247 | 
            +
             | 
| 248 | 
            +
            - Allocate an AWS IAM role for your app.
         | 
| 249 | 
            +
            - Create an IAM user for the role and pass credentials in standard AWS env vars (applications on Fargate get roles automatically).
         | 
| 250 | 
            +
            - Choose a prefix for the parameters. By default, the prefix is `/environment_name/AppClassName/`. You can change it with backend parameters (prefer to use '/' as separator).
         | 
| 251 | 
            +
            - Allow the role to read parameters from AWS SSM. Scope access by the prefix that you're going to use.
         | 
| 252 | 
            +
            - If you will use encrypted parameters: create a KMS key and allow the role to decrypt using the key.
         | 
| 253 | 
            +
            - Create parameters in Parameter Store. Use encryption for sensitive data like private keys and API credentials.
         | 
| 254 | 
            +
             | 
| 255 | 
            +
            #### Configuration examples
         | 
| 256 | 
            +
             | 
| 257 | 
            +
            Backend setup:
         | 
| 204 258 |  | 
| 205 259 | 
             
            ```ruby
         | 
| 206 | 
            -
             | 
| 260 | 
            +
            # in config/environments/development.rb
         | 
| 261 | 
            +
            # you don't need to go to Parameter Store for dev machines
         | 
| 262 | 
            +
            Global.backend(:filesystem)
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            # in config/environments/production.rb
         | 
| 265 | 
            +
            # enterprise grade protection for your secrets
         | 
| 266 | 
            +
            Global.backend(:aws_parameter_store, app_name: 'my_big_app')
         | 
| 207 267 | 
             
            ```
         | 
| 208 268 |  | 
| 209 | 
            -
             | 
| 269 | 
            +
            Create parameters:
         | 
| 210 270 |  | 
| 211 | 
            -
             | 
| 271 | 
            +
            ```
         | 
| 272 | 
            +
            /production/my_big_app/basic_auth/username => "bill"
         | 
| 273 | 
            +
            /production/my_big_app/basic_auth/password => "secret" # make sure to encrypt this one!
         | 
| 274 | 
            +
            /production/my_big_app/api_endpoint => "https://api.myapp.com"
         | 
| 275 | 
            +
            ```
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            Get configuration in the app:
         | 
| 212 278 |  | 
| 213 279 | 
             
            ```ruby
         | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
             | 
| 280 | 
            +
            # Encrypted parameters are automatically decrypted:
         | 
| 281 | 
            +
            > Global.basic_auth.password
         | 
| 282 | 
            +
            => "secret"
         | 
| 283 | 
            +
            > Global.api_endpoint
         | 
| 284 | 
            +
            => "https://api.myapp.com"
         | 
| 219 285 | 
             
            ```
         | 
| 220 | 
            -
            By default all files are excluded due to security reasons. Don't include files which contain protected information like api keys or credentials.
         | 
| 221 286 |  | 
| 222 | 
            -
             | 
| 287 | 
            +
            ### Google Cloud Secret Manager
         | 
| 223 288 |  | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 289 | 
            +
            Google Cloud Secret Manager allows you to store, manage, and access secrets as binary blobs or text strings. With the appropriate permissions, you can view the contents of the secret.
         | 
| 290 | 
            +
            Google Cloud Secret Manager works well for storing configuration information such as database passwords, API keys, or TLS certificates needed by an application at runtime.
         | 
| 291 | 
            +
             | 
| 292 | 
            +
            Refer to the [official documentation](https://cloud.google.com/secret-manager/docs) to set up the secret manager.
         | 
| 293 | 
            +
             | 
| 294 | 
            +
            Some steps you will need to follow:
         | 
| 229 295 |  | 
| 230 | 
            -
             | 
| 296 | 
            +
            - Choose a prefix for the secret key name. By default, the prefix is `environment_name-AppClassName-`. You can change it with backend parameters (prefer to use '-' as separator).
         | 
| 231 297 |  | 
| 232 | 
            -
             | 
| 298 | 
            +
            #### Configuration examples
         | 
| 233 299 |  | 
| 234 | 
            -
             | 
| 300 | 
            +
            Backend setup:
         | 
| 235 301 |  | 
| 236 | 
            -
            ``` | 
| 237 | 
            -
            #  | 
| 238 | 
            -
             | 
| 302 | 
            +
            ```ruby
         | 
| 303 | 
            +
            # in config/environments/development.rb
         | 
| 304 | 
            +
            # you don't need to go to Parameter Store for dev machines
         | 
| 305 | 
            +
            Global.backend(:filesystem)
         | 
| 239 306 |  | 
| 240 | 
            -
            #  | 
| 241 | 
            -
             | 
| 307 | 
            +
            # in config/environments/production.rb
         | 
| 308 | 
            +
            # enterprise grade protection for your secrets
         | 
| 309 | 
            +
            Global.backend(:gcp_secret_manager, prefix: 'prod-myapp-', project_id: 'example')
         | 
| 242 310 | 
             
            ```
         | 
| 243 311 |  | 
| 244 | 
            -
             | 
| 245 | 
            -
            # app/assets/javascripts/application/global.js.erb
         | 
| 246 | 
            -
            <%= Global.generate_js(namespace: "AppSettings", except: %w(admin credentials)) %>
         | 
| 312 | 
            +
            Create secrets:
         | 
| 247 313 |  | 
| 248 | 
            -
             | 
| 249 | 
            -
             | 
| 314 | 
            +
            ```
         | 
| 315 | 
            +
            prod-myapp-basic_auth-username => "bill"
         | 
| 316 | 
            +
            prod-myapp-basic_auth-password => "secret"
         | 
| 317 | 
            +
            prod-myapp-api_endpoint => "https://api.myapp.com"
         | 
| 250 318 | 
             
            ```
         | 
| 251 319 |  | 
| 252 | 
            -
             | 
| 320 | 
            +
            Get configuration in the app:
         | 
| 253 321 |  | 
| 254 | 
            -
             | 
| 322 | 
            +
            ```ruby
         | 
| 323 | 
            +
            # Encrypted parameters are automatically decrypted:
         | 
| 324 | 
            +
            > Global.basic_auth.password
         | 
| 325 | 
            +
            => "secret"
         | 
| 326 | 
            +
            > Global.api_endpoint
         | 
| 327 | 
            +
            => "https://api.myapp.com"
         | 
| 328 | 
            +
            ```
         | 
| 255 329 |  | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 258 | 
            -
             | 
| 259 | 
            -
             | 
| 260 | 
            -
            production:
         | 
| 261 | 
            -
              web: myhost.com
         | 
| 262 | 
            -
              api: api.myhost.com
         | 
| 330 | 
            +
            ### Reload configuration data
         | 
| 331 | 
            +
             | 
| 332 | 
            +
            ```ruby
         | 
| 333 | 
            +
            > Global.reload!
         | 
| 263 334 | 
             
            ```
         | 
| 264 | 
            -
            After that in development environment we have:
         | 
| 265 335 |  | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 336 | 
            +
            ## Using YAML configuration files with Rails Webpacker
         | 
| 337 | 
            +
             | 
| 338 | 
            +
            If you use the `:filesystem` backend, you can reuse the same configuration files on the frontend:
         | 
| 339 | 
            +
             | 
| 340 | 
            +
            Add [js-yaml](https://www.npmjs.com/package/js-yaml) npm package to `package.json` (use command `yarn add js-yaml`).
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            Then create a file at `config/webpacker/global/index.js` with the following:
         | 
| 343 | 
            +
             | 
| 344 | 
            +
            ```js
         | 
| 345 | 
            +
            const yaml = require('js-yaml')
         | 
| 346 | 
            +
            const fs = require('fs')
         | 
| 347 | 
            +
            const path = require('path')
         | 
| 348 | 
            +
             | 
| 349 | 
            +
            const FILE_ENV_SPLIT = '.'
         | 
| 350 | 
            +
            const YAML_EXT = '.yml'
         | 
| 351 | 
            +
             | 
| 352 | 
            +
            let globalConfig = {
         | 
| 353 | 
            +
              environment: null,
         | 
| 354 | 
            +
              configDirectory: null
         | 
| 355 | 
            +
            }
         | 
| 356 | 
            +
             | 
| 357 | 
            +
            const globalConfigure = (options = {}) => {
         | 
| 358 | 
            +
              globalConfig = Object.assign({}, globalConfig, options)
         | 
| 359 | 
            +
            }
         | 
| 360 | 
            +
             | 
| 361 | 
            +
            const getGlobalConfig = (key) => {
         | 
| 362 | 
            +
              let config = {}
         | 
| 363 | 
            +
              const filename = path.join(globalConfig.configDirectory, `${key}${YAML_EXT}`)
         | 
| 364 | 
            +
              if (fs.existsSync(filename)) {
         | 
| 365 | 
            +
                const configurations = yaml.safeLoad(fs.readFileSync(filename, 'utf8'))
         | 
| 366 | 
            +
                config = Object.assign({}, config, configurations['default'] || {})
         | 
| 367 | 
            +
                config = Object.assign({}, config, configurations[globalConfig.environment] || {})
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                const envFilename = path.join(globalConfig.configDirectory, `${key}${FILE_ENV_SPLIT}${globalConfig.environment}${YAML_EXT}`)
         | 
| 370 | 
            +
                if (fs.existsSync(envFilename)) {
         | 
| 371 | 
            +
                  const envConfigurations = yaml.safeLoad(fs.readFileSync(envFilename, 'utf8'))
         | 
| 372 | 
            +
                  config = Object.assign({}, config, envConfigurations || {})
         | 
| 373 | 
            +
                }
         | 
| 374 | 
            +
              }
         | 
| 375 | 
            +
              return config
         | 
| 376 | 
            +
            }
         | 
| 377 | 
            +
             | 
| 378 | 
            +
            module.exports = {
         | 
| 379 | 
            +
              globalConfigure,
         | 
| 380 | 
            +
              getGlobalConfig
         | 
| 381 | 
            +
            }
         | 
| 382 | 
            +
            ```
         | 
| 383 | 
            +
             | 
| 384 | 
            +
            After this, modify file `config/webpacker/environment.js`:
         | 
| 385 | 
            +
             | 
| 386 | 
            +
            ```js
         | 
| 387 | 
            +
            const path = require('path')
         | 
| 388 | 
            +
            const {environment} = require('@rails/webpacker')
         | 
| 389 | 
            +
            const {globalConfigure, getGlobalConfig} = require('./global')
         | 
| 390 | 
            +
             | 
| 391 | 
            +
            globalConfigure({
         | 
| 392 | 
            +
              environment: process.env.RAILS_ENV || 'development',
         | 
| 393 | 
            +
              configDirectory: path.resolve(__dirname, '../global')
         | 
| 394 | 
            +
            })
         | 
| 395 | 
            +
             | 
| 396 | 
            +
            const sentrySettings = getGlobalConfig('sentry')
         | 
| 397 | 
            +
             | 
| 398 | 
            +
            environment.plugins.prepend('Environment', new webpack.EnvironmentPlugin({
         | 
| 399 | 
            +
              GLOBAL_SENTRY_ENABLED: sentrySettings.enabled,
         | 
| 400 | 
            +
              GLOBAL_SENTRY_JS_KEY: sentrySettings.js,
         | 
| 401 | 
            +
              ...
         | 
| 402 | 
            +
            }))
         | 
| 403 | 
            +
             | 
| 404 | 
            +
            ...
         | 
| 405 | 
            +
             | 
| 406 | 
            +
            module.exports = environment
         | 
| 269 407 | 
             
            ```
         | 
| 270 408 |  | 
| 271 | 
            -
             | 
| 409 | 
            +
            Now you can use these `process.env` keys in your code:
         | 
| 272 410 |  | 
| 273 | 
            -
            ``` | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 411 | 
            +
            ```js
         | 
| 412 | 
            +
            import {init} from '@sentry/browser'
         | 
| 413 | 
            +
             | 
| 414 | 
            +
            if (process.env.GLOBAL_SENTRY_ENABLED) {
         | 
| 415 | 
            +
              init({
         | 
| 416 | 
            +
                dsn: process.env.GLOBAL_SENTRY_JS_KEY
         | 
| 417 | 
            +
              })
         | 
| 418 | 
            +
            }
         | 
| 276 419 | 
             
            ```
         | 
| 277 420 |  | 
| 278 421 | 
             
            ## Contributing to global
         | 
| @@ -285,6 +428,12 @@ Global.hosts.web | |
| 285 428 | 
             
            * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
         | 
| 286 429 | 
             
            * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
         | 
| 287 430 |  | 
| 288 | 
            -
             | 
| 431 | 
            +
            This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/railsware/global/blob/master/CODE_OF_CONDUCT.md).
         | 
| 432 | 
            +
             | 
| 433 | 
            +
            ## License
         | 
| 434 | 
            +
             | 
| 435 | 
            +
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         | 
| 436 | 
            +
             | 
| 437 | 
            +
            ## Code of Conduct
         | 
| 289 438 |  | 
| 290 | 
            -
             | 
| 439 | 
            +
            Everyone interacting in the Global project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/railsware/global/blob/master/CODE_OF_CONDUCT.md).
         |