Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a05a8f6
feat: Add wait handlers for VPN gateway creation, update and deletion
s-inter May 4, 2026
806af61
chore: ran sync-tidy
s-inter May 4, 2026
a67637a
chore: Update VPN service to version 0.7.0
s-inter May 4, 2026
3b20f53
Merge branch 'main' into si/vpn-waiter
s-inter May 11, 2026
1bd1e22
Revert "chore: Update VPN service to version 0.7.0"
s-inter May 12, 2026
ac31dc1
Merge remote-tracking branch 'origin/main' into si/vpn-waiter
s-inter May 12, 2026
e2e933b
feat(vpn): implement gateway wait handlers and corresponding tests fo…
s-inter May 12, 2026
f1ca97a
feat(vpn): update changelog and version to v0.8.0
s-inter May 12, 2026
7f957ff
feat(vpn): add example for VPN Gateway and Connection management
s-inter May 12, 2026
69721d5
refactor(vpn): remove default HTTP error status codes in DeleteGatewa…
s-inter May 12, 2026
0223925
refactor(vpn): change public interface to separate Create and Update …
s-inter May 12, 2026
66e27aa
fix(vpn): fix linter issues
s-inter May 12, 2026
1093613
Merge branch 'main' into si/vpn-waiter
s-inter May 12, 2026
05ec585
fix(vpn): revert unwanted change
s-inter May 13, 2026
2e8ddc4
fix(vpn): examples use go 1.25
s-inter May 13, 2026
430e4d6
Merge branch 'main' into si/vpn-waiter
s-inter May 13, 2026
fa096e3
Merge branch 'main' into si/vpn-waiter
s-inter May 13, 2026
0b8069c
fix(vpn): fix changelog message
s-inter May 13, 2026
c408573
fix(vpn): fix changelog message
s-inter May 13, 2026
3237d2f
Merge branch 'main' into si/vpn-waiter
s-inter May 13, 2026
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@
- `v1api`: New package which can be used for communication with the STACKIT vpn v1 API
- `v1beta1api`: Align package to latest API specification
- `v1alpha1api`: Align package to latest API specification
- [v0.8.0](services/vpn/CHANGELOG.md#v080)
- `v1api`:
Comment thread
s-inter marked this conversation as resolved.
- **Feature:** Add new wait handlers for gateway creation (`CreateGatewayWaitHandler`), update (`UpdateGatewayWaitHandler`), and deletion (`DeleteGatewayWaitHandler`)

## Release (2026-04-07)
- `alb`: [v0.13.1](services/alb/CHANGELOG.md#v0131)
Expand Down
16 changes: 16 additions & 0 deletions examples/vpn/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/stackitcloud/stackit-sdk-go/examples/vpn

go 1.25

// This is not needed in production. This is only here to point the golangci linter to the local version instead of the last release on GitHub.
replace github.com/stackitcloud/stackit-sdk-go/services/vpn => ../../services/vpn

require (
github.com/stackitcloud/stackit-sdk-go/core v0.26.0
github.com/stackitcloud/stackit-sdk-go/services/vpn v0.8.0
)

require (
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/uuid v1.6.0 // indirect
)
8 changes: 8 additions & 0 deletions examples/vpn/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/stackitcloud/stackit-sdk-go/core v0.26.0 h1:jQEb9gkehfp6VCP6TcYk7BI10cz4l0KM2L6hqYBH2QA=
github.com/stackitcloud/stackit-sdk-go/core v0.26.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA=
97 changes: 97 additions & 0 deletions examples/vpn/vpn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package main

import (
"context"
"fmt"
"os"

"github.com/stackitcloud/stackit-sdk-go/core/config"
vpn "github.com/stackitcloud/stackit-sdk-go/services/vpn/v1api"
)

func main() {
region := "eu01" // Region where the resources will be created
projectId := "PROJECT_ID" // the uuid of your STACKIT project
planId := "PLAN_ID" // the id of the plan you want to use for the VPN Gateway. You can get the available plans with `ListPlans`.

// STACKIT VPN enforces the following requirements for a secure PSK:
// - must be at least 20 characters long
// - must be at least 16 different characters
// - must have at least one upper case letter
// - must have at least one lower case letter
// - must have at least one number
psk := "Super.$ecret_Shared3Key12345"

// Create a new API client, that uses default authentication and configuration
vpnClient, err := vpn.NewAPIClient(
config.WithRegion(region),
)
if err != nil {
fmt.Fprintf(os.Stderr, "Creating API client: %v\n", err)
os.Exit(1)
}

// Create a VPN Gateway
createVpnGatewayPayload := vpn.CreateGatewayPayload{
DisplayName: "exampleVpnGateway",
PlanId: planId,
RoutingType: vpn.ROUTINGTYPE_ROUTE_BASED,
AvailabilityZones: vpn.CreateGatewayPayloadAvailabilityZones{
Tunnel1: "eu01-1",
Tunnel2: "eu01-2",
},
}

gatewayResp, err := vpnClient.DefaultAPI.CreateGateway(context.Background(), projectId, vpn.Region(region)).CreateGatewayPayload(createVpnGatewayPayload).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `CreateVpnGateway`: %v\n", err)
os.Exit(1)
}
fmt.Printf("Created VPN Gateway with id \"%s\".\n", *gatewayResp.Id)

// Create a VPN Connection
phase1 := vpn.TunnelConfigurationPhase1{
DhGroups: []string{"ecp384"},
EncryptionAlgorithms: []string{"aes256"},
IntegrityAlgorithms: []string{"sha2_384"},
}
phase2 := vpn.TunnelConfigurationPhase2{
DhGroups: []string{"ecp384"},
EncryptionAlgorithms: []string{"aes256"},
IntegrityAlgorithms: []string{"sha2_384"},
}
tunnel := vpn.TunnelConfiguration{
Phase1: phase1,
Phase2: phase2,
PreSharedKey: &psk,
RemoteAddress: "0.0.0.0",
}

createGatewayConnectionPayload := vpn.CreateGatewayConnectionPayload{
DisplayName: "exampleVpnConnection",
Tunnel1: tunnel,
Tunnel2: tunnel,
}
connectionResp, err := vpnClient.DefaultAPI.CreateGatewayConnection(context.Background(), projectId, vpn.Region(region), *gatewayResp.Id).CreateGatewayConnectionPayload(createGatewayConnectionPayload).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `CreateVpnConnection`: %v\n", err)
os.Exit(1)
}
fmt.Printf("Created VPN Connection with id \"%s\".\n", *connectionResp.Id)

// Delete the VPN Connection
err = vpnClient.DefaultAPI.DeleteGatewayConnection(context.Background(), projectId, vpn.Region(region), *gatewayResp.Id, *connectionResp.Id).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `DeleteVpnConnection`: %v\n", err)
os.Exit(1)
}
fmt.Printf("Deleted VPN Connection with id \"%s\".\n", *connectionResp.Id)

// Delete the VPN Gateway
err = vpnClient.DefaultAPI.DeleteGateway(context.Background(), projectId, vpn.Region(region), *gatewayResp.Id).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `DeleteVpnGateway`: %v\n", err)
os.Exit(1)
}
fmt.Printf("Deleted VPN Gateway with id \"%s\".\n", *gatewayResp.Id)
}
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use (
./examples/sqlserverflex
./examples/telemetrylink
./examples/telemetryrouter
./examples/vpn
./examples/waiter
./services/alb
./services/albwaf
Expand Down
4 changes: 4 additions & 0 deletions services/vpn/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v0.8.0
- `v1api`:
- **Feature:** Add new wait handlers for gateway creation (`CreateGatewayWaitHandler`), update (`UpdateGatewayWaitHandler`), and deletion (`DeleteGatewayWaitHandler`)

## v0.7.0
- `v1api`: New package which can be used for communication with the STACKIT vpn v1 API
- `v1beta1api`: Align package to latest API specification
Expand Down
2 changes: 1 addition & 1 deletion services/vpn/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.7.0
v0.8.0
5 changes: 4 additions & 1 deletion services/vpn/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module github.com/stackitcloud/stackit-sdk-go/services/vpn

go 1.25

require github.com/stackitcloud/stackit-sdk-go/core v0.26.0
require (
github.com/google/go-cmp v0.7.0
github.com/stackitcloud/stackit-sdk-go/core v0.26.0
)

require (
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
Expand Down
59 changes: 59 additions & 0 deletions services/vpn/v1api/wait/wait.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package wait

import (
"context"
"errors"
"time"

"github.com/stackitcloud/stackit-sdk-go/core/wait"
vpn "github.com/stackitcloud/stackit-sdk-go/services/vpn/v1api"
)

func createOrUpdateGatewayWaitHandler(ctx context.Context, a vpn.DefaultAPI, projectId string, region vpn.Region, gatewayId string) *wait.AsyncActionHandler[vpn.GatewayResponse] {
waitConfig := wait.WaiterHelper[vpn.GatewayResponse, vpn.GatewayStatus]{
FetchInstance: a.GetGateway(ctx, projectId, region, gatewayId).Execute,
GetState: func(resp *vpn.GatewayResponse) (vpn.GatewayStatus, error) {
if resp == nil {
return "", errors.New("could not get gateway status: response is nil")
}
if resp.State == nil {
return "", errors.New("could not get gateway status: state is nil")
}
return *resp.State, nil
},
ActiveState: []vpn.GatewayStatus{vpn.GATEWAYSTATUS_READY},
ErrorState: []vpn.GatewayStatus{vpn.GATEWAYSTATUS_ERROR, vpn.GATEWAYSTATUS_DELETING},
}

handler := wait.New(waitConfig.Wait())
handler.SetTimeout(45 * time.Minute)
return handler
}

func CreateGatewayWaitHandler(ctx context.Context, a vpn.DefaultAPI, projectId string, region vpn.Region, gatewayId string) *wait.AsyncActionHandler[vpn.GatewayResponse] {
return createOrUpdateGatewayWaitHandler(ctx, a, projectId, region, gatewayId)
}

func UpdateGatewayWaitHandler(ctx context.Context, a vpn.DefaultAPI, projectId string, region vpn.Region, gatewayId string) *wait.AsyncActionHandler[vpn.GatewayResponse] {
return createOrUpdateGatewayWaitHandler(ctx, a, projectId, region, gatewayId)
}

func DeleteGatewayWaitHandler(ctx context.Context, a vpn.DefaultAPI, projectId string, region vpn.Region, gatewayId string) *wait.AsyncActionHandler[vpn.GatewayResponse] {
waitConfig := wait.WaiterHelper[vpn.GatewayResponse, vpn.GatewayStatus]{
FetchInstance: a.GetGateway(ctx, projectId, region, gatewayId).Execute,
GetState: func(resp *vpn.GatewayResponse) (vpn.GatewayStatus, error) {
if resp == nil {
return "", errors.New("could not get gateway status: response is nil")
}
if resp.State == nil {
return "", errors.New("could not get gateway status: state is nil")
}
return *resp.State, nil
},
ErrorState: []vpn.GatewayStatus{vpn.GATEWAYSTATUS_ERROR},
}

handler := wait.New(waitConfig.Wait())
handler.SetTimeout(20 * time.Minute)
return handler
}
Loading
Loading