awsmeta 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 22655250d2a0f509faa429b62ea98f640c06d3b329c7a936329323f0ba5176ff
4
+ data.tar.gz: '036388775705add35cbb434f1922c1e01e82a9d7c971ac82d90b8ad12509d180'
5
+ SHA512:
6
+ metadata.gz: 72f8db6eb94cbfb7837ab59d9ce4c233327d8b3d6b572cc6102d58d33bb29e24fea032e9ef0a1eab28b7a7673b19ec240ad1b6ce65a5b22435df298ec06eb1a7
7
+ data.tar.gz: f2c8ad18eb645d18e3414375596ae6b53263d20dfb697157ee7d1851c673471a772f14a20005518e2bc1ce4871afc6e0227328bf10e26e46eafb8b9acb582b1c
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ - 2.7
5
+ install:
6
+ - bundle install
7
+ script:
8
+ - gem build awsmeta.gemspec
9
+ - rspec
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'rspec'
9
+ end
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ awsmeta (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rspec (3.9.0)
11
+ rspec-core (~> 3.9.0)
12
+ rspec-expectations (~> 3.9.0)
13
+ rspec-mocks (~> 3.9.0)
14
+ rspec-core (3.9.1)
15
+ rspec-support (~> 3.9.1)
16
+ rspec-expectations (3.9.0)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.9.0)
19
+ rspec-mocks (3.9.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.9.0)
22
+ rspec-support (3.9.2)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ awsmeta!
29
+ rspec
30
+
31
+ BUNDLED WITH
32
+ 2.0.2
@@ -0,0 +1,24 @@
1
+ MIT License
2
+ -----------
3
+
4
+ Copyright (c) 2020 Hayden McFarland
5
+ Permission is hereby granted, free of charge, to any person
6
+ obtaining a copy of this software and associated documentation
7
+ files (the "Software"), to deal in the Software without
8
+ restriction, including without limitation the rights to use,
9
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the
11
+ Software is furnished to do so, subject to the following
12
+ conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ # awsmeta
2
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/adfb8333557241e81a02/maintainability)](https://codeclimate.com/github/haydenmcfarland/awsmeta/maintainability)
4
+ [![Build Status](https://travis-ci.org/haydenmcfarland/awsmeta.svg?branch=master)](https://travis-ci.org/haydenmcfarland/awsmeta)
5
+
6
+ # How to use
7
+
8
+ Add `awsmeta` to your gem file:
9
+
10
+ ```ruby
11
+ gem 'awsmeta', git: 'https://github.com/haydenmcfarland/awsmeta'
12
+ ```
13
+
14
+ Run `bundle install`
15
+
16
+ # Example usage
17
+
18
+ ```ruby
19
+ Awsmeta.credentials
20
+
21
+ {
22
+ :code=>"Success",
23
+ :last_updated=>"2020-03-02T03:04:00Z",
24
+ :type=>"AWS-HMAC",
25
+ :access_key_id=>"***",
26
+ :secret_access_key=>"***",
27
+ :token=>"***",
28
+ :expiration=>"2020-03-02T09:39:04Z"
29
+ }
30
+ ```
31
+
32
+ ```ruby
33
+ Awsmeta.document
34
+
35
+ {
36
+ :account_id=>"***",
37
+ :architecture=>"x86_64",
38
+ :availability_zone=>"us-west-2a",
39
+ :billing_products=>nil,
40
+ :devpay_product_codes=>nil,
41
+ :marketplace_product_codes=>nil,
42
+ :image_id=>"ami-***",
43
+ :instance_id=>"i-***",
44
+ :instance_type=>"t2.micro",
45
+ :kernel_id=>nil,
46
+ :pending_time=>"2020-03-02T02:58:35Z",
47
+ :private_ip=>"*.*.*.*",
48
+ :ramdisk_id=>nil,
49
+ :region=>"us-west-2",
50
+ :version=>"2017-09-30"
51
+ }
52
+ ```
53
+
54
+ ```ruby
55
+ Awsmeta.instance_id
56
+ "i-***"
57
+ ```
58
+
59
+ ```ruby
60
+ Awsmeta.role
61
+ "ec2role"
62
+ ```
63
+
64
+ If a role is not defined, the `credential` and `role` calls will raise
65
+ an `A`wsmeta::Errors::ResourceNotFound` error.
66
+
67
+ ```ruby
68
+ Awsmeta.role
69
+ Awsmeta::Errors::ResourceNotFound (Not Found)
70
+ ```
@@ -0,0 +1,22 @@
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_relative 'lib/awsmeta/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'awsmeta'
9
+ s.version = Awsmeta::VERSION
10
+ s.authors = ['haydenmcfarland']
11
+ s.email = ['mcfarlandsms@gmail.com']
12
+ s.date = '2020-02-28'
13
+ s.summary = 'AWS metadata loader'
14
+ s.description = 'AWS metadata loader'
15
+ s.homepage = 'https://github.com/haydenmcfarland/awsmeta'
16
+ s.license = 'MIT'
17
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+
21
+ s.require_paths = ['lib']
22
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'uri'
6
+
7
+ # require gem ruby files
8
+ Dir[File.dirname(__FILE__) + '/**/*.rb'].sort.each { |file| require file }
9
+
10
+ # Awsmeta retrieves metadata from AWS EC2 instances
11
+ module Awsmeta
12
+ module_function
13
+
14
+ def credentials
15
+ path = ResourcePaths::Metadata::CREDENTIALS_PATH
16
+ result = Query.fetch("#{path}/#{role}")
17
+ Helpers::Hash.symbolize_and_underscore_keys(result)
18
+ end
19
+
20
+ def document
21
+ path = ResourcePaths::Dynamic::INSTANCE_IDENTITY_PATH
22
+ result = Query.fetch(path, true)
23
+ Helpers::Hash.symbolize_and_underscore_keys(result)
24
+ end
25
+
26
+ def instance_id
27
+ Query.fetch(ResourcePaths::Metadata::INSTANCE_ID_PATH)
28
+ end
29
+
30
+ def role
31
+ Query.fetch(ResourcePaths::Metadata::CREDENTIALS_PATH)
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ # contains configuration methods
5
+ module Config
6
+ module_function
7
+
8
+ def read_timeout
9
+ (ENV['AWSMETA_READ_TIMEOUT'] || 10).to_i
10
+ end
11
+
12
+ def open_timeout
13
+ (ENV['AWSMETA_OPEN_TIMEOUT'] || 10).to_i
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ module Constants
5
+ # aws reserved host used to get instance meta-data
6
+ METADATA_HOST = '169.254.169.254'
7
+ METADATA_BASE_URL = "http://#{METADATA_HOST}"
8
+ METADATA_LATEST_BASE_URL = "#{METADATA_BASE_URL}/latest/%s"
9
+ METADATA_LATEST_URL = "#{METADATA_LATEST_BASE_URL % 'meta-data'}/%s"
10
+ METADATA_LATEST_DYNAMIC_URL = "#{METADATA_LATEST_BASE_URL % 'dynamic'}/%s"
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ module Errors
5
+ class ResourceNotFound < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ # used to process metadata responses
5
+ module Extras
6
+ # useful extras that help with integration
7
+ module Discovery
8
+ module_function
9
+
10
+ # check for if code is executing on an ec2 instance
11
+ def ec2?
12
+ return false if ENV['AWSMETA_DISABLE_EC2_DISCOVERY'] == 'true'
13
+
14
+ !Awsmeta.instance_id.nil?
15
+ rescue Net::OpenTimeout,
16
+ Errno::EHOSTUNREACH,
17
+ Awsmeta::Errors::ResourceNotFound
18
+ false
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ # used to process metadata responses
5
+ module Helpers
6
+ # a set of hash processors
7
+ module Hash
8
+ module_function
9
+
10
+ def underscore(camel_cased_word)
11
+ return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
12
+
13
+ word = camel_cased_word.to_s.gsub('::', '/')
14
+ word.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
15
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
16
+ .tr('-', '_')
17
+ .downcase
18
+ end
19
+
20
+ def symbolize_and_underscore_keys(obj)
21
+ obj.each_with_object({}) do |(k, v), h|
22
+ h[k.nil? ? k : underscore(k).to_sym] = v
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ # contains methods to query meta data
5
+ module Query
6
+ module_function
7
+
8
+ def query_metadata(query)
9
+ url = Awsmeta::Constants::METADATA_LATEST_URL
10
+ Awsmeta::Request.request(url % query)
11
+ end
12
+
13
+ def query_dynamic(query)
14
+ url = Awsmeta::Constants::METADATA_LATEST_DYNAMIC_URL
15
+ Awsmeta::Request.request(url % query)
16
+ end
17
+
18
+ def fetch(query, dynamic = false)
19
+ result = dynamic ? query_dynamic(query) : query_metadata(query)
20
+
21
+ raise Awsmeta::Errors::ResourceNotFound, result[:error] unless
22
+ result[:resource]
23
+
24
+ result[:resource]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ # contains methods used to request and parse metadata
5
+ module Request
6
+ module_function
7
+
8
+ def get(url)
9
+ uri = URI.parse(url)
10
+ req = Net::HTTP.new(uri.host, uri.port)
11
+ req.read_timeout = Awsmeta::Config.read_timeout
12
+ req.open_timeout = Awsmeta::Config.open_timeout
13
+ req.start { |http| http.get(uri.to_s) }
14
+ end
15
+
16
+ def safe_json_parse(string)
17
+ JSON.parse(string)
18
+ rescue JSON::ParserError
19
+ string
20
+ end
21
+
22
+ def request(url)
23
+ response = get(url)
24
+ return { error: response.message, code: response.code } if
25
+ response.code != '200'
26
+
27
+ result = safe_json_parse(response.body)
28
+ { resource: result }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ module ResourcePaths
5
+ module Dynamic
6
+ INSTANCE_IDENTITY_PATH = 'instance-identity/document'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ module ResourcePaths
5
+ module Metadata
6
+ CREDENTIALS_PATH = 'iam/security-credentials'
7
+ INSTANCE_ID_PATH = 'instance-id'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Awsmeta
4
+ VERSION = '1.0.0'
5
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awsmeta
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - haydenmcfarland
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: AWS metadata loader
14
+ email:
15
+ - mcfarlandsms@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - ".travis.yml"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE.txt
25
+ - README.md
26
+ - awsmeta.gemspec
27
+ - lib/awsmeta.rb
28
+ - lib/awsmeta/config.rb
29
+ - lib/awsmeta/constants.rb
30
+ - lib/awsmeta/errors/resource_not_found.rb
31
+ - lib/awsmeta/extras/discovery.rb
32
+ - lib/awsmeta/helpers/hash/hash.rb
33
+ - lib/awsmeta/query.rb
34
+ - lib/awsmeta/request.rb
35
+ - lib/awsmeta/resource_paths/dynamic.rb
36
+ - lib/awsmeta/resource_paths/metadata.rb
37
+ - lib/awsmeta/version.rb
38
+ homepage: https://github.com/haydenmcfarland/awsmeta
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubygems_version: 3.0.3
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: AWS metadata loader
61
+ test_files: []