Cluster configuration update with APIv4 | Nutanix Community
Skip to main content

Cluster configuration update with APIv4

  • April 4, 2025
  • 1 reply
  • 26 views

Forum|alt.badge.img

Hi there

I am trying to patch some settings programmatically, for example the virtual IP of the cluster, but i encounter an interesting issue with the E-Tag mismatch although i am sure it’s right.

Here is my function:

def update_vip(cluster_name, cluster_uuid, old_vip, new_vip, api_credentials, pc_endpoint) -> None:

"""

This function is updating the VIP of the cluster

@param cluster_name[str] -> this parameter is the name of the cluster

@param cluster_uuid[str] -> this parameter is the UUID of the cluster

@param old_vip[str] -> this parameter is the current VIP of the cluster

@param new_vip[str] -> this parameter is the new VIP of the cluster

@param api_credentials[dict] -> this parameter is the API credentials used to connect to the cluster

@param pc_endpoint[str] -> this parameter is the endpoint of the cluster



Returns nothing

"""



viplog.info(f'Updating VIP on cluster {cluster_name}. Old VIP: {old_vip} New VIP: {new_vip}')



# make the API call to get all clusters from PC



config = ntnx_clustermgmt_py_client.Configuration()

# IPv4/IPv6 address or FQDN of the cluster

config.host = pc_endpoint

# Port to which to connect to

config.port = 9440

# Max retry attempts while reconnecting on a loss of connection

config.max_retry_attempts = 3

# Backoff factor to use during retry attempts

config.backoff_factor = 3

# UserName to connect to the cluster

config.username = api_credentials['username']

# Password to connect to the cluster

config.password = api_credentials['password']

# Please add authorization information here if needed.

client = ntnx_clustermgmt_py_client.ApiClient(configuration=config)

clusters_api = ntnx_clustermgmt_py_client.ClustersApi(api_client=client)



# get the cluster object so that we can extract the E-Tag header

max_retries = 3

for attempt in range(max_retries):

try:

api_response = clusters_api.get_cluster_by_id(extId=cluster_uuid)

break

except ntnx_clustermgmt_py_client.rest.ApiException as e:

if attempt < max_retries - 1:

continue

else:

raise ValueError(f'ERROR getting the cluster {cluster_name} from PC {pc_endpoint} during E-Tag extraction: {e}')



# Extract E-Tag Header

etag_value = ntnx_clustermgmt_py_client.ApiClient.get_etag(api_response)

cluster = api_response.data

# assign the new VIP to the cluster object

cluster.network.external_address.ipv4.value = new_vip



# update the cluster

max_retries = 3

for attempt in range(max_retries):

try:

api_response = clusters_api.update_cluster_by_id(extId=cluster_uuid, body=cluster, if_match=etag_value)

break

except ntnx_clustermgmt_py_client.rest.ApiException as e:

if attempt < max_retries - 1:

continue

else:

raise ValueError(f'ERROR updating cluster {cluster_name} configuration: {e}')



# Extract E-Tag Header

etag_value = ntnx_clustermgmt_py_client.ApiClient.get_etag(api_response)

 

In the API reference, they suggest the following piece of code for packing the cluster configuration:

cluster = ntnx_clustermgmt_py_client.Cluster()    
# Cluster object initializations here...    

 

However, since I already have my cluster and i only want to change a little piece of configuration, i prefer to pack my cluster config using the existing config, with

cluster = api_response.data

 

and then patch the parameter i want to patch with the new value

# assign the new VIP to the cluster object

cluster.network.external_address.ipv4.value = new_vip

 

then of course, submit the modified configuration

api_response = clusters_api.update_cluster_by_id(extId=cluster_uuid, body=cluster, if_match=etag_value)

 

However, since this is not the recommended approach, i am wondering if the Etag error i get is actually just a bad error handling by NTX APIs but it might be that i do not submit the cluster configuration correctly.

Here is the error: 

Error Status: 412

'{"data":{"error":[{"$reserved":{"$fv":"v4.r0"},"$objectType":"clustermgmt.v4.error.AppMessage","message":"Failed to perform the operation because Etag provided doesn\'t match.","severity":"ERROR","code":"CLU-10004","locale":"en_US","errorGroup":"CLUSTERMGMT_INVALID_INPUT"}],"$reserved":{"$fv":"v4.r0"},"$objectType":"clustermgmt.v4.error.ErrorResponse"},"$reserved":{"$fv":"v4.r0"},"$objectType":"clustermgmt.v4.config.UpdateClusterApiResponse"}'

 

What am i missing here? Do i really have to create the cluster config with cluster = ntnx_clustermgmt_py_client.Cluster() then pack all the config inside?… that would be pitty.
Also, before i was doing this with PATCH on APIv2, but there is no PATCH in APIv4 yet.

1 reply

Forum|alt.badge.img

i’ve decided to give a try and pack the configuration on a newly created cluster object with this piece of code:   
 

# create a new cluster object
cluster = ntnx_clustermgmt_py_client.Cluster()

# Copy attributes dynamically
for attribute in api_response.data.attribute_map:
    if attribute in ['_reserved', '_object_type', '_unknown_fields']:
        continue
    setattr(cluster, attribute, getattr(api_response.data, attribute))

# assign the new VIP to the cluster object
cluster.network.external_address.ipv4.value = new_vip


But unfortunately that still returns the same invalid E-Tag error.


Reply