Skip to content

Commit

Permalink
cmd: add kes ls command (#464)
Browse files Browse the repository at this point in the history
This commit adds the `kes ls` command that lists keys, policies and
identities.
```
Usage:
    kes ls [-a KEY] [-k] [--json] [-i] [-p] [-s HOST[:PORT]] [PREFIX]

Options:
    -a, --api-key KEY           API key to authenticate to the KES server.
                                Defaults to $MINIO_KES_API_KEY.
    -s, --server HOST[:PORT]    Use the server HOST[:PORT] instead of
                                $MINIO_KES_SERVER.
        --json                  Print output in JSON format.
    -i, --identity              List identities.
    -p, --policy                List policy names.
    -k, --insecure              Skip server certificate verification.
```

This command replaces `kes key ls`, `kes policy ls` and `kes identity ls`
mid-term.

Signed-off-by: Andreas Auernhammer <[email protected]>
  • Loading branch information
aead authored May 16, 2024
1 parent 802ce81 commit fe54489
Show file tree
Hide file tree
Showing 12 changed files with 438 additions and 113 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,18 @@ jobs:
go test ./...
vulncheck:
name: Vulncheck
needs: Lint
name: Vulncheck ${{ matrix.go-version }}
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [1.21.9, 1.22.3]
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Check out code into the Go module directory
uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.22.2
check-latest: true
- name: Get govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
shell: bash
Expand Down
4 changes: 2 additions & 2 deletions cmd/kes/color-option.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ package main

import (
"errors"
"os"
"strings"

tui "github.com/charmbracelet/lipgloss"
"github.com/minio/kes/internal/cli"
"github.com/muesli/termenv"
flag "github.com/spf13/pflag"
)
Expand All @@ -29,7 +29,7 @@ var _ flag.Value = (*colorOption)(nil)

func (c *colorOption) Colorize() bool {
v := strings.ToLower(c.value)
return v == "always" || ((v == "auto" || v == "") && isTerm(os.Stdout))
return v == "always" || ((v == "auto" || v == "") && cli.IsTerminal())
}

func (c *colorOption) String() string { return c.value }
Expand Down
33 changes: 33 additions & 0 deletions cmd/kes/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2024 - MinIO, Inc. All rights reserved.
// Use of this source code is governed by the AGPLv3
// license that can be found in the LICENSE file.

package main

import (
"github.com/minio/kes/internal/cli"
flag "github.com/spf13/pflag"
)

// Use register functions for common flags exposed by
// many commands. Common flags should have common names
// to make command usage consistent.

// flagsInsecureSkipVerify adds a bool flag '-k, --insecure'
// that sets insecureSkipVerify to true if provided on the
// command line.
func flagsInsecureSkipVerify(f *flag.FlagSet, insecureSkipVerify *bool) {
f.BoolVarP(insecureSkipVerify, "insecure", "k", false, "Skip server certificate verification")
}

func flagsAPIKey(f *flag.FlagSet, apiKey *string) {
f.StringVarP(apiKey, "api-key", "a", cli.Env(cli.EnvAPIKey), "API key to authenticate to the KES server")
}

func flagsOutputJSON(f *flag.FlagSet, jsonOutput *bool) {
f.BoolVar(jsonOutput, "json", false, "Print output in JSON format")
}

func flagsServer(f *flag.FlagSet, host *string) {
f.StringVarP(host, "server", "s", cli.Env(cli.EnvServer), "Use the server HOST[:PORT]")
}
12 changes: 8 additions & 4 deletions cmd/kes/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func newIdentityCmd(args []string) {
}

bold := tui.NewStyle()
if isTerm(os.Stdout) {
if cli.IsTerminal() {
bold = bold.Bold(true)
}
var buffer strings.Builder
Expand Down Expand Up @@ -418,7 +418,7 @@ func ofIdentityCmd(args []string) {
h := sha256.Sum256(cert.RawSubjectPublicKeyInfo)
identity = kes.Identity(hex.EncodeToString(h[:]))
}
if isTerm(os.Stdout) {
if cli.IsTerminal() {
var buffer strings.Builder
fmt.Fprintln(&buffer, "Identity:")
fmt.Fprintln(&buffer)
Expand Down Expand Up @@ -491,7 +491,9 @@ func infoIdentityCmd(args []string) {
dotDenyStyle = dotDenyStyle.Foreground(ColorDotDeny)
}

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
if cmd.NArg() == 0 {
info, policy, err := client.DescribeSelf(ctx)
if err != nil {
Expand Down Expand Up @@ -619,7 +621,9 @@ func lsIdentityCmd(args []string) {
ctx, cancelCtx := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancelCtx()

enclave := newClient(insecureSkipVerify)
enclave := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
iter := &kes.ListIter[kes.Identity]{
NextFunc: enclave.ListIdentities,
}
Expand Down
38 changes: 27 additions & 11 deletions cmd/kes/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ func createKeyCmd(args []string) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
for _, name := range cmd.Args() {
if err := client.CreateKey(ctx, name); err != nil {
if errors.Is(err, context.Canceled) {
Expand Down Expand Up @@ -169,7 +171,9 @@ func importKeyCmd(args []string) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()

enclave := newClient(insecureSkipVerify)
enclave := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
if err = enclave.ImportKey(ctx, name, &kes.ImportKeyRequest{Key: key}); err != nil {
if errors.Is(err, context.Canceled) {
os.Exit(1)
Expand Down Expand Up @@ -229,7 +233,9 @@ func describeKeyCmd(args []string) {
defer cancelCtx()

name := cmd.Arg(0)
client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
info, err := client.DescribeKey(ctx, name)
if err != nil {
if errors.Is(err, context.Canceled) {
Expand Down Expand Up @@ -308,7 +314,9 @@ func lsKeyCmd(args []string) {
ctx, cancelCtx := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancelCtx()

enclave := newClient(insecureSkipVerify)
enclave := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
iter := &kes.ListIter[string]{
NextFunc: enclave.ListKeys,
}
Expand Down Expand Up @@ -380,7 +388,9 @@ func rmKeyCmd(args []string) {
ctx, cancelCtx := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancelCtx()

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
for _, name := range cmd.Args() {
if err := client.DeleteKey(ctx, name); err != nil {
if errors.Is(err, context.Canceled) {
Expand Down Expand Up @@ -436,7 +446,9 @@ func encryptKeyCmd(args []string) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
ciphertext, err := client.Encrypt(ctx, name, []byte(message), nil)
if err != nil {
if errors.Is(err, context.Canceled) {
Expand All @@ -445,7 +457,7 @@ func encryptKeyCmd(args []string) {
cli.Fatalf("failed to encrypt message: %v", err)
}

if isTerm(os.Stdout) {
if cli.IsTerminal() {
fmt.Printf("\nciphertext: %s\n", base64.StdEncoding.EncodeToString(ciphertext))
} else {
fmt.Printf(`{"ciphertext":"%s"}`, base64.StdEncoding.EncodeToString(ciphertext))
Expand Down Expand Up @@ -509,7 +521,9 @@ func decryptKeyCmd(args []string) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
plaintext, err := client.Decrypt(ctx, name, ciphertext, associatedData)
if err != nil {
if errors.Is(err, context.Canceled) {
Expand All @@ -518,7 +532,7 @@ func decryptKeyCmd(args []string) {
cli.Fatalf("failed to decrypt ciphertext: %v", err)
}

if isTerm(os.Stdout) {
if cli.IsTerminal() {
fmt.Printf("\nplaintext: %s\n", base64.StdEncoding.EncodeToString(plaintext))
} else {
fmt.Printf(`{"plaintext":"%s"}`, base64.StdEncoding.EncodeToString(plaintext))
Expand Down Expand Up @@ -575,7 +589,9 @@ func dekCmd(args []string) {
ctx, cancelCtx := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancelCtx()

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
key, err := client.GenerateKey(ctx, name, associatedData)
if err != nil {
if errors.Is(err, context.Canceled) {
Expand All @@ -588,7 +604,7 @@ func dekCmd(args []string) {
plaintext = base64.StdEncoding.EncodeToString(key.Plaintext)
ciphertext = base64.StdEncoding.EncodeToString(key.Ciphertext)
)
if isTerm(os.Stdout) {
if cli.IsTerminal() {
const format = "\nplaintext: %s\nciphertext: %s\n"
fmt.Printf(format, plaintext, ciphertext)
} else {
Expand Down
6 changes: 4 additions & 2 deletions cmd/kes/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ func logCmd(args []string) {
auditFlag = !auditFlag
}

client := newClient(insecureSkipVerify)
client := newClient(config{
InsecureSkipVerify: insecureSkipVerify,
})
ctx, cancelCtx := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancelCtx()

Expand Down Expand Up @@ -125,7 +127,7 @@ func printAuditLog(stream *kes.AuditStream) {
format = "%02d:%02d:%02d %s %s %s %s %s\n"
)

if isTerm(os.Stdout) {
if cli.IsTerminal() {
fmt.Println(tui.NewStyle().Bold(true).Underline(true).Render(header))
} else {
fmt.Println(header)
Expand Down
Loading

0 comments on commit fe54489

Please sign in to comment.