Newer
Older
EnvoyControlPlane / internal / api.go
package internal

import (
	"context"
	"net/http"

	"github.com/envoyproxy/go-control-plane/pkg/cache/types"
	resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"

	internalapi "envoy-control-plane/internal/api"
	"envoy-control-plane/internal/pkg/snapshot"
)

// API holds reference to snapshot manager
type API struct {
	Manager            *snapshot.SnapshotManager
	enableCertIssuance bool
	acmeWebRootPath    string
}

// NewAPI returns a new REST API handler
func NewAPI(sm *snapshot.SnapshotManager, enableCertIssuance bool, acmeWebRootPath string) *API {
	return &API{
		Manager:            sm,
		enableCertIssuance: enableCertIssuance,
		acmeWebRootPath:    acmeWebRootPath,
	}
}

// RegisterRoutes mounts REST handlers
func (api *API) RegisterRoutes(mux *http.ServeMux) {
	// Management Handlers (Add / Remove / Enable / Disable)

	// Cluster Handlers
	mux.HandleFunc("/add-cluster", func(w http.ResponseWriter, r *http.Request) {
		api.addResourcesHandler(w, r, resourcev3.ClusterType, func(req interface{}) []types.Resource {
			cr := req.(*internalapi.AddClusterRequest)
			cls, er := snapshot.LoadResourceFromYAML(context.TODO(), cr.YAML, resourcev3.ClusterType)
			if er != nil {
				http.Error(w, "failed to load cluster", http.StatusBadRequest)
				return nil
			}
			return cls
		})
	})
	mux.HandleFunc("/disable-cluster", func(w http.ResponseWriter, r *http.Request) {
		api.disableResourceHandler(w, r, resourcev3.ClusterType)
	})
	mux.HandleFunc("/enable-cluster", func(w http.ResponseWriter, r *http.Request) {
		api.enableResourceHandler(w, r, resourcev3.ClusterType)
	})
	mux.HandleFunc("/remove-cluster", func(w http.ResponseWriter, r *http.Request) {
		api.removeResourceHandler(w, r, resourcev3.ClusterType)
	})

	// Listener Handlers
	mux.HandleFunc("/add-listener", func(w http.ResponseWriter, r *http.Request) {
		api.addResourcesHandler(w, r, resourcev3.ListenerType, func(req interface{}) []types.Resource {
			lr := req.(*internalapi.AddListenerRequest)
			lss, err := snapshot.LoadResourceFromYAML(context.TODO(), lr.YAML, resourcev3.ListenerType)
			if err != nil {
				http.Error(w, "failed to load listener", http.StatusBadRequest)
				return nil
			}
			return lss
		})
	})
	mux.HandleFunc("/disable-listener", func(w http.ResponseWriter, r *http.Request) {
		api.disableResourceHandler(w, r, resourcev3.ListenerType)
	})
	mux.HandleFunc("/enable-listener", func(w http.ResponseWriter, r *http.Request) {
		api.enableResourceHandler(w, r, resourcev3.ListenerType)
	})
	mux.HandleFunc("/remove-listener", func(w http.ResponseWriter, r *http.Request) {
		api.removeResourceHandler(w, r, resourcev3.ListenerType)
	})

	mux.HandleFunc("/append-filter-chain", func(w http.ResponseWriter, r *http.Request) {
		api.appendFilterChainHandler(w, r)
	})

	mux.HandleFunc("/update-filter-chain", func(w http.ResponseWriter, r *http.Request) {
		api.updateFilterChainHandler(w, r)
	})

	mux.HandleFunc("/remove-filter-chain", func(w http.ResponseWriter, r *http.Request) {
		api.removeFilterChainHandler(w, r)
	})

	// -------------------------------------------------------------------------
	// Secret Handlers (ADDED)
	// -------------------------------------------------------------------------
	mux.HandleFunc("/add-secret", func(w http.ResponseWriter, r *http.Request) {
		api.addResourcesHandler(w, r, resourcev3.SecretType, func(req interface{}) []types.Resource {
			sr := req.(*internalapi.AddSecretRequest)
			srs, err := snapshot.LoadResourceFromYAML(context.TODO(), sr.YAML, resourcev3.SecretType)
			if err != nil {
				http.Error(w, "failed to load secret", http.StatusBadRequest)
				return nil
			}
			return srs
		})
	})
	mux.HandleFunc("/disable-secret", func(w http.ResponseWriter, r *http.Request) {
		api.disableResourceHandler(w, r, resourcev3.SecretType)
	})
	mux.HandleFunc("/enable-secret", func(w http.ResponseWriter, r *http.Request) {
		api.enableResourceHandler(w, r, resourcev3.SecretType)
	})
	mux.HandleFunc("/remove-secret", func(w http.ResponseWriter, r *http.Request) {
		api.removeResourceHandler(w, r, resourcev3.SecretType)
	})
	mux.HandleFunc("/list-secrets", func(w http.ResponseWriter, r *http.Request) {
		api.listResourceHandler(w, r, resourcev3.SecretType)
	})
	mux.HandleFunc("/get-secret", func(w http.ResponseWriter, r *http.Request) {
		api.getResourceHandler(w, r, resourcev3.SecretType)
	})

	// Query / List Handlers
	mux.HandleFunc("/list-clusters", func(w http.ResponseWriter, r *http.Request) {
		api.listResourceHandler(w, r, resourcev3.ClusterType)
	})
	mux.HandleFunc("/get-cluster", func(w http.ResponseWriter, r *http.Request) {
		api.getResourceHandler(w, r, resourcev3.ClusterType)
	})

	mux.HandleFunc("/list-listeners", func(w http.ResponseWriter, r *http.Request) {
		api.listResourceHandler(w, r, resourcev3.ListenerType)
	})
	mux.HandleFunc("/get-listener", func(w http.ResponseWriter, r *http.Request) {
		api.getResourceHandler(w, r, resourcev3.ListenerType)
	})

	// Persistence Handlers
	mux.HandleFunc("/load-from-db", api.loadSnapshotFromDB)
	mux.HandleFunc("/flush-to-db", api.flushCacheToDB)
	mux.HandleFunc("/load-from-file", api.loadSnapshotFromFile)
	mux.HandleFunc("/save-to-file", api.saveSnapshotToFile)

	// Consistency Handler
	mux.HandleFunc("/is-consistent", api.isConsistentHandler)

	// Issuing Certificate Handler
	mux.HandleFunc("/issue-certificate", api.issueCertificateHandler)
	mux.HandleFunc("/parse-certificate", api.parseCertificateHandler)
	mux.HandleFunc("/check-certificate-validity", api.checkCertificateValidityHandler)
}