Skip to content

Commit

Permalink
[TRAFFIC-10482] Add network access-point, network dns record, and…
Browse files Browse the repository at this point in the history
… `network gateway` commands (#2666)

Co-authored-by: Sherwin Young <[email protected]>
Co-authored-by: Brian Strauch <[email protected]>
  • Loading branch information
3 people authored Mar 29, 2024
1 parent 869c7c1 commit 76551ca
Show file tree
Hide file tree
Showing 83 changed files with 2,531 additions and 4 deletions.
2 changes: 2 additions & 0 deletions cmd/lint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ var flagRules = []linter.FlagRule{
"encrypted-key-material",
"max-partition-memory-bytes",
"message-send-max-retries",
"private-link-access-point",
"request-required-acks",
"schema-registry-api-key",
"schema-registry-api-secret",
Expand All @@ -118,6 +119,7 @@ var flagRules = []linter.FlagRule{
"aws-ram-share-arn",
"max-partition-memory-bytes",
"message-send-max-retries",
"private-link-access-point",
"schema-registry-api-key",
"schema-registry-api-secret",
"skip-message-on-error",
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ require (
github.com/confluentinc/ccloud-sdk-go-v2/ksql v0.2.0
github.com/confluentinc/ccloud-sdk-go-v2/mds v0.4.0
github.com/confluentinc/ccloud-sdk-go-v2/metrics v0.2.0
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.10.0
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.11.0
github.com/confluentinc/ccloud-sdk-go-v2/networking-access-point v0.1.0
github.com/confluentinc/ccloud-sdk-go-v2/networking-dnsforwarder v0.2.0
github.com/confluentinc/ccloud-sdk-go-v2/networking-ip v0.1.0
github.com/confluentinc/ccloud-sdk-go-v2/networking-privatelink v0.2.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ github.com/confluentinc/ccloud-sdk-go-v2/mds v0.4.0 h1:jIXXhGi+Xn+XYFCErnMvd035Q
github.com/confluentinc/ccloud-sdk-go-v2/mds v0.4.0/go.mod h1:ufn9In8kDsyJ7Nru2ygpAaWdGw7DSDTOTtDhQVSmZjs=
github.com/confluentinc/ccloud-sdk-go-v2/metrics v0.2.0 h1:TWwZHdfo2XNKrnGOuxXx4LF8WgahqqDC47Ap51L4thM=
github.com/confluentinc/ccloud-sdk-go-v2/metrics v0.2.0/go.mod h1:odGsHChrn2l+jaOvx4Gib5//U4a3Id79wstQVkNh8v0=
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.10.0 h1:gqGScDC+kNUL0q9zBDI8Bvw5fEOVet80hz/2cL5SNnw=
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.10.0/go.mod h1:UITAYHPL/LWs/E4R8i+mvkJywhoCZBQSuNdXYRhxL5g=
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.11.0 h1:UWS2K/UYNBO63QU5wukkjvheChYKjyRGj/0mLe0edg4=
github.com/confluentinc/ccloud-sdk-go-v2/networking v0.11.0/go.mod h1:jL9lLHYwFKzCJE5Fh62UdRqJCMJ9T/xg5QOdnQRYIUg=
github.com/confluentinc/ccloud-sdk-go-v2/networking-access-point v0.1.0 h1:V/rWaPSmDXGaP/j1ITZEWI0n+POQjhWRQllR4YpLXKA=
github.com/confluentinc/ccloud-sdk-go-v2/networking-access-point v0.1.0/go.mod h1:HV1xGUwTsGEU3Mgvc+7Ya/0HRpUO69L2rqqxO7LeWMc=
github.com/confluentinc/ccloud-sdk-go-v2/networking-dnsforwarder v0.2.0 h1:OdIeCGfy8iQ2Bm+08CDXYttwZOUme0e9FVGrBjBJGx4=
github.com/confluentinc/ccloud-sdk-go-v2/networking-dnsforwarder v0.2.0/go.mod h1:472T8ufudvXgXea2BhYxhE/2eowwhoulZzboDh6+ec4=
github.com/confluentinc/ccloud-sdk-go-v2/networking-ip v0.1.0 h1:n104JfOJqZPqHcfr8Cc4e3PZPOXJfJ2q0ThTqjQ+cOo=
Expand Down
18 changes: 18 additions & 0 deletions internal/network/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ func New(prerunner pcmd.PreRunner) *cobra.Command {

c := &command{pcmd.NewAuthenticatedCLICommand(cmd, prerunner)}

cmd.AddCommand(newAccessPointCommand(prerunner))
cmd.AddCommand(c.newCreateCommand())
cmd.AddCommand(c.newDeleteCommand())
cmd.AddCommand(c.newDescribeCommand())
cmd.AddCommand(c.newDnsCommand())
cmd.AddCommand(c.newGatewayCommand())
cmd.AddCommand(c.newIpAddressCommand())
cmd.AddCommand(c.newListCommand())
cmd.AddCommand(c.newPeeringCommand())
Expand Down Expand Up @@ -371,3 +373,19 @@ func addForwarderFlags(cmd *cobra.Command) {
cmd.Flags().StringSlice("dns-server-ips", nil, "A comma-separated list of IP addresses for the DNS server.")
cmd.Flags().StringSlice("domains", nil, "A comma-separated list of domains for the DNS forwarder to use.")
}

func addGatewayFlag(cmd *cobra.Command, c *pcmd.AuthenticatedCLICommand) {
cmd.Flags().String("gateway", "", "Gateway ID.")
pcmd.RegisterFlagCompletionFunc(cmd, "gateway", func(cmd *cobra.Command, args []string) []string {
if err := c.PersistentPreRunE(cmd, args); err != nil {
return nil
}

environmentId, err := c.Context.EnvironmentId()
if err != nil {
return nil
}

return autocompleteGateways(c.V2Client, environmentId)
})
}
37 changes: 37 additions & 0 deletions internal/network/command_access_point.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package network

import (
"github.com/spf13/cobra"

pcmd "github.com/confluentinc/cli/v3/pkg/cmd"
)

type accessPointCommand struct {
*pcmd.AuthenticatedCLICommand
}

type accessPointOut struct {
Id string `human:"ID" serialized:"id"`
Name string `human:"Name,omitempty" serialized:"name,omitempty"`
AwsVpcEndpointService string `human:"AWS VPC Endpoint Service,omitempty" serialized:"aws_vpc_endpoint_service,omitempty"`
AwsVpcEndpoint string `human:"AWS VPC Endpoint,omitempty" serialized:"aws_vpc_endpoint,omitempty"`
AwsVpcEndpointDnsName string `human:"AWS VPC Endpoint DNS Name,omitempty" serialized:"aws_vpc_endpoint_dns_name,omitempty"`
HighAvailability bool `human:"High Availability,omitempty" serialized:"high_availability,omitempty"`
Environment string `human:"Environment" serialized:"environment"`
Gateway string `human:"Gateway" serialized:"gateway"`
Phase string `human:"Phase" serialized:"phase"`
}

func newAccessPointCommand(prerunner pcmd.PreRunner) *cobra.Command {
cmd := &cobra.Command{
Use: "access-point",
Short: "Manage access points.",
Annotations: map[string]string{pcmd.RunRequirement: pcmd.RequireNonAPIKeyCloudLogin},
}

c := &accessPointCommand{pcmd.NewAuthenticatedCLICommand(cmd, prerunner)}

cmd.AddCommand(c.newPrivateLinkCommand())

return cmd
}
16 changes: 16 additions & 0 deletions internal/network/command_access_point_private_link.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package network

import (
"github.com/spf13/cobra"
)

func (c *accessPointCommand) newPrivateLinkCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "private-link",
Short: "Manage access point private links.",
}

cmd.AddCommand(c.newEgressEndpointCommand())

return cmd
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package network

import (
"fmt"

"github.com/spf13/cobra"

networkingaccesspointv1 "github.com/confluentinc/ccloud-sdk-go-v2/networking-access-point/v1"

"github.com/confluentinc/cli/v3/pkg/errors"
"github.com/confluentinc/cli/v3/pkg/output"
)

func (c *accessPointCommand) newEgressEndpointCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "egress-endpoint",
Short: "Manage private link egress endpoints.",
}

cmd.AddCommand(c.newCreateCommand())
cmd.AddCommand(c.newDeleteCommand())
cmd.AddCommand(c.newDescribeCommand())
cmd.AddCommand(c.newListCommand())
cmd.AddCommand(c.newUpdateCommand())

return cmd
}

func (c *accessPointCommand) validArgs(cmd *cobra.Command, args []string) []string {
if len(args) > 0 {
return nil
}

return c.validArgsMultiple(cmd, args)
}

func (c *accessPointCommand) validArgsMultiple(cmd *cobra.Command, args []string) []string {
if err := c.PersistentPreRunE(cmd, args); err != nil {
return nil
}

return c.autocompleteEgressEndpoints()
}

func (c *accessPointCommand) autocompleteEgressEndpoints() []string {
environmentId, err := c.Context.EnvironmentId()
if err != nil {
return nil
}

egressEndpoints, err := c.V2Client.ListAccessPoints(environmentId, nil)
if err != nil {
return nil
}

suggestions := make([]string, len(egressEndpoints))
for i, egressEndpoint := range egressEndpoints {
suggestions[i] = fmt.Sprintf("%s\t%s", egressEndpoint.GetId(), egressEndpoint.Spec.GetDisplayName())
}
return suggestions
}

func printPrivateLinkEgressEndpointTable(cmd *cobra.Command, egressEndpoint networkingaccesspointv1.NetworkingV1AccessPoint) error {
if egressEndpoint.Spec == nil {
return fmt.Errorf(errors.CorruptedNetworkResponseErrorMsg, "spec")
}
if egressEndpoint.Status == nil {
return fmt.Errorf(errors.CorruptedNetworkResponseErrorMsg, "status")
}

out := &accessPointOut{
Id: egressEndpoint.GetId(),
Name: egressEndpoint.Spec.GetDisplayName(),
Gateway: egressEndpoint.Spec.Gateway.GetId(),
Environment: egressEndpoint.Spec.Environment.GetId(),
Phase: egressEndpoint.Status.GetPhase(),
}

if egressEndpoint.Spec.Config != nil && egressEndpoint.Spec.Config.NetworkingV1AwsEgressPrivateLinkEndpoint != nil {
out.AwsVpcEndpointService = egressEndpoint.Spec.Config.NetworkingV1AwsEgressPrivateLinkEndpoint.GetVpcEndpointServiceName()
out.HighAvailability = egressEndpoint.Spec.Config.NetworkingV1AwsEgressPrivateLinkEndpoint.GetEnableHighAvailability()
}

if egressEndpoint.Status.Config != nil && egressEndpoint.Status.Config.NetworkingV1AwsEgressPrivateLinkEndpointStatus != nil {
out.AwsVpcEndpoint = egressEndpoint.Status.Config.NetworkingV1AwsEgressPrivateLinkEndpointStatus.GetVpcEndpointId()
out.AwsVpcEndpointDnsName = egressEndpoint.Status.Config.NetworkingV1AwsEgressPrivateLinkEndpointStatus.GetVpcEndpointDnsName()
}

table := output.NewTable(cmd)
table.Add(out)
return table.Print()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package network

import (
"strings"

"github.com/spf13/cobra"

networkingaccesspointv1 "github.com/confluentinc/ccloud-sdk-go-v2/networking-access-point/v1"

pcmd "github.com/confluentinc/cli/v3/pkg/cmd"
"github.com/confluentinc/cli/v3/pkg/examples"
)

func (c *accessPointCommand) newCreateCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "create [name]",
Short: "Create an egress endpoint.",
Args: cobra.MaximumNArgs(1),
RunE: c.create,
Example: examples.BuildExampleString(
examples.Example{
Text: "Create an AWS private link egress endpoint with high availability.",
Code: "confluent network access-point private-link egress-endpoint create --cloud aws --gateway gw-123456 --service com.amazonaws.vpce.us-west-2.vpce-svc-00000000000000000 --high-availability",
},
),
}

cmd.Flags().String("cloud", "", "Specify the cloud provider as aws.")
cmd.Flags().String("service", "", "Name of an AWS VPC endpoint service.")
addGatewayFlag(cmd, c.AuthenticatedCLICommand)
cmd.Flags().Bool("high-availability", false, "Enable high availability for AWS egress endpoint.")
pcmd.AddContextFlag(cmd, c.CLICommand)
pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand)
pcmd.AddOutputFlag(cmd)

cobra.CheckErr(cmd.MarkFlagRequired("cloud"))
cobra.CheckErr(cmd.MarkFlagRequired("gateway"))
cobra.CheckErr(cmd.MarkFlagRequired("service"))

return cmd
}

func (c *accessPointCommand) create(cmd *cobra.Command, args []string) error {
name := ""
if len(args) == 1 {
name = args[0]
}

cloud, err := cmd.Flags().GetString("cloud")
if err != nil {
return err
}
cloud = strings.ToUpper(cloud)

gateway, err := cmd.Flags().GetString("gateway")
if err != nil {
return err
}

service, err := cmd.Flags().GetString("service")
if err != nil {
return err
}

environmentId, err := c.Context.EnvironmentId()
if err != nil {
return err
}

highAvailability, err := cmd.Flags().GetBool("high-availability")
if err != nil {
return err
}

createEgressEndpoint := networkingaccesspointv1.NetworkingV1AccessPoint{
Spec: &networkingaccesspointv1.NetworkingV1AccessPointSpec{
Environment: &networkingaccesspointv1.ObjectReference{Id: environmentId},
Gateway: &networkingaccesspointv1.ObjectReference{Id: gateway},
},
}

if name != "" {
createEgressEndpoint.Spec.SetDisplayName(name)
}

switch cloud {
case CloudAws:
createEgressEndpoint.Spec.Config = &networkingaccesspointv1.NetworkingV1AccessPointSpecConfigOneOf{
NetworkingV1AwsEgressPrivateLinkEndpoint: &networkingaccesspointv1.NetworkingV1AwsEgressPrivateLinkEndpoint{
Kind: "AwsEgressPrivateLinkEndpoint",
VpcEndpointServiceName: service,
EnableHighAvailability: networkingaccesspointv1.PtrBool(highAvailability),
},
}
}

egressEndpoint, err := c.V2Client.CreateAccessPoint(createEgressEndpoint)
if err != nil {
return err
}

return printPrivateLinkEgressEndpointTable(cmd, egressEndpoint)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package network

import (
"fmt"

"github.com/spf13/cobra"

pcmd "github.com/confluentinc/cli/v3/pkg/cmd"
"github.com/confluentinc/cli/v3/pkg/deletion"
"github.com/confluentinc/cli/v3/pkg/errors"
"github.com/confluentinc/cli/v3/pkg/output"
"github.com/confluentinc/cli/v3/pkg/resource"
"github.com/confluentinc/cli/v3/pkg/utils"
)

func (c *accessPointCommand) newDeleteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "delete <id-1> [id-2] ... [id-n]",
Short: "Delete one or more egress endpoints.",
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: pcmd.NewValidArgsFunction(c.validArgsMultiple),
RunE: c.delete,
}

pcmd.AddForceFlag(cmd)
pcmd.AddContextFlag(cmd, c.CLICommand)
pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand)

return cmd
}

func (c *accessPointCommand) delete(cmd *cobra.Command, args []string) error {
environmentId, err := c.Context.EnvironmentId()
if err != nil {
return err
}

existenceFunc := func(id string) bool {
_, err := c.V2Client.GetAccessPoint(environmentId, id)
return err == nil
}

if err := deletion.ValidateAndConfirmDeletionYesNo(cmd, args, existenceFunc, resource.AccessPoint); err != nil {
return err
}

deleteFunc := func(id string) error {
if err := c.V2Client.DeleteAccessPoint(environmentId, id); err != nil {
return fmt.Errorf(errors.DeleteResourceErrorMsg, resource.AccessPoint, id, err)
}
return nil
}

deletedIds, err := deletion.DeleteWithoutMessage(args, deleteFunc)
deleteMsg := "Requested to delete %s %s.\n"
if len(deletedIds) == 1 {
output.Printf(c.Config.EnableColor, deleteMsg, resource.AccessPoint, fmt.Sprintf(`"%s"`, deletedIds[0]))
} else if len(deletedIds) > 1 {
output.Printf(c.Config.EnableColor, deleteMsg, resource.Plural(resource.AccessPoint), utils.ArrayToCommaDelimitedString(deletedIds, "and"))
}

return err
}
Loading

0 comments on commit 76551ca

Please sign in to comment.