I have a case where I'm attempting to update the same custom property across several business groups to a new value. However, when I use the vCACCAFESubtenantHelper.updateCustomProperty function, it silently fails to update the subtenant property with the new value. It definitely gets to that call, and my logging statements all look as I'd expect. Here is my code:
# The host, productCodePropName, and whatIf variables are static attributes or input parameters
var detectHyphenBetweenCodeAndDescriptionWithWhitespaceRegex = /(?!^\d{4})\s*-\s*/;
var subtenants = vCACCAFEEntitiesFinder.getSubtenants( host );
for( var s in subtenants ){
var subtenant = subtenants[s];
System.log( "Evaluating ProductCode for " + subtenant.name );
var productCode = null;
try{
productCode = vCACCAFESubtenantHelper.getCustomPropertyValue( subtenant, productCodePropName );
} catch ( e ){
if( /java\.lang\.NullPointerException/.test( e ) ){
System.error( productCodePropName + " does not exist for subtenant " + subtenant.name + ", skipping." );
} else {
throw e;
};
};
if( productCode ){
System.log( "\tOld ProductCode: " + productCode );
productCode = productCode.replace( detectHyphenBetweenCodeAndDescriptionWithWhitespaceRegex, '-' ).toUpperCase();
System.log( "\tNew ProductCode: " + productCode );
if( !whatIf ) {
System.warn( "\tUpdating subtenant to use the new ProductCode" );
var isRuntime = vCACCAFESubtenantHelper.isCustomPropertyPromptUser( subtenant, productCodePropName );
System.debug( "\t\tisRuntime: " + isRuntime );
var isEncrypted = vCACCAFESubtenantHelper.isCustomPropertyEncrypted( subtenant, productCodePropName );
System.debug( "\t\tisEncrypted: " + isEncrypted );
vCACCAFESubtenantHelper.updateCustomProperty( subtenant, productCodePropName, productCodePropName, productCode, isEncrypted, isRuntime );
};
};
};
When I look at the Inventory tab of vRO and navigate to the business group, the property is not updated (buried in that literal map string). Checking the business group on the vRA side also shows that the custom property on the business groups has not been updated. Am I doing something incorrectly here?
Have you got any examples of the logging you can share here?
Also, it would be interesting to see what value you get for the property immediately after the update, e.g,
vCACCAFESubtenantHelper.updateCustomProperty( subtenant, productCodePropName, productCodePropName, productCode, isEncrypted, isRuntime );
// now reload immediately
var reloadedProductCode = vCACCAFESubtenantHelper.getCustomPropertyValue( subtenant, productCodePropName );
System.log("reloaded property value is " + reloadedProductCode);
Lastly, if you think the update is suspect, then perhaps try remove the property and then re-add it? From the parameters list on the update method (i.e., (..., oldname, newName, ...) ) it looks like the update might be a wrapper for the same thing?
HTH
Sure, here's the output from one subtenant:
[2019-01-14 13:34:51.492] [I] Evaluating ProductCode for Chef Automation Toolkit
[2019-01-14 13:34:51.493] [I] Old ProductCode: 0000 - Infrastructure
[2019-01-14 13:34:51.495] [I] New ProductCode: 0000-INFRASTRUCTURE
[2019-01-14 13:34:51.496] [W] Updating subtenant to use the new ProductCode
[2019-01-14 13:34:51.497] [D] isRuntime: false
[2019-01-14 13:34:51.498] [D] isEncrypted: false
I've run this several times one after another and get the same output, but if it were updating the Old ProductCode output should match the New ProductCode output for the previous run. I'll try removing and adding the property by hand and see if that makes a difference at all.
Ahem.... Note to self - RTFM
So, looks like you use the helper to update the Subtenant as each of the CRUD methods returns a new copy of the object!
The you use the Service to write the new copy Subtenant back to the system!
Yeah, I see that now on the scripting object itself in the API explorer. I'll see if I can't get this working using the vCACCAFEAuthenticationSubtenantService scripting class. I just don't understand what the purpose of vCACCAFESubtenantHelper.updateCustomProperty is if it doesn't save by design.
EDIT: You replied too fast and I posted this before I saw how it works. That makes sense I suppose, to write back the modified subtenant object to vRA.
Agreed - thought it looks to be in order to help with setting the property attributes correctly (Runtime, Encrypted, etc).
Wonder if it contains the code to Encrypt the property value if you set it as Encrypted = true...?
Anyway, hope you get sorted
I'll give this a shot and if it works, I'll mark your answer as the correct one. Thanks again!
Alright, after pulling out just a bit more hair, I found that you have to create the authentication client using the vCACHost object. I split this across the schema, but basically if it's determined that a subtenant needs to be updated, I add them into an array called subtenantsToUpdate and pass that into another Scriptable Task that looks like this:
var client = host.createAuthenticationClient();
var subtenantService = client.getAuthenticationSubtenantService();
for( var s in subtenantsToUpdate ){
var subtenant = subtenantsToUpdate[s];
System.warn( "Pushing updates for subtenant" + subtenant.name );
subtenantService.updateSubtenant( subtenant.tenant, subtenant );
};
This worked and pushed the updated subtenant object back to vRA. Thanks again for the assistance!