Merge pull request #6 from changzhi1990/stethoclient

Add check vlan_id in physical swith scenario
This commit is contained in:
Damon.Wang 2016-01-07 01:47:30 +08:00
commit 837be28b09
10 changed files with 230 additions and 5 deletions

93
etc/init.d/steth-agent Normal file
View File

@ -0,0 +1,93 @@
#!/bin/bash
#
# stetho OpenStack Software Defined Networking Debuging
#
# chkconfig: - 98 02
# description: neutron provides an API to \
# * request and configure virtual networks
# Just for CentOS 6.5
### END INIT INFO
. /etc/rc.d/init.d/functions
prog=stetho
exec="/usr/bin/$prog-agent"
pidfile="/var/run/$prog/$prog.pid"
logfile="/var/log/$prog/server.log"
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog-agent
start() {
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
daemon --user neutron --pidfile $pidfile "$exec & echo \$! > $pidfile"
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
reload() {
restart
}
force_reload() {
restart
}
rh_status() {
status -p $pidfile $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?

View File

@ -0,0 +1,13 @@
# Just for CentOS 7
[Unit]
Description=OpenStack Neutron Debug Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/python /usr/bin/stetho-agent
Restart=on-abort
[Install]
WantedBy=multi-user.target

View File

@ -1,3 +1,4 @@
jsonrpclib
netaddr
mock
cliff

View File

@ -13,8 +13,24 @@
# License for the specific language governing permissions and limitations
# under the License.
import sys
from setuptools import setup, find_packages
# In CentOS6.5, the version of python is 2.6, and in CentOS7 the version of
# python is 2.7. So we can according by the python version to put the
# stetho-agent script to the right place.
#
# If in CentOS6.5, the init script should be placed in "/etc/init.d/"
# If in CentOS7, the init script should be placed in "/etc/systemd/system/"
CENTOS6 = '/etc/init.d/'
CENTOS7 = '/etc/systemd/system/'
CENTOS6_SCRIPT = 'etc/init.d/stetho-agent'
CENTOS7_SCRIPT = 'etc/init.d/stetho-agent.service'
PYTHON_VERSION = '2.6' if '2.6' in sys.version else '2.7'
AGENT_INIT_SCRIPT = CENTOS6 if PYTHON_VERSION == '2.6' else CENTOS7
SCRIPT_LOCATION = CENTOS6_SCRIPT if PYTHON_VERSION == '2.6' else CENTOS7_SCRIPT
setup(name='stetho',
version="0.1.0",
packages = find_packages(),
@ -28,6 +44,8 @@ setup(name='stetho',
url = "https://www.ustack.com",
data_files=[
('/etc/stetho', ['etc/stetho.conf']),
(AGENT_INIT_SCRIPT, [SCRIPT_LOCATION]),
],
entry_points={
'console_scripts': [

View File

@ -1,5 +0,0 @@
======================
Running Stethoclient
======================
This is a client library for stetho built on the Stetho API. It provides a Python API (the stethoclient module) and a command-line tool (stetho).

View File

@ -24,6 +24,28 @@ from json import JSONDecoder
from stetho.stethoclient.constants import AGENT_INFOS
LISTEN_PORT = 9698
SETUP_LINK_IP_PRE = "192.168.100."
class Logger():
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
@staticmethod
def log_normal(info):
print Logger.OKBLUE + info + Logger.ENDC
@staticmethod
def log_high(info):
print Logger.OKGREEN + info + Logger.ENDC
@staticmethod
def log_fail(info):
print Logger.FAIL + info + Logger.ENDC
def setup_server(agent):
@ -90,6 +112,9 @@ class SetUpLink(Lister):
# Get Link info
res = server.get_interface(parsed_args.interface)
self.log.debug('Response is %s' % res)
if res['code'] == 1:
Logger.log_fail(res['message'])
sys.exit()
if res['code'] == 0:
return (('Field', 'Value'),
((k, v) for k, v in res['data'].items()))
@ -117,6 +142,9 @@ class GetInterface(Lister):
try:
res = server.get_interface(parsed_args.interface)
self.log.debug('Response is %s' % res)
if res['code'] == 1:
Logger.log_fail(res['message'])
sys.exit()
if res['code'] == 0:
return (('Field', 'Value'),
((k, v) for k, v in res['data'].items()))
@ -151,6 +179,9 @@ class AddVlanToInterface(Lister):
new_interface = parsed_args.interface + '.' + parsed_args.vlan_id
res = server.get_interface(new_interface)
self.log.debug('Response is %s' % res)
if res['code'] == 1:
Logger.log_fail(res['message'])
sys.exit()
if res['code'] == 0:
return (('Field', 'Value'),
((k, v) for k, v in res['data'].items()))
@ -183,6 +214,9 @@ class AgentPing(Lister):
timeout=parsed_args.timeout,
interface=parsed_args.interface)
self.log.debug('Response is %s' % res)
if res['code'] == 1:
Logger.log_fail(res['message'])
sys.exit()
if res['code'] == 0:
return (('Destination', 'Packet Loss (%)'),
((k, v) for k, v in res['data'].items()))
@ -210,9 +244,79 @@ class CheckPortsOnBr(Lister):
res = server.check_ports_on_br(parsed_args.bridge,
parsed_args.port)
self.log.debug('Response is %s' % res)
if res['code'] == 1:
Logger.log_fail(res['message'])
sys.exit()
if res['code'] == 0:
return (('Port', 'Exists'),
((k, v) for k, v in res['data'].items()))
except Exception as e:
self.log.error('Agent %s return error: %s!' % parsed_args.agent, e)
sys.exit()
class CheckVlanInterface(Lister):
"""Check vlan if exists in switch"""
log = logging.getLogger(__name__)
def get_parser(self, prog_name):
parser = super(CheckVlanInterface, self).get_parser(prog_name)
parser.add_argument('agentA', default='bad')
parser.add_argument('agentB', default='bad')
parser.add_argument('interface', default='eth0')
parser.add_argument('vlan_id', default='1124')
return parser
def take_action(self, parsed_args):
self.log.debug('Get parsed_args: %s' % parsed_args)
serverA = setup_server(parsed_args.agentA)
serverB = setup_server(parsed_args.agentB)
try:
interface = parsed_args.interface + '.' + parsed_args.vlan_id
# First of all, check the interface if exists
resA = serverA.get_interface(interface)
resB = serverB.get_interface(interface)
if resA['code'] == 1:
msg = "Agent: %s has no interface named %s!" % (
parsed_args.agentA, interface)
Logger.log_fail(msg)
sys.exit()
if resB['code'] == 1:
msg = "Agent: %s has no interface named %s!" % (
parsed_args.agentB, interface)
Logger.log_fail(msg)
sys.exit()
# add vlan interface in each agent
resA = serverA.add_vlan_to_interface(parsed_args.interface,
parsed_args.vlan_id)
self.log.debug('Response is %s' % resA)
resB = serverB.add_vlan_to_interface(parsed_args.interface,
parsed_args.vlan_id)
self.log.debug('Response is %s' % resB)
Logger.log_normal(('AgentA and agentB has already added the '
'interface %s ') % (interface))
# setup link in each agent
ipA = SETUP_LINK_IP_PRE + parsed_args.agentA.split('-')[1] + '/24'
resA = serverA.setup_link(interface, ipA)
self.log.debug('Response is %s' % resA)
ipB = SETUP_LINK_IP_PRE + parsed_args.agentB.split('-')[1] + '/24'
resB = serverB.setup_link(interface, ipB)
self.log.debug('Response is %s' % resB)
Logger.log_normal(('AgentA and agentB has already setup the '
'IP %s and IP %s') % (ipA, ipB))
# ping a agent from exists IP to check connectivity
res = serverA.ping(ips=[ipB])
# teardown the interface in each agent to clean all resources
resA = serverA.teardown_link(interface)
self.log.debug('Response is %s' % resA)
resB = serverB.teardown_link(interface)
self.log.debug('Response is %s' % resB)
Logger.log_normal(('AgentA and agentB has already deleted the'
'vlan %s in %s') % (parsed_args.vlan_id,
parsed_args.interface))
if res['code'] == 0:
return (('Destination', 'Packet Loss (%)'),
((k, v) for k, v in res['data'].items()))
except Exception as e:
self.log.error('Agent %s return error: %s!' % parsed_args.agent, e)
sys.exit()

View File

@ -35,6 +35,7 @@ COMMAND_V1 = {
'ping': agent_api.AgentPing,
'check-ports-on-br': agent_api.CheckPortsOnBr,
'get-interface': agent_api.GetInterface,
'check-vlan-interface': agent_api.CheckVlanInterface,
}
COMMANDS = {'0.1': COMMAND_V1}