11 Replies Latest reply on Aug 6, 2018 3:59 PM by bbusse

    OrionSDK and Python - Broken?

    bbusse

      Hello everyone,  i'm new to the Orion SDK.   I'm currently testing in both Powershell (works great) and Python and i'm having a problem trying to set an IP address's status to anything.  Ideally i can pass the URI and set Status=4 to mark it reserved but when doing so from Python it fails acting like i've passed it a non Int32 value (the 4).

       

      I'm home now, but i thought i would ask if anyone else has tried via Python to update the status of an IPAM.IPNODE successfully.   We can easily retrieve a list of available IPs for a given subnet along with the URI, but cannot update the Status of the node via python.    I've got a requirement to do this via Python, which is why i'm needing this to work, i'm just much more familiar with Powershell.

       

      This post's answer does not work for me:

      Mark ip as reserved via python api

       

      quote:

      You have to use:

      swis.update(uri, Status='Reserved')

      /quote:

       

      If I do that, it complains about not passing an Int32 value. if i do   Status=4,  it complains about not passing an Int32 value.       Python only,  Powershell works fine (different syntax of course, but basically the same).

       

      If anyone has any suggestions, i'm all ears.   The Orion SDK for python is version 0.0.6 last modified in early 2017.  Maybe that's the issue? It doesn't look like there are any newer versions for python.    I should note that I also tried via a REST POST and receive the same error as using the python code.  Still odd that Powershell works fine.

       

      Our Orion IPAM setup is version 4.5.2 (i believe,  it's 4.5.x for sure).

       

      If desired i can get specific errors and screenshots.

       

      EDIT:

      Example Powershell coommand that works:

      Set-SwisObject $swis -uri $URItoIPnode -Properties @{Status =4}

       

      Problematic Python REST call example (i've placed localhost in place of our real server name in the URI):

      requests.post('https://localhost:17778/SolarWinds/InformationService/v3/Json/swis://localhost/Orion/IPAM.IPNode/IpNodeId=4602141', json={'Status': 4}, verify=False, auth=('username', 'password'))

       

      Python OrionSDK example:

      swis.update("swis://localhost/Orion/IPAM.IPNode/IpNodeId=4602141", Status=4)

       

      The error message given using Python in either REST or SDK methods is as follows:

      Invalid input for IPAM.IpNode with Id:4602141. Unable to update IPAM.IpNode. Details : Error : In property DhcpClientName. Reason : The value passed in must be an enum base or an underlying type for an enum, such as an Int32.

       

      Note:  That error is identical when using powershell and setting @{Status = 'Reserved'} instead of using an Int32 like @{Status = 4}

       

      EDIT 2:

      I also just used the SWQL Studio to browse to IPAM.IPNode, right clicked and selected 'Update',  typed the URI and the status of 4 and clicked Update.  I get the same error in a popup window.  

       

      Confirmed versioning also:

      Orion Platform 2017.1, NCM 7.6, IPAM 4.5.0, NPM 12.1, VIM 7.0.0, NetPath 1.1.0

       

       

      Brian

        • Re: OrionSDK and Python - Broken?
          tdanner

          According to https://github.com/solarwinds/OrionSDK/wiki/IPAM-4.5.x-API , that should work in IPAM 4.5 but obviously it is not. For the specific case of updating status, there's also a verb you can use. Try that and see if it will meet your needs: https://github.com/solarwinds/OrionSDK/wiki/IPAM-4.5.x-API#change-ipnode-status

            • Re: OrionSDK and Python - Broken?
              bbusse

              Thanks for that link.   I've been all over that page and of course all of their examples for using verbs is in PowerShell.    I'm having trouble finding an example of that verb (ChangeIPStatus),  using python, in a correct format.  I've tried a few variations using my previous method attempting:1.1.1.1 is an example, not the real ip.  Not sure that's the right syntax at all, just kind of did that based on a few similar examples for other verbs, but again.. not python.

               

              requests.post('https://localhost:17778/Solarwinds/InformationService/v3/Json/Invoke/IPAM.SubnetManagement/ChangeIPStatus', json={'1.1.1.1': 4}, verify=False, auth=('username', ''password))

               

              This is the response:

               

              {u'Message': u'Verb IPAM.SubnetManagement.ChangeIpStatus requires 2 parameters not 0', u'ExceptionType': u'SolarWinds.InformationService.Verb.VerbExecutorException', u'FullException': u'SolarWinds.InformationService.Verb.VerbExecutorException: Verb IPAM.SubnetManagement.ChangeIpStatus requires 2 parameters not 0\r\n   at SolarWinds.InformationService.Verb.VerbExecutorContext.CreateParameters(Func`2 getParameterAt, Int32 parametersCount, Stream stream)\r\n   at SolarWinds.InformationService.Verb.VerbExecutorContext.UnpackageParameters(JArray parameters)\r\n   at SolarWinds.InformationService.Core.InformationService.Invoke[T](String entity, String verb, Action`1 setupParameters, Func`2 extractReturnValue)'}

               

              Brian

                • Re: OrionSDK and Python - Broken?
                  tdanner

                  How about this?

                   

                  swis.invoke('IPAM.SubnetManagement', 'ChangeIPStatus', '1.1.1.1', 'Used')

                   

                  If you want to use requests.post, then the body should be an array, like ['1.1.1.1', 'Used']

                    • Re: OrionSDK and Python - Broken?
                      bbusse

                      Well that's definitely interesting.   I'm a 100% full admin, not just in IPAM, and I got access denied.  Output below from your swis.invoke example, grabbed from the Orion.InformationService log file on the server.

                       

                       

                       

                      2018-08-01 16:38:58,986 [101] ERROR SolarWinds.InformationService.Core.InformationService - (null) (null) Exception caught in method SolarWinds.InformationService.Core.InformationService.Invoke

                      SolarWinds.Data.AccessDeniedException: Access denied

                         at SolarWinds.InformationService.Verb.VerbExecutor.Invoke(Object hostInstance, Object[] parameters)

                         at SolarWinds.InformationService.Verb.VerbExecutorContext.Invoke()

                         at SolarWinds.InformationService.Core.InformationService.Invoke[T](String entity, String verb, Action`1 setupParameters, Func`2 extractReturnValue)

                       

                      And the result on the screen within python:

                       

                      >>> swis.invoke('IPAM.SubnetManagement', 'ChangeIPStatus', '10.13.64.39', 'Used')

                      Traceback (most recent call last):

                        File "<stdin>", line 1, in <module>

                        File "build/bdist.linux-x86_64/egg/orionsdk/swisclient.py", line 29, in invoke

                        File "build/bdist.linux-x86_64/egg/orionsdk/swisclient.py", line 59, in _req

                        File "/usr/lib/python2.7/site-packages/requests/models.py", line 834, in raise_for_status

                          raise HTTPError(http_error_msg, response=self)

                      requests.exceptions.HTTPError: 403 Client Error: Access denied

                       

                      Brian

                      • Re: OrionSDK and Python - Broken?
                        bbusse

                        I just tried it again using Python on Windows and that Access denied message is a little more descriptive (last line):

                         

                        >>> swis.invoke('IPAM.SubnetManagement', 'ChangeIpStatus', '10.13.64.39', 'Used')
                        Traceback (most recent call last):
                          File "<stdin>", line 1, in <module>
                          File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python37\lib\site-packages\orionsdk\swisclient.py", line 29, in invoke
                            "Invoke/{}/{}".format(entity, verb), args).json()
                          File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python37\lib\site-packages\orionsdk\swisclient.py", line 59, in _req
                            resp.raise_for_status()
                          File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\models.py", line 939, in raise_for_status
                            raise HTTPError(http_error_msg, response=self)
                        requests.exceptions.HTTPError: 403 Client Error: Access denied for url: https://localhost:17778/SolarWinds/InformationService/v3/Json/Invoke/IPAM.SubnetManagement/ChangeIpStatus

                         

                        I should note that I get that access denied message any time I try to use invoke with IPAM.SubnetManagement.   

                         

                        We do now also have a test environment running IPAM 4.7 and it now works using the SWQL Studio 'Update' feature on IPAM.IPNode by passing the URI and setting Status to Used or 1.   So that's promising.     I do get a slightly different message on the test system now when using the requests.post method.   Instead of it complaining about not being an Int32, it's instead stating "The given key was not present in the dictionary".

                         

                        Here's the command i'm using:

                        requests.post('https://localhost:17778/SolarWinds/InformationService/v3/Json/swis://localhost/Orion/IPAM.IPNode/IpNodeId=4602159', json={"Status": "Used"}, verify=False, auth=('username', 'password'))

                         

                        What I would really love,  is for someone to try something similar in either 4.5 or 4.7 and give me an example command that you used that actually works successfully.   I understand (i think) what the syntax should be, but i'd prefer a suggestion that has been validated on one of those 2 versions to be 100% sure what i'm doing is right. 

                         

                        Brian

                  • Re: OrionSDK and Python - Broken?
                    bbusse

                    Could I please get someone to try what TDanner has suggested for reserving an IP using the SDK,  not via PowerShell.  I'm using Python on both Windows and Linux to test.    Either with IPAM 4.50, 4.5.2,  or even 4.7  (preferable, as we'll be upgrading to 4.7 soon-ish).

                     

                    Simply trying to mark an IP reserved or used.  either way, changing the status of the IPNode.  Substitute 1.1.1.1 for a valid, Available, IP in IPAM.

                     

                    swis.invoke('IPAM.SubnetManagement', 'ChangeIPStatus', '1.1.1.1', 'Used')

                     

                    I want to make sure it's not just our environment being stubborn.   We're currently on IPAM 4.5.0 but have a 4.7 test environment as well,  doesn't work on either

                     

                    Below is the minimum python code necessary to try exactly what i'm trying:

                     

                    import requests
                    from orionsdk import SwisClient
                    from requests.packages.urllib3.exceptions import InsecureRequestWarning
                    
                    #Disable Insecure HTTPS Certificates
                    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
                    
                    npm_server = 'orion.mycompany.com'
                    username = 'admin_user'
                    password = 'user_password'
                    swis = SwisClient(npm_server, username, password)
                    
                    #Attempt to mark 1.1.1.1 as Used.
                    swis.invoke('IPAM.SubnetManagement', 'ChangeIPStatus', '1.1.1.1', 'Used')

                     

                    I get Access Denied for url: https://orion.mycompany.com:17778/SolarWinds/InformationService/v3/Json/Invoke/IPAM.SubnetManagement/ChangeIPStatus

                     

                     

                     

                     

                    Brian

                    • Re: OrionSDK and Python - Broken?
                      bbusse

                      Success:

                      tdanner

                      I just wanted to point out that my entire problem stemmed from something in the Orion Permissions.    EVEN THOUGH..  my domain user ID was in an AD Group, which is configured in Orion, to give full admin privileges at all levels.      Only after creating a local Orion (SQL) Account was I able to get this to work.   Even though I gave the local account the same permissions as the AD Account and/or AD Group,  it only worked with the local account.

                       

                      I tried authenticating as domain\user,  user@domain, user@fqdn_of_domain, just plain 'user', etc...   and although it all worked for querying data, changing anything was not working. 

                       

                      TL;DR:

                      The API (modifying stuff) only works for me if i use a local account built into the database with IPAM Admin perms.    AD user and/or group does not work for me.  

                       

                      Brian

                        • Re: OrionSDK and Python - Broken?
                          tdanner

                          Thanks for sticking with this and finding the combination of factors that is not working. The factors are:

                           

                          1. Authenticating as an AD group member

                          2. Over the https/REST channel

                          3. To change data in IPAM (invoke/update)

                           

                          Is that an accurate summary of what you are seeing?

                            • Re: OrionSDK and Python - Broken?
                              bbusse

                              i actually avoided https/REST and just stuck with the native API (which does appear to use 'requests').    I was only trying the REST methods because the API was not working for me.

                               

                              So,  in my example (pasted below),  This exact code (except for 1.1.1.1 being a valid IP) would not work using AD,  but does with a local account.  I tried both an AD Account,  and just via being a member of an AD Group.

                               

                              Note:  it was this way in our production IPAM 4.5.0 and our test 4.7 setup.

                               

                              import requests  
                              from orionsdk import SwisClient  
                              from requests.packages.urllib3.exceptions import InsecureRequestWarning  
                                
                              #Disable Insecure HTTPS Certificates  
                              requests.packages.urllib3.disable_warnings(InsecureRequestWarning)  
                                
                              npm_server = 'orion.mycompany.com'  
                              username = 'admin_user'  
                              password = 'user_password'  
                              swis = SwisClient(npm_server, username, password)  
                                
                              #Attempt to mark 1.1.1.1 as Used.  
                              swis.invoke('IPAM.SubnetManagement', 'ChangeIPStatus', '1.1.1.1', 'Used')

                               

                              I have not gotten back to trying the REST methods yet.   I will and report back though.

                               

                              Brian

                                • Re: OrionSDK and Python - Broken?
                                  tdanner

                                  The SwisClient class is just a thin wrapper around requests - I would not expect any behavior difference between these two.

                                   

                                  But SwisPowerShell uses a different channel to talk to SWIS and there are some differences in how authentication is handled. In characterizing this bug, it would be helpful to know if, in your environment, this affects SwisPowerShell as well or only python/rest.