Skip to content

Commit

Permalink
up/profile: check for Spaces in 'profile set space'
Browse files Browse the repository at this point in the history
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.com>
  • Loading branch information
sttts committed Nov 1, 2023
1 parent a293ebc commit dffdbb2
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 7 deletions.
45 changes: 42 additions & 3 deletions cmd/up/profile/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,28 @@
package profile

import (
_ "embed"
"context"
"fmt"

"github.com/alecthomas/kong"
"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/pterm/pterm"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

"github.com/crossplane/crossplane-runtime/pkg/errors"

"github.com/upbound/up/internal/profile"
"github.com/upbound/up/internal/upbound"

_ "embed"
)

const (
errSetProfile = "unable to set profile"
errUpdateConfig = "unable to update config file"
errNoSpace = "cannot find Spaces in the Kubernetes cluster. Run 'up space init' to install Spaces."
errKubeContact = "unable to check for Spaces on Kubernetes cluster"
)

type setCmd struct {
Expand All @@ -37,6 +45,8 @@ type setCmd struct {

type spaceCmd struct {
Kube upbound.KubeFlags `embed:""`

getClient func() (kubernetes.Interface, error)
}

//go:embed space_help.txt
Expand All @@ -50,7 +60,7 @@ func (c *spaceCmd) AfterApply(kongCtx *kong.Context) error {
return c.Kube.AfterApply()
}

func (c *spaceCmd) Run(p pterm.TextPrinter, upCtx *upbound.Context) error {
func (c *spaceCmd) Run(ctx context.Context, p pterm.TextPrinter, upCtx *upbound.Context) error {
setDefault := false

// If profile name was not provided and no default exists, set name to
Expand All @@ -69,6 +79,14 @@ func (c *spaceCmd) Run(p pterm.TextPrinter, upCtx *upbound.Context) error {
BaseConfig: upCtx.Profile.BaseConfig,
}

installed, err := c.checkForSpaces(ctx)
if err != nil {
return err
}
if !installed {
return errors.New(errNoSpace)
}

if err := upCtx.Cfg.AddOrUpdateUpboundProfile(upCtx.ProfileName, prof); err != nil {
return errors.Wrap(err, errSetProfile)
}
Expand All @@ -95,3 +113,24 @@ func (c *spaceCmd) Run(p pterm.TextPrinter, upCtx *upbound.Context) error {

return nil
}

func (c *spaceCmd) checkForSpaces(ctx context.Context) (bool, error) {
kubeconfig := c.Kube.GetConfig()
var kClient kubernetes.Interface
var err error
if c.getClient != nil {
kClient, err = c.getClient()
} else {
kClient, err = kubernetes.NewForConfig(kubeconfig)
}
if err != nil {
return false, err
}
if _, err := kClient.AppsV1().Deployments("upbound-system").Get(ctx, "mxe-controller", metav1.GetOptions{}); kerrors.IsNotFound(err) {
return false, nil
} else if err != nil {
return false, errors.Wrap(err, errKubeContact)
}

return true, nil
}
73 changes: 69 additions & 4 deletions cmd/up/profile/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@
package profile

import (
"context"
"io"
"os"
"testing"

"github.com/crossplane/crossplane-runtime/pkg/test"
"github.com/google/go-cmp/cmp"
"github.com/pterm/pterm"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
clientgotesting "k8s.io/client-go/testing"

"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/test"

"github.com/upbound/up/internal/config"
"github.com/upbound/up/internal/profile"
Expand Down Expand Up @@ -54,8 +63,16 @@ func TestSpaceCmd_Run(t *testing.T) {
}
kubeconfig := wd + "/testdata/kubeconfig"

mxeController := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "mxe-controller",
Namespace: "upbound-system",
},
}

type args struct {
ctx *upbound.Context
ctx *upbound.Context
getClient func() (kubernetes.Interface, error)
}
type want struct {
cfg *config.Config
Expand All @@ -73,6 +90,9 @@ func TestSpaceCmd_Run(t *testing.T) {
Account: "test-account",
Cfg: &config.Config{},
},
getClient: func() (kubernetes.Interface, error) {
return fake.NewSimpleClientset(mxeController), nil
},
},
want: want{
cfg: &config.Config{Upbound: config.Upbound{
Expand All @@ -88,6 +108,42 @@ func TestSpaceCmd_Run(t *testing.T) {
}},
},
},
"NoSpacesError": {
reason: "There is no upbound/mxe-controller in the cluster.",
args: args{
ctx: &upbound.Context{
Account: "test-account",
Cfg: &config.Config{},
},
getClient: func() (kubernetes.Interface, error) {
return fake.NewSimpleClientset(), nil
},
},
want: want{
err: errors.New(errNoSpace),
cfg: &config.Config{},
},
},
"KubeClientError": {
reason: "The kube clients returns a non-NotFound error.",
args: args{
ctx: &upbound.Context{
Account: "test-account",
Cfg: &config.Config{},
},
getClient: func() (kubernetes.Interface, error) {
c := fake.NewSimpleClientset()
c.PrependReactor("get", "deployments", func(action clientgotesting.Action) (handled bool, ret runtime.Object, err error) {
return true, nil, errors.New("contact error")
})
return c, nil
},
},
want: want{
err: errors.Wrap(errors.New("contact error"), errKubeContact),
cfg: &config.Config{},
},
},
"PopulatedConfigDefaultProfile": {
reason: "Setting the default profile with populated config updates the default profile.",
args: args{
Expand All @@ -111,6 +167,9 @@ func TestSpaceCmd_Run(t *testing.T) {
},
}},
},
getClient: func() (kubernetes.Interface, error) {
return fake.NewSimpleClientset(mxeController), nil
},
},
want: want{
cfg: &config.Config{Upbound: config.Upbound{
Expand Down Expand Up @@ -150,6 +209,9 @@ func TestSpaceCmd_Run(t *testing.T) {
},
}},
},
getClient: func() (kubernetes.Interface, error) {
return fake.NewSimpleClientset(mxeController), nil
},
},
want: want{
cfg: &config.Config{Upbound: config.Upbound{
Expand Down Expand Up @@ -195,6 +257,9 @@ func TestSpaceCmd_Run(t *testing.T) {
},
}},
},
getClient: func() (kubernetes.Interface, error) {
return fake.NewSimpleClientset(mxeController), nil
},
},
want: want{
cfg: &config.Config{Upbound: config.Upbound{
Expand All @@ -220,15 +285,15 @@ func TestSpaceCmd_Run(t *testing.T) {

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
cmd := &spaceCmd{Kube: upbound.KubeFlags{Kubeconfig: kubeconfig}}
cmd := &spaceCmd{Kube: upbound.KubeFlags{Kubeconfig: kubeconfig}, getClient: tc.args.getClient}
if diff := cmp.Diff(nil, cmd.AfterApply(nil), test.EquateErrors()); diff != "" {
t.Errorf("\n%s\nspaceCmd.AfterApply(...): -want error, +got error:\n%s", tc.reason, diff)
}

cfgSrc := &mockConfigSource{cfg: tc.args.ctx.Cfg}
tc.args.ctx.CfgSrc = cfgSrc
p := pterm.DefaultBasicText.WithWriter(io.Discard)
if diff := cmp.Diff(tc.want.err, cmd.Run(p, tc.args.ctx), test.EquateErrors()); diff != "" {
if diff := cmp.Diff(tc.want.err, cmd.Run(context.TODO(), p, tc.args.ctx), test.EquateErrors()); diff != "" {
t.Errorf("\n%s\nspaceCmd.Run(...): -want error, +got error:\n%s", tc.reason, diff)
}
if diff := cmp.Diff(tc.want.cfg, cfgSrc.cfg); diff != "" {
Expand Down

0 comments on commit dffdbb2

Please sign in to comment.