diff --git a/src/config/common/SConscript b/src/config/common/SConscript index d3d0d3c8171..33aa98019bd 100644 --- a/src/config/common/SConscript +++ b/src/config/common/SConscript @@ -66,6 +66,7 @@ pkg = [env.SandeshGenPy('#controller/src/config/uve/service_instance.sandesh', ' env.SandeshGenPy('#controller/src/config/uve/vnc_api.sandesh', 'cfgm_common/uve/', False), env.SandeshGenPy('#controller/src/config/uve/virtual_machine.sandesh', 'cfgm_common/uve/', False), env.SandeshGenPy('#controller/src/config/uve/virtual_network.sandesh', 'cfgm_common/uve/', False), + env.SandeshGenPy('#controller/src/config/uve/physical_router.sandesh', 'cfgm_common/uve/', False), env.SandeshGenPy('#controller/src/config/uve/acl.sandesh', 'cfgm_common/uve/', False), env.SandeshGenPy('#controller/src/config/uve/cfgm_cpuinfo.sandesh', 'cfgm_common/uve/', False), ] diff --git a/src/config/common/setup.py b/src/config/common/setup.py index 93a05eae208..fed790e76c7 100644 --- a/src/config/common/setup.py +++ b/src/config/common/setup.py @@ -21,6 +21,7 @@ def requirements(filename): 'cfgm_common.uve.vnc_api', 'cfgm_common.uve.virtual_machine', 'cfgm_common.uve.virtual_network', + 'cfgm_common.uve.physical_router', 'cfgm_common.uve.cfgm_cpuinfo', 'cfgm_common.uve.cfgm_cpuinfo.cpuinfo', 'cfgm_common.uve.cfgm_cpuinfo.process_info' diff --git a/src/config/device-manager/device_manager/db.py b/src/config/device-manager/device_manager/db.py index 7fadeebc7cf..7a20662f804 100644 --- a/src/config/device-manager/device_manager/db.py +++ b/src/config/device-manager/device_manager/db.py @@ -10,6 +10,7 @@ from physical_router_config import PhysicalRouterConfig from sandesh.dm_introspect import ttypes as sandesh from cfgm_common.vnc_db import DBBase +from cfgm_common.uve.physical_router.ttypes import * import copy import gevent from gevent import queue @@ -86,6 +87,7 @@ def get_all_bgp_router_ips(self): class PhysicalRouterDM(DBBase): _dict = {} obj_type = 'physical_router' + _sandesh = None def __init__(self, uuid, obj_dict=None): self.uuid = uuid @@ -98,11 +100,13 @@ def __init__(self, uuid, obj_dict=None): self.config_manager = PhysicalRouterConfig( self.management_ip, self.user_credentials, self.vendor, self.product, self.vnc_managed, self._logger) + self.uve_send() # end __init__ def update(self, obj=None): if obj is None: obj = self.read_obj(self.uuid) + self.name = obj['fq_name'][-1] self.management_ip = obj.get('physical_router_management_ip') self.dataplane_ip = obj.get('physical_router_dataplane_ip') self.vendor = obj.get('physical_router_vendor_name') @@ -128,6 +132,7 @@ def delete(cls, uuid): return obj = cls._dict[uuid] obj.config_manager.delete_bgp_config() + self.uve_send(True) obj.update_single_ref('bgp_router', {}) obj.update_multiple_refs('virtual_network', {}) del cls._dict[uuid] @@ -247,7 +252,36 @@ def push_config(self): vn_obj.instance_ip_map) self.config_manager.send_bgp_config() + self.uve_send() # end push_config + + def uve_send(self, deleted=False): + pr_trace = UvePhysicalRouterConfig(name=self.name, + ip_address=self.management_ip, + connected_bgp_router=self.bgp_router, + auto_conf_enabled=self.vnc_managed, + product_info=self.vendor + ':' + self.product) + if deleted: + pr_trace.deleted = True + pr_msg = UvePhysicalRouterConfigTrace(data=pr_trace, + sandesh=PhysicalRouterDM._sandesh) + pr_msg.send(sandesh=PhysicalRouterDM._sandesh) + return + + commit_stats = self.config_manager.get_commit_stats() + + if commit_stats['netconf_enabled'] is True: + pr_trace.last_commit_time = commit_stats['last_commit_time'] + pr_trace.last_commit_duration = commit_stats['last_commit_duration'] + pr_trace.commit_status_message = commit_stats['commit_status_message'] + pr_trace.total_commits_sent_since_up = commit_stats['total_commits_sent_since_up'] + else: + pr_trace.netconf_enabled_status = commit_stats['netconf_enabled_status'] + + pr_msg = UvePhysicalRouterConfigTrace(data=pr_trace, sandesh=PhysicalRouterDM._sandesh) + pr_msg.send(sandesh=PhysicalRouterDM._sandesh) + # end uve_send + # end PhysicalRouterDM class GlobalSystemConfigDM(DBBase): diff --git a/src/config/device-manager/device_manager/device_manager.py b/src/config/device-manager/device_manager/device_manager.py index e982e855008..1ac9cf641a9 100644 --- a/src/config/device-manager/device_manager/device_manager.py +++ b/src/config/device-manager/device_manager/device_manager.py @@ -134,6 +134,7 @@ def __init__(self, args=None): file=args.log_file, enable_syslog=args.use_syslog, syslog_facility=args.syslog_facility) + PhysicalRouterDM._sandesh = self._sandesh ConnectionState.init( self._sandesh, hostname, module_name, instance_id, staticmethod(ConnectionState.get_process_state_cb), diff --git a/src/config/device-manager/device_manager/physical_router_config.py b/src/config/device-manager/device_manager/physical_router_config.py index f8d5f3218aa..c724646c8c4 100644 --- a/src/config/device-manager/device_manager/physical_router_config.py +++ b/src/config/device-manager/device_manager/physical_router_config.py @@ -10,6 +10,8 @@ from lxml import etree from ncclient import manager import copy +import time +import datetime class PhysicalRouterConfig(object): # mapping from contrail family names to junos @@ -28,6 +30,14 @@ def __init__(self, management_ip, user_creds, vendor, product, vnc_managed, logg self.vnc_managed = vnc_managed self.reset_bgp_config() self._logger = logger + self.commit_stats = { + 'netconf_enabled':False, + 'netconf_enabled_status':'', + 'last_commit_time': '', + 'last_commit_duration': '', + 'commit_status_message': '', + 'total_commits_sent_since_up': 0, + } self.bgp_config_sent = False # end __init__ @@ -39,18 +49,27 @@ def update(self, management_ip, user_creds, vendor, product, vnc_managed): self.vnc_managed = vnc_managed # end update + def get_commit_stats(): + return self.commit_stats + #end get_commit_stats + def send_netconf(self, new_config, default_operation="merge", operation="replace"): if (self.vendor is None or self.product is None or self.vendor.lower() != "juniper" or self.product.lower() != "mx"): self._logger.info("auto configuraion of physical router is not supported \ on the configured vendor family, ip: %s, not pushing netconf message" % (self.management_ip)) + self.commit_stats['netconf_enabled'] = False + self.commit_stats['netconf_enabled_status'] = "netconf configuraion is not supported on this vendor/product family" return if (self.vnc_managed is None or self.vnc_managed == False): self._logger.info("vnc managed property must be set for a physical router to get auto \ configured, ip: %s, not pushing netconf message" % (self.management_ip)) + self.commit_stats['netconf_enabled'] = False + self.commit_stats['netconf_enabled_status'] = "netconf auto configuraion is not enabled on this physical router" return - + self.commit_stats['netconf_enabled'] = True + self.commit_stats['netconf_enabled_status'] = '' try: with manager.connect(host=self.management_ip, port=22, username=self.user_creds['username'], @@ -78,11 +97,20 @@ def send_netconf(self, new_config, default_operation="merge", target='candidate', config=etree.tostring(add_config), test_option='test-then-set', default_operation=default_operation) + self.commit_stats['total_commits_sent_since_up'] += 1 + start_time = time.time() m.commit() + end_time = time.time() + self.commit_stats['commit_status_message'] = 'success' + self.commit_stats['last_commit_time'] = datetime.datetime.fromtimestamp(end_time).strftime('%Y-%m-%d %H:%M:%S') + self.commit_stats['last_commit_duration'] = str(end_time - start_time) except Exception as e: if self._logger: self._logger.error("Router %s: %s" % (self.management_ip, e.message)) + self.commit_stats['commit_status_message'] = 'failed to apply config, router response: ' + e.message + self.commit_stats['last_commit_time'] = datetime.datetime.fromtimestamp(end_time).strftime('%Y-%m-%d %H:%M:%S') + self.commit_stats['last_commit_duration'] = str(time.time() - start_time) # end send_config def add_dynamic_tunnels(self, tunnel_source_ip, ip_fabric_nets, bgp_router_ips): diff --git a/src/config/uve/SConscript b/src/config/uve/SConscript index 0a86c392119..83309a59148 100644 --- a/src/config/uve/SConscript +++ b/src/config/uve/SConscript @@ -10,6 +10,7 @@ env = CfgmEnv.Clone() # Generate the sandesh UVE source files SandeshGenPyFiles = env.SandeshGenPy('virtual_machine.sandesh') SandeshGenPyFiles += env.SandeshGenPy('virtual_network.sandesh') +SandeshGenPyFiles += env.SandeshGenPy('physical_router.sandesh') SandeshGenPyFiles += env.SandeshGenPy('vnc_api.sandesh') SandeshGenPyFiles += env.SandeshGenPy('acl.sandesh') SandeshGenPyFiles += env.SandeshGenPy('service_instance.sandesh') diff --git a/src/config/uve/physical_router.sandesh b/src/config/uve/physical_router.sandesh new file mode 100644 index 00000000000..7c50c63d433 --- /dev/null +++ b/src/config/uve/physical_router.sandesh @@ -0,0 +1,29 @@ +// +// physical_router.sandesh +// +// UVE physical router +// +// Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. +// + +// This is the structure sent by an application to the Collector to represent +// all or part of the Config state of the UVE on this app instance. +// +struct UvePhysicalRouterConfig { + 1: string name (key="ObjectPRouter") + 2: optional bool deleted + 3: optional string ip_address + 4: optional string connected_bgp_router + 5: optional string product_info + 6: optional bool auto_conf_enabled + 7: optional bool netconf_enabled_status + 8: optional string last_commit_time + 9: optional string last_commit_duration + 10: optional string commit_status_message + 11: optional i32 total_commits_sent_since_up + // Add additional items here as needed +} + +uve sandesh UvePhysicalRouterConfigTrace { + 1: UvePhysicalRouterConfig data +}