Skip to content

Commit abbc485

Browse files
committed
add exmaples in cobra command help
1 parent 77da3d6 commit abbc485

File tree

6 files changed

+191
-40
lines changed

6 files changed

+191
-40
lines changed

.goreleaser.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ builds:
1818
- amd64
1919
- arm64
2020
ignore:
21-
- goos: darwin
22-
goarch: arm64
2321
- goos: windows
2422
goarch: arm64
2523

.krew.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ spec:
1515
os: darwin
1616
arch: amd64
1717
uri: https://github.com/lmolas/kubectl-view-cert/releases/download/v0.0.1/kubectl-view-cert_v0.0.1.darwin_amd64.tar.gz
18-
sha256: a29565aa95ddb6a87dd1decbd1a4b7633184ad3017c17b56a1e5e5b302993785
18+
sha256: ac7305dcab0913945f2edb32e804673cc38bf7eceef0409bd595f603fe8e20f8
1919
bin: kubectl-view-cert

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
[![Go Report Card](https://goreportcard.com/badge/github.com/lmolas/kubectl-view-cert)](https://goreportcard.com/report/github.com/lmolas/kubectl-view-cert)
1+
[![Go Report Card](https://goreportcard.com/badge/github.com/lmolas/kubectl-view-cert)](https://goreportcard.com/report/github.com/lmolas/kubectl-view-cert)
22
[![github actions](https://github.com/lmolas/kubectl-view-cert/workflows/golangci-lint/badge.svg)](https://github.com/lmolas/kubectl-view-cert/actions?query=workflow%3Agolangci-lint)
3-
![github actions](https://github.com/lmolas/kubectl-view-cert/workflows/release/badge.svg)
43
[![GitHub release](https://img.shields.io/github/v/release/lmolas/kubectl-view-cert)](https://github.com/lmolas/kubectl-view-cert/releases/latest)
54
[![License](https://img.shields.io/github/license/lmolas/kubectl-view-cert)](LICENSE)
65

7-
86
# kubectl-view-cert
7+
98
A kubectl plugin to view certificate information stored in secrets.
109

1110
## Installation

cmd/kubectl-view-cert/root.go

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"encoding/json"
56
"errors"
67
"flag"
@@ -38,9 +39,28 @@ var rootCmd = &cobra.Command{
3839
Use: "kubectl view-cert [flags] [secret-name [secret-key]]",
3940
SilenceUsage: true, // for when RunE returns an error
4041
Short: "View certificate information stored in secrets",
41-
Example: "kubectl view-cert",
42-
RunE: run,
43-
Version: versionString(),
42+
Example: "# List certificates from secrets in current namespace \n" +
43+
"kubectl view-cert \n" +
44+
"\n" +
45+
"# List certificates from secrets in all namespaces \n" +
46+
"kubectl view-cert -A \n" +
47+
"\n" +
48+
"# List expired certificates from secrets in all namespaces \n" +
49+
"kubectl view-cert -A -E \n" +
50+
"\n" +
51+
"# List certificates that will expire in 90 days in all namespaces \n" +
52+
"kubectl view-cert -A -D 90 \n" +
53+
"\n" +
54+
"# If you want to include CA certificate informations you can use -S flag \n" +
55+
"\n" +
56+
"# View certificate from a specific secret (secret is parsed only if its type is kubernetes.io.tls) \n" +
57+
"kubectl view-cert mysecret \n" +
58+
"\n" +
59+
"# View certificate from a specific key in a specific secret (secret type could be anything as long as secret key contains base64 pem encoded data) \n" +
60+
"kubectl view-cert mysecret mykey \n",
61+
62+
RunE: run,
63+
Version: versionString(),
4464
}
4565

4666
// versionString returns the version prefixed by 'v'
@@ -93,61 +113,78 @@ func getNamespace() string {
93113
func main() {
94114
defer klog.Flush()
95115
if err := rootCmd.Execute(); err != nil {
96-
klog.Error(err)
97116
return
98117
}
99118
}
100119

101-
func run(command *cobra.Command, args []string) error {
102-
klog.V(1).Info("Run kubectl view-cert")
103-
104-
// Parse flags and arguments
120+
func parseFlagsAndArguments(command *cobra.Command, args []string) (allNs, expired, showCaCert bool, expiredInDays int, secretName, secretKey string) {
105121
allNs, err := command.Flags().GetBool(allNamespacesFlag)
106122
if err != nil {
107123
allNs = false
108124
}
109125

110-
expired, err := command.Flags().GetBool(expiredFlag)
126+
expired, err = command.Flags().GetBool(expiredFlag)
111127
if err != nil {
112128
expired = false
113129
}
114130

115-
showCaCert, err := command.Flags().GetBool(showCaCertFlag)
131+
showCaCert, err = command.Flags().GetBool(showCaCertFlag)
116132
if err != nil {
117133
showCaCert = false
118134
}
119135

120-
expiredInDays, err := command.Flags().GetInt(expiredDaysFromNowFlag)
136+
expiredInDays, err = command.Flags().GetInt(expiredDaysFromNowFlag)
121137
if err != nil {
122138
expiredInDays = 0
123139
}
124140

125-
var secretName string
126141
if len(args) > 0 {
127142
secretName = args[0]
128143
}
129144

130-
var secretKey string
131145
if len(args) > 1 {
132146
secretKey = args[1]
133147
}
134148

149+
return
150+
}
151+
152+
func run(command *cobra.Command, args []string) error {
153+
klog.V(1).Info("Run kubectl view-cert")
154+
155+
ctx := context.Background()
156+
157+
// Parse flags and arguments
158+
allNs, expired, showCaCert, expiredInDays, secretName, secretKey := parseFlagsAndArguments(command, args)
159+
160+
// Validate inputs
161+
if allNs && secretName != "" {
162+
return errors.New("a resource cannot be retrieved by name across all namespaces")
163+
}
164+
165+
if secretName != "" && (expired || expiredInDays != 0 || showCaCert) {
166+
return errors.New("when specifying secret name, no flags are allowed, only a second argument with secret key is allowed")
167+
}
168+
135169
// Prepare clients to interact with kubernetes api
136170
ns, ri, err := getResourceInterface(allNs, secretName)
137171
if err != nil {
138172
return err
139173
}
140174

141175
if secretName != "" {
142-
datas, err := getData(secretName, ns, secretKey, ri)
176+
datas, err := getData(ctx, secretName, ns, secretKey, ri)
143177
if err != nil {
144178
return err
145179
}
146180

147181
// Display
148-
displayDatas(datas)
182+
err = displayDatas(datas)
183+
if err != nil {
184+
return err
185+
}
149186
} else {
150-
datas, err := getDatas(ri)
187+
datas, err := getDatas(ctx, ri)
151188
if err != nil {
152189
return err
153190
}
@@ -168,17 +205,20 @@ func run(command *cobra.Command, args []string) error {
168205
}
169206

170207
// Display
171-
displayDatas(filteredDatas)
208+
err = displayDatas(filteredDatas)
209+
if err != nil {
210+
return err
211+
}
172212
}
173213

174214
return nil
175215
}
176216

177-
func getDatas(ri dynamic.ResourceInterface) ([]*Certificate, error) {
217+
func getDatas(ctx context.Context, ri dynamic.ResourceInterface) ([]*Certificate, error) {
178218
klog.V(1).Info("Scanning secrets")
179219
datas := make([]*Certificate, 0)
180220

181-
tlsSecrets, err := ri.List(v1.ListOptions{FieldSelector: "type=kubernetes.io/tls"})
221+
tlsSecrets, err := ri.List(ctx, v1.ListOptions{FieldSelector: "type=kubernetes.io/tls"})
182222
if err != nil {
183223
return datas, fmt.Errorf("failed to get secrets: %w", err)
184224
}
@@ -201,12 +241,12 @@ func getDatas(ri dynamic.ResourceInterface) ([]*Certificate, error) {
201241
return datas, nil
202242
}
203243

204-
func getData(secretName, ns, secretKey string, ri dynamic.ResourceInterface) ([]*Certificate, error) {
244+
func getData(ctx context.Context, secretName, ns, secretKey string, ri dynamic.ResourceInterface) ([]*Certificate, error) {
205245
klog.V(1).Infof("Get secret name %s in namespace %s", secretName, ns)
206246

207247
datas := make([]*Certificate, 0)
208248

209-
secret, err := ri.Get(secretName, v1.GetOptions{})
249+
secret, err := ri.Get(ctx, secretName, v1.GetOptions{})
210250
if err != nil {
211251
return datas, fmt.Errorf("failed to get secret with name %s: %w", secretName, err)
212252
}
@@ -227,13 +267,10 @@ func getData(secretName, ns, secretKey string, ri dynamic.ResourceInterface) ([]
227267
return datas, nil
228268
}
229269

230-
func displayDatas(datas []*Certificate) {
270+
func displayDatas(datas []*Certificate) error {
231271
encoder := json.NewEncoder(os.Stdout)
232272
encoder.SetIndent("", " ")
233-
err := encoder.Encode(&datas)
234-
if err != nil {
235-
klog.Error(err)
236-
}
273+
return encoder.Encode(&datas)
237274
}
238275

239276
func getResourceInterface(allNs bool, secretName string) (string, dynamic.ResourceInterface, error) {
@@ -281,14 +318,12 @@ func parseData(ns, secretName string, data map[string]interface{}, secretKey str
281318

282319
secretCertData, err := parse.NewCertificateData(ns, secretName, data, secretKey)
283320
if err != nil {
284-
klog.Errorf("failed to parse secret with name %s in namespace %s %v", secretName, ns, err)
285-
return nil, nil, err
321+
return nil, nil, fmt.Errorf("failed to parse secret with name %s in namespace %s %v", secretName, ns, err)
286322
}
287323

288324
parsedCerts, err := secretCertData.ParseCertificates()
289325
if err != nil {
290-
klog.Errorf("unable to parse certificates for secret %s in namespace %s %v", secretName, ns, err)
291-
return nil, nil, err
326+
return nil, nil, fmt.Errorf("unable to parse certificates for secret %s in namespace %s %v", secretName, ns, err)
292327
}
293328

294329
if parsedCerts.Certificate != nil {

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ module github.com/lmolas/kubectl-view-cert
33
go 1.14
44

55
require (
6-
github.com/spf13/cobra v0.0.5
6+
github.com/spf13/cobra v1.0.0
77
github.com/spf13/pflag v1.0.5
8-
k8s.io/apimachinery v0.17.0
9-
k8s.io/cli-runtime v0.17.0
10-
k8s.io/client-go v0.17.0
8+
k8s.io/apimachinery v0.18.9
9+
k8s.io/cli-runtime v0.18.9
10+
k8s.io/client-go v0.18.9
1111
k8s.io/klog v1.0.0
1212
)

0 commit comments

Comments
 (0)