aws_public_ips 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 91231fd301e6aec59763e203fd32c2d985974a4b
4
+ data.tar.gz: 340477b64151aeba0a89115b9f507ecd9283c9cc
5
+ SHA512:
6
+ metadata.gz: dc5775856d160fdfb16b6f2cb141ea242cedf35468e47889ad2b1b9f86c2d82825d3bc6aa1fb1aec0299a75e1954930d5af12f3b726245140fd82e934cbc7625
7
+ data.tar.gz: f02119924a590ce33d2999143217592071f7fb65cd2632222a5c36d99fa18fcb005460bbb5c208fce16b913a5586ab66931b295f9315d4abb67c6d1cfd3ef5e0
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.expand_path(File.join('..', '..', 'lib'), __FILE__))
5
+
6
+ require 'bundler/setup'
7
+ require 'aws_public_ips/cli'
8
+
9
+ AwsPublicIps::CLI.new.run(ARGV)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsPublicIps
4
+ end
5
+
6
+ require 'aws_public_ips/checks'
7
+ require 'aws_public_ips/cli'
8
+ require 'aws_public_ips/formatters'
9
+ require 'aws_public_ips/utils'
10
+ require 'aws_public_ips/version'
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsPublicIps
4
+ module Checks
5
+ end
6
+ end
7
+
8
+ require 'aws_public_ips/checks/apigateway'
9
+ require 'aws_public_ips/checks/cloudfront'
10
+ require 'aws_public_ips/checks/ec2'
11
+ require 'aws_public_ips/checks/elasticsearch'
12
+ require 'aws_public_ips/checks/elb'
13
+ require 'aws_public_ips/checks/elbv2'
14
+ require 'aws_public_ips/checks/lightsail'
15
+ require 'aws_public_ips/checks/rds'
16
+ require 'aws_public_ips/checks/redshift'
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-apigateway'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Apigateway
9
+ def self.run
10
+ client = Aws::APIGateway::Client.new
11
+
12
+ # TODO(arkadiy) https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html
13
+
14
+ # APIGateway doesn't return the full domain in the response, we have to build
15
+ # it using the api id and region
16
+ client.get_rest_apis.flat_map do |response|
17
+ response.items.map do |api|
18
+ hostname = "#{api.id}.execute-api.#{client.config.region}.amazonaws.com"
19
+ {
20
+ id: api.id,
21
+ hostname: hostname,
22
+ ip_addresses: Utils.resolve_hostname(hostname)
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-cloudfront'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Cloudfront
9
+ def self.run
10
+ client = Aws::CloudFront::Client.new
11
+
12
+ client.list_distributions.flat_map do |response|
13
+ response.distribution_list.items.flat_map do |distribution|
14
+ {
15
+ id: distribution.id,
16
+ hostname: distribution.domain_name,
17
+ ip_addresses: Utils.resolve_hostname(distribution.domain_name)
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-ec2'
4
+
5
+ module AwsPublicIps
6
+ module Checks
7
+ module Ec2
8
+ def self.run
9
+ client = Aws::EC2::Client.new
10
+
11
+ # TODO(arkadiy) confirm this covers Batch, Fargate
12
+ # Iterate over all EC2 instances. This will include those from EC2, ECS, EKS, Fargate, Batch,
13
+ # Beanstalk, and NAT Instances
14
+ # It will not include NAT Gateways (IPv4) or Egress Only Internet Gateways (IPv6), but they do not allow
15
+ # ingress traffic so we skip them anyway
16
+ client.describe_instances.flat_map do |response|
17
+ response.reservations.flat_map do |reservation|
18
+ reservation.instances.map do |instance|
19
+ # EC2-Classic instances have a `public_ip_address` and no `network_interfaces`
20
+ # EC2-VPC instances both set, so we uniq the ip addresses
21
+ ip_addresses = [instance.public_ip_address].compact + instance.network_interfaces.flat_map do |interface|
22
+ public_ip = interface.association ? [interface.association.public_ip].compact : []
23
+ public_ip + interface.ipv_6_addresses.map(&:ipv_6_address)
24
+ end
25
+
26
+ # If hostname is empty string, canonicalize to nil
27
+ hostname = instance.public_dns_name.empty? ? nil : instance.public_dns_name
28
+ {
29
+ id: instance.instance_id,
30
+ hostname: hostname,
31
+ ip_addresses: ip_addresses.uniq
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-elasticsearchservice'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Elasticsearch
9
+ def self.run
10
+ client = Aws::ElasticsearchService::Client.new
11
+
12
+ # ElasticSearch instances can be launched publicly or into VPCs. Public instances have a
13
+ # `domain_status.endpoint` hostname and VPC instances have a `domain_status.endpoints['vpc']` hostname.
14
+ # However VPC ElasticSearch instances create their own Network Interface and AWS will not allow you
15
+ # to associate an Elastic IP to it. As a result VPC ElasticSearch instances are always private, even with an
16
+ # internet gateway.
17
+
18
+ client.list_domain_names.flat_map do |response|
19
+ response.domain_names.flat_map do |domain_name|
20
+ client.describe_elasticsearch_domain(domain_name: domain_name.domain_name).map do |domain|
21
+ hostname = domain.domain_status.endpoint
22
+ next unless hostname
23
+ {
24
+ id: domain.domain_status.domain_id,
25
+ hostname: hostname,
26
+ ip_addresses: Utils.resolve_hostname(hostname)
27
+ }
28
+ end.compact
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-elasticloadbalancing'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Elb
9
+ def self.run
10
+ client = Aws::ElasticLoadBalancing::Client.new
11
+
12
+ # EC2-Classic load balancers are only returned by the 'elasticloadbalancing' API, and
13
+ # EC2-VPC ALBs/NLBs are only returned by the 'elasticloadbalancingv2' API
14
+ client.describe_load_balancers.flat_map do |response|
15
+ response.load_balancer_descriptions.flat_map do |load_balancer|
16
+ next [] unless load_balancer.scheme == 'internet-facing'
17
+ {
18
+ id: load_balancer.canonical_hosted_zone_name_id,
19
+ hostname: load_balancer.dns_name,
20
+ # EC2-Classic load balancers get IPv6 DNS records created but they are not returned by the API
21
+ ip_addresses: Utils.resolve_hostnames([load_balancer.dns_name, "ipv6.#{load_balancer.dns_name}"])
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-elasticloadbalancingv2'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Elbv2
9
+ def self.run
10
+ client = Aws::ElasticLoadBalancingV2::Client.new
11
+
12
+ # EC2-Classic load balancers are only returned by the 'elasticloadbalancing' API, and
13
+ # EC2-VPC ALBs/NLBs are only returned by the 'elasticloadbalancingv2' API
14
+
15
+ # NLBs only support IPv4
16
+ # ALBs support IPv4 or dualstack. Unlike Classic ELBs which have a separate IPv6 DNS name,
17
+ # dualstack ALBs only have a single DNS name
18
+ client.describe_load_balancers.flat_map do |response|
19
+ response.load_balancers.flat_map do |load_balancer|
20
+ next [] unless load_balancer.scheme == 'internet-facing'
21
+ {
22
+ id: load_balancer.canonical_hosted_zone_id,
23
+ hostname: load_balancer.dns_name,
24
+ ip_addresses: Utils.resolve_hostname(load_balancer.dns_name)
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-lightsail'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Lightsail
9
+ def self.run
10
+ client = Aws::Lightsail::Client.new
11
+
12
+ # Lightsail instances are always exposed directly, and can also be put behind a load balancer
13
+
14
+ instances = client.get_instances.flat_map do |response|
15
+ response.instances.map do |instance|
16
+ {
17
+ # Names are unique
18
+ id: instance.name,
19
+ hostname: nil,
20
+ ip_addresses: [instance.public_ip_address]
21
+ }
22
+ end
23
+ end
24
+
25
+ load_balancers = client.get_load_balancers.flat_map do |response|
26
+ response.load_balancers.map do |load_balancer|
27
+ {
28
+ # Names are unique
29
+ id: load_balancer.name,
30
+ hostname: load_balancer.dns_name,
31
+ ip_addresses: Utils.resolve_hostname(load_balancer.dns_name)
32
+ }
33
+ end
34
+ end
35
+
36
+ instances + load_balancers
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-rds'
4
+ require 'aws_public_ips/utils'
5
+
6
+ module AwsPublicIps
7
+ module Checks
8
+ module Rds
9
+ def self.run
10
+ client = Aws::RDS::Client.new
11
+
12
+ # TODO(arkadiy) not sure if this is true anymore after redshift, do more testing
13
+ # RDS instances can be:
14
+ # - launched into classic
15
+ # - launched into VPC
16
+ # - launched into a VPC but marked as `publicly_accessible`, in which case the VPC must have an Internet
17
+ # Gateway attached, and the DNS endpoint will resolve to a public ip address
18
+ client.describe_db_instances.flat_map do |response|
19
+ response.db_instances.flat_map do |instance|
20
+ next [] unless instance.publicly_accessible
21
+ {
22
+ id: instance.dbi_resource_id,
23
+ hostname: instance.endpoint.address,
24
+ ip_addresses: Utils.resolve_hostname(instance.endpoint.address)
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-redshift'
4
+
5
+ module AwsPublicIps
6
+ module Checks
7
+ module Redshift
8
+ def self.run
9
+ client = Aws::Redshift::Client.new
10
+
11
+ # TODO(arkadiy) update copy from RDS
12
+ # Redshift clusters can only be launched into VPCs. They can be marked as `publicly_accessible`,
13
+ # in which case the VPC must have an Internet Gateway attached, and the DNS endpoint will
14
+ # resolve to a public ip address
15
+ client.describe_clusters.flat_map do |response|
16
+ response.clusters.flat_map do |cluster|
17
+ next [] unless cluster.publicly_accessible
18
+ {
19
+ id: cluster.cluster_identifier,
20
+ hostname: cluster.endpoint.address,
21
+ ip_addresses: cluster.cluster_nodes.map(&:public_ip_address)
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module AwsPublicIps
6
+ class CLI
7
+ # Supported services:
8
+ # EC2 (and as a result: ECS, EKS, Beanstalk, Fargate, Batch, & NAT Instances)
9
+ # ELB (Classic ELB)
10
+ # ELBv2 (ALB/NLB)
11
+ # RDS
12
+ # Redshift
13
+ # APIGateway
14
+ # CloudFront
15
+ # Lightsail
16
+ # ElasticSearch
17
+
18
+ # Services that don't need to be supported:
19
+ # S3 - all s3 buckets resolve to the same ip addresses
20
+ # SQS - there's a single AWS-owned domain per region (i.e. sqs.us-east-1.amazonaws.com/<account_id>/<queue_name>)
21
+ # NAT Gateways - these do not allow ingress traffic
22
+ # ElastiCache - all elasticache instances are private. You can make one public by using a NAT instance with an EIP:
23
+ # https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/accessing-elasticache.html#access-from-outside-aws
24
+ # but NAT instances are EC2 machines, so this will be caught by the EC2 check.
25
+ # DynamoDB - no public endpoints
26
+ # SNS - no public endpoints
27
+ # Elastic Transcoder - no public endpoints
28
+ # Athena - no public endpoints
29
+
30
+ # Services that maybe have public endpoints / still need testing:
31
+ # fargate
32
+ # amazonmq
33
+ # directory service (AD)
34
+ # emr
35
+ # Directconnect
36
+ # Kinesis
37
+ # SES
38
+ # https://aws.amazon.com/products/
39
+ # AWS Neptune (still in preview / not GA yet)
40
+
41
+ def all_services
42
+ @all_services ||= Dir['lib/aws_public_ips/checks/*.rb'].map { |path| File.basename(path, '.rb') }.sort
43
+ end
44
+
45
+ def all_formats
46
+ @all_formats ||= Dir['lib/aws_public_ips/formatters/*.rb'].map { |path| File.basename(path, '.rb') }.sort
47
+ end
48
+
49
+ def parse(args)
50
+ options = {
51
+ format: 'text',
52
+ services: all_services,
53
+ verbose: false
54
+ }
55
+
56
+ OptionParser.new do |opts|
57
+ opts.banner = 'Usage: aws_public_ips [options]'
58
+
59
+ opts.on('-s', '--services <s1>,<s2>,<s3>', Array, 'List of AWS services to check. Available services: ' \
60
+ "#{all_services.join(',')}. Defaults to all.") do |services|
61
+ services.map(&:downcase!).uniq!
62
+ invalid_services = services - all_services
63
+ raise ArgumentError, "Invalid service(s): #{invalid_services.join(',')}" unless invalid_services.empty?
64
+ options[:services] = services
65
+ end
66
+
67
+ opts.on('-f', '--format <format>', String, 'Set output format. Available formats: ' \
68
+ "#{all_formats.join(',')}. Defaults to text.") do |fmt|
69
+ unless all_formats.include?(fmt)
70
+ raise ArgumentError, "Invalid format '#{fmt}'. Valid formats are: #{all_formats.join(',')}"
71
+ end
72
+ options[:format] = fmt
73
+ end
74
+
75
+ opts.on('-v', '--[no-]verbose', 'Enable debug/trace output') do |verbose|
76
+ options[:verbose] = verbose
77
+ end
78
+ end.parse(args)
79
+
80
+ options
81
+ end
82
+
83
+ def check_service(service)
84
+ require "aws_public_ips/checks/#{service}.rb"
85
+ AwsPublicIps::Checks.const_get(service.capitalize).run
86
+ end
87
+
88
+ def output(formatter, results)
89
+ require "aws_public_ips/formatters/#{formatter}.rb"
90
+ formatter_klass = AwsPublicIps::Formatters.const_get(formatter.capitalize)
91
+ output = formatter_klass.new(results).format
92
+ puts output unless output.empty?
93
+ end
94
+
95
+ def run(args)
96
+ options = parse(args)
97
+
98
+ results = options[:services].map do |service|
99
+ [service.to_sym, check_service(service)]
100
+ end.to_h
101
+
102
+ output(options[:format], results)
103
+ rescue StandardError, Interrupt => ex
104
+ puts ex.inspect
105
+ puts ex.backtrace if options[:verbose]
106
+ Process.exit(1)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsPublicIps
4
+ module Formatters
5
+ end
6
+ end
7
+
8
+ require 'aws_public_ips/formatters/json'
9
+ require 'aws_public_ips/formatters/prettyjson'
10
+ require 'aws_public_ips/formatters/text'
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module AwsPublicIps
6
+ module Formatters
7
+ class Json
8
+ def initialize(results)
9
+ @results = results
10
+ end
11
+
12
+ def format
13
+ @results.to_json
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module AwsPublicIps
6
+ module Formatters
7
+ class Prettyjson
8
+ def initialize(results)
9
+ @results = results
10
+ end
11
+
12
+ def format
13
+ JSON.pretty_generate(@results)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsPublicIps
4
+ module Formatters
5
+ class Text
6
+ def initialize(results)
7
+ @results = results
8
+ end
9
+
10
+ def format
11
+ @results.values.flatten.flat_map do |hash|
12
+ hash[:ip_addresses]
13
+ end.uniq.join("\n")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'resolv'
4
+
5
+ module AwsPublicIps
6
+ module Utils
7
+ def self.resolve_hostnames(hostnames)
8
+ hostnames.flat_map(&method(:resolve_hostname))
9
+ end
10
+
11
+ def self.resolve_hostname(hostname)
12
+ # Default Resolv.getaddresses doesn't seem to return IPv6 results
13
+ resources = Resolv::DNS.open do |dns|
14
+ dns.getresources(hostname, Resolv::DNS::Resource::IN::A) +
15
+ dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA)
16
+ end
17
+
18
+ resources.map do |resource|
19
+ resource.address.to_s.downcase
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsPublicIps
4
+ VERSION = '1.0.0'.freeze
5
+ end
metadata ADDED
@@ -0,0 +1,259 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws_public_ips
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Arkadiy Tetelman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-apigateway
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.10.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-cloudfront
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-ec2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.33.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.33.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-sdk-elasticloadbalancing
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: aws-sdk-elasticloadbalancingv2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.8.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.8.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-elasticsearchservice
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.5.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.5.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: aws-sdk-lightsail
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.4.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.4.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: aws-sdk-rds
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.18.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.18.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: aws-sdk-redshift
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.2.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.2.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: bundler-audit
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.6.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.6.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: coveralls
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.8.12
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.8.12
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 3.7.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 3.7.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.55.0
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.55.0
195
+ - !ruby/object:Gem::Dependency
196
+ name: webmock
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 3.4.1
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 3.4.1
209
+ description: A library/cli to fetch all public IP addresses associated with an AWS
210
+ account
211
+ email:
212
+ executables: []
213
+ extensions: []
214
+ extra_rdoc_files: []
215
+ files:
216
+ - bin/aws_public_ips
217
+ - lib/aws_public_ips.rb
218
+ - lib/aws_public_ips/checks.rb
219
+ - lib/aws_public_ips/checks/apigateway.rb
220
+ - lib/aws_public_ips/checks/cloudfront.rb
221
+ - lib/aws_public_ips/checks/ec2.rb
222
+ - lib/aws_public_ips/checks/elasticsearch.rb
223
+ - lib/aws_public_ips/checks/elb.rb
224
+ - lib/aws_public_ips/checks/elbv2.rb
225
+ - lib/aws_public_ips/checks/lightsail.rb
226
+ - lib/aws_public_ips/checks/rds.rb
227
+ - lib/aws_public_ips/checks/redshift.rb
228
+ - lib/aws_public_ips/cli.rb
229
+ - lib/aws_public_ips/formatters.rb
230
+ - lib/aws_public_ips/formatters/json.rb
231
+ - lib/aws_public_ips/formatters/prettyjson.rb
232
+ - lib/aws_public_ips/formatters/text.rb
233
+ - lib/aws_public_ips/utils.rb
234
+ - lib/aws_public_ips/version.rb
235
+ homepage: https://github.com/arkadiyt/aws_public_ips
236
+ licenses:
237
+ - MIT
238
+ metadata: {}
239
+ post_install_message:
240
+ rdoc_options: []
241
+ require_paths:
242
+ - lib
243
+ required_ruby_version: !ruby/object:Gem::Requirement
244
+ requirements:
245
+ - - ">="
246
+ - !ruby/object:Gem::Version
247
+ version: 2.1.0
248
+ required_rubygems_version: !ruby/object:Gem::Requirement
249
+ requirements:
250
+ - - ">="
251
+ - !ruby/object:Gem::Version
252
+ version: '0'
253
+ requirements: []
254
+ rubyforge_project:
255
+ rubygems_version: 2.6.14
256
+ signing_key:
257
+ specification_version: 4
258
+ summary: A library/cli to fetch all public IP addresses associated with an AWS account
259
+ test_files: []