aws-edges 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,53 @@
1
+ module AWSEdges
2
+ class EC2
3
+ attr_reader :nodes
4
+
5
+ def initialize(describe_instances)
6
+ @nodes = Array.new
7
+ describe_instances[:reservation_set].each{|r| r[:instances_set].each{|i|
8
+ @nodes.push({
9
+ :instance_id => i[:instance_id],
10
+ :instance_type => i[:instance_type],
11
+ :kernel_id => i[:kernel_id],
12
+ :ramdisk_id => i[:ramdisk_id],
13
+ :architecture => i[:architecture],
14
+ :ebs_optimized => i[:ebs_optimized],
15
+ :root_device_type => i[:root_device_type],
16
+ :root_device_name => i[:root_device_name],
17
+ :virtualization_type => i[:virtualization_type],
18
+ :hypervisor => i[:hypervisor],
19
+ :source_dest_check => i[:source_dest_check],
20
+ :image_id => i[:image_id],
21
+ :vpc_id => i[:vpc_id],
22
+ :subnet_id => i[:subnet_id],
23
+ :public_dns_name => i[:dns_name],
24
+ :public_ip_address => i[:ip_address],
25
+ :private_dns_name => i[:private_dns_name],
26
+ :private_ip_address => i[:private_ip_address],
27
+ :availability_zone => i[:placement][:availability_zone],
28
+ :security_groups => []
29
+ })
30
+
31
+ security_groups = Array.new
32
+ i[:group_set].each{|g|
33
+ security_groups.push({
34
+ :group_name => g[:group_name],
35
+ :group_id => g[:group_id]
36
+ })
37
+ }
38
+ @nodes[@nodes.length - 1][:security_groups] = security_groups
39
+ }}
40
+ end
41
+
42
+ def self.supported_fields
43
+ [
44
+ "instance_id", "kernel_id", "ramdisk_id", "architecture",
45
+ "ebs_optimized", "root_device_type", "root_device_name",
46
+ "virtualization_type", "hypervisor", "source_dest_check", "image_id", "vpc_id",
47
+ "subnet_id", "public_dns_name", "public_ip_address", "private_dns_name",
48
+ "private_ip_address", "availability_zone", "security_groups-group_name",
49
+ "security_groups-group_id"
50
+ ]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,190 @@
1
+ # TODO -list
2
+ # add edge shape/color attribute support
3
+ # add node (ie path) color/shape support
4
+ # allow control of node_attribs << filled
5
+ # add xref support for edge nodes (eg:)
6
+ # - ec2_private_ip_address
7
+ # - vpc_cidr_block
8
+ # change edge to node if point is missing
9
+ # add support for nested values
10
+ # - redshift_cluster_nodes-*
11
+
12
+ module AWSEdges
13
+ class Graph
14
+ attr_reader :format
15
+
16
+ def initialize(config_data, aws_data)
17
+ @config = config_data
18
+ @aws = aws_data
19
+ end
20
+
21
+ ##
22
+ # Generate the graphviz digraph statement for edges
23
+ #
24
+ def map_edges(from, from_color, from_shape, to, to_color, to_shape)
25
+ cmd_string = ""
26
+ from_prefix, from_node = $1, $2 if from =~ /^(\w+?)_(.+)/
27
+ to_prefix, to_node = $1, $2 if to =~ /^(\w+?)_(.+)/
28
+ @aws[:"#{from_prefix}"].each do |node|
29
+ if from_node.include?('-')
30
+ (parent, child) = from_node.split('-')
31
+ node[:"#{parent}"].each do |i|
32
+ cmd_string += " edge " + '"' +
33
+ i[:"#{child}"].to_s + '","' +
34
+ node[:"#{to_node}"].to_s + '";'
35
+
36
+ unless from_color.nil?
37
+ unless from_color.empty?
38
+ cmd_string += assign_color_attribute(from_color, i[:"#{child}"])
39
+ end
40
+ end
41
+
42
+ unless from_shape.nil?
43
+ unless from_shape.empty?
44
+ cmd_string += assign_shape_attribute(from_shape, i[:"#{child}"])
45
+ end
46
+ end
47
+
48
+ unless to_color.nil?
49
+ unless to_color.empty?
50
+ cmd_string += assign_color_attribute(to_color, node[:"#{to_node}"])
51
+ end
52
+ end
53
+
54
+ unless to_shape.nil?
55
+ unless to_shape.empty?
56
+ cmd_string += assign_shape_attribute(to_shape, node[:"#{to_node}"])
57
+ end
58
+ end
59
+
60
+ end unless node[:"#{parent}"].nil?
61
+ elsif to_node.include?('-')
62
+ (parent, child) = to_node.split('-')
63
+ node[:"#{parent}"].each do |i|
64
+ cmd_string += " edge " + '"' +
65
+ node[:"#{from_node}"].to_s + '","' +
66
+ i[:"#{child}"].to_s + '";'
67
+
68
+ unless from_color.nil?
69
+ unless from_color.empty?
70
+ cmd_string += assign_color_attribute(from_color, node[:"#{from_node}"])
71
+ end
72
+ end
73
+
74
+ unless from_shape.nil?
75
+ unless from_shape.empty?
76
+ cmd_string += assign_shape_attribute(from_shape, node[:"#{from_node}"])
77
+ end
78
+ end
79
+
80
+ unless to_color.nil?
81
+ unless to_color.empty?
82
+ cmd_string += assign_color_attribute(to_color, i[:"#{child}"])
83
+ end
84
+ end
85
+
86
+ unless to_shape.nil?
87
+ unless to_shape.empty?
88
+ cmd_string += assign_shape_attribute(to_shape, i[:"#{child}"])
89
+ end
90
+ end
91
+
92
+ end unless node[:"#{parent}"].nil?
93
+ else
94
+ cmd_string += " edge " + '"' +
95
+ node[:"#{from_node}"].to_s + '","' +
96
+ node[:"#{to_node}"].to_s + '";'
97
+
98
+ unless from_color.nil?
99
+ unless from_color.empty?
100
+ cmd_string += assign_color_attribute(from_color, node[:"#{from_node}"])
101
+ end
102
+ end
103
+
104
+ unless from_shape.nil?
105
+ unless from_shape.empty?
106
+ cmd_string += assign_shape_attribute(from_shape, node[:"#{from_node}"])
107
+ end
108
+ end
109
+
110
+ unless to_color.nil?
111
+ unless to_color.empty?
112
+ cmd_string += assign_color_attribute(to_color, node[:"#{to_node}"])
113
+ end
114
+ end
115
+
116
+ unless to_shape.nil?
117
+ unless to_shape.empty?
118
+ cmd_string += assign_shape_attribute(to_shape, node[:"#{to_node}"])
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ cmd_string
125
+ end
126
+
127
+ ##
128
+ # TODO: assign colors
129
+ # all eg: edge_attribs << orange
130
+ def assign_color_attribute(color, edge)
131
+ return "#{color} << node(\"#{edge}\");"
132
+ end
133
+
134
+ ##
135
+ # TODO: assign shapes
136
+ # all eg: edge_attribs << triangle
137
+ def assign_shape_attribute(shape, edge)
138
+ return "#{shape} << node(\"#{edge}\");"
139
+ end
140
+
141
+ ##
142
+ # Dynamically create graphviz digraph statements
143
+ # based on the config file input
144
+ def generate_graph_statements(config)
145
+ cmd_string = ""
146
+ config.each do |key,value|
147
+ if key == "cluster"
148
+ cmd_string += "cluster \"#{value['label']}\" do "
149
+ cmd_string += "label \"#{value['label']}\";"
150
+ cmd_string += generate_graph_statements(value)
151
+ cmd_string += " end;"
152
+ elsif key == "edges"
153
+ value.each do |e|
154
+ cmd_string += map_edges(
155
+ e['from'], e['from_color'], e['from_shape'],
156
+ e['to'], e['to_color'], e['to_shape']
157
+ )
158
+ end
159
+ end
160
+ end
161
+ cmd_string
162
+ end
163
+
164
+ ##
165
+ # Main method for creating graphviz digraphs from the
166
+ # parsed config file
167
+ def create_graph()
168
+ ##
169
+ # default to png output format
170
+ # for a full list: http://www.graphviz.org/doc/info/output.html
171
+ format = @config.delete('save_as')
172
+ format = "png" unless format
173
+ graph_name = @config.delete('name').gsub(/\s+/,'_')
174
+ rotate_layout = true if @config['rotate'] == true
175
+ cmds = generate_graph_statements(@config)
176
+ begin
177
+ digraph do
178
+ node_attribs << filled
179
+ rotate if rotate_layout
180
+ boxes
181
+ eval cmds
182
+ save "#{graph_name}", "#{format}"
183
+ end
184
+ rescue Exception => e
185
+ puts "Failed to create the graph: #{e}"
186
+ exit 1
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,91 @@
1
+ module AWSEdges
2
+ class IAM
3
+ attr_reader :nodes
4
+
5
+ def initialize(iam)
6
+ @nodes = Array.new
7
+
8
+ # get IAM groups
9
+ iam.list_groups[:groups].each{|g|
10
+ @nodes.push({
11
+ :group_name => g[:group_name],
12
+ :group_id => g[:group_id],
13
+ :group_arn => g[:arn],
14
+ :group_create_date => g[:create_date],
15
+ :users => [],
16
+ :group_policies => []
17
+ })
18
+
19
+ # get group members
20
+ assigned_users = Array.new
21
+ iam.get_group(options = {:group_name => g[:group_name]})[:users].each {|u|
22
+ assigned_users.push({
23
+ :user_name => u[:user_name],
24
+ :user_id => u[:user_id],
25
+ :arn => u[:arn],
26
+ :path => u[:path],
27
+ :create_date => u[:create_date],
28
+ })
29
+ }
30
+ @nodes[@nodes.length - 1][:users] = assigned_users
31
+
32
+ # get group policies
33
+ assigned_policies = Array.new
34
+ iam.list_group_policies(options = {:group_name => g[:group_name]})[:policy_names].each {|p|
35
+ assigned_policies.push({
36
+ :policy_name => p
37
+ })
38
+ }
39
+ @nodes[@nodes.length - 1][:group_policies] = assigned_policies
40
+ }
41
+
42
+ # get IAM users
43
+ iam.list_users[:users].each{|u|
44
+ @nodes.push({
45
+ :user_name => u[:user_name],
46
+ :user_id => u[:user_id],
47
+ :user_arn => u[:arn],
48
+ :user_path => u[:path],
49
+ :user_create_date => u[:create_date],
50
+ :groups => [],
51
+ :user_policies => []
52
+ })
53
+
54
+ # get membership
55
+ assigned_groups = Array.new
56
+ iam.list_groups_for_user(options = {:user_name => u[:user_name]})[:groups].each {|g|
57
+ assigned_groups.push({
58
+ :path => g[:path],
59
+ :group_name => g[:group_name],
60
+ :group_id => g[:group_id],
61
+ :arn => g[:arn],
62
+ :create_date => g[:create_date]
63
+ })
64
+ }
65
+ @nodes[@nodes.length - 1][:groups] = assigned_groups
66
+
67
+ # get user policies
68
+ assigned_policies = Array.new
69
+ iam.list_user_policies(options = {:user_name => u[:user_name]})[:policy_names].each {|p|
70
+ assigned_policies.push({
71
+ :policy_name => p
72
+ })
73
+ }
74
+ @nodes[@nodes.length - 1][:user_policies] = assigned_policies
75
+ }
76
+ end
77
+
78
+ def self.supported_fields
79
+ [ "group_path", "group_name", "group_id", "group_arn",
80
+ "group_create_date", "users-path", "users-user_name",
81
+ "users-user_id", "users-arn", "users-create_date",
82
+ "group_policies-policy_name",
83
+ "user_path", "user_name", "user_id", "user_arn",
84
+ "user_create_date", "groups-path", "groups-group_name",
85
+ "groups-group_id", "groups-arn", "groups-create_date",
86
+ "user_policies-policy_name"
87
+ ]
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,32 @@
1
+ module AWSEdges
2
+ class RDS
3
+ attr_reader :nodes
4
+
5
+ def initialize(describe_db_instances)
6
+ @nodes = Array.new
7
+ describe_db_instances[:db_instances].each{|i|
8
+ @nodes.push({
9
+ :db_name => i[:db_name],
10
+ :db_engine => i[:engine],
11
+ :vpc_id => i[:db_subnet_group][:vpc_id],
12
+ :subnet_group_name => i[:db_subnet_group][:db_subnet_group_name],
13
+ :availability_zone => i[:availability_zone],
14
+ :secondary_availability_zone => i[:secondary_availability_zone],
15
+ :multi_az => i[:multi_az],
16
+ :db_engine_version => i[:engine_version],
17
+ :iops => i[:iops],
18
+ :publicly_accessible => i[:publicly_accessible]
19
+ })
20
+ }
21
+ end
22
+
23
+ def self.supported_fields
24
+ [
25
+ "db_name", "db_engine", "vpc_id",
26
+ "subnet_group_name", "availability_zone",
27
+ "secondary_availability_zone", "multi_az",
28
+ "db_engine_version", "iops", "publicly_accessible"
29
+ ]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ module AWSEdges
2
+ class Redshift
3
+ attr_reader :nodes
4
+
5
+ def initialize(describe_clusters)
6
+ @nodes = Array.new
7
+ describe_clusters[:clusters].each{|c|
8
+ @nodes.push({
9
+ :db_name => c[:db_name],
10
+ :vpc_id => c[:vpc_id],
11
+ :availability_zone => c[:availability_zone],
12
+ :subnet_group_name => c[:cluster_subnet_group_name],
13
+ :publicly_accessible => c[:publicly_accessible],
14
+ :cluster_version => c[:cluster_version],
15
+ :encrypted => c[:encrypted],
16
+ :cluster_nodes => []
17
+ })
18
+
19
+ cluster_nodes = Array.new
20
+ c[:cluster_nodes].each{|n|
21
+ cluster_nodes.push({
22
+ :node_role => n[:role_name],
23
+ :public_ip_address => n[:public_ip_address],
24
+ :private_ip_address => n[:private_ip_address]
25
+ })
26
+ }
27
+ @nodes[@nodes.length - 1][:cluster_nodes] = cluster_nodes
28
+ }
29
+ end
30
+
31
+ def self.supported_fields
32
+ [
33
+ "db_name", "vpc_id", "availability_zone",
34
+ "subnet_group_name", "publicly_accessible", "cluster_version",
35
+ "encrypted", "cluster_nodes-node_role",
36
+ "cluster_nodes-public_ip_address", "cluster_nodes-private_ip_address"
37
+ ]
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ module AWSEdges
2
+ class Subnet
3
+ attr_reader :nodes
4
+
5
+ def initialize(describe_subnets)
6
+ @nodes = Array.new
7
+ describe_subnets[:subnet_set].each{|s|
8
+ @nodes.push({
9
+ :vpc_id => s[:vpc_id],
10
+ :cidr_block => s[:cidr_block],
11
+ :availability_zone => s[:availability_zone],
12
+ :subnet_id => s[:subnet_id]
13
+ })
14
+ }
15
+ end
16
+
17
+ def self.supported_fields
18
+ [ "vpc_id", "cidr_block", "availability_zone", "subnet_id" ]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module AWSEdges
2
+ ##
3
+ # returns the version of this module
4
+ VERSION = '0.8'
5
+ end
@@ -0,0 +1,19 @@
1
+ module AWSEdges
2
+ class VPC
3
+ attr_reader :nodes
4
+
5
+ def initialize(describe_vpcs)
6
+ @nodes = Array.new
7
+ describe_vpcs[:vpc_set].each{|v|
8
+ @nodes.push({
9
+ :vpc_id => v[:vpc_id],
10
+ :cidr_block => v[:cidr_block]
11
+ })
12
+ }
13
+ end
14
+
15
+ def self.supported_fields
16
+ [ "vpc_id", "cidr_block" ]
17
+ end
18
+ end
19
+ end