aws_public_ips 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
+ 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: []