aws_metadata 0.1.0
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 +7 -0
- data/.gitignore +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +22 -0
- data/README.md +112 -0
- data/Rakefile +10 -0
- data/aws_metadata.gemspec +27 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/aws_metadata.rb +75 -0
- data/lib/aws_metadata/cfn_stack_output.rb +49 -0
- data/lib/aws_metadata/instance_metadata.rb +106 -0
- data/lib/aws_metadata/version.rb +5 -0
- data/lib/extensions/string.rb +24 -0
- data/test/fixtures/responses.yml +83 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 23fc0654669922ff9d4131779dc09308d7491715
|
4
|
+
data.tar.gz: 55fb15342c8d499a5e3d4ec94f2846a518a7e8d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f0726ebb66175444ab5adf5d3153b313f11e95cdc7991b118f6d01c5808f99330f4c0d1cc8d97367d1875f741faec9f811f5b2522add5765d54693a30b7a4724
|
7
|
+
data.tar.gz: 7b938f5c05bd5488f3fcc8b7eeab91e4ffa4f25973838fb827840eb25817c1d3d2e1be34e94cae75997658657c867d4cd00d7610480293614a2a38f3bbc858d3
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
aws_metadata
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.4
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at kevintyll@gmail.com. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
aws_metadata (0.1.0)
|
5
|
+
aws-sdk
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
aws-sdk (2.1.36)
|
11
|
+
aws-sdk-resources (= 2.1.36)
|
12
|
+
aws-sdk-core (2.1.36)
|
13
|
+
jmespath (~> 1.0)
|
14
|
+
aws-sdk-resources (2.1.36)
|
15
|
+
aws-sdk-core (= 2.1.36)
|
16
|
+
jmespath (1.1.3)
|
17
|
+
rake (10.4.2)
|
18
|
+
rdiscount (2.2.0.1)
|
19
|
+
yard (0.9.5)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
aws_metadata!
|
26
|
+
bundler (~> 1.11)
|
27
|
+
rake (~> 10.0)
|
28
|
+
rdiscount
|
29
|
+
yard
|
30
|
+
|
31
|
+
BUNDLED WITH
|
32
|
+
1.11.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Evident.io
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# AWS Metadata
|
2
|
+
|
3
|
+
AWS::Metadata has 2 components to it. `AWS::Instance` and `AWS::StackOutput`
|
4
|
+
|
5
|
+
This first, `AWS::Instance`, is mostly identical to https://github.com/airbnb/gem-aws-instmd and exposes the instance metadata information through a Ruby API.
|
6
|
+
|
7
|
+
The second, `AWS::StackOutput`, gives you access to the Cloud Formation Outputs you define in your CFN template given a template name.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'aws_metadata'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install aws_metadata
|
24
|
+
|
25
|
+
## Usage for `AWS::Instance`
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
puts AWS::Instance.metadata.instance_id
|
29
|
+
puts AWS::Instance.dynamic.instance_identity.document.account_id
|
30
|
+
puts AWS::Instance.user_data
|
31
|
+
```
|
32
|
+
|
33
|
+
To return stubbed responses, you can add this to an initializer:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
AWS::Metadata.configure do |config|
|
37
|
+
config.stub_responses = Rails.env =~ /development|test/
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
or
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
AWS::Metadata.stub_responses = Rails.env =~ /development|test/
|
45
|
+
```
|
46
|
+
|
47
|
+
This will prevent HTTP calls to 169.254.169.254 and return canned results.
|
48
|
+
When stubbing responses, both `AWS::Instance` and `AWS::StackOutput` will be stubbed.
|
49
|
+
|
50
|
+
## Usage for `AWS::StackOutput`
|
51
|
+
You must first configure the gem in an initializer.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
AWS::Metadata.configure do |config|
|
55
|
+
config.cfn_stack_name = 'your_cfn_stack_name' # As identified by the Stack Name column in the CloudFormation Section of the AWS console.
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
or
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
AWS::Metadata.cfn_stack_name = 'your_cfn_stack_name'
|
63
|
+
AWS::StackOutput.get
|
64
|
+
```
|
65
|
+
|
66
|
+
Methods are dynamically generated from the Outputs that have been defined for the configured `cfn_stack_name`.
|
67
|
+
So if you have an output key of `S3BucketName` defined, you can get the value with
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
puts AWS::StackOutput.s3_bucket_name
|
71
|
+
```
|
72
|
+
|
73
|
+
If you have `stub_responses` set to true, you will have to create a `cfn_dev_output.yml` file with the keys you have defined as Outputs for your Cloud Formation stack.
|
74
|
+
For example, to stub the response of a stack that has a key of `S3BucketName`, create a `cfn_dev_output.yml` file with the contents of:
|
75
|
+
|
76
|
+
```yaml
|
77
|
+
S3BucketName: my_unique_bucket_for_this_stack
|
78
|
+
```
|
79
|
+
|
80
|
+
By default, the gem will look for `cfn_dev_output.yml` in the `config` directory of a Rails app. If you are not using this gem in a Rails app, then you need to specify the path in the initializer.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
AWS::Metadata.configure do |config|
|
84
|
+
config.cfn_stack_name = 'your_cfn_stack_name' # As identified by the Stack Name column in the CloudFormation Section of the AWS console.
|
85
|
+
config.stub_responses = Rails.env =~ /development|test/
|
86
|
+
config.cfn_dev_outputs_path = 'path/to/cfn_dev_output.yml'
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
or
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
AWS::Metadata.cfn_stack_name = 'your_cfn_stack_name'
|
94
|
+
AWS::Metadata.stub_responses = Rails.env =~ /development|test/
|
95
|
+
AWS::Metadata.cfn_dev_outputs_path = 'path/to/cfn_dev_output.yml'
|
96
|
+
AWS::StackOutput.get
|
97
|
+
```
|
98
|
+
|
99
|
+
## Differences between `AWS::InstMD` and `AWS::Instance`
|
100
|
+
|
101
|
+
The code for `AWS::Instance` is mostly a copy directly from the aws_instmd repo. The only differences between `AWS::Instance` and `AWS::InstMD` are:
|
102
|
+
|
103
|
+
1. The class name. We removed the MD(metadata) from the name since this gem also has the StackOutput namespace and it's all really metadata.
|
104
|
+
2. `AWS::InstMD.meta_data` to `AWS::Instance.metadata`. We changed meta_data to metadata to be consistent with the naming in our SDK and APIs.
|
105
|
+
3. The `AWS::Instance.dynamic.instance_identity.document` returns a Hashish object you can call methods on, rather than a JSON document that has to be parsed manually into a hash. So `AWS::Instance.dynamic.instance_identity.document.account_id` just works.
|
106
|
+
4. We added the ability to have stubbed responses returned. See the usage section below.
|
107
|
+
|
108
|
+
## Contributing
|
109
|
+
|
110
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/aws_metadata. 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.
|
111
|
+
|
112
|
+
Thanks to https://github.com/airbnb for their aws_instmd gem.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aws_metadata/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "aws_metadata"
|
8
|
+
spec.version = AWS::Metadata::VERSION
|
9
|
+
spec.authors = ['Evident.io']
|
10
|
+
spec.email = ['support@evident.io']
|
11
|
+
|
12
|
+
spec.summary = %q{Gem to provide the Instance Metadata and Cloud Formation template outputs.}
|
13
|
+
spec.homepage = "https://github.com/EvidentSecurity/aws_metadata"
|
14
|
+
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency 'yard'
|
24
|
+
spec.add_development_dependency 'rdiscount'
|
25
|
+
|
26
|
+
spec.add_runtime_dependency 'aws-sdk'
|
27
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "aws_metadata"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/aws_metadata.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative "extensions/string" unless String.method_defined?(:underscore)
|
2
|
+
require_relative "aws_metadata/version"
|
3
|
+
require_relative "aws_metadata/instance_metadata"
|
4
|
+
require_relative "aws_metadata/cfn_stack_output"
|
5
|
+
|
6
|
+
module AWS
|
7
|
+
module Metadata
|
8
|
+
# For use in a Rails initializer to set the {.cfn_stack_name}, {.stub_responses} and {.cfn_dev_outputs_path}.
|
9
|
+
#
|
10
|
+
# @yield [self]
|
11
|
+
# @return [void]
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# AWS::Metadata.configure do |config|
|
15
|
+
# config.cfn_stack_name = 'your_cfn_stack_name' # As identified by the Stack Name column in the CloudFormation Section of the AWS console.
|
16
|
+
# config.stub_responses = Rails.env =~ /development|test/
|
17
|
+
# config.cfn_dev_outputs_path = 'path/to/cfn_dev_output.yml`
|
18
|
+
# end
|
19
|
+
def self.configure
|
20
|
+
yield self
|
21
|
+
AWS::StackOutput.get
|
22
|
+
end
|
23
|
+
|
24
|
+
# Set to true to return canned Instance responses and stubbed StackOutput responses from a cfn_dev_output.yml file.
|
25
|
+
#
|
26
|
+
# @param stub_responses [Boolean]
|
27
|
+
# @return [Boolean]
|
28
|
+
def self.stub_responses=(stub_responses = false)
|
29
|
+
@stub_responses = stub_responses
|
30
|
+
end
|
31
|
+
|
32
|
+
# The flag whether or not to return canned Instance responses and stubbed StackOutput responses from a cfn_dev_output.yml file.
|
33
|
+
#
|
34
|
+
# @param stub_responses [Boolean]
|
35
|
+
# @return [Boolean]
|
36
|
+
def self.stub_responses
|
37
|
+
@stub_responses
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set the stack name as identified by the Stack Name column in the CloudFormation Section of the AWS console.
|
41
|
+
#
|
42
|
+
# @param stack_name
|
43
|
+
# @return [String]
|
44
|
+
def self.cfn_stack_name=(stack_name)
|
45
|
+
@stack_name = stack_name
|
46
|
+
end
|
47
|
+
|
48
|
+
# The stack name as identified by the Stack Name column in the CloudFormation Section of the AWS console.
|
49
|
+
#
|
50
|
+
# @return [String]
|
51
|
+
def self.cfn_stack_name
|
52
|
+
@stack_name
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set the path to the cfn_dev_output.yml file with the keys you have defined as Outputs for your Cloud Formation stack.
|
56
|
+
#
|
57
|
+
# Only needs to be set if {.stub_responses} is set to true.
|
58
|
+
#
|
59
|
+
# @param stack_name
|
60
|
+
# @return [String]
|
61
|
+
def self.cfn_dev_outputs_path=(dev_outputs_path)
|
62
|
+
@dev_outputs_path = dev_outputs_path
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set the path to the cfn_dev_output.yml file with the keys you have defined as Outputs for your Cloud Formation stack.
|
66
|
+
#
|
67
|
+
# Defaults to the config directory in a Rails application.
|
68
|
+
#
|
69
|
+
# @param stack_name
|
70
|
+
# @return [String]
|
71
|
+
def self.cfn_dev_outputs_path
|
72
|
+
@dev_outputs_path ||= defined?(Rails) ? Rails.root.join('config') : ''
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AWS
|
4
|
+
# @note Dynamic methods are generated from the underscored value of the Output Keys.
|
5
|
+
module StackOutput
|
6
|
+
|
7
|
+
# Makes the call to get the Stack Template's Outputs and dynamically creates methods for each Output.
|
8
|
+
def self.get
|
9
|
+
stack_outputs.each do |o|
|
10
|
+
(
|
11
|
+
class << StackOutput;
|
12
|
+
self
|
13
|
+
end).class_eval do
|
14
|
+
define_method(o.output_key.to_s.underscore.to_sym) { o.output_value }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private_class_method
|
20
|
+
|
21
|
+
# @private
|
22
|
+
def self.client
|
23
|
+
@client ||= Aws::CloudFormation::Client.new(region: AWS::Instance.dynamic.instance_identity.document.region, stub_responses: AWS::Metadata.stub_responses)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
def self.stack
|
28
|
+
@stack ||= client.describe_stacks(stack_name: AWS::Metadata.cfn_stack_name).first.stacks.first
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
def self.stack_outputs
|
33
|
+
@outputs ||= AWS::Metadata.stub_responses ? dev_outputs : stack.outputs
|
34
|
+
end
|
35
|
+
|
36
|
+
# @private
|
37
|
+
def self.dev_outputs
|
38
|
+
require 'erb'
|
39
|
+
output = Struct.new(:output_key, :output_value)
|
40
|
+
yaml = Pathname.new(File.join(AWS::Metadata.cfn_dev_outputs_path, 'cfn_dev_output.yml'))
|
41
|
+
output_values = YAML.load(ERB.new(yaml.read).result)
|
42
|
+
[].tap do |a|
|
43
|
+
output_values.each do |key, value|
|
44
|
+
a << output.new(key, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Original code from https://github.com/airbnb/gem-aws-Instance
|
2
|
+
# It's just a single file so eliminate the dependency by putting it in the repo directly and add parsing for the document object.
|
3
|
+
# Also added response stubs
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module AWS
|
7
|
+
class Instance
|
8
|
+
# @private
|
9
|
+
def self.method_missing name, *args, &block
|
10
|
+
@@root ||= Instance.new
|
11
|
+
@@root.method(name).call(*args, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Can't be the first one to make that pun.
|
15
|
+
# Still proud.
|
16
|
+
# @private
|
17
|
+
class Hashish < Hash
|
18
|
+
def initialize(hash = {})
|
19
|
+
hash.each do |key, value|
|
20
|
+
self[key.to_s.underscore.gsub('_', '-')] = value.is_a?(Hash) ? Hashish.new(value) : value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing name
|
25
|
+
if name.to_s == 'document'
|
26
|
+
Hashish.new(JSON.parse(self['document']))
|
27
|
+
else
|
28
|
+
self[name.to_s.gsub('_', '-')]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
class Treeish < Hashish
|
35
|
+
private
|
36
|
+
def initialize http, prefix
|
37
|
+
entries = Instance.query http, prefix
|
38
|
+
entries.lines.each do |l|
|
39
|
+
l.chomp!
|
40
|
+
if l.end_with? '/'
|
41
|
+
self[l[0..-2]] = Treeish.new http, "#{prefix}#{l}"
|
42
|
+
# meta-data/public-keys/ entries have a '0=foo' format
|
43
|
+
elsif l =~ /(\d+)=(.*)/
|
44
|
+
number, name = $1, $2
|
45
|
+
self[name] = Treeish.new http, "#{prefix}#{number}/"
|
46
|
+
else
|
47
|
+
self[l] = Instance.query http, "#{prefix}#{l}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :user_data, :metadata, :dynamic
|
54
|
+
|
55
|
+
# Amazon, Y U NO trailing slash entries
|
56
|
+
# in /, /$version and /$version/dynamic/??
|
57
|
+
# There is waaay too much code here.
|
58
|
+
# @private
|
59
|
+
def initialize version='latest', host='169.254.169.254', port='80'
|
60
|
+
if AWS::Metadata.stub_responses
|
61
|
+
load_stubs
|
62
|
+
return
|
63
|
+
end
|
64
|
+
http = Net::HTTP.new host, port
|
65
|
+
@metadata = Treeish.new http, "/#{version}/meta-data/"
|
66
|
+
@user_data = Instance.query http, "/#{version}/user-data"
|
67
|
+
@dynamic = Hashish.new
|
68
|
+
|
69
|
+
begin
|
70
|
+
dynamic_stuff = Instance.query(http, "/#{version}/dynamic/").lines
|
71
|
+
rescue
|
72
|
+
dynamic_stuff = []
|
73
|
+
end
|
74
|
+
dynamic_stuff.each do |e|
|
75
|
+
e = e.chomp.chomp '/'
|
76
|
+
@dynamic[e] = Treeish.new http, "/#{version}/dynamic/#{e}/"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# @private
|
81
|
+
def self.query http, path
|
82
|
+
rep = http.request Net::HTTP::Get.new path
|
83
|
+
unless Net::HTTPOK === rep
|
84
|
+
raise Net::HTTPBadResponse, "#{rep.code} #{path}"
|
85
|
+
end
|
86
|
+
rep.body
|
87
|
+
end
|
88
|
+
|
89
|
+
# Helper method to provide "stubs" for non aws deployments
|
90
|
+
# @private
|
91
|
+
def load_stubs
|
92
|
+
responses = YAML.load_file(File.expand_path(File.dirname(__FILE__) + '/../../test/fixtures/responses.yml'))
|
93
|
+
@metadata = Hashish.new responses[:metadata]
|
94
|
+
@user_data = responses[:user_data]
|
95
|
+
@dynamic = Hashish.new responses[:dynamic]
|
96
|
+
@dynamic['instance-identity']['document'] = @dynamic['instance-identity']['document'].to_json
|
97
|
+
end
|
98
|
+
|
99
|
+
# All the metadata from 169.254.169.254
|
100
|
+
#
|
101
|
+
# The hashes are Hashish objects that allows regular method like calls where all method names are the keys underscored.
|
102
|
+
def to_hash
|
103
|
+
{ :metadata => @metadata, :user_data => @user_data, :dynamic => @dynamic }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copied from ActiveSupport so we don't have to add ActiveSupport as a dependency just for this method.
|
2
|
+
class String
|
3
|
+
# Makes an underscored, lowercase form from the expression in the string.
|
4
|
+
#
|
5
|
+
# Changes '::' to '/' to convert namespaces to paths.
|
6
|
+
#
|
7
|
+
# 'ActiveModel'.underscore # => "active_model"
|
8
|
+
# 'ActiveModel::Errors'.underscore # => "active_model/errors"
|
9
|
+
#
|
10
|
+
# As a rule of thumb you can think of +underscore+ as the inverse of
|
11
|
+
# +camelize+, though there are cases where that does not hold:
|
12
|
+
#
|
13
|
+
# 'SSLError'.underscore.camelize # => "SslError"
|
14
|
+
def underscore
|
15
|
+
return self unless self =~ /[A-Z-]|::/
|
16
|
+
word = self.to_s.gsub(/::/, '/')
|
17
|
+
# word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
|
18
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
19
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
20
|
+
word.tr!("-", "_")
|
21
|
+
word.downcase!
|
22
|
+
word
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
:metadata:
|
2
|
+
ami-id: ami-81b164e1
|
3
|
+
ami-id: ami-id
|
4
|
+
ami-launch-index: '0'
|
5
|
+
ami-manifest-path: (unknown)
|
6
|
+
block-device-mapping:
|
7
|
+
ami: /dev/sda1
|
8
|
+
root: /dev/sda1
|
9
|
+
hostname: ip.us-west-2.compute.internal
|
10
|
+
iam:
|
11
|
+
info:
|
12
|
+
Code: Success
|
13
|
+
LastUpdated: 2016-08-26T13:06:48Z
|
14
|
+
InstanceProfileArn: arn:aws:iam::account:instance-profile/Role
|
15
|
+
InstanceProfileId: Profile ID
|
16
|
+
security-credentials:
|
17
|
+
Role:
|
18
|
+
Code: Success
|
19
|
+
LastUpdated: 2016-08-26T13:08:20Z
|
20
|
+
Type: AWS-HMAC
|
21
|
+
AccessKeyId: access id
|
22
|
+
SecretAccessKey: secret key
|
23
|
+
Token: token
|
24
|
+
Expiration: 2016-08-26T19:21:06Z
|
25
|
+
instance-action: none
|
26
|
+
instance-id: i-id
|
27
|
+
instance-type: c3.xlarge
|
28
|
+
local-hostname: ip.us-west-2.compute.internal
|
29
|
+
local-ipv4: 1.1.1.1
|
30
|
+
mac: 1:1:1:1:1:1
|
31
|
+
metrics:
|
32
|
+
vhostmd: <?xml version=1.0 encoding=UTF-8?>
|
33
|
+
network:
|
34
|
+
interfaces:
|
35
|
+
macs:
|
36
|
+
1:1:1:1:1:1:
|
37
|
+
device-number: '0'
|
38
|
+
interface-id: eni-1
|
39
|
+
local-hostname: ip.us-west-2.compute.internal
|
40
|
+
local-ipv4s: 1.1.1.1
|
41
|
+
mac: 1:1:1:1:1:1
|
42
|
+
owner-id: 'accountid'
|
43
|
+
security-group-ids: sg-id
|
44
|
+
security-groups: SecurityGroup-111
|
45
|
+
subnet-id: subnet-1
|
46
|
+
subnet-ipv4-cidr-block: 1.1.1.1/24
|
47
|
+
vpc-id: vpc-id
|
48
|
+
vpc-ipv4-cidr-block: 1.1.1.1/21
|
49
|
+
vpc-ipv4-cidr-blocks: 1.1.1.1/21
|
50
|
+
placement:
|
51
|
+
availability-zone: us-west-2c
|
52
|
+
profile: default-hvm
|
53
|
+
public-keys:
|
54
|
+
dev:
|
55
|
+
openssh-key: 'key'
|
56
|
+
reservation-id: r-id
|
57
|
+
security-groups: SecurityGroup-111
|
58
|
+
services:
|
59
|
+
domain: amazonaws.com
|
60
|
+
partition: aws
|
61
|
+
:user_data: 'user data'
|
62
|
+
:dynamic:
|
63
|
+
instance-identity:
|
64
|
+
pkcs7: bogus
|
65
|
+
document:
|
66
|
+
devpayProductCodes: null
|
67
|
+
availabilityZone: us-west-2c
|
68
|
+
accountId: accountid
|
69
|
+
privateIp: 1.1.1.1
|
70
|
+
version: 2010-08-31
|
71
|
+
region: us-west-2
|
72
|
+
instanceId: i-id
|
73
|
+
billingProducts: null
|
74
|
+
instanceType: c3.xlarge
|
75
|
+
imageId: ami-id
|
76
|
+
pendingTime: 2016-08-25T16:22:18Z
|
77
|
+
architecture: x86_64
|
78
|
+
kernelId: null
|
79
|
+
ramdiskId: null
|
80
|
+
signature: signature
|
81
|
+
rsa2048: rsa2048
|
82
|
+
fws:
|
83
|
+
instance-monitoring: enabled
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws_metadata
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Evident.io
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdiscount
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- support@evident.io
|
86
|
+
executables:
|
87
|
+
- console
|
88
|
+
- setup
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".ruby-gemset"
|
94
|
+
- ".ruby-version"
|
95
|
+
- ".travis.yml"
|
96
|
+
- ".yardopts"
|
97
|
+
- CODE_OF_CONDUCT.md
|
98
|
+
- Gemfile
|
99
|
+
- Gemfile.lock
|
100
|
+
- LICENSE.txt
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- aws_metadata.gemspec
|
104
|
+
- bin/console
|
105
|
+
- bin/setup
|
106
|
+
- lib/aws_metadata.rb
|
107
|
+
- lib/aws_metadata/cfn_stack_output.rb
|
108
|
+
- lib/aws_metadata/instance_metadata.rb
|
109
|
+
- lib/aws_metadata/version.rb
|
110
|
+
- lib/extensions/string.rb
|
111
|
+
- test/fixtures/responses.yml
|
112
|
+
homepage: https://github.com/EvidentSecurity/aws_metadata
|
113
|
+
licenses: []
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.4.8
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Gem to provide the Instance Metadata and Cloud Formation template outputs.
|
135
|
+
test_files:
|
136
|
+
- test/fixtures/responses.yml
|