1414clusternum = 0
1515awsflags = []
1616nocache = False
17+ toDraw = set ()
1718
1819
1920###############################################################################
@@ -151,10 +152,11 @@ def drawSec(self, fh):
151152 fh .write ("// NACL %s\n " % self .name )
152153 fh .write ('%s [shape="box", label="%s"];\n ' % (self .mn (), self .name ))
153154 self .genRuleBlock ('ingress' , fh )
155+ fh .write ("%s -> %s_ingress_rules\n " % (self .mn (), self .mn ()))
154156 self .genRuleBlock ('egress' , fh )
157+ fh .write ("%s_egress_rules -> %s\n " % (self .mn (), self .mn ()))
155158
156159 def genRuleBlock (self , direct , fh ):
157- fh .write ("%s -> %s_%s_rules\n " % (self .mn (), self .mn (), direct ))
158160 fh .write ("// NACL %s\n " % self .name )
159161 fh .write ('%s_%s_rules [ shape="Mrecord" label=<<table border="1">' % (self .mn (), direct ))
160162 fh .write ('<tr><td bgcolor="black" colspan="3"><font color="white">%s %s</font></td></tr>\n ' % (self .name , direct ))
@@ -252,7 +254,7 @@ def rank(self, fh):
252254
253255 def drawSec (self , fh ):
254256 fh .write ('// Instance %s\n ' % self .name )
255- fh .write ('%s [label="%s" %s];\n ' % (self .mn (self .name ), self .name , self .image ()))
257+ fh .write ('%s [label="%s\n %s " %s];\n ' % (self .mn (self .name ), self .name , self [ 'PrivateIpAddress' ] , self .image ()))
256258 for sg in self ['SecurityGroups' ]:
257259 self .connect (fh , self .name , sg ['GroupId' ])
258260 if self ['SubnetId' ]:
@@ -403,6 +405,7 @@ def __init__(self, sg, args):
403405 self .data = sg
404406 self .name = sg ['GroupId' ]
405407 self .args = args
408+ self .drawn = False
406409
407410 def draw (self , fh ):
408411 if self .args .vpc and self ['VpcId' ] != self .args .vpc :
@@ -416,6 +419,7 @@ def draw(self, fh):
416419 tportstr .append ("Ingress: %s" % portstr )
417420 if eportstr :
418421 tportstr .append ("Egress: %s" % eportstr )
422+ desc = "\\ n" .join (chunkstring (self ['Description' ], 20 ))
419423 fh .write ('%s [label="SG: %s\n %s\n %s" %s];\n ' % (self .mn (self .name ), self .name , desc , "\n " .join (tportstr ), self .image ()))
420424
421425 def drawSec (self , fh ):
@@ -426,6 +430,7 @@ def drawSec(self, fh):
426430 self .genRuleBlock (self ['IpPermissionsEgress' ], 'egress' , fh )
427431 fh .write ("%s_ingress_rules -> %s;\n " % (self .mn (), self .mn ()))
428432 fh .write ("%s -> %s_egress_rules;\n " % (self .mn (), self .mn ()))
433+ self .drawn = True
429434
430435 def genRuleBlock (self , struct , direct , fh ):
431436 fh .write ("// SG %s %s\n " % (self .name , direct ))
@@ -441,8 +446,16 @@ def genRuleBlock(self, struct, direct, fh):
441446 for ipr in e ['IpRanges' ]:
442447 if 'CidrIp' in ipr :
443448 ipranges .append (ipr ['CidrIp' ])
444- iprangestr = ';' .join (ipranges )
445- if not ipranges :
449+
450+ if ipranges :
451+ if len (ipranges ) > 1 :
452+ iprangestr = "<table>"
453+ for ipr in ipranges :
454+ iprangestr += "<tr><td>%s</td></tr>" % ipr
455+ iprangestr += "</table>"
456+ else :
457+ iprangestr = "%s" % ipranges [0 ]
458+ else :
446459 iprangestr = "See %s" % e ['UserIdGroupPairs' ][0 ]['GroupId' ]
447460 fh .write ("<td>%s</td>" % iprangestr )
448461 if 'FromPort' in e and e ['FromPort' ]:
@@ -456,7 +469,8 @@ def genRuleBlock(self, struct, direct, fh):
456469 for e in struct :
457470 if e ['UserIdGroupPairs' ]:
458471 for pair in e ['UserIdGroupPairs' ]:
459- fh .write ("%s_%s_rules -> %s;\n " % (self .mn (), direct , self .mn (pair ['GroupId' ])))
472+ toDraw .add (pair ['GroupId' ])
473+ fh .write ('%s_%s_rules -> %s [label="SG Referrer"];\n ' % (self .mn (), direct , self .mn (pair ['GroupId' ])))
460474
461475 def relevent_to_ip (self , ip ):
462476 for i in self ['IpPermissions' ]:
@@ -530,6 +544,9 @@ def rank(self, fh):
530544 if self .inVpc (self .args .vpc ) and self .inSubnet (self .args .subnet ):
531545 fh .write ("%s;" % self .mn ())
532546
547+ def drawSec (self , fh ):
548+ fh .write ('%s [label="%s:%s" %s];\n ' % (self .mn (self .name ), self .__class__ .__name__ , self .name , self .image ()))
549+
533550 def draw (self , fh ):
534551 if not self .inVpc (self .args .vpc ) or not self .inSubnet (self .args .subnet ):
535552 return
@@ -583,6 +600,13 @@ def inSubnet(self, subnet):
583600 return True
584601 return False
585602
603+ def drawSec (self , fh ):
604+ routelist = []
605+ for rt in self ['Routes' ]:
606+ if 'DestinationCidrBlock' in rt :
607+ routelist .append (rt ['DestinationCidrBlock' ])
608+ fh .write ('%s [label="RT: %s\n %s" %s];\n ' % (self .mn (), self .name , "\\ n" .join (routelist ), self .image ()))
609+
586610 def draw (self , fh ):
587611 if not self .inVpc (self .args .vpc ) or not self .inSubnet (self .args .subnet ):
588612 return
@@ -856,8 +880,24 @@ def draw(self, fh):
856880
857881
858882###############################################################################
859- def chunkstring (string , length ):
860- return (string [0 + i :length + i ] for i in range (0 , len (string ), length ))
883+ def chunkstring (strng , length ):
884+ """ Break a string on word boundaries, where each line is up to
885+ length characters long """
886+ ans = []
887+ line = []
888+ for w in strng .split ():
889+ if len (w ) >= length :
890+ ans .append (" " .join (line ))
891+ ans .append (w )
892+ line = []
893+ continue
894+ if len (" " .join (line )) + len (w ) < length :
895+ line .append (w )
896+ else :
897+ ans .append (" " .join (line ))
898+ line = []
899+ ans .append (" " .join (line ))
900+ return ans
861901
862902
863903###############################################################################
@@ -1097,6 +1137,7 @@ def generate_secmap(ec2, fh):
10971137 """ Generate a security map instead """
10981138 generateHeader (fh )
10991139 subnet = objects [ec2 ]['SubnetId' ]
1140+ vpc = objects [ec2 ]['VpcId' ]
11001141
11011142 # The ec2
11021143 objects [ec2 ].drawSec (fh )
@@ -1109,13 +1150,22 @@ def generate_secmap(ec2, fh):
11091150 subnet = objects [ec2 ]['SubnetId' ]
11101151 objects [subnet ].drawSec (fh )
11111152
1112- # NACLs associated with that subnet
1153+ # NACLs and RTs associated with that subnet
11131154 for obj in objects .values ():
1114- if obj .__class__ in (NetworkAcl , ):
1155+ if obj .__class__ in (NetworkAcl , RouteTable ):
11151156 for assoc in obj ['Associations' ]:
1116- if assoc ['SubnetId' ] == subnet :
1157+ if 'SubnetId' in assoc and assoc ['SubnetId' ] == subnet :
11171158 obj .drawSec (fh )
11181159 fh .write ("%s -> %s\n " % (obj .mn (), objects [subnet ].mn ()))
1160+
1161+ # VPC that the EC2 is in
1162+ objects [vpc ].drawSec (fh )
1163+
1164+ # Finish any referred to SG
1165+ for sg in list (toDraw ):
1166+ if not objects [sg ].drawn :
1167+ objects [sg ].drawSec (fh )
1168+
11191169 generateFooter (fh )
11201170
11211171
0 commit comments