diff --git a/docs/commands/vpc-gw.md b/docs/commands/vpc-gw.md index e3a15b131d..a7984172ac 100644 --- a/docs/commands/vpc-gw.md +++ b/docs/commands/vpc-gw.md @@ -366,7 +366,7 @@ scw vpc-gw gateway delete [arg=value ...] | Name | | Description | |------|---|-------------| | gateway-id | Required | ID of the gateway to delete | -| delete-ip | | Defines whether the PGW's IP should be deleted | +| with-ip | Default: `prompt`
One of: `prompt`, `true`, `false` | Delete the IP attached to the gateway | | zone | Default: `fr-par-1`
One of: `fr-par-1`, `fr-par-2`, `nl-ams-1`, `nl-ams-2`, `nl-ams-3`, `pl-waw-1`, `pl-waw-2`, `pl-waw-3` | Zone to target. If none is passed will use default zone from the config | diff --git a/internal/namespaces/vpcgw/v2/custom.go b/internal/namespaces/vpcgw/v2/custom.go index 0339834ed1..a7eab35480 100644 --- a/internal/namespaces/vpcgw/v2/custom.go +++ b/internal/namespaces/vpcgw/v2/custom.go @@ -30,6 +30,7 @@ func GetCommands() *core.Commands { cmds.MustFind("vpc-gw", "gateway-type", "list").Override(vpcgwGatewayTypeListBuilder) cmds.MustFind("vpc-gw", "gateway", "create").Override(gatewayCreateBuilder) + cmds.MustFind("vpc-gw", "gateway", "delete").Override(gatewayDeleteBuilder) cmds.MustFind("vpc-gw", "gateway-network", "create").Override(gatewayNetworkCreateBuilder) cmds.MustFind("vpc-gw", "gateway-network", "delete").Override(gatewayNetworkDeleteBuilder) diff --git a/internal/namespaces/vpcgw/v2/custom_gateway.go b/internal/namespaces/vpcgw/v2/custom_gateway.go index e80165d528..9979ecd0fe 100644 --- a/internal/namespaces/vpcgw/v2/custom_gateway.go +++ b/internal/namespaces/vpcgw/v2/custom_gateway.go @@ -2,11 +2,13 @@ package vpcgw import ( "context" + "reflect" "time" "github.com/fatih/color" "github.com/scaleway/scaleway-cli/v2/core" "github.com/scaleway/scaleway-cli/v2/core/human" + "github.com/scaleway/scaleway-cli/v2/internal/interactive" "github.com/scaleway/scaleway-sdk-go/api/vpcgw/v2" "github.com/scaleway/scaleway-sdk-go/scw" ) @@ -63,3 +65,106 @@ func gatewayMarshalerFunc(i any, opt *human.MarshalOpt) (string, error) { return str, nil } + +// Custom delete gateway command with interactive IP deletion confirmation +type customDeleteGatewayRequest struct { + Zone scw.Zone + GatewayID string + DeleteIP bool + WithIP string // "prompt", "true", "false" +} + +const ( + withIPPrompt = "prompt" + withIPTrue = "true" + withIPFalse = "false" +) + +func gatewayDeleteBuilder(c *core.Command) *core.Command { + c.ArgsType = reflect.TypeOf(customDeleteGatewayRequest{}) + c.ArgSpecs = core.ArgSpecs{ + { + Name: "gateway-id", + Short: "ID of the gateway to delete", + Required: true, + Positional: true, + }, + { + Name: "with-ip", + Short: "Delete the IP attached to the gateway", + Default: core.DefaultValueSetter(withIPPrompt), + EnumValues: []string{ + withIPPrompt, + withIPTrue, + withIPFalse, + }, + }, + core.ZoneArgSpec( + scw.ZoneFrPar1, + scw.ZoneFrPar2, + scw.ZoneNlAms1, + scw.ZoneNlAms2, + scw.ZoneNlAms3, + scw.ZonePlWaw1, + scw.ZonePlWaw2, + scw.ZonePlWaw3, + ), + } + c.Run = func(ctx context.Context, argsI any) (any, error) { + args := argsI.(*customDeleteGatewayRequest) + + client := core.ExtractClient(ctx) + api := vpcgw.NewAPI(client) + + // Get gateway info to check if it has an IP + gateway, err := api.GetGateway(&vpcgw.GetGatewayRequest{ + Zone: args.Zone, + GatewayID: args.GatewayID, + }) + if err != nil { + return nil, err + } + + // Determine if we should delete the IP + deleteIP, err := shouldDeleteIP(ctx, gateway, args.WithIP) + if err != nil { + return nil, err + } + + request := &vpcgw.DeleteGatewayRequest{ + Zone: args.Zone, + GatewayID: args.GatewayID, + DeleteIP: deleteIP, + } + + return api.DeleteGateway(request) + } + + return c +} + +func shouldDeleteIP( + ctx context.Context, + gateway *vpcgw.Gateway, + withIP string, +) (bool, error) { + switch withIP { + case withIPTrue: + return true, nil + case withIPFalse: + return false, nil + case withIPPrompt: + // Only prompt user if gateway has an IP + if gateway.IPv4 == nil { + return false, nil + } + + return interactive.PromptBoolWithConfig(&interactive.PromptBoolConfig{ + Prompt: "Do you also want to delete the IP attached to this gateway?", + DefaultValue: false, + Ctx: ctx, + }) + default: + return false, nil + } +}