6 Replies Latest reply on Nov 17, 2017 6:21 PM by clarv02

    Unable to query node for NCM properties

    davidvarnum

      I'm able to query the SWIS API for NPM properties, but not for NCM.  This works to pull the custom properties for a node:

       

      https://orion:17778/SolarWinds/InformationService/v3/Json/swis://orion/Orion/Orion.Nodes/NodeID=1/CustomProperties

       

      Based on the SWIS schema, I think I should be able to pull NCM node properties with this method:

       

      https://orion:17778/SolarWinds/InformationService/v3/Json/swis://orion/Orion/Orion.Nodes/NodeID=1/NodeProperties

       

      But I'm getting this error in return:

       

      {

        "Message": "Invalid key properties specified for entity NCM.NodeProperties.\r\nParameter name: filter",

        "ExceptionType": "System.ArgumentException",

        "FullException": "System.ArgumentException: Invalid key properties specified for entity NCM.NodeProperties.\r\nParameter name: filter\r\n   at SolarWinds.InformationService.Core.SwisUriResolver.ValidateAndResolveFilter(IEntityType entity, SwisUriFilter filter, Boolean isHosted)\r\n   at SolarWinds.InformationService.Core.SwisUriResolver.ValidateAndResolveUri(SwisUri uri, IQueryExecutionContext context)\r\n   at SolarWinds.InformationService.Core.CrudProcessor.Read[T](IServiceHost serviceHost, SwisUri uri, IQueryExecutionContext context)\r\n   at SolarWinds.InformationService.Core.InformationService.Read(String uri)"

      }

       

      Any ideas?  Thanks!

        • Re: Unable to query node for NCM properties
          davidvarnum

          Via the SwisClient Python applet I can query the Node's NCM properties, for example, to retrieve the Connection Profile ID.

           

          >>> swis.query("SELECT n.Uri, n.NodeProperties.ConnectionProfile FROM Orion.Nodes n WHERE n.NodeID=7500")

          {u'results': [{u'Uri': u'swis://orion/Orion/Orion.Nodes/NodeID=7500', u'ConnectionProfile': 3}]}

           

          However, the SwisClient doesn't allow me to read the Node's NCM properties via the assumed GET request:

           

          >>> swis.read('swis://orion/Orion/Orion.Nodes/NodeID=7500/NodeProperties')

          {u'Message': u'Invalid key properties specified for entity NCM.NodeProperties.\r\nParameter name: filter', u'ExceptionType': u'System.ArgumentException', u'FullException': u'System.ArgumentException: Invalid key properties specified for entity NCM.NodeProperties.\r\nParameter name: filter\r\n  at SolarWinds.InformationService.Core.SwisUriResolver.ValidateAndResolveFilter(IEntityType entity, SwisUriFilter filter, Boolean isHosted)\r\n  at SolarWinds.InformationService.Core.SwisUriResolver.ValidateAndResolveUri(SwisUri uri, IQueryExecutionContext context)\r\n  at SolarWinds.InformationService.Core.CrudProcessor.Read[T](IServiceHost serviceHost, SwisUri uri, IQueryExecutionContext context)\r\n  at SolarWinds.InformationService.Core.InformationService.Read(String uri)'}

          >>>

           

          I'm sure I'm missing something...

           

           

            • Re: Unable to query node for NCM properties
              tdanner

              Your assumptions are all valid, but there is a problem with the way the SWIS schema for NCM.NodeProperties is set up that prevents the "read" operation from working with it. I recommend you stick with the query interface when you need to deal with NCM NodeProperties.

                • Re: Unable to query node for NCM properties
                  davidvarnum

                  Thanks for the quick answer tdanner.  Maybe you can guide me in the right direction.  What I'm attempting to do is set the NCM node properties (Node Group, Template, Connection Profile) using the API, via Python.

                   

                  I'll query, and receive the NCM Device Template of "Cisco IOS".  Then attempt to update to '3Com'.

                   

                  >>> swis.query("SELECT n.Uri, n.NodeProperties.DeviceTemplate FROM Orion.Nodes n WHERE n.NodeID = 7500")

                  {u'results': [{u'DeviceTemplate': u'Cisco IOS', u'Uri': u'swis://orion/Orion/Orion.Nodes/NodeID=7500'}]}

                  >>>

                  >>> swis.update('swis://orion/Orion/Orion.Nodes/NodeID=7500/NodeProperties', DeviceTemplate='3Com')

                  >>>

                  >>> swis.query("SELECT n.Uri, n.NodeProperties.DeviceTemplate FROM Orion.Nodes n WHERE n.NodeID = 7500")

                  {u'results': [{u'DeviceTemplate': u'Cisco IOS', u'Uri': u'swis://orion/Orion/Orion.Nodes/NodeID=7500'}]}

                   

                  Unfortunately, it's just not updating.  Weird thing is the update function doesn't appear to fail.   Ultimately I'm trying to wrap this into an "add node" script, but for now I'm just trying to prove this functions via a normal POST.  I appreciate your assistance.  Thank you!

                    • Re: Unable to query node for NCM properties
                      tdanner

                      Unfortunately swis.update is not going to work for NCM.NodeProperties for the same reason that swis.read doesn't.

                       

                      NCM has another API you can use to set the device template and various other properties, a verb called Cirrus.Nodes.UpdateNode. It takes one object, an NCM Node. In JSON it looks like this:

                       

                      {
                        "NodeID": "727de772-30f9-4bbb-a70a-6d5e3ae4e88b",
                        "CoreNodeID": 2,
                        "NodeGroup": "",
                        "NodeComments": "",
                        "UseUserDeviceCredentials": false,
                        "Username": "SWEN__HepU+bIFJx0DwZvnEAlI6//26tmtYtVPihU866RJwXdvnHdYzq8r3UZIfG/PPTygpGlZe8AtYt4ZzGSX/Zhn0r43xccH9cTjxlQ+mx/frLxIJn3lWm6lbFGhaZj5SrwvBq1STIPSHMamCBkZDg0MytjRqFYHWc3jXJyP9kMCxrndVdIpv7QPaA7ci271vu6fJPaoBhRDCghNY1T3iARL1AyHQjvPt0cSG13+pxByprpctJ23LWhBdoRjSwuAvRKHF9Z55FQ/2f0dz9tsgax0y+2XCCPRsBZoQExIxPwziVF16N4bag2Elw0X2avkUbIC8iJjRkkJpTqM5BH4cozR+w==",
                        "Password": "SWEN__Qm/11BaGfm8EYhdcQ3ukxAqAutVIdQAiiB6GP1QK1L2l5lbD9sn1J9V67B61y8bw5PDBeaEK0zP+qBgpccxH1BIRUlpmlIFXZO33gToElEwe6vVICvm8T8XRVWyIS+6anFQGhTw9zglYuk5ttlbQ99s2q8sm4Cs/K65lXoivHursjw0JGXzmUA/O9dfRl6dkn+VCvVhaPoxWgCwRBFpXliU3gyKrvnArjM46TgEcYGq12zPEOivGl87uTwMTcRSjz1NO3xdojGcfIXzv8QvYPU31fQlH15nE3XcogIAFBTgSFkNYfHcSaWqOPkFgPnDqeC9UGnlfaIJxRA7QRRsSlg==",
                        "EnableLevel": "${GlobalEnableLevel}",
                        "EnablePassword": "SWEN__nGOyEahwRPXtuAbwzzLiMaxouq7qnwhnUvRPx0aKQ0M3R/VSq8RvN2qdVtr+Yh1sMisLRL/oFWdK19X+B3twaSuKaEmm3cTbjj9jH5R1oNN2hN0njA8dFPKZkkqgy7RhVO7OTs4FQJAobcPZrMMzN5YZJRjieY8m+DaUMxYVF2tyW3wWG4y17Gjmk0VQXqH50dWM2LRyXwb0WHR8cNud46vaDqS3DDCXO3J8fyc77c8YMtaVlm80/kJWVfUQAukGhrMQ00XFn2Ytqj2wmC5tz6Td+/Ij98+wcKuwrawphBM1QiuPs4rH8X4hA8ghj+p/e/rEcRWd+upCGf3irZDcEw==",
                        "DeviceTemplate": "Cisco Catalyst CatOS",
                        "ExecProtocol": "${GlobalExecProtocol}",
                        "CommandProtocol": "${GlobalConfigRequestProtocol}",
                        "TransferProtocol": "${GlobalConfigTransferProtocol}",
                        "LoginSatatus": "",
                        "UseHTTPS": false,
                        "LastInventory": "1899-12-30T00:00:00",
                        "TelnetPort": "${GlobalTelnetPort}",
                        "SSHPort": "${GlobalSSHPort}",
                        "AllowIntermediary": false,
                        "UseKeybInteractiveAuth": false,
                        "ConnectionProfile": -1,
                        "EndOfSupport": null,
                        "EndOfSales": null,
                        "EndOfSoftware": null,
                        "EosEntryID": null,
                        "EosType": 0,
                        "EosMatchDate": null,
                        "EosVersion": null,
                        "EosLink": null,
                        "EosComments": null,
                        "PartNumber": null,
                        "ReplacementPartNumber": null
                      }
                      

                       

                      Those long strings that start with "SWEN__" are encrypted.

                       

                      The important thing to know about UpdateNode is that it will overwrite all properties. You can't just send the subset of properties you want to update (i.e., only NodeID and DeviceTemplate). You have to fetch the current properties using another verb, Cirrus.Nodes.GetNode, change what you want to change, and then send that to UpdateNode. Like this:

                       

                      import requests
                      from orionsdk import SwisClient
                      
                      def main():
                          ncm_server = 'localhost'
                          username = 'admin'
                          password = ''
                      
                          swis = SwisClient(ncm_server, username, password)
                      
                          # Orion NodeID
                          nodeID = 2
                      
                          # Lookup the NCM NodeID, which is a Guid
                          ncmNodeID = swis.query('SELECT NodeID FROM Cirrus.Nodes WHERE CoreNodeID=@node', node=nodeID)['results'][0]['NodeID']
                      
                          # Fetch the NCM Node object
                          ncmNode = swis.invoke('Cirrus.Nodes', 'GetNode', ncmNodeID)
                      
                          # Modify our local copy of the NCM Node object
                          ncmNode['DeviceTemplate'] = 'Auto Determine'
                      
                          # Commit our changes
                          swis.invoke('Cirrus.Nodes', 'UpdateNode', ncmNode)
                      
                      requests.packages.urllib3.disable_warnings()
                      
                      if __name__ == '__main__':
                          main()
                      
                        • Re: Unable to query node for NCM properties
                          davidvarnum

                          This is extraordinarily helpful, and is precisely what I was looking for.  Thank you!

                          • Re: Unable to query node for NCM properties
                            clarv02

                            Hopefully I'm not off base here, but it seems things may have changed a bit since this last post. I've recently figured out how to assign NCM Connection Profiles (thanks to tdanner) and now I'm working on assigning Device Templates. And we're successfully doing both via swis.update. Copying what davidvarnum has above, I'm using basically the same command in Python and this would work:

                             

                            swis.update('swis://orion/Orion/Orion.Nodes/NodeID=7500/NodeProperties', DeviceTemplate='3Com')

                             

                            We query the Uri from Cirrus.Nodes and create a variable, then pass it to swis.update. So it looks more like this:

                             

                            swis.update(uri, ConnectionProfile = 2)

                            swis.update(uri, DeviceTemplate= 'device template name')

                             

                            Hopefully this is helpful to anyone out there trying to do this.

                            1 of 1 people found this helpful