Skip to content

Commit

Permalink
Add volume types filter in resource policies
Browse files Browse the repository at this point in the history
Signed-off-by: Ming Qiu <[email protected]>
  • Loading branch information
qiuming-best committed Sep 25, 2023
1 parent d3e5bb7 commit f5b03ea
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/6863-qiuming-best
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add volume types filter in resource policies
1 change: 1 addition & 0 deletions internal/resourcepolicies/resource_policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func (p *Policies) buildPolicy(resPolicies *resourcePolicies) error {
volP.conditions = append(volP.conditions, &storageClassCondition{storageClass: con.StorageClass})
volP.conditions = append(volP.conditions, &nfsCondition{nfs: con.NFS})
volP.conditions = append(volP.conditions, &csiCondition{csi: con.CSI})
volP.conditions = append(volP.conditions, &volumeTypeCondition{volumeTypes: con.VolumeTypes})
p.volumePolicies = append(p.volumePolicies, volP)
}

Expand Down
23 changes: 23 additions & 0 deletions internal/resourcepolicies/resource_policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,29 @@ volumePolicies:
},
skip: false,
},
{
name: "match volume by types",
yamlData: `version: v1
volumePolicies:
- conditions:
capacity: "0,100Gi"
volumeTypes:
- local
- hostPath
action:
type: skip`,
vol: &v1.PersistentVolume{
Spec: v1.PersistentVolumeSpec{
Capacity: v1.ResourceList{
v1.ResourceStorage: resource.MustParse("1Gi"),
},
PersistentVolumeSource: v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{Path: "/mnt/data"},
},
},
},
skip: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions internal/resourcepolicies/volume_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type structuredVolume struct {
storageClass string
nfs *nFSVolumeSource
csi *csiVolumeSource
volumeType string
}

func (s *structuredVolume) parsePV(pv *corev1api.PersistentVolume) {
Expand All @@ -46,6 +47,8 @@ func (s *structuredVolume) parsePV(pv *corev1api.PersistentVolume) {
if csi != nil {
s.csi = &csiVolumeSource{Driver: csi.Driver}
}

s.volumeType = getVolumeTypeFromPV(pv)
}

func (s *structuredVolume) parsePodVolume(vol *corev1api.Volume) {
Expand All @@ -58,6 +61,8 @@ func (s *structuredVolume) parsePodVolume(vol *corev1api.Volume) {
if csi != nil {
s.csi = &csiVolumeSource{Driver: csi.Driver}
}

s.volumeType = getVolumeTypeFromVolume(vol)
}

type capacityCondition struct {
Expand Down
1 change: 1 addition & 0 deletions internal/resourcepolicies/volume_resources_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type volumeConditions struct {
StorageClass []string `yaml:"storageClass,omitempty"`
NFS *nFSVolumeSource `yaml:"nfs,omitempty"`
CSI *csiVolumeSource `yaml:"csi,omitempty"`
VolumeTypes []string `yaml:"volumeTypes,omitempty"`
}

func (c *capacityCondition) validate() error {
Expand Down
207 changes: 207 additions & 0 deletions internal/resourcepolicies/volume_types_conditions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package resourcepolicies

import (
corev1api "k8s.io/api/core/v1"
)

type volumeTypeCondition struct {
volumeTypes []string
}

func (v *volumeTypeCondition) match(s *structuredVolume) bool {
if len(v.volumeTypes) == 0 {
return true
}

for _, vt := range v.volumeTypes {
if vt == s.volumeType {
return true
}
}
return false
}

func (s *volumeTypeCondition) validate() error {
// validate by yamlv3
return nil
}

func getVolumeTypeFromPV(pv *corev1api.PersistentVolume) string {
if pv == nil {
return ""
}
if pv.Spec.GCEPersistentDisk != nil {
return "gcePersistentDisk"
}
if pv.Spec.AWSElasticBlockStore != nil {
return "awsElasticBlockStore"
}
if pv.Spec.HostPath != nil {
return "hostPath"
}
if pv.Spec.Glusterfs != nil {
return "glusterfs"
}
if pv.Spec.NFS != nil {
return "nfs"
}
if pv.Spec.RBD != nil {
return "rbd"
}
if pv.Spec.ISCSI != nil {
return "iscsi"
}
if pv.Spec.Cinder != nil {
return "cinder"
}
if pv.Spec.CephFS != nil {
return "cephfs"
}
if pv.Spec.FC != nil {
return "fc"
}
if pv.Spec.Flocker != nil {
return "flocker"
}
if pv.Spec.FlexVolume != nil {
return "flexVolume"
}
if pv.Spec.AzureFile != nil {
return "azureFile"
}
if pv.Spec.VsphereVolume != nil {
return "vsphereVolume"
}
if pv.Spec.Quobyte != nil {
return "quobyte"
}
if pv.Spec.AzureDisk != nil {
return "azureDisk"
}
if pv.Spec.PhotonPersistentDisk != nil {
return "photonPersistentDisk"
}
if pv.Spec.PortworxVolume != nil {
return "portworxVolume"
}
if pv.Spec.ScaleIO != nil {
return "scaleIO"
}
if pv.Spec.Local != nil {
return "local"
}
if pv.Spec.StorageOS != nil {
return "storageOS"
}
if pv.Spec.CSI != nil {
return "csi"
}
return ""
}

func getVolumeTypeFromVolume(vol *corev1api.Volume) string {
if vol == nil {
return ""
}
if vol.HostPath != nil {
return "hostPath"
}
if vol.EmptyDir != nil {
return "emptyDir"
}
if vol.GCEPersistentDisk != nil {
return "gcePersistentDisk"
}
if vol.AWSElasticBlockStore != nil {
return "awsElasticBlockStore"
}
if vol.GitRepo != nil {
return "gitRepo"
}
if vol.Secret != nil {
return "secret"
}
if vol.NFS != nil {
return "nfs"
}
if vol.ISCSI != nil {
return "iscsi"
}
if vol.Glusterfs != nil {
return "glusterfs"
}
if vol.RBD != nil {
return "rbd"
}
if vol.FlexVolume != nil {
return "flexVolume"
}
if vol.Cinder != nil {
return "cinder"
}
if vol.CephFS != nil {
return "cephfs"
}
if vol.Flocker != nil {
return "flocker"
}
if vol.DownwardAPI != nil {
return "downwardAPI"
}
if vol.FC != nil {
return "fc"
}
if vol.AzureFile != nil {
return "azureFile"
}
if vol.ConfigMap != nil {
return "configMap"
}
if vol.VsphereVolume != nil {
return "vsphereVolume"
}
if vol.Quobyte != nil {
return "quobyte"
}
if vol.AzureDisk != nil {
return "azureDisk"
}
if vol.PhotonPersistentDisk != nil {
return "photonPersistentDisk"
}
if vol.Projected != nil {
return "projected"
}
if vol.PortworxVolume != nil {
return "portworxVolume"
}
if vol.ScaleIO != nil {
return "scaleIO"
}
if vol.StorageOS != nil {
return "storageOS"
}
if vol.CSI != nil {
return "csi"
}
if vol.Ephemeral != nil {
return "ephemeral"
}
return ""
}
25 changes: 23 additions & 2 deletions site/content/docs/main/resource-filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ Velero only support volume resource policies currently, other kinds of resource
driver: aws.ebs.csi.driver
# pv matches one of the storage class list
storageClass:
- gp2
- standard
- gp2
- standard
action:
type: skip
- conditions:
Expand All @@ -271,6 +271,14 @@ Velero only support volume resource policies currently, other kinds of resource
csi: {}
action:
type: skip
- conditions:
volumeTypes:
- emptyDir
- downwardAPI
- configmap
- cinder
action:
type: skip
```
**Supported conditions**
Expand Down Expand Up @@ -318,6 +326,19 @@ Velero supported conditions and format listed below:
```
For volume provisioned by [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes) support all above attributes, but for pod [Volume](https://kubernetes.io/docs/concepts/storage/volumes) only support filtered by volume source.
- volume types
Support filter volumes by types
```yaml
volumeTypes:
# matches volumes listed below
- emptyDir
- downwardAPI
- configmap
- cinder
```
Volume types could be found in [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes) and pod [Volume](https://kubernetes.io/docs/concepts/storage/volumes)
**Resource policies rules**
- Velero already has lots of include or exclude filters. the resource policies are the final filters after others include or exclude filters in one backup processing workflow. So if use a defined similar filter like the opt-in approach to backup one pod volume but skip backup of the same pod volume in resource policies, as resource policies are the final filters that are applied, the volume will not be backed up.
- If volume resource policies conflict with themselves the first matched policy will be respected when many policies are defined.

0 comments on commit f5b03ea

Please sign in to comment.