Skip to content

Commit

Permalink
Support Marketplace App Variables (#291)
Browse files Browse the repository at this point in the history
* Add marketplace service, list variables endpoint, and test

* Support marketplace app variables on instance/BM create
  • Loading branch information
christhemorse authored Dec 14, 2023
1 parent ec9fca1 commit f40104b
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 18 deletions.
15 changes: 8 additions & 7 deletions bare_metal_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,14 @@ type BareMetalCreate struct {
ActivationEmail *bool `json:"activation_email,omitempty"`
Hostname string `json:"hostname,omitempty"`
// Deprecated: Tag should no longer be used. Instead, use Tags.
Tag string `json:"tag,omitempty"`
ReservedIPv4 string `json:"reserved_ipv4,omitempty"`
PersistentPxe *bool `json:"persistent_pxe,omitempty"`
Tags []string `json:"tags"`
AttachVPC2 []string `json:"attach_vpc2,omitempty"`
DetachVPC2 []string `json:"detach_vpc2,omitempty"`
EnableVPC2 *bool `json:"enable_vpc2,omitempty"`
Tag string `json:"tag,omitempty"`
ReservedIPv4 string `json:"reserved_ipv4,omitempty"`
PersistentPxe *bool `json:"persistent_pxe,omitempty"`
Tags []string `json:"tags"`
AttachVPC2 []string `json:"attach_vpc2,omitempty"`
DetachVPC2 []string `json:"detach_vpc2,omitempty"`
EnableVPC2 *bool `json:"enable_vpc2,omitempty"`
AppVariables map[string]string `json:"app_variables,omitempty"`
}

// BareMetalUpdate represents the optional parameters that can be set when updating a Bare Metal server
Expand Down
2 changes: 2 additions & 0 deletions govultr.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type Client struct {
ISO ISOService
Kubernetes KubernetesService
LoadBalancer LoadBalancerService
Marketplace MarketplaceService
// Deprecated: Network should no longer be used. Instead, use VPC.
Network NetworkService
ObjectStorage ObjectStorageService
Expand Down Expand Up @@ -129,6 +130,7 @@ func NewClient(httpClient *http.Client) *Client {
client.ISO = &ISOServiceHandler{client}
client.Kubernetes = &KubernetesHandler{client}
client.LoadBalancer = &LoadBalancerHandler{client}
client.Marketplace = &MarketplaceServiceHandler{client}
client.Network = &NetworkServiceHandler{client}
client.ObjectStorage = &ObjectStorageServiceHandler{client}
client.OS = &OSServiceHandler{client}
Expand Down
23 changes: 12 additions & 11 deletions instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,18 @@ type InstanceCreateReq struct {
// Deprecated: EnablePrivateNetwork should no longer be used. Instead, use EnableVPC.
EnablePrivateNetwork *bool `json:"enable_private_network,omitempty"`
// Deprecated: AttachPrivateNetwork should no longer be used. Instead, use AttachVPC.
AttachPrivateNetwork []string `json:"attach_private_network,omitempty"`
EnableVPC *bool `json:"enable_vpc,omitempty"`
AttachVPC []string `json:"attach_vpc,omitempty"`
EnableVPC2 *bool `json:"enable_vpc2,omitempty"`
AttachVPC2 []string `json:"attach_vpc2,omitempty"`
SSHKeys []string `json:"sshkey_id,omitempty"`
Backups string `json:"backups,omitempty"`
DDOSProtection *bool `json:"ddos_protection,omitempty"`
UserData string `json:"user_data,omitempty"`
ReservedIPv4 string `json:"reserved_ipv4,omitempty"`
ActivationEmail *bool `json:"activation_email,omitempty"`
AttachPrivateNetwork []string `json:"attach_private_network,omitempty"`
EnableVPC *bool `json:"enable_vpc,omitempty"`
AttachVPC []string `json:"attach_vpc,omitempty"`
EnableVPC2 *bool `json:"enable_vpc2,omitempty"`
AttachVPC2 []string `json:"attach_vpc2,omitempty"`
SSHKeys []string `json:"sshkey_id,omitempty"`
Backups string `json:"backups,omitempty"`
DDOSProtection *bool `json:"ddos_protection,omitempty"`
UserData string `json:"user_data,omitempty"`
ReservedIPv4 string `json:"reserved_ipv4,omitempty"`
ActivationEmail *bool `json:"activation_email,omitempty"`
AppVariables map[string]string `json:"app_variables,omitempty"`
}

// InstanceUpdateReq struct used to update an instance.
Expand Down
50 changes: 50 additions & 0 deletions marketplace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package govultr

import (
"context"
"fmt"
"net/http"
)

const marketplacePath = "/v2/marketplace"

// MarketplaceService is the interface to interact with the Marketplace endpoints on the Vultr API
// Link: https://www.vultr.com/api/#tag/marketplace
type MarketplaceService interface {
ListAppVariables(ctx context.Context, imageID string) ([]MarketplaceAppVariable, *http.Response, error)
}

// MarketplaceServiceHandler handles interaction with the server methods for the Vultr API
type MarketplaceServiceHandler struct {
client *Client
}

// MarketplaceAppVariable represents a user-supplied variable for a Marketplace app
type MarketplaceAppVariable struct {
Name string `json:"name"`
Description string `json:"description"`
Required *bool `json:"required"`
}

// marketplaceAppVariablesBase holds the API response for retrieving a list of user-supplied variables for a Marketplace app
type marketplaceAppVariablesBase struct {
MarketplaceAppVariables []MarketplaceAppVariable `json:"variables"`
}

// ListAppVariables retrieves all user-supplied variables for a Marketplace app
func (d *MarketplaceServiceHandler) ListAppVariables(ctx context.Context, imageID string) ([]MarketplaceAppVariable, *http.Response, error) { //nolint:lll
uri := fmt.Sprintf("%s/apps/%s/variables", marketplacePath, imageID)

req, err := d.client.NewRequest(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, nil, err
}

marketplaceAppVariables := new(marketplaceAppVariablesBase)
resp, err := d.client.DoWithContext(ctx, req, marketplaceAppVariables)
if err != nil {
return nil, nil, err
}

return marketplaceAppVariables.MarketplaceAppVariables, resp, nil
}
53 changes: 53 additions & 0 deletions marketplace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package govultr

import (
"fmt"
"net/http"
"reflect"
"testing"
)

func TestMarketplaceServiceHandler_ListAppVariables(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc(fmt.Sprintf("/v2/marketplace/apps/%s/variables", "testimage"), func(writer http.ResponseWriter, request *http.Request) {
response := `{
"variables": [
{
"name": "some_required_variable",
"description": "This is an example of a required user-supplied variable for this Marketplace app.",
"required": true
},
{
"name": "some_optional_variable",
"description": "This is an example of an optional user-supplied variable for this Marketplace app.",
"required": false
}
]
}`
fmt.Fprint(writer, response)
})

variables, _, err := client.Marketplace.ListAppVariables(ctx, "testimage")
if err != nil {
t.Errorf("Marketplace.ListAppVariables returned %+v", err)
}

expected := []MarketplaceAppVariable{
{
Name: "some_required_variable",
Description: "This is an example of a required user-supplied variable for this Marketplace app.",
Required: BoolToBoolPtr(true),
},
{
Name: "some_optional_variable",
Description: "This is an example of an optional user-supplied variable for this Marketplace app.",
Required: BoolToBoolPtr(false),
},
}

if !reflect.DeepEqual(variables, expected) {
t.Errorf("Marketplace.ListAppVariables returned %+v, expected %+v", variables, expected)
}
}

0 comments on commit f40104b

Please sign in to comment.