Index: /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/controller/snmpv3_controller.py
===================================================================
--- /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/controller/snmpv3_controller.py	(revision 2791)
+++ /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/controller/snmpv3_controller.py	(working copy)
@@ -1,31 +1,30 @@
-# -*- coding: utf-8 -*-
 import json
+import subprocess
 from hive.util.utils import json_response
-from hive.services.snmpv3_service import (
-    save_snmpv3_device,
-    configure_telegraf_snmp,
-    get_snmpv3_device_config,
-    delete_snmpv3_device,
-    update_snmpv3_device_status,
-)
+from hive.services.snmpv3_service import Snmpv3Service
 from cm.lib.libbasic_operation import oper_log
 from hive.utils import andebug
+
 VALID_DEVICE_TYPES = ["apv", "vapv", "ag", "vxag", "asf", "vasf"]
 
+# Create a single shared instance of Snmpv3Service
+snmpv3_service = Snmpv3Service()
 
+
 def handle_snmpv3_req(request, path=None):
     """
     Main SNMPv3 handler for all SNMPv3-related routes.
     Supported endpoints:
-      POST   /snmpv3/config   → Configure or update SNMPv3 device
-      GET    /snmpv3/config   → Get SNMPv3 config(s)
-      DELETE /snmpv3/config   → Delete SNMPv3 device config
-      POST   /snmpv3/toggle   → Enable or disable SNMPv3 polling
+        POST   /snmpv3/config   → Configure or update SNMPv3 device
+        GET    /snmpv3/config   → Get SNMPv3 config(s)
+        DELETE /snmpv3/config   → Delete SNMPv3 device config
+        POST   /snmpv3/toggle   → Enable or disable SNMPv3 polling
     """
     try:
         if request.method == 'POST':
             if path == 'config':
                 return configure_snmpv3_device(request)
+
             elif path == 'toggle':
                 return toggle_snmpv3_device(request)
 
@@ -50,11 +49,11 @@
 
 def configure_snmpv3_device(request):
     """
-    Configure SNMPv3 for a device (save + reconfigure telegraf).
-
-    Accepts sec_level = "authPriv" or "authNoPriv".
-    If not provided, defaults to "authPriv".
-    """
+        Configure SNMPv3 for a device (save + reconfigure telegraf).
+        Accepts sec_level = "authPriv" or "authNoPriv".
+        If not provided, defaults to "authPriv".
+        """
+    # Parse JSON input
     try:
         data = json.loads(request.body)
     except Exception:
@@ -70,11 +69,11 @@
     if sec_level == "authPriv":
         required += ["priv_pass", "priv_protocol"]
 
+    # Validate fields
     for field in required:
         if field not in data or not data[field]:
             return json_response({"error": "Missing field: %s" % field}, status=400)
 
-    # Normalize
     data["device_type"] = data["device_type"].strip().lower()
     data["sec_level"] = sec_level
 
@@ -82,19 +81,35 @@
         return json_response({"error": "Invalid device_type"}, status=400)
 
     try:
-        # Step 1: Save SNMPv3 device config
-        success, msg = save_snmpv3_device(data)
+        # Save new SNMPv3 device config
+        success, msg = snmpv3_service.save_snmpv3_device(data)
+
         if not success:
             oper_log('error', 'system', "SNMPv3 device save failed: %s" % msg)
             return json_response({"error": msg}, status=500)
 
-        # Step 2: Regenerate Telegraf config
-        success, msg = configure_telegraf_snmp()
+        # Generate Telegraf config
+        success, msg = snmpv3_service.configure_telegraf_snmp()
+
         if not success:
             oper_log('error', 'system', "Telegraf config update failed: %s" % msg)
             return json_response({"error": msg}, status=500)
 
         oper_log('info', 'system', "SNMPv3 device configured successfully")
+
+        # Background regeneration (for override fix)
+        cmd = (
+            "import time; time.sleep(120); "
+            "import sys; "
+            "sys.path.extend(['/ca/webui/htdocs/new/src', '/ca/webui/htdocs/new/src/hive/services']); "
+            "from snmpv3_service import Snmpv3Service; "
+            "Snmpv3Service().configure_telegraf_snmp()"
+        )
+
+        subprocess.Popen(["python", "-c", cmd],
+                         stdin=subprocess.PIPE,
+                         close_fds=True).stdin.close()
+
         return json_response({"message": "SNMPv3 configuration successful"}, status=200)
 
     except Exception as e:
@@ -118,14 +133,14 @@
         if not device_ip or enabled is None:
             return json_response({"error": "Missing required fields: device_ip and enabled"}, status=400)
 
-        success, msg = update_snmpv3_device_status(device_ip, enabled)
+        success, msg = snmpv3_service.update_snmpv3_device_status(device_ip, enabled)
+
         if not success:
             oper_log('error', 'system', "SNMPv3 toggle failed: %s" % msg)
             return json_response({"error": "Failed to update device status"}, status=500)
 
         oper_log('info', 'system', "SNMPv3 device %s enabled=%s" % (device_ip, enabled))
         return json_response({"message": "Device polling status updated successfully"}, status=200)
-
     except Exception as e:
         oper_log('error', 'system', "SNMPv3 toggle error: %s" % str(e))
         return json_response({
@@ -137,9 +152,10 @@
     """Get SNMPv3 configuration for a specific device or all devices."""
     try:
         device_ip = request.GET.get('device_ip')
-        success, data = get_snmpv3_device_config(device_ip)
 
-        # Specific device request
+        success, data = snmpv3_service.get_snmpv3_device_config(device_ip)
+
+        # Return specific device
         if device_ip:
             if success:
                 return json_response(data, status=200)
@@ -168,7 +184,8 @@
         if not device_ip:
             return json_response({"error": "Device IP required"}, status=400)
 
-        success, msg = delete_snmpv3_device(device_ip)
+        success, msg = snmpv3_service.delete_snmpv3_device(device_ip)
+
         if success:
             oper_log('info', 'system', "Deleted SNMPv3 config for %s" % device_ip)
             return json_response({"message": msg}, status=200)
@@ -179,4 +196,4 @@
         oper_log('error', 'system', "Failed to delete SNMPv3 device: %s" % str(e))
         return json_response({
             "error": "Internal error while deleting SNMPv3 configuration"
-        }, status=500)
\ No newline at end of file
+        }, status=500)
Index: /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/services/snmpv3_service.py
===================================================================
--- /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/services/snmpv3_service.py	(revision 2791)
+++ /branches/amp_3_7_2/src/webui/webui/htdocs/new/src/hive/services/snmpv3_service.py	(working copy)
@@ -28,329 +28,326 @@
         json.dump(data, f, indent=4)
 
 
-def save_snmpv3_device(data):
-    """Save or update SNMPv3 device configuration."""
-    try:
-        # Ensure 'enabled' flag exists — default True
-        if "enabled" not in data:
-            data["enabled"] = True
+class Snmpv3Service:
+    def __init__(self):
+        pass
 
-        devices = _load_json(SNMPV3_DEVICES_PATH)
-        updated = False
+    def save_snmpv3_device(self, data):
+        """Save or update SNMPv3 device configuration."""
+        try:
+            # Ensure 'enabled' flag exists — default True
+            if "enabled" not in data:
+                data["enabled"] = True
 
-        # Update existing entry if found
-        for i, d in enumerate(devices):
-            if d.get("device_ip") == data["device_ip"]:
-                devices[i] = data
-                updated = True
-                break
+            devices = _load_json(SNMPV3_DEVICES_PATH)
+            updated = False
 
-        # Otherwise append new device
-        if not updated:
-            devices.append(data)
+            # Update existing entry if found
+            for i, d in enumerate(devices):
+                if d.get("device_ip") == data["device_ip"]:
+                    devices[i] = data
+                    updated = True
+                    break
 
-        # Ensure directory exists
-        directory = os.path.dirname(SNMPV3_DEVICES_PATH)
-        if not os.path.exists(directory):
-            os.makedirs(directory)
+            # Otherwise append new device
+            if not updated:
+                devices.append(data)
 
-        # Save back to JSON
-        _save_json(SNMPV3_DEVICES_PATH, devices)
-        oper_log('info', 'system', "SNMPv3 device saved: %s" % data["device_ip"])
-        return True, "SNMPv3 device saved successfully"
+            # Ensure directory exists
+            directory = os.path.dirname(SNMPV3_DEVICES_PATH)
+            if not os.path.exists(directory):
+                os.makedirs(directory)
 
-    except Exception as e:
-        oper_log('error', 'system', "Failed to save SNMPv3 device: %s" % str(e))
-        return False, str(e)
+            # Save back to JSON
+            _save_json(SNMPV3_DEVICES_PATH, devices)
+            oper_log('info', 'system', "SNMPv3 device saved: %s" % data["device_ip"])
+            return True, "SNMPv3 device saved successfully"
 
+        except Exception as e:
+            oper_log('error', 'system', "Failed to save SNMPv3 device: %s" % str(e))
+            return False, str(e)
 
-def delete_snmpv3_device(device_ip):
-    """Remove a device entry and update Telegraf config."""
-    try:
-        devices = _load_json(SNMPV3_DEVICES_PATH)
-        new_devices = [d for d in devices if d.get("device_ip") != device_ip]
+    def delete_snmpv3_device(self, device_ip):
+        """Remove a device entry and update Telegraf config."""
+        try:
+            devices = _load_json(SNMPV3_DEVICES_PATH)
+            new_devices = [d for d in devices if d.get("device_ip") != device_ip]
 
-        if len(new_devices) == len(devices):
-            return False, "Device not found in SNMPv3 configuration."
+            if len(new_devices) == len(devices):
+                return False, "Device not found in SNMPv3 configuration."
 
-        _save_json(SNMPV3_DEVICES_PATH, new_devices)
-        oper_log('info', 'system', "Removed SNMPv3 device: %s" % device_ip)
+            _save_json(SNMPV3_DEVICES_PATH, new_devices)
+            oper_log('info', 'system', "Removed SNMPv3 device: %s" % device_ip)
 
-        # Rebuild Telegraf config after removal
-        configure_telegraf_snmp()
-        return True, "SNMPv3 device removed and Telegraf updated."
-    except Exception as e:
-        oper_log('error', 'system', "Failed to remove SNMPv3 device: %s" % str(e))
-        return False, str(e)
+            # Rebuild Telegraf config after removal
+            self.configure_telegraf_snmp()
+            return True, "SNMPv3 device removed and Telegraf updated."
+        except Exception as e:
+            oper_log('error', 'system', "Failed to remove SNMPv3 device: %s" % str(e))
+            return False, str(e)
 
+    def get_snmpv3_device_config(self, device_ip=None):
+        """
+        Return SNMPv3 configuration for a specific device or all devices.
+        """
+        try:
+            devices = _load_json(SNMPV3_DEVICES_PATH)
+            if devices is None:
+                devices = []
+            if device_ip:
+                for d in devices:
+                    if d.get("device_ip") == device_ip:
+                        return True, d
+                return False, "No SNMPv3 configuration found for device %s" % device_ip
+            # All devices: return devices list (may be empty)
+            return True, devices
+        except Exception as e:
+            oper_log('error', 'system', "Failed to fetch SNMPv3 config: %s" % str(e))
+            return False, str(e)
 
-def get_snmpv3_device_config(device_ip=None):
-    """
-    Return SNMPv3 configuration for a specific device or all devices.
-    """
-    try:
-        devices = _load_json(SNMPV3_DEVICES_PATH)
-        if devices is None:
-            devices = []
-        if device_ip:
-            for d in devices:
-                if d.get("device_ip") == device_ip:
-                    return True, d
-            return False, "No SNMPv3 configuration found for device %s" % device_ip
-        # All devices: return devices list (may be empty)
-        return True, devices
-    except Exception as e:
-        oper_log('error', 'system', "Failed to fetch SNMPv3 config: %s" % str(e))
-        return False, str(e)
+    def _load_toml_fields(self, device_type):
+        """Lightweight TOML parser for SNMP OID files (no external dependencies).
 
+          Example TOML:
+            [[inputs.snmp.field]]
+            name = "cpu_usage"
+            oid = ".1.3.6.1.4.1.7564.30.1.0"
 
-def _load_toml_fields(device_type):
-    """Lightweight TOML parser for SNMP OID files (no external dependencies).
+            [[inputs.snmp.table]]
+            name = "realStats"
 
-      Example TOML:
-        [[inputs.snmp.field]]
-        name = "cpu_usage"
-        oid = ".1.3.6.1.4.1.7564.30.1.0"
+            [[inputs.snmp.table.field]]
+            name = "rsConnCnt"
+            oid = ".1.3.6.1.4.1.7564.19.2.1.1.1.6"
+            is_tag = true
 
-        [[inputs.snmp.table]]
-        name = "realStats"
+        Returns:
+            tuple: (fields, tables)
+                fields → List of dicts like:
+                    [
+                        {"name": "cpu_usage", "oid": ".1.3.6.1.4.1.7564.30.1.0"}
+                    ]
+                tables → List of dicts like:
+                    [
+                        {
+                            "name": "realStats",
+                            "field": [
+                                {"name": "rsConnCnt", "oid": ".1.3.6.1.4.1.7564.19.2.1.1.1.6", "is_tag": "true"}
+                            ]
+                        }
+                    ]
+        """
+        toml_map = {
+            'apv': '/ca/webui/conf/snmp/apv.toml',
+            'vapv': '/ca/webui/conf/snmp/apv.toml',
+            'ag': '/ca/webui/conf/snmp/ag.toml',
+            'vxag': '/ca/webui/conf/snmp/ag.toml',
+            'asf': '/ca/webui/conf/snmp/asf.toml',
+            'vasf': '/ca/webui/conf/snmp/asf.toml'
+        }
 
-        [[inputs.snmp.table.field]]
-        name = "rsConnCnt"
-        oid = ".1.3.6.1.4.1.7564.19.2.1.1.1.6"
-        is_tag = true
+        file_path = toml_map.get(device_type.lower())
+        if not file_path or not os.path.exists(file_path):
+            return [], []
 
-    Returns:
-        tuple: (fields, tables)
-            fields → List of dicts like:
-                [
-                    {"name": "cpu_usage", "oid": ".1.3.6.1.4.1.7564.30.1.0"}
-                ]
-            tables → List of dicts like:
-                [
-                    {
-                        "name": "realStats",
-                        "field": [
-                            {"name": "rsConnCnt", "oid": ".1.3.6.1.4.1.7564.19.2.1.1.1.6", "is_tag": "true"}
-                        ]
-                    }
-                ]
-    """
-    toml_map = {
-        'apv': '/ca/webui/conf/snmp/apv.toml',
-        'vapv': '/ca/webui/conf/snmp/apv.toml',
-        'ag': '/ca/webui/conf/snmp/ag.toml',
-        'vxag': '/ca/webui/conf/snmp/ag.toml',
-        'asf': '/ca/webui/conf/snmp/asf.toml',
-        'vasf': '/ca/webui/conf/snmp/asf.toml'
-    }
+        fields, tables = [], []
+        current_table = None
+        current_field = None
 
-    file_path = toml_map.get(device_type.lower())
-    if not file_path or not os.path.exists(file_path):
-        return [], []
+        with open(file_path, 'r') as f:
+            for line in f:
+                line = line.strip()
+                if not line or line.startswith('#'):
+                    continue
 
-    fields, tables = [], []
-    current_table = None
-    current_field = None
+                if line.startswith('[[inputs.snmp.field]]'):
+                    current_table = None
+                    current_field = {}
+                    fields.append(current_field)
+                    continue
 
-    with open(file_path, 'r') as f:
-        for line in f:
-            line = line.strip()
-            if not line or line.startswith('#'):
-                continue
+                if line.startswith('[[inputs.snmp.table]]'):
+                    current_table = {'name': None, 'field': []}
+                    tables.append(current_table)
+                    continue
 
-            if line.startswith('[[inputs.snmp.field]]'):
-                current_table = None
-                current_field = {}
-                fields.append(current_field)
-                continue
+                if line.startswith('[[inputs.snmp.table.field]]'):
+                    if current_table is not None:
+                        current_field = {}
+                        current_table['field'].append(current_field)
+                    continue
 
-            if line.startswith('[[inputs.snmp.table]]'):
-                current_table = {'name': None, 'field': []}
-                tables.append(current_table)
-                continue
+                if '=' not in line:
+                    continue
 
-            if line.startswith('[[inputs.snmp.table.field]]'):
-                if current_table is not None:
-                    current_field = {}
-                    current_table['field'].append(current_field)
-                continue
+                key, val = [x.strip() for x in line.split('=', 1)]
+                val = val.strip('"').strip("'")
 
-            if '=' not in line:
-                continue
-
-            key, val = [x.strip() for x in line.split('=', 1)]
-            val = val.strip('"').strip("'")
-
-            if current_table is not None:
-                if key == 'name' and current_table.get('name') is None:
-                    current_table['name'] = val
+                if current_table is not None:
+                    if key == 'name' and current_table.get('name') is None:
+                        current_table['name'] = val
+                    elif current_field is not None:
+                        current_field[key] = val
                 elif current_field is not None:
                     current_field[key] = val
-            elif current_field is not None:
-                current_field[key] = val
 
-    return fields, tables
+        return fields, tables
 
+    def configure_telegraf_snmp(self):
+        """Generate SNMPv3 Telegraf config based on stored devices (supports authPriv / authNoPriv)."""
+        try:
+            devices = _load_json(SNMPV3_DEVICES_PATH)
+            if not devices:
+                return False, "No SNMPv3 devices defined"
 
-def configure_telegraf_snmp():
-    """Generate SNMPv3 Telegraf config based on stored devices (supports authPriv / authNoPriv)."""
-    andebug('an.model.cli', 'Inside configure_telegraf_snmp')
-    try:
-        devices = _load_json(SNMPV3_DEVICES_PATH)
-        andebug('an.model.cli', 'devices: {}'.format(devices))
-        if not devices:
-            return False, "No SNMPv3 devices defined"
+            lines = []
 
-        lines = []
+            for d in devices:
+                if not d.get("enabled", True):
+                    continue
 
-        for d in devices:
-            if not d.get("enabled", True):
-                continue
+                device_ip = d.get("device_ip")
+                device_type = d.get("device_type", "").lower()
+                sec_level = d.get("sec_level", "authPriv")
+                if not device_ip:
+                    continue
 
-            device_ip = d.get("device_ip")
-            device_type = d.get("device_type", "").lower()
-            sec_level = d.get("sec_level", "authPriv")
-            if not device_ip:
-                continue
+                # Load SNMP OIDs dynamically from TOML
+                fields, tables = self._load_toml_fields(device_type)
 
-            # Load SNMP OIDs dynamically from TOML
-            fields, tables = _load_toml_fields(device_type)
-
-            # --- SNMPv3 section header ---
-            lines.extend([
-                '[[inputs.snmp]]',
-                '  agents = ["%s:161"]' % device_ip,
-                '  version = 3',
-                '  name = "snmpv3_metrics_%s"' % device_ip.replace('.', '_'),
-                '  timeout = "2s"',
-                '  sec_name = "%s"' % d["username"],
-                '  auth_protocol = "%s"' % d["auth_protocol"],
-                '  auth_password = "%s"' % d["auth_pass"]
-            ])
-
-            # Optional encryption fields (only for authPriv)
-            if sec_level == "authPriv":
+                # --- SNMPv3 section header ---
                 lines.extend([
-                    '  priv_protocol = "%s"' % d.get("priv_protocol", ""),
-                    '  priv_password = "%s"' % d.get("priv_pass", "")
+                    '[[inputs.snmp]]',
+                    '  agents = ["%s:161"]' % device_ip,
+                    '  version = 3',
+                    '  name = "snmpv3_metrics_%s"' % device_ip.replace('.', '_'),
+                    '  timeout = "2s"',
+                    '  sec_name = "%s"' % d["username"],
+                    '  auth_protocol = "%s"' % d["auth_protocol"],
+                    '  auth_password = "%s"' % d["auth_pass"]
                 ])
 
-            # Security level
-            lines.append('  sec_level = "%s"' % sec_level)
-            lines.append('')
+                # Optional encryption fields (only for authPriv)
+                if sec_level == "authPriv":
+                    lines.extend([
+                        '  priv_protocol = "%s"' % d.get("priv_protocol", ""),
+                        '  priv_password = "%s"' % d.get("priv_pass", "")
+                    ])
 
-            # --- Add SNMP fields ---
-            for f in fields:
-                if not f.get("name") or not f.get("oid"):
-                    continue
-                lines.extend([
-                    '  [[inputs.snmp.field]]',
-                    '    name = "%s"' % f["name"],
-                    '    oid = "%s"' % f["oid"]
-                ])
-                if f.get("conversion"):
-                    lines.append('    conversion = "%s"' % f["conversion"])
-                if f.get("is_tag"):
-                    lines.append('    is_tag = true')
+                # Security level
+                lines.append('  sec_level = "%s"' % sec_level)
                 lines.append('')
 
-            # --- Add SNMP tables ---
-            for table in tables:
-                if not isinstance(table, dict):
-                    continue
-                tname = table.get("name")
-                if not tname:
-                    continue
-
-                lines.append('  [[inputs.snmp.table]]')
-                lines.append('    name = "%s"' % tname)
-
-                if "prefix" in table:
-                    lines.append('    prefix = %s' % table["prefix"])
-
-                fields_list = table.get("field", [])
-                for f in fields_list:
+                # --- Add SNMP fields ---
+                for f in fields:
                     if not f.get("name") or not f.get("oid"):
                         continue
                     lines.extend([
-                        '    [[inputs.snmp.table.field]]',
-                        '      name = "%s"' % f["name"],
-                        '      oid = "%s"' % f["oid"]
+                        '  [[inputs.snmp.field]]',
+                        '    name = "%s"' % f["name"],
+                        '    oid = "%s"' % f["oid"]
                     ])
                     if f.get("conversion"):
-                        lines.append('      conversion = "%s"' % f["conversion"])
+                        lines.append('    conversion = "%s"' % f["conversion"])
                     if f.get("is_tag"):
-                        lines.append('      is_tag = true')
+                        lines.append('    is_tag = true')
                     lines.append('')
 
-            lines.append('')  # spacing between devices
+                # --- Add SNMP tables ---
+                for table in tables:
+                    if not isinstance(table, dict):
+                        continue
+                    tname = table.get("name")
+                    if not tname:
+                        continue
 
-        # --- Write new config ---
-        start_marker = "# BEGIN SNMPv3 AUTOGEN"
-        end_marker = "# END SNMPv3 AUTOGEN"
+                    lines.append('  [[inputs.snmp.table]]')
+                    lines.append('    name = "%s"' % tname)
 
-        if os.path.exists(COMPOSER_TELEGRAF_CONF):
-            with open(COMPOSER_TELEGRAF_CONF, "r") as f:
-                existing = f.read()
-        else:
-            existing = "[agent]\ninterval = \"10s\"\n\n"
+                    if "prefix" in table:
+                        lines.append('    prefix = %s' % table["prefix"])
 
-        if start_marker in existing and end_marker in existing:
-            pre = existing.split(start_marker)[0]
-            post = existing.split(end_marker)[-1]
-            new_conf = pre + start_marker + "\n" + "\n".join(lines) + "\n" + end_marker + post
-        else:
-            new_conf = existing.strip() + "\n\n" + start_marker + "\n" + "\n".join(lines) + "\n" + end_marker + "\n"
+                    fields_list = table.get("field", [])
+                    for f in fields_list:
+                        if not f.get("name") or not f.get("oid"):
+                            continue
+                        lines.extend([
+                            '    [[inputs.snmp.table.field]]',
+                            '      name = "%s"' % f["name"],
+                            '      oid = "%s"' % f["oid"]
+                        ])
+                        if f.get("conversion"):
+                            lines.append('      conversion = "%s"' % f["conversion"])
+                        if f.get("is_tag"):
+                            lines.append('      is_tag = true')
+                        lines.append('')
 
-        with open(COMPOSER_TELEGRAF_CONF, "w") as f:
-            f.write(new_conf)
+                lines.append('')  # spacing between devices
 
-        # --- Restart composer_tele safely ---
-        subprocess.call(["pkill", "-f", "composer_tele"])
-        time.sleep(2)
-        subprocess.Popen([
-            "/ca/extensions/auditing/syslogd/composer_tele",
-            "--config", COMPOSER_TELEGRAF_CONF
-        ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            # --- Write new config ---
+            start_marker = "# BEGIN SNMPv3 AUTOGEN"
+            end_marker = "# END SNMPv3 AUTOGEN"
 
-        time.sleep(5)
-        ps_check = subprocess.call(["pgrep", "-f", "composer_tele"])
-        if ps_check != 0:
-            oper_log('error', 'system', "composer_tele did not start properly")
-        else:
-            oper_log('info', 'system', "composer_tele restarted successfully")
+            if os.path.exists(COMPOSER_TELEGRAF_CONF):
+                with open(COMPOSER_TELEGRAF_CONF, "r") as f:
+                    existing = f.read()
+            else:
+                existing = "[agent]\ninterval = \"10s\"\n\n"
 
-        oper_log('info', 'system', "Telegraf SNMPv3 configuration updated successfully")
-        return True, "Telegraf SNMPv3 configuration updated successfully"
+            if start_marker in existing and end_marker in existing:
+                pre = existing.split(start_marker)[0]
+                post = existing.split(end_marker)[-1]
+                new_conf = pre + start_marker + "\n" + "\n".join(lines) + "\n" + end_marker + post
+            else:
+                new_conf = existing.strip() + "\n\n" + start_marker + "\n" + "\n".join(lines) + "\n" + end_marker + "\n"
 
-    except Exception as e:
-        oper_log('error', 'system', "Failed to configure Telegraf SNMPv3: %s" % str(e))
-        return False, str(e)
+            with open(COMPOSER_TELEGRAF_CONF, "w") as f:
+                f.write(new_conf)
 
+            # --- Restart composer_tele safely ---
+            subprocess.call(["pkill", "-f", "composer_tele"])
+            time.sleep(2)
+            subprocess.Popen([
+                "/ca/extensions/auditing/syslogd/composer_tele",
+                "--config", COMPOSER_TELEGRAF_CONF
+            ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
-def update_snmpv3_device_status(device_ip, enabled):
-    """Enable or disable SNMPv3 polling for a device."""
-    try:
-        devices = _load_json(SNMPV3_DEVICES_PATH)
-        found = False
+            time.sleep(5)
+            ps_check = subprocess.call(["pgrep", "-f", "composer_tele"])
+            if ps_check != 0:
+                oper_log('error', 'system', "composer_tele did not start properly")
+            else:
+                oper_log('info', 'system', "composer_tele restarted successfully")
 
-        for d in devices:
-            if d.get("device_ip") == device_ip:
-                d["enabled"] = bool(enabled)
-                found = True
-                break
+            oper_log('info', 'system', "Telegraf SNMPv3 configuration updated successfully")
+            return True, "Telegraf SNMPv3 configuration updated successfully"
 
-        if not found:
-            return False, "Device not found in SNMPv3 configuration."
+        except Exception as e:
+            oper_log('error', 'system', "Failed to configure Telegraf SNMPv3: %s" % str(e))
+            return False, str(e)
 
-        _save_json(SNMPV3_DEVICES_PATH, devices)
-        oper_log('info', 'system', "Updated SNMPv3 device %s: enabled=%s" % (device_ip, enabled))
+    def update_snmpv3_device_status(self, device_ip, enabled):
+        """Enable or disable SNMPv3 polling for a device."""
+        try:
+            devices = _load_json(SNMPV3_DEVICES_PATH)
+            found = False
 
-        # Rebuild telegraf config after toggle
-        configure_telegraf_snmp()
+            for d in devices:
+                if d.get("device_ip") == device_ip:
+                    d["enabled"] = bool(enabled)
+                    found = True
+                    break
 
-        return True, "Device polling status updated successfully."
-    except Exception as e:
-        oper_log('error', 'system', "Failed to update SNMPv3 device status: %s" % str(e))
-        return False, str(e)
+            if not found:
+                return False, "Device not found in SNMPv3 configuration."
+
+            _save_json(SNMPV3_DEVICES_PATH, devices)
+            oper_log('info', 'system', "Updated SNMPv3 device %s: enabled=%s" % (device_ip, enabled))
+
+            # Rebuild telegraf config after toggle
+            self.configure_telegraf_snmp()
+
+            return True, "Device polling status updated successfully."
+        except Exception as e:
+            oper_log('error', 'system', "Failed to update SNMPv3 device status: %s" % str(e))
+            return False, str(e)
