Skip to content

Commit

Permalink
[CLI-3150] Add mTLS implementations (#2862)
Browse files Browse the repository at this point in the history
Co-authored-by: Tushar Malik <[email protected]>
  • Loading branch information
sgagniere and tmalikconfluent authored Aug 27, 2024
1 parent 564343d commit 6bf2a10
Show file tree
Hide file tree
Showing 61 changed files with 1,495 additions and 20 deletions.
11 changes: 9 additions & 2 deletions cmd/docs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,19 @@ func main() {
panic(err)
}

removeUnreleasedDocs()

if err := os.Setenv("HOME", home); err != nil {
panic(err)
}
}

func removeUnreleasedCommands(command string) { //nolint:unused
func removeUnreleasedDocs() {
removeUnreleasedCommands("iam certificate-authority")
removeUnreleasedCommands("iam certificate-pool")
}

func removeUnreleasedCommands(command string) {
subcommands := strings.Split(command, " ")

line := fmt.Sprintf(`\s{3}%s/index\n`, subcommands[len(subcommands)-1])
Expand All @@ -86,7 +93,7 @@ func removeUnreleasedCommands(command string) { //nolint:unused
}
}

func removeLineFromFile(line, file string) error { //nolint:unused
func removeLineFromFile(line, file string) error {
out, err := os.ReadFile(file)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/lint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ var flagRules = []linter.FlagRule{
"accepted-environments",
"azure-subscription",
"certificate-authority-path",
"certificate-chain-filename",
"destination-api-key",
"destination-api-secret",
"destination-bootstrap-server",
Expand Down Expand Up @@ -188,6 +189,7 @@ var vocabWords = []string{
"avro",
"aws",
"backoff",
"base64",
"byok",
"cel",
"cfu",
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/confluentinc/ccloud-sdk-go-v2/billing v0.3.0
github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2
github.com/confluentinc/ccloud-sdk-go-v2/cdx v0.0.5
github.com/confluentinc/ccloud-sdk-go-v2/certificate-authority v0.0.0-20240827200211-50926cdd47e0
github.com/confluentinc/ccloud-sdk-go-v2/cli v0.3.0
github.com/confluentinc/ccloud-sdk-go-v2/cmk v0.10.0
github.com/confluentinc/ccloud-sdk-go-v2/connect v0.7.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2 h1:BV/dPTFVovJPylrcr9lcSmuk
github.com/confluentinc/ccloud-sdk-go-v2/byok v0.0.2/go.mod h1:MMtRTfg1g32bQrRwfqvGpe+grS5pQzeq9V+L5GKydV4=
github.com/confluentinc/ccloud-sdk-go-v2/cdx v0.0.5 h1:w0Z2hFxg8ng8gycWKRZFdus1R+q8D/I5AmN06NZso5s=
github.com/confluentinc/ccloud-sdk-go-v2/cdx v0.0.5/go.mod h1:L8U9xs2duASJnjIYkwGrSbZNpApsbh+vlxsJlZMHJPA=
github.com/confluentinc/ccloud-sdk-go-v2/certificate-authority v0.0.0-20240827200211-50926cdd47e0 h1:aY45SFMNIfxcawL54T0Xgod25dT8UjXACj7XYjbRWSw=
github.com/confluentinc/ccloud-sdk-go-v2/certificate-authority v0.0.0-20240827200211-50926cdd47e0/go.mod h1:xqB2YHUtcYF5cbwctSDzXoYw0YXaawj13d0lzcvphEA=
github.com/confluentinc/ccloud-sdk-go-v2/cli v0.3.0 h1:OOFNqtZN3Spuzz4TX6K6JfDM7zNDIE6BE1TtK78jFHQ=
github.com/confluentinc/ccloud-sdk-go-v2/cli v0.3.0/go.mod h1:Mv0WTsBXUfKjmF+r2t2Dv/xJzZf17shhf5J1cttU2Qo=
github.com/confluentinc/ccloud-sdk-go-v2/cmk v0.10.0 h1:YQEcSvhX5ODllg0mhxLivckKU3f5OF7s6zgABZporgA=
Expand Down
2 changes: 2 additions & 0 deletions internal/iam/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ func New(cfg *config.Config, prerunner pcmd.PreRunner) *cobra.Command {
cmd.AddCommand(newGroupMappingCommand(prerunner))
}
cmd.AddCommand(newAclCommand(prerunner))
cmd.AddCommand(newCertificateAuthorityCommand(cfg, prerunner))
cmd.AddCommand(newCertificatePoolCommand(cfg, prerunner))
cmd.AddCommand(newIpFilterCommand(prerunner))
cmd.AddCommand(newIpGroupCommand(prerunner))
cmd.AddCommand(newPoolCommand(prerunner))
Expand Down
79 changes: 79 additions & 0 deletions internal/iam/command_certificate_authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package iam

import (
"time"

"github.com/spf13/cobra"

certificateauthorityv2 "github.com/confluentinc/ccloud-sdk-go-v2/certificate-authority/v2"

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

type certificateAuthorityCommand struct {
*pcmd.AuthenticatedCLICommand
}

type certificateAuthorityOut struct {
Id string `human:"ID" serialized:"id"`
Name string `human:"Name" serialized:"name"`
Description string `human:"Description" serialized:"description"`
Fingerprints []string `human:"Fingerprints" serialized:"fingerprints"`
ExpirationDates []time.Time `human:"Expiration Dates" serialized:"expiration_dates"`
SerialNumbers []string `human:"Serial Numbers" serialized:"serial_numbers"`
CertificateChainFilename string `human:"Certificate Chain Filename" serialized:"certificate_chain_filename"`
State string `human:"State" serialized:"state"`
}

func newCertificateAuthorityCommand(cfg *config.Config, prerunner pcmd.PreRunner) *cobra.Command {
cmd := &cobra.Command{
Use: "certificate-authority",
Short: "Manage certificate authorities.",
Annotations: map[string]string{pcmd.RunRequirement: pcmd.RequireCloudLogin},
Hidden: !(cfg.IsTest || featureflags.Manager.BoolVariation("cli.mtls", cfg.Context(), config.CliLaunchDarklyClient, true, false)),
}

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

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

return cmd
}

func printCertificateAuthority(cmd *cobra.Command, certificateAuthority certificateauthorityv2.IamV2CertificateAuthority) error {
table := output.NewTable(cmd)
table.Add(&certificateAuthorityOut{
Id: certificateAuthority.GetId(),
Name: certificateAuthority.GetDisplayName(),
Description: certificateAuthority.GetDescription(),
Fingerprints: certificateAuthority.GetFingerprints(),
ExpirationDates: certificateAuthority.GetExpirationDates(),
SerialNumbers: certificateAuthority.GetSerialNumbers(),
CertificateChainFilename: certificateAuthority.GetCertificateChainFilename(),
State: certificateAuthority.GetState(),
})
return table.Print()
}

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

return c.validArgsMultiple(cmd, args)
}

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

return pcmd.AutocompleteCertificateAuthorities(c.V2Client)
}
89 changes: 89 additions & 0 deletions internal/iam/command_certificate_authority_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package iam

import (
"github.com/spf13/cobra"

certificateauthorityv2 "github.com/confluentinc/ccloud-sdk-go-v2/certificate-authority/v2"

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

func (c *certificateAuthorityCommand) newCreateCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "create <name>",
Short: "Create a certificate authority.",
Args: cobra.ExactArgs(1),
RunE: c.create,
Example: examples.BuildExampleString(
examples.Example{
Text: `Create the certificate authority "my-ca" using the certificate chain stored in the "CERTIFICATE_CHAIN" environment variable:`,
Code: `confluent iam certificate-authority create my-ca --description "my certificate authority" --certificate-chain $CERTIFICATE_CHAIN --certificate-chain-filename certificate.pem`,
},
examples.Example{
Text: "An example of a certificate chain:",
Code: `-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----`,
},
),
}

cmd.Flags().String("description", "", "Description of the certificate authority.")
cmd.Flags().String("certificate-chain", "", "A base64 encoded string containing the signing certificate chain.")
cmd.Flags().String("certificate-chain-filename", "", "The name of the certificate file.")
pcmd.AddContextFlag(cmd, c.CLICommand)
pcmd.AddOutputFlag(cmd)

cobra.CheckErr(cmd.MarkFlagRequired("description"))
cobra.CheckErr(cmd.MarkFlagRequired("certificate-chain"))
cobra.CheckErr(cmd.MarkFlagRequired("certificate-chain-filename"))

return cmd
}

func (c *certificateAuthorityCommand) create(cmd *cobra.Command, args []string) error {
description, err := cmd.Flags().GetString("description")
if err != nil {
return err
}

certificateChain, err := cmd.Flags().GetString("certificate-chain")
if err != nil {
return err
}

certificateChainFilename, err := cmd.Flags().GetString("certificate-chain-filename")
if err != nil {
return err
}

certRequest := certificateauthorityv2.IamV2CreateCertRequest{
DisplayName: certificateauthorityv2.PtrString(args[0]),
Description: certificateauthorityv2.PtrString(description),
CertificateChain: certificateauthorityv2.PtrString(certificateChain),
CertificateChainFilename: certificateauthorityv2.PtrString(certificateChainFilename),
}

certificateAuthority, err := c.V2Client.CreateCertificateAuthority(certRequest)
if err != nil {
return err
}

return printCertificateAuthority(cmd, certificateAuthority)
}
49 changes: 49 additions & 0 deletions internal/iam/command_certificate_authority_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package iam

import (
"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/examples"
"github.com/confluentinc/cli/v3/pkg/resource"
)

func (c *certificateAuthorityCommand) newDeleteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "delete <id-1> [id-2] ... [id-n]",
Short: "Delete one or more certificate authorities.",
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: pcmd.NewValidArgsFunction(c.validArgsMultiple),
RunE: c.delete,
Example: examples.BuildExampleString(
examples.Example{
Text: `Delete certificate authority "op-123456":`,
Code: "confluent iam certificate-authority delete op-123456",
},
),
}

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

return cmd
}

func (c *certificateAuthorityCommand) delete(cmd *cobra.Command, args []string) error {
existenceFunc := func(id string) bool {
_, err := c.V2Client.GetCertificateAuthority(id)
return err == nil
}

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

deleteFunc := func(id string) error {
return c.V2Client.DeleteCertificateAuthority(id)
}

_, err := deletion.Delete(args, deleteFunc, resource.CertificateAuthority)
return err
}
31 changes: 31 additions & 0 deletions internal/iam/command_certificate_authority_describe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package iam

import (
"github.com/spf13/cobra"

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

func (c *certificateAuthorityCommand) newDescribeCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "describe <id>",
Short: "Describe a certificate authority.",
Args: cobra.ExactArgs(1),
ValidArgsFunction: pcmd.NewValidArgsFunction(c.validArgs),
RunE: c.describe,
}

pcmd.AddContextFlag(cmd, c.CLICommand)
pcmd.AddOutputFlag(cmd)

return cmd
}

func (c *certificateAuthorityCommand) describe(cmd *cobra.Command, args []string) error {
certificateAuthority, err := c.V2Client.GetCertificateAuthority(args[0])
if err != nil {
return err
}

return printCertificateAuthority(cmd, certificateAuthority)
}
44 changes: 44 additions & 0 deletions internal/iam/command_certificate_authority_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package iam

import (
"github.com/spf13/cobra"

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

func (c *certificateAuthorityCommand) newListCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List certificate authorities.",
Args: cobra.NoArgs,
RunE: c.list,
}

pcmd.AddContextFlag(cmd, c.CLICommand)
pcmd.AddOutputFlag(cmd)

return cmd
}

func (c *certificateAuthorityCommand) list(cmd *cobra.Command, _ []string) error {
certificateAuthorities, err := c.V2Client.ListCertificateAuthorities()
if err != nil {
return err
}

list := output.NewList(cmd)
for _, certificateAuthority := range certificateAuthorities {
list.Add(&certificateAuthorityOut{
Id: certificateAuthority.GetId(),
Name: certificateAuthority.GetDisplayName(),
Description: certificateAuthority.GetDescription(),
Fingerprints: certificateAuthority.GetFingerprints(),
ExpirationDates: certificateAuthority.GetExpirationDates(),
SerialNumbers: certificateAuthority.GetSerialNumbers(),
CertificateChainFilename: certificateAuthority.GetCertificateChainFilename(),
State: certificateAuthority.GetState(),
})
}
return list.Print()
}
Loading

0 comments on commit 6bf2a10

Please sign in to comment.