diff --git a/api/routing/v1alpha1/envoybootstrapconfig_types.go b/api/routing/v1alpha1/envoybootstrapconfig_types.go
new file mode 100644
index 0000000..4922c77
--- /dev/null
+++ b/api/routing/v1alpha1/envoybootstrapconfig_types.go
@@ -0,0 +1,75 @@
+package v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+const (
+ KindEnvoyBootstrapConfig = "EnvoyBootstrapConfig"
+ ResourceEnvoyBootstrapConfig = "envoybootstrapconfigs"
+)
+
+//+kubebuilder:object:root=true
+// +kubebuilder:resource:path=envoybootstrapconfigs,singular=envoybootstrapconfig,shortName=ebc;ebcs
+// +kubebuilder:printcolumn:name="ClusterID",type=string,JSONPath=`.spec.clusterID`
+// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=`.status.ready`
+// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
+// +kubebuilder:subresource:status
+
+// EnvoyBootstrapConfig is the Schema for the envoybootstrapconfigs API.
+// It declares the desired state for an Envoy bootstrap configuration.
+// The route-manager reconciler watches these resources and produces a
+// ConfigMap (rendered bootstrap JSON) and a Secret (access token) in the
+// same namespace.
+type EnvoyBootstrapConfig struct {
+ metav1.TypeMeta `json:",inline"`
+ // Standard object's metadata.
+ // +optional
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec EnvoyBootstrapConfigSpec `json:"spec,omitempty"`
+ Status EnvoyBootstrapConfigStatus `json:"status,omitempty"`
+}
+
+// EnvoyBootstrapConfigSpec describes the desired Envoy bootstrap configuration.
+type EnvoyBootstrapConfigSpec struct {
+ // ClusterID identifies the Qdrant cluster this Envoy instance serves.
+ // When set the Envoy runs in dedicated mode for this cluster.
+ // When nil it runs in shared mode.
+ // +optional
+ ClusterID *string `json:"clusterID,omitempty"`
+ // ProxyProtocolEnabled enables the PROXY protocol on Envoy listeners.
+ // +kubebuilder:default=false
+ // +optional
+ ProxyProtocolEnabled bool `json:"proxyProtocolEnabled,omitempty"`
+}
+
+// EnvoyBootstrapConfigStatus defines the observed state of EnvoyBootstrapConfig.
+type EnvoyBootstrapConfigStatus struct {
+ // Ready is true once the ConfigMap and Secret exist and are up-to-date.
+ Ready bool `json:"ready,omitempty"`
+ // ConfigMapName is the name of the generated ConfigMap containing the bootstrap JSON.
+ ConfigMapName string `json:"configMapName,omitempty"`
+ // SecretName is the name of the access-token Secret (created or reused).
+ SecretName string `json:"secretName,omitempty"`
+ // Conditions represent the latest available observations of the resource's state.
+ // +optional
+ Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// EnvoyBootstrapConfigList contains a list of EnvoyBootstrapConfig objects.
+type EnvoyBootstrapConfigList struct {
+ metav1.TypeMeta `json:",inline"`
+ // Standard list metadata.
+ // +optional
+ metav1.ListMeta `json:"metadata,omitempty"`
+
+ // List of EnvoyBootstrapConfig objects
+ Items []EnvoyBootstrapConfig `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&EnvoyBootstrapConfig{}, &EnvoyBootstrapConfigList{})
+}
diff --git a/api/routing/v1alpha1/zz_generated.deepcopy.go b/api/routing/v1alpha1/zz_generated.deepcopy.go
index e372f84..0a0c3b6 100644
--- a/api/routing/v1alpha1/zz_generated.deepcopy.go
+++ b/api/routing/v1alpha1/zz_generated.deepcopy.go
@@ -5,6 +5,7 @@
package v1alpha1
import (
+ "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -38,6 +39,107 @@ func (in *BootstrapStatusInfo) DeepCopy() *BootstrapStatusInfo {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyBootstrapConfig) DeepCopyInto(out *EnvoyBootstrapConfig) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyBootstrapConfig.
+func (in *EnvoyBootstrapConfig) DeepCopy() *EnvoyBootstrapConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyBootstrapConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *EnvoyBootstrapConfig) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyBootstrapConfigList) DeepCopyInto(out *EnvoyBootstrapConfigList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]EnvoyBootstrapConfig, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyBootstrapConfigList.
+func (in *EnvoyBootstrapConfigList) DeepCopy() *EnvoyBootstrapConfigList {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyBootstrapConfigList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *EnvoyBootstrapConfigList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyBootstrapConfigSpec) DeepCopyInto(out *EnvoyBootstrapConfigSpec) {
+ *out = *in
+ if in.ClusterID != nil {
+ in, out := &in.ClusterID, &out.ClusterID
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyBootstrapConfigSpec.
+func (in *EnvoyBootstrapConfigSpec) DeepCopy() *EnvoyBootstrapConfigSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyBootstrapConfigSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyBootstrapConfigStatus) DeepCopyInto(out *EnvoyBootstrapConfigStatus) {
+ *out = *in
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]v1.Condition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyBootstrapConfigStatus.
+func (in *EnvoyBootstrapConfigStatus) DeepCopy() *EnvoyBootstrapConfigStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyBootstrapConfigStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *QdrantClusterRouting) DeepCopyInto(out *QdrantClusterRouting) {
*out = *in
diff --git a/charts/qdrant-kubernetes-api/templates/routing-crds/routing.qdrant.io_envoybootstrapconfigs.yaml b/charts/qdrant-kubernetes-api/templates/routing-crds/routing.qdrant.io_envoybootstrapconfigs.yaml
new file mode 100644
index 0000000..6fe6e6c
--- /dev/null
+++ b/charts/qdrant-kubernetes-api/templates/routing-crds/routing.qdrant.io_envoybootstrapconfigs.yaml
@@ -0,0 +1,154 @@
+{{ if .Values.includeRoutingCRDs }}
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.20.1
+ name: envoybootstrapconfigs.routing.qdrant.io
+spec:
+ group: routing.qdrant.io
+ names:
+ kind: EnvoyBootstrapConfig
+ listKind: EnvoyBootstrapConfigList
+ plural: envoybootstrapconfigs
+ shortNames:
+ - ebc
+ - ebcs
+ singular: envoybootstrapconfig
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .spec.clusterID
+ name: ClusterID
+ type: string
+ - jsonPath: .status.ready
+ name: Ready
+ type: boolean
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ EnvoyBootstrapConfig is the Schema for the envoybootstrapconfigs API.
+ It declares the desired state for an Envoy bootstrap configuration.
+ The route-manager reconciler watches these resources and produces a
+ ConfigMap (rendered bootstrap JSON) and a Secret (access token) in the
+ same namespace.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: EnvoyBootstrapConfigSpec describes the desired Envoy bootstrap
+ configuration.
+ properties:
+ clusterID:
+ description: |-
+ ClusterID identifies the Qdrant cluster this Envoy instance serves.
+ When set the Envoy runs in dedicated mode for this cluster.
+ When nil it runs in shared mode.
+ type: string
+ proxyProtocolEnabled:
+ default: false
+ description: ProxyProtocolEnabled enables the PROXY protocol on Envoy
+ listeners.
+ type: boolean
+ type: object
+ status:
+ description: EnvoyBootstrapConfigStatus defines the observed state of
+ EnvoyBootstrapConfig.
+ properties:
+ conditions:
+ description: Conditions represent the latest available observations
+ of the resource's state.
+ items:
+ description: Condition contains details for one aspect of the current
+ state of this API Resource.
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ configMapName:
+ description: ConfigMapName is the name of the generated ConfigMap
+ containing the bootstrap JSON.
+ type: string
+ ready:
+ description: Ready is true once the ConfigMap and Secret exist and
+ are up-to-date.
+ type: boolean
+ secretName:
+ description: SecretName is the name of the access-token Secret (created
+ or reused).
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+{{ end }}
diff --git a/docs/api.md b/docs/api.md
index 081205c..5851969 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1673,6 +1673,7 @@ _Appears in:_
Package v1alpha1 contains API Schema definitions for the routing.qdrant.io v1alpha1 API group
### Resource Types
+- [EnvoyBootstrapConfig](#envoybootstrapconfig)
- [QdrantClusterRouting](#qdrantclusterrouting)
@@ -1696,6 +1697,50 @@ _Appears in:_
| `bootstrapped` _boolean_ | Set to true if routing of the Qdrant cluster has been bootstrapped once for this specific route. | | |
+#### EnvoyBootstrapConfig
+
+
+
+EnvoyBootstrapConfig is the Schema for the envoybootstrapconfigs API.
+It declares the desired state for an Envoy bootstrap configuration.
+The route-manager reconciler watches these resources and produces a
+ConfigMap (rendered bootstrap JSON) and a Secret (access token) in the
+same namespace.
+
+
+
+_Appears in:_
+- [EnvoyBootstrapConfigList](#envoybootstrapconfiglist)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `apiVersion` _string_ | `routing.qdrant.io/v1alpha1` | | |
+| `kind` _string_ | `EnvoyBootstrapConfig` | | |
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | Optional: \{\}
|
+| `spec` _[EnvoyBootstrapConfigSpec](#envoybootstrapconfigspec)_ | | | |
+
+
+
+
+#### EnvoyBootstrapConfigSpec
+
+
+
+EnvoyBootstrapConfigSpec describes the desired Envoy bootstrap configuration.
+
+
+
+_Appears in:_
+- [EnvoyBootstrapConfig](#envoybootstrapconfig)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `clusterID` _string_ | ClusterID identifies the Qdrant cluster this Envoy instance serves.
When set the Envoy runs in dedicated mode for this cluster.
When nil it runs in shared mode. | | Optional: \{\}
|
+| `proxyProtocolEnabled` _boolean_ | ProxyProtocolEnabled enables the PROXY protocol on Envoy listeners. | false | Optional: \{\}
|
+
+
+
+
#### QdrantClusterRouting