Skip to content

Commit

Permalink
Present Runner Terms when creating first RC for org
Browse files Browse the repository at this point in the history
Present Runner Terms on first resource class creation [RT-219]
  • Loading branch information
jrahme-cci authored Nov 26, 2021
2 parents 566ad87 + 3e4141b commit e367219
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 11 deletions.
16 changes: 11 additions & 5 deletions api/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@ func (r *Runner) CreateResourceClass(resourceClass, desc string) (rc *ResourceCl
}

func (r *Runner) GetResourceClassByName(resourceClass string) (rc *ResourceClass, err error) {
s := strings.SplitN(resourceClass, "/", 2)
if len(s) != 2 {
return nil, fmt.Errorf("bad resource class: %q", resourceClass)
namespace, err := r.GetNamespaceByResourceClass(resourceClass)
if err != nil {
return nil, err
}

namespace := s[0]
rcs, err := r.GetResourceClassesByNamespace(namespace)
if err != nil {
return nil, err
Expand All @@ -61,6 +59,14 @@ func (r *Runner) GetResourceClassByName(resourceClass string) (rc *ResourceClass
return nil, fmt.Errorf("resource class %q not found", resourceClass)
}

func (r *Runner) GetNamespaceByResourceClass(resourceClass string) (ns string, err error) {
s := strings.SplitN(resourceClass, "/", 2)
if len(s) != 2 {
return "", fmt.Errorf("bad resource class: %q", resourceClass)
}
return s[0], nil
}

func (r *Runner) GetResourceClassesByNamespace(namespace string) ([]ResourceClass, error) {
query := url.Values{}
query.Set("namespace", namespace)
Expand Down
28 changes: 28 additions & 0 deletions cmd/runner/resource_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ func newResourceClassCommand(o *runnerOpts, preRunE validator) *cobra.Command {
Args: cobra.ExactArgs(2),
PreRunE: preRunE,
RunE: func(_ *cobra.Command, args []string) error {
if err := presentTerms(args[0], o, cmd); err != nil {
return err
}

rc, err := o.r.CreateResourceClass(args[0], args[1])
if err != nil {
return err
Expand Down Expand Up @@ -94,3 +98,27 @@ func newResourceClassTable(writer io.Writer) *tablewriter.Table {
func appendResourceClass(table *tablewriter.Table, rc runner.ResourceClass) {
table.Append([]string{rc.ResourceClass, rc.Description})
}

const terms = "If you have not already agreed to Runner Terms in a signed Order, " +
"then by continuing to install Runner, " +
"you are agreeing to CircleCI's Runner Terms which are found at: https://circleci.com/legal/runner-terms/.\n\n" +
"If you already agreed to Runner Terms in a signed Order, " +
"the Runner Terms in the signed Order supersede the Runner Terms in the web address above.\n\n" +
"If you did not already agree to Runner Terms through a signed Order and do not agree to the Runner Terms in the web address above, " +
"please do not install or use Runner.\n\n"

func presentTerms(rc string, o *runnerOpts, cmd *cobra.Command) error {
ns, err := o.r.GetNamespaceByResourceClass(rc)
if err != nil {
return err
}
rcs, err := o.r.GetResourceClassesByNamespace(ns)
if err != nil {
return err
}
// Only present the terms on creation of the first resource class in a namespace
if len(rcs) == 0 {
cmd.PrintErr(terms)
}
return nil
}
59 changes: 53 additions & 6 deletions cmd/runner/resource_class_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package runner

import (
"bytes"
"fmt"
"strings"
"testing"
"time"
Expand All @@ -16,13 +17,16 @@ import (
func Test_ResourceClass(t *testing.T) {
runner := runnerMock{}
cmd := newResourceClassCommand(&runnerOpts{r: &runner}, nil)
b := new(bytes.Buffer)
cmd.SetOut(b)
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
cmd.SetOut(stdout)
cmd.SetErr(stderr)

t.Run("create", func(t *testing.T) {
t.Run("without default token", func(t *testing.T) {
defer runner.reset()
defer b.Reset()
defer stdout.Reset()
defer stderr.Reset()

cmd.SetArgs([]string{
"create",
Expand All @@ -36,14 +40,32 @@ func Test_ResourceClass(t *testing.T) {
assert.Check(t, cmp.Equal(len(runner.resourceClasses), 1))
assert.Check(t, cmp.Equal(runner.resourceClasses[0].ResourceClass, "my-namespace/my-resource-class"))
assert.Check(t, cmp.Equal(runner.resourceClasses[0].Description, "my-description"))
assert.Check(t, cmp.Contains(b.String(), "my-namespace/my-resource-class"))
assert.Check(t, cmp.Contains(stdout.String(), "my-namespace/my-resource-class"))

assert.Check(t, cmp.Equal(len(runner.tokens), 0))

assert.Check(t, cmp.Contains(stderr.String(), terms))
t.Run("don't show terms again", func(t *testing.T) {
stderr.Reset()

cmd.SetArgs([]string{
"create",
"my-namespace/my-second-resource-class",
"my-description",
})

err := cmd.Execute()
assert.NilError(t, err)

assert.Check(t, cmp.Equal(len(runner.resourceClasses), 2))
assert.Check(t, !strings.Contains(stderr.String(), terms))
})
})

t.Run("with default token", func(t *testing.T) {
defer runner.reset()
defer b.Reset()
defer stdout.Reset()
defer stderr.Reset()

cmd.SetArgs([]string{
"create",
Expand All @@ -54,7 +76,7 @@ func Test_ResourceClass(t *testing.T) {

err := cmd.Execute()
assert.NilError(t, err)
out := b.String()
out := stdout.String()

assert.Check(t, cmp.Equal(len(runner.resourceClasses), 1))
assert.Check(t, cmp.Equal(runner.resourceClasses[0].ResourceClass, "my-namespace/my-other-resource-class"))
Expand All @@ -65,6 +87,23 @@ func Test_ResourceClass(t *testing.T) {
assert.Check(t, cmp.Equal(runner.tokens[0].ResourceClass, "my-namespace/my-other-resource-class"))
assert.Check(t, cmp.Equal(runner.tokens[0].Nickname, "default"))
assert.Check(t, cmp.Contains(out, "fake-token"))

assert.Check(t, cmp.Contains(stderr.String(), terms))
t.Run("don't show terms again", func(t *testing.T) {
stderr.Reset()

cmd.SetArgs([]string{
"create",
"my-namespace/my-second-resource-class",
"my-description",
})

err := cmd.Execute()
assert.NilError(t, err)

assert.Check(t, cmp.Equal(len(runner.resourceClasses), 2))
assert.Check(t, !strings.Contains(stderr.String(), terms))
})
})
})
}
Expand Down Expand Up @@ -93,6 +132,14 @@ func (r *runnerMock) GetResourceClassByName(resourceClass string) (*runner.Resou
return nil, errors.New("not found")
}

func (r *runnerMock) GetNamespaceByResourceClass(resourceClass string) (string, error) {
s := strings.SplitN(resourceClass, "/", 2)
if len(s) != 2 {
return "", fmt.Errorf("bad resource class: %q", resourceClass)
}
return s[0], nil
}

func (r *runnerMock) GetResourceClassesByNamespace(namespace string) ([]runner.ResourceClass, error) {
var rcs []runner.ResourceClass
for _, rc := range r.resourceClasses {
Expand Down
1 change: 1 addition & 0 deletions cmd/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func NewCommand(config *settings.Config, preRunE validator) *cobra.Command {
type running interface {
CreateResourceClass(resourceClass, desc string) (rc *runner.ResourceClass, err error)
GetResourceClassByName(resourceClass string) (rc *runner.ResourceClass, err error)
GetNamespaceByResourceClass(resourceClass string) (ns string, err error)
GetResourceClassesByNamespace(namespace string) ([]runner.ResourceClass, error)
DeleteResourceClass(id string) error
CreateToken(resourceClass, nickname string) (token *runner.Token, err error)
Expand Down

0 comments on commit e367219

Please sign in to comment.