package report import ( "errors" "fmt" "io" "net/http" "strings" "time" ) // Config-pull error types for setup-wizard UI display. // // These (and PullConfig) were previously part of infra_pull.go alongside the // disk-tier DR-recovery (PullRecovery / infra-backup) client. Disk recovery moved // to the host agent in slice 8C; only the fresh-install config download survives // here, so it lives in this slimmed file. var ( ErrHubUnreachable = errors.New("hub unreachable") ErrAuthFailed = errors.New("authentication failed") ErrNotFound = errors.New("customer not found") ErrHubError = errors.New("hub error") ) // PullConfig fetches a generated controller.yaml from the Hub config endpoint. // Auth: X-Retrieval-Password header. Used by the setup wizard's fresh-install flow. func PullConfig(hubURL, customerID, retrievalPassword string) (string, error) { url := strings.TrimRight(hubURL, "/") + "/api/v1/config/" + customerID client := &http.Client{Timeout: 30 * time.Second} req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return "", fmt.Errorf("%w: %v", ErrHubError, err) } req.Header.Set("X-Retrieval-Password", retrievalPassword) resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("%w: %v", ErrHubUnreachable, err) } defer resp.Body.Close() switch resp.StatusCode { case http.StatusOK: // success case http.StatusUnauthorized: return "", ErrAuthFailed case http.StatusNotFound: return "", ErrNotFound default: return "", fmt.Errorf("%w: HTTP %d", ErrHubError, resp.StatusCode) } body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) // 1MB limit if err != nil { return "", fmt.Errorf("%w: reading response: %v", ErrHubError, err) } return string(body), nil }