Documentation
¶
Overview ¶
Package controller reconciles the user-facing Gateway CR into a Crossplane XGatewayGCP composite, the WireGuard key Secrets, the in-cluster link Deployment and its RBAC, and an optional DNSEndpoint.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var XGatewayGCPGVK = schema.GroupVersionKind{Group: "infra.wgnet.dev", Version: "v1alpha1", Kind: "XGatewayGCP"}
XGatewayGCPGVK is the composite's GroupVersionKind, exported so the manager can register an unstructured Owns watch on it.
var XGatewayNetworkGVK = schema.GroupVersionKind{Group: "infra.wgnet.dev", Version: "v1alpha1", Kind: "XGatewayNetwork"}
XGatewayNetworkGVK is the shared-VPC composite's GroupVersionKind, exported so the manager can register an unstructured watch on it.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// LinkImage is the container image for the gateway-link Deployment.
LinkImage string `envconfig:"GATEWAY_LINK_IMAGE" required:"true"`
// LinkImagePullPolicy is the imagePullPolicy for the link container.
LinkImagePullPolicy string `envconfig:"GATEWAY_LINK_IMAGE_PULL_POLICY" default:"IfNotPresent"`
// UserData is the VM user-data the XGatewayGCP sets on the gateway instance. It is
// operator-level: every per-Gateway value is read from instance metadata at
// boot, so the rendered Ignition is byte-identical across every Gateway. Empty
// omits the field from the composite.
UserData string `envconfig:"GATEWAY_USER_DATA"`
// RequeueInterval is how often the reconciler re-polls the XGatewayGCP status,
// since the composite's status is not watched in realtime.
RequeueInterval time.Duration `envconfig:"GATEWAY_REQUEUE_INTERVAL" default:"30s"`
// to. Required so a misconfigured install fails fast rather than silently using
// the wrong VPC: the chart always supplies the release-derived name (wgnet-<release>),
// and operators serving separate tenants each get a distinct value so they do not
// contend for one VPC.
SharedNetworkName string `envconfig:"GATEWAY_SHARED_NETWORK_NAME" required:"true"`
// PodNamespace is where the operator pod itself runs, used to place the
// singleton shared-network composite alongside the operator. Supplied via the
// downward API.
PodNamespace string `envconfig:"POD_NAMESPACE" required:"true"`
}
Config carries the operator-level inputs the reconciler folds into every Gateway's children. These are the values that are identical across the whole operator install rather than per-Gateway: the link image, the VM userData, and the reconcile cadence. Every per-Gateway value (the GCP placement and the WireGuard tunnel parameters) lives on the Gateway CR's spec, not here.
Populated from the process environment via config.Load. The empty envconfig prefix means tags are read verbatim.
type GatewayReconciler ¶
type GatewayReconciler struct {
client.Client
Scheme *runtime.Scheme
Config Config
Recorder events.EventRecorder
// APIReader reads directly from the API server, bypassing the manager cache.
// The shared-network refcount in releaseAfterSharedNetwork uses it to read the
// shared XGatewayNetwork composite, which carries no owner ref and is not
// watched, so the cache never tracks it. SetupWithManager binds it to the
// manager's APIReader.
APIReader client.Reader
// GenerateKey supplies WireGuard keypairs. Nil defaults to wg.GenerateKeypair.
GenerateKey KeyGenerator
}
GatewayReconciler reconciles a Gateway into its XGatewayGCP composite, WireGuard key Secrets, link Deployment and NetworkPolicy, and optional DNSEndpoint, then mirrors the composite's observed status back onto the Gateway.
func (*GatewayReconciler) Reconcile ¶
Reconcile drives a Gateway toward its desired state. On deletion it deletes the XGatewayGCP and requeues until the composite is gone before releasing the finalizer; otherwise it ensures the finalizer, classifies the forwards, and ensures the key Secrets, the XGatewayGCP, and the link children rendered with the valid forward subset, then mirrors the composite status and requeues.
Forward classification gates provisioning per forward rather than all-or- nothing. A Gateway with at least one valid forward provisions, exposing exactly the valid subset. A Gateway whose forwards are all invalid does not provision while unprovisioned; once provisioned it keeps its VM and re-applies the children with an empty forward set, which closes the firewall to the WireGuard underlay only and stops the link serving any forward, rather than tearing the VM down on a transient backend outage. Invalid forwards always surface on the Ready condition.
func (*GatewayReconciler) SetupWithManager ¶
func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error
SetupWithManager registers the reconciler, watching the Gateway and owning the children GC reaps by owner-ref plus the unstructured XGatewayGCP. The DNSEndpoint is intentionally not owned: an Owns watch would make manager start require the external-dns CRD.
The XGatewayGCP and link Deployment watches deliberately omit GenerationChangedPredicate so their status-only updates trigger a reconcile: readiness gates on the XGatewayGCP's status.address and the Deployment's DeploymentAvailable condition, and the predicate would filter exactly those status writes, leaving readiness to flip only on the RequeueAfter fallback. This does not reintroduce a write loop: child applies are server-side and idempotent (re-applying an unchanged object is a no-op that bumps no resourceVersion) and mirrorStatusWithForwards writes only on change. The remaining child watches keep the predicate because nothing reads their status.
The Service and Namespace watches drive forward classification: a forward's backend Service appearing, disappearing, or changing its published ports, and a target namespace's consent label being added or removed, all change which forwards are valid. Mapping each such event back to the affected Gateways makes the operator converge promptly. These are external objects the operator does not own, so they are watched with explicit map functions rather than Owns. The operator watches all namespaces, so these watches observe a forward's backend Service or target namespace wherever it lives. Convergence does not depend on the watch alone: a Gateway with an invalid forward is also requeued on the fixed transient floor (anyTransientReason), so it reconverges even if a watch event is coalesced or missed.
type KeyGenerator ¶
KeyGenerator produces a WireGuard keypair. It is injected so tests can supply deterministic key material; production binds it to wg.GenerateKeypair.