1
2
3
4
5
6
7
8
9
10
11 __doc__="""GraphPoint
12
13 Defines attributes for how a data source will be graphed
14 and builds the nessesary rrd commands.
15 """
16
17 from Globals import InitializeClass
18 from AccessControl import ClassSecurityInfo, Permissions
19 from Products.ZenModel.ZenossSecurity import *
20 from Products.ZenRelations.RelSchema import *
21 from ZenModelRM import ZenModelRM
22 from ZenPackable import ZenPackable
23 from Products.ZenWidgets import messaging
24 from Products.ZenUtils.deprecated import deprecated
35
38 '''
39 '''
40
41 isThreshold = False
42
43 DEFAULT_FORMAT = '%5.2lf%s'
44 DEFAULT_LEGEND = '${graphPoint/id}'
45 DEFAULT_MULTIGRAPH_LEGEND = '${here/name | here/id} ${graphPoint/id}'
46
47 sequence = 0
48 _properties = (
49 {'id':'sequence', 'type':'long', 'mode':'w'},
50 )
51
52 _relations = ZenPackable._relations + (
53 ("graphDef", ToOne(ToManyCont,"Products.ZenModel.GraphDefinition","graphPoints")),
54 )
55
56 factory_type_information = (
57 {
58 'immediate_view' : 'editGraphPoint',
59 'actions' :
60 (
61 { 'id' : 'edit'
62 , 'name' : 'Graph Point'
63 , 'action' : 'editGraphPoint'
64 , 'permissions' : ( Permissions.view, )
65 },
66 )
67 },
68 )
69
70 colors = (
71 '#00cc00', '#0000ff', '#00ffff', '#ff0000',
72 '#ff9900', '#cc0000', '#0000cc', '#0080c0',
73 '#8080c0', '#ff0080', '#800080', '#0000a0',
74 '#408080', '#808000', '#000000', '#00ff00',
75 '#fb31fb', '#0080ff', '#ff8000', '#800000',
76 )
77
78 security = ClassSecurityInfo()
79
80
81
82
92
93
94 security.declareProtected(ZEN_MANAGE_DMD, 'manage_editProperties')
96 '''
97 Process a save request from a GraphPoint edit screen. Perform
98 validation on fields and either return error message or save
99 results.
100 '''
101 def IsHex(s):
102 try:
103 _ = long(color, 16)
104 except ValueError:
105 return False
106 return True
107
108 color = REQUEST.get('color', '').strip().lstrip('#').upper()
109 if color:
110 if len(color) in (6, 8) and IsHex(color):
111 REQUEST.form['color'] = color
112 else:
113 messaging.IMessageSender(self).sendToBrowser(
114 'Invalid Color',
115 'Color must be a 6 or 8-digit hexadecimal value.',
116 priority=messaging.WARNING
117 )
118 return self.callZenScreen(REQUEST)
119 return self.zmanage_editProperties(REQUEST)
120
121
123 ''' Return a description
124 '''
125 return self.id
126
127
128 - def getTalesContext(self, thing=None, **kw):
129 '''
130 Standard stuff to add to context for tales expressions
131 '''
132 context = {
133 'graphDef': self.graphDef(),
134 'graphPoint': self,
135 }
136 if thing:
137 thing.getRRDContextData(context)
138 for key, value in kw.items():
139 context[key] = value
140 return context
141
142
154
155
156
157
159 """
160 Return a string apprpriate for use as the color part of an
161 rrd graph command. The color either comes from the attribute on
162 this object or from an offset into the self.colors list.
163 """
164 color = None
165 if self.color:
166 color = self.color
167 try:
168 _ = long(color, 16)
169 except ValueError:
170 color = None
171 if not color:
172 index %= len(self.colors)
173 color = self.colors[index]
174 color = '#%s' % color.lstrip('#')
175 if hasattr(self, 'stacked'):
176
177
178 if not self.stacked and index>0: color += "99"
179 else: color += "ff"
180 return color
181
182
188
189
190 - def getGraphCmds(self, cmds, context, rrdDir, addSummary, idx,
191 multiid=-1, prefix=''):
192 ''' Build the graphing commands for this graphpoint
193 '''
194 from Products.ZenUtils.Utils import unused
195 unused(multiid, prefix, rrdDir)
196 return cmds
197
198
199 - def getDsName(self, base, multiid=-1, prefix=''):
204
205
207 ''' If not base then return ''
208 elif prefix then return prefix_base
209 else return base
210 The result is rrd scrubbed
211 '''
212 s = base or ''
213 if s and prefix:
214 s = '_'.join((prefix, base))
215 s = self.scrubForRRD(s)
216 return s
217
218
220 ''' scrub value so it is a valid rrd variable name. If namespace
221 is provided then massage value as needed to avoid name conflicts
222 with items in namespace.
223 '''
224 import string
225 import itertools
226 validRRDchars=set(string.ascii_letters + string.digits + '_-')
227 value = ''.join(c if c in validRRDchars else '_' for c in value)
228 if namespace:
229 postfixIter = itertools.count(2)
230 candidate = value
231 while candidate in namespace:
232 candidate = value + str(postfixIter.next())
233 value = candidate
234 return value
235
236
238 '''
239 Escapes characters like colon ':' for use by RRDTool which would
240 '''
241 value = value.replace(":", "\:")[:198]
242 return value
243
244
245 InitializeClass(GraphPoint)
246