Skip to content
Open
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
17 changes: 17 additions & 0 deletions internal/test/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package test

import (
"context"
"os"
"testing"

Expand Down Expand Up @@ -120,6 +121,22 @@ func WithInterceptorFuncs(f interceptor.Funcs) ClientSetupOption {
}
}

// WithNoFlagsInterceptor returns a ClientSetupOption that resets the
// ResourceVersion after each Update call, causing the updater to detect a
// no-op and return an error. Use this in "no-flags" test cases.
func WithNoFlagsInterceptor() ClientSetupOption {
return WithInterceptorFuncs(interceptor.Funcs{
Update: func(ctx context.Context, c client.WithWatch, obj client.Object, opts ...client.UpdateOption) error {
oldRV := obj.GetResourceVersion()
if err := c.Update(ctx, obj, opts...); err != nil {
return err
}
obj.SetResourceVersion(oldRV)
return nil
},
})
}

func SetupClient(t *testing.T, opts ...ClientSetupOption) *api.Client {
t.Helper()

Expand Down
6 changes: 3 additions & 3 deletions update/apiserviceaccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ func (cmd *apiServiceAccountCmd) Run(ctx context.Context, client *api.Client) er
if !ok {
return fmt.Errorf("resource is of type %T, expected %T", current, iam.APIServiceAccount{})
}
cmd.applyUpdates(asa)
return nil
return cmd.applyUpdates(asa)
}).Update(ctx)
}

func (cmd *apiServiceAccountCmd) applyUpdates(asa *iam.APIServiceAccount) {
func (cmd *apiServiceAccountCmd) applyUpdates(asa *iam.APIServiceAccount) error {
if cmd.OrganizationAccess != nil {
asa.Spec.ForProvider.OrganizationAccess = *cmd.OrganizationAccess
}
return nil
}
43 changes: 31 additions & 12 deletions update/apiserviceaccount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,22 @@ func TestAPIServiceAccount(t *testing.T) {
orig *iam.APIServiceAccount
cmd apiServiceAccountCmd
checkAPIServiceAccount func(t *testing.T, cmd apiServiceAccountCmd, orig, updated *iam.APIServiceAccount)
errorExpected bool
clientOpts []test.ClientSetupOption
}{
"no-flags": {
orig: &iam.APIServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: asaName,
Namespace: organization,
},
},
cmd: apiServiceAccountCmd{
resourceCmd: resourceCmd{Name: asaName},
},
errorExpected: true,
clientOpts: []test.ClientSetupOption{test.WithNoFlagsInterceptor()},
},
"all fields update": {
orig: &iam.APIServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -50,31 +65,35 @@ func TestAPIServiceAccount(t *testing.T) {
out := &bytes.Buffer{}
tc.cmd.Writer = format.NewWriter(out)

apiClient := test.SetupClient(t,
opts := []test.ClientSetupOption{
test.WithObjects(tc.orig),
test.WithOrganization(organization),
test.WithDefaultProject(organization),
test.WithKubeconfig(),
)
}
opts = append(opts, tc.clientOpts...)
apiClient := test.SetupClient(t, opts...)

if err := tc.cmd.Run(t.Context(), apiClient); err != nil {
t.Fatal(err)
if err := tc.cmd.Run(t.Context(), apiClient); (err != nil) != tc.errorExpected {
t.Fatalf("apiServiceAccountCmd.Run() error = %v, errorExpected %v", err, tc.errorExpected)
}

updated := &iam.APIServiceAccount{}
if err := apiClient.Get(t.Context(), api.ObjectName(tc.orig), updated); err != nil {
t.Fatal(err)
}

if tc.checkAPIServiceAccount != nil {
tc.checkAPIServiceAccount(t, tc.cmd, tc.orig, updated)
}
if !tc.errorExpected {
if tc.checkAPIServiceAccount != nil {
tc.checkAPIServiceAccount(t, tc.cmd, tc.orig, updated)
}

if !strings.Contains(out.String(), "updated") {
t.Errorf("expected output to contain 'updated', got %q", out.String())
}
if !strings.Contains(out.String(), asaName) {
t.Errorf("expected output to contain %q, got %q", asaName, out.String())
if !strings.Contains(out.String(), "updated") {
t.Errorf("expected output to contain 'updated', got %q", out.String())
}
if !strings.Contains(out.String(), asaName) {
t.Errorf("expected output to contain %q, got %q", asaName, out.String())
}
}
})
}
Expand Down
46 changes: 26 additions & 20 deletions update/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,22 @@ type applicationCmd struct {
// structs. Due to the usage of kong these pointers will never be `nil`.
// So checking for `nil` values can not be used to find out if some of
// the struct fields have been set.
DeployJob *deployJob `embed:"" prefix:"deploy-job-"`
WorkerJob *workerJob `embed:"" prefix:"worker-job-"`
ScheduledJob *scheduledJob `embed:"" prefix:"scheduled-job-"`
DeleteWorkerJob *string `help:"Delete a worker job by name."`
DeleteScheduledJob *string `help:"Delete a scheduled job by name."`
DeployJob *deployJob `embed:"" prefix:"deploy-job-"`
WorkerJob *workerJob `embed:"" prefix:"worker-job-"`
ScheduledJob *scheduledJob `embed:"" prefix:"scheduled-job-"`
DeleteWorkerJob *string `help:"Delete a worker job by name."`
DeleteScheduledJob *string `help:"Delete a scheduled job by name."`
Service application.ServiceMap `help:"Service reference to add/update in the form name=kind/target-name."`
DeleteService []string `help:"Service reference names to remove."`
RetryRelease *bool `help:"Retries release for the application." placeholder:"false"`
RetryBuild *bool `help:"Retries build for the application if set to true." placeholder:"false"`
Pause *bool `help:"Pauses the application if set to true. Stops all costs." placeholder:"false"`
GitInformationServiceURL string `help:"URL of the git information service." default:"https://git-info.deplo.io" env:"GIT_INFORMATION_SERVICE_URL" hidden:""`
SkipRepoAccessCheck bool `help:"Skip the git repository access check." default:"false"`
Debug bool `help:"Enable debug messages." default:"false"`
Language *string `help:"${app_language_help} Possible values: ${enum}" enum:"ruby,php,python,golang,nodejs,static,"`
DockerfileBuild dockerfileBuild `embed:""`
BuildpackStack *string `help:"${app_buildpack_stack_help} Possible values: ${enum}" enum:"paketo,heroku,"`
DeleteService []string `help:"Service reference names to remove."`
RetryRelease *bool `help:"Retries release for the application." placeholder:"false"`
RetryBuild *bool `help:"Retries build for the application if set to true." placeholder:"false"`
Pause *bool `help:"Pauses the application if set to true. Stops all costs." placeholder:"false"`
GitInformationServiceURL string `help:"URL of the git information service." default:"https://git-info.deplo.io" env:"GIT_INFORMATION_SERVICE_URL" hidden:""`
SkipRepoAccessCheck bool `help:"Skip the git repository access check." default:"false"`
Debug bool `help:"Enable debug messages." default:"false"`
Language *string `help:"${app_language_help} Possible values: ${enum}" enum:"ruby,php,python,golang,nodejs,static,"`
DockerfileBuild dockerfileBuild `embed:""`
BuildpackStack *string `help:"${app_buildpack_stack_help} Possible values: ${enum}" enum:"paketo,heroku,"`
}

type gitConfig struct {
Expand Down Expand Up @@ -151,7 +151,9 @@ func (cmd *applicationCmd) Run(ctx context.Context, client *api.Client) error {
if !ok {
return fmt.Errorf("resource is of type %T, expected %T", current, apps.Application{})
}
cmd.applyUpdates(app)
if err := cmd.applyUpdates(app); err != nil {
return err
}

// if there was no change in the git config, we don't have
// anything to do anymore
Expand Down Expand Up @@ -229,7 +231,7 @@ func (cmd *applicationCmd) Run(ctx context.Context, client *api.Client) error {
return upd.Update(ctx)
}

func (cmd *applicationCmd) applyUpdates(app *apps.Application) {
func (cmd *applicationCmd) applyUpdates(app *apps.Application) error {
// rebuildNeeded determines if a rebuild trigger should be added
rebuildNeeded := false
if cmd.Git != nil {
Expand Down Expand Up @@ -269,7 +271,9 @@ func (cmd *applicationCmd) applyUpdates(app *apps.Application) {
app.Spec.ForProvider.BasicAuthPasswordChange = new(metav1.Now())
}
if cmd.DeployJob != nil {
cmd.DeployJob.applyUpdates(&app.Spec.ForProvider.Config)
if err := cmd.DeployJob.applyUpdates(&app.Spec.ForProvider.Config); err != nil {
return err
}
}
if cmd.WorkerJob != nil && cmd.WorkerJob.changesGiven() {
cmd.WorkerJob.applyUpdates(cmd.Writer, &app.Spec.ForProvider.Config)
Expand Down Expand Up @@ -360,6 +364,7 @@ func (cmd *applicationCmd) applyUpdates(app *apps.Application) {
app.Spec.ForProvider.Services, toAdd, cmd.DeleteService, cmd.Writer,
)
}
return nil
}

func triggerTimestamp() string {
Expand Down Expand Up @@ -390,12 +395,12 @@ func (h healthProbe) applyUpdates(cfg *apps.Config) {
application.ApplyProbePatch(cfg, h.ToProbePatch())
}

func (job deployJob) applyUpdates(cfg *apps.Config) {
func (job deployJob) applyUpdates(cfg *apps.Config) error {
if job.Enabled != nil && !*job.Enabled {
// if enabled is explicitly set to false we set the DeployJob field to
// nil on the API, to completely remove the object.
cfg.DeployJob = nil
return
return nil
}

if job.Name != nil && len(*job.Name) != 0 {
Expand All @@ -410,6 +415,7 @@ func (job deployJob) applyUpdates(cfg *apps.Config) {
if job.Timeout != nil {
ensureDeployJob(cfg).DeployJob.Timeout = &metav1.Duration{Duration: *job.Timeout}
}
return nil
}

func ensureDeployJob(cfg *apps.Config) *apps.Config {
Expand Down
16 changes: 13 additions & 3 deletions update/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,18 @@ func TestApplication(t *testing.T) {
checkSecret func(t *testing.T, cmd applicationCmd, authSecret *corev1.Secret)
gitInformationServiceResponse test.GitInformationServiceResponse
errorExpected bool
clientOpts []test.ClientSetupOption
}{
"no-flags": {
orig: existingApp,
cmd: applicationCmd{
resourceCmd: resourceCmd{
Name: existingApp.Name,
},
},
errorExpected: true,
clientOpts: []test.ClientSetupOption{test.WithNoFlagsInterceptor()},
},
"change port": {
orig: existingApp,
cmd: applicationCmd{
Expand Down Expand Up @@ -761,9 +772,8 @@ func TestApplication(t *testing.T) {
tc.gitAuth.ApplyToSecret(secret)
objects = append(objects, secret)
}
apiClient := test.SetupClient(t,
test.WithObjects(objects...),
)
opts := append([]test.ClientSetupOption{test.WithObjects(objects...)}, tc.clientOpts...)
apiClient := test.SetupClient(t, opts...)

if err := tc.cmd.Run(t.Context(), apiClient); err != nil {
if tc.errorExpected {
Expand Down
10 changes: 8 additions & 2 deletions update/bucketuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ func (cmd *bucketUserCmd) Run(ctx context.Context, client *api.Client) error {
return fmt.Errorf("resource is of type %T, expected %T", current, storage.BucketUser{})
}

bu.Spec.ForProvider.ResetCredentials = cmd.ResetCredentials
return nil
return cmd.applyUpdates(bu)
})

return upd.Update(ctx)
}

func (cmd *bucketUserCmd) applyUpdates(bu *storage.BucketUser) error {
if cmd.ResetCredentials != nil {
bu.Spec.ForProvider.ResetCredentials = cmd.ResetCredentials
}
return nil
}
17 changes: 17 additions & 0 deletions update/bucketuser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,23 @@ func TestBucketUser(t *testing.T) {
}
}

func TestBucketUserNoFlags(t *testing.T) {
t.Parallel()

apiClient := test.SetupClient(t, test.WithNoFlagsInterceptor())

created := bucketUser("user-noflags", apiClient.Project, "nine-es34")
if err := apiClient.Create(t.Context(), created); err != nil {
t.Fatalf("bucketuser create error, got: %s", err)
}

out := &bytes.Buffer{}
cmd := bucketUserCmd{resourceCmd{Writer: format.NewWriter(out), Name: created.Name}, nil}
if err := cmd.Run(t.Context(), apiClient); err == nil {
t.Error("expected error when no flags provided, got nil")
}
}

func bucketUser(name, project, location string) *storage.BucketUser {
return &storage.BucketUser{
ObjectMeta: metav1.ObjectMeta{
Expand Down
18 changes: 12 additions & 6 deletions update/cloudvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ func TestCloudVM(t *testing.T) {
t.Parallel()

tests := []struct {
name string
create infrastructure.CloudVirtualMachineParameters
update cloudVMCmd
want infrastructure.CloudVirtualMachineParameters
wantErr bool
name string
create infrastructure.CloudVirtualMachineParameters
update cloudVMCmd
want infrastructure.CloudVirtualMachineParameters
wantErr bool
clientOpts []test.ClientSetupOption
}{
{
name: "no-flags",
wantErr: true,
clientOpts: []test.ClientSetupOption{test.WithNoFlagsInterceptor()},
},
{
name: "simple",
},
Expand Down Expand Up @@ -60,7 +66,7 @@ func TestCloudVM(t *testing.T) {
tt.update.Writer = format.NewWriter(out)
tt.update.Name = "test-" + t.Name()

apiClient := test.SetupClient(t)
apiClient := test.SetupClient(t, tt.clientOpts...)

created := test.CloudVirtualMachine(tt.update.Name, apiClient.Project, "nine-es34", tt.create.PowerState)
created.Spec.ForProvider = tt.create
Expand Down
6 changes: 3 additions & 3 deletions update/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ func (cmd *grafanaCmd) Run(ctx context.Context, client *api.Client) error {
return fmt.Errorf("resource is of type %T, expected %T", current, observability.Grafana{})
}

cmd.applyUpdates(grafana)
return nil
return cmd.applyUpdates(grafana)
}).Update(ctx)
}

func (cmd *grafanaCmd) applyUpdates(grafana *observability.Grafana) {
func (cmd *grafanaCmd) applyUpdates(grafana *observability.Grafana) error {
if cmd.AdminAccess != nil {
grafana.Spec.ForProvider.EnableAdminAccess = *cmd.AdminAccess
}
if cmd.LocalUsers != nil {
grafana.Spec.ForProvider.AllowLocalUsers = *cmd.LocalUsers
}
return nil
}
18 changes: 12 additions & 6 deletions update/grafana_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ func TestGrafana(t *testing.T) {
t.Parallel()

tests := []struct {
name string
create observability.GrafanaParameters
update grafanaCmd
want observability.GrafanaParameters
wantErr bool
name string
create observability.GrafanaParameters
update grafanaCmd
want observability.GrafanaParameters
wantErr bool
clientOpts []test.ClientSetupOption
}{
{
name: "no-flags",
wantErr: true,
clientOpts: []test.ClientSetupOption{test.WithNoFlagsInterceptor()},
},
{
name: "simple",
},
Expand Down Expand Up @@ -61,7 +67,7 @@ func TestGrafana(t *testing.T) {
tt.update.Writer = format.NewWriter(out)
tt.update.Name = "test-" + t.Name()

apiClient := test.SetupClient(t)
apiClient := test.SetupClient(t, tt.clientOpts...)

created := test.Grafana(tt.update.Name, apiClient.Project)
created.Spec.ForProvider = tt.create
Expand Down
Loading
Loading