Skip to content

Commit

Permalink
feat: allow attaching firewalls to the server (#221)
Browse files Browse the repository at this point in the history
Closes #157

This allows to attach a list of firewalls using their names or the IDs.
  • Loading branch information
jooola authored Aug 14, 2024
1 parent 7bcae2b commit 73f10e4
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .web-docs/components/builder/hcloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ builder.

- `public_ipv4_disabled` (bool) - Disable the public ipv6 for the created server.

- `firewalls` (array of strings) - List of Firewall by name or id to be attached
to the created server.

## Basic Example

Here is a basic example. It is completely valid as soon as you enter your own
Expand Down
11 changes: 6 additions & 5 deletions builder/hcloud/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ type Config struct {
SSHKeys []string `mapstructure:"ssh_keys"`
SSHKeysLabels map[string]string `mapstructure:"ssh_keys_labels"`

Networks []int64 `mapstructure:"networks"`
PublicIPv4 string `mapstructure:"public_ipv4"`
PublicIPv4Disabled bool `mapstructure:"public_ipv4_disabled"`
PublicIPv6 string `mapstructure:"public_ipv6"`
PublicIPv6Disabled bool `mapstructure:"public_ipv6_disabled"`
Networks []int64 `mapstructure:"networks"`
PublicIPv4 string `mapstructure:"public_ipv4"`
PublicIPv4Disabled bool `mapstructure:"public_ipv4_disabled"`
PublicIPv6 string `mapstructure:"public_ipv6"`
PublicIPv6Disabled bool `mapstructure:"public_ipv6_disabled"`
Firewalls []string `mapstructure:"firewalls"`

RescueMode string `mapstructure:"rescue"`

Expand Down
2 changes: 2 additions & 0 deletions builder/hcloud/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions builder/hcloud/step_create_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,29 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
}

sshKeys := []*hcloud.SSHKey{{ID: sshKeyId}}
for _, k := range c.SSHKeys {
sshKey, _, err := client.SSHKey.Get(ctx, k)
for _, idOrName := range c.SSHKeys {
sshKey, _, err := client.SSHKey.Get(ctx, idOrName)
if err != nil {
return errorHandler(state, ui, fmt.Sprintf("Could not fetch SSH key '%s'", k), err)
return errorHandler(state, ui, fmt.Sprintf("Could not fetch SSH key '%s'", idOrName), err)
}
if sshKey == nil {
return errorHandler(state, ui, "", fmt.Errorf("Could not find SSH key '%s'", k))
return errorHandler(state, ui, "", fmt.Errorf("Could not find SSH key '%s'", idOrName))
}
sshKeys = append(sshKeys, sshKey)
}

firewalls := make([]*hcloud.ServerCreateFirewall, 0, len(c.Firewalls))
for _, idOrName := range c.Firewalls {
firewall, _, err := client.Firewall.Get(ctx, idOrName)
if err != nil {
return errorHandler(state, ui, fmt.Sprintf("Could not fetch firewall '%s'", idOrName), err)
}
if firewall == nil {
return errorHandler(state, ui, "", fmt.Errorf("Could not find firewall '%s'", idOrName))
}
firewalls = append(firewalls, &hcloud.ServerCreateFirewall{Firewall: *firewall})
}

var image *hcloud.Image
var err error
if c.Image != "" {
Expand All @@ -77,6 +89,7 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
Name: c.ServerName,
ServerType: &hcloud.ServerType{Name: c.ServerType},
Image: image,
Firewalls: firewalls,
SSHKeys: sshKeys,
Location: &hcloud.Location{Name: c.Location},
UserData: userData,
Expand Down
76 changes: 76 additions & 0 deletions builder/hcloud/step_create_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,82 @@ func TestStepCreateServer(t *testing.T) {
assert.Equal(t, "1.2.3.4", serverIP)
},
},
{
Name: "happy with firewall",
Step: &stepCreateServer{},
SetupConfigFunc: func(c *Config) {
c.Firewalls = []string{"allow-ssh"}
},
SetupStateFunc: func(state multistep.StateBag) {
state.Put(StateSSHKeyID, int64(1))
state.Put(StateServerType, &hcloud.ServerType{ID: 9, Name: "cpx11", Architecture: "x86"})
},
WantRequests: []mockutil.Request{
{Method: "GET", Path: "/ssh_keys/1",
Status: 200,
JSONRaw: `{
"ssh_key": { "id": 1 }
}`,
},
{Method: "GET", Path: "/firewalls?name=allow-ssh",
Status: 200,
JSONRaw: `{
"firewalls": [{ "id": 986532, "name": "allow-ssh" }]
}`,
},
{Method: "GET", Path: "/images?architecture=x86&include_deprecated=true&name=debian-12",
Status: 200,
JSONRaw: `{
"images": [{ "id": 114690387, "name": "debian-12", "description": "Debian 12", "architecture": "x86" }]
}`,
},
{Method: "POST", Path: "/servers",
Want: func(t *testing.T, req *http.Request) {
payload := decodeJSONBody(t, req.Body, &schema.ServerCreateRequest{})
assert.Equal(t, "dummy-server", payload.Name)
assert.Equal(t, int64(114690387), int64(payload.Image.(float64)))
assert.Equal(t, "nbg1", payload.Location)
assert.Equal(t, "cpx11", payload.ServerType)
assert.Equal(t, int64(986532), payload.Firewalls[0].Firewall)
},
Status: 201,
JSONRaw: `{
"server": { "id": 8, "name": "dummy-server", "public_net": { "ipv4": { "ip": "127.0.0.1" }, "ipv6": { "ip": "::1" }}},
"action": { "id": 3, "status": "running" }
}`,
},
{Method: "GET", Path: "/actions?id=3&page=1&sort=status&sort=id",
Status: 200,
JSONRaw: `{
"actions": [
{ "id": 3, "status": "success" }
],
"meta": { "pagination": { "page": 1 }}
}`,
},
{Method: "GET", Path: "/firewalls/actions?page=1&status=running",
Status: 200,
JSONRaw: `{
"actions": [],
"meta": { "pagination": { "page": 1 }}
}`,
},
},
WantStepAction: multistep.ActionContinue,
WantStateFunc: func(t *testing.T, state multistep.StateBag) {
err, ok := state.Get(StateError).(error)
assert.False(t, ok)
assert.Nil(t, err)

serverID, ok := state.Get(StateServerID).(int64)
assert.True(t, ok)
assert.Equal(t, int64(8), serverID)

instanceID, ok := state.Get(StateInstanceID).(int64)
assert.True(t, ok)
assert.Equal(t, int64(8), instanceID)
},
},
{
Name: "happy with network",
Step: &stepCreateServer{},
Expand Down
3 changes: 3 additions & 0 deletions docs/builders/hcloud.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ builder.

- `public_ipv4_disabled` (bool) - Disable the public ipv6 for the created server.

- `firewalls` (array of strings) - List of Firewall by name or id to be attached
to the created server.

## Basic Example

Here is a basic example. It is completely valid as soon as you enter your own
Expand Down

0 comments on commit 73f10e4

Please sign in to comment.