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: allow disabling the server public ips #190

Merged
merged 7 commits into from
Jun 5, 2024
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
10 changes: 10 additions & 0 deletions .web-docs/components/builder/hcloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ servers that are launched within the Hetzner Cloud.
The builder does _not_ manage images. Once it creates an image, it is up to you
to use it or delete it.

The builder will connect to the server using the first available IP, in the following order:

- `public_ipv4`
- `public_ipv6`
- `private_ipv4`

## Configuration Reference

There are many configuration options available for the builder. They are
Expand Down Expand Up @@ -134,9 +140,13 @@ builder.
- `public_ipv4` (string) - ID, name or IP address of a pre-allocated Hetzner
Primary IPv4 address to use for the created server.

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

- `public_ipv6` (string) - ID, name or IP address of a pre-allocated Hetzner
Primary IPv6 address to use for the created server.

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

## Basic Example

Here is a basic example. It is completely valid as soon as you enter your own
Expand Down
9 changes: 6 additions & 3 deletions builder/hcloud/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ type Config struct {
UserDataFile string `mapstructure:"user_data_file"`
SSHKeys []string `mapstructure:"ssh_keys"`
SSHKeysLabels map[string]string `mapstructure:"ssh_keys_labels"`
Networks []int64 `mapstructure:"networks"`
PublicIPv4 string `mapstructure:"public_ipv4"`
PublicIPv6 string `mapstructure:"public_ipv6"`

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"`

RescueMode string `mapstructure:"rescue"`

Expand Down
4 changes: 4 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.

79 changes: 45 additions & 34 deletions builder/hcloud/step_create_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,32 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
UserData: userData,
Networks: networks,
Labels: c.ServerLabels,
PublicNet: &hcloud.ServerCreatePublicNet{
EnableIPv4: !c.PublicIPv4Disabled,
EnableIPv6: !c.PublicIPv6Disabled,
},
}

if c.PublicIPv4 != "" || c.PublicIPv6 != "" {
publicNetOpts := hcloud.ServerCreatePublicNet{
EnableIPv4: true,
EnableIPv6: true,
if !c.PublicIPv4Disabled && c.PublicIPv4 != "" {
publicIPv4, msg, err := getPrimaryIP(ctx, client, c.PublicIPv4)
if err != nil {
return errorHandler(state, ui, msg, err)
}
if publicIPv4.Type != hcloud.PrimaryIPTypeIPv4 {
return errorHandler(state, ui, "", fmt.Errorf("Primary ip %s is not an IPv4 address", c.PublicIPv4))
}
if c.PublicIPv4 != "" {
publicIPv4, msg, err := getPrimaryIP(ctx, client, c.PublicIPv4)
if err != nil {
return errorHandler(state, ui, msg, err)
}
if publicIPv4.Type != hcloud.PrimaryIPTypeIPv4 {
return errorHandler(state, ui, "", fmt.Errorf("Primary ip %s is not an IPv4 address", c.PublicIPv4))
}
publicNetOpts.IPv4 = publicIPv4
serverCreateOpts.PublicNet.IPv4 = publicIPv4
}

if !c.PublicIPv6Disabled && c.PublicIPv6 != "" {
publicIPv6, msg, err := getPrimaryIP(ctx, client, c.PublicIPv6)
if err != nil {
return errorHandler(state, ui, msg, err)
}
if c.PublicIPv6 != "" {
publicIPv6, msg, err := getPrimaryIP(ctx, client, c.PublicIPv6)
if err != nil {
return errorHandler(state, ui, msg, err)
}
if publicIPv6.Type != hcloud.PrimaryIPTypeIPv6 {
return errorHandler(state, ui, "", fmt.Errorf("Primary ip %s is not an IPv6 address", c.PublicIPv6))
}
publicNetOpts.IPv6 = publicIPv6
if publicIPv6.Type != hcloud.PrimaryIPTypeIPv6 {
return errorHandler(state, ui, "", fmt.Errorf("Primary ip %s is not an IPv6 address", c.PublicIPv6))
}
serverCreateOpts.PublicNet = &publicNetOpts
serverCreateOpts.PublicNet.IPv6 = publicIPv6
}

if c.UpgradeServerType != "" {
Expand All @@ -118,26 +116,39 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
if err != nil {
return errorHandler(state, ui, "Could not create server", err)
}
state.Put(StateServerIP, serverCreateResult.Server.PublicNet.IPv4.IP.String())

// We use this in cleanup
s.serverId = serverCreateResult.Server.ID

// Store the server id for later
state.Put(StateServerID, serverCreateResult.Server.ID)
// instance_id is the generic term used so that users can have access to the
// instance id inside of the provisioners, used in step_provision.
state.Put(StateInstanceID, serverCreateResult.Server.ID)

if err := client.Action.WaitFor(ctx, serverCreateResult.Action); err != nil {
return errorHandler(state, ui, "Could not create server", err)
}
if err := client.Action.WaitFor(ctx, serverCreateResult.NextActions...); err != nil {
return errorHandler(state, ui, "Could not create server", err)
}

// Store server data for later
server := serverCreateResult.Server

state.Put(StateServerID, server.ID)
// instance_id is the generic term used so that users can have access to the
// instance id inside of the provisioners, used in step_provision.
state.Put(StateInstanceID, server.ID)

switch {
case !server.PublicNet.IPv4.IsUnspecified():
state.Put(StateServerIP, server.PublicNet.IPv4.IP.String())
case !server.PublicNet.IPv6.IsUnspecified():
state.Put(StateServerIP, server.PublicNet.IPv6.IP.String())
case len(server.PrivateNet) > 0:
state.Put(StateServerIP, server.PrivateNet[0].IP.String())
default:
return errorHandler(state, ui, "", fmt.Errorf("Could not find server ip"))
}

if c.UpgradeServerType != "" {
ui.Say("Upgrading server type...")
serverChangeTypeAction, _, err := client.Server.ChangeType(ctx, serverCreateResult.Server, hcloud.ServerChangeTypeOpts{
serverChangeTypeAction, _, err := client.Server.ChangeType(ctx, server, hcloud.ServerChangeTypeOpts{
ServerType: &hcloud.ServerType{Name: c.UpgradeServerType},
UpgradeDisk: false,
})
Expand All @@ -150,7 +161,7 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
}

ui.Say("Starting server...")
serverPoweronAction, _, err := client.Server.Poweron(ctx, serverCreateResult.Server)
serverPoweronAction, _, err := client.Server.Poweron(ctx, server)
if err != nil {
return errorHandler(state, ui, "Could not start server", err)
}
Expand All @@ -162,12 +173,12 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu

if c.RescueMode != "" {
ui.Say("Enabling Rescue Mode...")
_, err := setRescue(ctx, client, serverCreateResult.Server, c.RescueMode, sshKeys)
_, err := setRescue(ctx, client, server, c.RescueMode, sshKeys)
if err != nil {
return errorHandler(state, ui, "Could not enable rescue mode", err)
}
ui.Say("Rebooting server...")
action, _, err := client.Server.Reset(ctx, serverCreateResult.Server)
action, _, err := client.Server.Reset(ctx, server)
if err != nil {
return errorHandler(state, ui, "Could not reboot server", err)
}
Expand Down
3 changes: 2 additions & 1 deletion builder/hcloud/step_create_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ func TestStepCreateServer(t *testing.T) {
assert.Equal(t, int64(114690387), int64(payload.Image.(float64)))
assert.Equal(t, "nbg1", payload.Location)
assert.Equal(t, "cpx11", payload.ServerType)
assert.True(t, payload.PublicNet.EnableIPv4)
assert.True(t, payload.PublicNet.EnableIPv6)
assert.Nil(t, payload.Networks)
assert.Nil(t, payload.PublicNet)
},
201, `{
"server": { "id": 8, "name": "dummy-server", "public_net": { "ipv4": { "ip": "1.2.3.4" }}},
Expand Down
10 changes: 10 additions & 0 deletions docs/builders/hcloud.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ servers that are launched within the Hetzner Cloud.
The builder does _not_ manage images. Once it creates an image, it is up to you
to use it or delete it.

The builder will connect to the server using the first available IP, in the following order:

- `public_ipv4`
- `public_ipv6`
- `private_ipv4`

## Configuration Reference

There are many configuration options available for the builder. They are
Expand Down Expand Up @@ -124,9 +130,13 @@ builder.
- `public_ipv4` (string) - ID, name or IP address of a pre-allocated Hetzner
Primary IPv4 address to use for the created server.

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

- `public_ipv6` (string) - ID, name or IP address of a pre-allocated Hetzner
Primary IPv6 address to use for the created server.

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

## Basic Example

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