Instance-namespace additional utility endpoints.
This commit is contained in:
@@ -108,9 +108,9 @@ func (api *API) RegisterRoutes(r *mux.Router) {
|
||||
|
||||
// Operations
|
||||
r.HandleFunc("/api/v1/instances/{name}/operations", api.OperationList).Methods("GET")
|
||||
r.HandleFunc("/api/v1/operations/{id}", api.OperationGet).Methods("GET")
|
||||
r.HandleFunc("/api/v1/operations/{id}/stream", api.OperationStream).Methods("GET")
|
||||
r.HandleFunc("/api/v1/operations/{id}/cancel", api.OperationCancel).Methods("POST")
|
||||
r.HandleFunc("/api/v1/instances/{name}/operations/{id}", api.OperationGet).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/operations/{id}/stream", api.OperationStream).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/operations/{id}/cancel", api.OperationCancel).Methods("POST")
|
||||
|
||||
// Cluster operations
|
||||
r.HandleFunc("/api/v1/instances/{name}/cluster/config/generate", api.ClusterGenerateConfig).Methods("POST")
|
||||
@@ -156,13 +156,12 @@ func (api *API) RegisterRoutes(r *mux.Router) {
|
||||
r.HandleFunc("/api/v1/instances/{name}/apps/{app}/restore", api.BackupAppRestore).Methods("POST")
|
||||
|
||||
// Utilities
|
||||
r.HandleFunc("/api/v1/utilities/health", api.UtilitiesHealth).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/health", api.InstanceUtilitiesHealth).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/dashboard/token", api.UtilitiesDashboardToken).Methods("GET")
|
||||
r.HandleFunc("/api/v1/utilities/nodes/ips", api.UtilitiesNodeIPs).Methods("GET")
|
||||
r.HandleFunc("/api/v1/utilities/controlplane/ip", api.UtilitiesControlPlaneIP).Methods("GET")
|
||||
r.HandleFunc("/api/v1/utilities/secrets/{secret}/copy", api.UtilitiesSecretCopy).Methods("POST")
|
||||
r.HandleFunc("/api/v1/utilities/version", api.UtilitiesVersion).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/nodes/ips", api.UtilitiesNodeIPs).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/controlplane/ip", api.UtilitiesControlPlaneIP).Methods("GET")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/secrets/{secret}/copy", api.UtilitiesSecretCopy).Methods("POST")
|
||||
r.HandleFunc("/api/v1/instances/{name}/utilities/version", api.UtilitiesVersion).Methods("GET")
|
||||
|
||||
// dnsmasq management
|
||||
r.HandleFunc("/api/v1/dnsmasq/status", api.DnsmasqStatus).Methods("GET")
|
||||
|
||||
@@ -17,12 +17,12 @@ import (
|
||||
// OperationGet returns operation status
|
||||
func (api *API) OperationGet(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
opID := vars["id"]
|
||||
|
||||
// Extract instance name from query param or header
|
||||
instanceName := r.URL.Query().Get("instance")
|
||||
if instanceName == "" {
|
||||
respondError(w, http.StatusBadRequest, "instance parameter is required")
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ func (api *API) OperationList(w http.ResponseWriter, r *http.Request) {
|
||||
// OperationCancel cancels an operation
|
||||
func (api *API) OperationCancel(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
opID := vars["id"]
|
||||
|
||||
// Extract instance name from query param
|
||||
instanceName := r.URL.Query().Get("instance")
|
||||
if instanceName == "" {
|
||||
respondError(w, http.StatusBadRequest, "instance parameter is required")
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ func (api *API) OperationCancel(w http.ResponseWriter, r *http.Request) {
|
||||
// OperationStream streams operation output via Server-Sent Events (SSE)
|
||||
func (api *API) OperationStream(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
opID := vars["id"]
|
||||
|
||||
// Extract instance name from query param
|
||||
instanceName := r.URL.Query().Get("instance")
|
||||
if instanceName == "" {
|
||||
respondError(w, http.StatusBadRequest, "instance parameter is required")
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -10,20 +10,6 @@ import (
|
||||
"github.com/wild-cloud/wild-central/daemon/internal/utilities"
|
||||
)
|
||||
|
||||
// UtilitiesHealth returns cluster health status (legacy, no instance context)
|
||||
func (api *API) UtilitiesHealth(w http.ResponseWriter, r *http.Request) {
|
||||
status, err := utilities.GetClusterHealth("")
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to get cluster health")
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"success": true,
|
||||
"data": status,
|
||||
})
|
||||
}
|
||||
|
||||
// InstanceUtilitiesHealth returns cluster health status for a specific instance
|
||||
func (api *API) InstanceUtilitiesHealth(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
@@ -82,7 +68,19 @@ func (api *API) UtilitiesDashboardToken(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// UtilitiesNodeIPs returns IP addresses for all cluster nodes
|
||||
func (api *API) UtilitiesNodeIPs(w http.ResponseWriter, r *http.Request) {
|
||||
nodes, err := utilities.GetNodeIPs()
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Get kubeconfig path for this instance
|
||||
kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
|
||||
|
||||
nodes, err := utilities.GetNodeIPs(kubeconfigPath)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to get node IPs")
|
||||
return
|
||||
@@ -98,7 +96,19 @@ func (api *API) UtilitiesNodeIPs(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// UtilitiesControlPlaneIP returns the control plane IP
|
||||
func (api *API) UtilitiesControlPlaneIP(w http.ResponseWriter, r *http.Request) {
|
||||
ip, err := utilities.GetControlPlaneIP()
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Get kubeconfig path for this instance
|
||||
kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
|
||||
|
||||
ip, err := utilities.GetControlPlaneIP(kubeconfigPath)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to get control plane IP")
|
||||
return
|
||||
@@ -115,8 +125,15 @@ func (api *API) UtilitiesControlPlaneIP(w http.ResponseWriter, r *http.Request)
|
||||
// UtilitiesSecretCopy copies a secret between namespaces
|
||||
func (api *API) UtilitiesSecretCopy(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
secretName := vars["secret"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
SourceNamespace string `json:"source_namespace"`
|
||||
DestinationNamespace string `json:"destination_namespace"`
|
||||
@@ -132,7 +149,10 @@ func (api *API) UtilitiesSecretCopy(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := utilities.CopySecretBetweenNamespaces(secretName, req.SourceNamespace, req.DestinationNamespace); err != nil {
|
||||
// Get kubeconfig path for this instance
|
||||
kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
|
||||
|
||||
if err := utilities.CopySecretBetweenNamespaces(kubeconfigPath, secretName, req.SourceNamespace, req.DestinationNamespace); err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to copy secret")
|
||||
return
|
||||
}
|
||||
@@ -145,7 +165,19 @@ func (api *API) UtilitiesSecretCopy(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// UtilitiesVersion returns cluster and Talos versions
|
||||
func (api *API) UtilitiesVersion(w http.ResponseWriter, r *http.Request) {
|
||||
k8sVersion, err := utilities.GetClusterVersion()
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Get kubeconfig path for this instance
|
||||
kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
|
||||
|
||||
k8sVersion, err := utilities.GetClusterVersion(kubeconfigPath)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, "Failed to get cluster version")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user