package bootstrap import ( "encoding/json" "fmt" "net/http" "net/url" "sort" "strings" "time" "github.com/Pingu-Studio/MaidnCLI/internal/config" ) var democraticCSIHTTPClient = &http.Client{Timeout: 30 * time.Second} func destroyDemocraticCSIStorage(csi config.DemocraticCSIConfig) error { parent := strings.Trim(csi.DatasetParentNFS, "/") if parent == "" || strings.Contains(parent, "..") { return fmt.Errorf("invalid Democratic CSI dataset parent") } base := "http://" + strings.TrimPrefix(strings.TrimPrefix(csi.TrueNASHost, "http://"), "https://") + ":80/api/v2.0/pool/dataset" request, err := http.NewRequest(http.MethodGet, base+"?parent="+url.QueryEscape(parent), nil) if err != nil { return err } request.Header.Set("Authorization", "Bearer "+csi.TrueNASAPIKey) response, err := democraticCSIHTTPClient.Do(request) if err != nil { return err } defer response.Body.Close() if response.StatusCode != http.StatusOK { return fmt.Errorf("list datasets: %s", response.Status) } var datasets []struct { Name string `json:"name"` } if err := json.NewDecoder(response.Body).Decode(&datasets); err != nil { return err } prefix := parent + "/" children := make([]string, 0, len(datasets)) for _, dataset := range datasets { if strings.HasPrefix(dataset.Name, prefix) && !strings.Contains(strings.TrimPrefix(dataset.Name, prefix), "/") { children = append(children, dataset.Name) } } sort.Strings(children) for _, child := range children { request, err := http.NewRequest(http.MethodDelete, base+"/id/"+url.PathEscape(child)+"?recursive=true&force=true", nil) if err != nil { return err } request.Header.Set("Authorization", "Bearer "+csi.TrueNASAPIKey) response, err := democraticCSIHTTPClient.Do(request) if err != nil { return err } response.Body.Close() if response.StatusCode != http.StatusNoContent { return fmt.Errorf("delete dataset %q: %s", child, response.Status) } } return nil }