fix unit test for new subPathExpr feature (#2638)
* fix unit test for new subPathExpr feature * add subPathExpr flag to CRD and re-sort
This commit is contained in:
parent
7bcb73a402
commit
b550f8ae39
|
|
@ -87,10 +87,14 @@ spec:
|
||||||
- mountPath
|
- mountPath
|
||||||
- volumeSource
|
- volumeSource
|
||||||
properties:
|
properties:
|
||||||
|
isSubPathExpr:
|
||||||
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
mountPath:
|
mountPath:
|
||||||
type: string
|
type: string
|
||||||
|
subPath:
|
||||||
|
type: string
|
||||||
targetContainers:
|
targetContainers:
|
||||||
type: array
|
type: array
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
@ -99,10 +103,6 @@ spec:
|
||||||
volumeSource:
|
volumeSource:
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
subPath:
|
|
||||||
type: string
|
|
||||||
isSubPathExpr:
|
|
||||||
type: boolean
|
|
||||||
allowedSourceRanges:
|
allowedSourceRanges:
|
||||||
type: array
|
type: array
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
@ -636,6 +636,8 @@ spec:
|
||||||
required:
|
required:
|
||||||
- size
|
- size
|
||||||
properties:
|
properties:
|
||||||
|
isSubPathExpr:
|
||||||
|
type: boolean
|
||||||
iops:
|
iops:
|
||||||
type: integer
|
type: integer
|
||||||
selector:
|
selector:
|
||||||
|
|
|
||||||
|
|
@ -485,6 +485,9 @@ properties of the persistent storage that stores Postgres data.
|
||||||
* **subPath**
|
* **subPath**
|
||||||
Subpath to use when mounting volume into Spilo container. Optional.
|
Subpath to use when mounting volume into Spilo container. Optional.
|
||||||
|
|
||||||
|
* **isSubPathExpr**
|
||||||
|
Set it to true if the specified subPath is an expression. Optional.
|
||||||
|
|
||||||
* **iops**
|
* **iops**
|
||||||
When running the operator on AWS the latest generation of EBS volumes (`gp3`)
|
When running the operator on AWS the latest generation of EBS volumes (`gp3`)
|
||||||
allows for configuring the number of IOPS. Maximum is 16000. Optional.
|
allows for configuring the number of IOPS. Maximum is 16000. Optional.
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ spec:
|
||||||
# matchLabels:
|
# matchLabels:
|
||||||
# environment: dev
|
# environment: dev
|
||||||
# service: postgres
|
# service: postgres
|
||||||
|
# subPath: $(NODE_NAME)/$(POD_NAME)
|
||||||
|
# isSubPathExpr: true
|
||||||
additionalVolumes:
|
additionalVolumes:
|
||||||
- name: empty
|
- name: empty
|
||||||
mountPath: /opt/empty
|
mountPath: /opt/empty
|
||||||
|
|
|
||||||
|
|
@ -85,10 +85,14 @@ spec:
|
||||||
- mountPath
|
- mountPath
|
||||||
- volumeSource
|
- volumeSource
|
||||||
properties:
|
properties:
|
||||||
|
isSubPathExpr:
|
||||||
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
mountPath:
|
mountPath:
|
||||||
type: string
|
type: string
|
||||||
|
subPath:
|
||||||
|
type: string
|
||||||
targetContainers:
|
targetContainers:
|
||||||
type: array
|
type: array
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
@ -97,10 +101,6 @@ spec:
|
||||||
volumeSource:
|
volumeSource:
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
subPath:
|
|
||||||
type: string
|
|
||||||
isSubPathExpr:
|
|
||||||
type: boolean
|
|
||||||
allowedSourceRanges:
|
allowedSourceRanges:
|
||||||
type: array
|
type: array
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
@ -634,6 +634,8 @@ spec:
|
||||||
required:
|
required:
|
||||||
- size
|
- size
|
||||||
properties:
|
properties:
|
||||||
|
isSubPathExpr:
|
||||||
|
type: boolean
|
||||||
iops:
|
iops:
|
||||||
type: integer
|
type: integer
|
||||||
selector:
|
selector:
|
||||||
|
|
|
||||||
|
|
@ -146,12 +146,18 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||||
Type: "object",
|
Type: "object",
|
||||||
Required: []string{"name", "mountPath", "volumeSource"},
|
Required: []string{"name", "mountPath", "volumeSource"},
|
||||||
Properties: map[string]apiextv1.JSONSchemaProps{
|
Properties: map[string]apiextv1.JSONSchemaProps{
|
||||||
|
"isSubPathExpr": {
|
||||||
|
Type: "boolean",
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
"mountPath": {
|
"mountPath": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
|
"subPath": {
|
||||||
|
Type: "string",
|
||||||
|
},
|
||||||
"targetContainers": {
|
"targetContainers": {
|
||||||
Type: "array",
|
Type: "array",
|
||||||
Nullable: true,
|
Nullable: true,
|
||||||
|
|
@ -165,12 +171,6 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||||
Type: "object",
|
Type: "object",
|
||||||
XPreserveUnknownFields: util.True(),
|
XPreserveUnknownFields: util.True(),
|
||||||
},
|
},
|
||||||
"subPath": {
|
|
||||||
Type: "string",
|
|
||||||
},
|
|
||||||
"isSubPathExpr": {
|
|
||||||
Type: "boolean",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1033,6 +1033,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||||
Type: "object",
|
Type: "object",
|
||||||
Required: []string{"size"},
|
Required: []string{"size"},
|
||||||
Properties: map[string]apiextv1.JSONSchemaProps{
|
Properties: map[string]apiextv1.JSONSchemaProps{
|
||||||
|
"isSubPathExpr": {
|
||||||
|
Type: "boolean",
|
||||||
|
},
|
||||||
"iops": {
|
"iops": {
|
||||||
Type: "integer",
|
Type: "integer",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -129,13 +129,14 @@ type MaintenanceWindow struct {
|
||||||
|
|
||||||
// Volume describes a single volume in the manifest.
|
// Volume describes a single volume in the manifest.
|
||||||
type Volume struct {
|
type Volume struct {
|
||||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||||
Size string `json:"size"`
|
Size string `json:"size"`
|
||||||
StorageClass string `json:"storageClass,omitempty"`
|
StorageClass string `json:"storageClass,omitempty"`
|
||||||
SubPath string `json:"subPath,omitempty"`
|
SubPath string `json:"subPath,omitempty"`
|
||||||
Iops *int64 `json:"iops,omitempty"`
|
IsSubPathExpr *bool `json:"isSubPathExpr,omitemtpy"`
|
||||||
Throughput *int64 `json:"throughput,omitempty"`
|
Iops *int64 `json:"iops,omitempty"`
|
||||||
VolumeType string `json:"type,omitempty"`
|
Throughput *int64 `json:"throughput,omitempty"`
|
||||||
|
VolumeType string `json:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdditionalVolume specs additional optional volumes for statefulset
|
// AdditionalVolume specs additional optional volumes for statefulset
|
||||||
|
|
@ -143,7 +144,7 @@ type AdditionalVolume struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
MountPath string `json:"mountPath"`
|
MountPath string `json:"mountPath"`
|
||||||
SubPath string `json:"subPath,omitempty"`
|
SubPath string `json:"subPath,omitempty"`
|
||||||
IsSubPathExpr bool `json:"isSubPathExpr,omitemtpy"`
|
IsSubPathExpr *bool `json:"isSubPathExpr,omitemtpy"`
|
||||||
TargetContainers []string `json:"targetContainers"`
|
TargetContainers []string `json:"targetContainers"`
|
||||||
VolumeSource v1.VolumeSource `json:"volumeSource"`
|
VolumeSource v1.VolumeSource `json:"volumeSource"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ func (in *AWSGCPConfiguration) DeepCopy() *AWSGCPConfiguration {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *AdditionalVolume) DeepCopyInto(out *AdditionalVolume) {
|
func (in *AdditionalVolume) DeepCopyInto(out *AdditionalVolume) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.IsSubPathExpr != nil {
|
||||||
|
in, out := &in.IsSubPathExpr, &out.IsSubPathExpr
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.TargetContainers != nil {
|
if in.TargetContainers != nil {
|
||||||
in, out := &in.TargetContainers, &out.TargetContainers
|
in, out := &in.TargetContainers, &out.TargetContainers
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
|
|
@ -1447,6 +1452,11 @@ func (in *Volume) DeepCopyInto(out *Volume) {
|
||||||
*out = new(metav1.LabelSelector)
|
*out = new(metav1.LabelSelector)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IsSubPathExpr != nil {
|
||||||
|
in, out := &in.IsSubPathExpr, &out.IsSubPathExpr
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.Iops != nil {
|
if in.Iops != nil {
|
||||||
in, out := &in.Iops, &out.Iops
|
in, out := &in.Iops, &out.Iops
|
||||||
*out = new(int64)
|
*out = new(int64)
|
||||||
|
|
|
||||||
|
|
@ -668,13 +668,19 @@ func isBootstrapOnlyParameter(param string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateVolumeMounts(volume acidv1.Volume) []v1.VolumeMount {
|
func generateVolumeMounts(volume acidv1.Volume) []v1.VolumeMount {
|
||||||
return []v1.VolumeMount{
|
volumeMount := []v1.VolumeMount{
|
||||||
{
|
{
|
||||||
Name: constants.DataVolumeName,
|
Name: constants.DataVolumeName,
|
||||||
MountPath: constants.PostgresDataMount, //TODO: fetch from manifest
|
MountPath: constants.PostgresDataMount, //TODO: fetch from manifest
|
||||||
SubPath: volume.SubPath,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if volume.IsSubPathExpr != nil && *volume.IsSubPathExpr {
|
||||||
|
volumeMount[0].SubPathExpr = volume.SubPath
|
||||||
|
} else {
|
||||||
|
volumeMount[0].SubPath = volume.SubPath
|
||||||
|
}
|
||||||
|
return volumeMount
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateContainer(
|
func generateContainer(
|
||||||
|
|
@ -1825,7 +1831,7 @@ func (c *Cluster) addAdditionalVolumes(podSpec *v1.PodSpec,
|
||||||
MountPath: additionalVolume.MountPath,
|
MountPath: additionalVolume.MountPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
if additionalVolume.IsSubPathExpr {
|
if additionalVolume.IsSubPathExpr != nil && *additionalVolume.IsSubPathExpr {
|
||||||
v.SubPathExpr = additionalVolume.SubPath
|
v.SubPathExpr = additionalVolume.SubPath
|
||||||
} else {
|
} else {
|
||||||
v.SubPath = additionalVolume.SubPath
|
v.SubPath = additionalVolume.SubPath
|
||||||
|
|
|
||||||
|
|
@ -1902,7 +1902,7 @@ func TestAdditionalVolume(t *testing.T) {
|
||||||
Name: "test6",
|
Name: "test6",
|
||||||
MountPath: "/test6",
|
MountPath: "/test6",
|
||||||
SubPath: "$(POD_NAME)",
|
SubPath: "$(POD_NAME)",
|
||||||
IsSubPathExpr: true,
|
IsSubPathExpr: util.True(),
|
||||||
TargetContainers: nil, // should mount only to postgres
|
TargetContainers: nil, // should mount only to postgres
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||||
|
|
@ -1922,7 +1922,9 @@ func TestAdditionalVolume(t *testing.T) {
|
||||||
ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
|
ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
|
||||||
},
|
},
|
||||||
Volume: acidv1.Volume{
|
Volume: acidv1.Volume{
|
||||||
Size: "1G",
|
Size: "1G",
|
||||||
|
SubPath: "$(POD_NAME)",
|
||||||
|
IsSubPathExpr: util.True(),
|
||||||
},
|
},
|
||||||
AdditionalVolumes: additionalVolumes,
|
AdditionalVolumes: additionalVolumes,
|
||||||
Sidecars: []acidv1.Sidecar{
|
Sidecars: []acidv1.Sidecar{
|
||||||
|
|
@ -1954,31 +1956,25 @@ func TestAdditionalVolume(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
subTest string
|
subTest string
|
||||||
container string
|
container string
|
||||||
expectedMounts []string
|
expectedMounts []string
|
||||||
expectedSubPath []string
|
expectedSubPaths []string
|
||||||
|
expectedSubPathExprs []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
subTest: "checking volume mounts of postgres container",
|
subTest: "checking volume mounts of postgres container",
|
||||||
container: constants.PostgresContainerName,
|
container: constants.PostgresContainerName,
|
||||||
expectedMounts: []string{"pgdata", "test1", "test3", "test4"},
|
expectedMounts: []string{"pgdata", "test1", "test3", "test4", "test5", "test6"},
|
||||||
|
expectedSubPaths: []string{"", "", "", "", "subpath", ""},
|
||||||
|
expectedSubPathExprs: []string{"$(POD_NAME)", "", "", "", "", "$(POD_NAME)"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subTest: "checking volume mounts of sidecar container",
|
subTest: "checking volume mounts of sidecar container",
|
||||||
container: "sidecar",
|
container: "sidecar",
|
||||||
expectedMounts: []string{"pgdata", "test1", "test2"},
|
expectedMounts: []string{"pgdata", "test1", "test2"},
|
||||||
},
|
expectedSubPaths: []string{"", "", ""},
|
||||||
{
|
expectedSubPathExprs: []string{"$(POD_NAME)", "", ""},
|
||||||
subTest: "checking volume mounts with subPath",
|
|
||||||
container: constants.PostgresContainerName,
|
|
||||||
expectedMounts: []string{"test5"},
|
|
||||||
expectedSubPath: []string{"subpath"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subTest: "checking volume mounts with subPathExpr",
|
|
||||||
container: constants.PostgresContainerName,
|
|
||||||
expectedMounts: []string{"test6"},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1990,6 +1986,7 @@ func TestAdditionalVolume(t *testing.T) {
|
||||||
mounts := []string{}
|
mounts := []string{}
|
||||||
subPaths := []string{}
|
subPaths := []string{}
|
||||||
subPathExprs := []string{}
|
subPathExprs := []string{}
|
||||||
|
|
||||||
for _, volumeMounts := range container.VolumeMounts {
|
for _, volumeMounts := range container.VolumeMounts {
|
||||||
mounts = append(mounts, volumeMounts.Name)
|
mounts = append(mounts, volumeMounts.Name)
|
||||||
subPaths = append(subPaths, volumeMounts.SubPath)
|
subPaths = append(subPaths, volumeMounts.SubPath)
|
||||||
|
|
@ -2001,14 +1998,14 @@ func TestAdditionalVolume(t *testing.T) {
|
||||||
t.Name(), tt.subTest, mounts, tt.expectedMounts)
|
t.Name(), tt.subTest, mounts, tt.expectedMounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !util.IsEqualIgnoreOrder(subPaths, tt.expectedSubPath) {
|
if !util.IsEqualIgnoreOrder(subPaths, tt.expectedSubPaths) {
|
||||||
t.Errorf("%s %s: different volume subPaths: got %v, expected %v",
|
t.Errorf("%s %s: different volume subPaths: got %v, expected %v",
|
||||||
t.Name(), tt.subTest, mounts, tt.expectedSubPath)
|
t.Name(), tt.subTest, subPaths, tt.expectedSubPaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !util.IsEqualIgnoreOrder(subPathExprs, []string{container.Name}) {
|
if !util.IsEqualIgnoreOrder(subPathExprs, tt.expectedSubPathExprs) {
|
||||||
t.Errorf("%s %s: different volume subPathExprs: got %v, expected %v",
|
t.Errorf("%s %s: different volume subPathExprs: got %v, expected %v",
|
||||||
t.Name(), tt.subTest, mounts, tt.expectedMounts)
|
t.Name(), tt.subTest, subPathExprs, tt.expectedSubPathExprs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue