diff --git a/api/v1/qdrantcluster_types.go b/api/v1/qdrantcluster_types.go index 9e7a785..121471f 100644 --- a/api/v1/qdrantcluster_types.go +++ b/api/v1/qdrantcluster_types.go @@ -762,6 +762,17 @@ type Ingress struct { // Traefik specifies the traefik ingress specific configurations. // +optional Traefik *TraefikConfig `json:"traefik,omitempty"` + // EnableAccessLog overrides the region-wide Envoy proxy access log setting + // for this cluster: true forces it on, false forces it off, and unset + // follows the region. + // + // The override matters in both directions. A single tenant can carry most + // of a region's traffic, so "off" has to be expressible for one cluster + // without giving up the log for every other cluster in that region; and + // "on" has to be expressible for a cluster under investigation without + // enabling the whole region. + // +optional + EnableAccessLog *bool `json:"enableAccessLog,omitempty"` } func (i *Ingress) GetAnnotations() map[string]string { @@ -785,6 +796,16 @@ func (i *Ingress) GetTls(def bool) bool { return *i.TLS } +// GetEnableAccessLog returns whether the Envoy access log is enabled for this +// cluster, falling back to def (the region-wide setting) when the cluster does +// not override it. +func (i *Ingress) GetEnableAccessLog(def bool) bool { + if i == nil || i.EnableAccessLog == nil { + return def + } + return *i.EnableAccessLog +} + func (i *Ingress) GetNGINX() *NGINXConfig { if i == nil { return nil diff --git a/api/v1/qdrantcluster_types_test.go b/api/v1/qdrantcluster_types_test.go index 651ee18..125e982 100644 --- a/api/v1/qdrantcluster_types_test.go +++ b/api/v1/qdrantcluster_types_test.go @@ -196,3 +196,34 @@ func TestValidate(t *testing.T) { }) } } + +// TestIngressGetEnableAccessLog pins the three-state override. The false case is +// the one that matters operationally: a single tenant can carry most of a +// region's traffic, so it has to be possible to silence one cluster without +// giving up the log for every other cluster in the region. +func TestIngressGetEnableAccessLog(t *testing.T) { + testCases := []struct { + name string + ingress *Ingress + region bool + want bool + }{ + {"nil ingress follows the region", nil, true, true}, + {"unset follows the region (on)", &Ingress{}, true, true}, + {"unset follows the region (off)", &Ingress{}, false, false}, + {"true forces on against a disabled region", &Ingress{EnableAccessLog: ptr.To(true)}, false, true}, + {"false forces off against an enabled region", &Ingress{EnableAccessLog: ptr.To(false)}, true, false}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.want, tc.ingress.GetEnableAccessLog(tc.region)) + }) + } +} + +func TestIngressJSONOmitsUnsetEnableAccessLog(t *testing.T) { + data, err := json.Marshal(Ingress{}) + + assert.NoError(t, err) + assert.NotContains(t, string(data), "enableAccessLog") +} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index c4ff7ee..bdeed7e 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -214,6 +214,11 @@ func (in *Ingress) DeepCopyInto(out *Ingress) { *out = new(TraefikConfig) (*in).DeepCopyInto(*out) } + if in.EnableAccessLog != nil { + in, out := &in.EnableAccessLog, &out.EnableAccessLog + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ingress. diff --git a/charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml b/charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml index a71249c..ca008e7 100644 --- a/charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml +++ b/charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml @@ -451,6 +451,18 @@ spec: type: string description: Annotations specifies annotations for the ingress. type: object + enableAccessLog: + description: |- + EnableAccessLog overrides the region-wide Envoy proxy access log setting + for this cluster: true forces it on, false forces it off, and unset + follows the region. + + The override matters in both directions. A single tenant can carry most + of a region's traffic, so "off" has to be expressible for one cluster + without giving up the log for every other cluster in that region; and + "on" has to be expressible for a cluster under investigation without + enabling the whole region. + type: boolean enabled: description: Enabled specifies whether to enable ingress for the cluster or not. diff --git a/crds/qdrant.io_qdrantclusters.yaml b/crds/qdrant.io_qdrantclusters.yaml index 3a2b691..48539c5 100644 --- a/crds/qdrant.io_qdrantclusters.yaml +++ b/crds/qdrant.io_qdrantclusters.yaml @@ -450,6 +450,18 @@ spec: type: string description: Annotations specifies annotations for the ingress. type: object + enableAccessLog: + description: |- + EnableAccessLog overrides the region-wide Envoy proxy access log setting + for this cluster: true forces it on, false forces it off, and unset + follows the region. + + The override matters in both directions. A single tenant can carry most + of a region's traffic, so "off" has to be expressible for one cluster + without giving up the log for every other cluster in that region; and + "on" has to be expressible for a cluster under investigation without + enabling the whole region. + type: boolean enabled: description: Enabled specifies whether to enable ingress for the cluster or not. diff --git a/docs/api.md b/docs/api.md index ad74936..92ced0a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -371,6 +371,7 @@ _Appears in:_ | `tlsSecretName` _string_ | TLSSecretName specifies the name of the secret containing the tls certificate. | | Optional: \{\}
| | `nginx` _[NGINXConfig](#nginxconfig)_ | NGINX specifies the nginx ingress specific configurations. | | Optional: \{\}
| | `traefik` _[TraefikConfig](#traefikconfig)_ | Traefik specifies the traefik ingress specific configurations. | | Optional: \{\}
| +| `enableAccessLog` _boolean_ | EnableAccessLog overrides the region-wide Envoy proxy access log setting
for this cluster: true forces it on, false forces it off, and unset
follows the region.
The override matters in both directions. A single tenant can carry most
of a region's traffic, so "off" has to be expressible for one cluster
without giving up the log for every other cluster in that region; and
"on" has to be expressible for a cluster under investigation without
enabling the whole region. | | Optional: \{\}
| #### KubernetesDistribution