sf-hiera-aws 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: 5158fadbf94eccfdfafaebf7b175d3c11f36a841
4
- data.tar.gz: d69011bbc8cd91207d999bbcb1889b88171a29cf
3
+ metadata.gz: 743247150dec1c5548e31200315a1fdd765afd22
4
+ data.tar.gz: ad06bef85101602ce5b65565289a60a5b13d2920
5
5
  SHA512:
6
- metadata.gz: bca35ff02edb74348a7e3d5a85e3160f6841b553ae8a09fbf350b741344f052eb7f92c21621069bbf2e58f4d2d9b3d5365b75b99d2d925bc6fe8c47364bdf378
7
- data.tar.gz: e6dd2449724903a05aa7b013868cd4237e02d6dc816ae126ce221a4a8d4af04a264f03fb6a2eaf24932685fa7c070a7c06574de1c873b6d100a37959294cba6a
6
+ metadata.gz: 5ab644f595db9b4752aac825b44286dd181282ba06d24ae1e4228a7b539c9a93c7aa9afc4c208b77a2c923f7d2412fea1728261f5124a253dfeb86c3556dc2d5
7
+ data.tar.gz: 1e701867da2da23d371b5d43f2b8c2e08f3663a06c9afcd5f71fbcae3138c59c912a6779f6d6086894ed375b4fe363af0ac94faccefdbdc28443f37b44fff673
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ .ruby-version
11
+ *.swp
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ Style/IndentationWidth:
2
+ Width: 4
3
+
4
+ Style/TrailingComma:
5
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ## 0.0.3 (16 December 2015)
2
+
3
+ * Add rspec tests
4
+ * Support configuration under a directory
5
+ * Configurable changes to return values
6
+
7
+ ## 0.0.2 (3 September 2015)
8
+
9
+ * Calculate AWS region from link-local data source
10
+
11
+ ## 0.0.1 (2 September 2015)
12
+
13
+ * Initial release
14
+
data/Gemfile CHANGED
@@ -2,3 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in sf-hiera-aws.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ gem 'rspec'
8
+ gem 'rspec-mocks'
9
+ gem 'webmock'
10
+ gem 'hiera'
11
+ gem 'mocha'
12
+ gem 'rubocop'
13
+ gem 'simplecov'
14
+ end
data/README.md CHANGED
@@ -42,6 +42,7 @@ The IAM role will need the following permissions:
42
42
  ## Configuration
43
43
 
44
44
  The plugin expects to find a configuration file under `/etc/puppet/sf_hiera_aws.yaml`, defining how we look up named keys. The keys at the top level of this file determine the names of the hiera keys the plugin will provide; the configuration determines how these are looked up.
45
+ Additional configuration can be given in files under `/etc/puppet/sf_hiera_aws.d`, which are evaluated in alphanumerical order. If a duplicate key is encountered in files evaluated later, this will override the earlier config.
45
46
 
46
47
  ### Example - EC2 nodes by tag
47
48
 
@@ -68,7 +69,9 @@ aws_am_bullseye_rds:
68
69
  db_instance_identifier: "%{::sf_location}-%{::sf_environment}-db"
69
70
  ```
70
71
 
71
- Calls to `:rds_db_instance` type keys return the instance identifier, endpoint address and endpoint port.
72
+ Calls to `:rds_db_instance` type keys return the instance identifier, endpoint address and endpoint port in a hash.
73
+ Pass a `return` key with value `:hostname` to have the hostname of the first matching instance returned.
74
+ Pass a `return` key with value `:hostname_and_port` to have a `"<hostname>:<port>"` string of the first matching instance returned.
72
75
 
73
76
  ### Example - ElastiCache cluster by name
74
77
 
@@ -79,5 +82,6 @@ aws_am_bullseye_redis:
79
82
  ```
80
83
 
81
84
  Calls to `:elasticache_cache_cluster` type keys return a list of cache nodes, their IDs and endpoint address/ports.
82
-
85
+ Pass a `return` key with value `:hostname` to have a list of hostnames of keys of all cache nodes matching the cache_cluster_id returned.
86
+ Pass a `return` key with value `:hostname_and_port` to have a list of `"<hostname>:<port>"` strings returned.
83
87
 
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'rspec/core/rake_task'
2
4
 
5
+ namespace :test do
6
+ RSpec::Core::RakeTask.new(:unit) do |t|
7
+ t.pattern = 'spec/unit/*_test.rb'
8
+ t.rspec_opts = '--color'
9
+ end
10
+ end
@@ -1,14 +1,11 @@
1
1
  class Hiera
2
-
3
2
  module Backend
4
-
5
3
  class Sf_hiera_aws_backend
4
+ private
6
5
 
7
- public
8
-
9
- def initialize
6
+ @instance_identity = nil
10
7
 
11
- require 'aws-sdk-resources'
8
+ def read_link_local_data
12
9
  require 'net/http'
13
10
  require 'json'
14
11
 
@@ -16,88 +13,140 @@ class Hiera
16
13
  http = Net::HTTP.new('169.254.169.254', 80)
17
14
  http.open_timeout = 1
18
15
  http.read_timeout = 1
19
- instance_identity = JSON.parse(http.request(Net::HTTP::Get.new("/latest/dynamic/instance-identity/document")).body)
20
- Aws.config.update({ region: instance_identity['region'] })
21
- rescue Exception
16
+ @instance_identity = JSON.parse(http.request(Net::HTTP::Get.new('/latest/dynamic/instance-identity/document')).body)
17
+ rescue Errno::EHOSTUNREACH, Net::OpenTimeout, Timeout::Error
22
18
  Hiera.warn('No link-local endpoint - can\'t calculate region')
23
19
  end
24
- Hiera.debug('Hiera AWS SDK backend started')
20
+ end
21
+
22
+ # Wrapped these in getters for dependency injection purposes
23
+ def get_rds_client
24
+ Aws::RDS::Client.new
25
+ end
25
26
 
27
+ def get_ec2_client
28
+ Aws::EC2::Client.new
26
29
  end
27
30
 
28
- def lookup (key, scope, order_override, resolution_type)
31
+ def get_elasticache_client
32
+ Aws::ElastiCache::Client.new
33
+ end
29
34
 
35
+ public
36
+
37
+ def initialize
38
+ require 'aws-sdk-resources'
39
+
40
+ read_link_local_data
41
+ unless @instance_identity.nil?
42
+ Aws.config.update(region: @instance_identity['region'])
43
+ end
44
+
45
+ Hiera.debug('Hiera AWS SDK backend started')
46
+ end
47
+
48
+ def lookup(key, scope, _order_override, _resolution_type)
30
49
  config = recursive_interpolate_config(aws_config, scope)
31
50
 
32
51
  Hiera.debug("Looking up '#{key} in AWS SDK backend")
33
52
 
34
- if ! config.key? key
35
- return nil
36
- end
53
+ return nil unless config.key? key
37
54
 
38
55
  Hiera.debug("Config: #{config[key].inspect}")
39
56
  type = config[key]['type']
40
57
 
41
- if self.methods.include? "type_#{type}".to_sym
58
+ if methods.include? "type_#{type}".to_sym
42
59
 
43
60
  begin
44
- answer = self.send("type_#{type}".to_sym, config[key])
45
- Hiera.debug( answer )
61
+ answer = send("type_#{type}".to_sym, config[key])
62
+ Hiera.debug(answer)
46
63
  return answer
47
64
  rescue Aws::Errors::MissingRegionError, Aws::Errors::MissingCredentialsError
48
- Hiera.warn("No IAM role or ENV based AWS config - skipping")
65
+ Hiera.warn('No IAM role or ENV based AWS config - skipping')
49
66
  return nil
50
67
  end
51
68
 
52
69
  end
53
70
 
54
71
  Hiera.debug("Type of AWS SDK lookup '#{type}' invalid")
55
- return nil
56
-
72
+ nil
57
73
  end
58
74
 
59
- def aws_config
60
-
61
- require 'yaml'
75
+ def config_file_name
62
76
 
63
- default_config_path = "/etc/puppet/sf_hiera_aws.yaml"
77
+ default_config_path = '/etc/puppet/sf_hiera_aws.yaml'
64
78
 
65
- if ! Config[:aws_sdk].nil?
79
+ if !Config[:aws_sdk].nil?
66
80
  config_file = Config[:aws_sdk][:config_file] || default_config_path
67
81
  else
68
82
  config_file = default_config_path
69
83
  end
70
84
 
85
+ return config_file
86
+
87
+ end
88
+
89
+ def config_directory_name
90
+
91
+ default_config_path = '/etc/puppet/sf_hiera_aws.d'
92
+
93
+ if !Config[:aws_sdk].nil?
94
+ config_dir = Config[:aws_sdk][:config_directory] || default_config_path
95
+ else
96
+ config_dir = default_config_path
97
+ end
98
+
99
+ return config_dir
100
+
101
+ end
102
+
103
+
104
+ def aws_config
105
+
106
+ require 'yaml'
107
+
108
+ config_file = config_file_name
109
+
71
110
  if File.exist?(config_file)
72
- config = YAML::load_file(config_file)
111
+ config = YAML.load_file(config_file)
73
112
  else
74
113
  Hiera.warn("No config file #{config_file} found")
75
114
  config = {}
76
115
  end
77
116
 
78
- config
117
+ # Merge configs from the config directory too
79
118
 
119
+ config_directory = config_directory_name
120
+
121
+ if File.directory?(config_directory)
122
+ Dir.entries(config_directory).sort.each do |p|
123
+ next if p == '.' or p == '..'
124
+ to_merge = YAML.load_file( File.join( config_directory, p ) )
125
+ config.merge! to_merge
126
+ end
127
+ end
128
+
129
+ config
80
130
  end
81
131
 
82
- def recursive_interpolate_config(h,scope)
132
+ def recursive_interpolate_config(h, scope)
83
133
  case h
84
134
  when Hash
85
135
  Hash[
86
136
  h.map do |k, v|
87
- [ Backend.parse_answer(k, scope), recursive_interpolate_config(v,scope) ]
137
+ [Backend.parse_answer(k, scope), recursive_interpolate_config(v, scope)]
88
138
  end
89
139
  ]
90
140
  when Enumerable
91
- h.map { |v| recursive_interpolate_config(v,scope) }
141
+ h.map { |v| recursive_interpolate_config(v, scope) }
92
142
  when String
93
- Backend.parse_answer(h,scope)
143
+ Backend.parse_answer(h, scope)
94
144
  else
95
145
  h
96
146
  end
97
147
  end
98
148
 
99
149
  def type_ec2_instance(options)
100
-
101
150
  options = {
102
151
  'return' => [
103
152
  :instance_id,
@@ -106,25 +155,23 @@ class Hiera
106
155
  ]
107
156
  }.merge(options)
108
157
 
109
- ec2 = Aws::EC2::Resource.new()
158
+ ec2 = get_ec2_client
110
159
 
111
160
  if options.key? 'filters'
112
- instances = ec2.instances( filters: options['filters'] ) || []
161
+ instances = ec2.describe_instances(filters: options['filters']).reservations.first.instances || []
113
162
  else
114
- instances = ec2.instances() || []
163
+ instances = ec2.describe_instances().reservations.first.instances || []
115
164
  end
116
165
 
117
166
  instances.collect do |i|
118
- Hash[ options['return'].map { |f|
119
- [f.to_s, i.methods.include?(f) ? i.send(f) : nil ]
120
- } ]
167
+ Hash[options['return'].map do |f|
168
+ [f.to_s, i.key?(f) ? i[f] : nil]
169
+ end]
121
170
  end
122
-
123
171
  end
124
172
 
125
173
  def type_rds_db_instance(options)
126
-
127
- rds = Aws::RDS::Client.new()
174
+ rds = get_rds_client
128
175
 
129
176
  if options.key? 'db_instance_identifier'
130
177
  instances = rds.describe_db_instances(
@@ -134,19 +181,42 @@ class Hiera
134
181
  instances = rds.describe_db_instances.db_instances
135
182
  end
136
183
 
137
- instances.collect do |i|
138
- {
139
- 'db_instance_identifier' => i.db_instance_identifier,
140
- 'endpoint_address' => i.endpoint.address,
141
- 'endpoint_port' => i.endpoint.port,
142
- }
184
+ if !options.key? 'return'
185
+
186
+ return instances.collect do |i|
187
+ {
188
+ 'db_instance_identifier' => i.db_instance_identifier,
189
+ 'endpoint_address' => i.endpoint.address,
190
+ 'endpoint_port' => i.endpoint.port,
191
+ }
192
+ end
193
+
143
194
  end
144
195
 
196
+ if options['return'] == :hostname
197
+
198
+ return instances.first.endpoint.address
199
+
200
+ elsif options['return'] == :hostname_and_port
201
+
202
+ return [
203
+ instances.first.endpoint.address,
204
+ instances.first.endpoint.port,
205
+ ].join(':')
206
+
207
+ else
208
+
209
+ Hiera.warn("No return handler for #{options['return']} in rds_db_instance")
210
+ return nil
211
+
212
+ end
213
+
214
+
215
+
145
216
  end
146
217
 
147
218
  def type_elasticache_cache_cluster(options)
148
-
149
- elasticache = Aws::ElastiCache::Client.new()
219
+ elasticache = get_elasticache_client
150
220
 
151
221
  if options.key? 'cache_cluster_id'
152
222
  clusters = elasticache.describe_cache_clusters(
@@ -159,23 +229,50 @@ class Hiera
159
229
  ).cache_clusters
160
230
  end
161
231
 
162
- clusters.collect do |i|
163
- {
164
- 'cache_cluster_id' => i.cache_cluster_id,
165
- 'cache_nodes' => i.cache_nodes.collect do |n|
166
- {
167
- 'cache_node_id' => n.cache_node_id,
168
- 'endpoint_address' => n.endpoint.address,
169
- 'endpoint_port' => n.endpoint.port,
170
- }
232
+ if !options.key? 'return'
233
+
234
+ return clusters.collect do |i|
235
+ {
236
+ 'cache_cluster_id' => i.cache_cluster_id,
237
+ 'cache_nodes' => i.cache_nodes.collect do |n|
238
+ {
239
+ 'cache_node_id' => n.cache_node_id,
240
+ 'endpoint_address' => n.endpoint.address,
241
+ 'endpoint_port' => n.endpoint.port,
242
+ }
243
+ end
244
+ }
245
+ end
246
+
247
+ end
248
+
249
+ if options['return'] == :hostname
250
+
251
+ nodes = []
252
+
253
+ clusters.each do |c|
254
+ c.cache_nodes.each do |n|
255
+ nodes.push(n.endpoint.address)
256
+ end
257
+ end
258
+
259
+ return nodes
260
+
261
+ elsif options['return'] == :hostname_and_port
262
+
263
+ nodes = []
264
+
265
+ clusters.each do |c|
266
+ c.cache_nodes.each do |n|
267
+ nodes.push( [ n.endpoint.address, n.endpoint.port ].join(':') )
171
268
  end
172
- }
269
+ end
270
+
271
+ return nodes
272
+
173
273
  end
174
- end
175
274
 
275
+ end
176
276
  end
177
-
178
277
  end
179
-
180
278
  end
181
-
data/sf-hiera-aws.gemspec CHANGED
@@ -3,21 +3,23 @@ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "sf-hiera-aws"
7
- spec.version = "0.0.2"
8
- spec.authors = ["Jon Topper"]
9
- spec.email = ["jon@scalefactory.com"]
6
+ spec.name = 'sf-hiera-aws'
7
+ spec.version = '0.0.3'
8
+ spec.authors = ['Jon Topper']
9
+ spec.email = ['jon@scalefactory.com']
10
10
 
11
- spec.summary = %q{Hiera backend for querying AWS resources}
12
- spec.homepage = "https://github.com/scalefactory/sf-hiera-aws"
13
- spec.license = "MIT"
11
+ spec.summary = 'Hiera backend for querying AWS resources'
12
+ spec.homepage = 'https://github.com/scalefactory/sf-hiera-aws'
13
+ spec.license = 'MIT'
14
14
 
15
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
17
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
19
21
 
20
- spec.add_development_dependency "bundler", "~> 1.8"
21
- spec.add_development_dependency "rake", "~> 10.0"
22
- spec.add_dependency "aws-sdk-resources", ">=2.1.18"
22
+ spec.add_development_dependency 'bundler', '~> 1.8'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_dependency 'aws-sdk-resources', '>=2.2.6'
23
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sf-hiera-aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Topper
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-03 00:00:00.000000000 Z
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 2.1.18
47
+ version: 2.2.6
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.1.18
54
+ version: 2.2.6
55
55
  description:
56
56
  email:
57
57
  - jon@scalefactory.com
@@ -60,6 +60,8 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - ".rubocop.yml"
64
+ - CHANGELOG.md
63
65
  - Gemfile
64
66
  - LICENSE.txt
65
67
  - README.md