├── .gitignore ├── .gitlab-ci.yml ├── .travis.yml ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── fluent-plugin-ec2-metadata.gemspec ├── lib └── fluent │ └── plugin │ ├── ec2_metadata.rb │ ├── filter_ec2_metadata.rb │ └── out_ec2_metadata.rb └── test ├── cassettes ├── ec2-classic.yml ├── ec2-vpc-with-imdsv2.yml └── ec2-vpc.yml ├── helper.rb └── plugin ├── test_filter_ec2_metadata.rb └── test_out_ec2_metadata.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | .idea 7 | Gemfile.lock 8 | InstalledFiles 9 | _yardoc 10 | coverage 11 | doc/ 12 | lib/bundler/man 13 | pkg 14 | rdoc 15 | spec/reports 16 | test/tmp 17 | test/version_tmp 18 | tmp 19 | vendor/bundle 20 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - build 3 | - test 4 | 5 | bundle: 6 | stage: build 7 | image: ruby:2.5 8 | cache: 9 | paths: 10 | - vendor/ruby 11 | script: 12 | - bundle install -j $(nproc) --path vendor 13 | artifacts: 14 | paths: 15 | - Gemfile.lock 16 | 17 | dependency_scanning: 18 | stage: test 19 | image: docker:stable 20 | variables: 21 | DOCKER_DRIVER: overlay2 22 | allow_failure: true 23 | services: 24 | - docker:stable-dind 25 | script: 26 | - export DS_VERSION=${SP_VERSION:-$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')} 27 | - | 28 | if ! docker info &>/dev/null; then 29 | if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then 30 | export DOCKER_HOST='tcp://localhost:2375' 31 | fi 32 | fi 33 | - | # this is required to avoid undesirable reset of Docker image ENV variables being set on build stage 34 | function propagate_env_vars() { 35 | CURRENT_ENV=$(printenv) 36 | 37 | for VAR_NAME; do 38 | echo $CURRENT_ENV | grep "${VAR_NAME}=" > /dev/null && echo "--env $VAR_NAME " 39 | done 40 | } 41 | - | 42 | docker run \ 43 | $(propagate_env_vars \ 44 | DS_ANALYZER_IMAGES \ 45 | DS_ANALYZER_IMAGE_PREFIX \ 46 | DS_ANALYZER_IMAGE_TAG \ 47 | DS_DEFAULT_ANALYZERS \ 48 | DS_EXCLUDED_PATHS \ 49 | DEP_SCAN_DISABLE_REMOTE_CHECKS \ 50 | DS_DOCKER_CLIENT_NEGOTIATION_TIMEOUT \ 51 | DS_PULL_ANALYZER_IMAGE_TIMEOUT \ 52 | DS_RUN_ANALYZER_TIMEOUT \ 53 | ) \ 54 | --volume "$PWD:/code" \ 55 | --volume /var/run/docker.sock:/var/run/docker.sock \ 56 | "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$DS_VERSION" /code 57 | artifacts: 58 | reports: 59 | dependency_scanning: gl-dependency-scanning-report.json 60 | dependencies: 61 | - bundle 62 | only: 63 | refs: 64 | - branches 65 | variables: 66 | - $GITLAB_FEATURES =~ /\bdependency_scanning\b/ 67 | except: 68 | variables: 69 | - $DEPENDENCY_SCANNING_DISABLED 70 | 71 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 2.1.* 3 | - 2.2.* 4 | - 2.3.* 5 | - 2.4.* 6 | - 2.5.* 7 | gemfile: 8 | - Gemfile 9 | before_install: gem update bundler 10 | after_script: codeclimate-test-reporter 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | group :test do 6 | gem 'codeclimate-test-reporter', require: nil 7 | end 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014- SAKAMOTO Takumi 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fluent-plugin-ec2-metadata 2 | 3 | [![Gem Version](https://badge.fury.io/rb/fluent-plugin-ec2-metadata.svg)](http://badge.fury.io/rb/fluent-plugin-ec2-metadata) 4 | [![Build Status](https://travis-ci.org/takus/fluent-plugin-ec2-metadata.svg?branch=master)](https://travis-ci.org/takus/fluent-plugin-ec2-metadata) 5 | [![Test Coverage](https://codeclimate.com/github/takus/fluent-plugin-ec2-metadata/badges/coverage.svg)](https://codeclimate.com/github/takus/fluent-plugin-ec2-metadata/coverage) 6 | [![Code Climate](https://codeclimate.com/github/takus/fluent-plugin-ec2-metadata/badges/gpa.svg)](https://codeclimate.com/github/takus/fluent-plugin-ec2-metadata) 7 | [![Codacy Badge](https://api.codacy.com/project/badge/grade/16f6786edb554f1ea7462353808011d6)](https://www.codacy.com/app/takus/fluent-plugin-ec2-metadata) 8 | 9 | [Fluentd](http://fluentd.org) plugin to add Amazon EC2 metadata fields to a event record 10 | 11 | ## Requirements 12 | 13 | | fluent-plugin-ec2-metadata | fluentd | ruby | 14 | |--------------------|------------|--------| 15 | | >= 0.1.0 | v0.14.x | >= 2.1 | 16 | | 0.0.15 <= | v0.12.x | >= 1.9 | 17 | 18 | ## Installation 19 | Use RubyGems: 20 | 21 | gem install fluent-plugin-ec2-metadata 22 | 23 | ## Configuration 24 | 25 | Example: 26 | 27 | 28 | @type ec2_metadata 29 | 30 | aws_key_id YOUR_AWS_KEY_ID 31 | aws_sec_key YOUR_AWS_SECRET/KEY 32 | 33 | metadata_refresh_seconds 300 # Optional, default 300 seconds 34 | imdsv2 true # Optional, default false 35 | 36 | output_tag ${instance_id}.${tag} 37 | 38 | hostname ${tagset_name} 39 | instance_id ${instance_id} 40 | instance_type ${instance_type} 41 | az ${availability_zone} 42 | private_ip ${private_ip} 43 | vpc_id ${vpc_id} 44 | ami_id ${image_id} 45 | account_id ${account_id} 46 | 47 | 48 | 49 | Assume following input is coming: 50 | 51 | ``` 52 | foo.bar {"message":"hello ec2!"} 53 | ``` 54 | 55 | then output becomes as below (indented): 56 | 57 | ``` 58 | i-28b5ee77.foo.bar { 59 | "hostname" : "web0001", 60 | "instance_id" : "i-28b5ee77", 61 | "instance_type" : "m1.large", 62 | "az" : "us-west-1b", 63 | "private_ip : "10.21.34.200", 64 | "vpc_id" : "vpc-25dab194", 65 | "account_id" : "123456789", 66 | "image_id" : "ami-123456", 67 | "message" : "hello ec2!" 68 | } 69 | ``` 70 | 71 | Or you can use filter version: 72 | 73 | 74 | @type ec2_metadata 75 | 76 | aws_key_id YOUR_AWS_KEY_ID 77 | aws_sec_key YOUR_AWS_SECRET/KEY 78 | 79 | metadata_refresh_seconds 300 # Optional, default 300 seconds 80 | imdsv2 true # Optional, default false 81 | 82 | 83 | hostname ${tagset_name} 84 | instance_id ${instance_id} 85 | instance_type ${instance_type} 86 | private_ip ${private_ip} 87 | az ${availability_zone} 88 | vpc_id ${vpc_id} 89 | ami_id ${image_id} 90 | account_id ${account_id} 91 | 92 | 93 | 94 | ### Placeholders 95 | 96 | The following placeholders are always available: 97 | 98 | * ${tag} input tag 99 | * ${tag_parts} input tag splitted by '.'. you can use it like `${tag_parts[0]}` or `${tag_parts[-1]}` 100 | * ${instance_id} instance id 101 | * ${instance_type} instance type 102 | * ${availability_zone} availability zone 103 | * ${region} region 104 | * ${private_ip} private ip 105 | * ${mac} MAC address 106 | * ${vpc_id} vpc id 107 | * ${subnet_id} subnet id 108 | * ${account_id} account id 109 | * ${image_id} ami image id 110 | 111 | The followings are available when you define `aws_key_id` and `aws_sec_key`(or define IAM Policy): 112 | 113 | * ${tagset_xxx} EC2 tag (e.g. tagset_name is replaced by the value of Key = Name) 114 | 115 | The following is an example for a minimal IAM policy needed to ReadOnlyAccess to EC2. 116 | 117 | ``` 118 | { 119 | "Version": "2012-10-17", 120 | "Statement": [ 121 | { 122 | "Effect": "Allow", 123 | "Action": "ec2:Describe*", 124 | "Resource": "*" 125 | }, 126 | { 127 | "Effect": "Allow", 128 | "Action": "elasticloadbalancing:Describe*", 129 | "Resource": "*" 130 | }, 131 | { 132 | "Effect": "Allow", 133 | "Action": [ 134 | "cloudwatch:ListMetrics", 135 | "cloudwatch:GetMetricStatistics", 136 | "cloudwatch:Describe*" 137 | ], 138 | "Resource": "*" 139 | }, 140 | { 141 | "Effect": "Allow", 142 | "Action": "autoscaling:Describe*", 143 | "Resource": "*" 144 | } 145 | ] 146 | } 147 | ``` 148 | 149 | Refer to the [AWS documentation](http://docs.aws.amazon.com/IAM/latest/UserGuide/ExampleIAMPolicies.html) for example policies. 150 | Using [IAM roles](http://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html) with a properly configured IAM policy are preferred over embedding access keys on EC2 instances. 151 | 152 | ## Contributing 153 | 154 | 1. Fork it 155 | 2. Create your feature branch (`git checkout -b my-new-feature`) 156 | 3. Commit your changes (`git commit -am 'Add some feature'`) 157 | 4. Push to the branch (`git push origin my-new-feature`) 158 | 5. Create new Pull Request 159 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "fluent/version" 3 | require "rake/testtask" 4 | 5 | Rake::TestTask.new(:test) do |test| 6 | test.libs << 'lib' << 'test' 7 | 8 | test.test_files = case 9 | when Fluent::VERSION.start_with?("0.10.") 10 | ["test/plugin/test_out_ec2_metadata.rb"] 11 | else 12 | Dir['test/**/test_*.rb'] 13 | end 14 | 15 | test.verbose = true 16 | end 17 | 18 | task default: :test 19 | -------------------------------------------------------------------------------- /fluent-plugin-ec2-metadata.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "fluent-plugin-ec2-metadata" 7 | spec.version = "0.1.3" 8 | spec.authors = ["SAKAMOTO Takumi"] 9 | spec.email = ["takumi.saka@gmail.com"] 10 | spec.description = %q{Fluentd output plugin to add Amazon EC2 metadata fields to a event record} 11 | spec.summary = %q{Fluentd output plugin to add Amazon EC2 metadata fields to a event record} 12 | spec.homepage = "https://github.com/takus/fluent-plugin-ec2-metadata" 13 | spec.license = "APLv2" 14 | 15 | spec.files = `git ls-files`.split($/) 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.add_runtime_dependency "fluentd", "> 0.14.0" 21 | spec.add_runtime_dependency "oj" 22 | spec.add_runtime_dependency "aws-sdk-ec2", "~> 1.1.0" 23 | 24 | spec.add_development_dependency "rake" 25 | spec.add_development_dependency "vcr" 26 | spec.add_development_dependency "webmock" 27 | spec.add_development_dependency "test-unit", ">= 3.1.0" 28 | end 29 | -------------------------------------------------------------------------------- /lib/fluent/plugin/ec2_metadata.rb: -------------------------------------------------------------------------------- 1 | module Fluent 2 | module EC2Metadata 3 | 4 | def initialize 5 | super 6 | require 'net/http' 7 | require 'aws-sdk-ec2' 8 | require 'oj' 9 | end 10 | 11 | def configure(conf) 12 | super 13 | 14 | # directive 15 | @map = {} 16 | conf.elements.select { |element| element.name == 'record' }.each { |element| 17 | element.each_pair { |k, v| 18 | element.has_key?(k) # to suppress unread configuration warning 19 | @map[k] = v 20 | } 21 | } 22 | 23 | @placeholder_expander = PlaceholderExpander.new(log) 24 | 25 | # get metadata first and then setup a refresh thread 26 | @ec2_metadata = get_metadata_and_tags 27 | @refresh_thread = Thread.new { 28 | while true 29 | sleep @metadata_refresh_seconds 30 | @ec2_metadata = get_metadata_and_tags 31 | end 32 | } 33 | end 34 | 35 | private 36 | 37 | def get_metadata_and_tags 38 | metadata = {} 39 | set_metadata(metadata) 40 | set_tag(metadata) 41 | metadata 42 | end 43 | 44 | def set_metadata(ec2_metadata) 45 | instance_identity = Oj.load(get_dynamic_data("instance-identity/document")) 46 | ec2_metadata['account_id'] = instance_identity["accountId"] 47 | ec2_metadata['image_id'] = instance_identity["imageId"] 48 | 49 | ec2_metadata['instance_id'] = get_metadata('instance-id') 50 | ec2_metadata['instance_type'] = get_metadata('instance-type') 51 | ec2_metadata['availability_zone'] = get_metadata('placement/availability-zone') 52 | ec2_metadata['region'] = ec2_metadata['availability_zone'].chop 53 | ec2_metadata['private_ip'] = get_metadata('local-ipv4') 54 | ec2_metadata['mac'] = get_metadata('mac') 55 | begin 56 | ec2_metadata['vpc_id'] = get_metadata("network/interfaces/macs/#{ec2_metadata['mac']}/vpc-id") 57 | rescue 58 | ec2_metadata['vpc_id'] = nil 59 | log.info "ec2-metadata: 'vpc_id' is undefined #{ec2_metadata['instance_id']} is not in VPC}" 60 | end 61 | begin 62 | ec2_metadata['subnet_id'] = get_metadata("network/interfaces/macs/#{ec2_metadata['mac']}/subnet-id") 63 | rescue 64 | ec2_metadata['subnet_id'] = nil 65 | log.info "ec2-metadata: 'subnet_id' is undefined because #{ec2_metadata['instance_id']} is not in VPC}" 66 | end 67 | ec2_metadata 68 | end 69 | 70 | def get_dynamic_data(f) 71 | Net::HTTP.start('169.254.169.254') do |http| 72 | res = http.get("/latest/dynamic/#{f}", get_header()) 73 | raise Fluent::ConfigError, "ec2-dynamic-data: failed to get #{f}" unless res.is_a?(Net::HTTPSuccess) 74 | res.body 75 | end 76 | end 77 | 78 | def get_metadata(f) 79 | Net::HTTP.start('169.254.169.254') do |http| 80 | res = http.get("/latest/meta-data/#{f}", get_header()) 81 | raise Fluent::ConfigError, "ec2-metadata: failed to get #{f}" unless res.is_a?(Net::HTTPSuccess) 82 | res.body 83 | end 84 | end 85 | 86 | def get_header() 87 | if @imdsv2 88 | Net::HTTP.start('169.254.169.254') do |http| 89 | res = http.put("/latest/api/token", '', { 'X-aws-ec2-metadata-token-ttl-seconds' => '300' }) 90 | raise Fluent::ConfigError, "ec2-metadata: failed to get token" unless res.is_a?(Net::HTTPSuccess) 91 | { 'X-aws-ec2-metadata-token' => res.body } 92 | end 93 | else 94 | {} 95 | end 96 | end 97 | 98 | def set_tag(ec2_metadata) 99 | if @map.values.any? { |v| v.match(/^\${tagset_/) } || @output_tag =~ /\${tagset_/ 100 | 101 | if @aws_key_id and @aws_sec_key 102 | ec2 = Aws::EC2::Client.new( 103 | region: ec2_metadata['region'], 104 | access_key_id: @aws_key_id, 105 | secret_access_key: @aws_sec_key, 106 | ) 107 | else 108 | ec2 = Aws::EC2::Client.new( 109 | region: ec2_metadata['region'], 110 | ) 111 | end 112 | 113 | response = ec2.describe_instances({ :instance_ids => [ec2_metadata['instance_id']] }) 114 | instance = response.reservations[0].instances[0] 115 | raise Fluent::ConfigError, "ec2-metadata: failed to get instance data #{response.pretty_inspect}" if instance.nil? 116 | 117 | instance.tags.each { |tag| 118 | ec2_metadata["tagset_#{tag.key.downcase}"] = tag.value 119 | } 120 | end 121 | end 122 | 123 | def modify_record(record, tag, tag_parts) 124 | placeholders = @placeholder_expander.prepare_placeholders(record, tag, tag_parts, @ec2_metadata) 125 | new_record = record.dup 126 | @map.each_pair { |k, v| new_record[k] = @placeholder_expander.expand(v, placeholders) } 127 | new_record 128 | end 129 | 130 | def modify(output_tag, record, tag, tag_parts) 131 | placeholders = @placeholder_expander.prepare_placeholders(record, tag, tag_parts, @ec2_metadata) 132 | 133 | new_tag = @placeholder_expander.expand(output_tag, placeholders) 134 | 135 | new_record = record.dup 136 | @map.each_pair { |k, v| new_record[k] = @placeholder_expander.expand(v, placeholders) } 137 | 138 | [new_tag, new_record] 139 | end 140 | 141 | class PlaceholderExpander 142 | def initialize(log) 143 | @log = log 144 | end 145 | 146 | # referenced https://github.com/fluent/fluent-plugin-rewrite-tag-filter 147 | # referenced https://github.com/sonots/fluent-plugin-record-reformer 148 | attr_reader :placeholders 149 | 150 | def prepare_placeholders(_record, tag, tag_parts, ec2_metadata) 151 | placeholders = { 152 | '${tag}' => tag, 153 | } 154 | 155 | size = tag_parts.size 156 | tag_parts.each_with_index { |t, idx| 157 | placeholders.store("${tag_parts[#{idx}]}", t) 158 | placeholders.store("${tag_parts[#{idx-size}]}", t) # support tag_parts[-1] 159 | } 160 | 161 | ec2_metadata.each { |k, v| 162 | placeholders.store("${#{k}}", v) 163 | } 164 | 165 | placeholders 166 | end 167 | 168 | def expand(str, placeholders) 169 | str.gsub(/(\${[a-z_:\-]+(\[-?[0-9]+\])?}|__[A-Z_]+__)/) { 170 | @log.warn "ec2-metadata: unknown placeholder `#{$1}` found in a tag `#{placeholders['${tag}']}`" unless placeholders.include?($1) 171 | placeholders[$1] 172 | } 173 | end 174 | end 175 | end 176 | end 177 | -------------------------------------------------------------------------------- /lib/fluent/plugin/filter_ec2_metadata.rb: -------------------------------------------------------------------------------- 1 | require 'fluent/plugin/filter' 2 | require_relative 'ec2_metadata' 3 | 4 | module Fluent::Plugin 5 | class EC2MetadataFilter < Filter 6 | include Fluent::EC2Metadata 7 | 8 | Fluent::Plugin.register_filter('ec2_metadata', self) 9 | 10 | config_param :aws_key_id, :string, default: ENV['AWS_ACCESS_KEY_ID'], secret: true 11 | config_param :aws_sec_key, :string, default: ENV['AWS_SECRET_ACCESS_KEY'], secret: true 12 | config_param :metadata_refresh_seconds, :integer, default: 300 13 | config_param :imdsv2, :bool, default: false 14 | 15 | attr_reader :ec2_metadata 16 | 17 | def filter(tag, time, record) 18 | tag_parts = tag.split('.') 19 | modify_record(record, tag, tag_parts) 20 | rescue => e 21 | log.warn "ec2-metadata: #{e.class} #{e.message} #{e.backtrace.join(', ')}" 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/fluent/plugin/out_ec2_metadata.rb: -------------------------------------------------------------------------------- 1 | require 'fluent/plugin/output' 2 | require_relative 'ec2_metadata' 3 | 4 | module Fluent::Plugin 5 | class EC2MetadataOutput < Output 6 | include Fluent::EC2Metadata 7 | 8 | Fluent::Plugin.register_output('ec2_metadata', self) 9 | 10 | helpers :event_emitter 11 | 12 | config_param :output_tag, :string 13 | config_param :aws_key_id, :string, default: ENV['AWS_ACCESS_KEY_ID'], secret: true 14 | config_param :aws_sec_key, :string, default: ENV['AWS_SECRET_ACCESS_KEY'], secret: true 15 | config_param :metadata_refresh_seconds, :integer, default: 300 16 | config_param :imdsv2, :bool, default: false 17 | 18 | attr_reader :ec2_metadata 19 | 20 | def process(tag, es) 21 | tag_parts = tag.split('.') 22 | es.each { |time, record| 23 | new_tag, new_record = modify(@output_tag, record, tag, tag_parts) 24 | router.emit(new_tag, time, new_record) 25 | } 26 | rescue => e 27 | log.warn "ec2-metadata: #{e.class} #{e.message} #{e.backtrace.join(', ')}" 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/cassettes/ec2-classic.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://169.254.169.254/latest/meta-data/instance-id 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept-Encoding: 11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 12 | Accept: 13 | - '*/*' 14 | User-Agent: 15 | - Ruby 16 | response: 17 | status: 18 | code: 200 19 | message: OK 20 | headers: 21 | Content-Type: 22 | - text/plain 23 | Accept-Ranges: 24 | - bytes 25 | Etag: 26 | - '"1971254081"' 27 | Last-Modified: 28 | - Thu, 02 Jul 2015 12:49:17 GMT 29 | Content-Length: 30 | - '10' 31 | Connection: 32 | - close 33 | Date: 34 | - Sun, 13 Dec 2015 06:37:00 GMT 35 | Server: 36 | - EC2ws 37 | body: 38 | encoding: UTF-8 39 | string: i-0c0c0000 40 | http_version: 41 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 42 | - request: 43 | method: get 44 | uri: http://169.254.169.254/latest/meta-data/instance-type 45 | body: 46 | encoding: US-ASCII 47 | string: '' 48 | headers: 49 | Accept-Encoding: 50 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 51 | Accept: 52 | - '*/*' 53 | User-Agent: 54 | - Ruby 55 | response: 56 | status: 57 | code: 200 58 | message: OK 59 | headers: 60 | Content-Type: 61 | - text/plain 62 | Accept-Ranges: 63 | - bytes 64 | Etag: 65 | - '"765393446"' 66 | Last-Modified: 67 | - Thu, 02 Jul 2015 12:49:17 GMT 68 | Content-Length: 69 | - '8' 70 | Connection: 71 | - close 72 | Date: 73 | - Sun, 13 Dec 2015 06:37:00 GMT 74 | Server: 75 | - EC2ws 76 | body: 77 | encoding: UTF-8 78 | string: m3.large 79 | http_version: 80 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 81 | - request: 82 | method: get 83 | uri: http://169.254.169.254/latest/meta-data/placement/availability-zone 84 | body: 85 | encoding: US-ASCII 86 | string: '' 87 | headers: 88 | Accept-Encoding: 89 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 90 | Accept: 91 | - '*/*' 92 | User-Agent: 93 | - Ruby 94 | response: 95 | status: 96 | code: 200 97 | message: OK 98 | headers: 99 | Content-Type: 100 | - text/plain 101 | Accept-Ranges: 102 | - bytes 103 | Etag: 104 | - '"1870317889"' 105 | Last-Modified: 106 | - Thu, 02 Jul 2015 12:49:17 GMT 107 | Content-Length: 108 | - '15' 109 | Connection: 110 | - close 111 | Date: 112 | - Sun, 13 Dec 2015 06:37:00 GMT 113 | Server: 114 | - EC2ws 115 | body: 116 | encoding: UTF-8 117 | string: ap-northeast-1b 118 | http_version: 119 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 120 | - request: 121 | method: get 122 | uri: http://169.254.169.254/latest/meta-data/local-ipv4 123 | body: 124 | encoding: US-ASCII 125 | string: '' 126 | headers: 127 | Accept-Encoding: 128 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 129 | Accept: 130 | - '*/*' 131 | User-Agent: 132 | - Ruby 133 | response: 134 | status: 135 | code: 200 136 | message: OK 137 | headers: 138 | Content-Type: 139 | - text/plain 140 | Accept-Ranges: 141 | - bytes 142 | Etag: 143 | - '"1870317889"' 144 | Last-Modified: 145 | - Thu, 02 Jul 2015 12:49:17 GMT 146 | Content-Length: 147 | - '15' 148 | Connection: 149 | - close 150 | Date: 151 | - Sun, 13 Dec 2015 06:37:00 GMT 152 | Server: 153 | - EC2ws 154 | body: 155 | encoding: UTF-8 156 | string: 10.21.34.200 157 | http_version: 158 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 159 | - request: 160 | method: get 161 | uri: http://169.254.169.254/latest/meta-data/mac 162 | body: 163 | encoding: US-ASCII 164 | string: '' 165 | headers: 166 | Accept-Encoding: 167 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 168 | Accept: 169 | - '*/*' 170 | User-Agent: 171 | - Ruby 172 | response: 173 | status: 174 | code: 200 175 | message: OK 176 | headers: 177 | Content-Type: 178 | - text/plain 179 | Accept-Ranges: 180 | - bytes 181 | Etag: 182 | - '"1925384845"' 183 | Last-Modified: 184 | - Fri, 27 Feb 2015 04:49:13 GMT 185 | Content-Length: 186 | - '17' 187 | Connection: 188 | - close 189 | Date: 190 | - Wed, 16 Dec 2015 17:11:22 GMT 191 | Server: 192 | - EC2ws 193 | body: 194 | encoding: UTF-8 195 | string: 00:00:0A:AA:0A:0A 196 | http_version: 197 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 198 | - request: 199 | method: get 200 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/vpc-id 201 | body: 202 | encoding: US-ASCII 203 | string: '' 204 | headers: 205 | Accept-Encoding: 206 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 207 | Accept: 208 | - '*/*' 209 | User-Agent: 210 | - Ruby 211 | response: 212 | status: 213 | code: 404 214 | message: Not Found 215 | headers: 216 | Content-Type: 217 | - text/html 218 | Content-Length: 219 | - '345' 220 | Connection: 221 | - close 222 | Date: 223 | - Wed, 16 Dec 2015 17:11:22 GMT 224 | Server: 225 | - EC2ws 226 | body: 227 | encoding: UTF-8 228 | string: | 229 | 230 | 232 | 233 | 234 | 404 - Not Found 235 | 236 | 237 |

404 - Not Found

238 | 239 | 240 | http_version: 241 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 242 | - request: 243 | method: get 244 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/subnet-id 245 | body: 246 | encoding: US-ASCII 247 | string: '' 248 | headers: 249 | Accept-Encoding: 250 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 251 | Accept: 252 | - '*/*' 253 | User-Agent: 254 | - Ruby 255 | response: 256 | status: 257 | code: 404 258 | message: Not Found 259 | headers: 260 | Content-Type: 261 | - text/html 262 | Content-Length: 263 | - '345' 264 | Connection: 265 | - close 266 | Date: 267 | - Wed, 16 Dec 2015 17:11:22 GMT 268 | Server: 269 | - EC2ws 270 | body: 271 | encoding: UTF-8 272 | string: | 273 | 274 | 276 | 277 | 278 | 404 - Not Found 279 | 280 | 281 |

404 - Not Found

282 | 283 | 284 | http_version: 285 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 286 | - request: 287 | method: get 288 | uri: http://169.254.169.254/latest/dynamic/instance-identity/document 289 | body: 290 | encoding: US-ASCII 291 | string: '' 292 | headers: 293 | Accept-Encoding: 294 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 295 | Accept: 296 | - '*/*' 297 | User-Agent: 298 | - Ruby 299 | response: 300 | status: 301 | code: 200 302 | message: OK 303 | headers: 304 | Content-Type: 305 | - text/plain 306 | Accept-Ranges: 307 | - bytes 308 | Etag: 309 | - '"2871764318"' 310 | Last-Modified: 311 | - Wed, 11 May 2016 20:52:55 GMT 312 | Content-Length: 313 | - '422' 314 | Connection: 315 | - close 316 | Date: 317 | - Wed, 11 May 2016 21:05:40 GMT 318 | Server: 319 | - EC2ws 320 | body: 321 | encoding: UTF-8 322 | string: |- 323 | { 324 | "privateIp" : "172.31.1.232", 325 | "devpayProductCodes" : null, 326 | "availabilityZone" : "us-west-1c", 327 | "version" : "2010-08-31", 328 | "instanceId" : "i-123456", 329 | "billingProducts" : null, 330 | "instanceType" : "t2.micro", 331 | "accountId" : "123456789", 332 | "imageId" : "ami-123456", 333 | "pendingTime" : "2016-05-11T20:52:25Z", 334 | "architecture" : "x86_64", 335 | "kernelId" : null, 336 | "ramdiskId" : null, 337 | "region" : "us-west-1" 338 | } 339 | http_version: 340 | recorded_at: Wed, 11 May 2016 21:05:40 GMT 341 | recorded_with: VCR 3.0.1 342 | -------------------------------------------------------------------------------- /test/cassettes/ec2-vpc-with-imdsv2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: put 5 | uri: http://169.254.169.254/latest/api/token 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 11 | - '300' 12 | Accept-Encoding: 13 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 14 | Accept: 15 | - "*/*" 16 | User-Agent: 17 | - Ruby 18 | response: 19 | status: 20 | code: 200 21 | message: OK 22 | headers: 23 | Content-Length: 24 | - '56' 25 | Content-Type: 26 | - text/plain 27 | Date: 28 | - Thu, 12 Dec 2019 11:38:19 GMT 29 | X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 30 | - '300' 31 | Connection: 32 | - close 33 | Server: 34 | - EC2ws 35 | body: 36 | encoding: UTF-8 37 | string: AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 38 | http_version: 39 | recorded_at: Thu, 12 Dec 2019 11:38:19 GMT 40 | - request: 41 | method: get 42 | uri: http://169.254.169.254/latest/meta-data/instance-id 43 | body: 44 | encoding: US-ASCII 45 | string: '' 46 | headers: 47 | Accept-Encoding: 48 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 49 | Accept: 50 | - '*/*' 51 | User-Agent: 52 | - Ruby 53 | X-aws-ec2-metadata-token: 54 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 55 | response: 56 | status: 57 | code: 200 58 | message: OK 59 | headers: 60 | Content-Type: 61 | - text/plain 62 | Accept-Ranges: 63 | - bytes 64 | Etag: 65 | - '"1971254081"' 66 | Last-Modified: 67 | - Thu, 02 Jul 2015 12:49:17 GMT 68 | Content-Length: 69 | - '10' 70 | Connection: 71 | - close 72 | Date: 73 | - Sun, 13 Dec 2015 06:37:00 GMT 74 | Server: 75 | - EC2ws 76 | body: 77 | encoding: UTF-8 78 | string: i-0c0c0000 79 | http_version: 80 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 81 | - request: 82 | method: get 83 | uri: http://169.254.169.254/latest/meta-data/instance-type 84 | body: 85 | encoding: US-ASCII 86 | string: '' 87 | headers: 88 | Accept-Encoding: 89 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 90 | Accept: 91 | - '*/*' 92 | User-Agent: 93 | - Ruby 94 | X-aws-ec2-metadata-token: 95 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 96 | response: 97 | status: 98 | code: 200 99 | message: OK 100 | headers: 101 | Content-Type: 102 | - text/plain 103 | Accept-Ranges: 104 | - bytes 105 | Etag: 106 | - '"765393446"' 107 | Last-Modified: 108 | - Thu, 02 Jul 2015 12:49:17 GMT 109 | Content-Length: 110 | - '8' 111 | Connection: 112 | - close 113 | Date: 114 | - Sun, 13 Dec 2015 06:37:00 GMT 115 | Server: 116 | - EC2ws 117 | body: 118 | encoding: UTF-8 119 | string: m3.large 120 | http_version: 121 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 122 | - request: 123 | method: get 124 | uri: http://169.254.169.254/latest/meta-data/placement/availability-zone 125 | body: 126 | encoding: US-ASCII 127 | string: '' 128 | headers: 129 | Accept-Encoding: 130 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 131 | Accept: 132 | - '*/*' 133 | User-Agent: 134 | - Ruby 135 | X-aws-ec2-metadata-token: 136 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 137 | response: 138 | status: 139 | code: 200 140 | message: OK 141 | headers: 142 | Content-Type: 143 | - text/plain 144 | Accept-Ranges: 145 | - bytes 146 | Etag: 147 | - '"1870317889"' 148 | Last-Modified: 149 | - Thu, 02 Jul 2015 12:49:17 GMT 150 | Content-Length: 151 | - '15' 152 | Connection: 153 | - close 154 | Date: 155 | - Sun, 13 Dec 2015 06:37:00 GMT 156 | Server: 157 | - EC2ws 158 | body: 159 | encoding: UTF-8 160 | string: ap-northeast-1b 161 | http_version: 162 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 163 | - request: 164 | method: get 165 | uri: http://169.254.169.254/latest/meta-data/local-ipv4 166 | body: 167 | encoding: US-ASCII 168 | string: '' 169 | headers: 170 | Accept-Encoding: 171 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 172 | Accept: 173 | - '*/*' 174 | User-Agent: 175 | - Ruby 176 | X-aws-ec2-metadata-token: 177 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 178 | response: 179 | status: 180 | code: 200 181 | message: OK 182 | headers: 183 | Content-Type: 184 | - text/plain 185 | Accept-Ranges: 186 | - bytes 187 | Etag: 188 | - '"1870317889"' 189 | Last-Modified: 190 | - Thu, 02 Jul 2015 12:49:17 GMT 191 | Content-Length: 192 | - '15' 193 | Connection: 194 | - close 195 | Date: 196 | - Sun, 13 Dec 2015 06:37:00 GMT 197 | Server: 198 | - EC2ws 199 | body: 200 | encoding: UTF-8 201 | string: 10.21.34.200 202 | http_version: 203 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 204 | - request: 205 | method: get 206 | uri: http://169.254.169.254/latest/meta-data/mac 207 | body: 208 | encoding: US-ASCII 209 | string: '' 210 | headers: 211 | Accept-Encoding: 212 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 213 | Accept: 214 | - '*/*' 215 | User-Agent: 216 | - Ruby 217 | X-aws-ec2-metadata-token: 218 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 219 | response: 220 | status: 221 | code: 200 222 | message: OK 223 | headers: 224 | Content-Type: 225 | - text/plain 226 | Accept-Ranges: 227 | - bytes 228 | Etag: 229 | - '"1996419393"' 230 | Last-Modified: 231 | - Thu, 02 Jul 2015 12:49:17 GMT 232 | Content-Length: 233 | - '17' 234 | Connection: 235 | - close 236 | Date: 237 | - Sun, 13 Dec 2015 06:37:00 GMT 238 | Server: 239 | - EC2ws 240 | body: 241 | encoding: UTF-8 242 | string: 00:A0:00:0A:AA:00 243 | http_version: 244 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 245 | - request: 246 | method: get 247 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:A0:00:0A:AA:00/vpc-id 248 | body: 249 | encoding: US-ASCII 250 | string: '' 251 | headers: 252 | Accept-Encoding: 253 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 254 | Accept: 255 | - '*/*' 256 | User-Agent: 257 | - Ruby 258 | X-aws-ec2-metadata-token: 259 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 260 | response: 261 | status: 262 | code: 200 263 | message: OK 264 | headers: 265 | Content-Type: 266 | - text/plain 267 | Accept-Ranges: 268 | - bytes 269 | Etag: 270 | - '"1822409025"' 271 | Last-Modified: 272 | - Thu, 02 Jul 2015 12:49:17 GMT 273 | Content-Length: 274 | - '12' 275 | Connection: 276 | - close 277 | Date: 278 | - Sun, 13 Dec 2015 06:37:00 GMT 279 | Server: 280 | - EC2ws 281 | body: 282 | encoding: UTF-8 283 | string: vpc-00000000 284 | http_version: 285 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 286 | - request: 287 | method: get 288 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:A0:00:0A:AA:00/subnet-id 289 | body: 290 | encoding: US-ASCII 291 | string: '' 292 | headers: 293 | Accept-Encoding: 294 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 295 | Accept: 296 | - '*/*' 297 | User-Agent: 298 | - Ruby 299 | X-aws-ec2-metadata-token: 300 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 301 | response: 302 | status: 303 | code: 200 304 | message: OK 305 | headers: 306 | Content-Type: 307 | - text/plain 308 | Accept-Ranges: 309 | - bytes 310 | Etag: 311 | - '"1870330753"' 312 | Last-Modified: 313 | - Thu, 02 Jul 2015 12:49:17 GMT 314 | Content-Length: 315 | - '15' 316 | Connection: 317 | - close 318 | Date: 319 | - Sun, 13 Dec 2015 06:37:00 GMT 320 | Server: 321 | - EC2ws 322 | body: 323 | encoding: UTF-8 324 | string: subnet-00000000 325 | http_version: 326 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 327 | - request: 328 | method: get 329 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/vpc-id 330 | body: 331 | encoding: US-ASCII 332 | string: '' 333 | headers: 334 | Accept-Encoding: 335 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 336 | Accept: 337 | - '*/*' 338 | User-Agent: 339 | - Ruby 340 | X-aws-ec2-metadata-token: 341 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 342 | response: 343 | status: 344 | code: 404 345 | message: Not Found 346 | headers: 347 | Content-Type: 348 | - text/html 349 | Content-Length: 350 | - '345' 351 | Connection: 352 | - close 353 | Date: 354 | - Wed, 16 Dec 2015 17:11:22 GMT 355 | Server: 356 | - EC2ws 357 | body: 358 | encoding: UTF-8 359 | string: | 360 | 361 | 363 | 364 | 365 | 404 - Not Found 366 | 367 | 368 |

404 - Not Found

369 | 370 | 371 | http_version: 372 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 373 | - request: 374 | method: get 375 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/subnet-id 376 | body: 377 | encoding: US-ASCII 378 | string: '' 379 | headers: 380 | Accept-Encoding: 381 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 382 | Accept: 383 | - '*/*' 384 | User-Agent: 385 | - Ruby 386 | X-aws-ec2-metadata-token: 387 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 388 | response: 389 | status: 390 | code: 404 391 | message: Not Found 392 | headers: 393 | Content-Type: 394 | - text/html 395 | Content-Length: 396 | - '345' 397 | Connection: 398 | - close 399 | Date: 400 | - Wed, 16 Dec 2015 17:11:22 GMT 401 | Server: 402 | - EC2ws 403 | body: 404 | encoding: UTF-8 405 | string: | 406 | 407 | 409 | 410 | 411 | 404 - Not Found 412 | 413 | 414 |

404 - Not Found

415 | 416 | 417 | http_version: 418 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 419 | - request: 420 | method: post 421 | uri: https://ec2.ap-northeast-1.amazonaws.com/ 422 | body: 423 | encoding: UTF-8 424 | string: Action=DescribeInstances&InstanceId.1=i-0c0c0000&Version=2015-10-01 425 | headers: 426 | Content-Type: 427 | - application/x-www-form-urlencoded; charset=utf-8 428 | Accept-Encoding: 429 | - '' 430 | User-Agent: 431 | - aws-sdk-ruby2/2.2.5 ruby/2.1.4 x86_64-linux 432 | X-Amz-Date: 433 | - 20151213T100607Z 434 | Host: 435 | - ec2.ap-northeast-1.amazonaws.com 436 | Content-Length: 437 | - '67' 438 | Accept: 439 | - '*/*' 440 | X-aws-ec2-metadata-token: 441 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 442 | response: 443 | status: 444 | code: 200 445 | message: OK 446 | headers: 447 | Content-Type: 448 | - text/xml;charset=UTF-8 449 | Transfer-Encoding: 450 | - chunked 451 | Vary: 452 | - Accept-Encoding 453 | Date: 454 | - Sun, 13 Dec 2015 10:06:07 GMT 455 | Server: 456 | - AmazonEC2 457 | body: 458 | encoding: UTF-8 459 | string: |- 460 | 461 | 462 | 00f71347-3b87-4f5b-a60f-8c46d76ea808 463 | 464 | 465 | r-44d8965d 466 | 000000000000 467 | 468 | 469 | 470 | i-0c0c0000 471 | 472 | 473 | Name 474 | instance-name 475 | 476 | 477 | aws:cloudformation:stack-name 478 | mystack 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | http_version: 487 | recorded_at: Sun, 13 Dec 2015 10:06:07 GMT 488 | - request: 489 | method: get 490 | uri: http://169.254.169.254/latest/dynamic/instance-identity/document 491 | body: 492 | encoding: US-ASCII 493 | string: '' 494 | headers: 495 | Accept-Encoding: 496 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 497 | Accept: 498 | - '*/*' 499 | User-Agent: 500 | - Ruby 501 | X-aws-ec2-metadata-token: 502 | - AAAAAAAAAAAAA__AAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAAAAAAAAA== 503 | response: 504 | status: 505 | code: 200 506 | message: OK 507 | headers: 508 | Content-Type: 509 | - text/plain 510 | Accept-Ranges: 511 | - bytes 512 | Etag: 513 | - '"2871764318"' 514 | Last-Modified: 515 | - Wed, 11 May 2016 20:52:55 GMT 516 | Content-Length: 517 | - '422' 518 | Connection: 519 | - close 520 | Date: 521 | - Wed, 11 May 2016 21:05:40 GMT 522 | Server: 523 | - EC2ws 524 | body: 525 | encoding: UTF-8 526 | string: |- 527 | { 528 | "privateIp" : "172.31.1.232", 529 | "devpayProductCodes" : null, 530 | "availabilityZone" : "us-west-1c", 531 | "version" : "2010-08-31", 532 | "instanceId" : "i-123456", 533 | "billingProducts" : null, 534 | "instanceType" : "t2.micro", 535 | "accountId" : "123456789", 536 | "imageId" : "ami-123456", 537 | "pendingTime" : "2016-05-11T20:52:25Z", 538 | "architecture" : "x86_64", 539 | "kernelId" : null, 540 | "ramdiskId" : null, 541 | "region" : "us-west-1" 542 | } 543 | http_version: 544 | recorded_at: Wed, 11 May 2016 21:05:40 GMT 545 | recorded_with: VCR 3.0.1 546 | -------------------------------------------------------------------------------- /test/cassettes/ec2-vpc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://169.254.169.254/latest/meta-data/instance-id 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Accept-Encoding: 11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 12 | Accept: 13 | - '*/*' 14 | User-Agent: 15 | - Ruby 16 | response: 17 | status: 18 | code: 200 19 | message: OK 20 | headers: 21 | Content-Type: 22 | - text/plain 23 | Accept-Ranges: 24 | - bytes 25 | Etag: 26 | - '"1971254081"' 27 | Last-Modified: 28 | - Thu, 02 Jul 2015 12:49:17 GMT 29 | Content-Length: 30 | - '10' 31 | Connection: 32 | - close 33 | Date: 34 | - Sun, 13 Dec 2015 06:37:00 GMT 35 | Server: 36 | - EC2ws 37 | body: 38 | encoding: UTF-8 39 | string: i-0c0c0000 40 | http_version: 41 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 42 | - request: 43 | method: get 44 | uri: http://169.254.169.254/latest/meta-data/instance-type 45 | body: 46 | encoding: US-ASCII 47 | string: '' 48 | headers: 49 | Accept-Encoding: 50 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 51 | Accept: 52 | - '*/*' 53 | User-Agent: 54 | - Ruby 55 | response: 56 | status: 57 | code: 200 58 | message: OK 59 | headers: 60 | Content-Type: 61 | - text/plain 62 | Accept-Ranges: 63 | - bytes 64 | Etag: 65 | - '"765393446"' 66 | Last-Modified: 67 | - Thu, 02 Jul 2015 12:49:17 GMT 68 | Content-Length: 69 | - '8' 70 | Connection: 71 | - close 72 | Date: 73 | - Sun, 13 Dec 2015 06:37:00 GMT 74 | Server: 75 | - EC2ws 76 | body: 77 | encoding: UTF-8 78 | string: m3.large 79 | http_version: 80 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 81 | - request: 82 | method: get 83 | uri: http://169.254.169.254/latest/meta-data/placement/availability-zone 84 | body: 85 | encoding: US-ASCII 86 | string: '' 87 | headers: 88 | Accept-Encoding: 89 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 90 | Accept: 91 | - '*/*' 92 | User-Agent: 93 | - Ruby 94 | response: 95 | status: 96 | code: 200 97 | message: OK 98 | headers: 99 | Content-Type: 100 | - text/plain 101 | Accept-Ranges: 102 | - bytes 103 | Etag: 104 | - '"1870317889"' 105 | Last-Modified: 106 | - Thu, 02 Jul 2015 12:49:17 GMT 107 | Content-Length: 108 | - '15' 109 | Connection: 110 | - close 111 | Date: 112 | - Sun, 13 Dec 2015 06:37:00 GMT 113 | Server: 114 | - EC2ws 115 | body: 116 | encoding: UTF-8 117 | string: ap-northeast-1b 118 | http_version: 119 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 120 | - request: 121 | method: get 122 | uri: http://169.254.169.254/latest/meta-data/local-ipv4 123 | body: 124 | encoding: US-ASCII 125 | string: '' 126 | headers: 127 | Accept-Encoding: 128 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 129 | Accept: 130 | - '*/*' 131 | User-Agent: 132 | - Ruby 133 | response: 134 | status: 135 | code: 200 136 | message: OK 137 | headers: 138 | Content-Type: 139 | - text/plain 140 | Accept-Ranges: 141 | - bytes 142 | Etag: 143 | - '"1870317889"' 144 | Last-Modified: 145 | - Thu, 02 Jul 2015 12:49:17 GMT 146 | Content-Length: 147 | - '15' 148 | Connection: 149 | - close 150 | Date: 151 | - Sun, 13 Dec 2015 06:37:00 GMT 152 | Server: 153 | - EC2ws 154 | body: 155 | encoding: UTF-8 156 | string: 10.21.34.200 157 | http_version: 158 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 159 | - request: 160 | method: get 161 | uri: http://169.254.169.254/latest/meta-data/mac 162 | body: 163 | encoding: US-ASCII 164 | string: '' 165 | headers: 166 | Accept-Encoding: 167 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 168 | Accept: 169 | - '*/*' 170 | User-Agent: 171 | - Ruby 172 | response: 173 | status: 174 | code: 200 175 | message: OK 176 | headers: 177 | Content-Type: 178 | - text/plain 179 | Accept-Ranges: 180 | - bytes 181 | Etag: 182 | - '"1996419393"' 183 | Last-Modified: 184 | - Thu, 02 Jul 2015 12:49:17 GMT 185 | Content-Length: 186 | - '17' 187 | Connection: 188 | - close 189 | Date: 190 | - Sun, 13 Dec 2015 06:37:00 GMT 191 | Server: 192 | - EC2ws 193 | body: 194 | encoding: UTF-8 195 | string: 00:A0:00:0A:AA:00 196 | http_version: 197 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 198 | - request: 199 | method: get 200 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:A0:00:0A:AA:00/vpc-id 201 | body: 202 | encoding: US-ASCII 203 | string: '' 204 | headers: 205 | Accept-Encoding: 206 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 207 | Accept: 208 | - '*/*' 209 | User-Agent: 210 | - Ruby 211 | response: 212 | status: 213 | code: 200 214 | message: OK 215 | headers: 216 | Content-Type: 217 | - text/plain 218 | Accept-Ranges: 219 | - bytes 220 | Etag: 221 | - '"1822409025"' 222 | Last-Modified: 223 | - Thu, 02 Jul 2015 12:49:17 GMT 224 | Content-Length: 225 | - '12' 226 | Connection: 227 | - close 228 | Date: 229 | - Sun, 13 Dec 2015 06:37:00 GMT 230 | Server: 231 | - EC2ws 232 | body: 233 | encoding: UTF-8 234 | string: vpc-00000000 235 | http_version: 236 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 237 | - request: 238 | method: get 239 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:A0:00:0A:AA:00/subnet-id 240 | body: 241 | encoding: US-ASCII 242 | string: '' 243 | headers: 244 | Accept-Encoding: 245 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 246 | Accept: 247 | - '*/*' 248 | User-Agent: 249 | - Ruby 250 | response: 251 | status: 252 | code: 200 253 | message: OK 254 | headers: 255 | Content-Type: 256 | - text/plain 257 | Accept-Ranges: 258 | - bytes 259 | Etag: 260 | - '"1870330753"' 261 | Last-Modified: 262 | - Thu, 02 Jul 2015 12:49:17 GMT 263 | Content-Length: 264 | - '15' 265 | Connection: 266 | - close 267 | Date: 268 | - Sun, 13 Dec 2015 06:37:00 GMT 269 | Server: 270 | - EC2ws 271 | body: 272 | encoding: UTF-8 273 | string: subnet-00000000 274 | http_version: 275 | recorded_at: Sun, 13 Dec 2015 06:37:00 GMT 276 | - request: 277 | method: get 278 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/vpc-id 279 | body: 280 | encoding: US-ASCII 281 | string: '' 282 | headers: 283 | Accept-Encoding: 284 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 285 | Accept: 286 | - '*/*' 287 | User-Agent: 288 | - Ruby 289 | response: 290 | status: 291 | code: 404 292 | message: Not Found 293 | headers: 294 | Content-Type: 295 | - text/html 296 | Content-Length: 297 | - '345' 298 | Connection: 299 | - close 300 | Date: 301 | - Wed, 16 Dec 2015 17:11:22 GMT 302 | Server: 303 | - EC2ws 304 | body: 305 | encoding: UTF-8 306 | string: | 307 | 308 | 310 | 311 | 312 | 404 - Not Found 313 | 314 | 315 |

404 - Not Found

316 | 317 | 318 | http_version: 319 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 320 | - request: 321 | method: get 322 | uri: http://169.254.169.254/latest/meta-data/network/interfaces/macs/00:00:0A:AA:0A:0A/subnet-id 323 | body: 324 | encoding: US-ASCII 325 | string: '' 326 | headers: 327 | Accept-Encoding: 328 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 329 | Accept: 330 | - '*/*' 331 | User-Agent: 332 | - Ruby 333 | response: 334 | status: 335 | code: 404 336 | message: Not Found 337 | headers: 338 | Content-Type: 339 | - text/html 340 | Content-Length: 341 | - '345' 342 | Connection: 343 | - close 344 | Date: 345 | - Wed, 16 Dec 2015 17:11:22 GMT 346 | Server: 347 | - EC2ws 348 | body: 349 | encoding: UTF-8 350 | string: | 351 | 352 | 354 | 355 | 356 | 404 - Not Found 357 | 358 | 359 |

404 - Not Found

360 | 361 | 362 | http_version: 363 | recorded_at: Wed, 16 Dec 2015 17:11:22 GMT 364 | - request: 365 | method: post 366 | uri: https://ec2.ap-northeast-1.amazonaws.com/ 367 | body: 368 | encoding: UTF-8 369 | string: Action=DescribeInstances&InstanceId.1=i-0c0c0000&Version=2015-10-01 370 | headers: 371 | Content-Type: 372 | - application/x-www-form-urlencoded; charset=utf-8 373 | Accept-Encoding: 374 | - '' 375 | User-Agent: 376 | - aws-sdk-ruby2/2.2.5 ruby/2.1.4 x86_64-linux 377 | X-Amz-Date: 378 | - 20151213T100607Z 379 | Host: 380 | - ec2.ap-northeast-1.amazonaws.com 381 | Content-Length: 382 | - '67' 383 | Accept: 384 | - '*/*' 385 | response: 386 | status: 387 | code: 200 388 | message: OK 389 | headers: 390 | Content-Type: 391 | - text/xml;charset=UTF-8 392 | Transfer-Encoding: 393 | - chunked 394 | Vary: 395 | - Accept-Encoding 396 | Date: 397 | - Sun, 13 Dec 2015 10:06:07 GMT 398 | Server: 399 | - AmazonEC2 400 | body: 401 | encoding: UTF-8 402 | string: |- 403 | 404 | 405 | 00f71347-3b87-4f5b-a60f-8c46d76ea808 406 | 407 | 408 | r-44d8965d 409 | 000000000000 410 | 411 | 412 | 413 | i-0c0c0000 414 | 415 | 416 | Name 417 | instance-name 418 | 419 | 420 | aws:cloudformation:stack-name 421 | mystack 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | http_version: 430 | recorded_at: Sun, 13 Dec 2015 10:06:07 GMT 431 | - request: 432 | method: get 433 | uri: http://169.254.169.254/latest/dynamic/instance-identity/document 434 | body: 435 | encoding: US-ASCII 436 | string: '' 437 | headers: 438 | Accept-Encoding: 439 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 440 | Accept: 441 | - '*/*' 442 | User-Agent: 443 | - Ruby 444 | response: 445 | status: 446 | code: 200 447 | message: OK 448 | headers: 449 | Content-Type: 450 | - text/plain 451 | Accept-Ranges: 452 | - bytes 453 | Etag: 454 | - '"2871764318"' 455 | Last-Modified: 456 | - Wed, 11 May 2016 20:52:55 GMT 457 | Content-Length: 458 | - '422' 459 | Connection: 460 | - close 461 | Date: 462 | - Wed, 11 May 2016 21:05:40 GMT 463 | Server: 464 | - EC2ws 465 | body: 466 | encoding: UTF-8 467 | string: |- 468 | { 469 | "privateIp" : "172.31.1.232", 470 | "devpayProductCodes" : null, 471 | "availabilityZone" : "us-west-1c", 472 | "version" : "2010-08-31", 473 | "instanceId" : "i-123456", 474 | "billingProducts" : null, 475 | "instanceType" : "t2.micro", 476 | "accountId" : "123456789", 477 | "imageId" : "ami-123456", 478 | "pendingTime" : "2016-05-11T20:52:25Z", 479 | "architecture" : "x86_64", 480 | "kernelId" : null, 481 | "ramdiskId" : null, 482 | "region" : "us-west-1" 483 | } 484 | http_version: 485 | recorded_at: Wed, 11 May 2016 21:05:40 GMT 486 | recorded_with: VCR 3.0.1 487 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | require 'simplecov' 2 | SimpleCov.start 3 | 4 | require 'rubygems' 5 | require 'bundler' 6 | begin 7 | Bundler.setup(:default, :development) 8 | rescue Bundler::BundlerError => e 9 | $stderr.puts e.message 10 | $stderr.puts "Run `bundle install` to install missing gems" 11 | exit e.status_code 12 | end 13 | 14 | require 'test/unit' 15 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 16 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 17 | 18 | require 'fluent/test' 19 | unless ENV.has_key?('VERBOSE') 20 | nulllogger = Object.new 21 | nulllogger.instance_eval {|obj| 22 | def method_missing(method, *args) 23 | # pass 24 | end 25 | } 26 | $log = nulllogger 27 | end 28 | 29 | require 'vcr' 30 | VCR.configure do |config| 31 | config.cassette_library_dir = 'test/cassettes' 32 | config.hook_into :webmock 33 | config.ignore_hosts 'codeclimate.com' 34 | end 35 | 36 | class Test::Unit::TestCase 37 | end 38 | -------------------------------------------------------------------------------- /test/plugin/test_filter_ec2_metadata.rb: -------------------------------------------------------------------------------- 1 | require 'helper' 2 | require 'fluent/test/driver/filter' 3 | require 'fluent/plugin/filter_ec2_metadata' 4 | 5 | require 'webmock/test_unit' 6 | WebMock.disable_net_connect! 7 | 8 | class EC2MetadataFilterTest < Test::Unit::TestCase 9 | 10 | CONFIG = %[ 11 | aws_key_id aws_key 12 | aws_sec_key aws_sec 13 | 14 | name ${tagset_name} 15 | instance_id ${instance_id} 16 | az ${availability_zone} 17 | 18 | ] 19 | 20 | def setup 21 | Fluent::Test.setup 22 | @time = Fluent::Engine.now 23 | end 24 | 25 | def create_driver(conf=CONFIG) 26 | Fluent::Test::Driver::Filter.new(Fluent::Plugin::EC2MetadataFilter).configure(conf) 27 | end 28 | 29 | test 'configure-vpc' do 30 | VCR.use_cassette('ec2-vpc') do 31 | c = %[ 32 | aws_key_id aws_key 33 | aws_sec_key aws_sec 34 | 35 | name ${tagset_name} 36 | 37 | ] 38 | d = create_driver(conf=c) 39 | 40 | assert_equal("aws_key", d.instance.aws_key_id) 41 | assert_equal("aws_sec", d.instance.aws_sec_key) 42 | 43 | assert_equal("ami-123456", d.instance.ec2_metadata['image_id']) 44 | assert_equal("123456789", d.instance.ec2_metadata['account_id']) 45 | 46 | assert_equal("i-0c0c0000", d.instance.ec2_metadata['instance_id']) 47 | assert_equal("m3.large", d.instance.ec2_metadata['instance_type']) 48 | assert_equal("ap-northeast-1", d.instance.ec2_metadata['region']) 49 | assert_equal("ap-northeast-1b", d.instance.ec2_metadata['availability_zone']) 50 | assert_equal("00:A0:00:0A:AA:00", d.instance.ec2_metadata['mac']) 51 | assert_equal("vpc-00000000", d.instance.ec2_metadata['vpc_id']) 52 | assert_equal("subnet-00000000", d.instance.ec2_metadata['subnet_id']) 53 | 54 | assert_equal("instance-name", d.instance.ec2_metadata['tagset_name']) 55 | end 56 | end 57 | 58 | test 'configure-vpc-with-imdsv2' do 59 | VCR.use_cassette('ec2-vpc-with-imdsv2', :allow_playback_repeats => true) do 60 | c = %[ 61 | aws_key_id aws_key 62 | aws_sec_key aws_sec 63 | imdsv2 true 64 | 65 | name ${tagset_name} 66 | 67 | ] 68 | d = create_driver(conf=c) 69 | 70 | assert_equal("aws_key", d.instance.aws_key_id) 71 | assert_equal("aws_sec", d.instance.aws_sec_key) 72 | 73 | assert_equal("ami-123456", d.instance.ec2_metadata['image_id']) 74 | assert_equal("123456789", d.instance.ec2_metadata['account_id']) 75 | 76 | assert_equal("i-0c0c0000", d.instance.ec2_metadata['instance_id']) 77 | assert_equal("m3.large", d.instance.ec2_metadata['instance_type']) 78 | assert_equal("ap-northeast-1", d.instance.ec2_metadata['region']) 79 | assert_equal("ap-northeast-1b", d.instance.ec2_metadata['availability_zone']) 80 | assert_equal("00:A0:00:0A:AA:00", d.instance.ec2_metadata['mac']) 81 | assert_equal("vpc-00000000", d.instance.ec2_metadata['vpc_id']) 82 | assert_equal("subnet-00000000", d.instance.ec2_metadata['subnet_id']) 83 | 84 | assert_equal("instance-name", d.instance.ec2_metadata['tagset_name']) 85 | end 86 | end 87 | 88 | test 'configure-classic' do 89 | VCR.use_cassette('ec2-classic') do 90 | c = %[ 91 | 92 | instance_id ${instance_id} 93 | 94 | ] 95 | d = create_driver(conf=c) 96 | 97 | assert_equal(nil, d.instance.aws_key_id) 98 | assert_equal(nil, d.instance.aws_sec_key) 99 | 100 | assert_equal("00:00:0A:AA:0A:0A", d.instance.ec2_metadata['mac']) 101 | assert_equal(nil, d.instance.ec2_metadata['vpc_id']) 102 | assert_equal(nil, d.instance.ec2_metadata['subnet_id']) 103 | end 104 | end 105 | 106 | test 'emit' do 107 | VCR.use_cassette('ec2-vpc') do 108 | d = create_driver 109 | 110 | d.run(default_tag: 'test') do 111 | d.feed("a" => 1) 112 | d.feed("a" => 2) 113 | end 114 | 115 | # record 116 | mapped = { 117 | 'instance_id' => 'i-0c0c0000', 118 | 'az' => 'ap-northeast-1b', 119 | 'name' => 'instance-name', 120 | } 121 | assert_equal [ 122 | {"a" => 1}.merge(mapped), 123 | {"a" => 2}.merge(mapped), 124 | ], d.filtered.map{|e| e.last} 125 | end 126 | end 127 | end 128 | -------------------------------------------------------------------------------- /test/plugin/test_out_ec2_metadata.rb: -------------------------------------------------------------------------------- 1 | require 'helper' 2 | require 'fluent/test/driver/output' 3 | require 'fluent/plugin/out_ec2_metadata' 4 | 5 | require 'webmock/test_unit' 6 | WebMock.disable_net_connect! 7 | 8 | class EC2MetadataOutputTest < Test::Unit::TestCase 9 | 10 | CONFIG = %[ 11 | output_tag ${instance_id}.${tag} 12 | aws_key_id aws_key 13 | aws_sec_key aws_sec 14 | 15 | name ${tagset_name} 16 | stack ${tagset_aws:cloudformation:stack-name} 17 | instance_id ${instance_id} 18 | az ${availability_zone} 19 | 20 | ] 21 | 22 | def setup 23 | Fluent::Test.setup 24 | @time = Fluent::Engine.now 25 | end 26 | 27 | def create_driver(conf=CONFIG) 28 | Fluent::Test::Driver::Output.new(Fluent::Plugin::EC2MetadataOutput).configure(conf) 29 | end 30 | 31 | test 'configure-vpc' do 32 | VCR.use_cassette('ec2-vpc') do 33 | c = %[ 34 | output_tag ${instance_id}.${tag} 35 | aws_key_id aws_key 36 | aws_sec_key aws_sec 37 | 38 | name ${tagset_name} 39 | stack ${tagset_aws:cloudformation:stack-name} 40 | 41 | ] 42 | d = create_driver(conf=c) 43 | 44 | assert_equal("${instance_id}.${tag}", d.instance.output_tag) 45 | assert_equal("aws_key", d.instance.aws_key_id) 46 | assert_equal("aws_sec", d.instance.aws_sec_key) 47 | 48 | assert_equal("ami-123456", d.instance.ec2_metadata['image_id']) 49 | assert_equal("123456789", d.instance.ec2_metadata['account_id']) 50 | assert_equal("10.21.34.200", d.instance.ec2_metadata['private_ip']) 51 | 52 | assert_equal("i-0c0c0000", d.instance.ec2_metadata['instance_id']) 53 | assert_equal("m3.large", d.instance.ec2_metadata['instance_type']) 54 | assert_equal("ap-northeast-1", d.instance.ec2_metadata['region']) 55 | assert_equal("ap-northeast-1b", d.instance.ec2_metadata['availability_zone']) 56 | assert_equal("00:A0:00:0A:AA:00", d.instance.ec2_metadata['mac']) 57 | assert_equal("vpc-00000000", d.instance.ec2_metadata['vpc_id']) 58 | assert_equal("subnet-00000000", d.instance.ec2_metadata['subnet_id']) 59 | 60 | assert_equal("instance-name", d.instance.ec2_metadata['tagset_name']) 61 | assert_equal("mystack", d.instance.ec2_metadata['tagset_aws:cloudformation:stack-name']) 62 | end 63 | end 64 | 65 | test 'configure-vpc-with-imdsv2' do 66 | VCR.use_cassette('ec2-vpc-with-imdsv2', :allow_playback_repeats => true) do 67 | c = %[ 68 | output_tag ${instance_id}.${tag} 69 | aws_key_id aws_key 70 | aws_sec_key aws_sec 71 | imdsv2 true 72 | 73 | name ${tagset_name} 74 | stack ${tagset_aws:cloudformation:stack-name} 75 | 76 | ] 77 | d = create_driver(conf=c) 78 | 79 | assert_equal("${instance_id}.${tag}", d.instance.output_tag) 80 | assert_equal("aws_key", d.instance.aws_key_id) 81 | assert_equal("aws_sec", d.instance.aws_sec_key) 82 | 83 | assert_equal("ami-123456", d.instance.ec2_metadata['image_id']) 84 | assert_equal("123456789", d.instance.ec2_metadata['account_id']) 85 | assert_equal("10.21.34.200", d.instance.ec2_metadata['private_ip']) 86 | 87 | assert_equal("i-0c0c0000", d.instance.ec2_metadata['instance_id']) 88 | assert_equal("m3.large", d.instance.ec2_metadata['instance_type']) 89 | assert_equal("ap-northeast-1", d.instance.ec2_metadata['region']) 90 | assert_equal("ap-northeast-1b", d.instance.ec2_metadata['availability_zone']) 91 | assert_equal("00:A0:00:0A:AA:00", d.instance.ec2_metadata['mac']) 92 | assert_equal("vpc-00000000", d.instance.ec2_metadata['vpc_id']) 93 | assert_equal("subnet-00000000", d.instance.ec2_metadata['subnet_id']) 94 | 95 | assert_equal("instance-name", d.instance.ec2_metadata['tagset_name']) 96 | assert_equal("mystack", d.instance.ec2_metadata['tagset_aws:cloudformation:stack-name']) 97 | end 98 | end 99 | 100 | test 'configure-classic' do 101 | VCR.use_cassette('ec2-classic') do 102 | c = %[ 103 | output_tag test 104 | 105 | instance_id ${instance_id} 106 | 107 | ] 108 | d = create_driver(conf=c) 109 | 110 | assert_equal("test", d.instance.output_tag) 111 | assert_equal(nil, d.instance.aws_key_id) 112 | assert_equal(nil, d.instance.aws_sec_key) 113 | 114 | assert_equal("00:00:0A:AA:0A:0A", d.instance.ec2_metadata['mac']) 115 | assert_equal(nil, d.instance.ec2_metadata['vpc_id']) 116 | assert_equal(nil, d.instance.ec2_metadata['subnet_id']) 117 | end 118 | end 119 | 120 | test 'emit' do 121 | VCR.use_cassette('ec2-vpc') do 122 | d = create_driver 123 | 124 | d.run(default_tag: 'test') do 125 | d.feed("a" => 1) 126 | d.feed("a" => 2) 127 | end 128 | 129 | # tag 130 | assert_equal "i-0c0c0000.test", d.events[0][0] 131 | assert_equal "i-0c0c0000.test", d.events[1][0] 132 | 133 | # record 134 | mapped = { 135 | 'instance_id' => 'i-0c0c0000', 136 | 'az' => 'ap-northeast-1b', 137 | 'name' => 'instance-name', 138 | 'stack' => 'mystack' 139 | } 140 | assert_equal [ 141 | {"a" => 1}.merge(mapped), 142 | {"a" => 2}.merge(mapped), 143 | ], d.events.map{|e| e.last} 144 | end 145 | end 146 | 147 | end 148 | --------------------------------------------------------------------------------