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): secure an instance to only receive traffic from a giv… #2569

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
@@ -0,0 +1,21 @@
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
Secure an instance to only receive traffic from a given LB

USAGE:
scw instance security-group secure-behind-lb [arg=value ...]

ARGS:
instance-id ID of the instance server.
lb-id ID of the load balancer you want to import the instance into
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | fr-par-3 | nl-ams-1 | nl-ams-2 | pl-waw-1)
[region=fr-par] Region to target. If none is passed will use default region from the config (fr-par | nl-ams | pl-waw)

FLAGS:
-h, --help help for secure-behind-lb

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
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ USAGE:
scw instance security-group <command>

AVAILABLE COMMANDS:
clear Remove all rules of a security group
create Create a security group
delete Delete a security group
get Get a security group
list List security groups
update Update security group
clear Remove all rules of a security group
create Create a security group
delete Delete a security group
get Get a security group
list List security groups
secure-behind-lb Secure an instance to only receive traffic from a given LB
update Update security group

FLAGS:
-h, --help help for security-group
Expand Down
23 changes: 23 additions & 0 deletions docs/commands/instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Instance API
- [Delete a security group](#delete-a-security-group)
- [Get a security group](#get-a-security-group)
- [List security groups](#list-security-groups)
- [Secure an instance to only receive traffic from a given LB](#secure-an-instance-to-only-receive-traffic-from-a-given-lb)
- [Update security group](#update-security-group)
- [Server management commands](#server-management-commands)
- [Attach an IP to a server](#attach-an-ip-to-a-server)
Expand Down Expand Up @@ -1122,6 +1123,28 @@ scw instance security-group list name=foobar



### Secure an instance to only receive traffic from a given LB



**Usage:**

```
scw instance security-group secure-behind-lb [arg=value ...]
```


**Args:**

| Name | | Description |
|------|---|-------------|
| instance-id | Required | ID of the instance server. |
| lb-id | Required | ID of the load balancer you want to import the instance into |
| zone | Default: `fr-par-1`<br />One of: `fr-par-1`, `fr-par-2`, `fr-par-3`, `nl-ams-1`, `nl-ams-2`, `pl-waw-1` | Zone to target. If none is passed will use default zone from the config |
| region | Default: `fr-par`<br />One of: `fr-par`, `nl-ams`, `pl-waw` | Region to target. If none is passed will use default region from the config |



### Update security group

Update security group.
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 @@ -64,6 +64,7 @@ func GetCommands() *core.Commands {
serverWaitCommand(),
serverAttachIPCommand(),
serverDetachIPCommand(),
serverSecureBehindLBSecurityGroupCommand(),
))

//
Expand Down
109 changes: 109 additions & 0 deletions internal/namespaces/instance/v1/custom_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/scaleway/scaleway-cli/v2/internal/interactive"
"github.com/scaleway/scaleway-cli/v2/internal/terminal"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/api/lb/v1"
"github.com/scaleway/scaleway-sdk-go/logger"
"github.com/scaleway/scaleway-sdk-go/scw"
)
Expand Down Expand Up @@ -497,3 +498,111 @@ func getDefaultProjectSecurityGroup(ctx context.Context, zone scw.Zone) (*instan

return nil, fmt.Errorf("%s project does not have a default security group", projectID)
}

func serverSecureBehindLBSecurityGroupCommand() *core.Command {
type secureBehindLBSecurityGroup struct {
InstanceID string
LBID string
Zone scw.Zone
Region scw.Region
}

return &core.Command{
Short: `Secure an instance to only receive traffic from a given LB`,
Namespace: "instance",
Resource: "security-group",
Verb: "secure-behind-lb",
ArgsType: reflect.TypeOf(secureBehindLBSecurityGroup{}),
ArgSpecs: core.ArgSpecs{
{
Name: "instance-id",
Short: "ID of the instance server.",
Required: true,
},
{
Name: "lb-id",
Short: "ID of the load balancer you want to import the instance into",
Required: true,
},
core.ZoneArgSpec(scw.ZoneFrPar1, scw.ZoneFrPar2, scw.ZoneFrPar3, scw.ZoneNlAms1, scw.ZoneNlAms2, scw.ZonePlWaw1),
core.RegionArgSpec(scw.RegionFrPar, scw.RegionNlAms, scw.RegionPlWaw),
},
Run: func(ctx context.Context, argsI interface{}) (i interface{}, err error) {
args := argsI.(*secureBehindLBSecurityGroup)

LBAPI := lb.NewAPI(core.ExtractClient(ctx))
loadbalancer, err := LBAPI.GetLB(&lb.GetLBRequest{
Region: args.Region,
LBID: args.LBID,
})
if err != nil {
return nil, err
}

instanceAPI := instance.NewAPI(core.ExtractClient(ctx))
server, err := instanceAPI.GetServer(&instance.GetServerRequest{
Zone: args.Zone,
ServerID: args.InstanceID,
})
if err != nil {
return nil, err
}

securityGroupRequest := &instance.CreateSecurityGroupRequest{
Name: server.Server.Name,
Project: &server.Server.Project,
Stateful: false,
InboundDefaultPolicy: "drop",
Zone: args.Zone,
}

securityGroup, err := instanceAPI.CreateSecurityGroup(securityGroupRequest)
if err != nil {
return nil, err
}

var ipList []string
for _, ip := range loadbalancer.IP {
ipList = append(ipList, ip.IPAddress)
}

var ipRange scw.IPNet
err = ipRange.UnmarshalJSON([]byte(`"` + ipList[0] + `"`))
if err != nil {
return nil, err
}

ruleRequest := &instance.CreateSecurityGroupRuleRequest{
SecurityGroupID: securityGroup.SecurityGroup.ID,
Protocol: "ANY",
Direction: "inbound",
Action: "accept",
IPRange: ipRange,
Zone: args.Zone,
}

rule, err := instanceAPI.CreateSecurityGroupRule(ruleRequest)
if err != nil {
return nil, err
}

securityGroupTemplate := instance.SecurityGroupTemplate{
ID: securityGroup.SecurityGroup.ID,
Name: securityGroup.SecurityGroup.Name,
}

updateServerRequest := &instance.UpdateServerRequest{
Zone: args.Zone,
ServerID: args.InstanceID,
SecurityGroup: &securityGroupTemplate,
}

_, err = instanceAPI.UpdateServer(updateServerRequest)
if err != nil {
return nil, err
}

return rule, nil
},
}
}
30 changes: 30 additions & 0 deletions internal/namespaces/instance/v1/custom_security_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package instance

import (
"testing"

"github.com/scaleway/scaleway-cli/v2/internal/core"
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/lb/v1"
)

func Test_SecureBehindLBSecurityGroup(t *testing.T) {
commands := GetCommands()
commands.Merge(lb.GetCommands())
t.Run("Simple", core.Test(&core.TestConfig{
Commands: commands,
BeforeFunc: core.BeforeFuncCombine(
core.ExecStoreBeforeCmd("LB", "scw lb lb create name=foobar description=foobar --wait"),
createServer("Server"),
startServer("Server"),
),
Cmd: "scw instance security-group secure-behind-lb instance-id={{ .Server.ID }} lb-id={{ .LB.ID }}",
Check: core.TestCheckCombine(
core.TestCheckGolden(),
core.TestCheckExitCode(0),
),
AfterFunc: core.AfterFuncCombine(
deleteServer("Server"),
core.ExecAfterCmd("scw lb lb delete {{ .LB.ID }}"),
),
}))
}
Loading