Public/System/Remove-VergeTagMember.ps1
|
function Remove-VergeTagMember { <# .SYNOPSIS Removes a tag assignment from a resource in VergeOS. .DESCRIPTION Remove-VergeTagMember removes a tag from a resource such as a VM, network, or tenant. This cmdlet supports multiple ways to identify the tag assignment to remove: by key, by tag member object, or by specifying the tag and resource. .PARAMETER Key The unique key (ID) of the tag member assignment to remove. .PARAMETER TagMember A tag member object from Get-VergeTagMember. Accepts pipeline input. .PARAMETER Tag The tag to remove. Used with VM, Network, Tenant, or ResourceType parameters. .PARAMETER VM The VM to remove the tag from. Accepts a VM name, key, or Verge.VM object. .PARAMETER Network The network to remove the tag from. Accepts a network name, key, or Verge.Network object. .PARAMETER Tenant The tenant to remove the tag from. Accepts a tenant name, key, or Verge.Tenant object. .PARAMETER ResourceType The type of resource when using ResourceKey parameter. .PARAMETER ResourceKey The key (ID) of the resource. Must be used with ResourceType. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Remove-VergeTagMember -Key 1 Removes the tag member assignment with key 1. .EXAMPLE Get-VergeTagMember -Tag "Production" | Remove-VergeTagMember Removes all tag assignments for the "Production" tag. .EXAMPLE Remove-VergeTagMember -Tag "Production" -VM "WebServer01" Removes the "Production" tag from the specified VM. .EXAMPLE Get-VergeVM -Name "Dev-*" | ForEach-Object { Remove-VergeTagMember -Tag "Production" -VM $_ } Removes the "Production" tag from all VMs matching "Dev-*". .OUTPUTS None .NOTES Use Get-VergeTagMember to list existing tag assignments. Use Add-VergeTagMember to assign tags to resources. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'ByKey')] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByKey')] [int]$Key, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTagMember')] [PSTypeName('Verge.TagMember')] [PSCustomObject]$TagMember, [Parameter(Mandatory, ParameterSetName = 'ByTagAndVM')] [Parameter(Mandatory, ParameterSetName = 'ByTagAndNetwork')] [Parameter(Mandatory, ParameterSetName = 'ByTagAndTenant')] [Parameter(Mandatory, ParameterSetName = 'ByTagAndGeneric')] [object]$Tag, [Parameter(Mandatory, ParameterSetName = 'ByTagAndVM')] [object]$VM, [Parameter(Mandatory, ParameterSetName = 'ByTagAndNetwork')] [Alias('VNet')] [object]$Network, [Parameter(Mandatory, ParameterSetName = 'ByTagAndTenant')] [object]$Tenant, [Parameter(Mandatory, ParameterSetName = 'ByTagAndGeneric')] [ValidateSet('vms', 'vnets', 'volumes', 'tenants', 'users', 'groups', 'nodes', 'clusters', 'sites', 'vnet_rules', 'vmware_containers', 'tenant_nodes')] [string]$ResourceType, [Parameter(Mandatory, ParameterSetName = 'ByTagAndGeneric')] [int]$ResourceKey, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } } process { $memberKey = $null $displayName = $null switch -Wildcard ($PSCmdlet.ParameterSetName) { 'ByKey' { $memberKey = $Key $displayName = "Tag member $Key" } 'ByTagMember' { $memberKey = $TagMember.Key $displayName = "Tag '$($TagMember.TagName)' from $($TagMember.ResourceRef)" } 'ByTagAnd*' { # Resolve tag $tagKey = $null $tagName = $null if ($Tag.PSObject.TypeNames -contains 'Verge.Tag') { $tagKey = $Tag.Key $tagName = $Tag.Name } elseif ($Tag -is [int]) { $tagKey = $Tag $foundTag = Get-VergeTag -Key $tagKey -Server $Server $tagName = if ($foundTag) { $foundTag.Name } else { "Tag $tagKey" } } elseif ($Tag -is [string]) { if ($Tag -match '^\d+$') { $tagKey = [int]$Tag $foundTag = Get-VergeTag -Key $tagKey -Server $Server $tagName = if ($foundTag) { $foundTag.Name } else { "Tag $tagKey" } } else { $foundTag = Get-VergeTag -Name $Tag -Server $Server | Select-Object -First 1 if ($foundTag) { $tagKey = $foundTag.Key $tagName = $foundTag.Name } } } if (-not $tagKey) { Write-Error -Message "Tag '$Tag' not found" -ErrorId 'TagNotFound' -Category ObjectNotFound return } # Resolve member reference $memberRef = $null $resourceName = $null switch ($PSCmdlet.ParameterSetName) { 'ByTagAndVM' { if ($VM.PSObject.TypeNames -contains 'Verge.VM') { $memberRef = "vms/$($VM.Key)" $resourceName = $VM.Name } elseif ($VM -is [int]) { $memberRef = "vms/$VM" $existingVM = Get-VergeVM -Key $VM -Server $Server -ErrorAction SilentlyContinue $resourceName = if ($existingVM) { $existingVM.Name } else { "VM $VM" } } elseif ($VM -is [string]) { $existingVM = Get-VergeVM -Name $VM -Server $Server -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existingVM) { $memberRef = "vms/$($existingVM.Key)" $resourceName = $existingVM.Name } else { Write-Error -Message "VM not found: $VM" -ErrorId 'VMNotFound' -Category ObjectNotFound return } } } 'ByTagAndNetwork' { if ($Network.PSObject.TypeNames -contains 'Verge.Network') { $memberRef = "vnets/$($Network.Key)" $resourceName = $Network.Name } elseif ($Network -is [int]) { $memberRef = "vnets/$Network" $existingNetwork = Get-VergeNetwork -Key $Network -Server $Server -ErrorAction SilentlyContinue $resourceName = if ($existingNetwork) { $existingNetwork.Name } else { "Network $Network" } } elseif ($Network -is [string]) { $existingNetwork = Get-VergeNetwork -Name $Network -Server $Server -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existingNetwork) { $memberRef = "vnets/$($existingNetwork.Key)" $resourceName = $existingNetwork.Name } else { Write-Error -Message "Network not found: $Network" -ErrorId 'NetworkNotFound' -Category ObjectNotFound return } } } 'ByTagAndTenant' { if ($Tenant.PSObject.TypeNames -contains 'Verge.Tenant') { $memberRef = "tenants/$($Tenant.Key)" $resourceName = $Tenant.Name } elseif ($Tenant -is [int]) { $memberRef = "tenants/$Tenant" $existingTenant = Get-VergeTenant -Key $Tenant -Server $Server -ErrorAction SilentlyContinue $resourceName = if ($existingTenant) { $existingTenant.Name } else { "Tenant $Tenant" } } elseif ($Tenant -is [string]) { $existingTenant = Get-VergeTenant -Name $Tenant -Server $Server -ErrorAction SilentlyContinue | Select-Object -First 1 if ($existingTenant) { $memberRef = "tenants/$($existingTenant.Key)" $resourceName = $existingTenant.Name } else { Write-Error -Message "Tenant not found: $Tenant" -ErrorId 'TenantNotFound' -Category ObjectNotFound return } } } 'ByTagAndGeneric' { $memberRef = "$ResourceType/$ResourceKey" $resourceName = "$ResourceType/$ResourceKey" } } if (-not $memberRef) { Write-Error -Message "Could not resolve resource reference" -ErrorId 'ResourceNotResolved' -Category InvalidArgument return } # Find the tag member by tag and member reference $existingMembers = Get-VergeTagMember -Tag $tagKey -Server $Server | Where-Object { $_.ResourceRef -eq $memberRef } if (-not $existingMembers -or $existingMembers.Count -eq 0) { Write-Warning "Tag '$tagName' is not assigned to '$resourceName'" return } $memberKey = $existingMembers[0].Key $displayName = "Tag '$tagName' from '$resourceName'" } } if (-not $memberKey) { Write-Error -Message "Could not determine tag member to remove" -ErrorId 'TagMemberNotFound' -Category ObjectNotFound return } if ($PSCmdlet.ShouldProcess($displayName, 'Remove Tag Assignment')) { try { Write-Verbose "Removing tag assignment (Key: $memberKey)" Invoke-VergeAPI -Method DELETE -Endpoint "tag_members/$memberKey" -Connection $Server | Out-Null Write-Verbose "Tag assignment removed successfully" } catch { $errorMessage = $_.Exception.Message if ($errorMessage -match 'not found') { Write-Warning "Tag assignment not found (may have already been removed)" } else { Write-Error -Message "Failed to remove tag assignment: $errorMessage" -ErrorId 'TagMemberDeleteFailed' } } } } } |