Proyecto

General

Perfil

##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: Hosts.py
# Purpose: Hosts class
# Language: Python 2.5
# Date: 7-Feb-2011.
# Ver: 7-Feb-2011.
# Author: Manuel Mora Gordillo
# Francisco Mendez Palma
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
# 2011 - Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import ldap
import logging
import time
from math import ceil
from operator import itemgetter

class Hosts(object):

def __init__(self):
pass
def __init__(self,ldap,name,ip,mac,group,type):
self.ldap = ldap
self.name = name
self.ip = ip
self.mac = mac
self.group = group
self.type = type
def getName (self):
return self.mac
def validation(self,action):

if action == "add":
if self.type == "none":
return "type"
if self.name == "":
return "name"
if self.type <> 'thinclient':
if self.ip == "":
return "ip"

if self.mac == "":
return "mac"
if self.type =="thinclient":
if self.group == "":
return "group"

if self.type == "":
return "type"
if action == "add":
if self.existsHostname():
return "hostAlreadyExists"
# thinclients no requieren ip, la cogen dinamicamente en el aula
if self.type <> "thinclient":
if self.existsIP():
return "ipAlreadyExists"
#controlar overflow en nodos
if self.groupOverflow(300):
return "groupOverflow"

if self.existsMAC():
return "macAlreadyExists"

elif action == "modify":
if self.groupOverflow(300):
return "groupOverflow"

if self.existsMAC():
return "macAlreadyExists"

return "OK"
def process(self,action):
import pdb
if action == "add":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.add()
return response

if action == "modify":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.modify()
return response
if action == "delete":
response = self.delete()
return response
if action == "list":
response = self.list();
return response
def list(self,args):
#from Plugins.LdapConnection import LdapConnection

#l = LdapConnection("172.23.36.5",'cn=admin,ou=People,dc=instituto,dc=extremadura,dc=es',"Sta1987teleco")
#l.connect()
# grid parameters
limit = int(args['rows'][0])
page = int(args['page'][0])
start = limit * page - limit
finish = start + limit;

# sort by field
sortBy = args['sidx'][0]
#if sortBy == "uid":
#sortBy = "id"

# reverse Sort
reverseSort = False
if args['sord'][0] == "asc":
reverseSort = True
#Distinguimos entre hosts ltsp, workstations y portatiles
type = args['type'][0]
if type == "ltsp":
# Obtengo todos los elementos del nodo hosts
#search = l.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
#filter = self.buildFilter(args)
search = self.ldap.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
# triplets que contiene los nombres de los ltsp-servers
hostnames = self.getLTSPServers()
# Ahora tengo que quedarme con los elementos de search que estan en hostnames: los que son ltsp
resultado=list()
for element in search:
if element[0][1]["cn"][0] in hostnames:
resultado.append(element)
search = resultado

rows = []
for i in search:
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]],
"cn":i[0][1]["cn"][0],
"ipHostNumber":i[0][1]["ipHostNumber"][0],
"macAddress":i[0][1]["macAddress"][0]
}
#row = { "cn":i[0][0], "cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]]}
rows.append(row)
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages

result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
elif type == "thinclient":
search = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn=*",["cn","dhcpHWAddress"])
filter="(|(dhcpOption=*subnet*)(dhcpOption=*log*))"
import pdb
rows = []
# esto hay que cambiarlo: tenemos 4 groups en thinclientes
for i in search[6:len(search)]:
nodeinfo=i[0][0].replace ("cn=","").split(",")
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["dhcpHWAddress"][0].replace("ethernet ",""), nodeinfo[1]],
"cn":i[0][1]["cn"][0],
"dhcpHWAddress":i[0][1]["dhcpHWAddress"][0],
"groupName":i[0][1]["dhcpHWAddress"][0]
}
rows.append(row)
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages
result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
elif type == "workstation":
# Obtengo todos los elementos del nodo hosts
#search = l.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
search = self.ldap.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
# triplets que contiene los nombres de las workstations
#triplets = l.search("ou=Netgroup","cn=workstation-hosts",["nisNetgroupTriple"])
triplets = self.ldap.search("ou=Netgroup","cn=workstation-hosts",["nisNetgroupTriple"])
triplets = triplets [0][0][1]["nisNetgroupTriple"]
hostnames=list()
# obtengo lista de nombres de los hosts workstation
for node in triplets:
name = node.replace(",-,-)","").replace("(","")
hostnames.append(name)
# Ahora tengo que quedarme con los elementos de search que estan en hostnames
resultado=list()
for element in search:
if element[0][1]["cn"][0] in hostnames:
resultado.append(element)
search = resultado

rows = []
for i in search:
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]],
"cn":i[0][1]["cn"][0],
"ipHostNumber":i[0][1]["ipHostNumber"][0],
"macAddress":i[0][1]["macAddress"][0]
}
#row = { "cn":i[0][0], "cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]]}
rows.append(row)

if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages

result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }

def add(self):
if self.type=="thinclient":
attr = [
('objectclass', ['top','dhcpHost']),
('cn', [self.name] ),
('dhcpStatements', ['filename "/var/lib/tftpboot/ltsp/i386/pxelinux.0"'] ),
('dhcpHWAddress', ['ethernet ' + self.mac] )
]
self.ldap.add("cn="+self.name +",cn="+self.group+",cn=THINCLIENTS,cn=DHCP Config", attr)
return "OK"
def modify(self):
attr = [
(ldap.MOD_REPLACE, 'cn', [self.name] ),
(ldap.MOD_REPLACE, 'dhcpHWAddress', ["ethernet "+ self.mac])
]
self.ldap.modify("cn="+self.name+",cn="+self.group +",cn=THINCLIENTS,cn=DHCP Config", attr)

return "OK"

def delete(self):
if self.type=="thinclient":
self.ldap.delete('cn='+ self.name +',cn=' +self.group +',cn=THINCLIENTS,cn=DHCP Config')

return "OK"

def wakeup(self):
from Plugins import NetworkUtils
NetworkUtils.startup(self.mac)
def groupOverflow(self,overflow):
import pdb
if self.type == 'thinclient':
search = self.ldap.search("cn=" + self.group +",cn=THINCLIENTS,cn=DHCP Config","cn=*",["cn"])
if len(search)-2 >= overflow:
return True
return False
def existsHostname(self):
if self.type == 'thinclient':
result = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn="+self.name,["cn"])
else:
result = self.ldap.search("ou=hosts","cn="+self.name,["cn"])
if len(result) > 0:
return True
return False
def existsMAC(self):
# Compruebo con las macs de la rama hosts
if self.type == 'thinclient':
result = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","dhcpHWAddress=*",["dhcpHWAddress"])
for i in range (0, len(result) - 1):
if result [i][0][1]['dhcpHWAddress'][0].replace ("ethernet ", "") == self.mac:
return True
else:
result = self.ldap.search("ou=hosts","macAddress="+self.mac,["macAddress"])

if len(result) > 0:
return True
return False
def existsIP (self):
# Cojo las ips de la rama hosts -> arpa -> in-addr
result = self.ldap.search ("dc=23,dc=172,dc=in-addr,dc=arpa,ou=hosts", "dc=*",["associatedDomain"])
myIP = self.ip.split (".")

for i in range (0, len (result) -1):
reverseIP = result [i][0][1]['associatedDomain'][0].replace (".in-addr.arpa","").split(".")
reverseIP.reverse()
if myIP == reverseIP:
return True
return False
def getThinclientGroups (self):

groups = []
search = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn=group*",["cn"])
for g in search:
groups.append (g[0][1]["cn"][0])
return { "groups":groups }
def getHostData(self):
#self.getUserGroups()
if self.type == "thinclient":
result = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn="+self.name,["cn","dhcpHWAddress"])
dataHost = {
"cn":result[0][0][1]["cn"][0],
"mac":result[0][0][1]["dhcpHWAddress"][0].replace("ethernet ",""),
"group":self.group
}
return dataHost
def getLTSPServers (self):
triplets = self.ldap.search("ou=Netgroup","cn=ltsp-server-hosts",["nisNetgroupTriple"])
triplets = triplets [0][0][1]["nisNetgroupTriple"]
hostnames=list()
for node in triplets:
name = node.replace(",-,-)","").replace("(","")
hostnames.append(name)
hostnames.sort()
return hostnames


def getLTSPStatus (self):
from Utils.avahiClient import avahiClient
import threading
a = avahiClient()
a.start()
time.sleep(1000)
a.cancel()
names = a.getList()
print names
"""a = avahiClient()
time.sleep(1000)
names = a.getList()
print names
a.kill()"""
return names

# def wakeup(self):
# from twisted.internet.task import LoopingCall
# from twisted.internet import defer
# from Plugins import NetworkUtils
# NetworkUtils.startup(self.mac)

# Encender el equipo
#def wakeup(self):
# macs=[]
# for i in self.targets:
# mac=Configs.MonitorConfigs.GetMAC(i)
# if mac !='':
# macs.append(mac)
# Actions.sendWOLBurst(macs, 2)

#Apagar el equipo
# def sleep(self):
# self.usersCommand(Desktop.sleep)

#def sendWOLBurst(macs,throttle):
# from twisted.internet.task import LoopingCall
# from twisted.internet import defer
# if not macs:
# return defer.succeed(None)
# d = defer.Deferred()
# work = list(macs)
# def sendNext():
# if not work:
# loop.stop()
# d.callback(None)
# return defer.succeed(None)
# next = work.pop(0)
#
# #subprocess.Popen(['wakeonlan',next ])
# #subprocess.Popen(['wakeonlan','-i','192.168.0.255',next ])
# NetworkUtils.startup(next)
#
# return None
# loop = LoopingCall(sendNext)
# loop.start(throttle)
# return d
(3-3/8)