aws-cache 0.0.01

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-cache.rb +193 -0
  3. metadata +72 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 401dd27434bfe5f1cb76b9b4e4ba32778186b3b4
4
+ data.tar.gz: 0acfb5461a33efaa30af90077a6fd9e510bf9ae9
5
+ SHA512:
6
+ metadata.gz: e62ab25345e9c47119490cf7261ac2ff86d9d32d5d226b89b9748c36d39f8e7ea10bc99382a7f5b944175721301c6de2bc37cc19f1d1fa09f113887d79c24454
7
+ data.tar.gz: 5d9a6fc941d936d9ac34f2773401c2b3444841a23498fab249417a09c9da1de5c02ac24081064cc55661ee95e45e8587c17f3d451d85e661a51fdf44fcbfbd67
@@ -0,0 +1,193 @@
1
+ require 'redis'
2
+ require 'json'
3
+ require 'aws-sdk'
4
+ require 'yaml'
5
+
6
+ class AwsCache
7
+ # Please follow semantic versioning (semver.org).
8
+ VERSION = '0.0.1'
9
+
10
+ def initialize(opts)
11
+ @redis = optional_element(opts, ['redis'])
12
+ if @redis.nil?
13
+ @redis = Redis.new(url: 'redis://aws-cache:6379/0')
14
+ end
15
+ @keyspace = optional_element(opts, ['keyspace'], AwsCache::VERSION)
16
+ @region = optional_element(opts, ['region'], 'us-east-1')
17
+ end
18
+
19
+ def ec2_instances
20
+ instances = cache_get('aws_ec2_instances', 300) do
21
+ instances = {}
22
+
23
+ ec2 = Aws::EC2::Client.new(region: @region)
24
+ page = ec2.describe_instances
25
+ page.each do |page|
26
+ page =
27
+ page.data[:reservations].each do |res|
28
+ res[:instances].each do |instance|
29
+ list_to_hash!(instance, [:tags], :key)
30
+ list_to_hash!(instance, [:block_device_mappings], :device_name)
31
+ instances[instance[:instance_id]] = instance
32
+ end
33
+ end
34
+ end
35
+
36
+ instances
37
+ end
38
+
39
+ return instances
40
+ end
41
+
42
+ def stack_instances(stack_name)
43
+ instances = self.ec2_instances
44
+ stack_instances = {}
45
+ instances.each do |id, instance|
46
+ if stack_name == optional_element(instance, [':tags','StackName',':value'], '')
47
+ stack_instances[id] = instance
48
+ end
49
+ end
50
+ return stack_instances
51
+ end
52
+
53
+ def auto_scaling_groups
54
+ groups = cache_get('aws_auto_scaling_groups', 300) do
55
+ groups = {}
56
+
57
+ autoscaling = Aws::AutoScaling::Client.new(region: @region)
58
+ page = autoscaling.describe_auto_scaling_groups
59
+ page.each do |page|
60
+ page.data[:auto_scaling_groups].each do |group|
61
+ instances = {}
62
+ list_to_hash!(group, [:instances], :instance_id)
63
+ list_to_hash!(group, [:tags], :key)
64
+ groups[group[:auto_scaling_group_name]] = group
65
+ end
66
+ end
67
+
68
+ groups
69
+ end
70
+
71
+ return groups
72
+ end
73
+
74
+ def stack_auto_scaling_groups(stack_name)
75
+ groups = self.auto_scaling_groups
76
+ stack_groups = {}
77
+ groups.each do |name, group|
78
+ if stack_name == optional_element(group, [':tags','StackName',':value'], '')
79
+ stack_groups[name] = group
80
+ end
81
+ end
82
+ return stack_groups
83
+ end
84
+
85
+ def describe_stacks
86
+ cloudformation_stacks = cache_get('aws_cloudformation_describe_stacks', 900) do
87
+ cloudformation_stacks = {}
88
+
89
+ cfn = Aws::CloudFormation::Client.new(region: @region)
90
+ page = cfn.describe_stacks
91
+ page.each do |page|
92
+ page.data[:stacks].each do |stack|
93
+ list_to_hash!(stack, [:parameters], :parameter_key)
94
+ list_to_hash!(stack, [:outputs], :output_key)
95
+ list_to_hash!(stack, [:tags], :key)
96
+ cloudformation_stacks[stack[:stack_name]] = stack
97
+ end
98
+ end
99
+
100
+ cloudformation_stacks
101
+ end
102
+
103
+ return cloudformation_stacks
104
+ end
105
+
106
+ def describe_stack(stack_name)
107
+ stacks = self.describe_stacks
108
+ return stacks[stack_name]
109
+ end
110
+
111
+ def list_stack_resources(stack_name)
112
+ stack_resources = cache_get("aws_cloudformation_list_stack_resources:#{stack_name}", 900) do
113
+ stack_resources = {}
114
+ cfn = Aws::CloudFormation::Client.new(region: @region)
115
+
116
+ page = cfn.list_stack_resources(stack_name: stack_name)
117
+ page.each do |page|
118
+ resources = page.data[:stack_resource_summaries]
119
+ resources.each do |resource|
120
+ stack_resources[resource[:logical_resource_id]] = resource
121
+ end
122
+ end
123
+
124
+ stack_resources
125
+ end
126
+
127
+ return stack_resources
128
+ end
129
+
130
+ # One way this is different than describe_stacks is that it includes
131
+ # deleted stacks.
132
+ def list_stacks
133
+ stacks = cache_get('aws_cloudformation_list_stacks', 900) do
134
+ # Can't return a hash, because some stacks will appear more
135
+ # than once, such as if the stack was deleted and recreated.
136
+ stacks = []
137
+
138
+ cfn = Aws::CloudFormation::Client.new(region: @region)
139
+ page = cfn.list_stacks
140
+ page.each do |page|
141
+ page.data[:stack_summaries].each do |stack|
142
+ stacks.push(stack)
143
+ end
144
+ end
145
+
146
+ stacks
147
+ end
148
+
149
+ return stacks
150
+ end
151
+
152
+ private
153
+ def optional_element(hash, keys, default=nil)
154
+ keys.each do |key|
155
+ if !hash.is_a?(Hash) || !hash.has_key?(key)
156
+ return default
157
+ end
158
+ hash = hash[key]
159
+ end
160
+ return hash
161
+ end
162
+
163
+ def cache_get(key, ttl)
164
+ vkey = "#{key}_#{@keyspace}"
165
+ hash = @redis.get(vkey)
166
+ puts hash
167
+ unless hash.nil?
168
+ hash = YAML.load(hash)
169
+ end
170
+
171
+ if hash.nil?
172
+ hash = yield
173
+
174
+ hash = hash.to_yaml
175
+ @redis.setex(vkey, ttl, hash)
176
+ hash = YAML.load(hash)
177
+ end
178
+
179
+ return hash
180
+ end
181
+
182
+ def list_to_hash!(src, keys, by_key)
183
+ hash = {}
184
+ last_key = keys.pop
185
+ keys.each do |key|
186
+ src = src[key]
187
+ end
188
+ src[last_key].each do |entry|
189
+ hash[entry[by_key]] = entry
190
+ end
191
+ src[last_key] = hash
192
+ end
193
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws-cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.01
5
+ platform: ruby
6
+ authors:
7
+ - Stephen J. Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: You know, to avoid api throttling errors.
42
+ email: stsmith@manta.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/aws-cache.rb
48
+ homepage: https://github.com/mantacode/aws-cache
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.0.14
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: AWS api access layer that caches via Redis.
72
+ test_files: []