diff --git a/integration/run/run_test.go b/integration/run/run_test.go index bc58f6bcb..ac95d749a 100644 --- a/integration/run/run_test.go +++ b/integration/run/run_test.go @@ -40,7 +40,7 @@ func TestVolume(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) image, err := c.AcornImageBuild(ctx, "./testdata/volume/Acornfile", &client.AcornImageBuildOptions{ @@ -55,7 +55,7 @@ func TestVolume(t *testing.T) { t.Fatal(err) } - pv := helper.Wait(t, kclient.Watch, &corev1.PersistentVolumeList{}, func(obj *corev1.PersistentVolume) bool { + pv := helper.Wait(t, kc.Watch, &corev1.PersistentVolumeList{}, func(obj *corev1.PersistentVolume) bool { return obj.Labels[labels.AcornAppName] == app.Name && obj.Labels[labels.AcornAppNamespace] == app.Namespace && obj.Labels[labels.AcornManaged] == "true" && @@ -85,7 +85,7 @@ func TestVolume(t *testing.T) { t.Fatal(err) } - helper.WaitForObject(t, kclient.Watch, &corev1.PersistentVolumeList{}, pv, func(obj *corev1.PersistentVolume) bool { + helper.WaitForObject(t, kc.Watch, &corev1.PersistentVolumeList{}, pv, func(obj *corev1.PersistentVolume) bool { return obj.Status.Phase == corev1.VolumeBound && obj.Labels[labels.AcornAppName] == app.Name && obj.Labels[labels.AcornAppNamespace] == app.Namespace && @@ -123,7 +123,7 @@ func TestServiceConsumer(t *testing.T) { ctx := helper.GetCTX(t) c, _ := helper.ClientAndProject(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) image, err := c.AcornImageBuild(ctx, "./testdata/serviceconsumer/Acornfile", &client.AcornImageBuildOptions{ Cwd: "./testdata/serviceconsumer/", @@ -151,9 +151,8 @@ func TestServiceConsumer(t *testing.T) { }}, }}, }, - Status: v1.AppInstanceStatus{}, } - if err := kclient.Create(ctx, appInstance); err != nil { + if err := kc.Create(ctx, appInstance); err != nil { t.Fatal(err) } @@ -171,11 +170,11 @@ func TestVolumeBadClassInImageBoundToGoodClass(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) storageClasses := new(storagev1.StorageClassList) - err := kclient.List(ctx, storageClasses) + err := kc.List(ctx, storageClasses) if err != nil || len(storageClasses.Items) == 0 { t.Skip("No storage classes, so skipping VolumeBadClassInImageBoundToGoodClass") return @@ -186,11 +185,11 @@ func TestVolumeBadClassInImageBoundToGoodClass(t *testing.T) { StorageClassName: getStorageClassName(t, storageClasses), SupportedRegions: []string{apiv1.LocalRegion}, } - if err = kclient.Create(ctx, &volumeClass); err != nil { + if err = kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err = kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err = kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -214,7 +213,7 @@ func TestVolumeBadClassInImageBoundToGoodClass(t *testing.T) { t.Fatal(err) } - helper.Wait(t, kclient.Watch, &corev1.PersistentVolumeClaimList{}, func(obj *corev1.PersistentVolumeClaim) bool { + helper.Wait(t, kc.Watch, &corev1.PersistentVolumeClaimList{}, func(obj *corev1.PersistentVolumeClaim) bool { return obj.Labels[labels.AcornAppName] == app.Name && obj.Labels[labels.AcornAppNamespace] == app.Namespace && obj.Labels[labels.AcornManaged] == "true" && @@ -232,11 +231,11 @@ func TestVolumeBoundBadClass(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) storageClasses := new(storagev1.StorageClassList) - if err := kclient.List(ctx, storageClasses); err != nil { + if err := kc.List(ctx, storageClasses); err != nil { t.Fatal(err) } @@ -246,11 +245,11 @@ func TestVolumeBoundBadClass(t *testing.T) { SupportedRegions: []string{apiv1.LocalRegion}, } - if err := kclient.Create(ctx, &volumeClass); err != nil { + if err := kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err := kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err := kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -279,7 +278,7 @@ func TestVolumeClassInactive(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) volumeClass := adminapiv1.ClusterVolumeClass{ @@ -287,11 +286,11 @@ func TestVolumeClassInactive(t *testing.T) { Inactive: true, SupportedRegions: []string{apiv1.LocalRegion}, } - if err := kclient.Create(ctx, &volumeClass); err != nil { + if err := kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err := kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err := kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -313,7 +312,7 @@ func TestVolumeClassSizeTooSmall(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) volumeClass := adminapiv1.ClusterVolumeClass{ @@ -324,11 +323,11 @@ func TestVolumeClassSizeTooSmall(t *testing.T) { }, SupportedRegions: []string{apiv1.LocalRegion}, } - if err := kclient.Create(ctx, &volumeClass); err != nil { + if err := kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err := kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err := kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -357,7 +356,7 @@ func TestVolumeClassSizeTooLarge(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) volumeClass := adminapiv1.ClusterVolumeClass{ @@ -368,11 +367,11 @@ func TestVolumeClassSizeTooLarge(t *testing.T) { }, SupportedRegions: []string{apiv1.LocalRegion}, } - if err := kclient.Create(ctx, &volumeClass); err != nil { + if err := kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err := kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err := kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -401,11 +400,11 @@ func TestVolumeClassRemoved(t *testing.T) { helper.StartController(t) ctx := helper.GetCTX(t) - kclient := helper.MustReturn(kclient.Default) + kc := helper.MustReturn(kclient.Default) c, _ := helper.ClientAndProject(t) storageClasses := new(storagev1.StorageClassList) - err := kclient.List(ctx, storageClasses) + err := kc.List(ctx, storageClasses) if err != nil || len(storageClasses.Items) == 0 { t.Skip("No storage classes, so skipping VolumeClassRemoved") return @@ -416,11 +415,11 @@ func TestVolumeClassRemoved(t *testing.T) { StorageClassName: getStorageClassName(t, storageClasses), SupportedRegions: []string{apiv1.LocalRegion}, } - if err = kclient.Create(ctx, &volumeClass); err != nil { + if err = kc.Create(ctx, &volumeClass); err != nil { t.Fatal(err) } defer func() { - if err = kclient.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { + if err = kc.Delete(context.Background(), &volumeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } }() @@ -437,7 +436,7 @@ func TestVolumeClassRemoved(t *testing.T) { t.Fatal(err) } - helper.Wait(t, kclient.Watch, &corev1.PersistentVolumeClaimList{}, func(obj *corev1.PersistentVolumeClaim) bool { + helper.Wait(t, kc.Watch, &corev1.PersistentVolumeClaimList{}, func(obj *corev1.PersistentVolumeClaim) bool { return obj.Labels[labels.AcornAppName] == app.Name && obj.Labels[labels.AcornAppNamespace] == app.Namespace && obj.Labels[labels.AcornManaged] == "true" && @@ -449,7 +448,7 @@ func TestVolumeClassRemoved(t *testing.T) { done := obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionVolumes).Success if done { - if err = kclient.Delete(ctx, &volumeClass); err != nil { + if err = kc.Delete(ctx, &volumeClass); err != nil { t.Fatal(err) } } @@ -934,13 +933,8 @@ func TestDeployParam(t *testing.T) { func TestUsingComputeClasses(t *testing.T) { helper.StartController(t) - cfg := helper.StartAPI(t) - project := helper.TempProject(t, helper.MustReturn(kclient.Default)) + c, _ := helper.ClientAndProject(t) kclient := helper.MustReturn(kclient.Default) - c, err := client.New(cfg, "", project.Name) - if err != nil { - t.Fatal(err) - } ctx := helper.GetCTX(t) @@ -950,7 +944,7 @@ func TestUsingComputeClasses(t *testing.T) { testDataDirectory string computeClass adminv1.ProjectComputeClassInstance expected map[string]v1.Scheduling - waitFor func(obj *apiv1.App) bool + waitFor func(obj *v1.AppInstance) bool fail bool }{ { @@ -993,7 +987,7 @@ func TestUsingComputeClasses(t *testing.T) { }, }}, }, - waitFor: func(obj *apiv1.App) bool { + waitFor: func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionScheduling).Success }, @@ -1027,7 +1021,7 @@ func TestUsingComputeClasses(t *testing.T) { Operator: corev1.TolerationOpExists, }, }}}, - waitFor: func(obj *apiv1.App) bool { + waitFor: func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionScheduling).Success }, @@ -1066,7 +1060,7 @@ func TestUsingComputeClasses(t *testing.T) { }, }}, }, - waitFor: func(obj *apiv1.App) bool { + waitFor: func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionScheduling).Success }, @@ -1104,7 +1098,7 @@ func TestUsingComputeClasses(t *testing.T) { }, }}, }, - waitFor: func(obj *apiv1.App) bool { + waitFor: func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionScheduling).Success }, @@ -1131,7 +1125,7 @@ func TestUsingComputeClasses(t *testing.T) { }, }}, }, - waitFor: func(obj *apiv1.App) bool { + waitFor: func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success && obj.Status.Condition(v1.AppInstanceConditionScheduling).Success }, @@ -1176,7 +1170,7 @@ func TestUsingComputeClasses(t *testing.T) { // Clean-up and gurantee the computeclass doesn't exist after this test run t.Cleanup(func() { - if err = kclient.Delete(context.Background(), computeClass); err != nil && !apierrors.IsNotFound(err) { + if err := kclient.Delete(context.Background(), computeClass); err != nil && !apierrors.IsNotFound(err) { t.Fatal(err) } err := helper.EnsureDoesNotExist(ctx, func() (crClient.Object, error) { @@ -1225,8 +1219,14 @@ func TestUsingComputeClasses(t *testing.T) { } if tt.waitFor != nil { - app = helper.WaitForObject(t, helper.Watcher(t, c), new(apiv1.AppList), app, tt.waitFor) - assert.EqualValues(t, app.Status.Scheduling, tt.expected, "generated scheduling rules are incorrect") + appInstance := &v1.AppInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: app.Name, + Namespace: app.Namespace, + }, + } + appInstance = helper.WaitForObject(t, kclient.Watch, new(v1.AppInstanceList), appInstance, tt.waitFor) + assert.EqualValues(t, appInstance.Status.Scheduling, tt.expected, "generated scheduling rules are incorrect") } }) } @@ -1745,8 +1745,8 @@ func TestAutoUpgradeLocalImage(t *testing.T) { if err != nil { t.Fatal("error while getting rest config:", err) } - kclient := helper.MustReturn(kclient.Default) - project := helper.TempProject(t, kclient) + kc := helper.MustReturn(kclient.Default) + project := helper.TempProject(t, kc) c, err := client.New(restConfig, project.Name, project.Name) if err != nil { @@ -1797,10 +1797,10 @@ func TestIgnoreResourceRequirements(t *testing.T) { if err != nil { t.Fatal("error while getting rest config:", err) } - kclient := helper.MustReturn(kclient.Default) - project := helper.TempProject(t, kclient) + kc := helper.MustReturn(kclient.Default) + project := helper.TempProject(t, kc) - helper.SetIgnoreResourceRequirementsWithRestore(t, ctx, kclient) + helper.SetIgnoreResourceRequirementsWithRestore(t, ctx, kc) c, err := client.New(restConfig, project.Name, project.Name) if err != nil { @@ -1824,8 +1824,14 @@ func TestIgnoreResourceRequirements(t *testing.T) { t.Fatal(err) } - app = helper.WaitForObject(t, helper.Watcher(t, c), &apiv1.AppList{}, app, func(obj *apiv1.App) bool { + appInstance := &v1.AppInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: app.Name, + Namespace: app.Namespace, + }, + } + appInstance = helper.WaitForObject(t, helper.Watcher(t, c), &v1.AppInstanceList{}, appInstance, func(obj *v1.AppInstance) bool { return obj.Status.Condition(v1.AppInstanceConditionParsed).Success }) - assert.Empty(t, app.Status.Scheduling["simple"].Requirements) + assert.Empty(t, appInstance.Status.Scheduling["simple"].Requirements) } diff --git a/pkg/apis/api.acorn.io/v1/app.go b/pkg/apis/api.acorn.io/v1/app.go new file mode 100644 index 000000000..d03a62e75 --- /dev/null +++ b/pkg/apis/api.acorn.io/v1/app.go @@ -0,0 +1,70 @@ +package v1 + +import ( + v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type App struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + Spec v1.AppInstanceSpec `json:"spec,omitempty"` + Status AppStatus `json:"status,omitempty"` +} + +func (in *App) GetStopped() bool { + return in.Spec.Stop != nil && *in.Spec.Stop && in.DeletionTimestamp.IsZero() +} + +func (in *App) GetRegion() string { + if in.Spec.Region != "" { + return in.Spec.Region + } + return in.Status.Defaults.Region +} + +type AppStatus v1.EmbeddedAppStatus + +func (in *AppStatus) Condition(name string) v1.Condition { + for _, cond := range in.Conditions { + if cond.Type == name { + return cond + } + } + return v1.Condition{} +} + +func (in *AppStatus) GetDevMode() bool { + return in.DevSession != nil +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AppList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []App `json:"items"` +} + +// AppToAppInstance converts an App to a [v1.AppInstance] and returns the result. +func AppToAppInstance(in *App) *v1.AppInstance { + return &v1.AppInstance{ + ObjectMeta: in.ObjectMeta, + Spec: in.Spec, + Status: v1.AppInstanceStatus{ + EmbeddedAppStatus: v1.EmbeddedAppStatus(in.Status), + }, + } +} + +// AppInstanceToApp converts a [v1.AppInstance] to an App and returns the result. +func AppInstanceToApp(in *v1.AppInstance) *App { + return &App{ + ObjectMeta: in.ObjectMeta, + Spec: in.Spec, + Status: AppStatus(in.Status.EmbeddedAppStatus), + } +} diff --git a/pkg/apis/api.acorn.io/v1/types.go b/pkg/apis/api.acorn.io/v1/types.go index a5553e3c4..0ad85c96b 100644 --- a/pkg/apis/api.acorn.io/v1/types.go +++ b/pkg/apis/api.acorn.io/v1/types.go @@ -10,37 +10,6 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type App struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - - Spec v1.AppInstanceSpec `json:"spec,omitempty"` - Status v1.AppInstanceStatus `json:"status,omitempty"` -} - -func (in *App) GetStopped() bool { - return in.Spec.Stop != nil && *in.Spec.Stop && in.DeletionTimestamp.IsZero() -} - -func (in *App) GetRegion() string { - if in.Spec.Region != "" { - return in.Spec.Region - } - return in.Status.Defaults.Region -} - -type Acornfile v1.AppSpec - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -type AppList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []App `json:"items"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - type ContainerReplica struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` diff --git a/pkg/apis/api.acorn.io/v1/zz_generated.deepcopy.go b/pkg/apis/api.acorn.io/v1/zz_generated.deepcopy.go index 56377b4e7..534d2bc89 100644 --- a/pkg/apis/api.acorn.io/v1/zz_generated.deepcopy.go +++ b/pkg/apis/api.acorn.io/v1/zz_generated.deepcopy.go @@ -71,105 +71,6 @@ func (in *AcornImageBuildList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Acornfile) DeepCopyInto(out *Acornfile) { - *out = *in - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Containers != nil { - in, out := &in.Containers, &out.Containers - *out = make(map[string]internal_acorn_iov1.Container, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Functions != nil { - in, out := &in.Functions, &out.Functions - *out = make(map[string]internal_acorn_iov1.Container, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Jobs != nil { - in, out := &in.Jobs, &out.Jobs - *out = make(map[string]internal_acorn_iov1.Container, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Images != nil { - in, out := &in.Images, &out.Images - *out = make(map[string]internal_acorn_iov1.Image, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make(map[string]internal_acorn_iov1.VolumeRequest, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Secrets != nil { - in, out := &in.Secrets, &out.Secrets - *out = make(map[string]internal_acorn_iov1.Secret, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Acorns != nil { - in, out := &in.Acorns, &out.Acorns - *out = make(map[string]internal_acorn_iov1.Acorn, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Routers != nil { - in, out := &in.Routers, &out.Routers - *out = make(map[string]internal_acorn_iov1.Router, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Services != nil { - in, out := &in.Services, &out.Services - *out = make(map[string]internal_acorn_iov1.Service, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Assistants != nil { - in, out := &in.Assistants, &out.Assistants - *out = make(map[string]internal_acorn_iov1.Assistant, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Acornfile. -func (in *Acornfile) DeepCopy() *Acornfile { - if in == nil { - return nil - } - out := new(Acornfile) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *App) DeepCopyInto(out *App) { *out = *in @@ -279,6 +180,55 @@ func (in *AppPullImage) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppStatus) DeepCopyInto(out *AppStatus) { + *out = *in + if in.DevSession != nil { + in, out := &in.DevSession, &out.DevSession + *out = new(internal_acorn_iov1.DevSessionInstanceSpec) + (*in).DeepCopyInto(*out) + } + out.Columns = in.Columns + in.Staged.DeepCopyInto(&out.Staged) + in.AppImage.DeepCopyInto(&out.AppImage) + in.AppSpec.DeepCopyInto(&out.AppSpec) + in.AppStatus.DeepCopyInto(&out.AppStatus) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]internal_acorn_iov1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Defaults.DeepCopyInto(&out.Defaults) + in.ResolvedOfferings.DeepCopyInto(&out.ResolvedOfferings) + in.Summary.DeepCopyInto(&out.Summary) + if in.Permissions != nil { + in, out := &in.Permissions, &out.Permissions + *out = make([]internal_acorn_iov1.Permissions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DeniedConsumerPermissions != nil { + in, out := &in.DeniedConsumerPermissions, &out.DeniedConsumerPermissions + *out = make([]internal_acorn_iov1.Permissions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppStatus. +func (in *AppStatus) DeepCopy() *AppStatus { + if in == nil { + return nil + } + out := new(AppStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Builder) DeepCopyInto(out *Builder) { *out = *in diff --git a/pkg/apis/internal.acorn.io/v1/appinstance.go b/pkg/apis/internal.acorn.io/v1/appinstance.go index d212b04bc..9a49d8157 100644 --- a/pkg/apis/internal.acorn.io/v1/appinstance.go +++ b/pkg/apis/internal.acorn.io/v1/appinstance.go @@ -191,31 +191,39 @@ type AppColumns struct { Created string `json:"created,omitempty" column:"name=Created,jsonpath=.metadata.creationTimestamp"` } -func (a AppInstanceStatus) GetDevMode() bool { - return a.DevSession != nil +type AppInstanceStatus struct { + EmbeddedAppStatus `json:",inline"` + Scheduling map[string]Scheduling `json:"scheduling,omitempty"` } -type AppInstanceStatus struct { - DevSession *DevSessionInstanceSpec `json:"devSession,omitempty"` - ObservedGeneration int64 `json:"observedGeneration,omitempty"` - ObservedImageDigest string `json:"observedImageDigest,omitempty"` - ObservedAutoUpgrade bool `json:"observedAutoUpgrade,omitempty"` - Columns AppColumns `json:"columns,omitempty"` - Ready bool `json:"ready,omitempty"` - Namespace string `json:"namespace,omitempty"` - Staged AppStatusStaged `json:"staged,omitempty"` - AppImage AppImage `json:"appImage,omitempty"` - AvailableAppImage string `json:"availableAppImage,omitempty"` - ConfirmUpgradeAppImage string `json:"confirmUpgradeAppImage,omitempty"` - AppSpec AppSpec `json:"appSpec,omitempty"` - AppStatus AppStatus `json:"appStatus,omitempty"` - Scheduling map[string]Scheduling `json:"scheduling,omitempty"` - Conditions []Condition `json:"conditions,omitempty"` - Defaults Defaults `json:"defaults,omitempty"` - ResolvedOfferings ResolvedOfferings `json:"resolvedOfferings,omitempty"` - Summary CommonSummary `json:"summary,omitempty"` - Permissions []Permissions `json:"permissions,omitempty"` // Permissions given to this appInstance (only containers within, not nested Acorns/Services) - DeniedConsumerPermissions []Permissions `json:"deniedConsumerPermissions,omitempty"` // Permissions given to this appInstance by a consumed service, which it is not authorized to have +type EmbeddedAppStatus struct { + DevSession *DevSessionInstanceSpec `json:"devSession,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + ObservedImageDigest string `json:"observedImageDigest,omitempty"` + ObservedAutoUpgrade bool `json:"observedAutoUpgrade,omitempty"` + Columns AppColumns `json:"columns,omitempty"` + Ready bool `json:"ready,omitempty"` + Namespace string `json:"namespace,omitempty"` + Staged AppStatusStaged `json:"staged,omitempty"` + AppImage AppImage `json:"appImage,omitempty"` + AvailableAppImage string `json:"availableAppImage,omitempty"` + ConfirmUpgradeAppImage string `json:"confirmUpgradeAppImage,omitempty"` + AppSpec AppSpec `json:"appSpec,omitempty"` + AppStatus AppStatus `json:"appStatus,omitempty"` + Conditions []Condition `json:"conditions,omitempty"` + Defaults Defaults `json:"defaults,omitempty"` + ResolvedOfferings ResolvedOfferings `json:"resolvedOfferings,omitempty"` + Summary CommonSummary `json:"summary,omitempty"` + + // Permissions granted to the app (only containers within, not nested Acorns/Services). + Permissions []Permissions `json:"permissions,omitempty"` + + // Permissions required by services the app, but have not been granted to the App. + DeniedConsumerPermissions []Permissions `json:"deniedConsumerPermissions,omitempty"` +} + +func (in EmbeddedAppStatus) GetDevMode() bool { + return in.DevSession != nil } type AppStatusStaged struct { diff --git a/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go b/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go index ae17dd8a3..e917be03d 100644 --- a/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go +++ b/pkg/apis/internal.acorn.io/v1/zz_generated.deepcopy.go @@ -561,16 +561,7 @@ func (in *AppInstanceSpec) DeepCopy() *AppInstanceSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppInstanceStatus) DeepCopyInto(out *AppInstanceStatus) { *out = *in - if in.DevSession != nil { - in, out := &in.DevSession, &out.DevSession - *out = new(DevSessionInstanceSpec) - (*in).DeepCopyInto(*out) - } - out.Columns = in.Columns - in.Staged.DeepCopyInto(&out.Staged) - in.AppImage.DeepCopyInto(&out.AppImage) - in.AppSpec.DeepCopyInto(&out.AppSpec) - in.AppStatus.DeepCopyInto(&out.AppStatus) + in.EmbeddedAppStatus.DeepCopyInto(&out.EmbeddedAppStatus) if in.Scheduling != nil { in, out := &in.Scheduling, &out.Scheduling *out = make(map[string]Scheduling, len(*in)) @@ -578,30 +569,6 @@ func (in *AppInstanceStatus) DeepCopyInto(out *AppInstanceStatus) { (*out)[key] = *val.DeepCopy() } } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - in.Defaults.DeepCopyInto(&out.Defaults) - in.ResolvedOfferings.DeepCopyInto(&out.ResolvedOfferings) - in.Summary.DeepCopyInto(&out.Summary) - if in.Permissions != nil { - in, out := &in.Permissions, &out.Permissions - *out = make([]Permissions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.DeniedConsumerPermissions != nil { - in, out := &in.DeniedConsumerPermissions, &out.DeniedConsumerPermissions - *out = make([]Permissions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppInstanceStatus. @@ -1744,6 +1711,55 @@ func (in *DevSessionInstanceStatus) DeepCopy() *DevSessionInstanceStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EmbeddedAppStatus) DeepCopyInto(out *EmbeddedAppStatus) { + *out = *in + if in.DevSession != nil { + in, out := &in.DevSession, &out.DevSession + *out = new(DevSessionInstanceSpec) + (*in).DeepCopyInto(*out) + } + out.Columns = in.Columns + in.Staged.DeepCopyInto(&out.Staged) + in.AppImage.DeepCopyInto(&out.AppImage) + in.AppSpec.DeepCopyInto(&out.AppSpec) + in.AppStatus.DeepCopyInto(&out.AppStatus) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Defaults.DeepCopyInto(&out.Defaults) + in.ResolvedOfferings.DeepCopyInto(&out.ResolvedOfferings) + in.Summary.DeepCopyInto(&out.Summary) + if in.Permissions != nil { + in, out := &in.Permissions, &out.Permissions + *out = make([]Permissions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DeniedConsumerPermissions != nil { + in, out := &in.DeniedConsumerPermissions, &out.DeniedConsumerPermissions + *out = make([]Permissions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmbeddedAppStatus. +func (in *EmbeddedAppStatus) DeepCopy() *EmbeddedAppStatus { + if in == nil { + return nil + } + out := new(EmbeddedAppStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Endpoint) DeepCopyInto(out *Endpoint) { *out = *in diff --git a/pkg/autoupgrade/daemon_test.go b/pkg/autoupgrade/daemon_test.go index 8773334f9..784d41671 100644 --- a/pkg/autoupgrade/daemon_test.go +++ b/pkg/autoupgrade/daemon_test.go @@ -207,7 +207,15 @@ func TestRefreshImages(t *testing.T) { app := v1.AppInstance{ ObjectMeta: metav1.ObjectMeta{Name: entry.Key, Namespace: "acorn"}, Spec: v1.AppInstanceSpec{Image: entry.Value}, - Status: v1.AppInstanceStatus{Staged: v1.AppStatusStaged{AppImage: v1.AppImage{Digest: fmt.Sprintf("sha256:acorn1234%sabcd", strings.Split(entry.Value, ":")[0])}}}, + Status: v1.AppInstanceStatus{ + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Staged: v1.AppStatusStaged{ + AppImage: v1.AppImage{ + Digest: fmt.Sprintf("sha256:acorn1234%sabcd", strings.Split(entry.Value, ":")[0]), + }, + }, + }, + }, } switch entry.Key { case "enabled-app", "no-tag-app": diff --git a/pkg/cli/completion_test.go b/pkg/cli/completion_test.go index 95e6fb985..e636ce75e 100644 --- a/pkg/cli/completion_test.go +++ b/pkg/cli/completion_test.go @@ -433,7 +433,7 @@ func TestAcornContainerCompletion(t *testing.T) { for _, entry := range typed.Sorted(names) { apps = append(apps, apiv1.App{ ObjectMeta: metav1.ObjectMeta{Name: entry.Key}, - Status: acornv1.AppInstanceStatus{ + Status: apiv1.AppStatus{ AppSpec: acornv1.AppSpec{Containers: entry.Value}, }, }) @@ -500,7 +500,7 @@ func TestOnlyAppsWithAcornContainer(t *testing.T) { appName := entry.Key apps = append(apps, apiv1.App{ ObjectMeta: metav1.ObjectMeta{Name: appName}, - Status: acornv1.AppInstanceStatus{ + Status: apiv1.AppStatus{ AppSpec: acornv1.AppSpec{Containers: entry.Value}, }, }) diff --git a/pkg/cli/containers_test.go b/pkg/cli/containers_test.go index 1847b3da2..de8fd29d8 100644 --- a/pkg/cli/containers_test.go +++ b/pkg/cli/containers_test.go @@ -54,7 +54,7 @@ var ( CreationTimestamp: metav1.NewTime(time.Now().AddDate(-10, 0, 0)), }, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{Ready: true}, + Status: apiv1.AppStatus{Ready: true}, } ) diff --git a/pkg/cli/run_test.go b/pkg/cli/run_test.go index f67fa9748..00c6e7498 100644 --- a/pkg/cli/run_test.go +++ b/pkg/cli/run_test.go @@ -49,17 +49,14 @@ func TestRun(t *testing.T) { return nil, fmt.Errorf("error: app %s does not exist", name) case "found": return &apiv1.App{ - TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{Ready: true}, + Status: apiv1.AppStatus{Ready: true}, }, nil case "found.container": return &apiv1.App{ - TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found.container"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, }, nil } return nil, nil @@ -71,17 +68,14 @@ func TestRun(t *testing.T) { return nil, fmt.Errorf("error: app %s does not exist", image) case "found": return &apiv1.App{ - TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{Ready: true}, + Status: apiv1.AppStatus{Ready: true}, }, nil case "found.container": return &apiv1.App{ - TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found.container"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, }, nil } return nil, fmt.Errorf("error: app %s does not exist", image) @@ -140,13 +134,7 @@ func TestRun(t *testing.T) { }, prepare: func(t *testing.T, f *mocks.MockClient) { t.Helper() - f.EXPECT().Info(gomock.Any()).Return( - []apiv1.Info{ - { - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - }, - }, nil) + f.EXPECT().Info(gomock.Any()).Return([]apiv1.Info{{}}, nil) }, wantErr: true, wantOut: "directory ./folder does not exist", @@ -162,13 +150,7 @@ func TestRun(t *testing.T) { }, prepare: func(t *testing.T, f *mocks.MockClient) { t.Helper() - f.EXPECT().Info(gomock.Any()).Return( - []apiv1.Info{ - { - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - }, - }, nil) + f.EXPECT().Info(gomock.Any()).Return([]apiv1.Info{{}}, nil) }, wantErr: true, wantOut: "open Acornfile: no such file or directory", @@ -184,13 +166,7 @@ func TestRun(t *testing.T) { }, prepare: func(t *testing.T, f *mocks.MockClient) { t.Helper() - f.EXPECT().Info(gomock.Any()).Return( - []apiv1.Info{ - { - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - }, - }, nil) + f.EXPECT().Info(gomock.Any()).Return([]apiv1.Info{{}}, nil) }, wantErr: true, wantOut: "open Acornfile: no such file or directory", @@ -226,13 +202,7 @@ func TestRun(t *testing.T) { t.Fatal() } - f.EXPECT().Info(gomock.Any()).Return( - []apiv1.Info{ - { - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - }, - }, nil) + f.EXPECT().Info(gomock.Any()).Return([]apiv1.Info{{}}, nil) }, wantErr: true, wantOut: "Acornfile_temp is not a directory", @@ -249,13 +219,7 @@ func TestRun(t *testing.T) { wantOut: "error: app dne does not exist", prepare: func(t *testing.T, f *mocks.MockClient) { t.Helper() - f.EXPECT().Info(gomock.Any()).Return( - []apiv1.Info{ - { - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{}, - }, - }, nil) + f.EXPECT().Info(gomock.Any()).Return([]apiv1.Info{{}}, nil) }, }, } diff --git a/pkg/cli/testdata/MockClient.go b/pkg/cli/testdata/MockClient.go index 6f82937b1..f8aacba10 100644 --- a/pkg/cli/testdata/MockClient.go +++ b/pkg/cli/testdata/MockClient.go @@ -184,7 +184,7 @@ func (m *MockClient) AppList(ctx context.Context) ([]apiv1.App, error) { TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, + Status: apiv1.AppStatus{}, }}, nil } @@ -219,14 +219,14 @@ func (m *MockClient) AppGet(ctx context.Context, name string) (*apiv1.App, error TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{Ready: true}, + Status: apiv1.AppStatus{Ready: true}, }, nil case "found.container": return &apiv1.App{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found.container"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, + Status: apiv1.AppStatus{}, }, nil } return nil, nil @@ -268,14 +268,14 @@ func (m *MockClient) AppRun(ctx context.Context, image string, opts *client.AppR TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{Ready: true}, + Status: apiv1.AppStatus{Ready: true}, }, nil case "found.container": return &apiv1.App{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found.container"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, + Status: apiv1.AppStatus{}, }, nil } return nil, fmt.Errorf("error: app %s does not exist", image) @@ -293,14 +293,14 @@ func (m *MockClient) AppUpdate(ctx context.Context, name string, opts *client.Ap TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, + Status: apiv1.AppStatus{}, }, nil case "found.container": return &apiv1.App{ TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{Name: "found.container"}, Spec: v1.AppInstanceSpec{Secrets: []v1.SecretBinding{{Secret: "found.secret", Target: "found"}}}, - Status: v1.AppInstanceStatus{}, + Status: apiv1.AppStatus{}, }, nil } return nil, fmt.Errorf("error: app %s does not exist", name) diff --git a/pkg/controller/appdefinition/acorn_test.go b/pkg/controller/appdefinition/acorn_test.go index 06b4bc4ad..1deddf3cd 100644 --- a/pkg/controller/appdefinition/acorn_test.go +++ b/pkg/controller/appdefinition/acorn_test.go @@ -45,17 +45,19 @@ func TestComputeMem(t *testing.T) { }, }, Status: v1.AppInstanceStatus{ - Namespace: "app-created-namespace", - AppImage: v1.AppImage{ - ID: "foo", - }, - AppSpec: v1.AppSpec{ - Acorns: map[string]v1.Acorn{ - "byname": { - Image: "foo", - }, - "other": { - Image: "foo", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-created-namespace", + AppImage: v1.AppImage{ + ID: "foo", + }, + AppSpec: v1.AppSpec{ + Acorns: map[string]v1.Acorn{ + "byname": { + Image: "foo", + }, + "other": { + Image: "foo", + }, }, }, }, diff --git a/pkg/controller/appdefinition/deploy_test.go b/pkg/controller/appdefinition/deploy_test.go index e7fa793cf..7fbef0159 100644 --- a/pkg/controller/appdefinition/deploy_test.go +++ b/pkg/controller/appdefinition/deploy_test.go @@ -99,11 +99,13 @@ func ToDeploymentsTest(t *testing.T, appInstance *v1.AppInstance, tag name.Refer func TestEntrypointCommand(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Entrypoint: []string{"hi", "bye"}, - Command: []string{"hi2", "bye2"}, + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Entrypoint: []string{"hi", "bye"}, + Command: []string{"hi2", "bye2"}, + }, }, }, }, @@ -116,26 +118,28 @@ func TestEntrypointCommand(t *testing.T) { func TestEnvironment(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Environment: []v1.EnvVar{ - { - Name: "hi", - Value: "bye", - }, - { - Name: "foo", - }, - { - Name: "foo\\.bar", - Value: "baz", - }, - { - Name: "foo\\.bar\\.baz", - Secret: v1.SecretReference{ - Name: "somesecret", - Key: "somesecretkey", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Environment: []v1.EnvVar{ + { + Name: "hi", + Value: "bye", + }, + { + Name: "foo", + }, + { + Name: "foo\\.bar", + Value: "baz", + }, + { + Name: "foo\\.bar\\.baz", + Secret: v1.SecretReference{ + Name: "somesecret", + Key: "somesecretkey", + }, }, }, }, @@ -174,10 +178,12 @@ func TestEnvironment(t *testing.T) { func TestWorkdir(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - WorkingDir: "something", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + WorkingDir: "something", + }, }, }, }, @@ -189,10 +195,12 @@ func TestWorkdir(t *testing.T) { func TestInteractive(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Interactive: true, + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Interactive: true, + }, }, }, }, @@ -205,19 +213,21 @@ func TestInteractive(t *testing.T) { func TestSidecar(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Sidecars: map[string]v1.Container{ - "left": { - Image: "sidecar", - Init: true, - }, - "right": { - Image: "sidecar2", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Sidecars: map[string]v1.Container{ + "left": { + Image: "sidecar", + Init: true, + }, + "right": { + Image: "sidecar2", + }, }, + WorkingDir: "something", }, - WorkingDir: "something", }, }, }, @@ -230,26 +240,28 @@ func TestSidecar(t *testing.T) { func TestPorts(t *testing.T) { dep := ToDeploymentsTest(t, &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Sidecars: map[string]v1.Container{ - "left": { - Ports: []v1.PortDef{ - { - Port: 90, - TargetPort: 91, - Protocol: v1.ProtocolHTTP, + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Sidecars: map[string]v1.Container{ + "left": { + Ports: []v1.PortDef{ + { + Port: 90, + TargetPort: 91, + Protocol: v1.ProtocolHTTP, + }, }, }, }, - }, - WorkingDir: "something", - Ports: []v1.PortDef{ - { - Port: 80, - TargetPort: 81, - Protocol: v1.ProtocolHTTP, + WorkingDir: "something", + Ports: []v1.PortDef{ + { + Port: 80, + TargetPort: 81, + Protocol: v1.ProtocolHTTP, + }, }, }, }, @@ -270,40 +282,42 @@ func TestFiles(t *testing.T) { UID: "123", }, Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test2": { - Files: map[string]v1.File{ - "/a2/b/c": { - Content: "ZA==", - }, - "/a1/b/c": { - Content: "ZQ==", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test2": { + Files: map[string]v1.File{ + "/a2/b/c": { + Content: "ZA==", + }, + "/a1/b/c": { + Content: "ZQ==", + }, }, - }, - Sidecars: map[string]v1.Container{ - "left": { - Files: map[string]v1.File{ - "/a/b2//c": {Content: "ZA=="}, - "/a/b1/c2/../c": {Content: "ZQ=="}, + Sidecars: map[string]v1.Container{ + "left": { + Files: map[string]v1.File{ + "/a/b2//c": {Content: "ZA=="}, + "/a/b1/c2/../c": {Content: "ZQ=="}, + }, }, }, }, - }, - "test": { - Files: map[string]v1.File{ - "/a2/b/c": { - Content: "ZA==", - }, - "/a1/b/c": { - Content: "ZQ==", + "test": { + Files: map[string]v1.File{ + "/a2/b/c": { + Content: "ZA==", + }, + "/a1/b/c": { + Content: "ZQ==", + }, }, - }, - Sidecars: map[string]v1.Container{ - "left": { - Files: map[string]v1.File{ - "/a/b2//c": {Content: "ZA=="}, - "/a/b1/c2/../c": {Content: "ZQ=="}, + Sidecars: map[string]v1.Container{ + "left": { + Files: map[string]v1.File{ + "/a/b2//c": {Content: "ZA=="}, + "/a/b1/c2/../c": {Content: "ZQ=="}, + }, }, }, }, @@ -349,20 +363,22 @@ func TestFiles(t *testing.T) { func TestUserContext(t *testing.T) { app := &v1.AppInstance{ Status: v1.AppInstanceStatus{ - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "foo": { - Image: "foo:latest", - UserContext: &v1.UserContext{ - UID: 1000, - GID: 2000, - }, - Sidecars: map[string]v1.Container{ - "bar": { - Image: "bar:latest", - UserContext: &v1.UserContext{ - UID: 3000, - GID: 4000, + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "foo": { + Image: "foo:latest", + UserContext: &v1.UserContext{ + UID: 1000, + GID: 2000, + }, + Sidecars: map[string]v1.Container{ + "bar": { + Image: "bar:latest", + UserContext: &v1.UserContext{ + UID: 3000, + GID: 4000, + }, }, }, }, diff --git a/pkg/controller/appdefinition/pullappimage_test.go b/pkg/controller/appdefinition/pullappimage_test.go index 21598d647..48d8b2e60 100644 --- a/pkg/controller/appdefinition/pullappimage_test.go +++ b/pkg/controller/appdefinition/pullappimage_test.go @@ -68,14 +68,16 @@ func app(specImage, statusImageID, statusAvailableImage, statusConfirmUpgradeIma NotifyUpgrade: ¬ifyUpgrade, }, Status: v1.AppInstanceStatus{ - Staged: v1.AppStatusStaged{ - AppImage: v1.AppImage{ - ID: statusImageID, - Name: statusImageID, + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Staged: v1.AppStatusStaged{ + AppImage: v1.AppImage{ + ID: statusImageID, + Name: statusImageID, + }, }, + AvailableAppImage: statusAvailableImage, + ConfirmUpgradeAppImage: statusConfirmUpgradeImage, }, - AvailableAppImage: statusAvailableImage, - ConfirmUpgradeAppImage: statusConfirmUpgradeImage, }, } } diff --git a/pkg/controller/appdefinition/secret_test.go b/pkg/controller/appdefinition/secret_test.go index f9e9642d8..1c476b1fb 100644 --- a/pkg/controller/appdefinition/secret_test.go +++ b/pkg/controller/appdefinition/secret_test.go @@ -17,34 +17,36 @@ func TestSecretDirsToMounts(t *testing.T) { Name: "app", }, Status: v1.AppInstanceStatus{ - AppImage: v1.AppImage{ - ID: "test", - }, - AppSpec: v1.AppSpec{ - Containers: map[string]v1.Container{ - "test": { - Dirs: map[string]v1.VolumeMount{ - "/dir": { - Secret: v1.VolumeSecretMount{ - Name: "dir-secret", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppImage: v1.AppImage{ + ID: "test", + }, + AppSpec: v1.AppSpec{ + Containers: map[string]v1.Container{ + "test": { + Dirs: map[string]v1.VolumeMount{ + "/dir": { + Secret: v1.VolumeSecretMount{ + Name: "dir-secret", + }, }, }, - }, - Sidecars: map[string]v1.Container{ - "left": { - Dirs: map[string]v1.VolumeMount{ - "/dir-side": { - Secret: v1.VolumeSecretMount{ - Name: "dir-side-secret", + Sidecars: map[string]v1.Container{ + "left": { + Dirs: map[string]v1.VolumeMount{ + "/dir-side": { + Secret: v1.VolumeSecretMount{ + Name: "dir-side-secret", + }, }, }, }, }, }, }, - }, - Secrets: map[string]v1.Secret{ - "dir-side-secret": {}, + Secrets: map[string]v1.Secret{ + "dir-side-secret": {}, + }, }, }, }, diff --git a/pkg/controller/appdefinition/volume_test.go b/pkg/controller/appdefinition/volume_test.go index 30c7b32f1..c99c62595 100644 --- a/pkg/controller/appdefinition/volume_test.go +++ b/pkg/controller/appdefinition/volume_test.go @@ -79,31 +79,33 @@ func TestVolumeLabelsAnnotations(t *testing.T) { Image: "image", }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "image", - }, - AppSpec: v1.AppSpec{ - Labels: map[string]string{ - "globalfromacornfile": "val", - }, - Annotations: map[string]string{ - "globalfromacornfilea": "val", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "image", }, - Volumes: map[string]v1.VolumeRequest{ - "volume1": { - Labels: map[string]string{ - "vol1fromacornfile": "val", + AppSpec: v1.AppSpec{ + Labels: map[string]string{ + "globalfromacornfile": "val", + }, + Annotations: map[string]string{ + "globalfromacornfilea": "val", + }, + Volumes: map[string]v1.VolumeRequest{ + "volume1": { + Labels: map[string]string{ + "vol1fromacornfile": "val", + }, + Annotations: map[string]string{ + "vol1fromacornfilea": "val", + }, + AccessModes: []v1.AccessMode{v1.AccessModeReadWriteOnce}, }, - Annotations: map[string]string{ - "vol1fromacornfilea": "val", + "volume2": { + Labels: nil, + Annotations: nil, + AccessModes: []v1.AccessMode{v1.AccessModeReadWriteOnce}, }, - AccessModes: []v1.AccessMode{v1.AccessModeReadWriteOnce}, - }, - "volume2": { - Labels: nil, - Annotations: nil, - AccessModes: []v1.AccessMode{v1.AccessModeReadWriteOnce}, }, }, }, diff --git a/pkg/controller/secrets/secret_test.go b/pkg/controller/secrets/secret_test.go index cddfb4737..008b43e0d 100644 --- a/pkg/controller/secrets/secret_test.go +++ b/pkg/controller/secrets/secret_test.go @@ -39,17 +39,19 @@ func TestOpaque_Gen(t *testing.T) { Namespace: "app-ns", }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "test", - }, - AppSpec: v1.AppSpec{ - Secrets: map[string]v1.Secret{ - "pass": { - Type: "opaque", - Data: map[string]string{ - "key1": "", - "key2": "value", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "test", + }, + AppSpec: v1.AppSpec{ + Secrets: map[string]v1.Secret{ + "pass": { + Type: "opaque", + Data: map[string]string{ + "key1": "", + "key2": "value", + }, }, }, }, @@ -81,25 +83,27 @@ func TestBasic_Gen(t *testing.T) { Namespace: "app-ns", }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "test", - }, - AppSpec: v1.AppSpec{ - Secrets: map[string]v1.Secret{ - "pass": { - Type: "basic", - Data: map[string]string{ - // cue will populate empty string if not sent - "username": "", - "password": "", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "test", + }, + AppSpec: v1.AppSpec{ + Secrets: map[string]v1.Secret{ + "pass": { + Type: "basic", + Data: map[string]string{ + // cue will populate empty string if not sent + "username": "", + "password": "", + }, }, - }, - "passuname": { - Type: "basic", - Data: map[string]string{ - "username": "admin", - "password": "", + "passuname": { + Type: "basic", + Data: map[string]string{ + "username": "admin", + "password": "", + }, }, }, }, @@ -139,16 +143,18 @@ func TestTemplateTokenMissing_Gen(t *testing.T) { Image: "image", }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "image", - }, - AppSpec: v1.AppSpec{ - Secrets: map[string]v1.Secret{ - "template": { - Type: "template", - Data: map[string]string{ - "template": "A happy little ${secret://pass/token} in a string", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "image", + }, + AppSpec: v1.AppSpec{ + Secrets: map[string]v1.Secret{ + "template": { + Type: "template", + Data: map[string]string{ + "template": "A happy little ${secret://pass/token} in a string", + }, }, }, }, @@ -180,28 +186,30 @@ func TestTemplateToken_Gen(t *testing.T) { Image: "image", }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "image", - }, - AppSpec: v1.AppSpec{ - Secrets: map[string]v1.Secret{ - "pass": {Type: "token", - Params: v1.NewGenericMap(map[string]any{ - "characters": "abc", - "length": int64(5), - }), - }, - "pass2": {Type: "token", - Params: v1.NewGenericMap(map[string]any{ - "characters": "xyz", - "length": int64(6), - }), - }, - "template": { - Type: "template", - Data: map[string]string{ - "template": "A happy little ${secret://pass/token} in a string followed by ${secret://pass2/token}", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "image", + }, + AppSpec: v1.AppSpec{ + Secrets: map[string]v1.Secret{ + "pass": {Type: "token", + Params: v1.NewGenericMap(map[string]any{ + "characters": "abc", + "length": int64(5), + }), + }, + "pass2": {Type: "token", + Params: v1.NewGenericMap(map[string]any{ + "characters": "xyz", + "length": int64(6), + }), + }, + "template": { + Type: "template", + Data: map[string]string{ + "template": "A happy little ${secret://pass/token} in a string followed by ${secret://pass2/token}", + }, }, }, }, @@ -286,38 +294,40 @@ func TestSecretLabelsAnnotations(t *testing.T) { }, }, Status: v1.AppInstanceStatus{ - Namespace: "app-target-ns", - AppImage: v1.AppImage{ - ID: "test", - }, - AppSpec: v1.AppSpec{ - Labels: map[string]string{ - "globalfromacornfile": "val", - }, - Annotations: map[string]string{ - "globalfromacornfilea": "val", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-target-ns", + AppImage: v1.AppImage{ + ID: "test", }, - Secrets: map[string]v1.Secret{ - "secret1": {Type: "basic", - Labels: map[string]string{ - "sec1fromacornfile": "val", - }, - Annotations: map[string]string{ - "sec1fromacornfilea": "val", - }, - Data: map[string]string{ - // cue will populate empty string if not sent - "username": "", - "password": "", - }, + AppSpec: v1.AppSpec{ + Labels: map[string]string{ + "globalfromacornfile": "val", }, - "secret2": { - Labels: nil, - Annotations: nil, - Type: "basic", - Data: map[string]string{ - "username": "", - "password": "", + Annotations: map[string]string{ + "globalfromacornfilea": "val", + }, + Secrets: map[string]v1.Secret{ + "secret1": {Type: "basic", + Labels: map[string]string{ + "sec1fromacornfile": "val", + }, + Annotations: map[string]string{ + "sec1fromacornfilea": "val", + }, + Data: map[string]string{ + // cue will populate empty string if not sent + "username": "", + "password": "", + }, + }, + "secret2": { + Labels: nil, + Annotations: nil, + Type: "basic", + Data: map[string]string{ + "username": "", + "password": "", + }, }, }, }, diff --git a/pkg/openapi/generated/openapi_generated.go b/pkg/openapi/generated/openapi_generated.go index d69d0750f..8894dd84b 100644 --- a/pkg/openapi/generated/openapi_generated.go +++ b/pkg/openapi/generated/openapi_generated.go @@ -36,11 +36,11 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/acorn-io/runtime/pkg/apis/admin.acorn.io/v1.QuotaRequestList": schema_pkg_apis_adminacornio_v1_QuotaRequestList(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AcornImageBuild": schema_pkg_apis_apiacornio_v1_AcornImageBuild(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AcornImageBuildList": schema_pkg_apis_apiacornio_v1_AcornImageBuildList(ref), - "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.Acornfile": schema_pkg_apis_apiacornio_v1_Acornfile(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.App": schema_pkg_apis_apiacornio_v1_App(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppInfo": schema_pkg_apis_apiacornio_v1_AppInfo(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppList": schema_pkg_apis_apiacornio_v1_AppList(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppPullImage": schema_pkg_apis_apiacornio_v1_AppPullImage(ref), + "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppStatus": schema_pkg_apis_apiacornio_v1_AppStatus(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.Builder": schema_pkg_apis_apiacornio_v1_Builder(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.BuilderList": schema_pkg_apis_apiacornio_v1_BuilderList(ref), "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.BuilderPortOptions": schema_pkg_apis_apiacornio_v1_BuilderPortOptions(ref), @@ -154,6 +154,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceList": schema_pkg_apis_internalacornio_v1_DevSessionInstanceList(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec": schema_pkg_apis_internalacornio_v1_DevSessionInstanceSpec(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceStatus": schema_pkg_apis_internalacornio_v1_DevSessionInstanceStatus(ref), + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.EmbeddedAppStatus": schema_pkg_apis_internalacornio_v1_EmbeddedAppStatus(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Endpoint": schema_pkg_apis_internalacornio_v1_Endpoint(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.EnvVar": schema_pkg_apis_internalacornio_v1_EnvVar(ref), "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.EventInstance": schema_pkg_apis_internalacornio_v1_EventInstance(ref), @@ -1647,216 +1648,147 @@ func schema_pkg_apis_apiacornio_v1_AcornImageBuildList(ref common.ReferenceCallb } } -func schema_pkg_apis_apiacornio_v1_Acornfile(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_apiacornio_v1_App(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ - "labels": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "annotations": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "description": { + "kind": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", }, }, - "readme": { + "apiVersion": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", }, }, - "info": { + "metadata": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, - "icon": { + "spec": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceSpec"), }, }, - "containers": { + "status": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Container"), - }, - }, - }, + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppStatus"), }, }, - "functions": { + }, + }, + }, + Dependencies: []string{ + "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.AppStatus", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_apiacornio_v1_AppInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Container"), - }, - }, - }, + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", }, }, - "jobs": { + "apiVersion": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Container"), - }, - }, - }, + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", }, }, - "images": { + "metadata": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Image"), - }, - }, - }, + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, - "volumes": { + "info": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeRequest"), - }, - }, - }, + Type: []string{"string"}, + Format: "", }, }, - "secrets": { + "interpolationError": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Secret"), - }, - }, - }, + Type: []string{"string"}, + Format: "", }, }, - "acorns": { + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_apiacornio_v1_AppList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Acorn"), - }, - }, - }, + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", }, }, - "routers": { + "apiVersion": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Router"), - }, - }, - }, + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", }, }, - "services": { + "metadata": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Service"), - }, - }, - }, + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, - "assistants": { + "items": { SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Assistant"), + Ref: ref("github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.App"), }, }, }, }, }, }, + Required: []string{"items"}, }, }, Dependencies: []string{ - "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Acorn", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Assistant", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Container", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Image", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Router", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Secret", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Service", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.VolumeRequest"}, + "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.App", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } -func schema_pkg_apis_apiacornio_v1_App(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_apiacornio_v1_AppPullImage(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -1882,151 +1814,158 @@ func schema_pkg_apis_apiacornio_v1_App(ref common.ReferenceCallback) common.Open Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceStatus"), - }, - }, }, }, }, Dependencies: []string{ - "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppInstanceStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } -func schema_pkg_apis_apiacornio_v1_AppInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_apiacornio_v1_AppStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ - "kind": { + "devSession": { SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec"), }, }, - "apiVersion": { + "observedGeneration": { SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", + Type: []string{"integer"}, + Format: "int64", }, }, - "metadata": { + "observedImageDigest": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "observedAutoUpgrade": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "columns": { SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns"), }, }, - "info": { + "ready": { SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, + Type: []string{"boolean"}, Format: "", }, }, - "interpolationError": { + "namespace": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, Format: "", }, }, - }, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_apiacornio_v1_AppList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { + "staged": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged"), + }, + }, + "appImage": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage"), + }, + }, + "availableAppImage": { SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, - "apiVersion": { + "confirmUpgradeAppImage": { SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, - "metadata": { + "appSpec": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec"), + }, + }, + "appStatus": { SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus"), }, }, - "items": { + "conditions": { SchemaProps: spec.SchemaProps{ Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.App"), + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition"), }, }, }, }, }, - }, - Required: []string{"items"}, - }, - }, - Dependencies: []string{ - "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1.App", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_apiacornio_v1_AppPullImage(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { + "defaults": { SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults"), }, }, - "apiVersion": { + "resolvedOfferings": { SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings"), }, }, - "metadata": { + "summary": { SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary"), + }, + }, + "permissions": { + SchemaProps: spec.SchemaProps{ + Description: "Permissions granted to the app (only containers within, not nested Acorns/Services).", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions"), + }, + }, + }, + }, + }, + "deniedConsumerPermissions": { + SchemaProps: spec.SchemaProps{ + Description: "Permissions required by services the app, but have not been granted to the App.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions"), + }, + }, + }, }, }, }, }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings"}, } } @@ -7202,20 +7141,6 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus"), }, }, - "scheduling": { - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Scheduling"), - }, - }, - }, - }, - }, "conditions": { SchemaProps: spec.SchemaProps{ Type: []string{"array"}, @@ -7249,7 +7174,8 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa }, "permissions": { SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, + Description: "Permissions granted to the app (only containers within, not nested Acorns/Services).", + Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -7261,7 +7187,7 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa }, "deniedConsumerPermissions": { SchemaProps: spec.SchemaProps{ - Description: "Permissions given to this appInstance (only containers within, not nested Acorns/Services)", + Description: "Permissions required by services the app, but have not been granted to the App.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -7272,6 +7198,20 @@ func schema_pkg_apis_internalacornio_v1_AppInstanceStatus(ref common.ReferenceCa }, }, }, + "scheduling": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Scheduling"), + }, + }, + }, + }, + }, }, }, }, @@ -9446,6 +9386,153 @@ func schema_pkg_apis_internalacornio_v1_DevSessionInstanceStatus(ref common.Refe } } +func schema_pkg_apis_internalacornio_v1_EmbeddedAppStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "devSession": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec"), + }, + }, + "observedGeneration": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + "observedImageDigest": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "observedAutoUpgrade": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "columns": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns"), + }, + }, + "ready": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "staged": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged"), + }, + }, + "appImage": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage"), + }, + }, + "availableAppImage": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "confirmUpgradeAppImage": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "appSpec": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec"), + }, + }, + "appStatus": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus"), + }, + }, + "conditions": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition"), + }, + }, + }, + }, + }, + "defaults": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults"), + }, + }, + "resolvedOfferings": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings"), + }, + }, + "summary": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary"), + }, + }, + "permissions": { + SchemaProps: spec.SchemaProps{ + Description: "Permissions granted to the app (only containers within, not nested Acorns/Services).", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions"), + }, + }, + }, + }, + }, + "deniedConsumerPermissions": { + SchemaProps: spec.SchemaProps{ + Description: "Permissions required by services the app, but have not been granted to the App.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppColumns", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppImage", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatus", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.AppStatusStaged", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.CommonSummary", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Condition", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Defaults", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.DevSessionInstanceSpec", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.Permissions", "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1.ResolvedOfferings"}, + } +} + func schema_pkg_apis_internalacornio_v1_Endpoint(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/ref/expr_test.go b/pkg/ref/expr_test.go index ff8a1dd9f..a117a83c3 100644 --- a/pkg/ref/expr_test.go +++ b/pkg/ref/expr_test.go @@ -58,7 +58,9 @@ func TestResolve(t *testing.T) { Namespace: "project-name", }, Status: v1.AppInstanceStatus{ - Namespace: "app-namespace", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "app-namespace", + }, }, }, &v1.AppInstance{ @@ -71,7 +73,9 @@ func TestResolve(t *testing.T) { }, }, Status: v1.AppInstanceStatus{ - Namespace: "child-app-random-ns", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "child-app-random-ns", + }, }, }, &v1.ServiceInstance{ @@ -115,7 +119,9 @@ func TestResolve(t *testing.T) { }, }, Status: v1.AppInstanceStatus{ - Namespace: "grandchild-app-random-ns", + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + Namespace: "grandchild-app-random-ns", + }, }, }, &corev1.Secret{ diff --git a/pkg/server/registry/apigroups/acorn/apps/storage.go b/pkg/server/registry/apigroups/acorn/apps/storage.go index cc4692344..71b7940df 100644 --- a/pkg/server/registry/apigroups/acorn/apps/storage.go +++ b/pkg/server/registry/apigroups/acorn/apps/storage.go @@ -4,10 +4,8 @@ import ( "net/http" "github.com/acorn-io/mink/pkg/stores" - "github.com/acorn-io/mink/pkg/strategy/remote" "github.com/acorn-io/mink/pkg/strategy/translation" apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1" - v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" "github.com/acorn-io/runtime/pkg/client" "github.com/acorn-io/runtime/pkg/event" "github.com/acorn-io/runtime/pkg/publicname" @@ -18,12 +16,12 @@ import ( ) func NewStorage(c kclient.WithWatch, clientFactory *client.Factory, recorder event.Recorder, transport http.RoundTripper, middlewares ...middleware.CompleteStrategy) rest.Storage { - remoteResource := remote.NewRemote(&v1.AppInstance{}, c) - strategy := translation.NewSimpleTranslationStrategy(&Translator{}, remoteResource) - strategy = publicname.NewStrategy(strategy) + strategy := newAppInstanceStrategy(c) + strategy = publicname.NewStrategy( + translation.NewSimpleTranslationStrategy(&translator{}, strategy), + ) strategy = newEventRecordingStrategy(strategy, recorder) strategy = middleware.ForCompleteStrategy(strategy, middlewares...) - validator := NewValidator(c, clientFactory, strategy, transport) return stores.NewBuilder(c.Scheme(), &apiv1.App{}). diff --git a/pkg/server/registry/apigroups/acorn/apps/strategy.go b/pkg/server/registry/apigroups/acorn/apps/strategy.go new file mode 100644 index 000000000..73dff3a44 --- /dev/null +++ b/pkg/server/registry/apigroups/acorn/apps/strategy.go @@ -0,0 +1,40 @@ +package apps + +import ( + "context" + + "github.com/acorn-io/mink/pkg/strategy" + "github.com/acorn-io/mink/pkg/strategy/remote" + mtypes "github.com/acorn-io/mink/pkg/types" + v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" + kclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +func newAppInstanceStrategy(c kclient.WithWatch) strategy.CompleteStrategy { + return &appInstanceStrategy{ + CompleteStrategy: remote.NewRemote(&v1.AppInstance{}, c), + c: c, + } +} + +type appInstanceStrategy struct { + strategy.CompleteStrategy + c kclient.WithWatch +} + +func (s *appInstanceStrategy) Update(ctx context.Context, obj mtypes.Object) (mtypes.Object, error) { + // Get the existing object + var existing v1.AppInstance + if err := s.c.Get(ctx, kclient.ObjectKeyFromObject(obj), &existing); err != nil { + return nil, err + } + + // Ensure that AppInstanceStatus fields not surfaced by AppStatus are preserved. + // Note: This is necessary because obj has been translated from an apiv1.App before being passed to this method, + // and since the AppStatus is a subset of the AppInstanceStatus, the App + if existing.Status.Scheduling != nil { + obj.(*v1.AppInstance).Status.Scheduling = existing.Status.Scheduling + } + + return s.CompleteStrategy.Update(ctx, obj) +} diff --git a/pkg/server/registry/apigroups/acorn/apps/translator.go b/pkg/server/registry/apigroups/acorn/apps/translator.go index 3a1a27627..8b4c4f67f 100644 --- a/pkg/server/registry/apigroups/acorn/apps/translator.go +++ b/pkg/server/registry/apigroups/acorn/apps/translator.go @@ -6,23 +6,12 @@ import ( v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" ) -type Translator struct { -} +type translator struct{} -func (s *Translator) FromPublic(obj mtypes.Object) mtypes.Object { - app := obj.(*apiv1.App) - return &v1.AppInstance{ - ObjectMeta: app.ObjectMeta, - Spec: app.Spec, - Status: app.Status, - } +func (*translator) FromPublic(obj mtypes.Object) mtypes.Object { + return apiv1.AppToAppInstance(obj.(*apiv1.App)) } -func (s *Translator) ToPublic(obj mtypes.Object) mtypes.Object { - app := obj.(*v1.AppInstance) - return &apiv1.App{ - ObjectMeta: app.ObjectMeta, - Spec: app.Spec, - Status: app.Status, - } +func (*translator) ToPublic(obj mtypes.Object) mtypes.Object { + return apiv1.AppInstanceToApp(obj.(*v1.AppInstance)) } diff --git a/pkg/server/registry/apigroups/acorn/apps/validator_test.go b/pkg/server/registry/apigroups/acorn/apps/validator_test.go index 48ea39d6c..895a73a56 100644 --- a/pkg/server/registry/apigroups/acorn/apps/validator_test.go +++ b/pkg/server/registry/apigroups/acorn/apps/validator_test.go @@ -93,7 +93,7 @@ func TestCannotChangeAppRegion(t *testing.T) { { name: "Cannot change region from calculated default", oldApp: apiv1.App{ - Status: internalv1.AppInstanceStatus{ + Status: apiv1.AppStatus{ Defaults: internalv1.Defaults{ Region: "old-acorn-test-region", }, diff --git a/pkg/server/registry/apigroups/acorn/containers/translator_test.go b/pkg/server/registry/apigroups/acorn/containers/translator_test.go index 4f9b2e22a..81dbb7ac6 100644 --- a/pkg/server/registry/apigroups/acorn/containers/translator_test.go +++ b/pkg/server/registry/apigroups/acorn/containers/translator_test.go @@ -7,7 +7,6 @@ import ( "github.com/acorn-io/baaah/pkg/router/tester" apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1" - v1 "github.com/acorn-io/runtime/pkg/apis/internal.acorn.io/v1" "github.com/acorn-io/runtime/pkg/scheme" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -19,7 +18,7 @@ func TestFromPublicName(t *testing.T) { Name: "app", Namespace: "appNs", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ Namespace: "podNs", }, } diff --git a/pkg/server/registry/apigroups/acorn/projects/validator_test.go b/pkg/server/registry/apigroups/acorn/projects/validator_test.go index f22052bd3..ebacd7b8c 100644 --- a/pkg/server/registry/apigroups/acorn/projects/validator_test.go +++ b/pkg/server/registry/apigroups/acorn/projects/validator_test.go @@ -236,7 +236,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-region", }, @@ -277,7 +277,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-region", }, @@ -323,7 +323,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, @@ -411,7 +411,7 @@ func TestProjectUpdateValidation(t *testing.T) { Name: "my-app", Namespace: "my-project", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, @@ -461,7 +461,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, @@ -508,7 +508,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, @@ -522,7 +522,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-region", }, @@ -569,7 +569,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, @@ -614,7 +614,7 @@ func TestProjectUpdateValidation(t *testing.T) { Spec: v1.AppInstanceSpec{ Region: "my-other-region", }, - Status: v1.AppInstanceStatus{ + Status: apiv1.AppStatus{ ResolvedOfferings: v1.ResolvedOfferings{ Region: "my-other-region", }, diff --git a/pkg/services/acorn_test.go b/pkg/services/acorn_test.go index ec2a3862d..715e0d687 100644 --- a/pkg/services/acorn_test.go +++ b/pkg/services/acorn_test.go @@ -89,18 +89,22 @@ func Test_filterForPermissionsAndAssignStatus(t *testing.T) { }}, }}, }, - Status: v1.AppInstanceStatus{AppStatus: v1.AppStatus{ - Services: map[string]v1.ServiceStatus{ - "reject": { - MissingConsumerPermissions: []v1.Permissions{{ - ServiceName: "reject", - Rules: []v1.PolicyRule{{PolicyRule: rbacv1.PolicyRule{ - Verbs: []string{"*"}, - APIGroups: []string{"*"}, - Resources: []string{"*"}, - }}}, - }}}}, - }}}).Equal(t, app) + Status: v1.AppInstanceStatus{ + EmbeddedAppStatus: v1.EmbeddedAppStatus{ + AppStatus: v1.AppStatus{ + Services: map[string]v1.ServiceStatus{ + "reject": { + MissingConsumerPermissions: []v1.Permissions{{ + ServiceName: "reject", + Rules: []v1.PolicyRule{{PolicyRule: rbacv1.PolicyRule{ + Verbs: []string{"*"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + }}}, + }}}}, + }, + }, + }}).Equal(t, app) autogold.Expect([]kclient.Object{ serviceAllow,