Skip to content

Commit

Permalink
Add kn secret command (#1791)
Browse files Browse the repository at this point in the history
* Add kn secret command

* Update vendor dir

* Apply suggestions from code review

Co-authored-by: Gunjan Vyas <vyasgun20@gmail.com>

* Fix nits from the review feedback

* Rerun docs generation

---------

Co-authored-by: Gunjan Vyas <vyasgun20@gmail.com>
  • Loading branch information
dsimansk and vyasgun authored Apr 24, 2023
1 parent 1895926 commit 1231cd2
Show file tree
Hide file tree
Showing 235 changed files with 22,674 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/cmd/kn.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Find more information about Knative at: https://knative.dev
* [kn plugin](kn_plugin.md) - Manage kn plugins
* [kn revision](kn_revision.md) - Manage service revisions
* [kn route](kn_route.md) - List and describe service routes
* [kn secret](kn_secret.md) - Manage secrets
* [kn service](kn_service.md) - Manage Knative services
* [kn source](kn_source.md) - Manage event sources
* [kn subscription](kn_subscription.md) - Manage event subscriptions
Expand Down
34 changes: 34 additions & 0 deletions docs/cmd/kn_secret.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## kn secret

Manage secrets

```
kn secret COMMAND
```

### Options

```
-h, --help help for secret
```

### Options inherited from parent commands

```
--as string username to impersonate for the operation
--as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups
--as-uid string uid to impersonate for the operation
--cluster string name of the kubeconfig cluster to use
--config string kn configuration file (default: ~/.config/kn/config.yaml)
--context string name of the kubeconfig context to use
--kubeconfig string kubectl configuration file (default: ~/.kube/config)
--log-http log http traffic
```

### SEE ALSO

* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn secret create](kn_secret_create.md) - Create secret
* [kn secret delete](kn_secret_delete.md) - Delete secret
* [kn secret list](kn_secret_list.md) - List secrets

36 changes: 36 additions & 0 deletions docs/cmd/kn_secret_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## kn secret create

Create secret

```
kn secret create NAME
```

### Options

```
-l, --from-literal strings Specify comma separated list of key=value pairs.
-h, --help help for create
-n, --namespace string Specify the namespace to operate in.
--tls-cert string Path to TLS certificate file.
--tls-key string Path to TLS key file.
--type string Specify Secret type.
```

### Options inherited from parent commands

```
--as string username to impersonate for the operation
--as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups
--as-uid string uid to impersonate for the operation
--cluster string name of the kubeconfig cluster to use
--config string kn configuration file (default: ~/.config/kn/config.yaml)
--context string name of the kubeconfig context to use
--kubeconfig string kubectl configuration file (default: ~/.kube/config)
--log-http log http traffic
```

### SEE ALSO

* [kn secret](kn_secret.md) - Manage secrets

32 changes: 32 additions & 0 deletions docs/cmd/kn_secret_delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## kn secret delete

Delete secret

```
kn secret delete NAME
```

### Options

```
-h, --help help for delete
-n, --namespace string Specify the namespace to operate in.
```

### Options inherited from parent commands

```
--as string username to impersonate for the operation
--as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups
--as-uid string uid to impersonate for the operation
--cluster string name of the kubeconfig cluster to use
--config string kn configuration file (default: ~/.config/kn/config.yaml)
--context string name of the kubeconfig context to use
--kubeconfig string kubectl configuration file (default: ~/.kube/config)
--log-http log http traffic
```

### SEE ALSO

* [kn secret](kn_secret.md) - Manage secrets

37 changes: 37 additions & 0 deletions docs/cmd/kn_secret_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## kn secret list

List secrets

```
kn secret list
```

### Options

```
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-h, --help help for list
-n, --namespace string Specify the namespace to operate in.
--no-headers When using the default output format, don't print headers (default: print headers).
-o, --output string Output format. One of: (json, yaml, name, go-template, go-template-file, template, templatefile, jsonpath, jsonpath-as-json, jsonpath-file).
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
```

### Options inherited from parent commands

```
--as string username to impersonate for the operation
--as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups
--as-uid string uid to impersonate for the operation
--cluster string name of the kubeconfig cluster to use
--config string kn configuration file (default: ~/.config/kn/config.yaml)
--context string name of the kubeconfig context to use
--kubeconfig string kubectl configuration file (default: ~/.kube/config)
--log-http log http traffic
```

### SEE ALSO

* [kn secret](kn_secret.md) - Manage secrets

102 changes: 102 additions & 0 deletions pkg/kn/commands/secret/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright © 2023 The Knative 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 secret

import (
"errors"
"fmt"
"os"

"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"knative.dev/client/pkg/util"

"knative.dev/client/pkg/kn/commands"
)

func NewSecretCreateCommand(p *commands.KnParams) *cobra.Command {
var literals []string
var cert, key, secretType string
cmd := &cobra.Command{
Use: "create NAME",
Short: "Create secret",
Example: ``,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {
return errors.New("'kn secret create' requires the secret name given as single argument")
}
name := args[0]
namespace, err := p.GetNamespace(cmd)
if err != nil {
return err
}
if cmd.Flags().Changed("from-literal") && (cmd.Flags().Changed("tls-cert") || cmd.Flags().Changed("tls-key")) {
return errors.New("TLS flags can't be combined with other options")
}
if cmd.Flags().Changed("tls-cert") != cmd.Flags().Changed("tls-key") {
return errors.New("both --tls-cert and --tls-key flags are required")
}

toCreate := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: name}}
// --from-literal
if len(literals) > 0 {
literalsMap, err := util.MapFromArray(literals, "=")
if err != nil {
return err
}
toCreate.StringData = literalsMap
}
// --tls-cert && --tls-key
if cert != "" && key != "" {
cerFromFile, err := os.ReadFile(cert)
if err != nil {
return err
}
keyFromFile, err := os.ReadFile(key)
if err != nil {
return err
}
certData := map[string]string{
"tls.cert": string(cerFromFile),
"tls.key": string(keyFromFile),
}
toCreate.Type = corev1.SecretTypeTLS
toCreate.StringData = certData
}
// override Secret type with provided value, otherwise `Opaque`
if secretType != "" {
toCreate.Type = corev1.SecretType(secretType)
}

client, err := p.NewKubeClient()
if err != nil {
return err
}
_, err = client.CoreV1().Secrets(namespace).Create(cmd.Context(), &toCreate, metav1.CreateOptions{})
if err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "Secret '%s' created in namespace '%s'.\n", name, namespace)
return nil
},
}
commands.AddNamespaceFlags(cmd.Flags(), false)
cmd.Flags().StringSliceVarP(&literals, "from-literal", "l", []string{}, "Specify comma separated list of key=value pairs.")
cmd.Flags().StringVar(&secretType, "type", "", "Specify Secret type.")
cmd.Flags().StringVar(&cert, "tls-cert", "", "Path to TLS certificate file.")
cmd.Flags().StringVar(&key, "tls-key", "", "Path to TLS key file.")
return cmd
}
50 changes: 50 additions & 0 deletions pkg/kn/commands/secret/create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright © 2021 The Knative 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 secret

import (
"testing"

"gotest.tools/v3/assert"
"k8s.io/client-go/kubernetes/fake"
"knative.dev/client/pkg/util"
)

func TestSecretCreate(t *testing.T) {
fakeClient := fake.NewSimpleClientset()

output, err := executeSecretCommand(fakeClient, "create", "foo", "--from-literal", "user=foo")
assert.NilError(t, err)
assert.Assert(t, util.ContainsAll(output, "created"))
}

func TestSecretCreateError(t *testing.T) {
fakeClient := fake.NewSimpleClientset()

_, err := executeSecretCommand(fakeClient, "create", "--from-literal", "user=foo")
assert.ErrorContains(t, err, "single argument")
}

func TestSecretCreateCertError(t *testing.T) {
fakeClient := fake.NewSimpleClientset()

_, err := executeSecretCommand(fakeClient, "create", "foo", "--tls-cert", "foo.cert")
assert.Assert(t, err != nil)
assert.Assert(t, util.ContainsAll(err.Error(), "--tls-cert", "--tls-key", "required"))

_, err = executeSecretCommand(fakeClient, "create", "foo", "-l", "k=v", "--tls-cert", "foo.cert")
assert.Assert(t, err != nil)
assert.Assert(t, util.ContainsAll(err.Error(), "combined", "options"))
}
48 changes: 48 additions & 0 deletions pkg/kn/commands/secret/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright © 2023 The Knative 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 secret

import (
"errors"

"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"knative.dev/client/pkg/kn/commands"
)

func NewSecretDeleteCommand(p *commands.KnParams) *cobra.Command {
cmd := &cobra.Command{
Use: "delete NAME",
Short: "Delete secret",
Example: ``,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {
return errors.New("'kn secret delete' requires the Secret name given as single argument")
}
name := args[0]
namespace, err := p.GetNamespace(cmd)
if err != nil {
return err
}
client, err := p.NewKubeClient()
if err != nil {
return err
}
return client.CoreV1().Secrets(namespace).Delete(cmd.Context(), name, metav1.DeleteOptions{})
},
}
commands.AddNamespaceFlags(cmd.Flags(), false)
return cmd
}
Loading

0 comments on commit 1231cd2

Please sign in to comment.