| 1 | # Copyright (C) 2006 The University of Waikato |
|---|
| 2 | # |
|---|
| 3 | # This file is part of crcnetd - CRCnet Configuration System Daemon |
|---|
| 4 | # |
|---|
| 5 | # This file deals with graphs |
|---|
| 6 | # |
|---|
| 7 | # Author: Chris Browning <ckb6@cs.waikato.ac.nz> |
|---|
| 8 | # Version: $Id$ |
|---|
| 9 | # |
|---|
| 10 | # crcnetd is free software; you can redistribute it and/or modify it under the |
|---|
| 11 | # terms of the GNU General Public License version 2 as published by the Free |
|---|
| 12 | # Software Foundation. |
|---|
| 13 | # |
|---|
| 14 | # crcnetd is distributed in the hope that it will be useful, but WITHOUT ANY |
|---|
| 15 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 16 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|---|
| 17 | # details. |
|---|
| 18 | # |
|---|
| 19 | # You should have received a copy of the GNU General Public License along with |
|---|
| 20 | # crcnetd; if not, write to the Free Software Foundation, Inc., |
|---|
| 21 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 22 | from crcnetd._utils.ccsd_common import * |
|---|
| 23 | from crcnetd._utils.ccsd_log import * |
|---|
| 24 | from crcnetd._utils.ccsd_events import * |
|---|
| 25 | from crcnetd._utils.ccsd_session import getSession, getSessionE |
|---|
| 26 | from crcnetd._utils.ccsd_server import exportViaXMLRPC |
|---|
| 27 | from crcnetd._utils.ccsd_service import getServiceInstance |
|---|
| 28 | ccs_mod_type = CCSD_SERVER |
|---|
| 29 | GRAPH_SERVER = "localhost:80" |
|---|
| 30 | |
|---|
| 31 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 32 | def getGraph(session_id, graph_id, time_id): |
|---|
| 33 | '''This returns everything the graph server needs to draw a graph''' |
|---|
| 34 | |
|---|
| 35 | session = getSessionE(session_id) |
|---|
| 36 | |
|---|
| 37 | #Get the graph type |
|---|
| 38 | sql = "SELECT a.*, b.class_name AS filename2 FROM graph_type a, rrdbot_class b WHERE b.class_id=a.class_id AND graph_id=%s" |
|---|
| 39 | #sql = "SELECT * FROM graph_type where graph_id=%s" |
|---|
| 40 | res = session.query(sql, (graph_id)) |
|---|
| 41 | |
|---|
| 42 | #Get the parts for the graph |
|---|
| 43 | sql = "SELECT * FROM graph_parts where graph_id=%s ORDER BY graph_order" |
|---|
| 44 | res2 = session.query(sql, (graph_id)) |
|---|
| 45 | |
|---|
| 46 | #Get the time class |
|---|
| 47 | sql = "SELECT * FROM graph_time where time_id=%s" |
|---|
| 48 | res3 = session.query(sql, (time_id)) |
|---|
| 49 | |
|---|
| 50 | return [res, res2, res3] |
|---|
| 51 | |
|---|
| 52 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 53 | def getSnmpLogs(session_id): |
|---|
| 54 | '''This returns a list of entries in the rrdbotlog view''' |
|---|
| 55 | |
|---|
| 56 | session = getSessionE(session_id) |
|---|
| 57 | |
|---|
| 58 | sql = "SELECT * FROM rrdbotlog" |
|---|
| 59 | res = session.query(sql, ()) |
|---|
| 60 | res.sort(key=lambda obj:obj["timestamp"]); |
|---|
| 61 | return res |
|---|
| 62 | |
|---|
| 63 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 64 | def snmpDelete(session_id, host_id, class_id, num): |
|---|
| 65 | '''This deletes a row in the snmp_discovery table''' |
|---|
| 66 | |
|---|
| 67 | session = getSessionE(session_id) |
|---|
| 68 | |
|---|
| 69 | sql = "DELETE FROM snmp_discovery WHERE host_id=%s AND class_id=%s AND num=%s" |
|---|
| 70 | session.execute(sql, (host_id,class_id, num)) |
|---|
| 71 | return 1 |
|---|
| 72 | |
|---|
| 73 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 74 | def snmpDeleteHost(session_id, host_id): |
|---|
| 75 | '''This removes a host from the snmp_discovery table''' |
|---|
| 76 | session = getSessionE(session_id) |
|---|
| 77 | |
|---|
| 78 | sql = "DELETE FROM snmp_discovery WHERE host_id=%s" |
|---|
| 79 | session.execute(sql, (host_id)) |
|---|
| 80 | return 1 |
|---|
| 81 | |
|---|
| 82 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 83 | def snmpFlush(session_id): |
|---|
| 84 | '''This flushes the entire snmp_discovery table''' |
|---|
| 85 | session = getSessionE(session_id) |
|---|
| 86 | |
|---|
| 87 | sql = "DELETE FROM snmp_discovery" |
|---|
| 88 | session.execute(sql, ()) |
|---|
| 89 | return 1 |
|---|
| 90 | |
|---|
| 91 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 92 | def getHostGraphs(session_id, host_id): |
|---|
| 93 | '''This returns a list of graphs that are available to a host''' |
|---|
| 94 | |
|---|
| 95 | session = getSessionE(session_id) |
|---|
| 96 | |
|---|
| 97 | #-1 means all types of graphs |
|---|
| 98 | if int(host_id) == -1: |
|---|
| 99 | sql = "SELECT * FROM graph_group" |
|---|
| 100 | res = session.query(sql, ()) |
|---|
| 101 | res.sort(key=lambda obj:obj["group_name"].lower()); |
|---|
| 102 | return res |
|---|
| 103 | |
|---|
| 104 | sql = "SELECT DISTINCT b.group_id, b.group_name, a.host_id, a.host_name FROM graphview a LEFT JOIN graph_group b ON b.group_id=a.group_id WHERE host_id=%s" |
|---|
| 105 | res = session.query(sql, (host_id)) |
|---|
| 106 | res.sort(key=lambda obj:obj["group_name"].lower()); |
|---|
| 107 | return res |
|---|
| 108 | |
|---|
| 109 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 110 | def getLinkGraphs(session_id, link_id=-1, graph_id=-1): |
|---|
| 111 | '''This returns graph data for a link''' |
|---|
| 112 | session = getSessionE(session_id) |
|---|
| 113 | link_id = int(link_id) |
|---|
| 114 | graph_id = int(graph_id) |
|---|
| 115 | |
|---|
| 116 | if graph_id == link_id == -1: |
|---|
| 117 | #This case is for a menu so return limited data |
|---|
| 118 | sql = "SELECT DISTINCT link_id, description FROM graphview WHERE link_id!=0" |
|---|
| 119 | res = session.query(sql, ()) |
|---|
| 120 | elif graph_id == -1: |
|---|
| 121 | sql = "SELECT * FROM graphview WHERE link_id=%s" |
|---|
| 122 | res = session.query(sql, (link_id)) |
|---|
| 123 | elif link_id == -1: |
|---|
| 124 | sql = "SELECT * FROM graphview WHERE graph_id=%s AND link_id!=0" |
|---|
| 125 | res = session.query(sql, (graph_id)) |
|---|
| 126 | else: |
|---|
| 127 | sql = "SELECT * FROM graphview WHERE link_id=%s AND graph_id=%s" |
|---|
| 128 | res = session.query(sql, (link_id,graph_id)) |
|---|
| 129 | res.sort(key=lambda obj:obj["description"].lower()) |
|---|
| 130 | |
|---|
| 131 | return res |
|---|
| 132 | |
|---|
| 133 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 134 | def getGraphs(session_id, host_id=-1, group_id=-1, mirror='f'): |
|---|
| 135 | global GRAPH_SERVER |
|---|
| 136 | '''This returns data to draw graphs''' |
|---|
| 137 | |
|---|
| 138 | '''It also handles mirror in which both sides of a link are returned''' |
|---|
| 139 | |
|---|
| 140 | host_id = int(host_id) |
|---|
| 141 | group_id = int(group_id) |
|---|
| 142 | session = getSessionE(session_id) |
|---|
| 143 | |
|---|
| 144 | #Select table based on mirror |
|---|
| 145 | if mirror == 't': |
|---|
| 146 | table = "mirrorview" |
|---|
| 147 | else: |
|---|
| 148 | table = "graphview" |
|---|
| 149 | |
|---|
| 150 | if group_id == host_id == -1: |
|---|
| 151 | sql = "SELECT * FROM %s" % table |
|---|
| 152 | res = session.query(sql, ()) |
|---|
| 153 | elif group_id == -1: |
|---|
| 154 | sql = "SELECT * FROM %s WHERE host_id=%%s" % table |
|---|
| 155 | res = session.query(sql, (host_id)) |
|---|
| 156 | elif host_id == -1: |
|---|
| 157 | sql = "SELECT * FROM %s WHERE group_id=%%s" % table |
|---|
| 158 | res = session.query(sql, (group_id)) |
|---|
| 159 | else: |
|---|
| 160 | sql = "SELECT * FROM %s WHERE host_id=%%s AND group_id=%%s" % table |
|---|
| 161 | res = session.query(sql, (host_id,group_id)) |
|---|
| 162 | |
|---|
| 163 | #Prune of pythons double up of data but keep all data |
|---|
| 164 | #This loop saves time in php as it has to decode less |
|---|
| 165 | graphs2 = [] |
|---|
| 166 | for graph in res: |
|---|
| 167 | newgraph = {} |
|---|
| 168 | newgraph ["host_id"] = graph["host_id"] |
|---|
| 169 | newgraph ["host_name"] = graph["host_name"] |
|---|
| 170 | newgraph ["graph_id"] = graph["graph_id"] |
|---|
| 171 | newgraph ["group_id"] = graph["group_id"] |
|---|
| 172 | newgraph ["title"] = graph["title"] |
|---|
| 173 | newgraph ["num"] = graph["num"] |
|---|
| 174 | newgraph ["description"] = graph["description"] |
|---|
| 175 | newgraph ["ip_address"] = graph["ip_address"] |
|---|
| 176 | |
|---|
| 177 | if "num2" in graph.keys(): |
|---|
| 178 | newgraph ["host_id2"] = graph["host_id2"] |
|---|
| 179 | newgraph ["host_name2"] = graph["host_name2"] |
|---|
| 180 | newgraph ["num2"] = graph["num2"] |
|---|
| 181 | newgraph ["ip_address2"] = graph["ip_address2"] |
|---|
| 182 | |
|---|
| 183 | graphs2.append(newgraph) |
|---|
| 184 | |
|---|
| 185 | return GRAPH_SERVER, graphs2 |
|---|
| 186 | |
|---|
| 187 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 188 | def getTimes(session_id): |
|---|
| 189 | '''Simple function to return all time classes''' |
|---|
| 190 | |
|---|
| 191 | session = getSessionE(session_id) |
|---|
| 192 | sql = "SELECT * from graph_time" |
|---|
| 193 | res = session.query(sql, ()) |
|---|
| 194 | res.sort() |
|---|
| 195 | return res |
|---|
| 196 | |
|---|
| 197 | |
|---|
| 198 | def getHostList(session_id): |
|---|
| 199 | ''' A custom getHostList that only returns hosts that there are graohs for''' |
|---|
| 200 | session = getSessionE(session_id) |
|---|
| 201 | sql = "SELECT DISTINCT host_id, host_name from graphview" |
|---|
| 202 | res = session.query(sql, ()) |
|---|
| 203 | res.sort(key=lambda obj:obj["host_name"].lower()) |
|---|
| 204 | return res |
|---|
| 205 | |
|---|
| 206 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 207 | def getEveryThing(session_id, host_id): |
|---|
| 208 | '''This function returns everything needed for the graph interface''' |
|---|
| 209 | |
|---|
| 210 | '''Its purpose is to reduce the number of xmlrpc calls required''' |
|---|
| 211 | |
|---|
| 212 | '''It also removes double up infomation for speed in php''' |
|---|
| 213 | x1 = time.time() |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | hostList = getHostList(session_id) |
|---|
| 217 | hostList2 = [] |
|---|
| 218 | for host in hostList: |
|---|
| 219 | newhost = {} |
|---|
| 220 | newhost["host_name"] = host["host_name"] |
|---|
| 221 | newhost["host_id"] = host["host_id"] |
|---|
| 222 | hostList2.append(newhost) |
|---|
| 223 | if host_id == '' and len(hostList2) > 0: |
|---|
| 224 | host_id = hostList2[0]["host_id"] |
|---|
| 225 | elif host_id == '': |
|---|
| 226 | host_id = 0 |
|---|
| 227 | |
|---|
| 228 | linkGraphs = getLinkGraphs(session_id) |
|---|
| 229 | linkGraphs2 = [] |
|---|
| 230 | for link in linkGraphs: |
|---|
| 231 | newlink = {} |
|---|
| 232 | newlink["link_id"] = link["link_id"] |
|---|
| 233 | newlink["description"] = link["description"] |
|---|
| 234 | linkGraphs2.append(newlink) |
|---|
| 235 | hostGraphs = getHostGraphs(session_id, host_id) |
|---|
| 236 | hostGraphs2 = [] |
|---|
| 237 | for graph in hostGraphs: |
|---|
| 238 | newgraph = {} |
|---|
| 239 | newgraph ["group_id"] = graph["group_id"] |
|---|
| 240 | newgraph ["group_name"] = graph["group_name"] |
|---|
| 241 | hostGraphs2.append(newgraph) |
|---|
| 242 | server, graphs = getGraphs(session_id) |
|---|
| 243 | times = getTimes(session_id) |
|---|
| 244 | pack = [hostList2, linkGraphs2, hostGraphs2, graphs, times] |
|---|
| 245 | return pack |
|---|
| 246 | |
|---|
| 247 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 248 | def getGraphGroups(session_id): |
|---|
| 249 | '''Simple function to return all graph groups''' |
|---|
| 250 | |
|---|
| 251 | session = getSessionE(session_id) |
|---|
| 252 | sql = "SELECT * from graph_group" |
|---|
| 253 | res = session.query(sql, ()) |
|---|
| 254 | return res |
|---|
| 255 | |
|---|
| 256 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 257 | def getGraphTypes(session_id, group_id): |
|---|
| 258 | '''Simple function to return all graph types in a group''' |
|---|
| 259 | |
|---|
| 260 | session = getSessionE(session_id) |
|---|
| 261 | sql = "SELECT * from graph_type WHERE group_id=%s" |
|---|
| 262 | res = session.query(sql, (group_id)) |
|---|
| 263 | return res |
|---|
| 264 | |
|---|
| 265 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 266 | def getGraphParts(session_id, graph_id): |
|---|
| 267 | '''Simple function to return all graph parts of a graph''' |
|---|
| 268 | |
|---|
| 269 | session = getSessionE(session_id) |
|---|
| 270 | sql = "SELECT * from graph_parts WHERE graph_id=%s ORDER BY graph_order" |
|---|
| 271 | res = session.query(sql, (graph_id)) |
|---|
| 272 | return res |
|---|
| 273 | |
|---|
| 274 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 275 | def getGraphPart(session_id, part_id): |
|---|
| 276 | '''Simple function to return a graph part''' |
|---|
| 277 | |
|---|
| 278 | session = getSessionE(session_id) |
|---|
| 279 | sql = "SELECT * from graph_parts WHERE part_id=%s" |
|---|
| 280 | res = session.query(sql, (part_id)) |
|---|
| 281 | return res[0] |
|---|
| 282 | |
|---|
| 283 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 284 | def getGraphGroup(session_id, group_id): |
|---|
| 285 | '''Simple function to return a group''' |
|---|
| 286 | |
|---|
| 287 | session = getSessionE(session_id) |
|---|
| 288 | sql = "SELECT * from graph_group WHERE group_id=%s" |
|---|
| 289 | res = session.query(sql, (group_id)) |
|---|
| 290 | return res[0] |
|---|
| 291 | |
|---|
| 292 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 293 | def getGraphType(session_id, graph_id): |
|---|
| 294 | '''Simple function to return a graph type''' |
|---|
| 295 | |
|---|
| 296 | session = getSessionE(session_id) |
|---|
| 297 | sql = "SELECT * from graph_type WHERE graph_id=%s" |
|---|
| 298 | res = session.query(sql, (graph_id)) |
|---|
| 299 | return res[0] |
|---|
| 300 | |
|---|
| 301 | @exportViaXMLRPC(SESSION_RO, AUTH_USER) |
|---|
| 302 | def getGraphVars(session_id, graph_id): |
|---|
| 303 | '''Returns all vars that are defined''' |
|---|
| 304 | |
|---|
| 305 | session = getSessionE(session_id) |
|---|
| 306 | sql = "SELECT varname from graph_parts WHERE graph_id=%s AND (type='DEF' OR type='CDEF')" |
|---|
| 307 | res = session.query(sql, (graph_id)) |
|---|
| 308 | return res |
|---|
| 309 | |
|---|
| 310 | @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR) |
|---|
| 311 | def updateGraphPartDetails(session_id, part_id, newDetails): |
|---|
| 312 | """Updates the details of the Graph part. |
|---|
| 313 | |
|---|
| 314 | newDetails should be a dictionary containing only these class paramters |
|---|
| 315 | that have changed and need to be updated in the database. |
|---|
| 316 | """ |
|---|
| 317 | session = getSessionE(session_id) |
|---|
| 318 | |
|---|
| 319 | # Build SQL |
|---|
| 320 | props = ["type", "colour", "text", "cf", \ |
|---|
| 321 | "filename", "varname", "graph_order"] |
|---|
| 322 | |
|---|
| 323 | (sql, values) = buildUpdateFromDict("graph_parts", props, newDetails, \ |
|---|
| 324 | "part_id", part_id) |
|---|
| 325 | |
|---|
| 326 | if values == None: |
|---|
| 327 | # No changes made... ? |
|---|
| 328 | return 1 |
|---|
| 329 | |
|---|
| 330 | # Run the query |
|---|
| 331 | session.execute(sql, values) |
|---|
| 332 | |
|---|
| 333 | return 1 |
|---|
| 334 | |
|---|
| 335 | @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR) |
|---|
| 336 | def updateGraphTypeDetails(session_id, graph_id, newDetails): |
|---|
| 337 | """Updates the details of the Graph type. |
|---|
| 338 | |
|---|
| 339 | newDetails should be a dictionary containing only these class paramters |
|---|
| 340 | that have changed and need to be updated in the database. |
|---|
| 341 | """ |
|---|
| 342 | session = getSessionE(session_id) |
|---|
| 343 | |
|---|
| 344 | # Build SQL |
|---|
| 345 | props = ["title", "class_id", "virtical_label"] |
|---|
| 346 | |
|---|
| 347 | (sql, values) = buildUpdateFromDict("graph_type", props, newDetails, \ |
|---|
| 348 | "graph_id", graph_id) |
|---|
| 349 | |
|---|
| 350 | if values == None: |
|---|
| 351 | # No changes made... ? |
|---|
| 352 | return 1 |
|---|
| 353 | |
|---|
| 354 | # Run the query |
|---|
| 355 | session.execute(sql, values) |
|---|
| 356 | |
|---|
| 357 | return 1 |
|---|
| 358 | |
|---|
| 359 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 360 | def addGraphGroup(session_id, clas): |
|---|
| 361 | """Adds a new graph group to the database""" |
|---|
| 362 | session = getSessionE(session_id) |
|---|
| 363 | |
|---|
| 364 | # Build query |
|---|
| 365 | props = ["group_name"] |
|---|
| 366 | (sql, values) = buildInsertFromDict("graph_group", props, clas) |
|---|
| 367 | |
|---|
| 368 | # Run query |
|---|
| 369 | session.execute(sql, values) |
|---|
| 370 | |
|---|
| 371 | return 1 |
|---|
| 372 | |
|---|
| 373 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 374 | def addGraphType(session_id, clas): |
|---|
| 375 | """Adds a new graph type to the database""" |
|---|
| 376 | session = getSessionE(session_id) |
|---|
| 377 | |
|---|
| 378 | # Build query |
|---|
| 379 | props = ["title", "class_id", "group_id"] |
|---|
| 380 | (sql, values) = buildInsertFromDict("graph_type", props, clas) |
|---|
| 381 | |
|---|
| 382 | # Run query |
|---|
| 383 | session.execute(sql, values) |
|---|
| 384 | |
|---|
| 385 | return 1 |
|---|
| 386 | |
|---|
| 387 | @exportViaXMLRPC(SESSION_RW, AUTH_USER) |
|---|
| 388 | def addGraphPart(session_id, clas): |
|---|
| 389 | """Adds a new graph part to the database""" |
|---|
| 390 | session = getSessionE(session_id) |
|---|
| 391 | |
|---|
| 392 | # Build query |
|---|
| 393 | props = ["type", "colour", "text", "varname", "cf", "filename", "graph_id", "graph_order"] |
|---|
| 394 | (sql, values) = buildInsertFromDict("graph_parts", props, clas) |
|---|
| 395 | |
|---|
| 396 | # Run query |
|---|
| 397 | session.execute(sql, values) |
|---|
| 398 | |
|---|
| 399 | return 1 |
|---|
| 400 | |
|---|
| 401 | @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR) |
|---|
| 402 | def removeGraphPart(session_id, part_id): |
|---|
| 403 | """Removes a graph part from the database.""" |
|---|
| 404 | |
|---|
| 405 | session = getSessionE(session_id) |
|---|
| 406 | |
|---|
| 407 | # Delete |
|---|
| 408 | sql = "DELETE FROM graph_parts WHERE part_id=%s" |
|---|
| 409 | res = session.execute(sql, (part_id)) |
|---|
| 410 | return 1 |
|---|
| 411 | |
|---|
| 412 | @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR) |
|---|
| 413 | def removeGraphType(session_id, graph_id): |
|---|
| 414 | """Removes a graph type from the database.""" |
|---|
| 415 | |
|---|
| 416 | session = getSessionE(session_id) |
|---|
| 417 | |
|---|
| 418 | # Delete |
|---|
| 419 | sql = "DELETE FROM graph_type WHERE graph_id=%s" |
|---|
| 420 | res = session.execute(sql, (graph_id)) |
|---|
| 421 | return 1 |
|---|
| 422 | |
|---|
| 423 | @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR) |
|---|
| 424 | def removeGraphGroup(session_id, group_id): |
|---|
| 425 | """Removes a graph group from the database.""" |
|---|
| 426 | |
|---|
| 427 | session = getSessionE(session_id) |
|---|
| 428 | |
|---|
| 429 | # Delete |
|---|
| 430 | sql = "DELETE FROM graph_group WHERE group_id=%s" |
|---|
| 431 | res = session.execute(sql, (group_id)) |
|---|
| 432 | return 1 |
|---|
| 433 | |
|---|
| 434 | def ccs_init(): |
|---|
| 435 | global GRAPH_SERVER |
|---|
| 436 | GRAPH_SERVER = "%s:%s" % (config_get("graphs", "host", "localhost"), \ |
|---|
| 437 | config_get("graphs", "port", "80")) |
|---|
| 438 | |
|---|