Remove --api-key parameter

fixes #1

Signed-off-by: Christian Dupuis <cd@atomist.com>
This commit is contained in:
Christian Dupuis
2022-09-19 15:16:09 +02:00
parent 1b78e08fca
commit 12098e0f6e
2 changed files with 92 additions and 26 deletions

View File

@@ -38,23 +38,29 @@ Alternatively, you can install manually by following these steps:
To detect base images for local or remote images, use the following command: To detect base images for local or remote images, use the following command:
```shell ```shell
$ docker base detect <image> $ docker base detect <IMAGE>
``` ```
`<image>` can either be a local image id or fully qualified image name from a remote registry. `<IMAGE>` can either be a local image id or fully qualified image name from a remote registry.
### `docker base login` ### `docker base login`
To authenticate with the Atomist data plane, use the following command: To authenticate with the Atomist data plane, use the following command:
```shell ```shell
$ docker base login --workspace <workspace id> --api-key <api key> $ docker base login <WORKSPACE ID>
``` ```
Authentication is not required. If not authenticated, the plugin will only use public data from Docker Official Images, For the security reasons the command does not accept an API key as command parameter. Instead, an API key can be passed
Docker Verified Publishers or Docker-sponsored Open Source. in via stdin with the parameter `--api-key-stdin`.
Visit [dso.docker.com](https://dso.docker.com/r/auth/integrations) to obtain a `workspace id` and `api key`. The `login` command will also check the legacy `ATOMIST_API_KEY` environment variable.
Authentication is not required. If not authenticated, the plugin will only use public data from Docker Official Images,
Docker Verified Publishers or Docker-sponsored Open Source. Without authentication the `detect` command will not take
into account your own data on Docker Hub when searching for matching base images.
Visit [dso.docker.com](https://dso.docker.com/r/auth/integrations) to obtain a `WORKSPACE ID` and `API KEY`.
### `docker base logout` ### `docker base logout`

100
main.go
View File

@@ -17,7 +17,11 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"io"
"os"
"strings"
"github.com/docker/base-cli-plugin/commands" "github.com/docker/base-cli-plugin/commands"
"github.com/docker/base-cli-plugin/internal" "github.com/docker/base-cli-plugin/internal"
@@ -25,6 +29,7 @@ import (
"github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/plugin" "github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/moby/term"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -32,7 +37,7 @@ import (
func main() { func main() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command { plugin.Run(func(dockerCli command.Cli) *cobra.Command {
var ( var (
workspace, apiKey string apiKeyStdin bool
) )
logout := &cobra.Command{ logout := &cobra.Command{
@@ -46,23 +51,29 @@ func main() {
} }
login := &cobra.Command{ login := &cobra.Command{
Use: "login", Use: "login WORKSPACE",
Short: "Authenticate with an Atomist workspace", Short: "Authenticate with Atomist workspace",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if !query.CheckAuth(workspace, apiKey) { workspace, err := readWorkspace(args, dockerCli)
return errors.New("login failed") if err != nil {
} else { return err
}
apiKey, err := readApiKey(apiKeyStdin, dockerCli)
if err != nil {
return err
}
if query.CheckAuth(workspace, apiKey) {
fmt.Println("Login successful")
dockerCli.ConfigFile().SetPluginConfig("base", "workspace", workspace) dockerCli.ConfigFile().SetPluginConfig("base", "workspace", workspace)
dockerCli.ConfigFile().SetPluginConfig("base", "api-key", apiKey) dockerCli.ConfigFile().SetPluginConfig("base", "api-key", apiKey)
return dockerCli.ConfigFile().Save() return dockerCli.ConfigFile().Save()
} else {
return errors.New("Login failed")
} }
}, },
} }
loginFlags := login.Flags() loginFlags := login.Flags()
loginFlags.StringVar(&workspace, "workspace", "", "Atomist workspace") loginFlags.BoolVar(&apiKeyStdin, "api-key-stdin", false, "Atomist API key")
loginFlags.StringVar(&apiKey, "api-key", "", "Atomist API key")
login.MarkFlagRequired("workspace")
login.MarkFlagRequired("api-key")
base := &cobra.Command{ base := &cobra.Command{
Use: "detect [OPTIONS] IMAGE", Use: "detect [OPTIONS] IMAGE",
@@ -74,19 +85,12 @@ func main() {
} }
return fmt.Errorf(`"docker base detect" requires exactly 1 argument`) return fmt.Errorf(`"docker base detect" requires exactly 1 argument`)
} }
if workspace == "" { workspace, _ := dockerCli.ConfigFile().PluginConfig("base", "workspace")
workspace, _ = dockerCli.ConfigFile().PluginConfig("base", "workspace") apiKey, _ := dockerCli.ConfigFile().PluginConfig("base", "api-key")
}
if apiKey == "" {
apiKey, _ = dockerCli.ConfigFile().PluginConfig("base", "api-key")
}
return commands.Detect(dockerCli, args[0], workspace, apiKey) return commands.Detect(dockerCli, args[0], workspace, apiKey)
}, },
} }
baseFlags := base.Flags()
baseFlags.StringVar(&workspace, "workspace", "", "Atomist workspace")
baseFlags.StringVar(&apiKey, "api-key", "", "Atomist API key")
base.MarkFlagRequired("image") base.MarkFlagRequired("image")
cmd := &cobra.Command{ cmd := &cobra.Command{
@@ -103,3 +107,59 @@ func main() {
Version: internal.FromBuild().Version, Version: internal.FromBuild().Version,
}) })
} }
func readWorkspace(args []string, cli command.Cli) (string, error) {
var workspace string
if len(args) == 1 {
workspace = args[0]
} else {
fmt.Fprintf(cli.Out(), "Workspace: ")
workspace = readInput(cli.In(), cli.Out())
if workspace == "" {
return "", errors.Errorf("Error: Workspace required")
}
}
return workspace, nil
}
func readApiKey(apiKeyStdin bool, cli command.Cli) (string, error) {
var apiKey string
if apiKeyStdin {
contents, err := io.ReadAll(cli.In())
if err != nil {
return "", err
}
apiKey = strings.TrimSuffix(string(contents), "\n")
apiKey = strings.TrimSuffix(apiKey, "\r")
} else if v, ok := os.LookupEnv("ATOMIST_API_KEY"); v != "" && ok {
apiKey = v
} else {
oldState, err := term.SaveState(cli.In().FD())
if err != nil {
return "", err
}
fmt.Fprintf(cli.Out(), "API key: ")
term.DisableEcho(cli.In().FD(), oldState)
apiKey = readInput(cli.In(), cli.Out())
fmt.Fprint(cli.Out(), "\n")
term.RestoreTerminal(cli.In().FD(), oldState)
if apiKey == "" {
return "", errors.Errorf("Error: API key required")
}
}
return apiKey, nil
}
func readInput(in io.Reader, out io.Writer) string {
reader := bufio.NewReader(in)
line, _, err := reader.ReadLine()
if err != nil {
fmt.Fprintln(out, err.Error())
os.Exit(1)
}
return string(line)
}