cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
705
Views
10
Helpful
2
Replies

ISE API Update Best Practice?

777GE90
Level 1
Level 1

I'm using the ISE API and looking at the documentation for UPDATE queries, I see that the best practice is to try and send "full objects".  Currently, I am using the InternalUser endpoint and first I am getting back the full details of a specific user, see example response below:

 

{
  "InternalUser": {
    "id": "26acf076-3010-4224-827e-a46ebba9a9a2",
    "name": "namevalue",
    "description": "some descriptioin",
    "enabled": true,
    "password": "*******",
    "firstName": "firstname",
    "lastName": "surname",
    "changePassword": false,
    "identityGroups": "26acf076-3010-4224-827e-a46ebba9a9a2",
    "expiryDateEnabled": false,
    "enablePassword": "*******",
    "passwordIDStore": "AD1",
    "link": {
      "rel": "self",
      "href": "https://host:port/ers/config/internaluser/26acf076-3010-4224-827e-a46ebba9a9a2",
      "type": "application/json"
    }
  }
}

I then take this entire object and modify one field, like "firstName" to something new like "test".  Then I send an UPDATE request with that entire updated object as the body / payload.  The problem I get is that an error is returned saying:

Validation Error - External Identity Store Users update is not supported for attribute: changePassword. Please remove it from the request body.

So my problem is that taking the full object and modifying it simply will not work in this case, I can delete the "changePassword" field in my code, but how do I know in the future a new field won't be added that would cause a similar error?  So instead, I decided to modify my query and only include bits I want to update in it (rather than the full information).  So my new UPDATE request payload now looks like:

{
  "InternalUser": {
    "id": "26acf076-3010-4224-827e-a46ebba9a9a2",
    "name": "namevalue",
    "firstName": "test",
    "passwordIDStore": "AD1"
  }
}

Now this works fine for me as I have tested and made sure it includes the minimum mandatory fields.  I think this is the best way for me to update the internal user data, however it appears it is against the recommended practice, which does not appear to work for me.

So my question is, does anyone see any issue with me updating the user like this (i.e. only providing mandatory fields and the fields I need to update)? Would this approach result in other values that are not included in the request to be overwritten by accident or is there any other risk? Or is this approach perfectly acceptable providing I have the mandatory fields?

 

1 Accepted Solution

Accepted Solutions

Johannes Luther
Level 4
Level 4

Good question and very poorly documented.

So, the SDK documentation is very vague in this regard:

>> Best Practice for update is to use Object generated from the schema and send full objects, however partial update is supported in some cases

 

So, here's a non working example. Given is the following network device (data from the Get-by-Id operation):

Note: I omitted the "link" attribute. All other data is pure lab and play data .. so no "do not post secrets" nagging :)

{
  "NetworkDevice": {
    "id": "13db83b0-3d2c-11ea-8848-0050568b5bee",
    "name": "myDevice_123",
    "description": "myDescription",
    "authenticationSettings": {
      "networkProtocol": "RADIUS",
      "radiusSharedSecret": "mySecret",
      "enableKeyWrap": false,
      "dtlsRequired": false,
      "keyInputFormat": "ASCII",
      "enableMultiSecret": "false"
    },
    "profileName": "Cisco",
    "coaPort": 0,
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ],
    "NetworkDeviceGroupList": [
      "Location#All Locations#EMEA#G1roup name",
      "Device Type#All Device Types#DCNM",
      "IPSEC#Is IPSEC Device"
    ]
  }
}

I just want to change the description. I found out by try and error, that some attributes (like NetworkIpList) are mandatory, so I added all of them along as the PUT body:

{
  "NetworkDevice": {
    "name": "myDevice_123",
    "description": "new description",
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ]
  }
}

I get a HTTP 200 (OK) as the PUT result, along with following response body:

{
  "UpdatedFieldsList" : {
    "updatedField" : [ {
      "field" : "Description",
      "oldValue" : "{\"description\":\"myDescription\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}",
      "newValue" : "{\"description\":\"new description\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}"
    }, {
      "field" : "NetworkDeviceGroupList",
      "oldValue" : "item removed: Name:Location#All Locations#EMEA#G1roup name ,Type:Location, NSF REF: a111f180-3c1c-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "oldValue" : "item removed: Name:Device Type#All Device Types#DCNM ,Type:Device Type, NSF REF: 7806bdc0-3c1c-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:BlaFasel#Test123 ,Type:BlaFasel, NSF REF: c46e6270-3da8-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Bla#Bla ,Type:Bla, NSF REF: eb377c20-3dad-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Device Type#All Device Types ,Type:Device Type, NSF REF: 70c79c30-8bff-11e6-996c-525400b48521"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Location#All Locations ,Type:Location, NSF REF: 70836740-8bff-11e6-996c-525400b48521"
    } ]
  }
}

Hmmmm I tought I did a single change (description) - however there are more results :(

So, let's do a Get-by-Id again ... I post a picture now to highlight the differences:

 

grafik.png

 

So obviously the description changed.

However, the network device group of the type location and device type were set to a value. After the PUT operation they are in the default group.

 

Funny thing: After I created the network device initially I added two network device group ROOT elements (Bla and BlaFasel). I never assigned the network device to those groups ... after the PUT operation, the groups are set ... strange.

 

 

So, let's revert to the initial state and send the NetworkDeviceGroupList along:

{
  "NetworkDevice": {
    "name": "myDevice_123",
    "description": "new description",
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ],
    "NetworkDeviceGroupList": [
      "Location#All Locations#EMEA#G1roup name",
      "Device Type#All Device Types#DCNM",
      "IPSEC#Is IPSEC Device",
      "Functional Group#Functional Group"
    ]
  }
}

The PUT body looks better now:

{
  "UpdatedFieldsList" : {
    "updatedField" : [ {
      "field" : "Description",
      "oldValue" : "{\"description\":\"myDescription\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}",
      "newValue" : "{\"description\":\"new description\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}"
    } ]
  }
}

Small hint: Don't trust the PUT body (updatedFieldsList). For example in the network device groups the updatedFieldList is always empty, altough there were changes (resourceVersion 1.1 of the network device groups)

 

Hope that helps!

View solution in original post

2 Replies 2

Johannes Luther
Level 4
Level 4

Good question and very poorly documented.

So, the SDK documentation is very vague in this regard:

>> Best Practice for update is to use Object generated from the schema and send full objects, however partial update is supported in some cases

 

So, here's a non working example. Given is the following network device (data from the Get-by-Id operation):

Note: I omitted the "link" attribute. All other data is pure lab and play data .. so no "do not post secrets" nagging :)

{
  "NetworkDevice": {
    "id": "13db83b0-3d2c-11ea-8848-0050568b5bee",
    "name": "myDevice_123",
    "description": "myDescription",
    "authenticationSettings": {
      "networkProtocol": "RADIUS",
      "radiusSharedSecret": "mySecret",
      "enableKeyWrap": false,
      "dtlsRequired": false,
      "keyInputFormat": "ASCII",
      "enableMultiSecret": "false"
    },
    "profileName": "Cisco",
    "coaPort": 0,
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ],
    "NetworkDeviceGroupList": [
      "Location#All Locations#EMEA#G1roup name",
      "Device Type#All Device Types#DCNM",
      "IPSEC#Is IPSEC Device"
    ]
  }
}

I just want to change the description. I found out by try and error, that some attributes (like NetworkIpList) are mandatory, so I added all of them along as the PUT body:

{
  "NetworkDevice": {
    "name": "myDevice_123",
    "description": "new description",
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ]
  }
}

I get a HTTP 200 (OK) as the PUT result, along with following response body:

{
  "UpdatedFieldsList" : {
    "updatedField" : [ {
      "field" : "Description",
      "oldValue" : "{\"description\":\"myDescription\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}",
      "newValue" : "{\"description\":\"new description\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}"
    }, {
      "field" : "NetworkDeviceGroupList",
      "oldValue" : "item removed: Name:Location#All Locations#EMEA#G1roup name ,Type:Location, NSF REF: a111f180-3c1c-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "oldValue" : "item removed: Name:Device Type#All Device Types#DCNM ,Type:Device Type, NSF REF: 7806bdc0-3c1c-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:BlaFasel#Test123 ,Type:BlaFasel, NSF REF: c46e6270-3da8-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Bla#Bla ,Type:Bla, NSF REF: eb377c20-3dad-11ea-8848-0050568b5bee"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Device Type#All Device Types ,Type:Device Type, NSF REF: 70c79c30-8bff-11e6-996c-525400b48521"
    }, {
      "field" : "NetworkDeviceGroupList",
      "newValue" : "item added: Name:Location#All Locations ,Type:Location, NSF REF: 70836740-8bff-11e6-996c-525400b48521"
    } ]
  }
}

Hmmmm I tought I did a single change (description) - however there are more results :(

So, let's do a Get-by-Id again ... I post a picture now to highlight the differences:

 

grafik.png

 

So obviously the description changed.

However, the network device group of the type location and device type were set to a value. After the PUT operation they are in the default group.

 

Funny thing: After I created the network device initially I added two network device group ROOT elements (Bla and BlaFasel). I never assigned the network device to those groups ... after the PUT operation, the groups are set ... strange.

 

 

So, let's revert to the initial state and send the NetworkDeviceGroupList along:

{
  "NetworkDevice": {
    "name": "myDevice_123",
    "description": "new description",
    "NetworkDeviceIPList": [
      {
        "ipaddress": "172.16.255.1",
        "mask": 32
      }
    ],
    "NetworkDeviceGroupList": [
      "Location#All Locations#EMEA#G1roup name",
      "Device Type#All Device Types#DCNM",
      "IPSEC#Is IPSEC Device",
      "Functional Group#Functional Group"
    ]
  }
}

The PUT body looks better now:

{
  "UpdatedFieldsList" : {
    "updatedField" : [ {
      "field" : "Description",
      "oldValue" : "{\"description\":\"myDescription\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}",
      "newValue" : "{\"description\":\"new description\",\"secondRadiusSharedSecret\":\"\",\"enableMultiSecret\":\"false\"}"
    } ]
  }
}

Small hint: Don't trust the PUT body (updatedFieldsList). For example in the network device groups the updatedFieldList is always empty, altough there were changes (resourceVersion 1.1 of the network device groups)

 

Hope that helps!

Wow! that's not good.

 

For a moment I thought I could rely on the updateFieldList to view what it changed and verify if it's what I expected to change, but if I can't even do that then that is unfortunate.

 

I guess I will have to provide the full set of fields minus the ones it moans about and hope it doesn't start moaning about new fields when our ISE instance is upgraded.

 

Out of interest, what do you think about supplying the password field? For example the password is shown as "******", do I just give it back "password": "*******"? Haven't tried it yet, but curious if needs that or not.
EDIT: Nevermind about the password, the API moans about that too, so just going to remove it from my request.  Thanks for your response, this is helpful, sending as full as possible requests is my only safe option then.