aws-edges 0.8

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,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