Documentation
¶
Overview ¶
Package kubernetes provides an in-memory Kubernetes data-plane API server.
Each cluster created via cloudemu's EKS, AKS, or GKE control-plane handlers registers a fresh ClusterState with a shared APIServer. Clients connect via kubeconfigs that point at <base-url>/k8s/<uid>, and the upstream Kubernetes REST surface (/api/v1/... and /apis/apps/v1/...) is served below that prefix. This makes a `client-go` round-trip against a cloudemu-emulated EKS/AKS/GKE cluster work end-to-end.
Index ¶
- Constants
- func RenderKubeconfig(apiServerBase, uid, clusterName string) []byte
- type APIServer
- func (s *APIServer) BaseURL() string
- func (s *APIServer) DeregisterCluster(uid string)
- func (s *APIServer) Lookup(uid string) *ClusterState
- func (*APIServer) Matches(r *http.Request) bool
- func (s *APIServer) RegisterCluster() (string, *ClusterState)
- func (s *APIServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *APIServer) SetBaseURL(url string)
- type ClusterState
- type Route
Constants ¶
const ( EventAdded = "ADDED" EventModified = "MODIFIED" EventDeleted = "DELETED" )
Watch event types per the Kubernetes API contract. Wire format is {"type":"<EventType>","object":{...}} sent as one JSON object per chunk.
const StubToken = "cloudemu-anonymous"
StubToken is the bearer token returned in every cloudemu-rendered kubeconfig. The in-memory APIServer accepts any (or no) bearer token, so this string is purely a syntactic placeholder so client-go's auth flow doesn't trip.
Variables ¶
This section is empty.
Functions ¶
func RenderKubeconfig ¶
RenderKubeconfig returns a syntactically-valid kubeconfig YAML pointing at apiServerBase + /k8s/<uid>. Callers (AKS ListClusterAdminCredentials and the AKS Mock's Kubeconfig method in particular) hand this to clients as the cluster's credentials.
apiServerBase is the URL of the SDK-compat httptest server (e.g. the value of httptest.Server.URL); cluster's data-plane URL appends /k8s/<uid> to that base. clusterName is what the kubeconfig surfaces in its clusters[], users[], and contexts[] entries — typically the cloud's own cluster name.
Types ¶
type APIServer ¶
type APIServer struct {
// contains filtered or unexported fields
}
APIServer is the shared in-memory Kubernetes data-plane API server. It holds independent ClusterState per registered cluster UID and dispatches HTTP requests to the right state based on the URL prefix.
One APIServer instance is wired into all three SDK-compat cloud servers (awsserver, azureserver, gcpserver) so kubeconfigs from any provider land on the same backend — exactly mirroring real-world Kubernetes, where the API is identical across EKS, AKS, and GKE.
func NewAPIServer ¶
func NewAPIServer() *APIServer
NewAPIServer returns an empty APIServer with no registered clusters.
func (*APIServer) DeregisterCluster ¶
DeregisterCluster removes a cluster's state. Called by control-plane handlers on DeleteCluster. Idempotent.
func (*APIServer) Lookup ¶
func (s *APIServer) Lookup(uid string) *ClusterState
Lookup returns the ClusterState for uid, or nil if it doesn't exist.
func (*APIServer) Matches ¶
Matches reports whether r is rooted under the /k8s/ prefix and should be served by this APIServer. Used by the SDK-compat cloud servers to route requests away from S3/EC2/EKS-control-plane and into the data plane.
func (*APIServer) RegisterCluster ¶
func (s *APIServer) RegisterCluster() (string, *ClusterState)
RegisterCluster allocates fresh state for a new cluster and returns its generated UID. The UID is the path segment that goes into the kubeconfig's server URL — kubeconfig "server" becomes "<base>/k8s/<uid>".
func (*APIServer) ServeHTTP ¶
func (s *APIServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP peels off /k8s/{uid} and dispatches the remainder of the URL into the matching ClusterState's handler. Unknown UIDs return 404 in the Kubernetes Status shape so client-go decodes the error correctly.
func (*APIServer) SetBaseURL ¶
SetBaseURL records the URL at which the APIServer is reachable — typically the URL of the httptest server it's registered on. Control-plane handlers (EKS/AKS/GKE) read this back via BaseURL() when rendering kubeconfigs so the kubeconfig's "server:" field points at a host that actually answers.
Callers set this after httptest.NewServer returns, before issuing any CreateCluster RPC that needs to emit a working kubeconfig.
type ClusterState ¶
type ClusterState struct {
// contains filtered or unexported fields
}
ClusterState is the in-memory backing store for one Kubernetes cluster's data plane. Every cluster registered with an APIServer gets its own ClusterState — two EKS clusters in the same test never see each other's resources.
Resources are kept in plain Go maps under a single RWMutex. The K8s API is read-heavy in the typical test scenario (Reflector list + watch), and the surface is small enough that finer-grained locking would just add complexity without measurable gain.
func (*ClusterState) ServeHTTP ¶
func (s *ClusterState) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP dispatches a Kubernetes REST request into the per-resource handlers. The request's URL has already been stripped of the /k8s/<uid> prefix by APIServer.ServeHTTP, so r.URL.Path here starts with /api/v1/... or /apis/<group>/<version>/...
type Route ¶
type Route struct {
APIGroup string // "" for core (/api/v1), "apps" for /apis/apps/v1, etc.
APIVersion string // always "v1" for Wave 2 Phase 1
Namespace string // "" for cluster-scoped resources
Resource string // "namespaces", "configmaps", "pods", …
Name string // "" for collection requests (LIST / CREATE)
}
Route holds the four pieces every Kubernetes REST URL decomposes into. One Route value is the dispatch key for the per-resource handlers.