Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1279 from thedadams/gh-1261
Browse files Browse the repository at this point in the history
Ensure acorn volumes command outputs volume class (#1261)
  • Loading branch information
thedadams authored Feb 28, 2023
2 parents b7c2661 + 9e4a5fb commit f4c514d
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 12 deletions.
27 changes: 18 additions & 9 deletions integration/run/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ func TestVolumeBadClassInImageBoundToGoodClass(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

helper.WaitForObject(t, helper.Watcher(t, c), &apiv1.AppList{}, app, func(obj *apiv1.App) bool {
Expand Down Expand Up @@ -374,7 +375,8 @@ func TestVolumeClassRemoved(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

helper.WaitForObject(t, helper.Watcher(t, c), &apiv1.AppList{}, app, func(obj *apiv1.App) bool {
Expand Down Expand Up @@ -444,7 +446,8 @@ func TestClusterVolumeClass(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

assert.Equal(t, []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, pv.Spec.AccessModes)
Expand Down Expand Up @@ -505,7 +508,8 @@ func TestClusterVolumeClassValuesInAcornfile(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

assert.Equal(t, []corev1.PersistentVolumeAccessMode{"ReadWriteMany"}, pvc.Spec.AccessModes)
Expand Down Expand Up @@ -562,7 +566,8 @@ func TestProjectVolumeClass(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

assert.Equal(t, []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, pv.Spec.AccessModes)
Expand All @@ -588,9 +593,11 @@ func TestProjectVolumeClassDefaultSizeValidation(t *testing.T) {
return
}

storageClassName := getStorageClassName(t, storageClasses)

volumeClass := adminapiv1.ProjectVolumeClass{
ObjectMeta: metav1.ObjectMeta{Namespace: c.GetNamespace(), Name: "acorn-test-custom"},
StorageClassName: getStorageClassName(t, storageClasses),
StorageClassName: storageClassName,
AllowedAccessModes: []v1.AccessMode{v1.AccessModeReadWriteOnce},
Size: adminv1.VolumeClassSize{
Default: v1.Quantity("5G"),
Expand Down Expand Up @@ -624,10 +631,11 @@ func TestProjectVolumeClassDefaultSizeValidation(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

assert.Equal(t, storageClasses.Items[0].Name, pv.Spec.StorageClassName)
assert.Equal(t, storageClassName, pv.Spec.StorageClassName)
assert.Equal(t, []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, pv.Spec.AccessModes)
assert.Equal(t, "6G", pv.Spec.Capacity.Storage().String())

Expand Down Expand Up @@ -733,7 +741,8 @@ func TestProjectVolumeClassValuesInAcornfile(t *testing.T) {
return obj.Labels[labels.AcornAppName] == app.Name &&
obj.Labels[labels.AcornAppNamespace] == app.Namespace &&
obj.Labels[labels.AcornManaged] == "true" &&
obj.Labels[labels.AcornVolumeName] == "my-data"
obj.Labels[labels.AcornVolumeName] == "my-data" &&
obj.Labels[labels.AcornVolumeClass] == volumeClass.Name
})

assert.Equal(t, []corev1.PersistentVolumeAccessMode{"ReadWriteMany"}, pvc.Spec.AccessModes)
Expand Down
31 changes: 31 additions & 0 deletions pkg/cli/volumes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import (
"os"
"strings"
"testing"
"time"

apiv1 "github.com/acorn-io/acorn/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/acorn/pkg/cli/testdata"
"github.com/acorn-io/acorn/pkg/labels"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestVolume(t *testing.T) {
tenYearsAgo := time.Now().AddDate(-10, 0, 0)
type fields struct {
Quiet bool
Output string
Expand Down Expand Up @@ -164,6 +169,32 @@ func TestVolume(t *testing.T) {
wantErr: true,
wantOut: "Error: No such volume: dne\n",
},
{
name: "acorn volume", fields: fields{},
commandContext: CommandContext{
ClientFactory: &testdata.MockClientFactory{
VolumeList: []apiv1.Volume{
{
ObjectMeta: metav1.ObjectMeta{
CreationTimestamp: metav1.NewTime(tenYearsAgo),
Name: "my-volume",
Labels: map[string]string{
labels.AcornVolumeClass: "my-class",
},
},
},
},
},
StdOut: w,
StdErr: w,
StdIn: strings.NewReader(""),
},
args: args{
args: []string{},
client: &testdata.MockClient{},
},
wantOut: "NAME APP-NAME BOUND-VOLUME CAPACITY VOLUME-CLASS STATUS ACCESS-MODES CREATED\nmy-volume <nil> my-class 10y ago\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "foo"
acorn.io/volume-class: "test-custom-class"
spec:
resources:
requests:
Expand All @@ -97,6 +98,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "bar"
acorn.io/volume-class: "test-custom-class"
spec:
resources:
requests:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "foo"
acorn.io/volume-class: cli-class
spec:
accessModes:
- ReadWriteOnce
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "foo"
acorn.io/volume-class: "test-custom-class"
spec:
resources:
requests:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "foo"
acorn.io/volume-class: "test-custom-class"
spec:
resources:
requests:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ metadata:
"acorn.io/app-name": "app-name"
"acorn.io/managed": "true"
"acorn.io/volume-name": "foo"
acorn.io/volume-class: "custom-class"
spec:
accessModes:
- ReadWriteOnce
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/appdefinition/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func toPVCs(req router.Request, appInstance *v1.AppInstance) (result []kclient.O
return nil, fmt.Errorf("%s has an invalid volume class %s", vol, volumeBinding.Class)
} else {
pvc.Spec.StorageClassName = &volClass.StorageClassName
pvc.Labels[labels.AcornVolumeClass] = volClass.Name
}
}

Expand All @@ -148,6 +149,7 @@ func toPVCs(req router.Request, appInstance *v1.AppInstance) (result []kclient.O
return nil, fmt.Errorf("%s has an invalid volume class %s", vol, volumeRequest.Class)
} else {
pvc.Spec.StorageClassName = &volClass.StorageClassName
pvc.Labels[labels.AcornVolumeClass] = volClass.Name
}
}
pvName, err := lookupExistingPV(req, appInstance, vol)
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/pvc/markandsave.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ func MarkAndSave(req router.Request, resp router.Response) error {
if pv.Labels[labels.AcornAppName] != pvc.Labels[labels.AcornAppName] ||
pv.Labels[labels.AcornAppNamespace] != pvc.Labels[labels.AcornAppNamespace] ||
pv.Labels[labels.AcornVolumeName] != pvc.Name ||
pv.Labels[labels.AcornVolumeClass] != pvc.Labels[labels.AcornVolumeClass] ||
pv.Labels[labels.AcornManaged] != "true" ||
pv.Spec.PersistentVolumeReclaimPolicy != corev1.PersistentVolumeReclaimRetain {
if pv.Labels == nil {
pv.Labels = map[string]string{}
}

pv.Labels[labels.AcornVolumeName] = pvc.Name
pv.Labels[labels.AcornVolumeClass] = pvc.Labels[labels.AcornVolumeClass]
pv.Labels[labels.AcornAppName] = pvc.Labels[labels.AcornAppName]
pv.Labels[labels.AcornAppNamespace] = pvc.Labels[labels.AcornAppNamespace]
pv.Labels[labels.AcornManaged] = "true"
Expand Down
1 change: 1 addition & 0 deletions pkg/labels/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
AcornDepNames = Prefix + "dep-names"
AcornAppUID = Prefix + "app-uid"
AcornVolumeName = Prefix + "volume-name"
AcornVolumeClass = Prefix + "volume-class"
AcornSecretName = Prefix + "secret-name"
AcornSecretGenerated = Prefix + "secret-generated"
AcornContainerName = Prefix + "container-name"
Expand Down
11 changes: 9 additions & 2 deletions pkg/server/registry/apigroups/acorn/volumes/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (t *Translator) ListOpts(ctx context.Context, namespace string, opts storag
return "", opts, nil
}

func pvToVolume(pv corev1.PersistentVolume) *apiv1.Volume {
func (t *Translator) pvToVolume(ctx context.Context, pv corev1.PersistentVolume) *apiv1.Volume {
var (
accessModes []v1.AccessMode
shortAccessModes []string
Expand Down Expand Up @@ -84,13 +84,20 @@ func pvToVolume(pv corev1.PersistentVolume) *apiv1.Volume {
vol.Status.Status += "/deleted"
}

if _, ok := pv.Labels[labels.AcornVolumeClass]; !ok && pv.Spec.ClaimRef != nil && pv.Spec.ClaimRef.Name != "" {
pvc := new(corev1.PersistentVolumeClaim)
if err := t.c.Get(ctx, ktypes.NamespacedName{Namespace: pv.Spec.ClaimRef.Namespace, Name: pv.Spec.ClaimRef.Name}, pvc); err == nil {
pv.Labels[labels.AcornVolumeClass] = pvc.Labels[labels.AcornVolumeClass]
}
}

return vol
}

func (t *Translator) ToPublic(ctx context.Context, objs ...runtime.Object) (result []types.Object, _ error) {
for _, obj := range objs {
pv := obj.(*corev1.PersistentVolume)
result = append(result, pvToVolume(*pv))
result = append(result, t.pvToVolume(ctx, *pv))
}
return
}
Expand Down
8 changes: 7 additions & 1 deletion pkg/tables/tables.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package tables

import (
"fmt"

"github.com/acorn-io/acorn/pkg/labels"
)

var (
CheckResult = [][]string{
{"Name", "Name"},
Expand All @@ -23,7 +29,7 @@ var (
{"App-Name", "Status.AppName"},
{"Bound-Volume", "Status.VolumeName"},
{"Capacity", "Spec.Capacity"},
{"Volume-Class", "Spec.Class"},
{"Volume-Class", fmt.Sprintf("{{ index .Labels %q }}", labels.AcornVolumeClass)},
{"Status", "Status.Status"},
{"Access-Modes", "Status.Columns.AccessModes"},
{"Created", "{{ago .CreationTimestamp}}"},
Expand Down

0 comments on commit f4c514d

Please sign in to comment.