1
2
3
4
5
6
7
8
9
10
11 """
12 Operations for Networks.
13
14 Available at: /zport/dmd/network_router
15 """
16
17 import logging
18 from Products.ZenUtils.Ext import DirectResponse
19 from Products.ZenUtils.IpUtil import IpAddressError
20 from Products.Zuul.decorators import require
21 from Products.Zuul.interfaces import ITreeNode
22 from Products.ZenUtils.jsonutils import unjson
23 from Products.ZenUtils.Utils import getDisplayType
24 from Products import Zuul
25 from Products.Zuul.decorators import serviceConnectionError
26 from Products.Zuul.routers import TreeRouter
27 from Products.ZenMessaging.audit import audit
28
29 log = logging.getLogger('zen.NetworkRouter')
32 """
33 A JSON/ExtDirect interface to operations on networks
34 """
35
39
41 return Zuul.getFacade('network', self.context)
42
43 @require('Manage DMD')
45 """
46 Discover devices on a network.
47
48 @type uid: string
49 @param uid: Unique identifier of the network to discover
50 @rtype: DirectResponse
51 @return: B{Properties}:
52 - jobId: (integer) The id of the discovery job
53 """
54 jobStatus = self.api.discoverDevices(uid)
55 if jobStatus:
56 audit('UI.Network.DiscoverDevices', uid)
57 return DirectResponse.succeed(new_jobs=Zuul.marshal([jobStatus],
58 keys=('uuid', 'description','started')))
59 else:
60 return DirectResponse.fail()
61
62 @require('Manage DMD')
63 - def addNode(self, newSubnet, contextUid):
64 """
65 Add a new subnet.
66
67 @type newSubnet: string
68 @param newSubnet: New subnet to add
69 @type contextUid: string
70 @param contextUid: Unique identifier of the network parent of the new subnet
71 @rtype: DirectResponse
72 @return: B{Properties}:
73 - newNode: (dictionary) An object representing the new subnet node
74 """
75
76 if '/' not in newSubnet:
77 response = DirectResponse.fail('You must include a subnet mask.')
78 else:
79 try:
80 netip, netmask = newSubnet.split('/')
81 netmask = int(netmask)
82 foundSubnet = self.api.findSubnet(netip, netmask, contextUid)
83
84 if foundSubnet is not None:
85 response = DirectResponse.fail('Did not add duplicate subnet: %s (%s/%s)' %
86 (newSubnet, foundSubnet.id, foundSubnet.netmask))
87 else:
88 newNet = self.api.addSubnet(newSubnet, contextUid)
89 node = ITreeNode(newNet)
90 audit('UI.Network.AddSubnet', contextUid, subnet=newSubnet)
91 response = DirectResponse.succeed(newNode=Zuul.marshal(node))
92
93 except IpAddressError as error:
94 response = DirectResponse.exception(error, 'Error adding subnet.')
95
96 except Exception as error:
97 log.exception("Error adding subnet.")
98 response = DirectResponse.exception(error, 'Error adding subnet.')
99
100 return response
101
102 @require('Manage DMD')
104 """
105 Delete a subnet.
106
107 @type uid: string
108 @param uid: Unique identifier of the subnet to delete
109 @rtype: DirectResponse
110 @return: B{Properties}:
111 - tree: (dictionary) An object representing the new network tree
112 """
113 self.api.deleteSubnet(uid)
114 audit('UI.Network.DeleteSubnet', subnet=uid)
115 return DirectResponse.succeed(tree=self.getTree())
116
117
118 - def getTree(self, id='/zport/dmd/Networks'):
119 """
120 Returns the tree structure of an organizer hierarchy where
121 the root node is the organizer identified by the id parameter.
122
123 @type id: string
124 @param id: Id of the root node of the tree to be returned. Defaults to
125 the Networks tree root.
126 @rtype: [dictionary]
127 @return: Object representing the tree
128 """
129 tree = self.api.getTree(id)
130 data = Zuul.marshal(tree)
131 return [data]
132
133 - def getInfo(self, uid, keys=None):
134 """
135 Returns a dictionary of the properties of an object
136
137 @type uid: string
138 @param uid: Unique identifier of an object
139 @type keys: list
140 @param keys: (optional) List of keys to include in the returned
141 dictionary. If None then all keys will be returned
142 @rtype: DirectResponse
143 @return: B{Properties}
144 - data: (dictionary) Object properties
145 """
146 network = self.api.getInfo(uid)
147 data = Zuul.marshal(network, keys)
148 disabled = not Zuul.checkPermission('Manage DMD')
149 return DirectResponse.succeed(data=data, disabled=disabled)
150
151 @require('Manage DMD')
153 """
154 Main method for setting attributes on a network or network organizer.
155 This method accepts any keyword argument for the property that you wish
156 to set. The only required property is "uid".
157
158 @type uid: string
159 @keyword uid: Unique identifier of an object
160 @rtype: DirectResponse
161 """
162 network = self.api.getInfo(data['uid'])
163 Zuul.unmarshal(data, network)
164 audit(['UI', getDisplayType(network), 'Edit'], network, data_=data)
165 return DirectResponse.succeed()
166
167 @serviceConnectionError
168 - def getIpAddresses(self, uid, start=0, params=None, limit=50, sort='ipAddressAsInt',
169 page=None, dir='ASC'):
170 """
171 Given a subnet, get a list of IP addresses and their relations.
172
173 @type uid: string
174 @param uid: Unique identifier of a subnet
175 @type start: integer
176 @param start: Offset to return the results from; used in pagination
177 @type params: string
178 @param params: Not used
179 @type limit: integer
180 @param limit: Number of items to return; used in pagination
181 @type sort: string
182 @param sort: (optional) Key on which to sort the return results;
183 defaults to 'name'
184 @type order: string
185 @param order: Sort order; can be either 'ASC' or 'DESC'
186 @rtype: DirectResponse
187 """
188 if isinstance(params, basestring):
189 params = unjson(params)
190 instances = self.api.getIpAddresses(uid=uid, start=start, params=params,
191 limit=limit, sort=sort, dir=dir)
192
193 keys = ['name', 'netmask', 'pingstatus', 'snmpstatus', 'uid',
194 'device', 'interface', 'macAddress',
195 'interfaceDescription']
196 data = Zuul.marshal(instances.results, keys)
197 return DirectResponse.succeed(data=data, totalCount=instances.total,
198 hash=instances.hash_)
199
201 """
202 Removes every ip address specified by uids that are
203 not attached to any device
204 @type uids: Array of Strings
205 @param uids: unique identfiers of the ip addresses to delete
206 """
207 if uids:
208 removedCount, errorCount = self.api.removeIpAddresses(uids)
209 audit('UI.IPAddress.Remove', ips=uids, numremoved=removedCount,
210 numerrors=errorCount)
211 return DirectResponse.succeed(removedCount=removedCount,
212 errorCount=errorCount)
213
214 - def newDiscoveryJob(self, networks=None, zProperties=None, collector='localhost'):
215 jobs = self.api.newDiscoveryJob(networks=networks, zProperties=zProperties, collector=collector)
216 audit('UI.Discovery.Add', networks=networks, collector=collector)
217 return DirectResponse.succeed(data=Zuul.marshal(jobs))
218
220 """
221 A JSON/ExtDirect interface to operations on IPv6 networks
222 """
223
227
229 return Zuul.getFacade('network6', self.context)
230