mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-30 01:59:58 +00:00
TUN-5361: Commands for managing virtual networks
This commit is contained in:
46
vnet/api.go
Normal file
46
vnet/api.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package vnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type NewVirtualNetwork struct {
|
||||
Name string `json:"name"`
|
||||
Comment string `json:"comment"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
type VirtualNetwork struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Comment string `json:"comment"`
|
||||
Name string `json:"name"`
|
||||
IsDefault bool `json:"is_default_network"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
DeletedAt time.Time `json:"deleted_at"`
|
||||
}
|
||||
|
||||
type UpdateVirtualNetwork struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Comment *string `json:"comment,omitempty"`
|
||||
IsDefault *bool `json:"is_default_network,omitempty"`
|
||||
}
|
||||
|
||||
func (virtualNetwork VirtualNetwork) TableString() string {
|
||||
deletedColumn := "-"
|
||||
if !virtualNetwork.DeletedAt.IsZero() {
|
||||
deletedColumn = virtualNetwork.DeletedAt.Format(time.RFC3339)
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"%s\t%s\t%s\t%s\t%s\t%s\t",
|
||||
virtualNetwork.ID,
|
||||
virtualNetwork.Name,
|
||||
strconv.FormatBool(virtualNetwork.IsDefault),
|
||||
virtualNetwork.Comment,
|
||||
virtualNetwork.CreatedAt.Format(time.RFC3339),
|
||||
deletedColumn,
|
||||
)
|
||||
}
|
79
vnet/api_test.go
Normal file
79
vnet/api_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package vnet
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestVirtualNetworkJsonRoundtrip(t *testing.T) {
|
||||
data := `{
|
||||
"id":"74fce949-351b-4752-b261-81a56cfd3130",
|
||||
"comment":"New York DC1",
|
||||
"name":"us-east-1",
|
||||
"is_default_network":true,
|
||||
"created_at":"2021-11-26T14:40:02.600673Z",
|
||||
"deleted_at":"2021-12-01T10:23:13.102645Z"
|
||||
}`
|
||||
var v VirtualNetwork
|
||||
err := json.Unmarshal([]byte(data), &v)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uuid.MustParse("74fce949-351b-4752-b261-81a56cfd3130"), v.ID)
|
||||
require.Equal(t, "us-east-1", v.Name)
|
||||
require.Equal(t, "New York DC1", v.Comment)
|
||||
require.Equal(t, true, v.IsDefault)
|
||||
|
||||
bytes, err := json.Marshal(v)
|
||||
require.NoError(t, err)
|
||||
obtainedJson := string(bytes)
|
||||
data = strings.Replace(data, "\t", "", -1)
|
||||
data = strings.Replace(data, "\n", "", -1)
|
||||
require.Equal(t, data, obtainedJson)
|
||||
}
|
||||
|
||||
func TestMarshalNewVnet(t *testing.T) {
|
||||
newVnet := NewVirtualNetwork{
|
||||
Name: "eu-west-1",
|
||||
Comment: "London office",
|
||||
IsDefault: true,
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(newVnet)
|
||||
require.NoError(t, err)
|
||||
require.True(t, strings.Contains(string(serialized), newVnet.Name))
|
||||
}
|
||||
|
||||
func TestMarshalUpdateVnet(t *testing.T) {
|
||||
newName := "bulgaria-1"
|
||||
updates := UpdateVirtualNetwork{
|
||||
Name: &newName,
|
||||
}
|
||||
|
||||
// Test where receiver is struct
|
||||
serialized, err := json.Marshal(updates)
|
||||
require.NoError(t, err)
|
||||
require.True(t, strings.Contains(string(serialized), newName))
|
||||
}
|
||||
|
||||
func TestVnetTableString(t *testing.T) {
|
||||
virtualNet := VirtualNetwork{
|
||||
ID: uuid.New(),
|
||||
Name: "us-east-1",
|
||||
Comment: "New York DC1",
|
||||
IsDefault: true,
|
||||
CreatedAt: time.Now(),
|
||||
DeletedAt: time.Time{},
|
||||
}
|
||||
|
||||
row := virtualNet.TableString()
|
||||
require.True(t, strings.HasPrefix(row, virtualNet.ID.String()))
|
||||
require.True(t, strings.Contains(row, virtualNet.Name))
|
||||
require.True(t, strings.Contains(row, virtualNet.Comment))
|
||||
require.True(t, strings.Contains(row, "true"))
|
||||
require.True(t, strings.HasSuffix(row, "-\t"))
|
||||
}
|
99
vnet/filter.go
Normal file
99
vnet/filter.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package vnet
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
filterId = cli.StringFlag{
|
||||
Name: "id",
|
||||
Usage: "List virtual networks with the given `ID`",
|
||||
}
|
||||
filterName = cli.StringFlag{
|
||||
Name: "name",
|
||||
Usage: "List virtual networks with the given `NAME`",
|
||||
}
|
||||
filterDefault = cli.BoolFlag{
|
||||
Name: "is-default",
|
||||
Usage: "If true, lists the virtual network that is the default one. If false, lists all non-default virtual networks for the account. If absent, all are included in the results regardless of their default status.",
|
||||
}
|
||||
filterDeleted = cli.BoolFlag{
|
||||
Name: "show-deleted",
|
||||
Usage: "If false (default), only show non-deleted virtual networks. If true, only show deleted virtual networks.",
|
||||
}
|
||||
FilterFlags = []cli.Flag{
|
||||
&filterId,
|
||||
&filterName,
|
||||
&filterDefault,
|
||||
&filterDeleted,
|
||||
}
|
||||
)
|
||||
|
||||
// Filter which virtual networks get queried.
|
||||
type Filter struct {
|
||||
queryParams url.Values
|
||||
}
|
||||
|
||||
func NewFilter() *Filter {
|
||||
return &Filter{
|
||||
queryParams: url.Values{},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Filter) ById(vnetId uuid.UUID) {
|
||||
f.queryParams.Set("id", vnetId.String())
|
||||
}
|
||||
|
||||
func (f *Filter) ByName(name string) {
|
||||
f.queryParams.Set("name", name)
|
||||
}
|
||||
|
||||
func (f *Filter) ByDefaultStatus(isDefault bool) {
|
||||
f.queryParams.Set("is_default", strconv.FormatBool(isDefault))
|
||||
}
|
||||
|
||||
func (f *Filter) WithDeleted(isDeleted bool) {
|
||||
f.queryParams.Set("is_deleted", strconv.FormatBool(isDeleted))
|
||||
}
|
||||
|
||||
func (f *Filter) MaxFetchSize(max uint) {
|
||||
f.queryParams.Set("per_page", strconv.Itoa(int(max)))
|
||||
}
|
||||
|
||||
func (f Filter) Encode() string {
|
||||
return f.queryParams.Encode()
|
||||
}
|
||||
|
||||
// NewFromCLI parses CLI flags to discover which filters should get applied to list virtual networks.
|
||||
func NewFromCLI(c *cli.Context) (*Filter, error) {
|
||||
f := NewFilter()
|
||||
|
||||
if id := c.String("id"); id != "" {
|
||||
vnetId, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%s is not a valid virtual network ID", id)
|
||||
}
|
||||
f.ById(vnetId)
|
||||
}
|
||||
|
||||
if name := c.String("name"); name != "" {
|
||||
f.ByName(name)
|
||||
}
|
||||
|
||||
if c.IsSet("is-default") {
|
||||
f.ByDefaultStatus(c.Bool("is-default"))
|
||||
}
|
||||
|
||||
f.WithDeleted(c.Bool("show-deleted"))
|
||||
|
||||
if maxFetch := c.Int("max-fetch-size"); maxFetch > 0 {
|
||||
f.MaxFetchSize(uint(maxFetch))
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
Reference in New Issue
Block a user