diff --git a/openstack_dashboard/don/ovs/analyzer.py b/openstack_dashboard/don/ovs/analyzer.py index 4e84840..5daa186 100644 --- a/openstack_dashboard/don/ovs/analyzer.py +++ b/openstack_dashboard/don/ovs/analyzer.py @@ -1,23 +1,36 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# analyzer.py: +# http://www.apache.org/licenses/LICENSE-2.0 # +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + # This file implements the following: # 1. Analysis of the collected info # 2. Report any problems # 3. Report what is correct -# -import pprint -import re + import argparse -import subprocess +from itertools import combinations import json import os -from itertools import combinations - -from common import settings, debug, get_router -from common import load_json, get_subnet, is_network_public +import pprint +import re +import subprocess import yaml +from openstack_dashboard.don.ovs.common import debug +from openstack_dashboard.don.ovs.common import get_router +from openstack_dashboard.don.ovs.common import get_subnet +from openstack_dashboard.don.ovs.common import is_network_public +from openstack_dashboard.don.ovs.common import load_json +from openstack_dashboard.don.ovs.common import settings + tick = '✔' cross = '✘' @@ -146,9 +159,8 @@ def get_vm_credentials(config_file='credentials.yaml'): try: with open(config_file, 'r') as s: return yaml.safe_load(s) - except IOError, e: - print '%s :%s' % (e.args[1], config_file) - raise + except IOError as e: + raise '%s :%s' % (e.args[1], config_file) def test_ping(info): @@ -203,7 +215,8 @@ def run_ovs_command(cmd, comment=''): return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, - universal_newlines=True).replace('\t', ' ') + universal_newlines=True).replace( + '\t', ' ') def process_ovs_output(output): @@ -361,8 +374,9 @@ def analyze(json_filename, params): def check_args(): - parser = argparse.ArgumentParser(description='Static analysis of output of commands', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser = argparse.ArgumentParser( + description='Static analysis of output of commands', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--debug', dest='debug', help='Enable debugging', default=True, action='store_true') diff --git a/openstack_dashboard/don/ovs/collector.py b/openstack_dashboard/don/ovs/collector.py index 152f6e5..12a3df4 100644 --- a/openstack_dashboard/don/ovs/collector.py +++ b/openstack_dashboard/don/ovs/collector.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/openstack_dashboard/don/ovs/common.py b/openstack_dashboard/don/ovs/common.py index 0dc3f18..3215c53 100644 --- a/openstack_dashboard/don/ovs/common.py +++ b/openstack_dashboard/don/ovs/common.py @@ -1,10 +1,22 @@ -# common.py: Common functions and data structures used by multiple modules. +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# common.py: Common functions and data structures used by multiple modules. +import json import paramiko -import sys -import re import pprint +import re import subprocess +import sys import yaml # Program settings @@ -17,7 +29,7 @@ settings = { def debug(msg): if settings['debug']: - if not sys.stdout == sys.__stdout__: + if sys.stdout != sys.__stdout__: tmp = sys.stdout sys.stdout = sys.__stdout__ print('DEBUG: ' + msg) @@ -27,7 +39,7 @@ def debug(msg): def error(msg): - if not sys.stdout == sys.__stdout__: + if sys.stdout != sys.__stdout__: tmp = sys.stdout sys.stdout = sys.__stdout__ print('ERROR: ' + msg) @@ -37,7 +49,7 @@ def error(msg): def warning(msg): - if not sys.stdout == sys.__stdout__: + if sys.stdout != sys.__stdout__: tmp = sys.stdout sys.stdout = sys.__stdout__ print('WARNING: ' + msg) @@ -49,7 +61,7 @@ def warning(msg): def status_update(msg): # storing in log file for interactive display on UI log = open('collector_log.txt', 'w') - if not sys.stdout == sys.__stdout__: + if sys.stdout != sys.__stdout__: tmp = sys.stdout sys.stdout = sys.__stdout__ print('STATUS: ' + msg) @@ -61,12 +73,11 @@ def status_update(msg): def dump_json(json_info, json_filename): - import json try: outfile = open(json_filename, "w") - except IOError, e: - print e - print 'Couldn\'t open <%s>; Redirecting output to stdout' % json_filename + except IOError as e: + print(e) + print('Couldn\'t open <%s>; Redirecting output to stdout' % json_filename) outfile = sys.stdout json.dump(json_info, outfile) @@ -75,12 +86,11 @@ def dump_json(json_info, json_filename): def load_json(json_filename): - import json try: infile = open(json_filename, "r") - except IOError, e: - print e - print 'Couldn\'t open <%s>; Error!' % json_filename + except IOError as e: + print(e) + print('Couldn\'t open <%s>; Error!' % json_filename) return None tmp = json.load(infile) @@ -94,7 +104,7 @@ def connect_to_box(server, username, password, timeout=3): try: ssh.connect(server, username=username, password=password, timeout=timeout) - except: + except Exception: return None return ssh # def connect_to_box (server, username, password,timeout=3) : @@ -108,7 +118,7 @@ def ssh_cmd(ssh, cmd): ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd) error = ssh_stderr.read() if len(error): - print 'ERROR: ' + error + print('ERROR: ' + error) output = ssh_stdout.read() ssh_stdout.flush() return output @@ -230,13 +240,15 @@ def execute_cmd(cmd, sudo=False, shell=False, env=None): shell=shell, stderr=subprocess.STDOUT, env=env, - universal_newlines=True).replace('\t', ' ') + universal_newlines=True).replace( + '\t', ' ') def get_instance_ips(objs): ip_list = [] for line in objs: - if re.search('^\+', line) or re.search('^$', line) or re.search('Networks', line): + if re.search('^\+', line) or re.search('^$', line) or re.search( + 'Networks', line): continue parts = line.split('|') parts = [x.strip() for x in parts] @@ -247,7 +259,8 @@ def get_instance_ips(objs): # excluding ipv6 ip if len(entry.split(',')) > 1: # network = entry.split('=')[0] - ip = filter(lambda a: re.search("(\d+\.\d+\.\d+\.\d+)", a) is not None, + ip = filter(lambda a: re.search("(\d+\.\d+\.\d+\.\d+)", + a) is not None, entry.split('=')[1].split(','))[0].strip() ip_list.append(ip) else: @@ -259,7 +272,8 @@ def get_router_names(objs): routers = [] for line in objs: - if re.search('^\+', line) or re.search('^$', line) or re.search('external_gateway_info', line): + if re.search('^\+', line) or re.search('^$', line) or re.search( + 'external_gateway_info', line): continue parts = line.split('|') parts = [x.strip() for x in parts] @@ -272,9 +286,8 @@ def get_router_names(objs): def get_env(file_path): try: lines = open(file_path, 'r').read().splitlines() - except IOError, e: - print "%s :%s" % (e.args[1], file_path) - raise + except IOError as e: + raise "%s :%s" % (e.args[1], file_path) env = {} for line in lines: if line.startswith('export'): @@ -290,6 +303,5 @@ def get_vm_credentials(config_file='credentials.yaml'): try: with open(config_file, 'r') as s: return yaml.safe_load(s) - except IOError, e: - print '%s :%s' % (e.args[1], config_file) - raise + except IOError as e: + raise '%s :%s' % (e.args[1], config_file) diff --git a/openstack_dashboard/don/ovs/forms.py b/openstack_dashboard/don/ovs/forms.py index e044214..64cf9da 100644 --- a/openstack_dashboard/don/ovs/forms.py +++ b/openstack_dashboard/don/ovs/forms.py @@ -1,3 +1,15 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + from django import forms diff --git a/openstack_dashboard/don/ovs/load_json.py b/openstack_dashboard/don/ovs/load_json.py index 5c0fd36..5db4240 100644 --- a/openstack_dashboard/don/ovs/load_json.py +++ b/openstack_dashboard/don/ovs/load_json.py @@ -1,7 +1,19 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + import pprint import sys -from common import load_json +from openstack_dashboard.don.ovs.common import load_json if len(sys.argv) != 2: print ('Usage: ' + sys.argv[0] + ' ') diff --git a/openstack_dashboard/don/ovs/ovs.py b/openstack_dashboard/don/ovs/ovs.py index fdc57e8..daedc99 100644 --- a/openstack_dashboard/don/ovs/ovs.py +++ b/openstack_dashboard/don/ovs/ovs.py @@ -1,12 +1,23 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + # ovs.py: Runs ovs-appctl command to check if A -> B flow is working fine. -# -# -import re import argparse import json -from common import debug, settings -from common import execute_cmd +import re + +from openstack_dashboard.don.ovs.common import debug +from openstack_dashboard.don.ovs.common import execute_cmd +from openstack_dashboard.don.ovs.common import settings params = {} @@ -74,7 +85,8 @@ def ovs_test(src_port_id, dst_port_id, tag, ovs_bridge): if vlan != tag: output_dict['errors'].append( - '%s learnt on vlan %s but should have been learnt on vlan %s on port %s' % (smac, vlan, tag, port)) + '%s learnt on vlan %s but should have been learnt on vlan %s on port %s' % ( + smac, vlan, tag, port)) output_dict['pass'] = False return False output_dict['debugs'].append( @@ -116,12 +128,14 @@ def ovs_test(src_port_id, dst_port_id, tag, ovs_bridge): output_dict['debugs'].append( 'Packet forwarded to correct port %s' % egress_port) else: - output_dict['errors'].append('Packet forwarded to incorrect port %s, expected %s' % - (egress_port, src_port_id)) + output_dict['errors'].append( + 'Packet forwarded to incorrect port %s, expected %s' % + (egress_port, src_port_id)) result = False else: - output_dict['errors'].append('No egress port assigned to packet! Expected %s' % - src_port_id) + output_dict['errors'].append( + 'No egress port assigned to packet! Expected %s' % + src_port_id) result = False output_dict['pass'] = result @@ -132,17 +146,23 @@ def check_args(): global params parser = argparse.ArgumentParser( - description='OVS test', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + description='OVS test', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--debug', dest='debug', - help='Enable debugging', default=False, action='store_true') + help='Enable debugging', + default=False, action='store_true') parser.add_argument('--src_port_id', dest='src_port_id', - help='OVS src port id (required)', type=str, required=True) + help='OVS src port id (required)', + type=str, required=True) parser.add_argument('--dst_port_id', dest='dst_port_id', - help='OVS dst port id (required)', type=str, required=True) + help='OVS dst port id (required)', + type=str, required=True) parser.add_argument( - '--tag', dest='tag', help='VLAN tag of port (required)', type=str, required=True) + '--tag', dest='tag', help='VLAN tag of port (required)', + type=str, required=True) parser.add_argument('--ovs_bridge', dest='ovs_bridge', - help='OVS bridge to be tested (required)', type=str, required=True) + help='OVS bridge to be tested (required)', + type=str, required=True) args = parser.parse_args() settings['debug'] = args.debug @@ -165,12 +185,12 @@ def main(): ovs_success = ovs_test(src_port_id, dst_port_id, tag, ovs_bridge) output_dict[ - 'comment'] = 'ovs %s port %s --> %s' % (ovs_bridge, src_port_id, dst_port_id) + 'comment'] = 'ovs %s port %s --> %s' % ( + ovs_bridge, src_port_id, dst_port_id) output_dict['pass'] = ovs_success a = json.dumps(output_dict, sort_keys=True, indent=4) - print a - pass + print(a) if __name__ == "__main__": main() diff --git a/openstack_dashboard/don/ovs/path.py b/openstack_dashboard/don/ovs/path.py index e48574a..1d8f7ec 100644 --- a/openstack_dashboard/don/ovs/path.py +++ b/openstack_dashboard/don/ovs/path.py @@ -1,19 +1,35 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + # path.py: Figures out a path between two IP addresses and then traces it -# -# HOWTO: -# -import re -import pprint -import subprocess import argparse -import os.path -import signal import json +import os.path +import pprint +import re +import signal +import subprocess import time -from common import error, settings, debug, status_update -from common import load_json, execute_cmd, dump_json -from common import ip_to_intf, intf_to_namespace, router_to_namespace + +from openstack_dashboard.don.ovs.common import debug +from openstack_dashboard.don.ovs.common import dump_json +from openstack_dashboard.don.ovs.common import error +from openstack_dashboard.don.ovs.common import execute_cmd +from openstack_dashboard.don.ovs.common import intf_to_namespace +from openstack_dashboard.don.ovs.common import ip_to_intf +from openstack_dashboard.don.ovs.common import load_json +from openstack_dashboard.don.ovs.common import router_to_namespace +from openstack_dashboard.don.ovs.common import settings +from openstack_dashboard.don.ovs.common import status_update COUNT = 10 # how many packets to be captured by tcpdump @@ -63,7 +79,8 @@ def qrouter_usable(qrouter, src_ip, dst_ip, username, passwd): return False -def launch_ping(src_ip, dst_ip, username, passwd, count, timeout, qrouter, filename): +def launch_ping(src_ip, dst_ip, username, passwd, + count, timeout, qrouter, filename): cmd = 'sudo ip netns exec ' + str(qrouter) cmd += ' python ping.py --src_ip %s --dst_ip %s --username "%s" --passwd "%s" --count %d --timeout %d' % \ (src_ip, dst_ip, username, passwd, count, timeout) @@ -95,7 +112,6 @@ def capture_network_packets(params, hop_list): net_info['pids'].append(pid) status_update( 'net: tcpdump launched with pid %d for interface %s' % (pid, dev)) - pass def capture_packets(params, tag='src', src_tag=None): @@ -481,8 +497,6 @@ def path(params): (src_ip, dst_ip)) path_same_network(params, next_hop_list) - pass - def main(): diff --git a/openstack_dashboard/don/ovs/ping.py b/openstack_dashboard/don/ovs/ping.py index 0322e63..d5251e2 100644 --- a/openstack_dashboard/don/ovs/ping.py +++ b/openstack_dashboard/don/ovs/ping.py @@ -1,19 +1,30 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + # ping.py: Runs a ping test from src_ip to dst_ip. Also provides analysis if # things are not okay (TBD). # # HOWTO: # # For OpenStack, this program must be run from inside the correct namespace -# # sudo ip netns exec qrouter-ac41aab2-f9c3-4a06-8eef-f909ee1e6e50 python ping.py 10.0.3.3 10.0.2.4 cirros "cubswin:)" -# -import re + import argparse import json -from common import connect_to_box, ssh_cmd -from common import settings +import re +from openstack_dashboard.don.ovs.common import connect_to_box +from openstack_dashboard.don.ovs.common import settings +from openstack_dashboard.don.ovs.common import ssh_cmd params = {} @@ -56,8 +67,8 @@ def ping_test(src_ip, dst_ip, username, passwd, count, timeout): result = True break except (KeyboardInterrupt, SystemExit): - print '\nkeyboardinterrupt caught (again)' - print '\n...Program Stopped Manually!' + print('\nkeyboardinterrupt caught (again)') + print('\n...Program Stopped Manually!') raise cmd_dict['pass'] = result output_dict['command_list'].append(cmd_dict) @@ -115,8 +126,7 @@ def main(): output_dict['comment'] = 'PING %s to %s' % (src_ip, dst_ip) output_dict['pass'] = ping_success - a = json.dumps(output_dict, sort_keys=True, indent=4) - print a + print(json.dumps(output_dict, sort_keys=True, indent=4)) if __name__ == "__main__": main() diff --git a/openstack_dashboard/don/ovs/plot.py b/openstack_dashboard/don/ovs/plot.py index f859907..698c0b0 100644 --- a/openstack_dashboard/don/ovs/plot.py +++ b/openstack_dashboard/don/ovs/plot.py @@ -1,19 +1,36 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# plot.py: Generates an SVG file showing the networking internals of a compute node. +# http://www.apache.org/licenses/LICENSE-2.0 # -import pprint -import subprocess -import re +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. import argparse -import sys +import pprint import random +import re +import subprocess +import sys -from common import settings, debug, warning -from common import load_json, get_subnet -from common import get_vlan_tag, get_intf_ip, get_ip_network +from common import debug +from common import get_intf_ip +from common import get_ip_network +from common import get_subnet +from common import get_vlan_tag +from common import load_json +from common import settings +from common import warning -class DotGenerator: +class DotGenerator(object): + """Generates an SVG file showing the network internals of + + a compute node. + """ def __init__(self, in_json_filename, compute_dot_file, compute_svg_file, @@ -236,34 +253,34 @@ class DotGenerator: return port_count def __html_row_open(self): - print '' + print('') def __html_row_close(self): - print '' + print('') def __html_row(self, name, rspan, cspan, color, tag=None): # tags do not allow "-" (dash) in DOT language. Convert to "_" # (underscore) if tag: - print '%s' % (rspan, cspan, color, tag.replace('-', '_'), name) + print('%s' % (rspan, cspan, color, tag.replace('-', '_'), name)) else: - print '%s' % (rspan, cspan, color, name) + print('%s' % (rspan, cspan, color, name)) pass def __html_edge(selft, src_tag, dst_tag, color, penwidth="4", style=None): src_tag = src_tag.replace('-', '_') dst_tag = dst_tag.replace('-', '_') if not style: - print '%s:s -> %s:n [color = "%s", penwidth = "%s"]' % (src_tag, + print('%s:s -> %s:n [color = "%s", penwidth = "%s"]' % (src_tag, dst_tag, color, - penwidth) + penwidth)) else: - print '%s:s -> %s:n [color = "%s", penwidth = "%s", style="%s"]' % (src_tag, + print('%s:s -> %s:n [color = "%s", penwidth = "%s", style="%s"]' % (src_tag, dst_tag, color, penwidth, - style) + style)) def __digraph_open(self, tag): msg = 'digraph DON_' + tag + ' {' + \ @@ -276,36 +293,36 @@ concentrate = true; compound = true; edge [dir=none] ''' - print msg + print(msg) def __digraph_close(self): msg = '\n}\n' - print msg + print(msg) def __cluster_name(self, tag, col_span, color="white"): self.__html_row_open() port = tag.replace(' ', '').replace('-', '_') - print '%s' % (col_span, color, port, tag) + print('%s' % (col_span, color, port, tag)) self.__html_row_close() def __cluster_open_plain(self, tag, label=None): - print 'subgraph cluster_%s {' % (tag) - print 'style=filled' + print('subgraph cluster_%s {' % (tag)) + print('style=filled') if label: - print 'label="%s"' % (label) + print('label="%s"' % (label)) def __cluster_close_plain(self): - print '}\n' + print('}\n') def __cluster_open(self, tag, color="white"): - print 'subgraph cluster_%s {' % (tag) - print '%s [ shape = plaintext, label = <' % (tag) - print '' % (color) + print('subgraph cluster_%s {' % (tag)) + print('%s [ shape = plaintext, label = <' % (tag)) + print('
' % (color)) pass def __cluster_close(self): - print '
>];\n' - print '}\n' + print('>];\n') + print('}\n') pass def __plot_title_edges(self, tag): @@ -451,7 +468,8 @@ edge [dir=none] if br_int['ports'].has_key(qvo_port): tag = br_int['ports'][qvo_port]['tag'] self.__html_row('VLAN tag:' + tag, row_span, col_span, - self.__get_vlan_color(tag), qvo_port + 'tag_' + tag) + self.__get_vlan_color(tag), + qvo_port + 'tag_' + tag) self.__html_row_close() col_span = self.__get_total_vm_port_count() @@ -468,9 +486,7 @@ edge [dir=none] self.__html_row_close() self.__cluster_close() - pass - # TODO def __plot_br_ex_to_br_int(self): namespaces = self.info['namespaces'] @@ -492,7 +508,6 @@ edge [dir=none] dst_tag = 'network_br_int:' + intf self.__html_edge(src_tag, dst_tag, self.__get_color('edge')) - pass def __plot_br_ex_network(self): routers = self.info['routers'] @@ -571,9 +586,11 @@ edge [dir=none] port_id = '[' + br_int['ports'][intf]['id'] + '] ' color = self.__get_vlan_color(tag, intf) self.__html_row( - port_id + intf, row_span, col_span, color, intf) + port_id + intf, row_span, + col_span, color, intf) # now plot the corresponding tap interface - (tap_nms, tap) = self.__get_tap_interface(nms, intf) + (tap_nms, tap) = self.__get_tap_interface(nms, + intf) tag = br_int['ports'][tap]['tag'] color = self.__get_vlan_color(tag, tap) port_id = '[' + br_int['ports'][tap]['id'] + '] ' @@ -602,7 +619,8 @@ edge [dir=none] tag = br_int['ports'][tap_intf]['tag'] self.__html_row('VLAN tag:' + tag, row_span, col_span, - self.__get_vlan_color(tag), tap_intf + 'tag_' + tag) + self.__get_vlan_color(tag), + tap_intf + 'tag_' + tag) self.__html_row_close() @@ -695,7 +713,6 @@ edge [dir=none] color = self.__get_edge_color(src_tag, dst_tag) self.__html_edge(src_tag, dst_tag, color) break - pass def __plot_linuxbridge_to_br_int(self): brctl = self.info['brctl'] @@ -713,7 +730,6 @@ edge [dir=none] color = self.__get_edge_color(src_tag, dst_tag) self.__html_edge(src_tag, dst_tag, color) break - pass def __plot_br_int_to_br_tun(self, tag): br_int = self.info['bridges']['br-int']['ports'] @@ -734,7 +750,6 @@ edge [dir=none] self.__html_edge(src_tag, dst_tag, self.__get_color('edge')) return - pass def plot_combined(self): self.outfile = open(self.combined_dot_file, 'w') @@ -845,12 +860,15 @@ edge [dir=none] def check_args(): - parser = argparse.ArgumentParser(description='Plot the compute node network internals', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser = argparse.ArgumentParser( + description='Plot the compute node network internals', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--debug', dest='debug', - help='Enable debugging', default=True, action='store_true') + help='Enable debugging', + default=True, action='store_true') parser.add_argument('--info_file', dest='info_file', - help='Info is read in JSON format in this file', default="don.json", type=str) + help='Info is read in JSON format in this file', + default="don.json", type=str) parser.add_argument('--compute_file', dest='compute_file', help='[compute_file].dot and [compute_file].svg will be generated for compute node', default="compute", type=str) parser.add_argument('--network_file', dest='network_file', @@ -858,7 +876,8 @@ def check_args(): parser.add_argument('--combined_file', dest='combined_file', help='[combined_file].dot and [combined_file].svg will be generated', default="don", type=str) parser.add_argument('--highlight_file', dest='highlight_file', - help='pass and fail node are specified in this file', default=None, type=str) + help='pass and fail node are specified in this file', + default=None, type=str) args = parser.parse_args() diff --git a/openstack_dashboard/don/ovs/run_nms_cmd.py b/openstack_dashboard/don/ovs/run_nms_cmd.py index 2667090..94d9c46 100644 --- a/openstack_dashboard/don/ovs/run_nms_cmd.py +++ b/openstack_dashboard/don/ovs/run_nms_cmd.py @@ -1,13 +1,23 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + # run_nms_cmd.py: This needs to be run from inside appropriate namespace -# # sudo ip netns exec qrouter-ac41aab2-f9c3-4a06-8eef-f909ee1e6e50 python # run_nms_cmd.py "command" -# import argparse import json -from common import connect_to_box, ssh_cmd -from common import settings +from openstack_dashboard.don.ovs.common import connect_to_box +from openstack_dashboard.don.ovs.common import settings +from openstack_dashboard.don.ovs.common import ssh_cmd params = {} @@ -45,8 +55,8 @@ def run_nms_cmd(args): cmd_dict['cmd'] = cmd cmd_dict['output'] = output except (KeyboardInterrupt, SystemExit): - print '\nkeyboardinterrupt caught (again)' - print '\n...Program Stopped Manually!' + print('\nkeyboardinterrupt caught (again)') + print('\n...Program Stopped Manually!') result = False raise cmd_dict['pass'] = result @@ -58,17 +68,23 @@ def check_args(): global params parser = argparse.ArgumentParser( - description='Run command from inside nms', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + description='Run command from inside nms', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--debug', dest='debug', - help='Enable debugging', default=False, action='store_true') + help='Enable debugging', + default=False, action='store_true') parser.add_argument('--host_ip', dest='host_ip', - help='IP where the command will be run', type=str, required=True) + help='IP where the command will be run', + type=str, required=True) parser.add_argument('--username', dest='username', - help='SSH login username (required)', type=str, required=True) + help='SSH login username (required)', + type=str, required=True) parser.add_argument('--passwd', dest='passwd', - help='SSH login passwd (required)', type=str, required=True) + help='SSH login passwd (required)', + type=str, required=True) parser.add_argument('--cmd', dest='cmd', - help='cmd to be run', type=str, required=True) + help='cmd to be run', + type=str, required=True) args = parser.parse_args() settings['debug'] = args.debug @@ -85,8 +101,7 @@ def main(): output_dict['pass'] = run_nms_cmd(params) - a = json.dumps(output_dict, sort_keys=True, indent=4) - print a + print(json.dumps(output_dict, sort_keys=True, indent=4)) if __name__ == "__main__": main() diff --git a/openstack_dashboard/don/ovs/urls.py b/openstack_dashboard/don/ovs/urls.py index 69e0e2e..ca2759a 100644 --- a/openstack_dashboard/don/ovs/urls.py +++ b/openstack_dashboard/don/ovs/urls.py @@ -1,11 +1,19 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. from django.conf.urls import patterns from django.conf.urls import url -from don.ovs.views \ - import IndexView - -from . import views - +from don.ovs.views import IndexView +import openstack_dashboard.don.ovs.views as views urlpatterns = patterns( '', diff --git a/openstack_dashboard/don/ovs/views.py b/openstack_dashboard/don/ovs/views.py index e6fed13..90f1ebb 100644 --- a/openstack_dashboard/don/ovs/views.py +++ b/openstack_dashboard/don/ovs/views.py @@ -1,20 +1,33 @@ -from horizon import views -from django.http import HttpResponse +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + from django.conf import settings -from plot import DotGenerator -import os -import subprocess -from .forms import PingForm -# from django.shortcuts import render_to_response -from horizon import messages -import analyzer -import path -from common import execute_cmd, get_instance_ips, get_env, get_router_names -import json -import shlex - - +from django.http import HttpResponse from django.shortcuts import render +from forms import PingForm +from horizon import messages +from horizon import views +import json +import os +import shlex +import subprocess + +import openstack_dashboard.don.ovs.analyzer as analyzer +from openstack_dashboard.don.ovs.common import execute_cmd +from openstack_dashboard.don.ovs.common import get_env +from openstack_dashboard.don.ovs.common import get_instance_ips +from openstack_dashboard.don.ovs.common import get_router_names +import openstack_dashboard.don.ovs.path as path +from openstack_dashboard.don.ovs.plot import DotGenerator class IndexView(views.APIView): @@ -31,8 +44,6 @@ def index(request): def view(request): - # import pdb - # pdb.set_trace() pwd = settings.ROOT_PATH # +'/openstack_dashboard/dashboards/admin/don/' JSON_FILE = pwd + '/don/ovs/don.json' @@ -53,7 +64,6 @@ def view(request): COMBINED_SVG_FILE = static_path + '/don/don.svg' macro = {} - # return HttpResponseRedirect('static/view.html') plotter = DotGenerator(JSON_FILE, COMPUTE_DOT_FILE, @@ -72,12 +82,11 @@ def view(request): plotter.plot_combined() plotter.generate_combined_svg() - # return HttpResponseRedirect('static/view.html') + return render(request, "don/ovs/views.html", macro) def analyze(request): - # pwd = settings.BASE_DIR pwd = settings.ROOT_PATH JSON_FILE = pwd + '/don/ovs/don.json' @@ -89,14 +98,9 @@ def analyze(request): 'test:ovs': True, 'test:report_file': pwd + '/don/templates/don/don.report.html', } - print "params ====> ", params + print("params ====> ", params) analyzer.analyze(JSON_FILE, params) - # output = analyzer.analyze(JSON_FILE, params) - # html = 'Output: %s' % output - # return HttpResponse(html) - # return HttpResponseRedirect('/static/don.report.html') return render(request, "don/ovs/analyze.html") - # return render_to_response('don/ovs/analyze.html') def test(request): @@ -111,13 +115,10 @@ def ping(request): # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required - # ... # redirect to a new URL: src_ip = form.cleaned_data['src_ip'] dst_ip = form.cleaned_data['dst_ip'] router = form.cleaned_data['router'] - # html = 'SIP: %s DIP: %s router: %s' % (src_ip, dst_ip, router) - # return HttpResponse(html) static_path = settings.STATIC_ROOT pwd = settings.ROOT_PATH JSON_FILE = pwd + '/don/ovs/don.json' @@ -148,7 +149,6 @@ def ping(request): NETWORK_SVG_FILE = None COMBINED_DOT_FILE = static_path + '/don/ping.dot' COMBINED_SVG_FILE = static_path + '/don/ping.svg' - # HIGHLIGHT_FILE = pwd + '/don/ovs/static/ping.html' HIGHLIGHT_FILE = static_path + '/don/ping.html' plotter = DotGenerator(JSON_FILE, @@ -163,7 +163,6 @@ def ping(request): plotter.plot_combined() plotter.generate_combined_svg() - # return HttpResponseRedirect('/static/path.html') return render(request, 'don/ovs/path.html') # if a GET (or any other method) we'll create a blank form @@ -177,7 +176,8 @@ def ping(request): ip_list = get_instance_ips(output) ip_list.sort() router_op = execute_cmd( - ['neutron', 'router-list'], sudo=False, shell=False, env=myenv).split('\n') + ['neutron', 'router-list'], + sudo=False, shell=False, env=myenv).split('\n') router_list = get_router_names(router_op) router_list.sort() # insert first value of select menu @@ -197,11 +197,11 @@ def collect(request): status = 0 BASE_DIR = settings.ROOT_PATH - # CUR_DIR = os.getcwd() os.chdir(BASE_DIR + '/don/ovs') cmd = 'sudo python collector.py' for line in run_command(cmd): - if line.startswith('STATUS:') and line.find('Writing collected info') != -1: + if line.startswith('STATUS:') and line.find( + 'Writing collected info') != -1: status = 1 macro['collect_status'] = \ "Collecton successful. Click visualize to display" @@ -230,4 +230,5 @@ def get_status(request): BASE_DIR = settings.ROOT_PATH + '/don/ovs/' status = open(BASE_DIR + 'collector_log.txt', 'r').readline() if status != " " and status != '\n': - return HttpResponse(json.dumps({'status': status}), content_type="application/json") + return HttpResponse(json.dumps( + {'status': status}), content_type="application/json")