samba-tool viusalize: mark RODCs in distance matrix
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 8 Mar 2018 01:29:40 +0000 (14:29 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 30 May 2018 23:57:15 +0000 (01:57 +0200)
RODCs should not be replicating out, which means they look alarming
when they are working properly. We label them as RODCs to reminds users
that no outbound replication is expected.

This results in slightly rejigged output formatting.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/graph.py
python/samba/netcmd/visualize.py
python/samba/tests/samba_tool/visualize.py

index 7d195e3574a75d81f377714109f9a8c4d203f79b..a36dc25c2f76928bd55051f10c3f9dcab89db1de 100644 (file)
@@ -513,7 +513,8 @@ def distance_matrix(vertices, edges,
                     colour=None,
                     shorten_names=False,
                     generate_key=False,
-                    grouping_function=None):
+                    grouping_function=None,
+                    row_comments=None):
     lines = []
     write = lines.append
 
@@ -525,8 +526,10 @@ def distance_matrix(vertices, edges,
         diagonal = '·'
         #missing = '🕱'
         missing = '-'
+        right_arrow = '←'
     else:
         vertical, horizontal, corner, diagonal, missing = '|-,0-'
+        right_arrow = '<-'
 
     colours = COLOUR_SETS[colour]
 
@@ -607,6 +610,9 @@ def distance_matrix(vertices, edges,
                     link = '+'
                 row.append('%s%s%s' % (ct, link, c_reset))
 
+        if row_comments is not None and row_comments[i]:
+            row.append('%s %s %s' % (c_reset, right_arrow, row_comments[i]))
+
         write('%s%*s%s %s%s' % (c, vlen, v, c_reset,
                                 ''.join(row), c_reset))
 
index e66030d310705f984b19b69553cc821d0549aad1..2b8c5fc57ff80ecc78e59f9798823f89231036f0 100644 (file)
@@ -450,7 +450,13 @@ class cmd_ntdsconn(GraphCommand):
                 ntds_dn = 'CN=NTDS Settings,' + dsa_dn
                 dn = dsa_dn
 
-            vertices.add(ntds_dn)
+            res = samdb.search(ntds_dn,
+                               scope=SCOPE_BASE,
+                               attrs=["msDS-isRODC"])
+
+            is_rodc = res[0]["msDS-isRODC"][0] == 'TRUE'
+
+            vertices.add((ntds_dn, 'RODC' if is_rodc else ''))
             # XXX we could also look at schedule
             res = samdb.search(dn,
                                scope=SCOPE_SUBTREE,
@@ -482,16 +488,25 @@ class cmd_ntdsconn(GraphCommand):
                 edges[k] = e
             e.attest(attester)
 
+        vertices, rodc_status = zip(*sorted(vertices))
+
         if self.calc_output_format(format, output) == 'distance':
             color_scheme = self.calc_distance_color_scheme(color,
                                                            color_scheme,
                                                            output)
+            colours = COLOUR_SETS[color_scheme]
+            c_header = colours.get('header', '')
+            c_reset = colours.get('reset', '')
+
+            epilog = []
+            if 'RODC' in rodc_status:
+                epilog.append('No outbound connections are expected from RODCs')
+
             if not talk_to_remote:
                 # If we are not talking to remote servers, we list all
                 # the connections.
                 graph_edges = edges.keys()
                 title = 'NTDS Connections known to %s' % local_dsa_dn
-                epilog = ''
 
             else:
                 # If we are talking to the remotes, there are
@@ -521,7 +536,7 @@ class cmd_ntdsconn(GraphCommand):
                         both_deny.append(e)
 
                 title = 'NTDS Connections known to each destination DC'
-                epilog = []
+
                 if both_deny:
                     epilog.append('The following connections are alleged by '
                                   'DCs other than the source and '
@@ -540,15 +555,25 @@ class cmd_ntdsconn(GraphCommand):
                                   'are not known to the source DC:\n')
                     for e in source_denies:
                         epilog.append('  %s -> %s\n' % e)
-                epilog = ''.join(epilog)
 
-            s = distance_matrix(sorted(vertices), graph_edges,
+
+            s = distance_matrix(vertices, graph_edges,
                                 utf8=utf8,
                                 colour=color_scheme,
                                 shorten_names=shorten_names,
                                 generate_key=key,
-                                grouping_function=get_dnstr_site)
-            self.write('\n%s\n%s\n%s' % (title, s, epilog), output)
+                                grouping_function=get_dnstr_site,
+                                row_comments=rodc_status)
+
+            epilog = ''.join(epilog)
+            if epilog:
+                epilog = '\n%sNOTES%s\n%s' % (c_header,
+                                              c_reset,
+                                              epilog)
+
+            self.write('\n%s\n\n%s\n%s' % (title,
+                                           s,
+                                           epilog), output)
             return
 
         dot_edges = []
index 1afb210b7bdc9c192dc3af35f679ba1cca1bd8e3..43757e7b49722e18b8101edc0e92b7533c9280a3 100644 (file)
@@ -71,11 +71,12 @@ def samdb_from_ldif(ldif, tempdir, lp, dsa=None, tag=''):
     return (samdb, dburl)
 
 
-def collapse_space(s):
+def collapse_space(s, keep_empty_lines=False):
     lines = []
     for line in s.splitlines():
         line = ' '.join(line.strip().split())
-        lines.append(line)
+        if line or keep_empty_lines:
+            lines.append(line)
     return '\n'.join(lines)
 
 
@@ -453,6 +454,7 @@ key_0__label -> elision0 [style=invis; weight=9]
 
 EXPECTED_DISTANCE_GRAPH_WITH_KEY = """
 NTDS Connections known to CN=LOCALDC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=samba,DC=example,DC=com
+
                             destination
                   ,-------- *,CN=CLIENT+
                   |,------- *,CN=LOCALDC+