diff --git a/README.md b/README.md index a3f488d..450279f 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,5 @@ I do try to include a final confirmation prompt with proposed changes (especiall | Script | Description | Notes | ------ | ----------- | ----- -| [cleanup-velero-resource-labels.py](./cleanup-velero-restore-labels.py) | Cleans up the `velero.io/backup-name` and `velero.io/restore-name` labels given to resources restored by Velero. | Built to work cluster-wide but not difficult to have it scoped to a specific namespace. \ No newline at end of file +| [cleanup-velero-resource-labels.py](./cleanup-velero-restore-labels.py) | Cleans up the `velero.io/backup-name` and `velero.io/restore-name` labels given to resources restored by Velero. | Built to work cluster-wide but not difficult to have it scoped to a specific namespace. +| [get-backed-up-volumes.py](./get-backed-up-volumes.py) | Lists pods which have `backup.velero.io/backup-volumes` annotations and which volumes are backed up by Velero | \ No newline at end of file diff --git a/get-backed-up-volumes.py b/get-backed-up-volumes.py new file mode 100644 index 0000000..b091ee5 --- /dev/null +++ b/get-backed-up-volumes.py @@ -0,0 +1,39 @@ +from kubernetes import client, config +from helper import identifyVolume + +config.load_kube_config() + +api_client = client.ApiClient() +core_api = client.CoreV1Api(api_client) + +pods = [] + +ret = core_api.list_pod_for_all_namespaces(watch=False) +for i in ret.items: + pod_volumes = i.spec.volumes + backed_up_volumes = [] + if "backup.velero.io/backup-volumes" in (i.metadata.annotations or {}): + vol_type = "" + data = (i.metadata.annotations.get("backup.velero.io/backup-volumes")).split(",") + for vol in data: + for podvol in pod_volumes: + if podvol.name == vol: + vol_type = identifyVolume(podvol) + backed_up_volumes.append(f"{vol} ({vol_type})") + pods.append({ + "namespace": i.metadata.namespace, + "name": i.metadata.name, + "volumes": backed_up_volumes, + }) + + +col_ns = max(len(p["namespace"]) for p in pods) if pods else 9 +col_name = max(len(p["name"]) for p in pods) if pods else 4 + +print(f"{'Namespace':<{col_ns}} {'Name':<{col_name}} Backed Up Volumes") +for p in pods: + volumes = p["volumes"] + first = volumes[0] if volumes else "" + print(f"{p['namespace']:<{col_ns}} {p['name']:<{col_name}} {first}") + for vol in volumes[1:]: + print(f"{'':<{col_ns}} {'':<{col_name}} {vol}") \ No newline at end of file diff --git a/helper.py b/helper.py new file mode 100644 index 0000000..7b3d627 --- /dev/null +++ b/helper.py @@ -0,0 +1,62 @@ +def identifyVolume(vol): + if vol.aws_elastic_block_store is not None: + return "awsElasticBlockStore" + if vol.azure_disk is not None: + return "azureDisk" + if vol.azure_file is not None: + return "azureFile" + if vol.cephfs is not None: + return "cephfs" + if vol.cinder is not None: + return "cinder" + if vol.config_map is not None: + return "configMap" + if vol.csi is not None: + return "csi" + if vol.downward_api is not None: + return "downwardAPI" + if vol.empty_dir is not None: + return "emptyDir" + if vol.ephemeral is not None: + return "ephemeral" + if vol.fc is not None: + return "fc" + if vol.flex_volume is not None: + return "flexVolume" + if vol.flocker is not None: + return "flocker" + if vol.gce_persistent_disk is not None: + return "gcePersistentDisk" + if vol.git_repo is not None: + return "gitRepo" + if vol.glusterfs is not None: + return "glusterfs" + if vol.host_path is not None: + return "hostPath" + if vol.image is not None: + return "image" + if vol.iscsi is not None: + return "iscsi" + if vol.nfs is not None: + return "nfs" + if vol.persistent_volume_claim is not None: + return "persistentVolumeClaim" + if vol.photon_persistent_disk is not None: + return "photonPersistentDisk" + if vol.portworx_volume is not None: + return "portworxVolume" + if vol.projected is not None: + return "projected" + if vol.quobyte is not None: + return "quobyte" + if vol.rbd is not None: + return "rbd" + if vol.scale_io is not None: + return "scaleIO" + if vol.secret is not None: + return "secret" + if vol.storageos is not None: + return "storageos" + if vol.vsphere_volume is not None: + return "vsphereVolume" + return vol.name