Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kn secret command #1791

Merged
merged 5 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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