From de64d287f0104548477bc43529889cfaee8ddbd6 Mon Sep 17 00:00:00 2001 From: John Gardiner Myers Date: Thu, 22 Jul 2021 16:12:13 -0700 Subject: [PATCH] Replace "kops describe keypair" with "kops get keypair -oyaml" --- cmd/kops/BUILD.bazel | 2 - cmd/kops/describe.go | 53 ---------- cmd/kops/describe_keypairs.go | 152 ----------------------------- cmd/kops/get_keypairs.go | 72 +++++++++++--- docs/cli/kops.md | 1 - docs/cli/kops_describe.md | 49 ---------- docs/cli/kops_describe_keypairs.md | 53 ---------- docs/secrets.md | 4 - mkdocs.yml | 1 - 9 files changed, 56 insertions(+), 331 deletions(-) delete mode 100644 cmd/kops/describe.go delete mode 100644 cmd/kops/describe_keypairs.go delete mode 100644 docs/cli/kops_describe.md delete mode 100644 docs/cli/kops_describe_keypairs.md diff --git a/cmd/kops/BUILD.bazel b/cmd/kops/BUILD.bazel index cc66aced6f..8541ab6d38 100644 --- a/cmd/kops/BUILD.bazel +++ b/cmd/kops/BUILD.bazel @@ -18,8 +18,6 @@ go_library( "delete_instance.go", "delete_instancegroup.go", "delete_secret.go", - "describe.go", - "describe_keypairs.go", "distrust.go", "distrust_keypair.go", "edit.go", diff --git a/cmd/kops/describe.go b/cmd/kops/describe.go deleted file mode 100644 index c7c0abac9c..0000000000 --- a/cmd/kops/describe.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "github.com/spf13/cobra" - "k8s.io/kubectl/pkg/util/i18n" - "k8s.io/kubectl/pkg/util/templates" -) - -var ( - describeLong = templates.LongDesc(i18n.T(` - Get additional information about cloud and cluster resources. - `)) - - describeExample = templates.Examples(i18n.T(` - `)) - describeShort = i18n.T(`Describe a resource.`) -) - -// DescribeCmd represents the describe command -type DescribeCmd struct { - cobraCommand *cobra.Command -} - -var describeCmd = DescribeCmd{ - cobraCommand: &cobra.Command{ - Use: "describe", - Short: describeShort, - Long: describeLong, - Example: describeExample, - }, -} - -func init() { - cmd := describeCmd.cobraCommand - - rootCommand.AddCommand(cmd) -} diff --git a/cmd/kops/describe_keypairs.go b/cmd/kops/describe_keypairs.go deleted file mode 100644 index 13a8b9c7de..0000000000 --- a/cmd/kops/describe_keypairs.go +++ /dev/null @@ -1,152 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "bytes" - "context" - "crypto/rsa" - "fmt" - "os" - "sort" - "strings" - "text/tabwriter" - - "github.com/spf13/cobra" - "k8s.io/kops/pkg/pki" - "k8s.io/kubectl/pkg/util/i18n" - "k8s.io/kubectl/pkg/util/templates" -) - -var ( - describeKeypairLong = templates.LongDesc(i18n.T(` - Get additional information about keypairs. - `)) - - describeKeypairExample = templates.Examples(i18n.T(` - # Describe a keypair - kops describe keypairs ca - `)) - describeKeypairShort = i18n.T(`Describe a cluster keypair`) -) - -type DescribeKeypairsCommand struct { -} - -var describeKeypairsCommand DescribeKeypairsCommand - -func init() { - cmd := &cobra.Command{ - Use: "keypairs", - Aliases: []string{"keypair"}, - Short: describeKeypairShort, - Long: describeKeypairLong, - Example: describeKeypairExample, - Run: func(cmd *cobra.Command, args []string) { - ctx := context.TODO() - err := describeKeypairsCommand.Run(ctx, args) - if err != nil { - exitWithError(err) - } - }, - } - - describeCmd.cobraCommand.AddCommand(cmd) -} - -func (c *DescribeKeypairsCommand) Run(ctx context.Context, args []string) error { - cluster, err := rootCommand.Cluster(ctx) - if err != nil { - return err - } - - clientset, err := rootCommand.Clientset() - if err != nil { - return err - } - - keyStore, err := clientset.KeyStore(cluster) - if err != nil { - return err - } - - items, err := listKeypairs(keyStore, args, false) - if err != nil { - return err - } - - if len(items) == 0 { - fmt.Fprintf(os.Stderr, "No keypairs found\n") - - return nil - } - - w := new(tabwriter.Writer) - var b bytes.Buffer - - // Format in tab-separated columns with a tab stop of 8. - w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.StripEscape) - - for _, i := range items { - fmt.Fprintf(w, "Name:\t%s\n", i.Name) - fmt.Fprintf(w, "Id:\t%s\n", i.Id) - - err = describeKeypair(i, &b) - if err != nil { - return err - } - - b.WriteString("\n") - _, err = w.Write(b.Bytes()) - if err != nil { - return fmt.Errorf("error writing to output: %v", err) - } - - b.Reset() - } - - return w.Flush() -} - -func describeKeypair(item *keypairItem, w *bytes.Buffer) error { - cert := item.Certificate - - if cert != nil { - var alternateNames []string - alternateNames = append(alternateNames, cert.Certificate.DNSNames...) - alternateNames = append(alternateNames, cert.Certificate.EmailAddresses...) - for _, ip := range cert.Certificate.IPAddresses { - alternateNames = append(alternateNames, ip.String()) - } - sort.Strings(alternateNames) - - fmt.Fprintf(w, "Subject:\t%s\n", pki.PkixNameToString(&cert.Certificate.Subject)) - fmt.Fprintf(w, "Issuer:\t%s\n", pki.PkixNameToString(&cert.Certificate.Issuer)) - fmt.Fprintf(w, "AlternateNames:\t%s\n", strings.Join(alternateNames, ", ")) - fmt.Fprintf(w, "CA:\t%v\n", cert.IsCA) - fmt.Fprintf(w, "NotAfter:\t%s\n", cert.Certificate.NotAfter) - fmt.Fprintf(w, "NotBefore:\t%s\n", cert.Certificate.NotBefore) - if rsaKey, ok := cert.PublicKey.(*rsa.PublicKey); ok { - fmt.Fprintf(w, "KeyLength:\t%v\n", rsaKey.N.BitLen()) - } - // PublicKeyAlgorithm doesn't have a String() function. Also, is this important information? - //fmt.Fprintf(w, "PublicKeyAlgorithm:\t%v\n", c.Certificate.PublicKeyAlgorithm) - //fmt.Fprintf(w, "SignatureAlgorithm:\t%v\n", c.Certificate.SignatureAlgorithm) - } - - return nil -} diff --git a/cmd/kops/get_keypairs.go b/cmd/kops/get_keypairs.go index 4db11d43ab..f8baae890a 100644 --- a/cmd/kops/get_keypairs.go +++ b/cmd/kops/get_keypairs.go @@ -18,19 +18,22 @@ package main import ( "context" + "crypto/rsa" + "encoding/json" "fmt" "io" + "sort" "time" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/kops/cmd/kops/util" "k8s.io/kops/pkg/commands/commandutils" - "k8s.io/kops/pkg/pki" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/util/pkg/tables" "k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/templates" + "sigs.k8s.io/yaml" ) var ( @@ -82,12 +85,18 @@ func NewCmdGetKeypairs(f *util.Factory, out io.Writer, getOptions *GetOptions) * } type keypairItem struct { - Name string - Id string - DistrustTimestamp *time.Time - IsPrimary bool - Certificate *pki.Certificate - HasPrivateKey bool + Name string `json:"name"` + ID string `json:"id"` + DistrustTimestamp *time.Time `json:"distrustTimestamp,omitempty"` + IsPrimary bool `json:"isPrimary,omitempty"` + Subject string `json:"subject"` + Issuer string `json:"issuer"` + AlternateNames []string `json:"alternateNames,omitempty"` + IsCA bool `json:"isCA,omitempty"` + NotBefore time.Time `json:"notBefore"` + NotAfter time.Time `json:"notAfter"` + KeyLength *int `json:"keyLength,omitempty"` + HasPrivateKey bool `json:"hasPrivateKey,omitempty"` } func listKeypairs(keyStore fi.CAStore, names []string, includeDistrusted bool) ([]*keypairItem, error) { @@ -114,14 +123,31 @@ func listKeypairs(keyStore fi.CAStore, names []string, includeDistrusted bool) ( for _, item := range keyset.Items { if includeDistrusted || item.DistrustTimestamp == nil { - items = append(items, &keypairItem{ + var alternateNames []string + alternateNames = append(alternateNames, item.Certificate.Certificate.DNSNames...) + alternateNames = append(alternateNames, item.Certificate.Certificate.EmailAddresses...) + for _, ip := range item.Certificate.Certificate.IPAddresses { + alternateNames = append(alternateNames, ip.String()) + } + sort.Strings(alternateNames) + + keypair := keypairItem{ Name: name, - Id: item.Id, + ID: item.Id, DistrustTimestamp: item.DistrustTimestamp, IsPrimary: item.Id == keyset.Primary.Id, - Certificate: item.Certificate, + Subject: item.Certificate.Subject.String(), + Issuer: item.Certificate.Certificate.Issuer.String(), + AlternateNames: alternateNames, + IsCA: item.Certificate.IsCA, + NotBefore: item.Certificate.Certificate.NotBefore.UTC(), + NotAfter: item.Certificate.Certificate.NotAfter.UTC(), HasPrivateKey: item.PrivateKey != nil, - }) + } + if rsaKey, ok := item.Certificate.PublicKey.(*rsa.PublicKey); ok { + keypair.KeyLength = fi.Int(rsaKey.N.BitLen()) + } + items = append(items, &keypair) } } } @@ -161,7 +187,7 @@ func RunGetKeypairs(ctx context.Context, f commandutils.Factory, out io.Writer, return i.Name }) t.AddColumn("ID", func(i *keypairItem) string { - return i.Id + return i.ID }) t.AddColumn("DISTRUSTED", func(i *keypairItem) string { if i.DistrustTimestamp != nil { @@ -170,10 +196,10 @@ func RunGetKeypairs(ctx context.Context, f commandutils.Factory, out io.Writer, return "" }) t.AddColumn("ISSUED", func(i *keypairItem) string { - return i.Certificate.Certificate.NotBefore.Local().Format("2006-01-02") + return i.NotBefore.Local().Format("2006-01-02") }) t.AddColumn("EXPIRES", func(i *keypairItem) string { - return i.Certificate.Certificate.NotAfter.Local().Format("2006-01-02") + return i.NotAfter.Local().Format("2006-01-02") }) t.AddColumn("PRIMARY", func(i *keypairItem) string { if i.IsPrimary { @@ -195,13 +221,27 @@ func RunGetKeypairs(ctx context.Context, f commandutils.Factory, out io.Writer, return t.Render(items, out, columnNames...) case OutputYaml: - return fmt.Errorf("yaml output format is not (currently) supported for keypairs") + y, err := yaml.Marshal(items) + if err != nil { + return fmt.Errorf("unable to marshal YAML: %v", err) + } + if _, err := out.Write(y); err != nil { + return fmt.Errorf("error writing to output: %v", err) + } case OutputJSON: - return fmt.Errorf("json output format is not (currently) supported for keypairs") + j, err := json.Marshal(items) + if err != nil { + return fmt.Errorf("unable to marshal JSON: %v", err) + } + if _, err := out.Write(j); err != nil { + return fmt.Errorf("error writing to output: %v", err) + } default: return fmt.Errorf("Unknown output format: %q", options.Output) } + + return nil } func completeGetKeypairs(options *GetKeypairsOptions, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/docs/cli/kops.md b/docs/cli/kops.md index 9b2dafd1fd..8708b340a6 100644 --- a/docs/cli/kops.md +++ b/docs/cli/kops.md @@ -40,7 +40,6 @@ kOps is Kubernetes Operations. * [kops completion](kops_completion.md) - generate the autocompletion script for the specified shell * [kops create](kops_create.md) - Create a resource by command line, filename or stdin. * [kops delete](kops_delete.md) - Delete clusters, instancegroups, instances, and secrets. -* [kops describe](kops_describe.md) - Describe a resource. * [kops distrust](kops_distrust.md) - Distrust keypairs. * [kops edit](kops_edit.md) - Edit clusters and other resources. * [kops export](kops_export.md) - Export configuration. diff --git a/docs/cli/kops_describe.md b/docs/cli/kops_describe.md deleted file mode 100644 index 6130b35428..0000000000 --- a/docs/cli/kops_describe.md +++ /dev/null @@ -1,49 +0,0 @@ - - - -## kops describe - -Describe a resource. - -### Synopsis - -Get additional information about cloud and cluster resources. - -### Examples - -``` - -``` - -### Options - -``` - -h, --help help for describe -``` - -### Options inherited from parent commands - -``` - --add_dir_header If true, adds the file directory to the header of the log messages - --alsologtostderr log to standard error as well as files - --config string yaml config file (default is $HOME/.kops.yaml) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) - --log_dir string If non-empty, write log files in this directory - --log_file string If non-empty, use this log file - --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) - --logtostderr log to standard error instead of files (default true) - --name string Name of cluster. Overrides KOPS_CLUSTER_NAME environment variable - --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) - --skip_headers If true, avoid header prefixes in the log messages - --skip_log_headers If true, avoid headers when opening log files - --state string Location of state storage (kops 'config' file). Overrides KOPS_STATE_STORE environment variable - --stderrthreshold severity logs at or above this threshold go to stderr (default 2) - -v, --v Level number for the log level verbosity - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kops](kops.md) - kOps is Kubernetes Operations. -* [kops describe keypairs](kops_describe_keypairs.md) - Describe a cluster keypair - diff --git a/docs/cli/kops_describe_keypairs.md b/docs/cli/kops_describe_keypairs.md deleted file mode 100644 index c2253a17d4..0000000000 --- a/docs/cli/kops_describe_keypairs.md +++ /dev/null @@ -1,53 +0,0 @@ - - - -## kops describe keypairs - -Describe a cluster keypair - -### Synopsis - -Get additional information about keypairs. - -``` -kops describe keypairs [flags] -``` - -### Examples - -``` - # Describe a keypair - kops describe keypairs ca -``` - -### Options - -``` - -h, --help help for keypairs -``` - -### Options inherited from parent commands - -``` - --add_dir_header If true, adds the file directory to the header of the log messages - --alsologtostderr log to standard error as well as files - --config string yaml config file (default is $HOME/.kops.yaml) - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) - --log_dir string If non-empty, write log files in this directory - --log_file string If non-empty, use this log file - --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) - --logtostderr log to standard error instead of files (default true) - --name string Name of cluster. Overrides KOPS_CLUSTER_NAME environment variable - --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) - --skip_headers If true, avoid header prefixes in the log messages - --skip_log_headers If true, avoid headers when opening log files - --state string Location of state storage (kops 'config' file). Overrides KOPS_STATE_STORE environment variable - --stderrthreshold severity logs at or above this threshold go to stderr (default 2) - -v, --v Level number for the log level verbosity - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging -``` - -### SEE ALSO - -* [kops describe](kops_describe.md) - Describe a resource. - diff --git a/docs/secrets.md b/docs/secrets.md index b66304ce09..1b4990a3dc 100644 --- a/docs/secrets.md +++ b/docs/secrets.md @@ -6,10 +6,6 @@ -oplaintext exposes the raw secret value. -### describe secret - -`kops describe secret` - ### create secret `kops create secret sshpublickey admin -i ~/.ssh/id_rsa.pub` diff --git a/mkdocs.yml b/mkdocs.yml index 92705cd4aa..9f4014ead2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -52,7 +52,6 @@ nav: - kops completion: "cli/kops_completion.md" - kops create: "cli/kops_create.md" - kops delete: "cli/kops_delete.md" - - kops describe: "cli/kops_describe.md" - kops distrust: "cli/kops_distrust.md" - kops edit: "cli/kops_edit.md" - kops export: "cli/kops_export.md"