aws-graph 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/README.md +39 -0
- data/Rakefile +1 -0
- data/aws-graph.gemspec +27 -0
- data/bin/aws-graph +5 -0
- data/lib/aws-graph/version.rb +3 -0
- data/lib/aws-graph.rb +208 -0
- data/lib/ec2.png +0 -0
- data/lib/ec2_disactive.png +0 -0
- data/lib/elb.png +0 -0
- data/lib/rds.png +0 -0
- data/sample.png +0 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 98684500355629aba642dc7d73f4b88f01d40825
|
4
|
+
data.tar.gz: b85e7d15a321c9d25ac7410007bbe6b8efc7eae8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a0c17fbc993ad3773b65783e9071d79c130d9c05c019f2f6a6a2c0f3ef67652871ff3bc8109cbcf2c5ba851cafd690569a0729d33c35a40cf19329db852ed391
|
7
|
+
data.tar.gz: 9915d7062faed34d1413a3e091303b1ad7bdcbfd324777bd1e49969b45b843637f5b9a28ece89ec59c25f30889ac015c8fd1dd6a91298616dbb6e46d995de739
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# aws-graph
|
2
|
+
|
3
|
+
Draw AWS network graph with Graphviz.
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'aws-graph'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install aws-graph
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Make config.yml
|
24
|
+
|
25
|
+
aws_access_key_id: XXXXXXXXXXXXXXXXXXXX
|
26
|
+
aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
27
|
+
aws_region: ap-northeast-1
|
28
|
+
|
29
|
+
And draw graph
|
30
|
+
|
31
|
+
$ aws-graph draw -c config.yml -o output.png
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( http://github.com/<my-github-username>/aws-graph/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/aws-graph.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aws-graph/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "aws-graph"
|
8
|
+
spec.version = AwsGraph::VERSION
|
9
|
+
spec.authors = ["k1LoW"]
|
10
|
+
spec.email = ["k1lowxb@gmail.com"]
|
11
|
+
spec.summary = %q{Draw AWS network graph with Graphviz}
|
12
|
+
spec.description = %q{Draw AWS security based network graph with Graphviz}
|
13
|
+
spec.homepage = "https://github.com/k1LoW/aws-graph"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_dependency "aws-sdk"
|
25
|
+
spec.add_dependency "thor"
|
26
|
+
spec.add_dependency "gviz"
|
27
|
+
end
|
data/bin/aws-graph
ADDED
data/lib/aws-graph.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
require "aws-graph/version"
|
2
|
+
require "thor"
|
3
|
+
require 'aws-sdk'
|
4
|
+
require 'gviz'
|
5
|
+
|
6
|
+
module AwsGraph
|
7
|
+
class CLI < Thor
|
8
|
+
|
9
|
+
desc "draw [config.yml]", "Draw AWS network graph"
|
10
|
+
method_option :config, :type => :string, :aliases => '-c', :default => 'config.yml', :banner => 'AWS config.yml'
|
11
|
+
method_option :output, :type => :string, :aliases => '-o', :default => 'output.png', :banner => 'output file path'
|
12
|
+
method_option :secret, :type => :boolean, :aliases => '-s', :default => false, :banner => 'mask label'
|
13
|
+
def draw()
|
14
|
+
yml = options[:config]
|
15
|
+
self.load(yml)
|
16
|
+
self.sg()
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def sg()
|
21
|
+
gv = Gviz.new(:AWS, :digraph)
|
22
|
+
|
23
|
+
ec2_instances = @ec2.instances # EC2 instances
|
24
|
+
vpcs = @ec2.vpcs # VPC Collection
|
25
|
+
security_groups = @ec2.security_groups # EC2 security groups
|
26
|
+
rds_client = @rds.client # RDS low level client
|
27
|
+
db_instances = rds_client.describe_db_instances
|
28
|
+
db_security_groups = rds_client.describe_db_security_groups
|
29
|
+
lbs = @elb.load_balancers # ELB
|
30
|
+
|
31
|
+
secret = options[:secret]
|
32
|
+
|
33
|
+
gv.graph do
|
34
|
+
global layout:'fdp', overlap:false, compound:true, rankdir:'LR'
|
35
|
+
edges lhead: '', ltail: ''
|
36
|
+
nodes shape: 'box'
|
37
|
+
|
38
|
+
sg_hash = {}
|
39
|
+
|
40
|
+
# Create EC2 security group cluster
|
41
|
+
security_groups.each do | sg |
|
42
|
+
print "."
|
43
|
+
cluster_id = 'cluster' + sg.id.gsub(/[-\/]/,'')
|
44
|
+
sg_hash[sg.id] = cluster_id
|
45
|
+
subgraph(cluster_id.to_sym) do
|
46
|
+
global label: Util.new.label(sg.name + '[' + sg.id + ']', secret), style: 'rounded'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create RDS security group cluster
|
51
|
+
db_security_groups[:db_security_groups].each do | db_sg |
|
52
|
+
print "."
|
53
|
+
cluster_id = 'cluster' + db_sg[:db_security_group_name].gsub(/[-\/]/,'')
|
54
|
+
subgraph(cluster_id.to_sym) do
|
55
|
+
global label: Util.new.label(db_sg[:db_security_group_name], secret), style: 'rounded'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Append EC2 to EC2 security group
|
60
|
+
ec2_instances.each do | e |
|
61
|
+
if e.status == :running
|
62
|
+
image_path = File.dirname(__FILE__) + '/ec2.png'
|
63
|
+
else
|
64
|
+
image_path = File.dirname(__FILE__) + '/ec2_disactive.png'
|
65
|
+
end
|
66
|
+
e.security_groups.each do | sg |
|
67
|
+
print "."
|
68
|
+
cluster_id = 'cluster' + sg.id.gsub(/[-\/]/,'')
|
69
|
+
subgraph(cluster_id.to_sym) do
|
70
|
+
node (sg.id + ':' + e.id).gsub(/[-\/]/, '').to_sym, label: Util.new.label(e.id, secret), shape: :none, image: image_path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Append VPC EC2 to EC2 security group
|
76
|
+
vpcs.each do | vpc |
|
77
|
+
vpc.instances.each do | e |
|
78
|
+
if e.status == :running
|
79
|
+
image_path = File.dirname(__FILE__) + '/ec2.png'
|
80
|
+
else
|
81
|
+
image_path = File.dirname(__FILE__) + '/ec2_disactive.png'
|
82
|
+
end
|
83
|
+
e.security_groups.each do | sg |
|
84
|
+
print "v"
|
85
|
+
cluster_id = 'cluster' + sg.id.gsub(/[-\/]/,'')
|
86
|
+
subgraph(cluster_id.to_sym) do
|
87
|
+
node (sg.id + ':' + e.id).gsub(/[-\/]/, '').to_sym, label: Util.new.label(e.id, secret), shape: :none, image: image_path
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Append RDS to RDS security group
|
94
|
+
db_instancesa = {}
|
95
|
+
db_instances[:db_instances].each do | r |
|
96
|
+
r[:db_security_groups].each do | db_sg |
|
97
|
+
print "."
|
98
|
+
cluster_id = 'cluster' + db_sg[:db_security_group_name].gsub(/[-\/]/,'')
|
99
|
+
image_path = File.dirname(__FILE__) + '/rds.png'
|
100
|
+
subgraph(cluster_id.to_sym) do
|
101
|
+
node (r[:db_instance_identifier]).gsub(/[-\/]/, '').to_sym, label: Util.new.label(r[:db_instance_identifier], secret), shape: :none, image: image_path
|
102
|
+
end
|
103
|
+
end
|
104
|
+
r[:vpc_security_groups].each do | sg |
|
105
|
+
print "v"
|
106
|
+
cluster_id = 'cluster' + sg[:vpc_security_group_id].gsub(/[-\/]/,'')
|
107
|
+
image_path = File.dirname(__FILE__) + '/rds.png'
|
108
|
+
subgraph(cluster_id.to_sym) do
|
109
|
+
node (r[:db_instance_identifier]).gsub(/[-\/]/, '').to_sym, label: Util.new.label(r[:db_instance_identifier], secret), shape: :none, image: image_path
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Add edges EC2 security group
|
115
|
+
security_groups.each do | sg |
|
116
|
+
ips = sg.ingress_ip_permissions # inbound permissions
|
117
|
+
ips.each do | ip |
|
118
|
+
|
119
|
+
# EC2 security group -> EC2 security group
|
120
|
+
ip.groups.each do | fromsg |
|
121
|
+
next if fromsg.id == sg.id
|
122
|
+
print "-"
|
123
|
+
unless sg_hash[fromsg.id]
|
124
|
+
# Unknown security group is amazon-elb/amazon-elb-sg
|
125
|
+
unknown = AWS::EC2::SecurityGroup.new(fromsg.id)
|
126
|
+
cluster_id = 'cluster' + fromsg.id.gsub(/[-\/]/,'')
|
127
|
+
sg_hash['amazon-elb/amazon-elb-sg'] = cluster_id
|
128
|
+
subgraph(cluster_id.to_sym) do
|
129
|
+
global label: Util.new.label('amazon-elb/amazon-elb-sg', false), style: 'rounded'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
from_cluster_id = 'cluster' + fromsg.id.gsub(/[-\/]/,'')
|
133
|
+
to_cluster_id = 'cluster' + sg.id.gsub(/[-\/]/,'')
|
134
|
+
route from_cluster_id.to_sym => to_cluster_id.to_sym
|
135
|
+
edge (from_cluster_id + '_' + to_cluster_id).to_sym, label: Util.new.label(ip.port_range.to_s + '[' + ip.protocol.to_s + ']', secret)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# EC2 security group -> RDS security group
|
141
|
+
db_security_groups[:db_security_groups].each do | db_sg |
|
142
|
+
print "-"
|
143
|
+
db_sg[:ec2_security_groups].each do | sg |
|
144
|
+
if sg[:ec2_security_group_id]
|
145
|
+
from_cluster_id = 'cluster' + sg[:ec2_security_group_id].gsub(/[-\/]/,'')
|
146
|
+
to_cluster_id = 'cluster' + db_sg[:db_security_group_name].gsub(/[-\/]/,'')
|
147
|
+
route from_cluster_id.to_sym => to_cluster_id.to_sym
|
148
|
+
edge (from_cluster_id + '_' + to_cluster_id).to_sym, label: 'RDS'
|
149
|
+
else
|
150
|
+
# なぜかdb_security_group_idが存在しないものがある
|
151
|
+
security_groups.each do | s |
|
152
|
+
if s.name == sg[:ec2_security_group_name]
|
153
|
+
from_cluster_id = 'cluster' + s.id.gsub(/[-\/]/,'')
|
154
|
+
to_cluster_id = 'cluster' + db_sg[:db_security_group_name].gsub(/[-\/]/,'')
|
155
|
+
route from_cluster_id.to_sym => to_cluster_id.to_sym
|
156
|
+
edge (from_cluster_id + '_' + to_cluster_id).to_sym, label: 'RDS'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Append ELB to ELB security group
|
164
|
+
lbs.each do | lb |
|
165
|
+
break unless sg_hash['amazon-elb/amazon-elb-sg']
|
166
|
+
cluster_id = sg_hash['amazon-elb/amazon-elb-sg']
|
167
|
+
image_path = File.dirname(__FILE__) + '/elb.png'
|
168
|
+
subgraph(cluster_id.to_sym) do
|
169
|
+
node lb.name.gsub('-', '').to_sym, label: Util.new.label(lb.name, secret), shape: :none, image: image_path
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
puts ''
|
174
|
+
end
|
175
|
+
gv.save(options[:output].sub(/\.png$/,''), :png)
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
def load(yml)
|
180
|
+
@config = YAML.load_file(yml)
|
181
|
+
@ec2 = AWS::EC2.new(
|
182
|
+
:access_key_id => @config['aws_access_key_id'],
|
183
|
+
:secret_access_key => @config['aws_secret_access_key'],
|
184
|
+
:region => @config['aws_region'],
|
185
|
+
)
|
186
|
+
@rds = AWS::RDS.new(
|
187
|
+
:access_key_id => @config['aws_access_key_id'],
|
188
|
+
:secret_access_key => @config['aws_secret_access_key'],
|
189
|
+
:region => @config['aws_region'],
|
190
|
+
)
|
191
|
+
@elb = AWS::ELB.new(
|
192
|
+
:access_key_id => @config['aws_access_key_id'],
|
193
|
+
:secret_access_key => @config['aws_secret_access_key'],
|
194
|
+
:region => @config['aws_region'],
|
195
|
+
)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
class Util
|
200
|
+
def label(text, secret)
|
201
|
+
if secret
|
202
|
+
return text.gsub(/[^\[\]]/,'*')
|
203
|
+
else
|
204
|
+
return text
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
data/lib/ec2.png
ADDED
Binary file
|
Binary file
|
data/lib/elb.png
ADDED
Binary file
|
data/lib/rds.png
ADDED
Binary file
|
data/sample.png
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws-graph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- k1LoW
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aws-sdk
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gviz
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Draw AWS security based network graph with Graphviz
|
84
|
+
email:
|
85
|
+
- k1lowxb@gmail.com
|
86
|
+
executables:
|
87
|
+
- aws-graph
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- aws-graph.gemspec
|
96
|
+
- bin/aws-graph
|
97
|
+
- lib/aws-graph.rb
|
98
|
+
- lib/aws-graph/version.rb
|
99
|
+
- lib/ec2.png
|
100
|
+
- lib/ec2_disactive.png
|
101
|
+
- lib/elb.png
|
102
|
+
- lib/rds.png
|
103
|
+
- sample.png
|
104
|
+
homepage: https://github.com/k1LoW/aws-graph
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.0.14
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Draw AWS network graph with Graphviz
|
128
|
+
test_files: []
|