chambermaid 0.2.0 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ceb4e76a467a39e91b32a40efff57e8fe8d213e28ea38c9742569af98eac7e0f
4
- data.tar.gz: dfdb963dece1c57711fae828eaeebf53490ce2569f6fa339839d2c01a24787ca
3
+ metadata.gz: 5f6943ccaff6b33633d9cee801822d739f222b1eb86dd63b154ad0ee5139a252
4
+ data.tar.gz: 2a4bed5d0f0fe66048880f57e4ed1c7b62530bd1a6eabdc3227ea05e98528a4c
5
5
  SHA512:
6
- metadata.gz: 2997b5bf940b31802cb900d50b042820885da4209fff8e2231228994fbb3daf3efa4c979fb6a41f37a1512e3cea96440e3744b8ca2939dcd2543cc1287c1e960
7
- data.tar.gz: cc518b62b452ea0c63e83b04fd3535345ed335a671fffd6fba6c184addfdaa45a9f29553a825d55e97921598300675e1c054d496dd30a850ca520968170f15be
6
+ metadata.gz: a22085c2da52baec3bb93cd59f7cc524e3f87f974cfdf26a5f315eed7cb90002fdd315c3718aed15be0b6c253ec05fcab76137a86f96808dbc374eb205b948d3
7
+ data.tar.gz: 2991226e4b8fb1021b2369e4b449967ce5d925d6e66f7d56fa64cc2c1d0e051c4ea4640d674a87d17b325a01724aa13e4491c95789d08fdb25e76ce6d4f13274
data/Gemfile CHANGED
@@ -2,6 +2,3 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in chambermaid.gemspec
4
4
  gemspec
5
-
6
- gem "rake", "~> 12.0"
7
- gem "rspec", "~> 3.0"
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chambermaid (0.2.0)
4
+ chambermaid (0.4.1)
5
5
  aws-sdk-ssm (~> 1.85)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  aws-eventstream (1.1.0)
11
- aws-partitions (1.348.0)
11
+ aws-partitions (1.349.0)
12
12
  aws-sdk-core (3.104.3)
13
13
  aws-eventstream (~> 1, >= 1.0.2)
14
14
  aws-partitions (~> 1, >= 1.239.0)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Chambermaid
1
+ # Chambermaid [![Gem Version](https://badge.fury.io/rb/chambermaid.svg)](https://badge.fury.io/rb/chambermaid) [![Build Status](https://travis-ci.com/mileszim/chambermaid.svg?branch=master)](https://travis-ci.com/mileszim/chambermaid)
2
2
 
3
3
  Companion RubyGem for [chamber](https://github.com/segmentio/chamber).
4
4
 
@@ -26,6 +26,7 @@ Or install it yourself as:
26
26
 
27
27
  ```ruby
28
28
  Chambermaid.add_namespace("/my/param/namespace")
29
+ Chambermaid.add_service("my-chamber-service")
29
30
  ```
30
31
 
31
32
  **Configuration Block**
@@ -34,12 +35,24 @@ Chambermaid.add_namespace("/my/param/namespace")
34
35
  # config/initializers/chambermaid.rb
35
36
 
36
37
  Chambermaid.configure do |config|
38
+ # Load all values from SSM Namespace path
37
39
  config.add_namespace("/my/param/namespace")
38
40
 
41
+ # Load values from chamber-cli service
42
+ config.add_service("my-chamber-service")
43
+
39
44
  # Set `overload: true` to choose these params over existing
40
45
  # ones in ENV when they are merged together
41
46
  config.add_namespace("/my/important/namespace", overload: true)
42
47
  end
48
+
49
+ # Load after configuration
50
+ Chambermaid.load!
51
+ ```
52
+
53
+ **Reload SSM into ENV**
54
+ ```ruby
55
+ Chambermaid.reload!
43
56
  ```
44
57
 
45
58
  **Restore ENV to original state**
@@ -48,6 +61,24 @@ Chambermaid.restore!
48
61
  Chambermaid.reset! # alias of .restore!
49
62
  ```
50
63
 
64
+ **Configure Logging**
65
+ ```ruby
66
+ Chambermaid.configure do |config|
67
+ # ... other config ...
68
+
69
+ # Change log level
70
+ config.log_level = :debug
71
+
72
+ # Set custom logger instance
73
+ config.logger = MyCoolLogger.new
74
+ end
75
+
76
+ # Outside of config block
77
+ Chambermaid.log_level = :warn
78
+ ```
79
+
80
+ _Note: Chambermaid.logger is set to Rails.logger automatically if including inside a rails app_
81
+
51
82
  ## Development
52
83
 
53
84
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -28,4 +28,6 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  # Gems
30
30
  spec.add_dependency("aws-sdk-ssm", "~> 1.85")
31
+ spec.add_development_dependency("rspec", "~> 3.0")
32
+ spec.add_development_dependency("rake", "~> 12.0")
31
33
  end
@@ -1,5 +1,6 @@
1
1
  require "chambermaid/base"
2
2
  require "chambermaid/version"
3
+ require "chambermaid/railtie" if defined?(Rails)
3
4
 
4
5
  module Chambermaid
5
6
  class Error < StandardError; end
@@ -1,10 +1,14 @@
1
+ require "logger"
2
+
3
+ require "chambermaid/environment"
4
+ require "chambermaid/namespace"
1
5
  require "chambermaid/parameter_store"
2
6
 
3
7
  module Chambermaid
4
8
  module Base
5
9
  def self.extended(base)
6
10
  # Make a copy of ENV before we mess it all up
7
- @@_original_env = ENV.to_h.dup
11
+ @@_original_env = ENV.to_h.dup.freeze
8
12
  end
9
13
 
10
14
  extend self
@@ -18,16 +22,18 @@ module Chambermaid
18
22
  raise "Namespaces must be defined" unless @namespaces
19
23
  end
20
24
 
25
+ # Load SSM into ENV
26
+ def load!
27
+ @namespaces.each(&:load!)
28
+ end
29
+
21
30
  # @todo
22
31
  def reload!
23
- restore!
24
- @namespaces.each do |ns|
25
- ns[:store].reload!
26
- update_env!(
27
- params: ns[:store].params,
28
- overload: ns[:overload]
29
- )
30
- end
32
+ @namespaces.each(&:reload!)
33
+ end
34
+
35
+ def unload!
36
+ @namespaces.each(&:unload!)
31
37
  end
32
38
 
33
39
  # Restore ENV to its original state
@@ -43,30 +49,99 @@ module Chambermaid
43
49
  # true - replace any duplicate ENV keys with new params
44
50
  # false - keep any existing duplicate ENV key values
45
51
  #
46
- # @raise
52
+ # @raise [ArgumentError]
53
+ # when `path` is not a string
54
+ #
55
+ # @example
56
+ # Chambermaid.add_namespace("/my/param/namespace")
57
+ #
58
+ # @example overload duplicate ENV vars
59
+ # Chambermaid.add_namespace("/my/param/namespace", overload: true)
47
60
  def add_namespace(path, overload: false)
48
- @namespaces ||= []
49
- # raise "namespace already included in ENV" unless @namespaces[path].nil?
61
+ raise ArgumentError.new("`path` must be a string") unless path.is_a?(String)
62
+ raise ArgumentError.new("`overload` must be a boolean") unless [true, false].include?(overload)
63
+
64
+ namespaces << Namespace.new(path: path, overload: overload)
65
+ end
66
+
67
+ # Immediately load an AWS SSM parameter namespace to ENV
68
+ #
69
+ # @param [String] path
70
+ # @param [Boolean] overload
71
+ # true - replace any duplicate ENV keys with new params
72
+ # false - keep any existing duplicate ENV key values
73
+ #
74
+ # @raise [ArgumentError]
75
+ # when `path` is not a string
76
+ #
77
+ # @example
78
+ # Chambermaid.add_namespace!("/my/param/namespace")
79
+ #
80
+ # @example overload duplicate ENV vars
81
+ # Chambermaid.add_namespace("/my/param/namespace", overload: true)
82
+ def add_namespace!(path, overload: false)
83
+ raise ArgumentError.new("`path` must be a string") unless path.is_a?(String)
84
+ raise ArgumentError.new("`overload` must be a boolean") unless [true, false].include?(overload)
50
85
 
51
- store = ParameterStore.load!(path: path)
52
- @namespaces << { store: store, overload: overload }
53
- update_env!(params: store.params, overload: overload)
86
+ namespaces << Namespace.load!(path: path, overload: overload)
54
87
  end
55
88
 
56
- # Inject into ENV
89
+ # Add all secrets from Chamber service to ENV
57
90
  #
58
- # @param [Hash] params
91
+ # @param [String] service
59
92
  # @param [Boolean] overload
60
93
  # true - replace any duplicate ENV keys with new params
61
94
  # false - keep any existing duplicate ENV key values
62
- def update_env!(params:, overload:)
63
- if overload
64
- ENV.update(params)
65
- else
66
- current_env = ENV.to_h.dup
67
- new_env = params.merge(current_env)
68
- ENV.replace(new_env)
69
- end
95
+ #
96
+ # @example
97
+ # Chambermaid.add_service("my-chamber-service")
98
+ #
99
+ # @example overload duplicate ENV vars
100
+ # Chambermaid.add_service("my-chamber-service", overload: true)
101
+ #
102
+ # @see {Chambermaid::Base.add_namespace}
103
+ def add_service(service, overload: false)
104
+ service = "/#{service}" unless service[0] == "/"
105
+ add_namespace(service)
106
+ end
107
+
108
+ # !@attribute [r] logger
109
+ # @return [Logger]
110
+ def logger
111
+ @logger ||= Logger.new(STDOUT,
112
+ level: log_level,
113
+ progname: "Chambermaid"
114
+ )
115
+ end
116
+
117
+ # !@attribute [w] logger
118
+ # @return [Logger]
119
+ def logger=(val)
120
+ @logger = val
121
+ @logger.progname = "Chambermaid"
122
+ logger
123
+ end
124
+
125
+ # !@attribute [r] log_level
126
+ # @return [Symbol] (default = :info) current logger level
127
+ def log_level
128
+ return logger.level unless @logger.nil?
129
+ return @log_level unless @log_level.nil?
130
+ return :info
131
+ end
132
+
133
+ # !@attribute [w] log_level
134
+ # @return [Symbol] (default = :info) current logger level
135
+ def log_level=(val = :info)
136
+ @logger.level = val unless @logger.nil?
137
+ @log_level = val
138
+ val
139
+ end
140
+
141
+ private
142
+
143
+ def namespaces
144
+ @namespaces ||= []
70
145
  end
71
146
  end
72
147
  end
@@ -0,0 +1,68 @@
1
+ module Chambermaid
2
+ class Environment < Hash
3
+ attr_reader :params
4
+
5
+ # Create new Chambermaid::Environment
6
+ #
7
+ # @param [Hash] params
8
+ #
9
+ # @raise [ArgumentError]
10
+ # if params is not type Hash
11
+ #
12
+ # @return [Chambermaid::Environment]
13
+ def initialize(params)
14
+ validate_params!(params)
15
+ stash_current_env!
16
+ update(format_env(params))
17
+ end
18
+
19
+ # Generate a dotenv (.env) compatible string
20
+ #
21
+ # @return [String] dotenv compatible string
22
+ def to_dotenv
23
+ to_h.inject("") do |env_str, param|
24
+ env_str + "#{param[0]}=#{param[1]}\n"
25
+ end
26
+ end
27
+
28
+ # Write a .env file
29
+ #
30
+ # @param [String] file_path
31
+ def to_file!(file_path)
32
+ File.open(file_path, "wb") do |f|
33
+ f.write(to_dotenv)
34
+ end
35
+ end
36
+
37
+ # Inject into ENV without overwriting duplicates
38
+ def load!
39
+ each { |k, v| ENV[k] ||= v }
40
+ end
41
+
42
+ # Inject into ENV and overwrite duplicates
43
+ def overload!
44
+ each { |k, v| ENV[k] = v }
45
+ end
46
+
47
+ # Restore to original ENV
48
+ def unload!
49
+ ENV.replace(@_original_env)
50
+ end
51
+
52
+ private
53
+
54
+ def stash_current_env!
55
+ @_original_env ||= ENV.to_h.dup.freeze
56
+ end
57
+
58
+ def format_env(params)
59
+ params.map{|k,v| [k.upcase, v]}.to_h
60
+ end
61
+
62
+ def validate_params!(params)
63
+ unless params.is_a?(Hash)
64
+ raise ArgumentError.new("`params` must be a hash")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,44 @@
1
+ module Chambermaid
2
+ class Namespace
3
+ # @param [String] path
4
+ # @param [Boolean] overload
5
+ def initialize(path:, overload: false)
6
+ @path = path
7
+ @overload = overload
8
+
9
+ @store = ParameterStore.new(path: path)
10
+ @env = Environment.new({})
11
+ end
12
+
13
+ def self.load!(path:, overload: false)
14
+ namespace = new(path: path, overload: overload)
15
+ namespace.load!
16
+ namespace
17
+ end
18
+
19
+ def load!
20
+ @store.load!
21
+ load_env!
22
+ end
23
+
24
+ def reload!
25
+ @env.unload!
26
+ @store.reload!
27
+ load_env!
28
+ end
29
+
30
+ def unload!
31
+ @env.unload!
32
+ Chambermaid.logger.info("unloaded #{@env.size} params from ENV")
33
+ end
34
+
35
+ private
36
+
37
+ # Inject into ENV
38
+ def load_env!
39
+ @env.replace(@store.params)
40
+ @overload ? @env.overload! : @env.load!
41
+ Chambermaid.logger.info("loaded #{@env.size} params into ENV from `#{@path}`")
42
+ end
43
+ end
44
+ end
@@ -15,6 +15,10 @@ module Chambermaid
15
15
  fetch_ssm_params!
16
16
  end
17
17
 
18
+ def loaded?
19
+ !@params_list.empty?
20
+ end
21
+
18
22
  def self.load!(path:)
19
23
  store = new(path: path)
20
24
  store.load!
@@ -29,12 +33,6 @@ module Chambermaid
29
33
 
30
34
  alias :to_h :params
31
35
 
32
- def to_env
33
- params.inject("") do |env_str, param|
34
- env_str + "#{param[0]}=#{param[1]}\n"
35
- end
36
- end
37
-
38
36
  private
39
37
 
40
38
  def client
@@ -42,14 +40,20 @@ module Chambermaid
42
40
  end
43
41
 
44
42
  def fetch_ssm_params!
43
+ Chambermaid.logger.debug("fetching AWS SSM parameters from `#{@path}`")
45
44
  @param_list = []
46
45
  response = nil
47
46
  loop do
48
47
  response = fetch_ssm_param_batch!(response&.next_token)
49
48
  @param_list.concat(response.parameters)
50
49
 
51
- break unless response.next_token
50
+ if response.next_token
51
+ Chambermaid.logger.debug("response.next_token found, continuing fetch")
52
+ else
53
+ break
54
+ end
52
55
  end
56
+ Chambermaid.logger.debug("fetched #{@param_list.size} parameters from `#{@path}`")
53
57
  end
54
58
 
55
59
  def fetch_ssm_param_batch!(next_token = nil)
@@ -63,7 +67,7 @@ module Chambermaid
63
67
 
64
68
  def clear_params!
65
69
  @params = nil
66
- @params_list = nil
70
+ @params_list = []
67
71
  end
68
72
  end
69
73
  end
@@ -0,0 +1,8 @@
1
+ module Chambermaid
2
+ class Railtie < Rails::Railtie
3
+ config.after_initialize do
4
+ Chambermaid.logger = Rails.logger
5
+ Chambermaid.load!
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module Chambermaid
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chambermaid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Zimmerman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-01 00:00:00.000000000 Z
11
+ date: 2020-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-ssm
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.85'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
27
55
  description:
28
56
  email:
29
57
  - miles@asktrim.com
@@ -45,7 +73,10 @@ files:
45
73
  - chambermaid.gemspec
46
74
  - lib/chambermaid.rb
47
75
  - lib/chambermaid/base.rb
76
+ - lib/chambermaid/environment.rb
77
+ - lib/chambermaid/namespace.rb
48
78
  - lib/chambermaid/parameter_store.rb
79
+ - lib/chambermaid/railtie.rb
49
80
  - lib/chambermaid/version.rb
50
81
  homepage: https://github.com/mileszim/chambermaid
51
82
  licenses: