Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Add --user flag to "secrets" and "envs" #92

Merged
merged 1 commit into from
Aug 12, 2020
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
Add --user flag to "secrets" and "envs"
  • Loading branch information
cmoog committed Aug 12, 2020
commit 8f41aa3c274f69855009e7b6f49ba39fe8bb3156
6 changes: 4 additions & 2 deletions cmd/coder/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ func newClient() (*entclient.Client, error) {
return nil, xerrors.Errorf("url misformatted: %v (try runing coder login)", err)
}

return &entclient.Client{
client := &entclient.Client{
BaseURL: u,
Token: sessionToken,
}, nil
}

return client, nil
}
22 changes: 12 additions & 10 deletions cmd/coder/ceapi.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"context"

"golang.org/x/xerrors"

"go.coder.com/flog"
Expand All @@ -27,23 +29,23 @@ outer:
}

// getEnvs returns all environments for the user.
func getEnvs(client *entclient.Client) ([]entclient.Environment, error) {
me, err := client.Me()
func getEnvs(ctx context.Context, client *entclient.Client, email string) ([]entclient.Environment, error) {
user, err := client.UserByEmail(ctx, email)
if err != nil {
return nil, xerrors.Errorf("get self: %+v", err)
return nil, xerrors.Errorf("get user: %+v", err)
}

orgs, err := client.Orgs()
orgs, err := client.Orgs(ctx)
if err != nil {
return nil, xerrors.Errorf("get orgs: %+v", err)
}

orgs = userOrgs(me, orgs)
orgs = userOrgs(user, orgs)

var allEnvs []entclient.Environment

for _, org := range orgs {
envs, err := client.Envs(me, org)
envs, err := client.Envs(ctx, user, org)
if err != nil {
return nil, xerrors.Errorf("get envs for %v: %+v", org.Name, err)
}
Expand All @@ -56,8 +58,8 @@ func getEnvs(client *entclient.Client) ([]entclient.Environment, error) {
}

// findEnv returns a single environment by name (if it exists.)
func findEnv(client *entclient.Client, name string) (*entclient.Environment, error) {
envs, err := getEnvs(client)
func findEnv(ctx context.Context, client *entclient.Client, envName, userEmail string) (*entclient.Environment, error) {
envs, err := getEnvs(ctx, client, userEmail)
if err != nil {
return nil, xerrors.Errorf("get environments: %w", err)
}
Expand All @@ -66,11 +68,11 @@ func findEnv(client *entclient.Client, name string) (*entclient.Environment, err

for _, env := range envs {
found = append(found, env.Name)
if env.Name == name {
if env.Name == envName {
return &env, nil
}
}
flog.Error("found %q", found)
flog.Error("%q not found", name)
flog.Error("%q not found", envName)
return nil, xerrors.New("environment not found")
}
8 changes: 4 additions & 4 deletions cmd/coder/configssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,19 @@ func configSSH(filepath *string, remove *bool) func(cmd *cobra.Command, _ []stri
return xerrors.New("SSH is disabled or not available for your Coder Enterprise deployment.")
}

me, err := entClient.Me()
user, err := entClient.Me(cmd.Context())
if err != nil {
return xerrors.Errorf("fetch username: %w", err)
}

envs, err := getEnvs(entClient)
envs, err := getEnvs(cmd.Context(), entClient, entclient.Me)
if err != nil {
return err
}
if len(envs) < 1 {
return xerrors.New("no environments found")
}
newConfig, err := makeNewConfigs(me.Username, envs, startToken, startMessage, endToken)
newConfig, err := makeNewConfigs(user.Username, envs, startToken, startMessage, endToken)
if err != nil {
return xerrors.Errorf("make new ssh configurations: %w", err)
}
Expand Down Expand Up @@ -127,7 +127,7 @@ var (
)

func writeSSHKey(ctx context.Context, client *entclient.Client) error {
key, err := client.SSHKey()
key, err := client.SSHKey(ctx)
if err != nil {
return err
}
Expand Down
11 changes: 10 additions & 1 deletion cmd/coder/envs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@ import (
"encoding/json"
"os"

"cdr.dev/coder-cli/internal/entclient"
"cdr.dev/coder-cli/internal/x/xtabwriter"
"github.com/spf13/cobra"
"golang.org/x/xerrors"

"go.coder.com/flog"
)

func makeEnvsCommand() *cobra.Command {
var outputFmt string
var user string
cmd := &cobra.Command{
Use: "envs",
Short: "Interact with Coder environments",
Long: "Perform operations on the Coder environments owned by the active user.",
}
cmd.PersistentFlags().StringVar(&user, "user", entclient.Me, "Specify the user whose resources to target")

lsCmd := &cobra.Command{
Use: "ls",
Short: "list all environments owned by the active user",
Long: "List all Coder environments owned by the active user.",
RunE: func(cmd *cobra.Command, args []string) error {
entClient := requireAuth()
envs, err := getEnvs(entClient)
envs, err := getEnvs(cmd.Context(), entClient, user)
if err != nil {
return err
}
if len(envs) < 1 {
flog.Info("no environments found")
return nil
}

switch outputFmt {
case "human":
Expand Down
6 changes: 5 additions & 1 deletion cmd/coder/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"fmt"
"log"
"net/http"
Expand All @@ -19,6 +20,9 @@ var (
)

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

if os.Getenv("PPROF") != "" {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
Expand Down Expand Up @@ -49,7 +53,7 @@ func main() {
makeURLCmd(),
completionCmd,
)
err = app.Execute()
err = app.ExecuteContext(ctx)
if err != nil {
os.Exit(1)
}
Expand Down
134 changes: 75 additions & 59 deletions cmd/coder/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,39 @@ import (
)

func makeSecretsCmd() *cobra.Command {
var user string
cmd := &cobra.Command{
Use: "secrets",
Short: "Interact with Coder Secrets",
Long: "Interact with secrets objects owned by the active user.",
}
cmd.PersistentFlags().StringVar(&user, "user", entclient.Me, "Specify the user whose resources to target")
cmd.AddCommand(
&cobra.Command{
Use: "ls",
Short: "List all secrets owned by the active user",
RunE: listSecrets,
RunE: listSecrets(&user),
},
makeCreateSecret(),
makeCreateSecret(&user),
&cobra.Command{
Use: "rm [...secret_name]",
Short: "Remove one or more secrets by name",
Args: cobra.MinimumNArgs(1),
RunE: removeSecrets,
RunE: makeRemoveSecrets(&user),
Example: "coder secrets rm mysql-password mysql-user",
},
&cobra.Command{
Use: "view [secret_name]",
Short: "View a secret by name",
Args: cobra.ExactArgs(1),
RunE: viewSecret,
RunE: makeViewSecret(&user),
Example: "coder secrets view mysql-password",
},
)
return cmd
}

func makeCreateSecret() *cobra.Command {
func makeCreateSecret(user *string) *cobra.Command {
var (
fromFile string
fromLiteral string
Expand Down Expand Up @@ -107,10 +109,12 @@ coder secrets create aws-credentials --from-file ./credentials.json`,
}
}

err = client.InsertSecret(entclient.InsertSecretReq{
err = client.InsertSecret(cmd.Context(), entclient.InsertSecretReq{
Name: name,
Value: value,
Description: description,
}, &entclient.ReqOptions{
User: *user,
})
if err != nil {
return xerrors.Errorf("insert secret: %w", err)
Expand All @@ -127,71 +131,83 @@ coder secrets create aws-credentials --from-file ./credentials.json`,
return cmd
}

func listSecrets(cmd *cobra.Command, _ []string) error {
client := requireAuth()
func listSecrets(user *string) func(cmd *cobra.Command, _ []string) error {
return func(cmd *cobra.Command, _ []string) error {
client := requireAuth()

secrets, err := client.Secrets()
if err != nil {
return xerrors.Errorf("get secrets: %w", err)
}
secrets, err := client.Secrets(cmd.Context(), &entclient.ReqOptions{
User: *user,
})
if err != nil {
return xerrors.Errorf("get secrets: %w", err)
}

if len(secrets) < 1 {
flog.Info("No secrets found")
return nil
}
if len(secrets) < 1 {
flog.Info("No secrets found")
return nil
}

err = xtabwriter.WriteTable(len(secrets), func(i int) interface{} {
s := secrets[i]
s.Value = "******" // value is omitted from bulk responses
return s
})
if err != nil {
return xerrors.Errorf("write table of secrets: %w", err)
err = xtabwriter.WriteTable(len(secrets), func(i int) interface{} {
s := secrets[i]
s.Value = "******" // value is omitted from bulk responses
return s
})
if err != nil {
return xerrors.Errorf("write table of secrets: %w", err)
}
return nil
}
return nil
}

func viewSecret(_ *cobra.Command, args []string) error {
var (
client = requireAuth()
name = args[0]
)
if name == "" {
return xerrors.New("[name] is a required argument")
}
func makeViewSecret(user *string) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var (
client = requireAuth()
name = args[0]
)
if name == "" {
return xerrors.New("[name] is a required argument")
}

secret, err := client.SecretByName(name)
if err != nil {
return xerrors.Errorf("get secret by name: %w", err)
}
secret, err := client.SecretByName(cmd.Context(), name, &entclient.ReqOptions{
User: *user,
})
if err != nil {
return xerrors.Errorf("get secret by name: %w", err)
}

_, err = fmt.Fprintln(os.Stdout, secret.Value)
if err != nil {
return xerrors.Errorf("write secret value: %w", err)
_, err = fmt.Fprintln(os.Stdout, secret.Value)
if err != nil {
return xerrors.Errorf("write secret value: %w", err)
}
return nil
}
return nil
}

func removeSecrets(_ *cobra.Command, args []string) error {
var (
client = requireAuth()
)
if len(args) < 1 {
return xerrors.New("[...secret_name] is a required argument")
}
func makeRemoveSecrets(user *string) func(c *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var (
client = requireAuth()
)
if len(args) < 1 {
return xerrors.New("[...secret_name] is a required argument")
}

errorSeen := false
for _, n := range args {
err := client.DeleteSecretByName(n)
if err != nil {
flog.Error("failed to delete secret %q: %v", n, err)
errorSeen = true
} else {
flog.Success("successfully deleted secret %q", n)
errorSeen := false
for _, n := range args {
err := client.DeleteSecretByName(cmd.Context(), n, &entclient.ReqOptions{
User: *user,
})
if err != nil {
flog.Error("failed to delete secret %q: %v", n, err)
errorSeen = true
} else {
flog.Success("successfully deleted secret %q", n)
}
}
if errorSeen {
os.Exit(1)
}
return nil
}
if errorSeen {
os.Exit(1)
}
return nil
}
Loading