Package ZenModel :: Module LinkManager
[hide private]
[frames] | no frames]

Source Code for Module ZenModel.LinkManager

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  from sets import Set as set 
 15  from itertools import groupby 
 16   
 17  from Acquisition import aq_base 
 18   
 19  from Globals import InitializeClass 
 20  from AccessControl import ClassSecurityInfo 
 21   
 22  from OFS.Folder import Folder 
 23   
 24  from simplejson import dumps 
 25  from Products.CMFCore.utils import getToolByName 
 26  from Products.ZCatalog.ZCatalog import manage_addZCatalog 
 27  from Products.ZenUtils.Search import makeCaseInsensitiveFieldIndex 
 28  from Products.ZenUtils.NetworkTree import NetworkLink 
 29   
 30  security = ClassSecurityInfo() 
 31   
 32  NODE_IDS = dict( 
 33      layer_3 = {'IpNetwork':'networkId', 'Device':'deviceId'}, 
 34      layer_2 = {'LAN':'lanId', 'Device':'deviceId'} 
 35  ) 
 36   
37 -def _getComplement(context, layer=3):
38 key = 'layer_%d' % layer 39 nodestuff = NODE_IDS[key] 40 if not type(context)==type(""): 41 try: 42 context = nodestuff[context.meta_type] 43 except KeyError: 44 return None 45 first, second = nodestuff.values() 46 if context==first: 47 return second 48 else: 49 return first
50
51 -def manage_addLinkManager(context, id="ZenLinkManager"):
52 """ Make a LinkManager """ 53 mgr = LinkManager(id) 54 context._setObject(mgr.id, mgr) 55 mgr = context._getOb(id) 56 _create_catalogs(mgr)
57 58
59 -def _create_layer2_catalog(mgr):
60 layer_2_indices = ( 61 ('lanId', makeCaseInsensitiveFieldIndex), 62 ('macaddress', makeCaseInsensitiveFieldIndex), 63 ('deviceId', makeCaseInsensitiveFieldIndex), 64 ('interfaceId', makeCaseInsensitiveFieldIndex) 65 ) 66 mgr._addLinkCatalog('layer2_catalog', layer_2_indices)
67 68
69 -def _create_layer3_catalog(mgr):
70 layer_3_indices = ( 71 ('networkId', makeCaseInsensitiveFieldIndex), 72 ('ipAddressId', makeCaseInsensitiveFieldIndex), 73 ('deviceId', makeCaseInsensitiveFieldIndex), 74 ('interfaceId', makeCaseInsensitiveFieldIndex) 75 ) 76 mgr._addLinkCatalog('layer3_catalog', layer_3_indices)
77 78
79 -def _create_catalogs(mgr):
80 _create_layer2_catalog(mgr) 81 _create_layer3_catalog(mgr)
82 83 112 113
114 -class LinkManager(Folder):
115 """ 116 A tool that keeps track of OSI layer links between objects. 117 """
118 - def __init__(self, id, *args, **kwargs):
119 Folder.__init__(self, id, *args, **kwargs) 120 self.id = id
121
122 - def _getCatalog(self, layer=3):
123 try: 124 return getToolByName(self, 'layer%d_catalog' % layer) 125 except AttributeError: 126 return None
127
128 - def _addLinkCatalog(self, id, indices):
129 manage_addZCatalog(self, id, id) 130 zcat = self._getOb(id) 131 cat = zcat._catalog 132 for index, factory in indices: 133 cat.addIndex(index, factory(index)) 134 zcat.addColumn(index)
135
136 - def getLinkedNodes(self, meta_type, id, layer=3, visited=None):
137 cat = self._getCatalog(layer) 138 col = NODE_IDS['layer_%d' % layer][meta_type] 139 nextcol = _getComplement(col, layer) 140 brains = cat(**{col:id}) 141 gen1ids = set(getattr(brain, nextcol) for brain in brains) 142 if visited: 143 gen1ids = gen1ids - visited # Don't go places we've been! 144 gen2 = cat(**{nextcol:list(gen1ids)}) 145 return gen2, gen1ids
146 166 167 def _whichnet(brain): 168 return brain.networkId
169 170 def _whichdev(brain): 171 return brain.deviceId 172 173 links, nets = self.getLinkedNodes('Device', subids.keys()) 174 links = map(aq_base, links) # For comparison, can't be ImplicitAcq 175 176 byloc = {} 177 for k, g in groupby(links, _whichorg): 178 byloc.setdefault(k, []).extend(g) 179 if '__outside' in byloc: del byloc['__outside'] 180 181 bynet = {} 182 for k, g in groupby(links, _whichnet): 183 if getattr(self.dmd.unrestrictedTraverse(k), 'zDrawMapLinks', True): 184 bynet.setdefault(k, []).extend(g) 185 186 final = {} 187 linkobs = [] 188 189 inverted_loc = {} 190 for loc in byloc: 191 for dev in byloc[loc]: 192 inverted_loc[dev.deviceId] = loc 193 for net in bynet: 194 devs = bynet[net] 195 alllocs = set() 196 for dev in devs: 197 if dev.deviceId and dev.deviceId in inverted_loc: 198 alllocs.add(inverted_loc[dev.deviceId]) 199 if len(alllocs)>=2: 200 for dev in devs: 201 if dev.deviceId: 202 loc = inverted_loc.get(dev.deviceId, None) 203 if loc: 204 final.setdefault(loc, []).append(dev) 205 def haslink(locs1, locs2): 206 for l in locs1: 207 for b in locs2: 208 if l.networkId==b.networkId: 209 return True 210 locs = final.keys() 211 while locs: 212 loc = locs.pop() 213 for loc2 in locs: 214 first = final[loc] 215 second = final[loc2] 216 if haslink(first, second): 217 link = Layer3Link(self.dmd, {loc:first, loc2:second}) 218 linkobs.append(link) 219 return dumps([(x.getAddresses(), x.getStatus()) for x in linkobs]) 220 236 259 for ip in net.ipaddresses.objectValuesGen(): 260 iface = ip.interface() 261 if iface: addToDict(iface) 262 if len(locdict)<=1: continue 263 locgroups = locdict.values() 264 while locgroups: 265 lg = locgroups.pop() 266 targets = [] 267 for g in locgroups: targets.extend(g) 268 for l in lg: 269 for t in targets: 270 n = NetworkLink() 271 n.setEndpoints(l, t) 272 result.add(n) 273 return result 274 InitializeClass(LinkManager) 275