@@ -65,11 +65,18 @@ func (c *client) IsCapcManaged(resourceType ResourceType, resourceID string) (bo
6565}
6666
6767// AddClusterTag adds cluster tag to a resource. This tag indicates the resource is used by a given the cluster.
68+ // If old cluster tags exist (from previous cluster UIDs), they are removed first to prevent dual-tagging.
6869func (c * client ) AddClusterTag (rType ResourceType , rID string , csCluster * infrav1.CloudStackCluster ) error {
6970 if managedByCAPC , err := c .IsCapcManaged (rType , rID ); err != nil {
7071 return err
7172 } else if managedByCAPC {
7273 ClusterTagName := generateClusterTagName (csCluster )
74+
75+ // Remove old cluster tags before adding new one to prevent dual-tagging during pivot
76+ if err := c .removeOldClusterTags (rType , rID , ClusterTagName ); err != nil {
77+ return errors .Wrapf (err , "removing old cluster tags from %s %s" , rType , rID )
78+ }
79+
7380 return c .AddTags (rType , rID , map [string ]string {ClusterTagName : "1" })
7481 }
7582 return nil
@@ -163,6 +170,32 @@ func (c *client) DeleteTags(resourceType ResourceType, resourceID string, tagsTo
163170 return nil
164171}
165172
173+ // removeOldClusterTags removes any cluster tags that don't match the current cluster UID.
174+ // This prevents dual-tagging when a resource is moved during pivot and gets a new cluster UID.
175+ func (c * client ) removeOldClusterTags (rType ResourceType , rID string , currentClusterTagName string ) error {
176+ tags , err := c .GetTags (rType , rID )
177+ if err != nil {
178+ return errors .Wrapf (err , "getting tags for %s %s" , rType , rID )
179+ }
180+
181+ oldClusterTags := make (map [string ]string )
182+ for tagName , tagValue := range tags {
183+ // Find cluster tags that are NOT the current cluster's tag
184+ if strings .HasPrefix (tagName , ClusterTagNamePrefix ) && tagName != currentClusterTagName {
185+ oldClusterTags [tagName ] = tagValue
186+ }
187+ }
188+
189+ // Delete old cluster tags if any exist
190+ if len (oldClusterTags ) > 0 {
191+ if err := c .DeleteTags (rType , rID , oldClusterTags ); err != nil {
192+ return errors .Wrapf (err , "deleting old cluster tags %v from %s %s" , oldClusterTags , rType , rID )
193+ }
194+ }
195+
196+ return nil
197+ }
198+
166199func generateClusterTagName (csCluster * infrav1.CloudStackCluster ) string {
167200 return ClusterTagNamePrefix + string (csCluster .UID )
168201}
0 commit comments