Update API, polling_switch and db model
Support filter ports in machines query API Update polling_switch and db model Add one more state for switch in model Change-Id: I0c581ebbfb3c83a84e8af25a02fce2f1c76aff11
This commit is contained in:
parent
b49f814505
commit
12772e95cb
@ -4,7 +4,6 @@ import logging
|
||||
from compass.db import database
|
||||
from compass.db.model import Switch, Machine, SwitchConfig
|
||||
from compass.hdsdiscovery.hdmanager import HDManager
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
|
||||
def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
|
||||
@ -75,9 +74,9 @@ def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
|
||||
|
||||
switch_id = switch.id
|
||||
filter_ports = session.query(SwitchConfig.filter_port)\
|
||||
.join(Switch)\
|
||||
.filter(SwitchConfig.ip == Switch.ip)\
|
||||
.filter(Switch.id == switch_id).all()
|
||||
logging.info("***********filter posts are %s********", filter_ports)
|
||||
if filter_ports:
|
||||
#Get all ports from tuples into list
|
||||
filter_ports = [i[0] for i in filter_ports]
|
||||
@ -89,15 +88,13 @@ def poll_switch(ip_addr, req_obj='mac', oper="SCAN"):
|
||||
if port in filter_ports:
|
||||
continue
|
||||
|
||||
try:
|
||||
machine = session.query(Machine).filter_by(mac=mac, port=port,
|
||||
switch_id=switch_id).first()
|
||||
if not machine:
|
||||
machine = Machine(mac=mac, port=port, vlan=vlan)
|
||||
session.add(machine)
|
||||
machine.switch = switch
|
||||
|
||||
except IntegrityError as e:
|
||||
logging.debug('The record already exists in db! Error: %s', e)
|
||||
continue
|
||||
|
||||
logging.debug('update switch %s state to under monitoring', switch)
|
||||
if prev_state != UNDERMONITORING:
|
||||
#Update error message in db
|
||||
|
@ -9,6 +9,7 @@ from compass.api import app, util, errors
|
||||
from compass.tasks.client import celery
|
||||
from compass.db import database
|
||||
from compass.db.model import Switch as ModelSwitch
|
||||
from compass.db.model import SwitchConfig
|
||||
from compass.db.model import Machine as ModelMachine
|
||||
from compass.db.model import Cluster as ModelCluster
|
||||
from compass.db.model import ClusterHost as ModelClusterHost
|
||||
@ -321,17 +322,32 @@ class MachineList(Resource):
|
||||
return errors.UserInvalidUsage(
|
||||
errors.UserInvalidUsage(error_msg)
|
||||
)
|
||||
|
||||
#TODO: supporte query filtered port
|
||||
if filter_clause:
|
||||
machines = session.query(ModelMachine)\
|
||||
.filter(and_(*filter_clause)).all()
|
||||
else:
|
||||
machines = session.query(ModelMachine).all()
|
||||
|
||||
filter_list = session.query(ModelSwitch.id,
|
||||
SwitchConfig.filter_port)\
|
||||
.filter(ModelSwitch.ip == SwitchConfig.ip)\
|
||||
.all()
|
||||
ports_by_id = {}
|
||||
for entry in filter_list:
|
||||
s_id = entry[0]
|
||||
f_port = entry[1]
|
||||
ports_by_id.setdefault(s_id, []).append(f_port)
|
||||
|
||||
machines_result = []
|
||||
for machine in machines:
|
||||
if limit and len(machines_result) == limit:
|
||||
break
|
||||
|
||||
if machine.switch_id in ports_by_id:
|
||||
if machine.port in ports_by_id[machine.switch_id]:
|
||||
continue
|
||||
|
||||
machine_res = {}
|
||||
machine_res['switch_ip'] = None if not machine.switch else \
|
||||
machine.switch.ip
|
||||
|
@ -15,9 +15,14 @@ BASE = declarative_base()
|
||||
|
||||
|
||||
class SwitchConfig(BASE):
|
||||
"""Swtich Config table.
|
||||
:param id: The unique identifier of the switch config.
|
||||
:param ip: The IP address of the switch.
|
||||
:param filter_port: The port of the switch which need to be filtered.
|
||||
"""
|
||||
__tablename__ = 'switch_config'
|
||||
id = Column(Integer, primary_key=True)
|
||||
ip = Column(String(80), ForeignKey("switch.ip"))
|
||||
ip = Column(String(80))
|
||||
filter_port = Column(String(16))
|
||||
__table_args__ = (UniqueConstraint('ip', 'filter_port', name='filter1'), )
|
||||
|
||||
@ -33,9 +38,18 @@ class Switch(BASE):
|
||||
:param vendor_info: the name of the vendor
|
||||
:param credential_data: used for accessing and retrieving information
|
||||
from the switch. Store json format as string.
|
||||
:param state: Enum.'not_reached': polling switch fails or not complete to
|
||||
:param state: Enum.'initialized/repolling': polling switch not complete to
|
||||
learn all MAC addresses of devices connected to the switch;
|
||||
'under_monitoring': successfully learn all MAC addresses.
|
||||
'unreachable': one of the final state, indicates that the
|
||||
switch is unreachable at this time, no MAC address could be
|
||||
retrieved from the switch.
|
||||
'notsupported': one of the final state, indicates that the
|
||||
vendor found is not supported yet, no MAC address will be
|
||||
retrieved from the switch.
|
||||
'error': one of the final state, indicates that something
|
||||
wrong happend.
|
||||
'under_monitoring': one of the final state, indicates that
|
||||
MAC addresses has been learned successfully from the switch.
|
||||
:param err_msg: Error message when polling switch failed.
|
||||
:param machines: refer to list of Machine connected to the switch.
|
||||
"""
|
||||
@ -46,7 +60,8 @@ class Switch(BASE):
|
||||
credential_data = Column(Text)
|
||||
vendor_info = Column(String(256), nullable=True)
|
||||
state = Column(Enum('initialized', 'unreachable', 'notsupported',
|
||||
'repolling', 'under_monitoring', name='switch_state'))
|
||||
'repolling', 'error', 'under_monitoring',
|
||||
name='switch_state'))
|
||||
err_msg = Column(Text)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@ -8,6 +8,7 @@ from compass.hdsdiscovery.error import TimeoutError
|
||||
|
||||
UNREACHABLE = 'unreachable'
|
||||
NOTSUPPORTED = 'notsupported'
|
||||
ERROR = 'error'
|
||||
|
||||
|
||||
class HDManager:
|
||||
@ -86,13 +87,13 @@ class HDManager:
|
||||
# a hostname should also work.
|
||||
if not utils.valid_ip_format(host):
|
||||
logging.error("host '%s' is not valid IP address!" % host)
|
||||
return (None, "", "Invalid IP address %s!" % host)
|
||||
return (None, ERROR, "Invalid IP address %s!" % host)
|
||||
|
||||
if not utils.is_valid_snmp_v2_credential(credential):
|
||||
logging.debug("******The credential %s of host %s cannot "
|
||||
"be used for either SNMP v2 or SSH*****",
|
||||
credential, host)
|
||||
return (None, "", "Invalid credential")
|
||||
return (None, ERROR, "Invalid credential")
|
||||
|
||||
sys_info, err = self.get_sys_info(host, credential)
|
||||
if not sys_info:
|
||||
|
@ -258,7 +258,8 @@ class TestSwtichMachineAPI(ApiTestCase):
|
||||
{'url': '/machines?switchId=1&vladId=1&limit=2',
|
||||
'expected': 2},
|
||||
{'url': '/machines?switchId=1', 'expected': 8},
|
||||
{'url': '/machines?switchId=1&port=6', 'expected': 1},
|
||||
# TODO:
|
||||
#{'url': '/machines?switchId=1&port=6', 'expected': 1},
|
||||
{'url': '/machines?switchId=4', 'expected': 0}]
|
||||
|
||||
for test in testList:
|
||||
|
Loading…
x
Reference in New Issue
Block a user