15 Replies Latest reply on Aug 23, 2017 8:49 AM by HerrDoktor

    Python API add node?

    andrew.jackson

      Is it possible to add a node using the python api? I have been trying and have been unsuccessful. Here are the requests I've tried to perform:

       

      Using API:

      r = swis.create(Orion.Nodes, {"IPAddress = " + ip + "; EngineID = 1; ObjectSubType = " + objsubtype+ "; Caption = " + caption + ";"})

       

      Using requests:

      r = requests.request("POST", "https://solarwinds:17778/SolarWinds/InformationService/v3/Json/Create/Orion.Nodes", data=json.dumps("Orion.Nodes", {"IPAddress = " + ip + "; EngineID = 1; ObjectSubType = " + objsubtype+ "; Caption = " + caption + ";"}), verify=False, auth=(username, password), headers={'Content-Type': 'application/json'})

       

      Unfortunately, all I have been able to get is a 500 response.Can anybody help?

          • Re: Python API add node?
            san360

            I tried with the script but i get below error in response. We are using NPM 12.1

            {

                "Message": "Specified cast is not valid.",

                "ExceptionType": "System.InvalidCastException",

                "FullException": "System.InvalidCastException: Specified cast is not valid.\r\n   at SolarWinds.Data.Providers.Orion.Helpers.SnmpV3CredentialsHelper.UpdateNodesSnmpV3Credentials(Int32[] nodeIds, IDictionary`2 columnsToUpdate)\r\n   at SolarWinds.Data.Providers.Orion.CrudHandlers.NodeCrudHandler.Create(IEnumerable`1 infos, Func`2 baseCall)\r\n   at SolarWinds.InformationService.Addons.DataProvider.<Create>d__62.MoveNext()\r\n   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)\r\n   at SolarWinds.InformationService.Core.CrudProcessor.<CreateLocal>d__21.MoveNext()\r\n   at SolarWinds.InformationService.Core.CrudProcessor.<CreateInternal>d__18.MoveNext()\r\n   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)\r\n   at SolarWinds.InformationService.Core.CrudProcessor.Create(String entityType, IDictionary`2 properties, IQueryExecutionContext context)\r\n   at SolarWinds.InformationService.Core.InformationService.Create(String entityType, IDictionary`2 properties)"

            }

            • Re: Python API add node?
              robert.booth

              I have a requirement to automate deployment is CSR1000v routers and am 99% there.   I use the Orion SDK & Python 2.7 to query IPAM for IP Addresses and then use those IP Addresses to deploy the CSR1000v routers.  Once Deployed, I again use Orion SDK & Python 2.7 to mark the IP Addresses as "used" in IPAM.  Now that I have the routers deployed up and running, I need to add them to Orion for Monitoring and Alerting.  We have a requirement to only use SNMPv3 and I tried several script examples to add the new CSR1000v nodes to Orion using SNMPv3; however, It failed in every attempt.   To help my troubleshoot the issue, I figure I would at least try to add them using SNMP v2, so I started with the example python script as suggested and get the response as shown below and not really sure where to go and what to do next to resolve.  I am so close to being successful with my automation project and just need to resolve the issues with adding a to add the node as SNMPv3 and would be extremely grateful for any and all assistance/feedback, etc....

               

               

              Note:   Again, I have no problems communicating with my Orion server as I am able to get IP Addresses from IPAM as well as update their status using the Orion SDK & Python 2.7.

               

              Here is the script and the response when I run it. 

               

              def main():

                npm_server = '1.1.1.1'
                 username = 'XXXXX'
                 password = 'XXXXX'

                 swis = SwisClient(npm_server, username, password)

                 print("Add an SNMP v2c node:")

               

                 # fill these in for the node you want to add!
                 ip_address = '1.1.1.1'
                 community = 'XXXXXXX'

                 # set up property bag for the new node
                 props = {

                 'IPAddress': ip_address,

                 'EngineID': 1,

                 'ObjectSubType': 'SNMP',

                 'SNMPVersion': 2,

                 'Community': community

                }

               

                 print("Adding node {}... ".format(props['IPAddress']), end="")

                results = swis.create('Orion.Nodes', **props)

                 print("DONE!")

               

                 # extract the nodeID from the result
                 nodeid = re.search(r'(\d+)$', results).group(0)

               

                pollers_enabled = {

                 'N.Status.ICMP.Native': True,

                 'N.Status.SNMP.Native': False,

                 'N.ResponseTime.ICMP.Native': True,

                 'N.ResponseTime.SNMP.Native': False,

                 'N.Details.SNMP.Generic': True,

                 'N.Uptime.SNMP.Generic': True,

                 'N.Cpu.SNMP.HrProcessorLoad': True,

                 'N.Memory.SNMP.NetSnmpReal': True,

                 'N.AssetInventory.Snmp.Generic': True,

                 'N.Topology_Layer3.SNMP.ipNetToMedia': False,

                 'N.Routing.SNMP.Ipv4CidrRoutingTable': False
                 }

               

                pollers = []

                 for k in pollers_enabled:

                pollers.append(

                {

                 'PollerType': k,

                 'NetObject': 'N:' + nodeid,

                 'NetObjectType': 'N',

                 'NetObjectID': nodeid,

                 'Enabled': pollers_enabled[k]

                }

                )

               

                 for poller in pollers:

                 print(" Adding poller type: {} with status {}... ".format(poller['PollerType'], poller['Enabled']), end="")

                 response = swis.create('Orion.Pollers', **poller)

                 print("DONE!")

               

               

              requests.packages.urllib3.disable_warnings()

               

               

              if __name__ == '__main__':

                main()

               

              When I run the script, below is the output and the node is never added.   The error message does not really give me much information on where to look to resolve the issue.

               

              File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 937, in raise_for_status

                  raise HTTPError(http_error_msg, response=self)

              requests.exceptions.HTTPError: 400 Client Error: Unable to create Node. Details : Information : Assigned default value 'Orion.Nodes' for EntityType.

              Information : Assigned default value 'False' for DynamicIP.

              Information : Assigned default value '' for Caption.

              Error : In property EngineID. Reason : Invalid EngineID. Value : 1.

              Information : Assigned default value '0' for Status.

              Information : Assigned default value '' for Location.

              Information : Assigned default value '' for Contact.

              Information : Assigned default value '' for NodeDescription.

              Information : Assigned default value '' for IOSImage.

              Information : Assigned default value '' for IOSVersion.

              Information : Assigned default value 'False' for UnManaged.

              Information : Assigned default value 'True' for Allow64BitCounters.

              Information : Assigned default value '' for SysObjectID.

              Information : Assigned default value 'Unknown' for MachineType.

              Information : Assigned default value 'Unknown' for Vendor.

              Information : Assigned default value 'Unknown.gif' for VendorIcon.

              Information : Assigned default value '120' for PollInterval.

              Information : Assigned default value '1440' for RediscoveryInterval.

              Information : Assigned default value '10' for StatCollection.

              Information : Assigned default value '-2' for BufferBgMissThisHour.

              Information : Assigned default value '-2' for BufferBgMissToday.

              Information : Assigned default value '-2' for BufferHgMissThisHour.

              Information : Assigned default value '-2' for BufferHgMissToday.

              Information : Assigned default value '-2' for BufferLgMissThisHour.

              Information : Assigned default value '-2' for BufferLgMissToday.

              Information : Assigned default value '-2' for BufferMdMissThisHour.

              Information : Assigned default value '-2' for BufferMdMissToday.

              Information : Assigned default value '-2' for BufferNoMemThisHour.

              Information : Assigned default value '-2' for BufferNoMemToday.

              Information : Assigned default value '-2' for BufferSmMissThisHour.

              Information : Assigned default value '-2' for BufferSmMissToday.

               

              ---------------------------------- for url: https://XXX.XXX.XXX.XXX:17778/SolarWinds/InformationService/v3/Json/Create/Orion.Nodes

               

              Process finished with exit code 1

                • Re: Python API add node?
                  tdanner

                  This line tells you what the problem is:

                   

                       Error : In property EngineID. Reason : Invalid EngineID. Value : 1.

                   

                  You don't have a polling engine with EngineID=1. Use a query like this to see your EngineIDs and choose an appropriate one:

                   

                       SELECT EngineID, ServerName, ServerType FROM Orion.Engines

                    • Re: Python API add node?
                      robert.booth

                      Thanks for pointing out what the real error was.  I am going to test making changes to that so that the engine ID is accurate and will report back.   I am highly motivated to get the addnode with SNMPv3 to work with Python and when and if I am successful I most certainly will report back.   Greatly appreaciate all of the swift responses, help and suggestions.

                       

                      Warmest Regards,

                       

                      Robert Booth

                      • Re: Python API add node?
                        robert.booth

                        Tdanner,

                         

                          That EngineID did the trick for at least SNMPv2 and just basic node ; however, I can't to get it to add the node with all the typical information we provide through the webconsole manually.  I tried making sure to use the correct names of the fields and used SWQL to make sure I was using what I thought were accurate fields.  The script runs, add the node without name and does not grab any of the interfaces despite it all working if I manual add using same device and snmp creds.  I suspect I might still be using the wrong names for the properties.   For example:  We when manually add a node, we provide the IP, (snmpv2 for this test) snmpv3 creds, the hostname of the device, polling times are left at default, we have a custom properties: One  called "AWS_VPC" which is a dropdown that allows the user to select the AWS-VPC that the node is deployed in, two "Owner" which technical team is responsible for the device - (Another dropdown) and everything else on page 1 of add node we leave at default except for "Manage nodes with NCM"  If I can't add the node with all the properties we fill out; I'm not really worried about it as we can always make that a manual process after the deployment.  With that said, There are three things i really need to have as part of node add that I currently don't with this snmpv2 test.  1) Name of the node  2) All interfaces on the node 3)Node needs to be monitored and have our basic node down alert added.   As of this morning I only can add the node and the only thing that shows up under the node is the IP, snmpc2 credential and thats it.  Nothing else is there nor are the interfaces discovered and added.

                         

                        def main():

                            npm_server = 'XXXXX'

                            username = 'XXXX

                            password = 'XXXX'

                         

                         

                            swis = SwisClient(npm_server, username, password)

                            print ("AWS Automation Deployment is working to add the device for monitoring and alerting, via snmp v2c node:")

                         

                         

                            # fill these in for the node you want to add!

                            ip_address = '1.1.1.1'

                            community = 'lalalalalal'

                         

                         

                            # set up property bag for the new node

                            props = {

                                'IPAddress': ip_address,

                                'EngineID': 3,

                                'ObjectSubType': 'SNMP',

                                'SNMPVersion': 2,

                                'Community': community,

                                'Description': 'AWS-CSR-TEST',

                                'NodeDescription': "AWS-CSR-TEST",

                                'Location': "TESTING LOCATION",

                                'UnManaged': False,

                                'Allow64BitCounters': True,

                         

                         

                            }

                         

                         

                            print("AWS Automation Deployment is working to Add node IP Address {}... ".format(props['IPAddress']), end="")

                            results = swis.create('Orion.Nodes', **props)

                            print("AWS Automation Deployment added the node to SolarWinds NPM, lets make sure polling is properly configured...")

                         

                         

                            # extract the nodeID from the result

                            nodeid = re.search('(\d+)$', results).group(0)

                            print(nodeid)

                         

                         

                            pollers_enabled = {

                                'N.Status.ICMP.Native': True,

                                'N.Status.SNMP.Native': False,

                                'N.ResponseTime.ICMP.Native': True,

                                'N.ResponseTime.SNMP.Native': False,

                                'N.Details.SNMP.Generic': True,

                                'N.Uptime.SNMP.Generic': True,

                                'N.Cpu.SNMP.HrProcessorLoad': True,

                                'N.Memory.SNMP.NetSnmpReal': True,

                                'N.AssetInventory.Snmp.Generic': True,

                                'N.Topology_Layer3.SNMP.ipNetToMedia': False,

                                'N.Routing.SNMP.Ipv4CidrRoutingTable': False

                            }

                         

                         

                            pollers = []

                            for k in pollers_enabled:

                                pollers.append(

                                    {

                                        'PollerType': k,

                                        'NetObject': 'N:' + nodeid,

                                        'NetObjectType': 'N',

                                        'NetObjectID': nodeid,

                                        'Enabled': pollers_enabled[k]

                                    }

                                )

                         

                         

                            for poller in pollers:

                                print("AWS Automation Deployment is adding poller type: {} with status {}... ".format(poller['PollerType'], poller['Enabled']), end="")

                                response = swis.create('Orion.Pollers', **poller)

                                print("AWS Automation Deployment is done with the poller configuration!")

                         

                         

                            print("AWS Automation Deployment is working to discover and add the node interfaces:")

                            results = swis.invoke('Orion.NPM.Interfaces', 'DiscoverInterfacesOnNode', nodeid)

                         

                         

                            # use the results['DiscoveredInterfaces'] for all interfaces

                            # or get a subset of interfaces using a comprehension like below

                            eth_only = [

                                x for x

                                in results['DiscoveredInterfaces']

                                if x['Caption'].startswith('VLAN')]

                         

                         

                            print(eth_only)

                         

                         

                            results2 = swis.invoke(

                                'Orion.NPM.Interfaces',

                                'AddInterfacesOnNode',

                                nodeid,

                                eth_only,

                                'AddDefaultPollers')

                         

                         

                            print(results2)

                         

                         

                        requests.packages.urllib3.disable_warnings()

                         

                         

                        if __name__ == '__main__':

                            main()

                        tdanner  wrote:

                         

                        This line tells you what the problem is:

                         

                             Error : In property EngineID. Reason : Invalid EngineID. Value : 1.

                         

                        You don't have a polling engine with EngineID=1. Use a query like this to see your EngineIDs and choose an appropriate one:

                         

                             SELECT EngineID, ServerName, ServerType FROM Orion.Engines

                          • Re: Python API add node?
                            robert.booth

                            Sorry, I mean to include the actual output from the python run.  As you can see I don't get any error; however, no matter what I try it will not get the interfaces and they are nothing special.  I was able to figure out the correct field names use in order to populate the device name, location and other fields.   Is there any logging I could change to figure out why after it adds the node that it does not add / discover any interfaces and why it will not be configured as NCM managed node for backups?  I suspect the NCM managed node issue is because there is nothing in the script to tell it that.  I have not been successful with finding what that property is called and how I enable it when adding the node.

                             

                             

                            AWS Automation Deployment is working to add the device for monitoring and alerting, via snmp v2c node:

                            AWS Automation Deployment is working to Add node IP Address X>X>X>X... AWS Automation Deployment added the node to SolarWinds NPM, lets make sure polling is properly configured...

                            2603

                            AWS Automation Deployment is adding poller type: N.Memory.SNMP.NetSnmpReal with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.ResponseTime.ICMP.Native with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.ResponseTime.SNMP.Native with status False... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Status.SNMP.Native with status False... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Cpu.SNMP.HrProcessorLoad with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Routing.SNMP.Ipv4CidrRoutingTable with status False... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Uptime.SNMP.Generic with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Details.SNMP.Generic with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Topology_Layer3.SNMP.ipNetToMedia with status False... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.Status.ICMP.Native with status True... Done  with the poller configuration!

                            AWS Automation Deployment is adding poller type: N.AssetInventory.Snmp.Generic with status True... Done  with the poller configuration!

                            AWS Automation Deployment is working to discover and add the node interfaces:

                            []

                            {u'DiscoveredInterfaces': [], u'Result': 0}

                        • Re: Python API add node?
                          clarv02

                          Highly recommend checking out the usage Discovery and AutoImport to add nodes. Here is info on using Discovery Context:

                          Discovery · solarwinds/OrionSDK Wiki · GitHub

                          Setting CreateCorePluginConfiguration details for Orion.Discovery in python

                           

                          We're successfully using this approach and have incorporated:

                           

                          - Auto selecting polling engine with lowest job weight (and excluding our Primary server)

                          - Programmatically populating all the SNMP credentials so they don't have to be hard coded in the corePluginContext

                          - Auto populate custom properties based on naming convention

                          - Auto assign custom pollers (UnDP) based on naming convention

                           

                          It took a while to develop, but was well worth it in our large environment. If interested, I can provide some snippet examples.

                            • Re: Python API add node?
                              robert.booth

                              Clarv02,

                               

                                   I most certainly am interested and would again be very grateful for additional help, snippet / examples.  Being honest I am completely new to all programming and only started when we made a large move to AWS EC2 & VPCs back in March of this year.   It took me a long time, much frustration (due to my ignorance and lack of programming / scripting knowledge) and a lot of google.com to get where I am with a python script that is launched, queries the user for a couple variables such as a CIDR to use for AWS VPC as well as a name for the VPC.  From those two inputs from the user, the python script then automatically creates a AWS three tier multiple VPC infastructure with 8 CSR1000v routers, GRE connected tunnels, using the Orion SDK to query IPAM for the GRE tunnels and marking those IP address as used.  All works we'll and I'm at the last stage which is adding the AWS CSR1000v routers to NPM for monitoring and alerting.

                               

                              I look forward to trying the examples / suggestions and will be certain to keep communicating in this thread with regards to the results. 

                               

                               

                              Robert Booth