diff --git a/src/analytics/contrail-topology/contrail_topology/config.py b/src/analytics/contrail-topology/contrail_topology/config.py index 4a4c284c003..e54d2e7b902 100644 --- a/src/analytics/contrail-topology/contrail_topology/config.py +++ b/src/analytics/contrail-topology/contrail_topology/config.py @@ -4,9 +4,11 @@ import argparse, os, ConfigParser, sys, re from pysandesh.sandesh_base import * from pysandesh.gen_py.sandesh.ttypes import SandeshLevel -from sandesh_common.vns.constants import ModuleNames, HttpPortTopology +from sandesh_common.vns.constants import ModuleNames, HttpPortTopology, API_SERVER_DISCOVERY_SERVICE_NAME from sandesh_common.vns.ttypes import Module import discoveryclient.client as discovery_client +import traceback +from vnc_api.vnc_api import VncApi class CfgParser(object): CONF_DEFAULT_PATH = '/etc/contrail/contrail-topology.conf' @@ -27,6 +29,8 @@ def parse(self): [--use_syslog] [--syslog_facility SYSLOG_FACILITY] [--scan_frequency SCAN_FREQUENCY] [--http_server_port HTTP_SERVER_PORT] + [--disc_server_ip 127.0.0.1] + [--disc_server_port 5998] optional arguments: -h, --help show this help message and exit @@ -82,6 +86,14 @@ def parse(self): 'disc_server_ip' : '127.0.0.1', 'disc_server_port' : 5998, } + ksopts = { + 'auth_host': '127.0.0.1', + 'auth_protocol': 'http', + 'auth_port': 35357, + 'admin_user': 'user1', + 'admin_password': 'password1', + 'admin_tenant_name': 'default-domain' + } config = None if args.conf_file: @@ -92,6 +104,8 @@ def parse(self): defaults.update(dict(config.items("DEFAULTS"))) if 'DISCOVERY' in config.sections(): disc_opts.update(dict(config.items('DISCOVERY'))) + if 'KEYSTONE' in config.sections(): + ksopts.update(dict(config.items("KEYSTONE"))) # Override with CLI options # Don't surpress add_help here so it will handle -h parser = argparse.ArgumentParser( @@ -103,6 +117,7 @@ def parse(self): formatter_class=argparse.RawDescriptionHelpFormatter, ) defaults.update(disc_opts) + defaults.update(ksopts) parser.set_defaults(**defaults) parser.add_argument("--analytics_api", help="List of analytics-api IP addresses in ip:port format", @@ -140,6 +155,18 @@ def parse(self): help="Sandesh send rate limit in messages/sec.") parser.add_argument("--cluster_id", help="Used for database keyspace separation") + parser.add_argument("--auth_host", + help="ip of keystone server") + parser.add_argument("--auth_protocol", + help="keystone authentication protocol") + parser.add_argument("--auth_port", type=int, + help="ip of keystone server") + parser.add_argument("--admin_user", + help="Name of keystone admin user") + parser.add_argument("--admin_password", + help="Password of keystone admin user") + parser.add_argument("--admin_tenant_name", + help="Tenant name for keystone admin user") self._args = parser.parse_args(remaining_argv) if type(self._args.collectors) is str: @@ -199,3 +226,35 @@ def http_port(self): def sandesh_send_rate_limit(self): return self._args.sandesh_send_rate_limit + + def api_svrs(self): + a = self._disc.subscribe(API_SERVER_DISCOVERY_SERVICE_NAME, 0) + x = a.read() + return map(lambda d:d['ip-address'] + ':' + d['port'], x) + + def vnc_api(self, notifycb=None): + e = SystemError('Cant connect to API server') + for rt in (5, 2, 7, 9, 16, 25): + for api_server in self.api_svrs(): + srv = api_server.split(':') + if len(srv) == 2: + ip, port = srv[0], int(srv[1]) + else: + ip, port = '127.0.0.1', int(srv[0]) + try: + vnc = VncApi(self._args.admin_user, + self._args.admin_password, + self._args.admin_tenant_name, + auth_host=self._args.auth_host, + auth_port=self._args.auth_port, + auth_protocol=self._args.auth_protocol) + if callable(notifycb): + notifycb('api', 'Connected', servers=api_server) + return vnc + except Exception as e: + traceback.print_exc() + if callable(notifycb): + notifycb('api', 'Not connected', servers=api_server, + up=False) + time.sleep(rt) + raise e diff --git a/src/analytics/contrail-topology/contrail_topology/controller.py b/src/analytics/contrail-topology/contrail_topology/controller.py index 765b0976a72..0801f416d3f 100644 --- a/src/analytics/contrail-topology/contrail_topology/controller.py +++ b/src/analytics/contrail-topology/contrail_topology/controller.py @@ -7,6 +7,7 @@ import gevent from gevent.coros import Semaphore from opserver.consistent_schdlr import ConsistentScheduler +import traceback class PRouter(object): def __init__(self, name, data): @@ -21,6 +22,7 @@ def __init__(self, config): self.uve = LinkUve(self._config) self.sleep_time() self._keep_running = True + self._vnc = self._config.vnc_api() def stop(self): self._keep_running = False @@ -102,6 +104,38 @@ def _chk_lnk(self, pre, index): return d['ifOperStatus'] == 1 return False + def bms_links(self, prouter, ifm): + if not self._vnc: + self._vnc = self._config.vnc_api() + if self._vnc: + try: + for li in self._vnc.logical_interfaces_list()[ + 'logical-interfaces']: + if prouter.name in li['fq_name']: + lif = self._vnc.logical_interface_read(id=li['uuid']) + for vmif in lif.get_virtual_machine_interface_refs(): + vmi = self._vnc.virtual_machine_interface_read( + id=vmif['uuid']) + for mc in vmi.virtual_machine_interface_mac_addresses.get_mac_address(): + ifi = [k for k in ifm if ifm[k] in li[ + 'fq_name']][0] + rsys = '-'.join(['bms', 'host'] + mc.split( + ':')) + if self._add_link( + prouter=prouter, + remote_system_name=rsys, + local_interface_name=li['fq_name'][ + -1], + remote_interface_name='em0',#no idea + local_interface_index=ifi, + remote_interface_index=1, #dont know TODO:FIX + link_type=2): + pass + except: + traceback.print_exc() + self._vnc = None # refresh + + def compute(self): self.link = {} for prouter in self.constnt_schdlr.work_items(): @@ -112,6 +146,7 @@ def compute(self): lldp_ints = [] ifm = dict(map(lambda x: (x['ifIndex'], x['ifDescr']), d['PRouterEntry']['ifTable'])) + self.bms_links(prouter, ifm) for pl in d['PRouterEntry']['lldpTable']['lldpRemoteSystemsData']: if d['PRouterEntry']['lldpTable']['lldpLocalSystemData'][ 'lldpLocSysDesc'].startswith('Cisco'): diff --git a/src/analytics/contrail-topology/link.sandesh b/src/analytics/contrail-topology/link.sandesh index 5dac439691a..17d7db23d62 100644 --- a/src/analytics/contrail-topology/link.sandesh +++ b/src/analytics/contrail-topology/link.sandesh @@ -12,11 +12,13 @@ namespace cpp prouter enum RemoteType { VRouter = 0 PRouter = 1 + BMS = 2 } const map RemoteTypeMapNames = { RemoteType.VRouter : "VRouter", RemoteType.PRouter : "PRouter" + RemoteType.BMS : "BMS" } /**