', 'Daemon':'zenhub', 'Seconds':10}
]}"
"""
- ICONS = ['/zport/dmd/img/agt_action_success-32.png',
- '/zport/dmd/img/messagebox_warning-32.png',
- '/zport/dmd/img/agt_stop-32.png']
+ ICONS = [
+ "/zport/dmd/img/agt_action_success-32.png",
+ "/zport/dmd/img/messagebox_warning-32.png",
+ "/zport/dmd/img/agt_stop-32.png",
+ ]
msgbox = messaging.IUserMessages(self.context)
msgs = msgbox.get_messages()
- cols = ['Message']
+ cols = ["Message"]
res = []
for msg in msgs:
- res.append(dict(
- title = msg.title,
- imgpath = ICONS[msg.priority],
- body = msg.body,
- ago = relative_time(msg.timestamp),
- deletelink = msg.absolute_url_path() + '/delMsg'
- ))
+ res.append(
+ dict(
+ title=msg.title,
+ imgpath=ICONS[msg.priority],
+ body=msg.body,
+ ago=relative_time(msg.timestamp),
+ deletelink=msg.absolute_url_path() + "/delMsg",
+ )
+ )
res.reverse()
- return { 'columns': cols, 'data': res }
+ return {"columns": cols, "data": res}
diff --git a/Products/ZenWidgets/browser/__init__.py b/Products/ZenWidgets/browser/__init__.py
index de5b4971fc..8f3a86088f 100644
--- a/Products/ZenWidgets/browser/__init__.py
+++ b/Products/ZenWidgets/browser/__init__.py
@@ -1,11 +1,8 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
-
-
diff --git a/Products/ZenWidgets/browser/messaging.py b/Products/ZenWidgets/browser/messaging.py
index bf5a324690..c12ccf328f 100644
--- a/Products/ZenWidgets/browser/messaging.py
+++ b/Products/ZenWidgets/browser/messaging.py
@@ -1,42 +1,46 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
from Products.Five.browser import BrowserView
from Products.ZenUtils.jsonutils import json
-from Products.ZenModel.ZenossSecurity import *
-from Products.ZenWidgets.interfaces import IUserMessages, IBrowserMessages
-from Products.ZenWidgets import messaging
+
+from .. import messaging
+from ..interfaces import IBrowserMessages, IUserMessages
+
class UserMessages(BrowserView):
"""
Delivers up user messages for the current user to the client-side
YAHOO.zenoss.Messenger.
"""
+
@json
def __call__(self):
messages = IUserMessages(self.context).get_unread()
messages.extend(IBrowserMessages(self.context).get_unread())
- messages.sort(key=lambda x:x.timestamp)
+ messages.sort(key=lambda x: x.timestamp)
result = []
for message in messages:
- result.append(dict(
- sticky=message.priority>=messaging.CRITICAL and True or False,
- image=message.image,
- title=message.title,
- body=message.body,
- priority=message.priority
- ))
+ result.append(
+ dict(
+ sticky=message.priority >= messaging.CRITICAL
+ and True
+ or False,
+ image=message.image,
+ title=message.title,
+ body=message.body,
+ priority=message.priority,
+ )
+ )
message.mark_as_read()
- result = {'totalRecords':len(result),
- 'messages':result}
+ result = {"totalRecords": len(result), "messages": result}
return result
diff --git a/Products/ZenWidgets/browser/quickstart/__init__.py b/Products/ZenWidgets/browser/quickstart/__init__.py
index de5b4971fc..8f3a86088f 100644
--- a/Products/ZenWidgets/browser/quickstart/__init__.py
+++ b/Products/ZenWidgets/browser/quickstart/__init__.py
@@ -1,11 +1,8 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
-
-
diff --git a/Products/ZenWidgets/browser/quickstart/userViews.py b/Products/ZenWidgets/browser/quickstart/userViews.py
index 4a5cbd3a50..e5dea600ee 100644
--- a/Products/ZenWidgets/browser/quickstart/userViews.py
+++ b/Products/ZenWidgets/browser/quickstart/userViews.py
@@ -1,32 +1,33 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2009, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
import logging
-log = logging.getLogger("zen.widgets.userviews")
+from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
+
+from Products.ZenModel.Quickstart import getTopQuickstartStep
from Products.ZenUtils import Ext
from Products.ZenUtils.csrf import check_csrf_token
-from Products.CMFCore.utils import getToolByName
-from Products.ZenModel.Quickstart import getTopQuickstartStep
+
+log = logging.getLogger("zen.widgets.userviews")
class SetAdminPasswordException(Exception):
- """There was a problem setting the admin password"""
+ """There was a problem setting the admin password."""
+
class CreateUserView(BrowserView):
- """
- Creates the initial user and sets the admin password.
- """
- __call__ = ZopeTwoPageTemplateFile('templates/createuser.pt')
+ """Creates the initial user and sets the admin password."""
+
+ __call__ = ZopeTwoPageTemplateFile("templates/createuser.pt")
@Ext.form_action
def createUser(self):
@@ -43,35 +44,47 @@ def createUser(self):
userPassword = self.request.form.get("password1")
emailAddress = self.request.form.get("emailAddress")
- zenUsers = getToolByName(self.context, 'ZenUsers')
+ zenUsers = getToolByName(self.context, "ZenUsers")
# Set admin password
try:
- admin = zenUsers.getUserSettings('admin')
- admin.manage_editUserSettings(password=adminPassword,
- sndpassword=adminPassword,
- roles=('ZenManager', 'Manager'),
- oldpassword='zenoss')
+ admin = zenUsers.getUserSettings("admin")
+ admin.manage_editUserSettings(
+ password=adminPassword,
+ sndpassword=adminPassword,
+ roles=("ZenManager", "Manager"),
+ oldpassword="zenoss",
+ )
except Exception:
log.exception("Failed to set admin password")
- response.error('admin-password1',
- "There was a problem setting the admin password.")
+ response.error(
+ "admin-password1",
+ "There was a problem setting the admin password.",
+ )
- if not zenUsers.checkValidId(userName) == True:
- response.error('username', 'That username already exists.')
+ if not zenUsers.checkValidId(userName) is True:
+ response.error("username", "That username already exists.")
else:
- ret = zenUsers.manage_addUser(userName, userPassword,
- ('Manager',), REQUEST=None, email=emailAddress)
+ ret = zenUsers.manage_addUser(
+ userName,
+ userPassword,
+ ("Manager",),
+ REQUEST=None,
+ email=emailAddress,
+ )
if ret is None:
- response.error('username',
- 'We were unable to add a user at this time.'
- ' Check your installation.')
+ response.error(
+ "username",
+ "We were unable to add a user at this time."
+ " Check your installation.",
+ )
if not response.has_errors():
# Log out, so the form can log us in as the new user
- acl_users = self.context.getPhysicalRoot().acl_users
+ _ = self.context.getPhysicalRoot().acl_users
self.context.acl_users.resetCredentials(
- self.request, self.request.response)
+ self.request, self.request.response
+ )
# Don't run the quickstart next time
self.context.dmd._rq = True
diff --git a/Products/ZenWidgets/browser/quickstart/views.py b/Products/ZenWidgets/browser/quickstart/views.py
index 6faa14c13c..c6ec4a7a4f 100644
--- a/Products/ZenWidgets/browser/quickstart/views.py
+++ b/Products/ZenWidgets/browser/quickstart/views.py
@@ -7,55 +7,61 @@
#
##############################################################################
-
-import re
-import logging
import cgi
+import logging
+import re
+
from Acquisition import aq_base
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
+
+from Products.ZenMessaging.audit import audit
from Products.ZenModel.IpNetwork import AutoDiscoveryJob
-from Products.ZenWidgets.messaging import IMessageSender
from Products.ZenUtils import Ext
from Products.ZenUtils.jsonutils import json
-from Products.ZenMessaging.audit import audit
-_is_network = lambda x: bool(re.compile(r'^(\d+\.){3}\d+\/\d+$').search(x))
-_is_range = lambda x: bool(re.compile(r'^(\d+\.){3}\d+\-\d+$').search(x))
+from ...messaging import IMessageSender
+
log = logging.getLogger("zen.quickstart")
+
+def _is_network(x):
+ return bool(re.compile(r"^(\d+\.){3}\d+\/\d+$").search(x))
+
+
+def _is_range(x):
+ return bool(re.compile(r"^(\d+\.){3}\d+\-\d+$").search(x))
+
+
class QuickstartBase(BrowserView):
- """
- Standard macros for the quickstart.
- """
- template = ZopeTwoPageTemplateFile('templates/quickstart_macros.pt')
+ """Standard macros for the quickstart."""
+
+ template = ZopeTwoPageTemplateFile("templates/quickstart_macros.pt")
def __getitem__(self, key):
return self.template.macros[key]
class OutlineView(BrowserView):
- """
- Displays the steps the user will soon be completing. The anticipation!
- """
- __call__ = ZopeTwoPageTemplateFile('templates/outline.pt')
+ """Displays the steps the user will soon be completing."""
+
+ __call__ = ZopeTwoPageTemplateFile("templates/outline.pt")
class CreateUserView(BrowserView):
- """
- Creates the initial user and sets the admin password.
- """
- __call__ = ZopeTwoPageTemplateFile('templates/createuser.pt')
+ """Creates the initial user and sets the admin password."""
+
+ __call__ = ZopeTwoPageTemplateFile("templates/createuser.pt")
class DeviceAddView(BrowserView):
- """
- Specify devices to be added.
- """
+ """Specify devices to be added."""
+
@property
def hasLDAPInstalled(self):
try:
- import ZenPacks.zenoss.LDAPAuthenticator
+ import ZenPacks.zenoss.LDAPAuthenticator # noqa F401
+
# return javascript true/false
return "true"
except ImportError:
@@ -67,19 +73,19 @@ def default_communities(self):
Format the value of Devices.Discovered.zSnmpCommunities for a textarea
"""
devclass = self.context.dmd.Devices.Discovered.primaryAq()
- return '\n'.join(devclass.zSnmpCommunities)
+ return "\n".join(devclass.zSnmpCommunities)
def _assemble_types_list(self):
"""
Walks all device classes building a list of description/protocol pairs.
"""
- ALLOWED_PROTOCOLS = ('SSH', 'SNMP', 'WMI', 'WinRM')
+ ALLOWED_PROTOCOLS = ("SSH", "SNMP", "WMI", "WinRM")
devclass = self.context.dmd.Devices
orgs = devclass.getSubOrganizers()
types = []
for org in orgs:
# Skip it if it doesn't have types registered
- if not hasattr(aq_base(org), 'devtypes') or not org.devtypes:
+ if not hasattr(aq_base(org), "devtypes") or not org.devtypes:
continue
for t in org.devtypes:
try:
@@ -93,16 +99,23 @@ def _assemble_types_list(self):
# special case for migrating from WMI to WinRM so we
# can allow the zenpack to be backwards compatible
- if org.getOrganizerName() == '/Server/Microsoft/Windows' and ptcl == 'WMI':
+ if (
+ org.getOrganizerName() == "/Server/Microsoft/Windows"
+ and ptcl == "WMI"
+ ):
ptcl = "WinRM"
# We only care about orgs with acceptable protocols
- if ptcl not in ALLOWED_PROTOCOLS: continue
+ if ptcl not in ALLOWED_PROTOCOLS:
+ continue
types.append((org.getOrganizerName(), desc, ptcl))
return types
@json
def collectors(self):
- return [[name] for name in self.context.dmd.Monitors.getPerformanceMonitorNames()]
+ return [
+ [name]
+ for name in self.context.dmd.Monitors.getPerformanceMonitorNames()
+ ]
@json
def device_types(self):
@@ -115,12 +128,16 @@ def device_types(self):
appropriate ZenPack installed?).
"""
# Turn them into the dictionary format expected
- types = {'win':[], 'ssh':[], 'snmp':[], 'winrm': []}
+ types = {"win": [], "ssh": [], "snmp": [], "winrm": []}
for t in self._assemble_types_list():
- if t[2]=='WMI': types['win'].append(t)
- elif t[2]=='SNMP': types['snmp'].append(t)
- elif t[2]=='SSH': types['ssh'].append(t)
- elif t[2]=='WinRM': types['win'].append(t)
+ if t[2] == "WMI":
+ types["win"].append(t)
+ elif t[2] == "SNMP":
+ types["snmp"].append(t)
+ elif t[2] == "SSH":
+ types["ssh"].append(t)
+ elif t[2] == "WinRM":
+ types["win"].append(t)
def dev_class_exists(path):
"""
@@ -128,8 +145,7 @@ def dev_class_exists(path):
exists.
"""
try:
- self.context.unrestrictedTraverse(
- '/zport/dmd/Devices' + path)
+ self.context.unrestrictedTraverse("/zport/dmd/Devices" + path)
except AttributeError:
return False
else:
@@ -140,10 +156,13 @@ def format_type(credtype, classpath, description, protocol):
Turn information representing a device class into a dictionary of
the format our ComboBox expects.
"""
- value = '%s_%s' % (classpath, credtype)
- return dict(value=value,
- shortdesc="%s (%s)" % (description, protocol),
- description=description, protocol=protocol)
+ value = "%s_%s" % (classpath, credtype)
+ return dict(
+ value=value,
+ shortdesc="%s (%s)" % (description, protocol),
+ description=description,
+ protocol=protocol,
+ )
# Iterate over all types
response = []
@@ -155,148 +174,184 @@ def format_type(credtype, classpath, description, protocol):
response.append(format_type(credtype, *devtype))
# Sort alphabetically by description
- response.sort(key=lambda x:x['description'])
+ response.sort(key=lambda x: x["description"])
# Final response needs an object under a defined root, in this case
# "types"
return dict(types=response)
-
@Ext.form_action
def autodiscovery(self):
response = Ext.FormResponse()
- submitted = self.request.form.get('network', [])
+ submitted = self.request.form.get("network", [])
if isinstance(submitted, basestring):
submitted = [submitted]
zProperties = {
- 'zCommandUsername': self.request.form.get('sshusername'),
- 'zCommandPassword': self.request.form.get('sshpass'),
- 'zWinRMUser': self.request.form.get('winusername'),
- 'zWinRMPassword': self.request.form.get('winpass'),
- 'zSnmpCommunities': self.request.form.get('snmpcommunities').splitlines()
+ "zCommandUsername": self.request.form.get("sshusername"),
+ "zCommandPassword": self.request.form.get("sshpass"),
+ "zWinRMUser": self.request.form.get("winusername"),
+ "zWinRMPassword": self.request.form.get("winpass"),
+ "zSnmpCommunities": self.request.form.get(
+ "snmpcommunities"
+ ).splitlines(),
}
- collector = self.request.form.get('autodiscovery_collector', 'localhost')
+ collector = self.request.form.get(
+ "autodiscovery_collector", "localhost"
+ )
# Split rows into networks and ranges
nets = []
ranges = []
for row in submitted:
- if _is_network(row): nets.append(row)
- elif _is_range(row): ranges.append(row)
+ if _is_network(row):
+ nets.append(row)
+ elif _is_range(row):
+ ranges.append(row)
if not nets and not ranges:
- response.error('network',
- 'You must enter at least one network or IP range.')
+ response.error(
+ "network", "You must enter at least one network or IP range."
+ )
if nets:
for net in nets:
# Make the network if it doesn't exist, so zendisc has
# something to discover
- _n = self.context.dmd.Networks.createNet(net)
+ _ = self.context.dmd.Networks.createNet(net)
try:
- netdesc = ("network %s" % nets[0] if len(nets)==1
- else "%s networks" % len(nets))
+ netdesc = (
+ "network %s" % nets[0]
+ if len(nets) == 1
+ else "%s networks" % len(nets)
+ )
self.context.JobManager.addJob(
AutoDiscoveryJob,
description="Discover %s" % netdesc,
kwargs=dict(
- nets=nets,
- zProperties=zProperties,
- collector=collector
- )
+ nets=nets, zProperties=zProperties, collector=collector
+ ),
)
except Exception as e:
log.exception(e)
- response.error('network', 'There was an error scheduling this '
- 'job. Please check your installation and try '
- 'again.')
+ response.error(
+ "network",
+ "There was an error scheduling this job. "
+ "Please check your installation and try again.",
+ )
else:
IMessageSender(self.context).sendToUser(
- 'Autodiscovery Task Created',
- 'Discovery of the following networks is in progress: %s' % (
- ', '.join(nets))
+ "Autodiscovery Task Created",
+ "Discovery of the following networks is in progress: %s"
+ % (", ".join(nets)),
)
if ranges:
# Ranges can just be sent to zendisc, as they are merely sets of
# IPs
try:
- rangedesc = ("IP range %s" % ranges[0]
- if len(ranges)==1
- else "%s IP ranges" % len(ranges))
+ rangedesc = (
+ "IP range %s" % ranges[0]
+ if len(ranges) == 1
+ else "%s IP ranges" % len(ranges)
+ )
self.context.JobManager.addJob(
AutoDiscoveryJob,
description="Discover %s" % rangedesc,
kwargs=dict(
ranges=ranges,
zProperties=zProperties,
- collector=collector
- )
+ collector=collector,
+ ),
)
except Exception as e:
log.exception(e)
- response.error('network', 'There was an error scheduling this '
- 'job. Please check your installation and try '
- 'again.')
+ response.error(
+ "network",
+ "There was an error scheduling this job. "
+ "Please check your installation and try again.",
+ )
else:
IMessageSender(self.context).sendToUser(
- 'Autodiscovery Task Created',
- 'Discovery of the following IP ranges is in progress: %s' % (
- ', '.join(ranges))
+ "Autodiscovery Task Created",
+ "Discovery of the following IP ranges is in progress: %s"
+ % (", ".join(ranges)),
)
- audit('UI.Device.Autodiscovery', networks=','.join(nets), ipRanges=','.join(ranges))
- response.redirect('/zport/dmd')
+ audit(
+ "UI.Device.Autodiscovery",
+ networks=",".join(nets),
+ ipRanges=",".join(ranges),
+ )
+ response.redirect("/zport/dmd")
return response
-
@Ext.form_action
def manual(self):
# Pull all the device name keys
response = Ext.FormResponse()
- devs = filter(lambda x:x.startswith('device_'),
- self.request.form.keys())
+ devs = filter(
+ lambda x: x.startswith("device_"), self.request.form.keys()
+ )
# Make sure we have at least one device name
- devnames = filter(lambda x:bool(self.request.form.get(x)), devs)
+ devnames = filter(lambda x: bool(self.request.form.get(x)), devs)
if not devnames:
- response.error('device_0',
- 'You must enter at least one hostname/IP.')
+ response.error(
+ "device_0", "You must enter at least one hostname/IP."
+ )
return response
# Create jobs based on info passed
for k in devs:
# Ignore empty device names
- if not self.request.form.get(k): continue
- idx = k.split('_')[1]
+ if not self.request.form.get(k):
+ continue
+ idx = k.split("_")[1]
devclass, type_ = self.request.form.get(
- 'deviceclass_%s' % idx).split('_')
- collector = self.request.form.get('collector_' + str(idx), 'localhost')
+ "deviceclass_%s" % idx
+ ).split("_")
+ collector = self.request.form.get(
+ "collector_" + str(idx), "localhost"
+ )
# Set zProps based on type
- if type_=='ssh':
+ if type_ == "ssh":
zProps = {
- 'zCommandUsername': self.request.form.get('sshuser_%s' % idx),
- 'zCommandPassword': self.request.form.get(
- 'sshpass_%s' % idx),
+ "zCommandUsername": self.request.form.get(
+ "sshuser_%s" % idx
+ ),
+ "zCommandPassword": self.request.form.get(
+ "sshpass_%s" % idx
+ ),
}
- elif type_=='win':
+ elif type_ == "win":
zProps = {
- 'zWinRMUser': self.request.form.get('winuser_%s' % idx),
- 'zWinRMPassword': self.request.form.get('winpass_%s' % idx),
+ "zWinRMUser": self.request.form.get("winuser_%s" % idx),
+ "zWinRMPassword": self.request.form.get(
+ "winpass_%s" % idx
+ ),
}
- elif type_=='snmp':
+ elif type_ == "snmp":
zProps = {
- 'zSnmpCommunities': self.request.form.get(
- 'snmpcomm_%s' % idx
+ "zSnmpCommunities": self.request.form.get(
+ "snmpcomm_%s" % idx
).splitlines()
}
deviceName = self.request.form.get(k)
perfConf = self.context.Monitors.getPerformanceMonitor(collector)
- perfConf.addCreateDeviceJob(deviceName=deviceName, performanceMonitor=collector,
- devicePath=devclass, zProperties=zProps, discoverProto='auto')
- deviceClassUid = '/Devices' + devclass
- deviceUid = '/'.join([deviceClassUid, 'devices', deviceName])
- audit('UI.Device.Add', deviceUid, deviceClass=deviceClassUid, model=True)
+ perfConf.addCreateDeviceJob(
+ deviceName=deviceName,
+ performanceMonitor=collector,
+ devicePath=devclass,
+ zProperties=zProps,
+ discoverProto="auto",
+ )
+ deviceClassUid = "/Devices" + devclass
+ deviceUid = "/".join([deviceClassUid, "devices", deviceName])
+ audit(
+ "UI.Device.Add",
+ deviceUid,
+ deviceClass=deviceClassUid,
+ model=True,
+ )
devnames = [self.request.form.get(dev) for dev in devs]
IMessageSender(self.context).sendToUser(
- 'Devices Added',
- 'Modeling of the following devices has been scheduled: %s' % (
- cgi.escape(', '.join(filter(None, devnames)))
- )
+ "Devices Added",
+ "Modeling of the following devices has been scheduled: %s"
+ % (cgi.escape(", ".join(filter(None, devnames)))),
)
- response.redirect('/zport/dmd')
+ response.redirect("/zport/dmd")
return response
diff --git a/Products/ZenWidgets/interfaces.py b/Products/ZenWidgets/interfaces.py
index 7ef424fdc1..dc0935cffc 100644
--- a/Products/ZenWidgets/interfaces.py
+++ b/Products/ZenWidgets/interfaces.py
@@ -1,22 +1,23 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
-from zope.interface import Interface, Attribute
from zope.container.interfaces import IContained, IContainer
+from zope.interface import Interface, Attribute
class IMessage(IContained):
+ """A single message.
+
+ Messages are stored in user-specific MessageQueue objects and in the
+ session object.
"""
- A single message. Messages are stored in user-specific MessageQueue objects
- and in the session object.
- """
+
title = Attribute("Title of the message")
body = Attribute("Body of the message")
image = Attribute("Optional path to image to be displayed")
@@ -25,28 +26,24 @@ class IMessage(IContained):
sticky = Attribute("Explicitly designate stickiness")
def delete():
- """
- Delete this message from any queues in which it exists.
- """
+ """Delete this message from any queues in which it exists."""
+
def mark_as_read():
- """
- Mark this message as read.
- """
+ """Mark this message as read."""
class IMessageSender(Interface):
- """
- Something able to send messages.
- """
+ """Something able to send messages."""
+
def sendToBrowser(title, body, priority, image=None, sticky=None):
- """
- Create a message and store it on the request object.
- """
+ """Create a message and store it on the request object."""
+
def sendToUser(title, body, priority, image=None, user=None):
"""
Create a message and store it in the L{IMessageQueue} of the user
specified. If no user is specified, use the queue of the current user.
"""
+
def sendToAll(title, body, priority, image=None):
"""
For eash user in the system, create an identical message and store it
@@ -55,33 +52,24 @@ def sendToAll(title, body, priority, image=None):
class IMessageQueue(IContainer):
- """
- Marker interface for a message container.
- """
+ """Marker interface for a message container."""
class IMessageBox(Interface):
- """
- Something that can provide messages.
- """
+ """Something that can provide messages."""
+
messagebox = Attribute("The source of IMessage objects.")
+
def get_messages():
- """
- Return all messages.
- """
+ """Return all messages."""
+
def get_unread():
- """
- Return all messages that have not been marked as read.
- """
+ """Return all messages that have not been marked as read."""
class IUserMessages(IMessageBox):
- """
- Object that is able to provide IMessage objects from a user queue.
- """
+ """Object that is able to provide IMessage objects from a user queue."""
class IBrowserMessages(IMessageBox):
- """
- Object that is able to provide IMessage objects from the request.
- """
+ """Object that is able to provide IMessage objects from the request."""
diff --git a/Products/ZenWidgets/messaging.py b/Products/ZenWidgets/messaging.py
index 9b7370b1fc..5b4dde8f4a 100644
--- a/Products/ZenWidgets/messaging.py
+++ b/Products/ZenWidgets/messaging.py
@@ -1,32 +1,40 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
+
import cgi
import time
-from zope.interface import implements
from Products.CMFCore.utils import getToolByName
-from Products.ZenRelations.utils import ZenRelationshipNameChooser
-from Products.ZenWidgets.interfaces import *
+from zope.interface import implementer
+from Products.ZenRelations.utils import ZenRelationshipNameChooser
+from Products.ZenWidgets.interfaces import (
+ IBrowserMessages,
+ IMessage,
+ IMessageBox,
+ IMessageSender,
+ IUserMessages,
+)
# Constants representing priorities.
# Parallel definitions exist in zenoss.js.
-INFO = 0
-WARNING = 1
+INFO = 0
+WARNING = 1
CRITICAL = 2
+
+@implementer(IMessage)
class BrowserMessage(object):
+ """A single message.
+
+ Messages are stored on UserSettings and in the session object.
"""
- A single message. Messages are stored on UserSettings and in the session
- object.
- """
- implements(IMessage)
__parent__ = None
title = None
@@ -36,8 +44,7 @@ class BrowserMessage(object):
_read = False
def __init__(self, title, body, priority=INFO, image=None, sticky=None):
- """
- Initialization method.
+ """Initialize a BrowserMessage instance.
@param title: The message title
@type title: str
@@ -56,12 +63,13 @@ def __init__(self, title, body, priority=INFO, image=None, sticky=None):
self.sticky = sticky
def delete(self):
- """
- Delete this message from the system.
+ """Delete this message from the system.
"""
self._read = True
- try: self.__parent__.remove(self)
- except (ValueError): pass
+ try:
+ self.__parent__.remove(self)
+ except (ValueError):
+ pass
del self
def mark_as_read(self):
@@ -69,18 +77,17 @@ def mark_as_read(self):
self.delete()
+@implementer(IMessageBox)
class MessageBox(object):
+ """Adapter for all persistent objects.
+
+ Provides a method, L{get_messages}, that retrieves L{Message} objects.
"""
- Adapter for all persistent objects. Provides a method, L{get_messages},
- that retrieves L{Message} objects.
- """
- implements(IMessageBox)
messagebox = None
def get_unread(self, min_priority=INFO):
- """
- Retrieve unread messages.
+ """Retrieve unread messages.
@param min_priority: Optional minimum priority of messages to be
returned; one of INFO, WARNING, CRITICAL
@@ -89,12 +96,11 @@ def get_unread(self, min_priority=INFO):
@rtype: list
"""
msgs = self.get_messages(min_priority)
- msgs = filter(lambda x:not x._read, msgs)
+ msgs = filter(lambda x: not x._read, msgs)
return msgs
def get_messages(self, min_priority=INFO):
- """
- Retrieve messages from the current users's session object.
+ """Retrieve messages from the current users's session object.
@param min_priority: Optional minimum priority of messages to be
returned; one of INFO, WARNING, CRITICAL
@@ -102,69 +108,73 @@ def get_messages(self, min_priority=INFO):
@return: A list of L{Message} objects.
@rtype: list
"""
- msgs = sorted(self.messagebox, key=lambda x:x.timestamp)
- msgs = filter(lambda x:x.priority>=min_priority, msgs)
+ msgs = sorted(self.messagebox, key=lambda x: x.timestamp)
+ msgs = filter(lambda x: x.priority >= min_priority, msgs)
return msgs
+@implementer(IBrowserMessages)
class BrowserMessageBox(MessageBox):
+ """Adapter for all persistent objects.
+
+ Provides a method, L{get_messages}, that retrieves L{Message} objects
+ from the current user's session.
"""
- Adapter for all persistent objects. Provides a method, L{get_messages},
- that retrieves L{Message} objects from the current user's session.
- """
- implements(IBrowserMessages)
+
def __init__(self, context):
- """
- Initialization method.
+ """Initialize a BrowserMessageBox instance.
@param context: The object being adapted. Must have access to the
- current request object via acquisition.
+ current request object via acquisition.
@type context: Persistent
"""
self.context = context
- self.messagebox = self.context.REQUEST.SESSION.get('messages', [])
+ self.messagebox = self.context.REQUEST.SESSION.get("messages", [])
def get_unread(self, min_priority=INFO):
- msgs = super(BrowserMessageBox, self).get_unread(min_priority=min_priority)
+ msgs = super(BrowserMessageBox, self).get_unread(
+ min_priority=min_priority
+ )
# force the session to persist
if msgs:
self.context.REQUEST.SESSION._p_changed = True
return msgs
+
+@implementer(IUserMessages)
class UserMessageBox(MessageBox):
+ """Adapter for all persistent objects.
+
+ Provides a method, L{get_messages}, that retrieves L{Message} objects
+ from the current user's L{MessageQueue}.
"""
- Adapter for all persistent objects. Provides a method, L{get_messages},
- that retrieves L{Message} objects from the current user's L{MessageQueue}.
- """
- implements(IUserMessages)
+
def __init__(self, context, user=None):
- """
- Initialization method.
+ """Initialize a UserMessageBox instance.
@param context: The object being adapted. Must have access to the dmd
- via acquisition.
+ via acquisition.
@type context: Persistent
@param user: Optional username corresponding to the queue from which
- messages will be retrieved. If left as C{None}, the
- current user's queue will be used.
+ messages will be retrieved. If left as C{None}, the current
+ user's queue will be used.
@type user: str
"""
self.context = context
self.user = user
- users = getToolByName(self.context, 'ZenUsers')
+ users = getToolByName(self.context, "ZenUsers")
us = users.getUserSettings(self.user)
self.messagebox = us.messages()
+@implementer(IMessageSender)
class MessageSender(object):
"""
Adapts persistent objects in order to provide message sending capability.
"""
- implements(IMessageSender)
def __init__(self, context):
- """
- Initialization method.
+ """Initialize a MessageSender instance.
@param context: The object being adapted. Must have access to the
dmd and the current request object via acquisition.
@@ -172,9 +182,10 @@ def __init__(self, context):
"""
self.context = context
- def sendToBrowser(self, title, body, priority=INFO, image=None, sticky=None):
- """
- Create a message and store it on the session object.
+ def sendToBrowser(
+ self, title, body, priority=INFO, image=None, sticky=None
+ ):
+ """Create a message and store it on the session object.
@param title: The message title
@type title: str
@@ -185,9 +196,9 @@ def sendToBrowser(self, title, body, priority=INFO, image=None, sticky=None):
@param image: Optional URL of an image to be displayed in the message
@type image: str
"""
- context = self.context.REQUEST.SESSION.get('messages')
+ context = self.context.REQUEST.SESSION.get("messages")
if context is None:
- self.context.REQUEST.SESSION['messages'] = context = []
+ self.context.REQUEST.SESSION["messages"] = context = []
m = BrowserMessage(title, body, priority, image, sticky)
m.__parent__ = context
context.append(m)
@@ -211,11 +222,12 @@ def sendToUser(self, title, body, priority=INFO, image=None, user=None):
user's queue will be used.
@type user: str
"""
- users = getToolByName(self.context, 'ZenUsers')
+ users = getToolByName(self.context, "ZenUsers")
us = users.getUserSettings(user)
- id = ZenRelationshipNameChooser(us.messages).chooseName('msg')
+ id = ZenRelationshipNameChooser(us.messages).chooseName("msg")
# done in here to prevent recursive imports from ZenModelRM
from PersistentMessage import PersistentMessage
+
m = PersistentMessage(id, title, body, priority, image)
us.messages._setObject(m.id, m)
@@ -233,18 +245,22 @@ def sendToAll(self, title, body, priority=INFO, image=None):
@param image: Optional URL of an image to be displayed in the message
@type image: str
"""
- users = getToolByName(self.context, 'ZenUsers')
+ users = getToolByName(self.context, "ZenUsers")
for name in users.getAllUserSettingsNames():
self.sendToUser(title, body, priority, user=name, image=image)
class ScriptMessageSender(MessageSender):
+ """Special message sender for use in scripts.
+
+ Short-circuits sendToBrowser and sendToUser, since they don't really
+ apply. sendToAll should still work fine though.
"""
- Special message sender for use in scripts. Short-circuits sendToBrowser and
- sendToUser, since they don't really apply. sendToAll should still work fine
- though.
- """
- def sendToBrowser(self, title, body, priority=INFO, image=None, sticky=None):
+
+ def sendToBrowser(
+ self, title, body, priority=INFO, image=None, sticky=None
+ ):
pass
+
def sendToUser(self, title, body, priority=INFO, image=None, user=None):
pass
diff --git a/Products/ZenWidgets/tests/__init__.py b/Products/ZenWidgets/tests/__init__.py
index de5b4971fc..8f3a86088f 100644
--- a/Products/ZenWidgets/tests/__init__.py
+++ b/Products/ZenWidgets/tests/__init__.py
@@ -1,11 +1,8 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2007, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
-
-
diff --git a/Products/ZenWidgets/tests/test_Portlets.py b/Products/ZenWidgets/tests/test_Portlets.py
index 611d19c82f..79095637e8 100644
--- a/Products/ZenWidgets/tests/test_Portlets.py
+++ b/Products/ZenWidgets/tests/test_Portlets.py
@@ -1,52 +1,59 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2009, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
import json
+from Products import Zuul
from Products.ZenTestCase.BaseTestCase import BaseTestCase
from Products.ZenWidgets.browser.Portlets import ProductionStatePortletView
-from Products import Zuul
-class TestPortlets(BaseTestCase):
+class TestPortlets(BaseTestCase):
def afterSetUp(self):
super(TestPortlets, self).afterSetUp()
- self.facade = Zuul.getFacade('device', self.dmd)
+ self.facade = Zuul.getFacade("device", self.dmd)
def test_ProductionStatePortletView(self):
# Create some devices
devices = self.dmd.Devices
- test_device_maintenance = devices.createInstance('testDeviceMaintenance')
- test_device_production = devices.createInstance('testDeviceProduction')
+ test_device_maintenance = devices.createInstance(
+ "testDeviceMaintenance"
+ )
+ test_device_production = devices.createInstance("testDeviceProduction")
test_device_maintenance.setProdState(300)
test_device_production.setProdState(1000)
psPortlet = ProductionStatePortletView(self.dmd, self.dmd.REQUEST)
-
+
# filter by maintenance
result = json.loads(psPortlet())
- self.assertEqual(len(result['data']), 1)
- self.assertEqual(result['data'][0]['Device'], test_device_maintenance.getPrettyLink())
+ self.assertEqual(len(result["data"]), 1)
+ self.assertEqual(
+ result["data"][0]["Device"],
+ test_device_maintenance.getPrettyLink(),
+ )
# filter by production
result = json.loads(psPortlet("Production"))
- self.assertEqual(len(result['data']), 1)
- self.assertEqual(result['data'][0]['Device'], test_device_production.getPrettyLink())
+ self.assertEqual(len(result["data"]), 1)
+ self.assertEqual(
+ result["data"][0]["Device"], test_device_production.getPrettyLink()
+ )
# filter by both
result = json.loads(psPortlet(["Production", "Maintenance"]))
- self.assertEqual(len(result['data']), 2)
-
+ self.assertEqual(len(result["data"]), 2)
def test_suite():
from unittest import TestSuite, makeSuite
+
suite = TestSuite()
suite.addTest(makeSuite(TestPortlets))
return suite
diff --git a/Products/ZenWidgets/tests/test_messaging.py b/Products/ZenWidgets/tests/test_messaging.py
index 99a859d360..54617b1863 100644
--- a/Products/ZenWidgets/tests/test_messaging.py
+++ b/Products/ZenWidgets/tests/test_messaging.py
@@ -1,25 +1,27 @@
##############################################################################
-#
+#
# Copyright (C) Zenoss, Inc. 2009, all rights reserved.
-#
+#
# This content is made available according to terms specified in
# License.zenoss under the directory where your Zenoss product is installed.
-#
+#
##############################################################################
-
from AccessControl.SecurityManagement import newSecurityManager
from Products.ZenTestCase.BaseTestCase import BaseTestCase
-from Products.ZenWidgets.messaging import MessageSender
-from Products.ZenWidgets.messaging import BrowserMessageBox, UserMessageBox
+from Products.ZenWidgets.messaging import (
+ BrowserMessageBox,
+ MessageSender,
+ UserMessageBox,
+)
+
class DummySession(dict):
_p_changed = False
class TestMessaging(BaseTestCase):
-
def afterSetUp(self):
super(TestMessaging, self).afterSetUp()
self.dmd.REQUEST.SESSION = DummySession()
@@ -30,46 +32,45 @@ def _login(self, name):
"""
uf = self.dmd.zport.acl_users
user = uf.getUserById(name)
- if not hasattr(user, 'aq_base'):
+ if not hasattr(user, "aq_base"):
user = user.__of__(uf)
newSecurityManager(None, user)
def test_sending_to_request(self):
- MessageSender(self.dmd).sendToBrowser('title', 'This is a message')
- us = self.dmd.ZenUsers.getUserSettings('tester')
+ MessageSender(self.dmd).sendToBrowser("title", "This is a message")
+ us = self.dmd.ZenUsers.getUserSettings("tester")
self.assertEqual(len(us.messages()), 0)
- self.assertEqual(len(self.dmd.REQUEST.SESSION['messages']), 1)
- self.assertEqual(self.dmd.REQUEST.SESSION['messages'][0].body,
- 'This is a message')
+ self.assertEqual(len(self.dmd.REQUEST.SESSION["messages"]), 1)
+ self.assertEqual(
+ self.dmd.REQUEST.SESSION["messages"][0].body, "This is a message"
+ )
def test_sending_to_user(self):
- self._login('tester')
- MessageSender(self.dmd).sendToUser('title', 'This is a message')
- us = self.dmd.ZenUsers.getUserSettings('tester')
+ self._login("tester")
+ MessageSender(self.dmd).sendToUser("title", "This is a message")
+ us = self.dmd.ZenUsers.getUserSettings("tester")
self.assertEqual(len(us.messages), 1)
- self.assertEqual(us.messages()[0].body, 'This is a message')
+ self.assertEqual(us.messages()[0].body, "This is a message")
def test_adapters(self):
MessageSender(self.dmd).sendToBrowser(
- 'title',
- 'This is a browser message')
- MessageSender(self.dmd).sendToUser(
- 'title',
- 'This is a user message')
+ "title", "This is a browser message"
+ )
+ MessageSender(self.dmd).sendToUser("title", "This is a user message")
brow = BrowserMessageBox(self.dmd)
user = UserMessageBox(self.dmd)
browmsgs = brow.get_messages()
usermsgs = user.get_messages()
self.assertEqual(len(browmsgs), 1)
self.assertEqual(len(usermsgs), 1)
- self.assertEqual(browmsgs[0].body, 'This is a browser message')
- self.assertEqual(usermsgs[0].body, 'This is a user message')
+ self.assertEqual(browmsgs[0].body, "This is a browser message")
+ self.assertEqual(usermsgs[0].body, "This is a user message")
def test_mark_as_read(self):
- MessageSender(self.dmd).sendToBrowser('title',
- 'This is a browser message')
- MessageSender(self.dmd).sendToUser('title',
- 'This is a user message')
+ MessageSender(self.dmd).sendToBrowser(
+ "title", "This is a browser message"
+ )
+ MessageSender(self.dmd).sendToUser("title", "This is a user message")
brow = BrowserMessageBox(self.dmd)
user = UserMessageBox(self.dmd)
@@ -85,11 +86,9 @@ def test_mark_as_read(self):
self.assertEqual(len(user.get_unread()), 0)
-
-
-
def test_suite():
from unittest import TestSuite, makeSuite
+
suite = TestSuite()
suite.addTest(makeSuite(TestMessaging))
return suite
diff --git a/Products/Zuul/facades/devicefacade.py b/Products/Zuul/facades/devicefacade.py
index 166efd6471..d63879b82f 100644
--- a/Products/Zuul/facades/devicefacade.py
+++ b/Products/Zuul/facades/devicefacade.py
@@ -7,55 +7,74 @@
#
##############################################################################
-
-import socket
-import re
-import os
import logging
-import subprocess
+import re
+import socket
+
from collections import OrderedDict
from itertools import imap
+
+import six
+
+from AccessControl import getSecurityManager
+from Acquisition import aq_base
+from Products.AdvancedQuery import Eq, Or, Generic, And, MatchGlob
from ZODB.transact import transact
-from zope.interface import implements
+from zope.component import getMultiAdapter
from zope.event import notify
-from zope.component import getMultiAdapter, queryUtility
-from Products.AdvancedQuery import Eq, Or, Generic, And, MatchGlob
-from Products.Zuul.catalog.interfaces import IComponentFieldSpec
-from Products.Zuul.decorators import info
-from Products.Zuul.utils import unbrain
-from Products.Zuul.facades import TreeFacade
-from Products.Zuul.catalog.component_catalog import get_component_field_spec, pad_numeric_values_for_indexing
-from Products.Zuul.catalog.interfaces import IModelCatalogTool
-from Products.Zuul.interfaces import IDeviceFacade, IInfo, ITemplateNode, IMetricServiceGraphDefinition
+from zope.interface import implements
+
+from Products.DataCollector.Plugins import (
+ CoreImporter,
+ loadPlugins,
+ PackImporter,
+)
from Products.Jobber.jobs import FacadeMethodJob
-from Products.Zuul.tree import SearchResults
-from Products.DataCollector.Plugins import CoreImporter, PackImporter, loadPlugins
-from Products.ZenModel.DeviceOrganizer import DeviceOrganizer
+from Products.ZenCollector.configcache.api import ConfigCache
+from Products.ZenEvents.Event import Event
+from Products.ZenMessaging.ChangeEvents.events import (
+ ObjectAddedToOrganizerEvent,
+ ObjectRemovedFromOrganizerEvent,
+)
from Products.ZenModel.ComponentGroup import ComponentGroup
-from Products.ZenModel.DeviceGroup import DeviceGroup
-from Products.ZenModel.System import System
-from Products.ZenModel.Location import Location
from Products.ZenModel.DeviceClass import DeviceClass
+from Products.ZenModel.DeviceGroup import DeviceGroup
from Products.ZenModel.Device import Device
-from Products.ZenMessaging.ChangeEvents.events import ObjectAddedToOrganizerEvent, \
- ObjectRemovedFromOrganizerEvent
-from Products.Zuul import getFacade
-from Products.Zuul.exceptions import DatapointNameConfict
-from Products.Zuul.utils import ZuulMessageFactory as _t, UncataloguedObjectException
-from Products.Zuul.interfaces import IDeviceCollectorChangeEvent
-from Products.Zuul.catalog.events import IndexingEvent
+from Products.ZenModel.Location import Location
+from Products.ZenModel.System import System
+from Products.ZenModel.ZenossSecurity import ZEN_VIEW
from Products.ZenUtils.IpUtil import isip, getHostByName
from Products.ZenUtils.Utils import getObjectsFromCatalog
-from Products.ZenEvents.Event import Event
-from Products.ZenUtils.Utils import binPath, zenPath
-from Acquisition import aq_base
-from Products.Zuul.infos.metricserver import MultiContextMetricServiceGraphDefinition
-from AccessControl import getSecurityManager
-from Products.ZenModel.ZenossSecurity import ZEN_VIEW
+from Products.Zuul.catalog.component_catalog import (
+ get_component_field_spec,
+ pad_numeric_values_for_indexing,
+)
+from Products.Zuul.catalog.events import IndexingEvent
+from Products.Zuul.catalog.interfaces import IModelCatalogTool
+from Products.Zuul.decorators import info
+from Products.Zuul.exceptions import DatapointNameConfict
+from Products.Zuul.facades import TreeFacade
+from Products.Zuul import getFacade
+from Products.Zuul.infos.metricserver import (
+ MultiContextMetricServiceGraphDefinition,
+)
+from Products.Zuul.interfaces import IDeviceCollectorChangeEvent
+from Products.Zuul.interfaces import (
+ IDeviceFacade,
+ IInfo,
+ ITemplateNode,
+ IMetricServiceGraphDefinition,
+)
+from Products.Zuul.tree import SearchResults
+from Products.Zuul.utils import unbrain
+from Products.Zuul.utils import (
+ UncataloguedObjectException,
+ ZuulMessageFactory as _t,
+)
iszprop = re.compile("z[A-Z]").match
-log = logging.getLogger('zen.DeviceFacade')
+log = logging.getLogger("zen.DeviceFacade")
class DeviceCollectorChangeEvent(object):
@@ -92,6 +111,7 @@ class DeviceFacade(TreeFacade):
"""
Facade for device stuff.
"""
+
implements(IDeviceFacade)
def _classFactory(self, contextUid):
@@ -103,25 +123,34 @@ def _root(self):
@property
def _instanceClass(self):
- return 'Products.ZenModel.Device.Device'
+ return "Products.ZenModel.Device.Device"
def setInfo(self, uid, data):
- """
- """
+ """ """
super(DeviceFacade, self).setInfo(uid, data)
obj = self._getObject(uid)
if isinstance(obj, Device):
obj.index_object()
notify(IndexingEvent(obj))
- def findComponentIndex(self, componentUid, uid=None, meta_type=None,
- sort='name', dir='ASC', name=None):
- brains, total = self._typecatComponentBrains(uid=uid, meta_type=meta_type, sort=sort, dir=dir, name=name)
+ def findComponentIndex(
+ self,
+ componentUid,
+ uid=None,
+ meta_type=None,
+ sort="name",
+ dir="ASC",
+ name=None,
+ ):
+ brains, total = self._typecatComponentBrains(
+ uid=uid, meta_type=meta_type, sort=sort, dir=dir, name=name
+ )
if brains is None:
- comps = self._componentSearch(uid=uid, meta_type=meta_type, sort=sort,
- dir=dir, name=name)
+ comps = self._componentSearch(
+ uid=uid, meta_type=meta_type, sort=sort, dir=dir, name=name
+ )
for i, b in enumerate(comps):
- if '/'.join(b._object.getPrimaryPath())==componentUid:
+ if "/".join(b._object.getPrimaryPath()) == componentUid:
return i
else:
for i, b in enumerate(brains):
@@ -130,8 +159,8 @@ def findComponentIndex(self, componentUid, uid=None, meta_type=None,
def _filterComponents(self, comps, keys, query):
"""
- Returns a list of components where one of the attributes in keys contains
- the query (case-insensitive).
+ Returns a list of components where one of the attributes in keys
+ contains the query (case-insensitive).
@type comps: SearchResults
@param comps: All the Components for this query
@@ -148,7 +177,7 @@ def _filterComponents(self, comps, keys, query):
keep = False
for key in keys:
# non searchable fields
- if key in ('uid', 'uuid', 'events', 'status', 'severity'):
+ if key in ("uid", "uuid", "events", "status", "severity"):
continue
val = getattr(comp, key, None)
if not val:
@@ -164,8 +193,18 @@ def _filterComponents(self, comps, keys, query):
results.append(comp)
return results
- def _typecatComponentBrains(self, uid=None, types=(), meta_type=(), start=0,
- limit=None, sort='name', dir='ASC', name=None, keys=()):
+ def _typecatComponentBrains(
+ self,
+ uid=None,
+ types=(),
+ meta_type=(),
+ start=0,
+ limit=None,
+ sort="name",
+ dir="ASC",
+ name=None,
+ keys=(),
+ ):
obj = self._getObject(uid)
spec = get_component_field_spec(meta_type)
if spec is None:
@@ -177,31 +216,41 @@ def _typecatComponentBrains(self, uid=None, types=(), meta_type=(), start=0,
# Fall back to slow queries and sorting
return None, 0
sortspec = ((sort, dir),)
- querySet = [Generic('path', uid)]
+ querySet = [Generic("path", uid)]
if name:
- querySet.append(Or(*(MatchGlob(field, '*%s*' % name) for field in spec.fields)))
+ querySet.append(
+ Or(*(MatchGlob(field, "*%s*" % name) for field in spec.fields))
+ )
brains = typecat.evalAdvancedQuery(And(*querySet), sortspec)
total = len(brains)
if limit is None:
brains = brains[start:]
else:
- brains = brains[start:start+limit]
+ brains = brains[start : start + limit]
return brains, total
- def _typecatComponentPostProcess(self, brains, total, sort='name', reverse=False):
+ def _typecatComponentPostProcess(
+ self, brains, total, sort="name", reverse=False
+ ):
hash_ = str(total)
comps = map(IInfo, map(unbrain, brains))
# fetch any rrd data necessary
self.bulkLoadMetricData(comps)
# Do one big lookup of component events and add to the result objects
- showSeverityIcon = self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get('showEventSeverityIcons')
+ showSeverityIcon = (
+ self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get(
+ "showEventSeverityIcons"
+ )
+ )
if showSeverityIcon:
uuids = [r.uuid for r in comps]
- zep = getFacade('zep')
+ zep = getFacade("zep")
severities = zep.getWorstSeverity(uuids)
for r in comps:
r.setWorstEventSeverity(severities[r.uuid])
- sortedComps = sorted(comps, key=lambda x: getattr(x, sort), reverse=reverse)
+ sortedComps = sorted(
+ comps, key=lambda x: getattr(x, sort), reverse=reverse
+ )
return SearchResults(iter(sortedComps), total, hash_, False)
# Get components from model catalog. Not used for now
@@ -211,33 +260,51 @@ def _get_component_brains_from_model_catalog(self, uid, meta_type=()):
query = {}
if meta_type:
query["meta_type"] = meta_type
- query["objectImplements"] = "Products.ZenModel.DeviceComponent.DeviceComponent"
+ query["objectImplements"] = (
+ "Products.ZenModel.DeviceComponent.DeviceComponent"
+ )
query["deviceId"] = uid
model_query_results = model_catalog.search(query=query)
- brains = [ brain for brain in model_query_results.results ]
+ brains = list(model_query_results.results)
return brains
- def _componentSearch(self, uid=None, types=(), meta_type=(), start=0,
- limit=None, sort='name', dir='ASC', name=None, keys=()):
- reverse = dir=='DESC'
- if isinstance(meta_type, basestring) and get_component_field_spec(meta_type) is not None:
- brains, total = self._typecatComponentBrains(uid, types, meta_type, start,
- limit, sort, dir, name, keys)
+ def _componentSearch(
+ self,
+ uid=None,
+ types=(),
+ meta_type=(),
+ start=0,
+ limit=None,
+ sort="name",
+ dir="ASC",
+ name=None,
+ keys=(),
+ ):
+ reverse = dir == "DESC"
+ if (
+ isinstance(meta_type, six.string_types)
+ and get_component_field_spec(meta_type) is not None
+ ):
+ brains, total = self._typecatComponentBrains(
+ uid, types, meta_type, start, limit, sort, dir, name, keys
+ )
if brains is not None:
- return self._typecatComponentPostProcess(brains, total, sort, reverse)
- if isinstance(meta_type, basestring):
+ return self._typecatComponentPostProcess(
+ brains, total, sort, reverse
+ )
+ if isinstance(meta_type, six.string_types):
meta_type = (meta_type,)
- if isinstance(types, basestring):
+ if isinstance(types, six.string_types):
types = (types,)
querySet = []
if meta_type:
- querySet.append(Or(*(Eq('meta_type', t) for t in meta_type)))
- querySet.append(Generic('getAllPaths', uid))
+ querySet.append(Or(*(Eq("meta_type", t) for t in meta_type)))
+ querySet.append(Generic("getAllPaths", uid))
query = And(*querySet)
obj = self._getObject(uid)
cat = obj.device().componentSearch
- if 'getAllPaths' not in cat.indexes():
+ if "getAllPaths" not in cat.indexes():
obj.device()._createComponentSearchPathIndex()
brains = cat.evalAdvancedQuery(query)
@@ -247,8 +314,12 @@ def _componentSearch(self, uid=None, types=(), meta_type=(), start=0,
try:
comps.append(IInfo(unbrain(brain)))
except Exception:
- log.warn('There is broken component "%s" in componentSearch catalog on %s device.',
- brain.id, obj.device().id)
+ log.warn(
+ 'There is broken component "%s" in componentSearch '
+ "catalog on %s device.",
+ brain.id,
+ obj.device().id,
+ )
# filter the components
if name is not None:
@@ -269,32 +340,55 @@ def componentSortKey(parent):
return pad_numeric_values_for_indexing(val)
# sort the components
- sortedResults = list(sorted(comps, key=componentSortKey, reverse=reverse))
+ sortedResults = sorted(comps, key=componentSortKey, reverse=reverse)
# limit the search results to the specified range
if limit is None:
pagedResult = sortedResults[start:]
else:
- pagedResult = sortedResults[start:start + limit]
+ pagedResult = sortedResults[start : start + limit]
# fetch any rrd data necessary
self.bulkLoadMetricData(pagedResult)
# Do one big lookup of component events and add to the result objects
- showSeverityIcon = self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get('showEventSeverityIcons')
+ showSeverityIcon = (
+ self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get(
+ "showEventSeverityIcons"
+ )
+ )
if showSeverityIcon:
uuids = [r.uuid for r in pagedResult]
- zep = getFacade('zep')
+ zep = getFacade("zep")
severities = zep.getWorstSeverity(uuids)
for r in pagedResult:
r.setWorstEventSeverity(severities[r.uuid])
return SearchResults(iter(pagedResult), total, hash_, False)
- def getComponents(self, uid=None, types=(), meta_type=(), start=0,
- limit=None, sort='name', dir='ASC', name=None, keys=()):
- return self._componentSearch(uid, types, meta_type, start, limit,
- sort, dir, name=name, keys=keys)
+ def getComponents(
+ self,
+ uid=None,
+ types=(),
+ meta_type=(),
+ start=0,
+ limit=None,
+ sort="name",
+ dir="ASC",
+ name=None,
+ keys=(),
+ ):
+ return self._componentSearch(
+ uid,
+ types,
+ meta_type,
+ start,
+ limit,
+ sort,
+ dir,
+ name=name,
+ keys=keys,
+ )
def bulkLoadMetricData(self, infos):
"""
@@ -305,19 +399,21 @@ def bulkLoadMetricData(self, infos):
if len(infos) == 0:
return
datapoints = set()
- indexedInfos = dict()
- for info in infos:
- indexedInfos[info._object.getResourceKey()] = info
- if hasattr(info, "dataPointsToFetch"):
- [datapoints.add(dp) for dp in info.dataPointsToFetch]
+ indexedInfos = {}
+ for inf in infos:
+ indexedInfos[inf._object.getResourceKey()] = inf
+ if hasattr(inf, "dataPointsToFetch"):
+ [datapoints.add(dp) for dp in inf.dataPointsToFetch]
# in case no metrics were asked for
if len(datapoints) == 0:
return
# get the metric facade
- mfacade = getFacade('metric', self._dmd)
+ mfacade = getFacade("metric", self._dmd)
# metric facade expects zenmodel objects or uids
- results = mfacade.getMultiValues([i._object for i in infos], datapoints, returnSet="LAST")
+ results = mfacade.getMultiValues(
+ [i._object for i in infos], datapoints, returnSet="LAST"
+ )
# assign the metrics to the info objects
for resourceKey, record in results.iteritems():
@@ -332,14 +428,21 @@ def _get_component_types_from_model_catalog(self, uid):
componentTypes = {}
uuidMap = {}
model_catalog = IModelCatalogTool(self.context.dmd)
- model_query = Eq('objectImplements', "Products.ZenModel.DeviceComponent.DeviceComponent")
+ model_query = Eq(
+ "objectImplements",
+ "Products.ZenModel.DeviceComponent.DeviceComponent",
+ )
model_query = And(model_query, Eq("deviceId", uid))
- model_query_results = model_catalog.search(query=model_query, fields=["uuid", "meta_type"])
+ model_query_results = model_catalog.search(
+ query=model_query, fields=["uuid", "meta_type"]
+ )
for brain in model_query_results.results:
uuidMap[brain.uuid] = brain.meta_type
- compType = componentTypes.setdefault(brain.meta_type, { 'count' : 0, 'severity' : 0 })
- compType['count'] += 1
+ compType = componentTypes.setdefault(
+ brain.meta_type, {"count": 0, "severity": 0}
+ )
+ compType["count"] += 1
return (componentTypes, uuidMap)
def _get_component_types_from_zcatalog(self, uid):
@@ -349,8 +452,10 @@ def _get_component_types_from_zcatalog(self, uid):
dev = self._getObject(uid)
for brain in dev.componentSearch():
uuidMap[brain.getUUID] = brain.meta_type
- compType = componentTypes.setdefault(brain.meta_type, { 'count' : 0, 'severity' : 0 })
- compType['count'] += 1
+ compType = componentTypes.setdefault(
+ brain.meta_type, {"count": 0, "severity": 0}
+ )
+ compType["count"] += 1
return (componentTypes, uuidMap)
def getComponentTree(self, uid):
@@ -362,40 +467,53 @@ def getComponentTree(self, uid):
if not uuidMap:
return []
- zep = getFacade('zep')
- showSeverityIcon = self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get('showEventSeverityIcons')
+ zep = getFacade("zep")
+ showSeverityIcon = (
+ self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get(
+ "showEventSeverityIcons"
+ )
+ )
if showSeverityIcon:
severities = zep.getWorstSeverity(uuidMap.keys())
for uuid, sev in severities.iteritems():
compType = componentTypes[uuidMap[uuid]]
- compType['severity'] = max(compType['severity'], sev)
+ compType["severity"] = max(compType["severity"], sev)
result = []
for name, compType in componentTypes.iteritems():
- result.append({
- 'type' : name,
- 'count' : compType['count'],
- 'severity' : EventManagerBase.severities.get(compType['severity'], 0).lower()
- })
+ result.append(
+ {
+ "type": name,
+ "count": compType["count"],
+ "severity": EventManagerBase.severities.get(
+ compType["severity"], 0
+ ).lower(),
+ }
+ )
return result
def getDeviceUids(self, uid):
cat = IModelCatalogTool(self._getObject(uid))
- return [b.getPath() for b in cat.search('Products.ZenModel.Device.Device')]
+ return [
+ b.getPath() for b in cat.search("Products.ZenModel.Device.Device")
+ ]
def deleteComponents(self, uids):
comps = imap(self._getObject, uids)
for comp in comps:
if comp.isLockedFromDeletion():
- raise Exception("Component %s is locked from deletion" % comp.id)
+ raise Exception(
+ "Component %s is locked from deletion" % comp.id
+ )
- if hasattr(comp, 'manage_deleteComponent'):
+ if hasattr(comp, "manage_deleteComponent"):
comp.manage_deleteComponent()
else:
- raise Exception("%s %s cannot be manually deleted" %
- (getattr(comp,'meta_type','component'),comp.id))
-
+ raise Exception(
+ "%s %s cannot be manually deleted"
+ % (getattr(comp, "meta_type", "component"), comp.id)
+ )
def _deleteDevices(self, uids, deleteEvents=False, deletePerf=True):
@transact
@@ -405,26 +523,29 @@ def dbDeleteDevices(uids):
for dev in devs:
devid = dev.getId()
deletedIds.append(devid)
- parent = dev.getPrimaryParent()
- dev.deleteDevice(deleteStatus=deleteEvents,
- deletePerf=deletePerf)
+ dev.deleteDevice(
+ deleteStatus=deleteEvents, deletePerf=deletePerf
+ )
return deletedIds
def uidChunks(uids, chunksize=10):
i = 0
maxi = len(uids)
while i < maxi:
- nexti = i+chunksize
+ nexti = i + chunksize
yield uids[i:nexti]
i = nexti
deletedIds = sum(map(dbDeleteDevices, uidChunks(uids)), [])
for devid in deletedIds:
- self._dmd.ZenEventManager.sendEvent(Event(
- summary='Deleted device: '+devid,
- severity=2, #info
- eventClass='/Change/Remove', #zEventAction=history
- device=devid))
+ self._dmd.ZenEventManager.sendEvent(
+ Event(
+ summary="Deleted device: " + devid,
+ severity=2, # info
+ eventClass="/Change/Remove", # zEventAction=history
+ device=devid,
+ )
+ )
def deleteDevices(self, uids, deleteEvents=False, deletePerf=True):
"""
@@ -441,15 +562,16 @@ def deleteDevices(self, uids, deleteEvents=False, deletePerf=True):
@info
def removeDevices(self, uids, organizer):
# Resolve target if a path
- if isinstance(organizer, basestring):
+ if isinstance(organizer, six.string_types):
organizer = self._getObject(organizer)
- assert isinstance(organizer, DeviceOrganizer)
devs = map(self._getObject, uids)
removed = []
if isinstance(organizer, DeviceGroup):
for dev in devs:
oldGroupNames = dev.getDeviceGroupNames()
- newGroupNames = self._removeOrganizer(organizer, list(oldGroupNames))
+ newGroupNames = self._removeOrganizer(
+ organizer, list(oldGroupNames)
+ )
if oldGroupNames != newGroupNames:
dev.setGroups(newGroupNames)
notify(ObjectRemovedFromOrganizerEvent(dev, organizer))
@@ -458,7 +580,9 @@ def removeDevices(self, uids, organizer):
elif isinstance(organizer, System):
for dev in devs:
oldSystemNames = dev.getSystemNames()
- newSystemNames = self._removeOrganizer(organizer, list(oldSystemNames))
+ newSystemNames = self._removeOrganizer(
+ organizer, list(oldSystemNames)
+ )
if newSystemNames != oldSystemNames:
dev.setSystems(newSystemNames)
notify(ObjectRemovedFromOrganizerEvent(dev, organizer))
@@ -483,30 +607,42 @@ def getUserCommands(self, uid=None):
org = self._getObject(uid)
return org.getUserCommands()
- def setProductInfo(self, uid, hwManufacturer=None, hwProductName=None,
- osManufacturer=None, osProductName=None):
+ def setProductInfo(
+ self,
+ uid,
+ hwManufacturer=None,
+ hwProductName=None,
+ osManufacturer=None,
+ osProductName=None,
+ ):
dev = self._getObject(uid)
- dev.setProductInfo(hwManufacturer=hwManufacturer,
- hwProductName=hwProductName,
- osManufacturer=osManufacturer,
- osProductName=osProductName)
+ dev.setProductInfo(
+ hwManufacturer=hwManufacturer,
+ hwProductName=hwProductName,
+ osManufacturer=osManufacturer,
+ osProductName=osProductName,
+ )
def setProductionState(self, uids, state, asynchronous=False):
if asynchronous:
self._dmd.JobManager.addJob(
FacadeMethodJob,
- description="Set state %s for %s" % (state, ','.join(uids)),
- kwargs=dict(
- facadefqdn="Products.Zuul.facades.devicefacade.DeviceFacade",
- method="_setProductionState",
- uids=uids,
- state=state
- ))
+ description="Set state %s for %s" % (state, ",".join(uids)),
+ kwargs={
+ "facadefqdn": (
+ "Products.Zuul.facades.devicefacade.DeviceFacade"
+ ),
+ "method": "_setProductionState",
+ "uids": uids,
+ "state": state,
+ },
+ )
else:
self._setProductionState(uids, state)
- def setLockState(self, uids, deletion=False, updates=False,
- sendEvent=False):
+ def setLockState(
+ self, uids, deletion=False, updates=False, sendEvent=False
+ ):
devs = imap(self._getObject, uids)
for dev in devs:
if deletion or updates:
@@ -522,15 +658,18 @@ def setMonitor(self, uids, monitor=False):
for comp in comps:
IInfo(comp).monitor = monitor
# update the componentSearch catalog
- comp.index_object(idxs=('monitored',))
+ comp.index_object(idxs=("monitored",))
# update the global catalog as well
- notify(IndexingEvent(comp, idxs=('monitored',)))
+ notify(IndexingEvent(comp, idxs=("monitored",)))
def pushChanges(self, uids):
devs = imap(self._getObject, uids)
+ if not devs:
+ return
+ configcache = ConfigCache.new()
for dev in devs:
- dev.pushConfig()
+ configcache.update_device(dev)
def modelDevices(self, uids):
devs = imap(self._getObject, uids)
@@ -553,9 +692,8 @@ def resumeCollection(self, uid):
def _moveDevices(self, uids, target):
# Resolve target if a path
- if isinstance(target, basestring):
+ if isinstance(target, six.string_types):
target = self._getObject(target)
- assert isinstance(target, DeviceOrganizer)
devs = (self._getObject(uid) for uid in uids)
targetname = target.getOrganizerName()
moved_devices_count = 0
@@ -578,24 +716,28 @@ def _moveDevices(self, uids, target):
elif isinstance(target, Location):
for dev in devs:
if dev.location():
- notify(ObjectRemovedFromOrganizerEvent(dev, dev.location()))
+ notify(
+ ObjectRemovedFromOrganizerEvent(dev, dev.location())
+ )
dev.setLocation(targetname)
notify(ObjectAddedToOrganizerEvent(dev, target))
success = True
elif isinstance(target, DeviceClass):
- moved_devices_count = self._dmd.Devices.moveDevices(targetname,[dev.id for dev in devs])
+ moved_devices_count = self._dmd.Devices.moveDevices(
+ targetname, [dev.id for dev in devs]
+ )
success = True
remodel_required = True
result = {
- 'success': success,
- 'message': 'The %s devices have been moved' % moved_devices_count,
- 'remodel_required': remodel_required
+ "success": success,
+ "message": "The %s devices have been moved" % moved_devices_count,
+ "remodel_required": remodel_required,
}
return result
def _setProductionState(self, uids, state):
- if isinstance(uids, basestring):
+ if isinstance(uids, six.string_types):
uids = (uids,)
for uid in uids:
dev = self._getObject(uid)
@@ -604,9 +746,8 @@ def _setProductionState(self, uids, state):
def doesMoveRequireRemodel(self, uid, target):
# Resolve target if a path
- if isinstance(target, basestring):
+ if isinstance(target, six.string_types):
target = self._getObject(target)
- assert isinstance(target, DeviceClass)
targetClass = target.getPythonDeviceClass()
dev = self._getObject(uid)
return dev and dev.__class__ != targetClass
@@ -614,20 +755,29 @@ def doesMoveRequireRemodel(self, uid, target):
@info
def moveDevices(self, uids, target, asynchronous=True):
if asynchronous:
- devdesc = ("device %s" % uids[0].split('/')[-1] if len(uids)==1
- else "%s devices" % len(uids))
+ devdesc = (
+ "device %s" % uids[0].split("/")[-1]
+ if len(uids) == 1
+ else "%s devices" % len(uids)
+ )
return self._dmd.JobManager.addJob(
- FacadeMethodJob, description="Move %s to %s" % (devdesc, target),
- kwargs=dict(
- facadefqdn="Products.Zuul.facades.devicefacade.DeviceFacade",
- method="_moveDevices",
- uids=uids,
- target=target
- ))
+ FacadeMethodJob,
+ description="Move %s to %s" % (devdesc, target),
+ kwargs={
+ "facadefqdn": (
+ "Products.Zuul.facades.devicefacade.DeviceFacade"
+ ),
+ "method": "_moveDevices",
+ "uids": uids,
+ "target": target,
+ },
+ )
else:
return self._moveDevices(uids, target)
- def getDeviceByIpAddress(self, deviceName, collector="localhost", ipAddress=""):
+ def getDeviceByIpAddress(
+ self, deviceName, collector="localhost", ipAddress=""
+ ):
# convert device name to an ip address
if not ipAddress:
if isip(deviceName):
@@ -641,8 +791,10 @@ def getDeviceByIpAddress(self, deviceName, collector="localhost", ipAddress=""):
# find a device with the same ip on the same collector
cat = IModelCatalogTool(self.context.Devices)
- query = And(Eq('text_ipAddress', ipAddress),
- Eq('objectImplements', 'Products.ZenModel.Device.Device'))
+ query = And(
+ Eq("text_ipAddress", ipAddress),
+ Eq("objectImplements", "Products.ZenModel.Device.Device"),
+ )
search_results = cat.search(query=query)
for brain in search_results.results:
@@ -656,82 +808,123 @@ def getDeviceByName(self, deviceName):
def setCollector(self, uids, collector, moveData=False, asynchronous=True):
# Keep 'moveData' in signature even though it's unused now
if asynchronous:
- prettyUids = ", ".join([uid.split('/')[-1] for uid in uids])
+ prettyUids = ", ".join([uid.split("/")[-1] for uid in uids])
return self._dmd.JobManager.addJob(
- FacadeMethodJob, description="Move devices %s to collector %s" % (prettyUids, collector),
- kwargs=dict(
- facadefqdn="Products.Zuul.facades.devicefacade.DeviceFacade",
- method="_setCollector",
- uids=uids,
- collector=collector
- ))
+ FacadeMethodJob,
+ description="Move devices %s to collector %s"
+ % (prettyUids, collector),
+ kwargs={
+ "facadefqdn": (
+ "Products.Zuul.facades.devicefacade.DeviceFacade"
+ ),
+ "method": "_setCollector",
+ "uids": uids,
+ "collector": collector,
+ },
+ )
else:
return self._setCollector(uids, collector)
- def _setCollector(self, uids, collector, moveData=False, asynchronous=True):
+ def _setCollector(
+ self, uids, collector, moveData=False, asynchronous=True
+ ):
movedDevices = []
for uid in uids:
info = self.getInfo(uid)
- movedDevices.append({
- 'id': uid.split("/")[-1],
- 'fromCollector': info.collector,
- })
+ movedDevices.append(
+ {
+ "id": uid.split("/")[-1],
+ "fromCollector": info.collector,
+ }
+ )
info.collector = collector
- # If an event is desired at this point, use a DeviceCollectorChangeEvent here
+ # If an event is desired at this point,
+ # use a DeviceCollectorChangeEvent here
@info
- def addDevice(self, deviceName, deviceClass, title=None, snmpCommunity="",
- snmpPort=161, manageIp="", model=False, collector='localhost',
- rackSlot=0, productionState=1000, comments="",
- hwManufacturer="", hwProductName="", osManufacturer="",
- osProductName="", priority = 3, tag="", serialNumber="",
- locationPath="", zCommandUsername="", zCommandPassword="",
- zWinUser="", zWinPassword="", systemPaths=[], groupPaths=[],
- zProperties={}, cProperties={},
- ):
- zProps = dict(zSnmpCommunity=snmpCommunity,
- zSnmpPort=snmpPort,
- zCommandUsername=zCommandUsername,
- zCommandPassword=zCommandPassword,
- zWinUser=zWinUser,
- zWinPassword=zWinPassword
- )
+ def addDevice(
+ self,
+ deviceName,
+ deviceClass,
+ title=None,
+ snmpCommunity="",
+ snmpPort=161,
+ manageIp="",
+ model=False,
+ collector="localhost",
+ rackSlot=0,
+ productionState=1000,
+ comments="",
+ hwManufacturer="",
+ hwProductName="",
+ osManufacturer="",
+ osProductName="",
+ priority=3,
+ tag="",
+ serialNumber="",
+ locationPath="",
+ zCommandUsername="",
+ zCommandPassword="",
+ zWinUser="",
+ zWinPassword="",
+ systemPaths=None,
+ groupPaths=None,
+ zProperties=None,
+ cProperties=None,
+ ):
+ systemPaths = systemPaths if systemPaths else []
+ groupPaths = groupPaths if groupPaths else []
+ zProperties = zProperties if zProperties else {}
+ cProperties = cProperties if cProperties else {}
+ zProps = {
+ "zSnmpCommunity": snmpCommunity,
+ "zSnmpPort": snmpPort,
+ "zCommandUsername": zCommandUsername,
+ "zCommandPassword": zCommandPassword,
+ "zWinUser": zWinUser,
+ "zWinPassword": zWinPassword,
+ }
zProps.update(zProperties)
model = model and "Auto" or "none"
perfConf = self._dmd.Monitors.getPerformanceMonitor(collector)
if perfConf.viewName() != collector:
raise Exception("Collector `{}` does not exist".format(collector))
- jobrecords = perfConf.addCreateDeviceJob(deviceName=deviceName,
- devicePath=deviceClass,
- performanceMonitor=collector,
- discoverProto=model,
- manageIp=manageIp,
- zProperties=zProps,
- cProperties=cProperties,
- rackSlot=rackSlot,
- productionState=productionState,
- comments=comments,
- hwManufacturer=hwManufacturer,
- hwProductName=hwProductName,
- osManufacturer=osManufacturer,
- osProductName=osProductName,
- priority=priority,
- tag=tag,
- serialNumber=serialNumber,
- locationPath=locationPath,
- systemPaths=systemPaths,
- groupPaths=groupPaths,
- title=title)
+ jobrecords = perfConf.addCreateDeviceJob(
+ deviceName=deviceName,
+ devicePath=deviceClass,
+ performanceMonitor=collector,
+ discoverProto=model,
+ manageIp=manageIp,
+ zProperties=zProps,
+ cProperties=cProperties,
+ rackSlot=rackSlot,
+ productionState=productionState,
+ comments=comments,
+ hwManufacturer=hwManufacturer,
+ hwProductName=hwProductName,
+ osManufacturer=osManufacturer,
+ osProductName=osProductName,
+ priority=priority,
+ tag=tag,
+ serialNumber=serialNumber,
+ locationPath=locationPath,
+ systemPaths=systemPaths,
+ groupPaths=groupPaths,
+ title=title,
+ )
return jobrecords
- def remodel(self, deviceUid, collectPlugins='', background=True):
- #fake_request will break not a background command
- fake_request = {'CONTENT_TYPE': 'xml'} if background else None
+ def remodel(self, deviceUid, collectPlugins="", background=True):
+ # fake_request will break not a background command
+ fake_request = {"CONTENT_TYPE": "xml"} if background else None
device = self._getObject(deviceUid)
return device.getPerformanceServer().collectDevice(
- device, background=background, collectPlugins=collectPlugins,
- REQUEST=fake_request)
+ device,
+ background=background,
+ collectPlugins=collectPlugins,
+ REQUEST=fake_request,
+ )
def addLocalTemplate(self, deviceUid, templateId):
"""
@@ -745,8 +938,10 @@ def addLocalTemplate(self, deviceUid, templateId):
def removeLocalTemplate(self, deviceUid, templateUid):
"""
Removes a local definition of a template on a device
- @param string deviceUid: Absolute path to the device that has the template
- @param string templateUid: Absolute path to the template we wish to remove
+ @param deviceUid: Absolute path to the device that has the template
+ @type deviceUid: str
+ @param templateUid: Absolute path to the template we wish to remove
+ @type templateUid: str
"""
device = self._getObject(deviceUid)
template = self._getObject(templateUid)
@@ -754,39 +949,101 @@ def removeLocalTemplate(self, deviceUid, templateUid):
def getTemplates(self, id):
object = self._getObject(id)
-
- if isinstance(object, Device):
- rrdTemplates = object.getAvailableTemplates()
- else:
- rrdTemplates = object.getRRDTemplates()
- # used to sort the templates
- def byTitleOrId(left, right):
- return cmp(left.titleOrId().lower(), right.titleOrId().lower())
+ isDeviceClass = isinstance(object, DeviceClass)
+ if isDeviceClass:
+ pythonDeviceClass = object.getPythonDeviceClass()
+
+ zDeviceTemplates = object.zDeviceTemplates
+
+ rrdTemplates = object.getRRDTemplates()
- for rrdTemplate in sorted(rrdTemplates, byTitleOrId):
- uid = '/'.join(rrdTemplate.getPrimaryPath())
- # only show Bound Templates
+ templateNames = []
+ boundTemplates = []
+ unboundTemplates = []
+ for rrdTemplate in rrdTemplates:
+ if isDeviceClass and not issubclass(
+ pythonDeviceClass, rrdTemplate.getTargetPythonClass()
+ ):
+ continue
+ templateNames.append(rrdTemplate.id)
if rrdTemplate.id in object.zDeviceTemplates:
- path = rrdTemplate.getUIPath()
-
- # if defined directly on the device do not show the path
- if isinstance(object, Device) and object.titleOrId() in path:
- path = _t('Locally Defined')
- yield {'id': uid,
- 'uid': uid,
- 'path': path,
- 'text': '%s (%s)' % (rrdTemplate.titleOrId(), path),
- 'leaf': True
- }
+ boundTemplates.append(rrdTemplate)
+ else:
+ unboundTemplates.append(rrdTemplate)
+
+ # used to sort the templates
+ def byTitleOrId(obj):
+ return obj.titleOrId().lower()
+
+ for rrdTemplate in list(unboundTemplates):
+ if rrdTemplate.id.endswith(
+ "-replacement"
+ ) or rrdTemplate.id.endswith("-addition"):
+ if (
+ "-".join(rrdTemplate.id.split("-")[:-1])
+ in zDeviceTemplates
+ ):
+ boundTemplates.append(rrdTemplate)
+ unboundTemplates.remove(rrdTemplate)
+
+ def makenode(rrdTemplate, suborg=None):
+ uid = "/".join(rrdTemplate.getPrimaryPath())
+ path = ""
+
+ # for DeviceClasses show which are bound
+ if isinstance(object, DeviceClass):
+ if rrdTemplate.id in zDeviceTemplates:
+ path = "%s (%s)" % (path, _t("Bound"))
+ if rrdTemplate.id + "-replacement" in templateNames:
+ path = "%s (%s)" % (path, _t("Replaced"))
+
+ # if defined directly on the device do not show the path
+ uiPath = rrdTemplate.getUIPath()
+ if (not isDeviceClass) and object.titleOrId() in uiPath:
+ path = "%s (%s)" % (path, _t("Locally Defined"))
+ else:
+ path = "%s (%s)" % (path, uiPath)
+ return {
+ "id": uid,
+ "uid": uid,
+ "path": path,
+ "text": "%s %s" % (rrdTemplate.titleOrId(), path),
+ "leaf": True,
+ }
+
+ for rrdTemplate in sorted(boundTemplates, key=byTitleOrId):
+ yield makenode(rrdTemplate)
+
+ if isDeviceClass:
+ available = []
+ for rrdTemplate in sorted(unboundTemplates, key=byTitleOrId):
+ available.append(makenode(rrdTemplate, "Available"))
+ yield {
+ "id": "Available",
+ "text": "Available",
+ "leaf": False,
+ "children": available,
+ }
def getLocalTemplates(self, uid):
"""
- Returns a dictionary of every template defined on the device specified by the uid
+ Returns a dictionary of every template defined on the device
+ specified by the uid.
+
@param string uid: absolute path of a device
@returns [Dict] All the templates defined on this device
"""
- return [template for template in self.getTemplates(uid) if template['path'] == _t('Locally Defined')]
+ for template in self._getObject(uid).objectValues("RRDTemplate"):
+ uid = "/".join(template.getPrimaryPath())
+ path = template.getUIPath()
+ yield {
+ "id": uid,
+ "uid": uid,
+ "path": path,
+ "text": "%s (%s)" % (template.titleOrId(), path),
+ "leaf": True,
+ }
def getUnboundTemplates(self, uid):
return self._getBoundTemplates(uid, False)
@@ -819,8 +1076,14 @@ def setBoundTemplates(self, uid, templateIds):
if intersection:
dp_name = intersection.pop()
other_id = bound_dp_names[dp_name]
- fmt = "both {template.id} and {other_id} have a datapoint named {dp_name}"
- raise DatapointNameConfict(fmt.format(template=template, other_id=other_id, dp_name=dp_name))
+ raise DatapointNameConfict(
+ "both {template.id} and {other_id} have a "
+ "datapoint named {dp_name}".format(
+ template=template,
+ other_id=other_id,
+ dp_name=dp_name,
+ )
+ )
for dp_name in dp_names:
bound_dp_names[dp_name] = template.id
@@ -829,13 +1092,14 @@ def setBoundTemplates(self, uid, templateIds):
def resetBoundTemplates(self, uid):
obj = self._getObject(uid)
# make sure we have bound templates before we remove them
- if obj.hasProperty('zDeviceTemplates'):
+ if obj.hasProperty("zDeviceTemplates"):
obj.removeZDeviceTemplates()
def getOverridableTemplates(self, uid):
"""
- A template is overrideable at the device if it is bound to the device and
- we have not already overridden it.
+ A template is overrideable at the device if it is bound to the
+ device and we have not already overridden it.
+
@param string uid: the unique id of a device
@returns a list of all available templates for the given uid
"""
@@ -843,19 +1107,25 @@ def getOverridableTemplates(self, uid):
templates = obj.getRRDTemplates()
for template in templates:
# see if the template is already overridden here
- if not obj.id in template.getPhysicalPath():
+ if obj.id not in template.getPhysicalPath():
try:
yield ITemplateNode(template)
except UncataloguedObjectException:
pass
- def addLocationOrganizer(self, contextUid, id, description = '', address=''):
- org = super(DeviceFacade, self).addOrganizer(contextUid, id, description)
+ def addLocationOrganizer(self, contextUid, id, description="", address=""):
+ org = super(DeviceFacade, self).addOrganizer(
+ contextUid, id, description
+ )
org.address = address
return org
- def addDeviceClass(self, contextUid, id, description = '', connectionInfo=None):
- org = super(DeviceFacade, self).addOrganizer(contextUid, id, description)
+ def addDeviceClass(
+ self, contextUid, id, description="", connectionInfo=None
+ ):
+ org = super(DeviceFacade, self).addOrganizer(
+ contextUid, id, description
+ )
if connectionInfo:
org.connectionInfo = connectionInfo
return org
@@ -872,16 +1142,22 @@ def getModelerPluginDocStrings(self, uid):
coreImporter = CoreImporter()
for plugin in plugins:
try:
- module = coreImporter.importModule(plugin.package, plugin.modPath)
+ module = coreImporter.importModule(
+ plugin.package, plugin.modPath
+ )
except ImportError:
try:
- module = packImporter.importModule(plugin.package, plugin.modPath)
+ module = packImporter.importModule(
+ plugin.package, plugin.modPath
+ )
except ImportError:
# unable to import skip over this one
continue
pluginDocs = module.__doc__
if pluginDocs:
- pluginDocs = '' + pluginDocs.replace('\n', '\n