Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.
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
30 changes: 1 addition & 29 deletions api/privatelink.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (api *API) EnablePrivatelink(instanceID int, params map[string][]interface{
path = fmt.Sprintf("/api/instances/%d/privatelink", instanceID)
)

if err := api.enableVPC(instanceID); err != nil {
if err := api.EnableVPC(instanceID); err != nil {
return err
}

Expand Down Expand Up @@ -126,31 +126,3 @@ func (api *API) waitForEnablePrivatelinkWithRetry(instanceID, attempt, sleep, ti
return fmt.Errorf("wait for enable PrivateLink failed, status: %v, message: %s",
response.StatusCode, failed)
}

// enableVPC: Enable VPC for an instance
// Check if the instance already have a standalone VPC
func (api *API) enableVPC(instanceID int) error {
var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc", instanceID)
)

data, _ := api.ReadInstance(fmt.Sprintf("%d", instanceID))
if data["vpc"] == nil {
response, err := api.sling.New().Put(path).Receive(nil, &failed)
if err != nil {
return err
}

if response.StatusCode == 200 {
log.Printf("[DEBUG] PrivateLink: VPC features enabled")
return nil
} else {
return fmt.Errorf("enable VPC failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

log.Printf("[DEBUG] PrivateLink: VPC features already enabled")
return nil
}
163 changes: 163 additions & 0 deletions api/vpc_connect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package api

import (
"fmt"
"log"
"time"
)

// EnableVpcConnect: Enable VPC Connect and wait until finished.
// Need to enable VPC for an instance, if no standalone VPC used.
// Wait until finished with configureable sleep and timeout.
func (api *API) EnableVpcConnect(instanceID int, params map[string][]interface{},
sleep, timeout int) error {

var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc-connect", instanceID)
)

if err := api.EnableVPC(instanceID); err != nil {
return err
}

response, err := api.sling.New().Post(path).BodyJSON(params).Receive(nil, &failed)
if err != nil {
return err
}

switch response.StatusCode {
case 204:
return api.waitForEnableVpcConnectWithRetry(instanceID, 1, sleep, timeout)
default:
return fmt.Errorf("enable VPC Connect failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

// ReadVpcConnect: Reads VPC Connect information
func (api *API) ReadVpcConnect(instanceID int) (map[string]interface{}, error) {
var (
data map[string]interface{}
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc-connect", instanceID)
)

response, err := api.sling.New().Get(path).Receive(&data, &failed)
if err != nil {
return nil, err
}

switch response.StatusCode {
case 200:
return data, nil
default:
return nil, fmt.Errorf("read VPC Connect failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

// UpdateVpcConnect: Update allowlist for the VPC Connect
func (api *API) UpdateVpcConnect(instanceID int, params map[string][]interface{}) error {
var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc-connect", instanceID)
)

response, err := api.sling.New().Put(path).BodyJSON(params).Receive(nil, &failed)
if err != nil {
return err
}

switch response.StatusCode {
case 204:
return nil
default:
return fmt.Errorf("update VPC connect failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

// DisableVpcConnect: Disable the VPC Connect feature
func (api *API) DisableVpcConnect(instanceID int) error {
var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc-connect", instanceID)
)

response, err := api.sling.New().Delete(path).Receive(nil, &failed)
if err != nil {
return err
}

switch response.StatusCode {
case 204:
return nil
default:
return fmt.Errorf("disable VPC Connect failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

// waitForEnableVpcConnectWithRetry: Wait until status change from pending to enable
func (api *API) waitForEnableVpcConnectWithRetry(instanceID, attempt, sleep, timeout int) error {
var (
data map[string]interface{}
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc-connect", instanceID)
)

response, err := api.sling.New().Get(path).Receive(&data, &failed)
if err != nil {
return err
} else if attempt*sleep > timeout {
return fmt.Errorf("enable VPC Connect failed, reached timeout of %d seconds", timeout)
}
log.Printf("[DEBUG] VPC-Connect: waitForEnableVpcConnectWithRetry data: %v", data)

switch response.StatusCode {
case 200:
switch data["status"].(string) {
case "enabled":
return nil
case "pending":
log.Printf("[DEBUG] go-api::vpc-connect::enable not finished and will retry, "+
"attempt: %d, until timeout: %d", attempt, (timeout - (attempt * sleep)))
attempt++
time.Sleep(time.Duration(sleep) * time.Second)
return api.waitForEnableVpcConnectWithRetry(instanceID, attempt, sleep, timeout)
}
}

return fmt.Errorf("wait for enable VPC Connect failed, status: %v, message: %s",
response.StatusCode, failed)
}

// enableVPC: Enable VPC for an instance
// Check if the instance already have a standalone VPC
func (api *API) EnableVPC(instanceID int) error {
var (
failed map[string]interface{}
path = fmt.Sprintf("/api/instances/%d/vpc", instanceID)
)

data, _ := api.ReadInstance(fmt.Sprintf("%d", instanceID))
if data["vpc"] == nil {
response, err := api.sling.New().Put(path).Receive(nil, &failed)
if err != nil {
return err
}

switch response.StatusCode {
case 200:
log.Printf("[DEBUG] VPC-Connect: VPC features enabled")
return nil
default:
return fmt.Errorf("enable VPC failed, status: %v, message: %s",
response.StatusCode, failed)
}
}

log.Printf("[DEBUG] VPC-Connect: VPC features already enabled")
return nil
}