Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(instance): routed ip support #3297

Merged
merged 10 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ARGS:
[bootscript-id] The bootscript ID to use, if empty the local boot will be used
[cloud-init] The cloud-init script to use (Support file loading with @/path/to/file)
[boot-type=local] The boot type to use, if empty the local boot will be used. Will be overwritten to bootscript if bootscript-id is set. (local | bootscript | rescue)
[routed-ip-enabled] Enable routed IP support
[project-id] Project ID to use. If none is passed the default project ID will be used
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config
[organization-id] Organization ID to use. If none is passed the default organization ID will be used
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
Enable routed IP for this server and migrate the nat public IP to routed
Server will reboot !
https://www.scaleway.com/en/docs/compute/instances/api-cli/using-ip-mobility/

USAGE:
scw instance server enable-routed-ip <server-id ...> [arg=value ...]

EXAMPLES:
Migrate a server with legacy network to IP mobility
scw instance server enable-routed-ip 11111111-1111-1111-1111-111111111111

ARGS:
server-id ID of the server affected by the action.
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config

FLAGS:
-h, --help help for enable-routed-ip
-w, --wait wait until the server is ready

GLOBAL FLAGS:
-c, --config string The path to the config file
-D, --debug Enable debug mode
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human")
-p, --profile string The config profile to use
39 changes: 20 additions & 19 deletions cmd/scw/testdata/test-all-usage-instance-server-usage.golden
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,28 @@ USAGE:
scw instance server <command>

AVAILABLE COMMANDS:
attach-ip Attach an IP to a server
attach-volume Attach a volume to a server
backup Backup server
console Connect to the serial console of an instance
create Create server
delete Delete server
detach-ip Detach an IP from a server
detach-volume Detach a volume from its server
get Get an Instance
list List all Instances
list-actions List Instance actions
reboot Reboot server
ssh SSH into a server
standby Put server in standby mode
start Power on server
stop Power off server
terminate Terminate server
update Update an Instance
attach-ip Attach an IP to a server
attach-volume Attach a volume to a server
backup Backup server
console Connect to the serial console of an instance
create Create server
delete Delete server
detach-ip Detach an IP from a server
detach-volume Detach a volume from its server
enable-routed-ip Migrate server to IP mobility
get Get an Instance
list List all Instances
list-actions List Instance actions
reboot Reboot server
ssh SSH into a server
standby Put server in standby mode
start Power on server
stop Power off server
terminate Terminate server
update Update an Instance

WORKFLOW COMMANDS:
wait Wait for server to reach a stable state
wait Wait for server to reach a stable state

FLAGS:
-h, --help help for server
Expand Down
35 changes: 35 additions & 0 deletions docs/commands/instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Instance API.
- [Delete server](#delete-server)
- [Detach an IP from a server](#detach-an-ip-from-a-server)
- [Detach a volume from its server](#detach-a-volume-from-its-server)
- [Migrate server to IP mobility](#migrate-server-to-ip-mobility)
- [Get an Instance](#get-an-instance)
- [List all Instances](#list-all-instances)
- [List Instance actions](#list-instance-actions)
Expand Down Expand Up @@ -1715,6 +1716,7 @@ scw instance server create [arg=value ...]
| bootscript-id | | The bootscript ID to use, if empty the local boot will be used |
| cloud-init | | The cloud-init script to use |
| boot-type | Default: `local`<br />One of: `local`, `bootscript`, `rescue` | The boot type to use, if empty the local boot will be used. Will be overwritten to bootscript if bootscript-id is set. |
| routed-ip-enabled | | Enable routed IP support |
| project-id | | Project ID to use. If none is passed the default project ID will be used |
| zone | Default: `fr-par-1` | Zone to target. If none is passed will use default zone from the config |
| organization-id | | Organization ID to use. If none is passed the default organization ID will be used |
Expand Down Expand Up @@ -1855,6 +1857,39 @@ scw instance server detach-volume volume-id=22222222-1111-5555-2222-666666111111



### Migrate server to IP mobility

Enable routed IP for this server and migrate the nat public IP to routed
Server will reboot !
https://www.scaleway.com/en/docs/compute/instances/api-cli/using-ip-mobility/


**Usage:**

```
scw instance server enable-routed-ip <server-id ...> [arg=value ...]
```


**Args:**

| Name | | Description |
|------|---|-------------|
| server-id | Required | ID of the server affected by the action. |
| zone | Default: `fr-par-1` | Zone to target. If none is passed will use default zone from the config |


**Examples:**


Migrate a server with legacy network to IP mobility
```
scw instance server enable-routed-ip 11111111-1111-1111-1111-111111111111
```




### Get an Instance

Get the details of a specified Instance.
Expand Down
7 changes: 6 additions & 1 deletion internal/human/marshal_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ func init() {
})
marshalerFuncs.Store(reflect.TypeOf(scw.IPNet{}), func(i interface{}, opt *MarshalOpt) (string, error) {
v := i.(scw.IPNet)
return v.String(), nil
str := v.String()
if str == "<nil>" {
return "-", nil
}
Codelax marked this conversation as resolved.
Show resolved Hide resolved

return str, nil
})
marshalerFuncs.Store(reflect.TypeOf(version.Version{}), func(i interface{}, opt *MarshalOpt) (string, error) {
v := i.(version.Version)
Expand Down
1 change: 1 addition & 0 deletions internal/namespaces/instance/v1/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func GetCommands() *core.Commands {
serverStopCommand(),
serverStandbyCommand(),
serverRebootCommand(),
serverEnableRoutedIPCommand(),
serverWaitCommand(),
serverAttachIPCommand(),
serverDetachIPCommand(),
Expand Down
29 changes: 27 additions & 2 deletions internal/namespaces/instance/v1/custom_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func serversMarshalerFunc(i interface{}, opt *human.MarshalOpt) (string, error)
PrivateIP *string
Tags []string
ImageName string
RoutedIPEnabled bool
PlacementGroup *instance.PlacementGroup
ModificationDate *time.Time
CreationDate *time.Time
Expand Down Expand Up @@ -101,6 +102,7 @@ func serversMarshalerFunc(i interface{}, opt *human.MarshalOpt) (string, error)
PrivateIP: server.PrivateIP,
Tags: server.Tags,
ImageName: serverImageName,
RoutedIPEnabled: server.RoutedIPEnabled,
PlacementGroup: server.PlacementGroup,
ModificationDate: server.ModificationDate,
CreationDate: server.CreationDate,
Expand Down Expand Up @@ -395,8 +397,8 @@ func serverGetBuilder(c *core.Command) *core.Command {
Title: "Volumes",
},
{
Title: "Public IP",
FieldName: "PublicIP",
Title: "Public IPs",
FieldName: "PublicIPs",
},
{
Title: "IPv6",
Expand Down Expand Up @@ -729,6 +731,29 @@ func serverRebootCommand() *core.Command {
}
}

func serverEnableRoutedIPCommand() *core.Command {
return &core.Command{
Short: `Migrate server to IP mobility`,
Long: `Enable routed IP for this server and migrate the nat public IP to routed
Server will reboot !
https://www.scaleway.com/en/docs/compute/instances/api-cli/using-ip-mobility/
`,
Namespace: "instance",
Resource: "server",
Verb: "enable-routed-ip",
ArgsType: reflect.TypeOf(instanceActionRequest{}),
Run: getRunServerAction("enable_routed_ip"),
WaitFunc: waitForServerFunc(),
ArgSpecs: serverActionArgSpecs,
Examples: []*core.Example{
{
Short: "Migrate a server with legacy network to IP mobility",
ArgsJSON: `{"server_id": "11111111-1111-1111-1111-111111111111"}`,
},
},
}
}

func serverBackupCommand() *core.Command {
type instanceBackupRequest struct {
Zone scw.Zone
Expand Down
50 changes: 37 additions & 13 deletions internal/namespaces/instance/v1/custom_server_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type instanceCreateServerRequest struct {
Stopped bool
SecurityGroupID string
PlacementGroupID string

// IP Mobility
RoutedIPEnabled *bool

// Deprecated
BootscriptID string
CloudInit string
Expand Down Expand Up @@ -121,6 +125,10 @@ func serverCreateCommand() *core.Command {
Default: core.DefaultValueSetter(instance.BootTypeLocal.String()),
EnumValues: []string{instance.BootTypeLocal.String(), instance.BootTypeBootscript.String(), instance.BootTypeRescue.String()},
},
{
Name: "routed-ip-enabled",
Short: "Enable routed IP support",
},
core.ProjectIDArgSpec(),
core.ZoneArgSpec(),
core.OrganizationIDArgSpec(),
Expand Down Expand Up @@ -182,13 +190,14 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
needIPCreation := false

serverReq := &instance.CreateServerRequest{
Zone: args.Zone,
Organization: args.OrganizationID,
Project: args.ProjectID,
Name: args.Name,
CommercialType: args.Type,
EnableIPv6: args.IPv6,
Tags: args.Tags,
Zone: args.Zone,
Organization: args.OrganizationID,
Project: args.ProjectID,
Name: args.Name,
CommercialType: args.Type,
EnableIPv6: args.IPv6,
Tags: args.Tags,
RoutedIPEnabled: args.RoutedIPEnabled,
}

client := core.ExtractClient(ctx)
Expand Down Expand Up @@ -356,15 +365,11 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
if needIPCreation {
logger.Debugf("creating IP")

res, err := apiInstance.CreateIP(&instance.CreateIPRequest{
Zone: args.Zone,
Project: args.ProjectID,
Organization: args.OrganizationID,
})
ip, err := instanceServerCreateIPCreate(args, apiInstance)
if err != nil {
return nil, fmt.Errorf("error while creating your public IP: %s", err)
}
serverReq.PublicIP = scw.StringPtr(res.IP.ID)
serverReq.PublicIP = scw.StringPtr(ip.ID)
logger.Debugf("IP created: %s", serverReq.PublicIP)
}

Expand Down Expand Up @@ -714,3 +719,22 @@ func getServerType(apiInstance *instance.API, zone scw.Zone, commercialType stri

return serverType
}

func instanceServerCreateIPCreate(args *instanceCreateServerRequest, api *instance.API) (*instance.IP, error) {
req := &instance.CreateIPRequest{
Zone: args.Zone,
Project: args.ProjectID,
Organization: args.OrganizationID,
}

if args.RoutedIPEnabled != nil && *args.RoutedIPEnabled {
req.Type = instance.IPTypeRoutedIPv4
}

res, err := api.CreateIP(req)
if err != nil {
return nil, err
}

return res.IP, nil
}
31 changes: 31 additions & 0 deletions internal/namespaces/instance/v1/custom_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,34 @@ func Test_ServerBackup(t *testing.T) {
),
}))
}

func Test_ServerEnableRoutedIP(t *testing.T) {
t.Run("simple", core.Test(&core.TestConfig{
Commands: GetCommands(),
BeforeFunc: core.ExecStoreBeforeCmd("Server", "scw instance server create zone=fr-par-3 type=PRO2-XXS image=ubuntu_jammy ip=new --wait"),
Cmd: `scw instance server enable-routed-ip zone=fr-par-3 {{ .Server.ID }} --wait`,
Check: core.TestCheckCombine(
func(t *testing.T, ctx *core.CheckFuncCtx) {
storedServer := ctx.Meta["Server"].(*instance.Server)
api := instance.NewAPI(ctx.Client)
server, err := api.GetServer(&instance.GetServerRequest{
Zone: storedServer.Zone,
ServerID: storedServer.ID,
})
assert.Nil(t, err)
assert.Equal(t, true, server.Server.RoutedIPEnabled)
ip, err := api.GetIP(&instance.GetIPRequest{
Zone: storedServer.Zone,
IP: storedServer.PublicIP.ID,
})
assert.Nil(t, err)
assert.Equal(t, instance.IPTypeRoutedIPv4, ip.IP.Type)
},
core.TestCheckGolden(),
core.TestCheckExitCode(0),
),
AfterFunc: core.AfterFuncCombine(
core.ExecAfterCmd("scw instance server delete zone=fr-par-3 {{ .Server.ID }} force-shutdown=true with-ip=true with-volumes=local"),
),
}))
}
Loading
Loading