chambermaid 0.1.0 → 0.4.0

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: 96de691a190b68ff6d24e2410f1191ac0f3ef29c534de37ae73b7e7a7f4d8530
4
- data.tar.gz: 16b2fb406a93c823bba30938594294fdcad94a1588718327c57b1d10fddf7f0a
3
+ metadata.gz: 7205cca8ffd4e9f7b2e20eb02239fd42be4f9dcdbd7c85eafb2e74c000d39be6
4
+ data.tar.gz: a1b394c7dd79578e738defb6657276aa6988185d432153f900dab3b2bfeda97d
5
5
  SHA512:
6
- metadata.gz: 4d73421e3cdac6a8e835b745df14a2fe012f4785183e4cc28c4222358553a8ac29a12f5e7cd256af7d7bf2bfcbf5bf8cf2783d089dbb09e435d07f717a359269
7
- data.tar.gz: 7d7a11dbb825742c23bd9a1d8b2ac10cabb44c92b66d6fea40ae828c01862611d97b5422efafd3f57f9c5826e39648240eb389f69d9d98acf0635118908c266a
6
+ metadata.gz: 4ef58ed041bd944a89d06a72c4b4f71dfe7695ef86aa4c2a28edf6d32d6a8b46122c1bfe7b1f6461cf9199dfbe73cfcf9fadd7ee101b54f0e86be5d36cd76c9d
7
+ data.tar.gz: 9cb1b2f1781b2903a9af7121e7720a8c2f875a28472f8d0ded8b455560262917f2fec5e0cb8584886257de8141fabc90ca7d244d86435004b9c1377a121d4ee2
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.1.0)
4
+ chambermaid (0.4.0)
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,14 +35,50 @@ 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
 
39
- # Set `overwrite_duplicates: true` to choose these params over existing
41
+ # Load values from chamber-cli service
42
+ config.add_service("my-chamber-service")
43
+
44
+ # Set `overload: true` to choose these params over existing
40
45
  # ones in ENV when they are merged together
41
- config.add_namespace("/my/important/namespace", overwrite_duplicates: true)
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
 
58
+ **Restore ENV to original state**
59
+ ```ruby
60
+ Chambermaid.restore!
61
+ Chambermaid.reset! # alias of .restore!
62
+ ```
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
+
45
82
  ## Development
46
83
 
47
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,7 +1,16 @@
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
9
+ def self.extended(base)
10
+ # Make a copy of ENV before we mess it all up
11
+ @@_original_env = ENV.to_h.dup.freeze
12
+ end
13
+
5
14
  extend self
6
15
 
7
16
  def configure
@@ -13,43 +22,126 @@ module Chambermaid
13
22
  raise "Namespaces must be defined" unless @namespaces
14
23
  end
15
24
 
25
+ # Load SSM into ENV
26
+ def load!
27
+ @namespaces.each(&:load!)
28
+ end
29
+
16
30
  # @todo
17
31
  def reload!
32
+ @namespaces.each(&:reload!)
18
33
  end
19
34
 
35
+ def unload!
36
+ @namespaces.each(&:unload!)
37
+ end
38
+
39
+ # Restore ENV to its original state
40
+ def restore!
41
+ ENV.replace(@@_original_env)
42
+ end
43
+ alias :reset! :restore!
44
+
20
45
  # Add an AWS SSM parameter namespace to ENV
21
46
  #
22
47
  # @param [String] path
23
- # @param [Boolean] overwrite_duplicates
48
+ # @param [Boolean] overload
24
49
  # true - replace any duplicate ENV keys with new params
25
50
  # false - keep any existing duplicate ENV key values
26
51
  #
27
- # @raise
28
- def add_namespace(path, overwrite_duplicates: false)
29
- @namespaces ||= {}
30
- raise "namespace already included in ENV" unless @namespaces[path].nil?
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)
60
+ def add_namespace(path, overload: false)
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)
31
63
 
32
- @namespaces[path] = ParameterStore.load!(path: path)
33
- update_env!(
34
- params: @namespaces[path].params,
35
- overwrite_duplicates: overwrite_duplicates
36
- )
64
+ namespaces << Namespace.new(path: path, overload: overload)
37
65
  end
38
66
 
39
- # Inject into ENV
67
+ # Immediately load an AWS SSM parameter namespace to ENV
40
68
  #
41
- # @param [Hash] params
42
- # @param [Boolean] overwrite_duplicates
69
+ # @param [String] path
70
+ # @param [Boolean] overload
43
71
  # true - replace any duplicate ENV keys with new params
44
72
  # false - keep any existing duplicate ENV key values
45
- def update_env!(params:, overwrite_duplicates:)
46
- if overwrite_duplicates
47
- ENV.update(params)
48
- else
49
- current_env = ENV.to_h.dup
50
- new_env = params.merge(current_env)
51
- ENV.replace(new_env)
52
- end
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)
85
+
86
+ namespaces << Namespace.load!(path: path, overload: overload)
87
+ end
88
+
89
+ # Add all secrets from Chamber service to ENV
90
+ #
91
+ # @param [String] service
92
+ # @param [Boolean] overload
93
+ # true - replace any duplicate ENV keys with new params
94
+ # false - keep any existing duplicate ENV key values
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 ||= []
53
145
  end
54
146
  end
55
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
@@ -10,6 +10,15 @@ module Chambermaid
10
10
  fetch_ssm_params!
11
11
  end
12
12
 
13
+ def reload!
14
+ clear_params!
15
+ fetch_ssm_params!
16
+ end
17
+
18
+ def loaded?
19
+ !@params_list.empty?
20
+ end
21
+
13
22
  def self.load!(path:)
14
23
  store = new(path: path)
15
24
  store.load!
@@ -24,12 +33,6 @@ module Chambermaid
24
33
 
25
34
  alias :to_h :params
26
35
 
27
- def to_env
28
- params.inject("") do |env_str, param|
29
- env_str + "#{param[0]}=#{param[1]}\n"
30
- end
31
- end
32
-
33
36
  private
34
37
 
35
38
  def client
@@ -37,14 +40,20 @@ module Chambermaid
37
40
  end
38
41
 
39
42
  def fetch_ssm_params!
43
+ Chambermaid.logger.debug("fetching AWS SSM parameters from `#{@path}`")
40
44
  @param_list = []
41
45
  response = nil
42
46
  loop do
43
47
  response = fetch_ssm_param_batch!(response&.next_token)
44
48
  @param_list.concat(response.parameters)
45
49
 
46
- 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
47
55
  end
56
+ Chambermaid.logger.debug("fetched #{@param_list.size} parameters from `#{@path}`")
48
57
  end
49
58
 
50
59
  def fetch_ssm_param_batch!(next_token = nil)
@@ -55,5 +64,10 @@ module Chambermaid
55
64
  next_token: next_token
56
65
  )
57
66
  end
67
+
68
+ def clear_params!
69
+ @params = nil
70
+ @params_list = []
71
+ end
58
72
  end
59
73
  end
@@ -0,0 +1,8 @@
1
+ module Chambermaid
2
+ class Railtie < Rails::Railtie
3
+ config.before_configuration 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.1.0"
2
+ VERSION = "0.4.0"
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.1.0
4
+ version: 0.4.0
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: