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

Add network update outbound #503

Merged
merged 3 commits into from
Jan 28, 2025
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
57 changes: 57 additions & 0 deletions cli/cmd/network.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cmd

import (
"github.com/replicatedhq/replicated/pkg/credentials"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/platformclient"
"github.com/spf13/cobra"
)

Expand All @@ -15,3 +18,57 @@ func (r *runners) InitNetworkCommand(parent *cobra.Command) *cobra.Command {

return cmd
}

func (r *runners) initNetworkClient() error {
if apiToken == "" {
creds, err := credentials.GetCurrentCredentials()
if err != nil {
return err
}

apiToken = creds.APIToken
}

httpClient := platformclient.NewHTTPClient(platformOrigin, apiToken)
kotsAPI := &kotsclient.VendorV3Client{HTTPClient: *httpClient}
r.kotsAPI = kotsAPI
return nil
}

func (r *runners) completeNetworkNames(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
err := r.initNetworkClient()
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}

networks, err := r.kotsAPI.ListNetworks(nil, nil)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

var names []string
for _, network := range networks {
if network.Name != "" {
names = append(names, network.Name)
}
}
return names, cobra.ShellCompDirectiveNoFileComp
}

func (r *runners) completeNetworkIDs(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
err := r.initNetworkClient()
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}

networks, err := r.kotsAPI.ListNetworks(nil, nil)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

var ids []string
for _, network := range networks {
ids = append(ids, network.ID)
}
return ids, cobra.ShellCompDirectiveNoFileComp
}
56 changes: 56 additions & 0 deletions cli/cmd/network_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/pkg/platformclient"
"github.com/spf13/cobra"
)

func (r *runners) InitNetworkUpdateCommand(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "update",
Short: "Update network settings.",
Long: `The 'update' command allows you to update various settings of a test network.

You can either specify the network ID directly or provide the network name, and the command will resolve the corresponding network ID.`,
Example: `# Update a network using its ID
replicated network update --id <network-id> [subcommand]

# Update a network using its name
replicated network update --name <network-name> [subcommand]`,
}
parent.AddCommand(cmd)

cmd.PersistentFlags().StringVar(&r.args.updateNetworkName, "name", "", "Name of the network to update.")
cmd.RegisterFlagCompletionFunc("name", r.completeNetworkNames)

cmd.PersistentFlags().StringVar(&r.args.updateNetworkID, "id", "", "id of the network to update (when name is not provided)")
cmd.RegisterFlagCompletionFunc("id", r.completeNetworkIDs)

return cmd
}

func (r *runners) ensureUpdateNetworkIDArg(args []string) error {
if len(args) > 0 {
r.args.updateNetworkID = args[0]
} else if r.args.updateNetworkName != "" {
networks, err := r.kotsAPI.ListNetworks(nil, nil)
if errors.Cause(err) == platformclient.ErrForbidden {
return ErrCompatibilityMatrixTermsNotAccepted
} else if err != nil {
return errors.Wrap(err, "list networks")
}
for _, network := range networks {
if network.Name == r.args.updateNetworkName {
r.args.updateNetworkID = network.ID
break
}
}
} else if r.args.updateNetworkID != "" {
// do nothing
} else {
return errors.New("must provide network id or name")
}

return nil
}
52 changes: 52 additions & 0 deletions cli/cmd/network_update_outbound.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"github.com/pkg/errors"
"github.com/replicatedhq/replicated/cli/print"
"github.com/replicatedhq/replicated/pkg/kotsclient"
"github.com/replicatedhq/replicated/pkg/platformclient"
"github.com/spf13/cobra"
)

func (r *runners) InitNetworkUpdateOutbound(parent *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "outbound [ID]",
Short: "Update outbound setting for a test network.",
Long: `The 'outbound' command allows you to update the outbound setting of a test network. The outbound setting can be either 'none' or 'any'.`,
Example: `# Update the outbound setting for a specific network
replicated network update outbound NETWORK_ID --outbound any`,
RunE: r.updateNetworkOutbound,
SilenceUsage: true,
ValidArgsFunction: r.completeNetworkIDs,
}
parent.AddCommand(cmd)

cmd.Flags().StringVar(&r.args.updateNetworkOutbound, "outbound", "", "Update outbound setting (must be 'none' or 'any')")
cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table|wide")

cmd.MarkFlagRequired("outbound")

return cmd
}

func (r *runners) updateNetworkOutbound(cmd *cobra.Command, args []string) error {
if err := r.ensureUpdateNetworkIDArg(args); err != nil {
return errors.Wrap(err, "ensure network id arg")
}

if r.args.updateNetworkOutbound != "none" && r.args.updateNetworkOutbound != "any" {
return errors.New("outbound must be either 'none' or 'any'")
}

opts := kotsclient.UpdateNetworkOutboundOpts{
Outbound: r.args.updateNetworkOutbound,
}
network, err := r.kotsAPI.UpdateNetworkOutbound(r.args.updateNetworkID, opts)
if errors.Cause(err) == platformclient.ErrForbidden {
return ErrCompatibilityMatrixTermsNotAccepted
} else if err != nil {
return errors.Wrap(err, "update network outbound")
}

return print.Network(r.outputFormat, r.w, network)
}
3 changes: 3 additions & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i
runCmds.InitNetworkList(networkCmd)
runCmds.InitNetworkRemove(networkCmd)
runCmds.InitNetworkJoin(networkCmd)

networkUpdateCmd := runCmds.InitNetworkUpdateCommand(networkCmd)
runCmds.InitNetworkUpdateOutbound(networkUpdateCmd)

runCmds.InitLoginCommand(runCmds.rootCmd)
runCmds.InitLogoutCommand(runCmds.rootCmd)
Expand Down
5 changes: 5 additions & 0 deletions cli/cmd/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ type runnerArgs struct {
lsNetworkEndTime string
lsNetworkWatch bool

updateNetworkOutbound string

updateNetworkName string
updateNetworkID string

clusterAddonCreateObjectStoreBucket string
clusterAddonCreateObjectStoreClusterID string
clusterAddonCreateObjectStoreDuration time.Duration
Expand Down
8 changes: 4 additions & 4 deletions cli/print/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import (
)

// Table formatting
var networksTmplTableHeaderSrc = `ID NAME STATUS CREATED EXPIRES`
var networksTmplTableHeaderSrc = `ID NAME STATUS CREATED EXPIRES OUTBOUND`
var networksTmplTableRowSrc = `{{ range . -}}
{{ .ID }} {{ padding .Name 27 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}}
{{ .ID }} {{ padding .Name 27 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{if eq .Outbound ""}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (.Outbound)) 30 }}{{end}}
{{ end }}`
var networksTmplTableSrc = fmt.Sprintln(networksTmplTableHeaderSrc) + networksTmplTableRowSrc
var networksTmplTable = template.Must(template.New("networks").Funcs(funcs).Parse(networksTmplTableSrc))
var networksTmplTableNoHeader = template.Must(template.New("networks").Funcs(funcs).Parse(networksTmplTableRowSrc))

// Wide table formatting
var networksTmplWideHeaderSrc = `ID NAME STATUS CREATED EXPIRES`
var networksTmplWideHeaderSrc = `ID NAME STATUS CREATED EXPIRES OUTBOUND`
var networksTmplWideRowSrc = `{{ range . -}}
{{ .ID }} {{ padding .Name 27 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}}
{{ .ID }} {{ padding .Name 27 }} {{ padding (printf "%s" .Status) 12 }} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{if eq .Outbound ""}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (.Outbound)) 30 }}{{end}}
{{ end }}`
var networksTmplWideSrc = fmt.Sprintln(networksTmplWideHeaderSrc) + networksTmplWideRowSrc
var networksTmplWide = template.Must(template.New("networks").Funcs(funcs).Parse(networksTmplWideSrc))
Expand Down
41 changes: 41 additions & 0 deletions pkg/kotsclient/network_update_outbound.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package kotsclient

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

"github.com/replicatedhq/replicated/pkg/types"
)

type UpdateNetworkOutboundRequest struct {
Outbound string `json:"outbound"`
}

type UpdateNetworkOutboundResponse struct {
Network *types.Network `json:"network"`
Errors []string `json:"errors"`
}

type UpdateNetworkOutboundOpts struct {
Outbound string
}

func (c *VendorV3Client) UpdateNetworkOutbound(networkID string, opts UpdateNetworkOutboundOpts) (*types.Network, error) {
req := UpdateNetworkOutboundRequest{
Outbound: opts.Outbound,
}

return c.doUpdateNetworkOutboundRequest(networkID, req)
}

func (c *VendorV3Client) doUpdateNetworkOutboundRequest(networkID string, req UpdateNetworkOutboundRequest) (*types.Network, error) {
resp := UpdateNetworkOutboundResponse{}
endpoint := fmt.Sprintf("/v3/network/%s/outbound", networkID)
err := c.DoJSON(context.TODO(), "PUT", endpoint, http.StatusOK, req, &resp)
if err != nil {
return nil, err
}

return resp.Network, nil
}
2 changes: 2 additions & 0 deletions pkg/types/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type Network struct {

OverlayEndpoint string `json:"overlay_endpoint,omitempty"`
OverlayToken string `json:"overlay_token,omitempty"`

Outbound string `json:"outbound,omitempty"`
}

type NetworkStatus string
Expand Down