Forum Discussion

Michael_Baker's avatar
4 years ago

Oracle DB names via SNMP

Given the existing modules use SSH/WMI to discover the DB names we required a way without the need to SSH into a server we have published a Property Source 4TK9LN that utilises SNMP to pull the DB names and then populate auto.oracle_dbs, you will either need to update / fork existing Oracle datasources or move this to a DS and set the oracle_dbnames there. Also attached inline. any improvements welcome!

{
    "scheduleOption": 0,
    "dataType": 0,
    "description": "List all Oracle databases with SNMP",
    "appliesTo": "hasCategory(\"OracleDB\")",
    "technology": "",
    "type": "propertyrule",
    "params": [
        {
            "name": "linuxcmdline",
            "comment": "",
            "value": ""
        },
        {
            "name": "linuxscript",
            "comment": "",
            "value": ""
        },
        {
            "name": "scriptgroovy",
            "comment": "",
            "value": "// Locate Oracle database names via SNMP, tested on Linux\nimport com.santaba.agent.groovyapi.snmp.Snmp\n\ndef snmp_timeout = 15000\n\ndef g_hostname = hostProps.get(\"system.hostname\")\ndef g_community = hostProps.get(\"snmp.community\")\ndef g_version  = hostProps.get(\"snmp.version\")\ndef g_security_name = hostProps.get(\"snmp.security\")\ndef g_auth_proto = hostProps.get(\"snmp.auth\")\ndef g_auth_token = hostProps.get(\"snmp.authtoken\")\ndef g_priv_proto = hostProps.get(\"snmp.priv\")\ndef g_priv_token = hostProps.get(\"snmp.privtoken\")\n\ndef snmp = new lm_snmp( g_hostname, g_community, g_version, g_security_name, g_auth_proto, g_auth_token, g_priv_proto, g_priv_token, snmp_timeout)\n// List all running processes\noutput = snmp.snmpwalk(\"1.3.6.1.2.1.25.4.2.1.4\")\ndef databases = [:]\ndef dblist = []\noutput.eachLine { entry ->\n      process = entry.split(\"=\")\n      // Find the Oracle process names\n      def proc_name = process[1] =~  /oracle(?!PRD)(\\w+)/\n      if(proc_name) {\n          // Dump it in a Map to keep it unique\n          databases[proc_name[0][1]] = 1\n      }\n}\n// Loop the Map and pump them back into an array\ndatabases.each{entry -> dblist << entry.key}\ndb_names = dblist.join(\",\")\nprint \"auto.oracle_dbs=${db_names}\"\n\n// Core classes\nclass lm_snmp\n{\n\n    String community\n    String version      // v1, v2c, v3\n    String security_name\n    String auth_proto   // MD5\n    String auth_token\n    String priv_token\n    String priv_proto   // DES\n    Integer timeout = 30000\n\n    Map v3_map = [:]\n\n    String hostname\n\n    lm_snmp( String hostname, String community, String version = \"v3\", String security_name = null, String auth_proto = null, String auth_token=null, String priv_proto=null, String priv_token=null, Integer timeout = 30000 ) {\n\n        this.hostname = hostname\n        this.community = community\n        this.version = version\n        this.timeout = timeout\n\n        if ( this.version == \"v3\" )\n        {\n            this.security_name = security_name\n            if ( auth_proto == null ) { this.auth_proto = \"SHA\" } else { this.auth_proto = auth_proto }\n            this.auth_token = auth_token\n\n            if ( priv_proto == null ) { this.priv_proto = \"AES\" } else { this.priv_proto = priv_proto }\n            this.priv_token = priv_token\n\n            v3_map[\"snmp.version\"] = \"v3\"\n            v3_map[\"snmp.security_name\"] = this.security_name\n            v3_map[\"snmp.auth_proto\"] = this.auth_proto\n            v3_map[\"snmp.auth_token\"] = this.auth_token\n            v3_map[\"snmp.priv_proto\"] = this.priv_proto\n            v3_map[\"snmp.priv_token\"] = this.priv_token\n        }\n    }\n\n    def snmpget ( String oid )\n    {\n\n        println \"Trying: ${oid}\"\n\n        if ( this.version == \"v3\" )\n        {\n            //return Snmp.getV3(this.hostname, this.security_name, this.auth_proto, this.auth_token, this.priv_proto, this.priv_token,oid, this.timeout)\n            return Snmp.get(this.hostname, oid, v3_map )\n        }\n        else\n        {\n            return Snmp.get(this.hostname, this.community, this.version, oid, this.timeout)\n        }\n\n    }\n\n    def snmpwalk ( String oid )\n    {\n\n        println \"debug: ${this.hostname}, ${this.security_name}, ${this.auth_proto}, ${this.auth_token}, ${this.priv_proto}, ${this.priv_token}, ${oid}, ${this.timeout.toString()}\"\n\n        if ( this.version == \"v3\" )\n        {\n            //return Snmp.walkV3(this.hostname, this.security_name, this.auth_proto, this.auth_token, this.priv_proto, this.priv_token, oid, this.timeout)\n            return Snmp.walk( this.hostname, oid, v3_map)\n        }\n        else\n        {\n            return Snmp.walk(this.hostname, this.community, this.version, oid, this.timeout)\n        }\n    }\n}"
        },
        {
            "name": "scripttype",
            "comment": "embed",
            "value": "embed"
        },
        {
            "name": "windowscmdline",
            "comment": "",
            "value": ""
        },
        {
            "name": "windowsscript",
            "comment": "",
            "value": ""
        }
    ],
    "version": 1628127167,
    "tags": "",
    "auditVersion": 0,
    "name": "List_Oracle_Databases_SNMP",
    "id": 153,
    "group": "Oracle"
}

 

  • @Michael Baker thanks for the contribution! I just put it through Security Review.

    One tip: the Snmp methods like get() and walk() will handle auth properties transparently if they're configured on the target host. All you really need to pass is the OID and hostname. There are quite a few examples in core DataSources. You might give the collection script of Cisco_Nexus_Temperature a look.

    We're working on publishing more information about these built-in classes to make this easier.

  • I would also take a look at the walkAsMap() method, as it returns a parsed array whereas walk() gives you kind of an unruly string.

    You can find it used in Cisco_CPU_Usage

  • Cheating? That's the beauty of the Exchange!

    If there's anything you think we can look at to make the process easier I'd love to hear your thoughts on that too.

  • Updated version! Much smaller now thank you @Michael Rodrigues

    {
        "scheduleOption": 0,
        "dataType": 0,
        "description": "List all Oracle databases with SNMP",
        "appliesTo": "hasCategory(\"OracleDB\")",
        "technology": "",
        "type": "propertyrule",
        "params": [
            {
                "name": "linuxcmdline",
                "comment": "",
                "value": ""
            },
            {
                "name": "linuxscript",
                "comment": "",
                "value": ""
            },
            {
                "name": "scriptgroovy",
                "comment": "",
                "value": "// Locate Oracle database names via SNMP, tested on Linux\nimport com.santaba.agent.groovyapi.snmp.Snmp\n\ndef host = hostProps.get('system.hostname')\ndef timeout = 30000 // 30 seconds\n\n// List all running processes\noutput = Snmp.walkAsMap(host, \"1.3.6.1.2.1.25.4.2.1.4\", null, timeout)\ndef databases = [:]\ndef dblist = []\noutput.each { oid,process ->\n      // Find the Oracle process names\n      def proc_name = process =~  /oracle(?!PRD)([A-Z]+)([0-9+]?)/\n      if(proc_name) {\n          // Dump it in a Map to keep it unique\n          databases[proc_name[0][1]] = 1\n      }\n}\n// Loop the Map and pump them back into an array\ndatabases.each{entry -> dblist << entry.key}\ndb_names = dblist.join(\",\")\nprint \"auto.oracle_dbs=${db_names}\""
            },
            {
                "name": "scripttype",
                "comment": "embed",
                "value": "embed"
            },
            {
                "name": "windowscmdline",
                "comment": "",
                "value": ""
            },
            {
                "name": "windowsscript",
                "comment": "",
                "value": ""
            }
        ],
        "version": 1628201456,
        "tags": "",
        "auditVersion": 0,
        "name": "List_Oracle_Databases_SNMP",
        "id": 153,
        "group": "Oracle"
    }

     

  • Hey @Michael Rodriguesdone! ZKLDJD one thing I would ask.. Getting all the Oracle modules updated to check for the auto.oracle_dbs, for the interim we have used the api to grab that and override the oracle.dbnames, this is not ideal as its a Jenkins job that we will need to run weekly as it discovers new databases. I do not want to find and update every datasource as we then need to maintain them in future 

    I can submit a FR if needed?

  • On 8/6/2021 at 8:16 AM, Michael Baker said:

    Hey @Michael Rodriguesdone! ZKLDJD one thing I would ask.. Getting all the Oracle modules updated to check for the auto.oracle_dbs, for the interim we have used the api to grab that and override the oracle.dbnames, this is not ideal as its a Jenkins job that we will need to run weekly as it discovers new databases. I do not want to find and update every datasource as we then need to maintain them in future 

    I can submit a FR if needed?

    Ignore the above I was reading the existing DS's wrong!