@@ -128,16 +128,24 @@ func (opsync *operationRevokeCredentials) SynchronizeOperation(ctx context.Conte
128128 // replace fails we'll just retry later since the operation status
129129 // will remain non-terminal.
130130
131- logger .Info ("clearing RevokeCredentialsOperationID from cluster" )
132131 dbClient := opsync .cosmosClient .HCPClusters (oldOperation .ExternalID .SubscriptionID , oldOperation .ExternalID .ResourceGroupName )
133132 cluster , err := dbClient .Get (ctx , oldOperation .ExternalID .Name )
134133 if err != nil {
135134 return utils .TrackError (err )
136135 }
137- cluster .ServiceProviderProperties .RevokeCredentialsOperationID = ""
138- _ , err = dbClient .Replace (ctx , cluster , nil )
139- if err != nil {
140- return utils .TrackError (err )
136+
137+ // If the controller successfully clears the RevokeCredentialsOperationID field
138+ // in the cluster document but fails to update the operation document, then the
139+ // frontend is free to start a new RevokeCredentials operation, and may well do
140+ // so before the failed operation update is retried. Account for this by making
141+ // sure the field value still matches this operation's ID before clearing it.
142+ if cluster .ServiceProviderProperties .RevokeCredentialsOperationID == oldOperation .OperationID .Name {
143+ logger .Info ("clearing RevokeCredentialsOperationID from cluster" )
144+ cluster .ServiceProviderProperties .RevokeCredentialsOperationID = ""
145+ _ , err = dbClient .Replace (ctx , cluster , nil )
146+ if err != nil {
147+ return utils .TrackError (err )
148+ }
141149 }
142150
143151 logger .Info ("updating status" )
0 commit comments