Adding encrypt and decrypt subcommands to secret command

Design document: https://docs.google.com/document/d/1EjiCuXoiy8DEEXe15KxVJ4iWrwogCyG113_0LdzcWzQ/edit?usp=drive_web&ouid=102644738301620637153

This is the third of multiple patchsets to support
encryption and decryption in airshipctl

Complete feature: https://review.opendev.org/#/c/742695/

Change-Id: Ibe1060a83d11233cccaa3d3989765968a4dbed76
This commit is contained in:
uday.ruddarraju 2020-09-14 10:11:30 -07:00
parent 96e88e2523
commit 8fccf09753
11 changed files with 342 additions and 2 deletions

View File

@ -78,7 +78,7 @@ func AddDefaultAirshipCTLCommands(cmd *cobra.Command, factory cfg.Factory) *cobr
cmd.AddCommand(document.NewDocumentCommand(factory))
cmd.AddCommand(config.NewConfigCommand(factory))
cmd.AddCommand(image.NewImageCommand(factory))
cmd.AddCommand(secret.NewSecretCommand())
cmd.AddCommand(secret.NewSecretCommand(factory))
cmd.AddCommand(phase.NewPhaseCommand(factory))
cmd.AddCommand(NewVersionCommand())

View File

@ -0,0 +1,65 @@
/*
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
https://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 decrypt
import (
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/errors"
"opendev.org/airship/airshipctl/pkg/log"
)
const (
decryptShort = `
Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data.`
decryptExample = `
# Decrypt all encrypted files in the manifests directory.
airshipctl secret decrypt
# Decrypt encrypted file from src and write the plain text to a different dst file
airshipctl secret decrypt \
--src /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/qualified-secret.yaml
`
)
// NewDecryptCommand creates a new command for decrypting encrypted secrets in the manifests
func NewDecryptCommand(_ config.Factory) *cobra.Command {
var srcPath, dstPath string
decryptCmd := &cobra.Command{
Use: "decrypt",
Short: decryptShort[1:],
Example: decryptExample,
RunE: func(cmd *cobra.Command, args []string) error {
// TODO: Need to integrate with business logic to decrypt with sops
return errors.ErrNotImplemented{What: "secret encryption/decryption"}
},
}
decryptCmd.Flags().StringVar(&srcPath, "src", "",
`Path to the file or directory that has secrets in encrypted text that need to be decrypted. `+
`Defaults to the manifest location in airship config`)
decryptCmd.Flags().StringVar(&dstPath, "dst", "",
"Path to the file or directory to store decrypted secrets. Defaults to src if empty.")
err := decryptCmd.MarkFlagRequired("dst")
if err != nil {
log.Fatalf("marking dst flag required failed: %v", err)
}
return decryptCmd
}

View File

@ -0,0 +1,36 @@
/*
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
https://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 decrypt_test
import (
"testing"
"opendev.org/airship/airshipctl/cmd/secret/decrypt"
"opendev.org/airship/airshipctl/testutil"
)
func TestDecrypt(t *testing.T) {
cmdTests := []*testutil.CmdTest{
{
Name: "decrypt-cmd-cmd-with-help",
CmdLine: "--help",
Cmd: decrypt.NewDecryptCommand(nil),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}

View File

@ -0,0 +1,20 @@
Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data.
Usage:
decrypt [flags]
Examples:
# Decrypt all encrypted files in the manifests directory.
airshipctl secret decrypt
# Decrypt encrypted file from src and write the plain text to a different dst file
airshipctl secret decrypt \
--src /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/qualified-secret.yaml
Flags:
--dst string Path to the file or directory to store decrypted secrets. Defaults to src if empty.
-h, --help help for decrypt
--src string Path to the file or directory that has secrets in encrypted text that need to be decrypted. Defaults to the manifest location in airship config

View File

@ -0,0 +1,64 @@
/*
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
https://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 encrypt
import (
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/errors"
"opendev.org/airship/airshipctl/pkg/log"
)
const (
encryptShort = `
Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration.`
encryptExample = `
# Encrypt all kubernetes objects in the manifests directory.
airshipctl secret encrypt
# Encrypt file from src and write to a different dst file
airshipctl secret encrypt \
--src /tmp/manifests/target/secrets/qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml
`
)
// NewEncryptCommand creates a new command for encrypting plain text secrets using sops
func NewEncryptCommand(_ config.Factory) *cobra.Command {
var srcPath, dstPath string
encryptCmd := &cobra.Command{
Use: "encrypt",
Short: encryptShort[1:],
Example: encryptExample,
RunE: func(cmd *cobra.Command, args []string) error {
return errors.ErrNotImplemented{What: "secret encryption/decryption"}
},
}
encryptCmd.Flags().StringVar(&srcPath, "src", "",
`Path to the file or directory that has secrets in plaintext that need to be encrypted. `+
`Defaults to the manifest location in airship config`)
encryptCmd.Flags().StringVar(&dstPath, "dst", "",
"Path to the file or directory that has encrypted secrets for decryption. Defaults to src if empty.")
err := encryptCmd.MarkFlagRequired("dst")
if err != nil {
log.Fatalf("marking dst flag required failed: %v", err)
}
return encryptCmd
}

View File

@ -0,0 +1,36 @@
/*
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
https://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 encrypt_test
import (
"testing"
"opendev.org/airship/airshipctl/cmd/secret/encrypt"
"opendev.org/airship/airshipctl/testutil"
)
func TestDecrypt(t *testing.T) {
cmdTests := []*testutil.CmdTest{
{
Name: "encrypt-cmd-cmd-with-help",
CmdLine: "--help",
Cmd: encrypt.NewEncryptCommand(nil),
},
}
for _, tt := range cmdTests {
testutil.RunTest(t, tt)
}
}

View File

@ -0,0 +1,20 @@
Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration.
Usage:
encrypt [flags]
Examples:
# Encrypt all kubernetes objects in the manifests directory.
airshipctl secret encrypt
# Encrypt file from src and write to a different dst file
airshipctl secret encrypt \
--src /tmp/manifests/target/secrets/qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml
Flags:
--dst string Path to the file or directory that has encrypted secrets for decryption. Defaults to src if empty.
-h, --help help for encrypt
--src string Path to the file or directory that has secrets in plaintext that need to be encrypted. Defaults to the manifest location in airship config

View File

@ -17,11 +17,14 @@ package secret
import (
"github.com/spf13/cobra"
"opendev.org/airship/airshipctl/cmd/secret/decrypt"
"opendev.org/airship/airshipctl/cmd/secret/encrypt"
"opendev.org/airship/airshipctl/cmd/secret/generate"
"opendev.org/airship/airshipctl/pkg/config"
)
// NewSecretCommand creates a new command for managing airshipctl secrets
func NewSecretCommand() *cobra.Command {
func NewSecretCommand(cfgFactory config.Factory) *cobra.Command {
secretRootCmd := &cobra.Command{
Use: "secret",
// TODO(howell): Make this more expressive
@ -29,6 +32,8 @@ func NewSecretCommand() *cobra.Command {
}
secretRootCmd.AddCommand(generate.NewGenerateCommand())
secretRootCmd.AddCommand(encrypt.NewEncryptCommand(cfgFactory))
secretRootCmd.AddCommand(decrypt.NewDecryptCommand(cfgFactory))
return secretRootCmd
}

View File

@ -23,5 +23,7 @@ Manage secrets
### SEE ALSO
* [airshipctl](airshipctl.md) - A unified entrypoint to various airship components
* [airshipctl secret decrypt](airshipctl_secret_decrypt.md) - Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data.
* [airshipctl secret encrypt](airshipctl_secret_encrypt.md) - Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration.
* [airshipctl secret generate](airshipctl_secret_generate.md) - Generate various secrets

View File

@ -0,0 +1,46 @@
## airshipctl secret decrypt
Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data.
### Synopsis
Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data.
```
airshipctl secret decrypt [flags]
```
### Examples
```
# Decrypt all encrypted files in the manifests directory.
airshipctl secret decrypt
# Decrypt encrypted file from src and write the plain text to a different dst file
airshipctl secret decrypt \
--src /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/qualified-secret.yaml
```
### Options
```
--dst string Path to the file or directory to store decrypted secrets. Defaults to src if empty.
-h, --help help for decrypt
--src string Path to the file or directory that has secrets in encrypted text that need to be decrypted. Defaults to the manifest location in airship config
```
### Options inherited from parent commands
```
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
--debug enable verbose output
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
```
### SEE ALSO
* [airshipctl secret](airshipctl_secret.md) - Manage secrets

View File

@ -0,0 +1,46 @@
## airshipctl secret encrypt
Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration.
### Synopsis
Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration.
```
airshipctl secret encrypt [flags]
```
### Examples
```
# Encrypt all kubernetes objects in the manifests directory.
airshipctl secret encrypt
# Encrypt file from src and write to a different dst file
airshipctl secret encrypt \
--src /tmp/manifests/target/secrets/qualified-secret.yaml \
--dst /tmp/manifests/target/secrets/encrypted-qualified-secret.yaml
```
### Options
```
--dst string Path to the file or directory that has encrypted secrets for decryption. Defaults to src if empty.
-h, --help help for encrypt
--src string Path to the file or directory that has secrets in plaintext that need to be encrypted. Defaults to the manifest location in airship config
```
### Options inherited from parent commands
```
--airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config")
--debug enable verbose output
--kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig")
```
### SEE ALSO
* [airshipctl secret](airshipctl_secret.md) - Manage secrets