chambermaid 0.2.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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: