Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
/coder-v1-cliPublic archive

Add secrets ls, add, view, rm commands#81

Merged
cmoog merged 2 commits intomasterfromsecrets
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes fromall 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
124 changes: 74 additions & 50 deletionsci/integration/integration_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,10 +4,8 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"math/rand"
"regexp"
"testing"
"time"

Expand All@@ -17,50 +15,6 @@ import (
"cdr.dev/slog/sloggers/slogtest/assert"
)

func build(path string) error {
cmd := exec.Command(
"sh", "-c",
fmt.Sprintf("cd ../../ && go build -o %s ./cmd/coder", path),
)
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")

_, err := cmd.CombinedOutput()
if err != nil {
return err
}
return nil
}

var binpath string

func init() {
cwd, err := os.Getwd()
if err != nil {
panic(err)
}

binpath = filepath.Join(cwd, "bin", "coder")
err = build(binpath)
if err != nil {
panic(err)
}
}

// write session tokens to the given container runner
func headlessLogin(ctx context.Context, t *testing.T, runner *tcli.ContainerRunner) {
creds := login(ctx, t)
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p ~/.config/coder && cat > ~/.config/coder/session")

// !IMPORTANT: be careful that this does not appear in logs
cmd.Stdin = strings.NewReader(creds.token)
runner.RunCmd(cmd).Assert(t,
tcli.Success(),
)
runner.Run(ctx, fmt.Sprintf("echo -ne %s > ~/.config/coder/url", creds.url)).Assert(t,
tcli.Success(),
)
}

func TestCoderCLI(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
Expand DownExpand Up@@ -116,7 +70,7 @@ func TestCoderCLI(t *testing.T) {
var user entclient.User
c.Run(ctx, `coder users ls -o json | jq -c '.[] | select( .username == "charlie")'`).Assert(t,
tcli.Success(),
jsonUnmarshals(&user),
stdoutUnmarshalsJSON(&user),
)
assert.Equal(t, "user email is as expected", "charlie@coder.com", user.Email)
assert.Equal(t, "username is as expected", "Charlie", user.Name)
Expand All@@ -135,10 +89,80 @@ func TestCoderCLI(t *testing.T) {
)
}

func jsonUnmarshals(target interface{}) tcli.Assertion {
func TestSecrets(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
defer cancel()

c, err := tcli.NewContainerRunner(ctx, &tcli.ContainerConfig{
Image: "codercom/enterprise-dev",
Name: "secrets-cli-tests",
BindMounts: map[string]string{
binpath: "/bin/coder",
},
})
assert.Success(t, "new run container", err)
defer c.Close()

headlessLogin(ctx, t, c)

c.Run(ctx, "coder secrets ls").Assert(t,
tcli.Success(),
)

name, value := randString(8), randString(8)

c.Run(ctx, "coder secrets create").Assert(t,
tcli.Error(),
tcli.StdoutEmpty(),
tcli.StderrMatches("required flag"),
)

c.Run(ctx, fmt.Sprintf("coder secrets create --name %s --value %s", name, value)).Assert(t,
tcli.Success(),
tcli.StderrEmpty(),
)

c.Run(ctx, "coder secrets ls").Assert(t,
tcli.Success(),
tcli.StderrEmpty(),
tcli.StdoutMatches("Value"),
tcli.StdoutMatches(regexp.QuoteMeta(name)),
)

c.Run(ctx, "coder secrets view "+name).Assert(t,
tcli.Success(),
tcli.StderrEmpty(),
tcli.StdoutMatches(regexp.QuoteMeta(value)),
)

c.Run(ctx, "coder secrets rm").Assert(t,
tcli.Error(),
)
c.Run(ctx, "coder secrets rm "+name).Assert(t,
tcli.Success(),
)
c.Run(ctx, "coder secrets view "+name).Assert(t,
tcli.Error(),
tcli.StdoutEmpty(),
)
}

func stdoutUnmarshalsJSON(target interface{}) tcli.Assertion {
return func(t *testing.T, r *tcli.CommandResult) {
slog.Helper()
err := json.Unmarshal(r.Stdout, target)
assert.Success(t, "json unmarshals", err)
}
}

var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))

func randString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}
60 changes: 60 additions & 0 deletionsci/integration/setup_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
package integration

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"cdr.dev/coder-cli/ci/tcli"
"golang.org/x/xerrors"
)

var binpath string

// initialize integration tests by building the coder-cli binary
func init() {
cwd, err := os.Getwd()
if err != nil {
panic(err)
}

binpath = filepath.Join(cwd, "bin", "coder")
err = build(binpath)
if err != nil {
panic(err)
}
}

// build the coder-cli binary and move to the integration testing bin directory
func build(path string) error {
cmd := exec.Command(
"sh", "-c",
fmt.Sprintf("cd ../../ && go build -o %s ./cmd/coder", path),
)
cmd.Env = append(os.Environ(), "GOOS=linux", "CGO_ENABLED=0")

out, err := cmd.CombinedOutput()
if err != nil {
return xerrors.Errorf("failed to build coder-cli (%v): %w", string(out), err)
}
return nil
}

// write session tokens to the given container runner
func headlessLogin(ctx context.Context, t *testing.T, runner *tcli.ContainerRunner) {
creds := login(ctx, t)
cmd := exec.CommandContext(ctx, "sh", "-c", "mkdir -p ~/.config/coder && cat > ~/.config/coder/session")

// !IMPORTANT: be careful that this does not appear in logs
cmd.Stdin = strings.NewReader(creds.token)
runner.RunCmd(cmd).Assert(t,
tcli.Success(),
)
runner.Run(ctx, fmt.Sprintf("echo -ne %s > ~/.config/coder/url", creds.url)).Assert(t,
tcli.Success(),
)
}
5 changes: 4 additions & 1 deletionci/tcli/tcli.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -163,13 +163,16 @@ type Assertable struct {
}

// Assert runs the Assertable and
func (a Assertable) Assert(t *testing.T, option ...Assertion) {
func (a*Assertable) Assert(t *testing.T, option ...Assertion) {
slog.Helper()
var (
stdout bytes.Buffer
stderr bytes.Buffer
result CommandResult
)
if a.cmd == nil {
slogtest.Fatal(t, "test failed to initialize: no command specified")
}

a.cmd.Stdout = &stdout
a.cmd.Stderr = &stderr
Expand Down
14 changes: 3 additions & 11 deletionscmd/coder/auth.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,27 +3,19 @@ package main
import (
"net/url"

"go.coder.com/flog"

"cdr.dev/coder-cli/internal/config"
"cdr.dev/coder-cli/internal/entclient"
)

func requireAuth() *entclient.Client {
sessionToken, err := config.Session.Read()
if err != nil {
flog.Fatal("read session: %v (did you run coder login?)", err)
}
requireSuccess(err, "read session: %v (did you run coder login?)", err)

rawURL, err := config.URL.Read()
if err != nil {
flog.Fatal("read url: %v (did you run coder login?)", err)
}
requireSuccess(err, "read url: %v (did you run coder login?)", err)

u, err := url.Parse(rawURL)
if err != nil {
flog.Fatal("url misformatted: %v (try runing coder login)", err)
}
requireSuccess(err, "url misformatted: %v (try runing coder login)", err)

return &entclient.Client{
BaseURL: u,
Expand Down
13 changes: 4 additions & 9 deletionscmd/coder/ceapi.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,24 +27,19 @@ outer:
// getEnvs returns all environments for the user.
func getEnvs(client *entclient.Client) []entclient.Environment {
me, err := client.Me()
if err != nil {
flog.Fatal("get self: %+v", err)
}
requireSuccess(err, "get self: %+v", err)

orgs, err := client.Orgs()
if err != nil {
flog.Fatal("get orgs: %+v", err)
}
requireSuccess(err, "get orgs: %+v", err)

orgs = userOrgs(me, orgs)

var allEnvs []entclient.Environment

for _, org := range orgs {
envs, err := client.Envs(me, org)
if err != nil {
flog.Fatal("get envs for %v: %+v", org.Name, err)
}
requireSuccess(err, "get envs for %v: %+v", org.Name, err)

for _, env := range envs {
allEnvs = append(allEnvs, env)
}
Expand Down
10 changes: 9 additions & 1 deletioncmd/coder/main.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@ import (
_ "net/http/pprof"
"os"

"cdr.dev/coder-cli/internal/xterminal"
"cdr.dev/coder-cli/internal/x/xterminal"
"github.com/spf13/pflag"

"go.coder.com/flog"
Expand DownExpand Up@@ -43,6 +43,7 @@ func (r *rootCmd) Subcommands() []cli.Command {
&versionCmd{},
&configSSHCmd{},
&usersCmd{},
&secretsCmd{},
}
}

Expand All@@ -61,3 +62,10 @@ func main() {

cli.RunRoot(&rootCmd{})
}

// requireSuccess prints the given message and format args as a fatal error if err != nil
func requireSuccess(err error, msg string, args ...interface{}) {
if err != nil {
flog.Fatal(msg, args...)
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp