knowledge-ssm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Knowledge Ssm
2
+
3
+ This is the official AWS SSM adapter for knowledge gem.
4
+
5
+ ## Disclaimer
6
+
7
+ The full documentation is currently being written. You should be able to find a better documentation in a few hours or days.
8
+
9
+ Waiting for the full documentation, you can have a look at the code which is already well-documented.
10
+
11
+ Have a look to the [wiki](https://github.com/knowledge-ruby/knowledge-ssm/wiki) too.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'knowledge-ssm'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install knowledge-ssm
28
+
29
+ ## Usage
30
+
31
+ ```ruby
32
+ require 'knowledge/ssm'
33
+
34
+ knowledge = Knowledge::Learner.new
35
+ knowledge.variables = { ssm: { my_secret: 'path/to/secret' } }
36
+
37
+ knowledge.use(name: :ssm)
38
+ knowledge.add_adapter_params(adapter: :ssm, params: { root_path: '/project' })
39
+
40
+ knowledge.gather!
41
+
42
+ Knowledge::Configuration.my_secret # "Secret value"
43
+ ```
44
+
45
+ ## Development
46
+
47
+ 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.
48
+
49
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/knowledge-ruby/knowledge-ssm. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
54
+
55
+ ## Code of Conduct
56
+
57
+ Everyone interacting in the Knowledge::Ssm project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/knowledge-ruby/knowledge-ssm/blob/master/CODE_OF_CONDUCT.md).
58
+
59
+ ## Licensing
60
+
61
+ This project is licensed under [GPLv3+](https://www.gnu.org/licenses/gpl-3.0.en.html).
62
+
63
+ You can find it in LICENSE.md file.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'knowledge/ssm'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'knowledge/ssm/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'knowledge-ssm'
9
+ spec.version = Knowledge::Ssm::VERSION
10
+ spec.authors = ['Johann Wilfrid-Calixte']
11
+ spec.email = ['johann.open-source@protonmail.ch']
12
+
13
+ spec.summary = 'SSM adapter for knowledge gem'
14
+ spec.description = 'SSM adapter for knowledge gem'
15
+ spec.homepage = 'https://github.com/knowledge-ruby/knowledge-ssm'
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = 'https://johann.wilfrid-calixte.fr'
21
+
22
+ spec.metadata['homepage_uri'] = spec.homepage
23
+ spec.metadata['source_code_uri'] = 'https://github.com/knowledge-ruby/knowledge-ssm'
24
+ spec.metadata['changelog_uri'] = 'https://github.com/knowledge-ruby/knowledge-ssm/blob/master/CHANGELOG.md'
25
+ else
26
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
27
+ 'public gem pushes.'
28
+ end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = 'exe'
36
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ['lib']
38
+
39
+ spec.add_dependency 'aws-sdk-ssm', '~> 1.34'
40
+ spec.add_dependency 'knowledge', '~> 0.1'
41
+
42
+ spec.add_development_dependency 'bundler', '~> 1.16'
43
+ spec.add_development_dependency 'pry', '>= 0.12'
44
+ spec.add_development_dependency 'rake', '~> 10.0'
45
+ spec.add_development_dependency 'rspec', '~> 3.0'
46
+ spec.add_development_dependency 'rubocop', '>= 0.60'
47
+ spec.add_development_dependency 'simplecov'
48
+ end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-ssm'
4
+
5
+ module Knowledge
6
+ module Adapters
7
+ #
8
+ # === Description ===
9
+ #
10
+ # This adapter takes some vars in your SSM parameters and set it in your project's config.
11
+ #
12
+ # === Usage ===
13
+ #
14
+ # @example:
15
+ # adapter = Knowledge::Adapters::Ssm.new(params: { root_path: '/path', setter: MySetter, variables: my_vars)
16
+ #
17
+ # adapter.run
18
+ #
19
+ # === Attributes ===
20
+ #
21
+ # @attr_reader [Boolean] raise_not_found
22
+ # @attr_reader [String] root_path
23
+ # @attr_reader [Class] setter
24
+ # @attr_reader [Array<Aws::SSM::Types::Parameter>] ssm_parameters
25
+ # @attr_reader [Hash] variables
26
+ #
27
+ class Ssm < Base
28
+ # == Attributes ==================================================================================================
29
+ attr_reader :raise_not_found, :root_path, :ssm_parameters
30
+
31
+ # == Constructor =================================================================================================
32
+ #
33
+ # @param [Hash] :params
34
+ # @option params [Aws::SSM::Client] :client
35
+ # @option params [Boolean] :raise_on_parameter_not_found
36
+ # @option params [String] :root_path
37
+ # @param [Hash] :variables
38
+ # @param [Class] :setter
39
+ #
40
+ def initialize(params: {}, setter:, variables:)
41
+ super
42
+
43
+ @client = params[:client] || params['client']
44
+ @raise_not_found = params[:raise_on_parameter_not_found] || params['raise_on_parameter_not_found'] || false
45
+ @root_path = params[:root_path] || params['root_path']
46
+ @ssm_parameters = @root_path ? fetch_recursive_parameters : fetch_parameters
47
+ end
48
+
49
+ # == Instance Methods ============================================================================================
50
+ #
51
+ # === Description ===
52
+ #
53
+ # Runs the actual adapter.
54
+ #
55
+ def run
56
+ variables.each do |name, path|
57
+ base_path = root_path[0..-2] if root_path&.end_with?('/')
58
+ path = "/#{path.sub('/', '')}"
59
+ value = Array(@ssm_parameters).detect { |p| p.name == "#{base_path}#{path}" }&.value
60
+
61
+ setter.set(name: name, value: value)
62
+ end
63
+ end
64
+
65
+ protected
66
+
67
+ #
68
+ # === Description ===
69
+ #
70
+ # Credentials for AWS should be loaded from the ENV vars by the client itself.
71
+ # Authorization is done automatically according to the current AWS policies.
72
+ #
73
+ # === Errors ===
74
+ #
75
+ # @raise [Aws::SSM::Errors::UnrecognizedClientException]
76
+ # @raise [Aws::SSM::AccessDeniedException]
77
+ #
78
+ # === Parameters ===
79
+ #
80
+ # @return [Aws::SSM::Client]
81
+ #
82
+ def client
83
+ @client ||= ::Aws::SSM::Client.new
84
+ end
85
+
86
+ #
87
+ # === Description ===
88
+ #
89
+ # Fetches parameters one by one on SSM according to their specific path
90
+ #
91
+ # === Parameters ===
92
+ #
93
+ # @return [Array<Aws::SSM::Types::Parameter>]
94
+ #
95
+ def fetch_parameters
96
+ variables.map { |_name, path| fetch_parameter(path: path) }.compact
97
+ end
98
+
99
+ #
100
+ # === Description ===
101
+ #
102
+ # Recursively fetches parameters on SSM according to the given path
103
+ #
104
+ # === Errors ===
105
+ #
106
+ # @raise [Knowledge::SsmError]
107
+ #
108
+ # === Parameters ===
109
+ #
110
+ # @return [Array<Aws::SSM::Types::Parameter>]
111
+ #
112
+ def fetch_recursive_parameters
113
+ parameters = []
114
+ next_token = nil
115
+ first_page = true
116
+
117
+ while next_token || first_page
118
+ first_page = false
119
+ result = client.get_parameters_by_path(
120
+ next_token: next_token,
121
+ path: root_path,
122
+ recursive: true,
123
+ with_decryption: true
124
+ )
125
+ parameters += result.parameters
126
+ next_token = result.next_token
127
+ end
128
+
129
+ parameters
130
+ rescue ::Aws::SSM::Errors::AccessDeniedException, ::Aws::SSM::Errors::UnrecognizedClientException => e
131
+ raise ::Knowledge::SsmError, "[#{e.class}]: #{e.message}"
132
+ end
133
+
134
+ #
135
+ # === Description ===
136
+ #
137
+ # Fetches a parameter by its path on SSM
138
+ #
139
+ # === Error ===
140
+ #
141
+ # @raise [Knowledge::SsmError]
142
+ #
143
+ # === Parameters ===
144
+ #
145
+ # @param [String] :path
146
+ #
147
+ # @return [Aws::SSM::Types::Parameter]
148
+ #
149
+ def fetch_parameter(path:)
150
+ client.get_parameter(name: path, with_decryption: true).parameter
151
+ rescue ::Aws::SSM::Errors::AccessDeniedException, ::Aws::SSM::Errors::UnrecognizedClientException => e
152
+ raise ::Knowledge::SsmError, "[#{e.class}]: #{e.message}"
153
+ rescue ::Aws::SSM::Errors::ParameterNotFound => e
154
+ raise ::Knowledge::SsmError, "[#{e.class}]: #{e.message}" if raise_not_found
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ ::Knowledge::Learner.register_default_adapter(
161
+ klass: ::Knowledge::Adapters::Ssm,
162
+ names: %i[aws_ssm ssm]
163
+ )
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'knowledge/ssm/version'
4
+
5
+ module Knowledge
6
+ class SsmError < Error; end
7
+
8
+ #
9
+ # === Description ===
10
+ #
11
+ # SSM Adapter for Knowledge gem
12
+ #
13
+ # === Usage ===
14
+ #
15
+ # @example:
16
+ # require 'knowledge/ssm'
17
+ #
18
+ # knowledge = Knowledge::Learner.new
19
+ # knowledge.variables = { ssm: { my_secret: 'path/to/secret' } }
20
+ #
21
+ # knowledge.use(name: :ssm)
22
+ # knowledge.add_adapter_params(adapter: :ssm, params: { root_path: '/project' })
23
+ #
24
+ # knowledge.gather!
25
+ #
26
+ # Knowledge::Configuration.my_secret # "Secret value"
27
+ #
28
+ module Ssm; end
29
+ end
30
+
31
+ require 'knowledge/adapters/ssm'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Knowledge
4
+ module Ssm
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knowledge-ssm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Johann Wilfrid-Calixte
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-ssm
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.34'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.34'
27
+ - !ruby/object:Gem::Dependency
28
+ name: knowledge
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0.60'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0.60'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: SSM adapter for knowledge gem
126
+ email:
127
+ - johann.open-source@protonmail.ch
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".circleci/config.yml"
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
136
+ - ".ruby-gemset"
137
+ - ".ruby-version"
138
+ - ".travis.yml"
139
+ - CODE_OF_CONDUCT.md
140
+ - Gemfile
141
+ - Gemfile.lock
142
+ - LICENSE.md
143
+ - README.md
144
+ - Rakefile
145
+ - bin/console
146
+ - bin/setup
147
+ - knowledge-ssm.gemspec
148
+ - lib/knowledge/adapters/ssm.rb
149
+ - lib/knowledge/ssm.rb
150
+ - lib/knowledge/ssm/version.rb
151
+ homepage: https://github.com/knowledge-ruby/knowledge-ssm
152
+ licenses: []
153
+ metadata:
154
+ homepage_uri: https://github.com/knowledge-ruby/knowledge-ssm
155
+ source_code_uri: https://github.com/knowledge-ruby/knowledge-ssm
156
+ changelog_uri: https://github.com/knowledge-ruby/knowledge-ssm/blob/master/CHANGELOG.md
157
+ post_install_message:
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 2.7.8
174
+ signing_key:
175
+ specification_version: 4
176
+ summary: SSM adapter for knowledge gem
177
+ test_files: []