Skip to content

Implement deregistration functionality for resources and VMs#2286

Merged
cb-github-robot merged 9 commits intocloud-barista:mainfrom
leehyeoklee:improve-registration
Jan 26, 2026
Merged

Implement deregistration functionality for resources and VMs#2286
cb-github-robot merged 9 commits intocloud-barista:mainfrom
leehyeoklee:improve-registration

Conversation

@leehyeoklee
Copy link
Copy Markdown
Contributor

Summary

This PR introduces resource deregistration functionality across major resources and significantly improves the validation logic for subnet deletion to prevent accidental data inconsistency.

Key Changes

1. Feature: Resource Deregistration

Implemented Deregister operations for the following resources. This action removes the resource metadata from Spider and Tumblebug while preserving the actual resource on the CSP.

  • Supported Resources:

    • SSH Keys, Security Groups, Data Disks, Custom Images (New Endpoints)
    • VNets, Subnets (Logic implemented on existing endpoints)
  • Implementation Details:

    • Utilizes Spider's deregister APIs (e.g., /regkeypair/{Name}, /regvpc/{Name}) instead of delete APIs.
    • Dependency Cleanup: Invokes ClearDependencyFromVMs to remove references to the deregistered resource from associated VM fields.
  • API Endpoints:

    • DELETE /ns/{nsId}/deregisterCspResource/sshKey/{sshKeyId} (New)
    • DELETE /ns/{nsId}/deregisterCspResource/securityGroup/{securityGroupId} (New)
    • DELETE /ns/{nsId}/deregisterCspResource/dataDisk/{dataDiskId} (New)
    • DELETE /ns/{nsId}/deregisterCspResource/customImage/{customImageId} (New)
    • (Note: Deregistration endpoints for VNet and Subnet already existed; logic has been updated.)

2. Fix: Subnet Deletion/Deregistration Validation

Problem:
Previously, the code checked subnetInfo.Status == NetworkInUse to prevent deleting in-use subnets. However, this status field was never properly set, allowing subnets attached to active VMs to be deleted or deregistered.

	// Todo: Check if the subnet is being used by any resouces, such as virtual machines, gateways, etc.
	// Check if the vNet has subnets or not
	if action == ActionNone && subnetInfo.Status == string(NetworkInUse) {
		err := fmt.Errorf("the subnet (%s) is in-use, may have any resources", subnetId)
		log.Error().Err(err).Msg("")
		return emptyRet, err
	}

Solution:

  • Implemented CheckSubnetInUseByVMs: A new function that scans all VMs in the namespace to verify if the target subnetId is in use.
  • Applied this validation to both DelSubnet and DeregisterSubnet.
  • The API now returns a clear error message listing the VMs currently using the subnet.

Todo:

  • Validation currently checks usage by VMs only. Future updates are needed to check for other resources.

Copy link
Copy Markdown
Member

@seokho-son seokho-son left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @leehyeoklee
I have some opinions for this PR. PTAL. :)

Comment on lines +2670 to +2685
err = common.CheckString(vmId)
if err != nil {
log.Error().Err(err).Msg("")
return err
}
check, _ := CheckVm(nsId, mciId, vmId)

if !check {
err := fmt.Errorf("The vm " + vmId + " does not exist.")
return err
}

log.Debug().Msg("[Deregister VM] " + vmId)

// get vm info
vmInfo, _ := GetVmObject(nsId, mciId, vmId)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetVmObject will validate existence of the VM object too.
So, CheckVm related code can be moved.

and, vmInfo, _ := GetVmObject(nsId, mciId, vmId) needs err handling if we remove CheckVm here.

}
log.Debug().Msg("Deregister request finished from " + url)

// delete vms info from TB
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// delete vms info from TB
// delete the VM info from TB

return err
}
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the logic of this section is complex.

We can refine it more direct way. I guess.

  1. identify the (one) subnet object to be removed before removing vm object.
  2. remove identified subnet just after vm object has been removed.

// Update associated object lists
_, err = resource.UpdateAssociatedObjectList(nsId, model.StrImage, vmInfo.ImageId, model.StrDelete, key)
if err != nil {
resource.UpdateAssociatedObjectList(nsId, model.StrCustomImage, vmInfo.ImageId, model.StrDelete, key)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have additional trial only for image type ? intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the delete method pattern but excluded associatedObjectList as it's not applicable to Images😓

Comment on lines +601 to +623
err := common.CheckString(nsId)
if err != nil {
log.Error().Err(err).Msg("")
return err
}

err = common.CheckString(resourceId)
if err != nil {
log.Error().Err(err).Msg("")
return err
}
check, err := CheckResource(nsId, resourceType, resourceId)

if err != nil {
log.Error().Err(err).Msg("")
return err
}

if !check {
errString := "The " + resourceType + " " + resourceId + " does not exist."
err := fmt.Errorf(errString)
return err
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's reduce duplicated validations. :)

log.Debug().Msg("Image deregistered successfully from database")
return nil

case model.StrCustomImage:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's find an existing function for this operation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced the direct ORM query with the GetResource(nsId, model.StrCustomImage, resourceId) funtion!

url = model.SpiderRestUrl + "/regmyimage/" + temp.CspImageName
uid = temp.Uid

case model.StrSpec:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to remove Specs in general. too

Comment on lines +813 to +825
mciId, vmId, err := parseVMKeyPath(vmKey)
if err != nil {
log.Warn().Err(err).Str("vmKey", vmKey).Msg("Failed to parse VM key")
continue
}

// Get VM object from kvstore
vmStoreKey := common.GenMciKey(nsId, mciId, vmId)
vmKeyValue, exists, err := kvstore.GetKv(vmStoreKey)
if err != nil || !exists {
log.Warn().Msgf("Failed to get VM %s to update fields", vmId)
continue
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to avoid writing codes directly controlling kvstore and the other DBs. I think we have existing functions for this.

log.Debug().Msg("Deregister request finished from " + url)

// Get associated VMs and update their fields to remove references to this resource
err = ClearDependencyFromVMs(nsId, resourceType, resourceId)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we clear Clear Dependency From VMs?
or should we block it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the logic to prevent VM deregistration if any associated resources (SSH Key, Security Group, Data Disk) still exist. The system now checks for these dependencies and blocks the operation if any are found.


// parseVMKeyPath parses a VM key path and extracts mciId and vmId
// Expected format: /ns/{nsId}/mci/{mciId}/vm/{vmId}
func parseVMKeyPath(vmKey string) (mciId string, vmId string, err error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should avoid this pattern.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the sys.securityGroup label to the VM creation/registration logic. This allowed me to remove the previous check by using a label selector to verify VM existence in the subnet instead

@github-actions github-actions bot added the src label Jan 26, 2026
Copy link
Copy Markdown
Member

@seokho-son seokho-son left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! @leehyeoklee thanks!

@seokho-son
Copy link
Copy Markdown
Member

/approve

@github-actions github-actions bot added the approved This PR is approved and will be merged soon. label Jan 26, 2026
@cb-github-robot cb-github-robot merged commit 9286e8a into cloud-barista:main Jan 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved This PR is approved and will be merged soon. src

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants