Add dropdown also to Backup PVC

This commit is contained in:
dvirlabs 2025-06-11 05:28:21 +03:00
parent 81ec39d1f0
commit 9b5666a72e
6 changed files with 52 additions and 30 deletions

View File

@ -1,5 +1,6 @@
import subprocess
import json
import re
def get_namespaces():
output = subprocess.check_output(["kubectl", "get", "ns", "-o", "json"])
@ -10,3 +11,18 @@ def get_pvcs(namespace: str):
output = subprocess.check_output(["kubectl", "get", "pvc", "-n", namespace, "-o", "json"])
data = json.loads(output)
return [item["metadata"]["name"] for item in data["items"]]
def get_all_backup_pvcs():
output = subprocess.check_output(["kubectl", "get", "pvc", "-A", "-o", "json"])
data = json.loads(output)
backup_pvcs = []
for item in data["items"]:
name = item["metadata"]["name"]
namespace = item["metadata"]["namespace"]
if re.match(r"^snapix-bkp-temp-", name):
backup_pvcs.append({
"name": name,
"namespace": namespace
})
return backup_pvcs

View File

@ -1,7 +1,7 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from models import BackupRequest, RestoreRequest
from k8s_utils import get_namespaces, get_pvcs
from k8s_utils import get_namespaces, get_pvcs, get_all_backup_pvcs
from backup_manager import create_backup, restore_backup
app = FastAPI()
@ -33,6 +33,11 @@ def restore_pvc(request: RestoreRequest):
return {"message": "Restore job created."}
@app.get("/backup-pvcs")
def list_backup_pvcs():
return get_all_backup_pvcs()
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

View File

@ -8,3 +8,5 @@ export const getNamespaces = () => api.get('/namespaces');
export const getPVCs = (namespace) => api.get(`/pvcs/${namespace}`);
export const createBackup = (payload) => api.post('/backup', payload);
export const restoreBackup = (payload) => api.post('/restore', payload);
export const getBackupPVCs = () => api.get('/backup-pvcs');

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { restoreBackup, getNamespaces, getPVCs } from '../api/snapix';
import { Button, Input } from '@mui/base';
import { restoreBackup, getNamespaces, getBackupPVCs } from '../api/snapix';
import { Button } from '@mui/base';
import '../style/RestoreForm.css';
export default function RestoreForm() {
@ -8,7 +8,7 @@ export default function RestoreForm() {
const [targetNs, setTargetNs] = useState('');
const [targetPvc, setTargetPvc] = useState('');
const [namespaces, setNamespaces] = useState([]);
const [pvcs, setPvcs] = useState([]);
const [backupPvcs, setBackupPvcs] = useState([]);
useEffect(() => {
getNamespaces().then(res => setNamespaces(res.data));
@ -16,9 +16,13 @@ export default function RestoreForm() {
useEffect(() => {
if (targetNs) {
getPVCs(targetNs).then(res => setPvcs(res.data));
getBackupPVCs().then(res => {
// Filter backup PVCs only for the selected namespace
const filtered = res.data.filter(pvc => pvc.namespace === targetNs);
setBackupPvcs(filtered);
});
} else {
setPvcs([]);
setBackupPvcs([]);
}
}, [targetNs]);
@ -38,43 +42,38 @@ export default function RestoreForm() {
<div className="form-group">
<h2>🔁 Restore PVC</h2>
<div className="form-content">
<label>Backup Name:</label>
<Input
type="text"
value={backupName}
onChange={e => setBackupName(e.target.value)}
className="restore-input"
placeholder="The exact name of the backup to restore"
/>
</div>
<div className="form-content">
<label>Target Namespace:</label>
<select value={targetNs} onChange={e => setTargetNs(e.target.value)}>
<option value="">-- Select Namespace --</option>
{namespaces.map(ns => (
<option key={ns} value={ns}>
{ns}
</option>
<option key={ns} value={ns}>{ns}</option>
))}
</select>
</div>
<div className="form-content">
<label>Backup PVC:</label>
<select
value={backupName}
onChange={e => setBackupName(e.target.value)}
disabled={!targetNs}
>
<option value="">-- Select Backup PVC --</option>
{backupPvcs.map(({ name }) => (
<option key={name} value={name}>{name}</option>
))}
</select>
</div>
<div className="form-content">
<label>Target PVC:</label>
<select
<input
type="text"
value={targetPvc}
onChange={e => setTargetPvc(e.target.value)}
disabled={!targetNs}
>
<option value="">-- Select PVC --</option>
{pvcs.map(pvc => (
<option key={pvc} value={pvc}>
{pvc}
</option>
))}
</select>
placeholder="the exact name of the pvc of your app"
/>
</div>
<Button id="restore-btn" className="btn" onClick={handleRestore}>