From 93c6ea69fb877de999c9c95021d63a638aed4cf4 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Mon, 6 Jan 2025 16:54:28 -0800 Subject: [PATCH] Validate no duplicate targetRefs --- apis/v1alpha1/observabilitypolicy_types.go | 5 +- apis/v1alpha1/upstreamsettingspolicy_types.go | 3 + apis/v1alpha2/doc.go | 6 + apis/v1alpha2/observabilitypolicy_types.go | 139 ++++++ apis/v1alpha2/policy_methods.go | 21 + apis/v1alpha2/register.go | 42 ++ apis/v1alpha2/zz_generated.deepcopy.go | 130 +++++ ...teway.nginx.org_observabilitypolicies.yaml | 467 ++++++++++++++++- ...ay.nginx.org_upstreamsettingspolicies.yaml | 4 + deploy/crds.yaml | 471 +++++++++++++++++- docs/proposals/observability.md | 2 +- internal/mode/static/manager.go | 36 +- internal/mode/static/manager_test.go | 47 +- .../policies/clientsettings/generator_test.go | 77 +-- .../policies/observability/generator.go | 12 +- .../policies/observability/generator_test.go | 77 +-- .../policies/observability/validator.go | 32 +- .../policies/observability/validator_test.go | 65 +-- .../upstreamsettings/processor_test.go | 137 ++--- .../mode/static/state/change_processor.go | 17 +- .../static/state/change_processor_test.go | 96 ++-- .../static/state/dataplane/configuration.go | 25 +- .../state/dataplane/configuration_test.go | 333 +++++++------ .../state/graph/policy_ancestor_test.go | 4 +- site/content/how-to/monitoring/tracing.md | 2 +- site/content/overview/custom-policies.md | 3 +- site/content/reference/api.md | 327 +++++++++++- .../manifests/tracing/policy-multiple.yaml | 2 +- .../manifests/tracing/policy-single.yaml | 2 +- tests/suite/system_suite_test.go | 6 +- tests/suite/tracing_test.go | 7 +- 31 files changed, 2108 insertions(+), 489 deletions(-) create mode 100644 apis/v1alpha2/doc.go create mode 100644 apis/v1alpha2/observabilitypolicy_types.go create mode 100644 apis/v1alpha2/policy_methods.go create mode 100644 apis/v1alpha2/register.go create mode 100644 apis/v1alpha2/zz_generated.deepcopy.go diff --git a/apis/v1alpha1/observabilitypolicy_types.go b/apis/v1alpha1/observabilitypolicy_types.go index 99b09e4ff..2366a1fff 100644 --- a/apis/v1alpha1/observabilitypolicy_types.go +++ b/apis/v1alpha1/observabilitypolicy_types.go @@ -7,11 +7,12 @@ import ( // +genclient // +kubebuilder:object:root=true -// +kubebuilder:storageversion +// +kubebuilder:deprecatedversion:warning="The 'v1alpha1' version of ObservabilityPolicy API is deprecated, please migrate to 'v1alpha2'." // +kubebuilder:subresource:status // +kubebuilder:resource:categories=nginx-gateway-fabric,scope=Namespaced // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` // +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=direct" +//nolint:lll // ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for // the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the @@ -50,7 +51,7 @@ type ObservabilityPolicySpec struct { // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 // +kubebuilder:validation:XValidation:message="TargetRef Kind must be: HTTPRoute or GRPCRoute",rule="(self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute'))" - // +kubebuilder:validation:XValidation:message="TargetRef Group must be gateway.networking.k8s.io.",rule="self.all(t, t.group=='gateway.networking.k8s.io')" + // +kubebuilder:validation:XValidation:message="TargetRef Group must be gateway.networking.k8s.io",rule="self.all(t, t.group=='gateway.networking.k8s.io')" //nolint:lll TargetRefs []gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRefs"` } diff --git a/apis/v1alpha1/upstreamsettingspolicy_types.go b/apis/v1alpha1/upstreamsettingspolicy_types.go index f3276d0f6..158776491 100644 --- a/apis/v1alpha1/upstreamsettingspolicy_types.go +++ b/apis/v1alpha1/upstreamsettingspolicy_types.go @@ -55,10 +55,13 @@ type UpstreamSettingsPolicySpec struct { // Objects must be in the same namespace as the policy. // Support: Service // + // TargetRefs must be _distinct_. The `name` field must be unique for all targetRef entries in the UpstreamSettingsPolicy. + // // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 // +kubebuilder:validation:XValidation:message="TargetRefs Kind must be: Service",rule="self.all(t, t.kind=='Service')" // +kubebuilder:validation:XValidation:message="TargetRefs Group must be core",rule="self.exists(t, t.group=='') || self.exists(t, t.group=='core')" + // +kubebuilder:validation:XValidation:message="TargetRef Name must be unique",rule="self.all(p1, self.exists_one(p2, p1.name == p2.name))" //nolint:lll TargetRefs []gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRefs"` } diff --git a/apis/v1alpha2/doc.go b/apis/v1alpha2/doc.go new file mode 100644 index 000000000..6e93a89ac --- /dev/null +++ b/apis/v1alpha2/doc.go @@ -0,0 +1,6 @@ +// Package v1alpha2 contains API Schema definitions for the +// gateway.nginx.org API group. +// +// +kubebuilder:object:generate=true +// +groupName=gateway.nginx.org +package v1alpha2 diff --git a/apis/v1alpha2/observabilitypolicy_types.go b/apis/v1alpha2/observabilitypolicy_types.go new file mode 100644 index 000000000..d46b64ddd --- /dev/null +++ b/apis/v1alpha2/observabilitypolicy_types.go @@ -0,0 +1,139 @@ +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:subresource:status +// +kubebuilder:resource:categories=nginx-gateway-fabric,scope=Namespaced +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` +// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=direct" + +// ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for +// the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the +// GatewayClass parametersRef. +type ObservabilityPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the ObservabilityPolicy. + Spec ObservabilityPolicySpec `json:"spec"` + + // Status defines the state of the ObservabilityPolicy. + Status gatewayv1alpha2.PolicyStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ObservabilityPolicyList contains a list of ObservabilityPolicies. +type ObservabilityPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ObservabilityPolicy `json:"items"` +} + +// ObservabilityPolicySpec defines the desired state of the ObservabilityPolicy. +type ObservabilityPolicySpec struct { + // Tracing allows for enabling and configuring tracing. + // + // +optional + Tracing *Tracing `json:"tracing,omitempty"` + + // TargetRefs identifies the API object(s) to apply the policy to. + // Objects must be in the same namespace as the policy. + // Support: HTTPRoute, GRPCRoute. + // + // TargetRefs must be _distinct_. This means that the multi-part key defined by `kind` and `name` must + // be unique across all targetRef entries in the ObservabilityPolicy. + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 + // +kubebuilder:validation:XValidation:message="TargetRef Kind must be: HTTPRoute or GRPCRoute",rule="(self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute'))" + // +kubebuilder:validation:XValidation:message="TargetRef Group must be gateway.networking.k8s.io",rule="self.all(t, t.group=='gateway.networking.k8s.io')" + // +kubebuilder:validation:XValidation:message="TargetRef Kind and Name combination must be unique",rule="self.all(p1, self.exists_one(p2, (p1.name == p2.name) && (p1.kind == p2.kind)))" + //nolint:lll + TargetRefs []gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRefs"` +} + +// Tracing allows for enabling and configuring OpenTelemetry tracing. +// +// +kubebuilder:validation:XValidation:message="ratio can only be specified if strategy is of type ratio",rule="!(has(self.ratio) && self.strategy != 'ratio')" +// +//nolint:lll +type Tracing struct { + // Strategy defines if tracing is ratio-based or parent-based. + Strategy TraceStrategy `json:"strategy"` + + // Ratio is the percentage of traffic that should be sampled. Integer from 0 to 100. + // By default, 100% of http requests are traced. Not applicable for parent-based tracing. + // If ratio is set to 0, tracing is disabled. + // + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=100 + Ratio *int32 `json:"ratio,omitempty"` + + // Context specifies how to propagate traceparent/tracestate headers. + // Default: https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context + // + // +optional + Context *TraceContext `json:"context,omitempty"` + + // SpanName defines the name of the Otel span. By default is the name of the location for a request. + // If specified, applies to all locations that are created for a route. + // Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + // Examples of invalid names: some-$value, quoted-"value"-name, unescaped\ + // + // +optional + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=255 + // +kubebuilder:validation:Pattern=`^([^"$\\]|\\[^$])*$` + SpanName *string `json:"spanName,omitempty"` + + // SpanAttributes are custom key/value attributes that are added to each span. + // + // +optional + // +listType=map + // +listMapKey=key + // +kubebuilder:validation:MaxItems=64 + SpanAttributes []ngfAPIv1alpha1.SpanAttribute `json:"spanAttributes,omitempty"` +} + +// TraceStrategy defines the tracing strategy. +// +// +kubebuilder:validation:Enum=ratio;parent +type TraceStrategy string + +const ( + // TraceStrategyRatio enables ratio-based tracing, defaulting to 100% sampling rate. + TraceStrategyRatio TraceStrategy = "ratio" + + // TraceStrategyParent enables tracing and only records spans if the parent span was sampled. + TraceStrategyParent TraceStrategy = "parent" +) + +// TraceContext specifies how to propagate traceparent/tracestate headers. +// +// +kubebuilder:validation:Enum=extract;inject;propagate;ignore +type TraceContext string + +const ( + // TraceContextExtract uses an existing trace context from the request, so that the identifiers + // of a trace and the parent span are inherited from the incoming request. + TraceContextExtract TraceContext = "extract" + + // TraceContextInject adds a new context to the request, overwriting existing headers, if any. + TraceContextInject TraceContext = "inject" + + // TraceContextPropagate updates the existing context (combines extract and inject). + TraceContextPropagate TraceContext = "propagate" + + // TraceContextIgnore skips context headers processing. + TraceContextIgnore TraceContext = "ignore" +) diff --git a/apis/v1alpha2/policy_methods.go b/apis/v1alpha2/policy_methods.go new file mode 100644 index 000000000..8fc6dc768 --- /dev/null +++ b/apis/v1alpha2/policy_methods.go @@ -0,0 +1,21 @@ +package v1alpha2 + +import ( + "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +// FIXME(kate-osborn): https://github.com/nginxinc/nginx-gateway-fabric/issues/1939. +// Figure out a way to generate these methods for all our policies. +// These methods implement the policies.Policy interface which extends client.Object to add the following methods. + +func (p *ObservabilityPolicy) GetTargetRefs() []v1alpha2.LocalPolicyTargetReference { + return p.Spec.TargetRefs +} + +func (p *ObservabilityPolicy) GetPolicyStatus() v1alpha2.PolicyStatus { + return p.Status +} + +func (p *ObservabilityPolicy) SetPolicyStatus(status v1alpha2.PolicyStatus) { + p.Status = status +} diff --git a/apis/v1alpha2/register.go b/apis/v1alpha2/register.go new file mode 100644 index 000000000..23601e280 --- /dev/null +++ b/apis/v1alpha2/register.go @@ -0,0 +1,42 @@ +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName specifies the group name used to register the objects. +const GroupName = "gateway.nginx.org" + +// SchemeGroupVersion is group version used to register these objects. +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder collects functions that add things to a scheme. It's to allow + // code to compile without explicitly referencing generated types. You should + // declare one in each package that will have generated deep copy or conversion + // functions. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme applies all the stored functions to the scheme. A non-nil error + // indicates that one function failed and the attempt was abandoned. + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ObservabilityPolicy{}, + &ObservabilityPolicyList{}, + ) + // AddToGroupVersion allows the serialization of client types like ListOptions. + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + + return nil +} diff --git a/apis/v1alpha2/zz_generated.deepcopy.go b/apis/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 000000000..a8f1a87f9 --- /dev/null +++ b/apis/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,130 @@ +//go:build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + apisv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObservabilityPolicy) DeepCopyInto(out *ObservabilityPolicy) { + *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 ObservabilityPolicy. +func (in *ObservabilityPolicy) DeepCopy() *ObservabilityPolicy { + if in == nil { + return nil + } + out := new(ObservabilityPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObservabilityPolicy) 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 *ObservabilityPolicyList) DeepCopyInto(out *ObservabilityPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ObservabilityPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObservabilityPolicyList. +func (in *ObservabilityPolicyList) DeepCopy() *ObservabilityPolicyList { + if in == nil { + return nil + } + out := new(ObservabilityPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObservabilityPolicyList) 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 *ObservabilityPolicySpec) DeepCopyInto(out *ObservabilityPolicySpec) { + *out = *in + if in.Tracing != nil { + in, out := &in.Tracing, &out.Tracing + *out = new(Tracing) + (*in).DeepCopyInto(*out) + } + if in.TargetRefs != nil { + in, out := &in.TargetRefs, &out.TargetRefs + *out = make([]apisv1alpha2.LocalPolicyTargetReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObservabilityPolicySpec. +func (in *ObservabilityPolicySpec) DeepCopy() *ObservabilityPolicySpec { + if in == nil { + return nil + } + out := new(ObservabilityPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Tracing) DeepCopyInto(out *Tracing) { + *out = *in + if in.Ratio != nil { + in, out := &in.Ratio, &out.Ratio + *out = new(int32) + **out = **in + } + if in.Context != nil { + in, out := &in.Context, &out.Context + *out = new(TraceContext) + **out = **in + } + if in.SpanName != nil { + in, out := &in.SpanName, &out.SpanName + *out = new(string) + **out = **in + } + if in.SpanAttributes != nil { + in, out := &in.SpanAttributes, &out.SpanAttributes + *out = make([]v1alpha1.SpanAttribute, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tracing. +func (in *Tracing) DeepCopy() *Tracing { + if in == nil { + return nil + } + out := new(Tracing) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/gateway.nginx.org_observabilitypolicies.yaml b/config/crd/bases/gateway.nginx.org_observabilitypolicies.yaml index 8a27d8459..ff3d67c9b 100644 --- a/config/crd/bases/gateway.nginx.org_observabilitypolicies.yaml +++ b/config/crd/bases/gateway.nginx.org_observabilitypolicies.yaml @@ -22,6 +22,9 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date + deprecated: true + deprecationWarning: The 'v1alpha1' version of ObservabilityPolicy API is deprecated, + please migrate to 'v1alpha2'. name: v1alpha1 schema: openAPIV3Schema: @@ -90,7 +93,7 @@ spec: x-kubernetes-validations: - message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute' rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute')) - - message: TargetRef Group must be gateway.networking.k8s.io. + - message: TargetRef Group must be gateway.networking.k8s.io rule: self.all(t, t.group=='gateway.networking.k8s.io') tracing: description: Tracing allows for enabling and configuring tracing. @@ -471,6 +474,468 @@ spec: - spec type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for + the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the + GatewayClass parametersRef. + 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: Spec defines the desired state of the ObservabilityPolicy. + properties: + targetRefs: + description: |- + TargetRefs identifies the API object(s) to apply the policy to. + Objects must be in the same namespace as the policy. + Support: HTTPRoute, GRPCRoute. + + TargetRefs must be _distinct_. This means that the multi-part key defined by `kind` and `name` must + be unique across all targetRef entries in the ObservabilityPolicy. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-validations: + - message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute' + rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute')) + - message: TargetRef Group must be gateway.networking.k8s.io + rule: self.all(t, t.group=='gateway.networking.k8s.io') + - message: TargetRef Kind and Name combination must be unique + rule: self.all(p1, self.exists_one(p2, (p1.name == p2.name) && (p1.kind + == p2.kind))) + tracing: + description: Tracing allows for enabling and configuring tracing. + properties: + context: + description: |- + Context specifies how to propagate traceparent/tracestate headers. + Default: https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context + enum: + - extract + - inject + - propagate + - ignore + type: string + ratio: + description: |- + Ratio is the percentage of traffic that should be sampled. Integer from 0 to 100. + By default, 100% of http requests are traced. Not applicable for parent-based tracing. + If ratio is set to 0, tracing is disabled. + format: int32 + maximum: 100 + minimum: 0 + type: integer + spanAttributes: + description: SpanAttributes are custom key/value attributes that + are added to each span. + items: + description: SpanAttribute is a key value pair to be added to + a tracing span. + properties: + key: + description: |- + Key is the key for a span attribute. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + value: + description: |- + Value is the value for a span attribute. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + required: + - key + - value + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + spanName: + description: |- + SpanName defines the name of the Otel span. By default is the name of the location for a request. + If specified, applies to all locations that are created for a route. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + Examples of invalid names: some-$value, quoted-"value"-name, unescaped\ + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + strategy: + description: Strategy defines if tracing is ratio-based or parent-based. + enum: + - ratio + - parent + type: string + required: + - strategy + type: object + x-kubernetes-validations: + - message: ratio can only be specified if strategy is of type ratio + rule: '!(has(self.ratio) && self.strategy != ''ratio'')' + required: + - targetRefs + type: object + status: + description: Status defines the state of the ObservabilityPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true storage: true subresources: status: {} diff --git a/config/crd/bases/gateway.nginx.org_upstreamsettingspolicies.yaml b/config/crd/bases/gateway.nginx.org_upstreamsettingspolicies.yaml index 992af7993..455dd92b5 100644 --- a/config/crd/bases/gateway.nginx.org_upstreamsettingspolicies.yaml +++ b/config/crd/bases/gateway.nginx.org_upstreamsettingspolicies.yaml @@ -90,6 +90,8 @@ spec: TargetRefs identifies API object(s) to apply the policy to. Objects must be in the same namespace as the policy. Support: Service + + TargetRefs must be _distinct_. The `name` field must be unique for all targetRef entries in the UpstreamSettingsPolicy. items: description: |- LocalPolicyTargetReference identifies an API object to apply a direct or @@ -127,6 +129,8 @@ spec: rule: self.all(t, t.kind=='Service') - message: TargetRefs Group must be core rule: self.exists(t, t.group=='') || self.exists(t, t.group=='core') + - message: TargetRef Name must be unique + rule: self.all(p1, self.exists_one(p2, p1.name == p2.name)) zoneSize: description: |- ZoneSize is the size of the shared memory zone used by the upstream. This memory zone is used to share diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 5a9d708c6..01e4c8322 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -841,6 +841,9 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date + deprecated: true + deprecationWarning: The 'v1alpha1' version of ObservabilityPolicy API is deprecated, + please migrate to 'v1alpha2'. name: v1alpha1 schema: openAPIV3Schema: @@ -909,8 +912,470 @@ spec: x-kubernetes-validations: - message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute' rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute')) - - message: TargetRef Group must be gateway.networking.k8s.io. + - message: TargetRef Group must be gateway.networking.k8s.io + rule: self.all(t, t.group=='gateway.networking.k8s.io') + tracing: + description: Tracing allows for enabling and configuring tracing. + properties: + context: + description: |- + Context specifies how to propagate traceparent/tracestate headers. + Default: https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context + enum: + - extract + - inject + - propagate + - ignore + type: string + ratio: + description: |- + Ratio is the percentage of traffic that should be sampled. Integer from 0 to 100. + By default, 100% of http requests are traced. Not applicable for parent-based tracing. + If ratio is set to 0, tracing is disabled. + format: int32 + maximum: 100 + minimum: 0 + type: integer + spanAttributes: + description: SpanAttributes are custom key/value attributes that + are added to each span. + items: + description: SpanAttribute is a key value pair to be added to + a tracing span. + properties: + key: + description: |- + Key is the key for a span attribute. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + value: + description: |- + Value is the value for a span attribute. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + required: + - key + - value + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + spanName: + description: |- + SpanName defines the name of the Otel span. By default is the name of the location for a request. + If specified, applies to all locations that are created for a route. + Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\' + Examples of invalid names: some-$value, quoted-"value"-name, unescaped\ + maxLength: 255 + minLength: 1 + pattern: ^([^"$\\]|\\[^$])*$ + type: string + strategy: + description: Strategy defines if tracing is ratio-based or parent-based. + enum: + - ratio + - parent + type: string + required: + - strategy + type: object + x-kubernetes-validations: + - message: ratio can only be specified if strategy is of type ratio + rule: '!(has(self.ratio) && self.strategy != ''ratio'')' + required: + - targetRefs + type: object + status: + description: Status defines the state of the ObservabilityPolicy. + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: |- + ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for + the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the + GatewayClass parametersRef. + 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: Spec defines the desired state of the ObservabilityPolicy. + properties: + targetRefs: + description: |- + TargetRefs identifies the API object(s) to apply the policy to. + Objects must be in the same namespace as the policy. + Support: HTTPRoute, GRPCRoute. + + TargetRefs must be _distinct_. This means that the multi-part key defined by `kind` and `name` must + be unique across all targetRef entries in the ObservabilityPolicy. + items: + description: |- + LocalPolicyTargetReference identifies an API object to apply a direct or + inherited policy to. This should be used as part of Policy resources + that can target Gateway API resources. For more information on how this + policy attachment model works, and a sample Policy resource, refer to + the policy attachment documentation for Gateway API. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + maxItems: 16 + minItems: 1 + type: array + x-kubernetes-validations: + - message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute' + rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute')) + - message: TargetRef Group must be gateway.networking.k8s.io rule: self.all(t, t.group=='gateway.networking.k8s.io') + - message: TargetRef Kind and Name combination must be unique + rule: self.all(p1, self.exists_one(p2, (p1.name == p2.name) && (p1.kind + == p2.kind))) tracing: description: Tracing allows for enabling and configuring tracing. properties: @@ -1574,6 +2039,8 @@ spec: TargetRefs identifies API object(s) to apply the policy to. Objects must be in the same namespace as the policy. Support: Service + + TargetRefs must be _distinct_. The `name` field must be unique for all targetRef entries in the UpstreamSettingsPolicy. items: description: |- LocalPolicyTargetReference identifies an API object to apply a direct or @@ -1611,6 +2078,8 @@ spec: rule: self.all(t, t.kind=='Service') - message: TargetRefs Group must be core rule: self.exists(t, t.group=='') || self.exists(t, t.group=='core') + - message: TargetRef Name must be unique + rule: self.all(p1, self.exists_one(p2, p1.name == p2.name)) zoneSize: description: |- ZoneSize is the size of the shared memory zone used by the upstream. This memory zone is used to share diff --git a/docs/proposals/observability.md b/docs/proposals/observability.md index 71ed333cd..0d6952d62 100644 --- a/docs/proposals/observability.md +++ b/docs/proposals/observability.md @@ -148,7 +148,7 @@ type SpanAttribute struct { Below is an example YAML version of an `ObservabilityPolicy`: ```yaml -apiVersion: gateway.nginx.org/v1alpha1 +apiVersion: gateway.nginx.org/v1alpha2 kind: ObservabilityPolicy metadata: name: example-observability-policy diff --git a/internal/mode/static/manager.go b/internal/mode/static/manager.go index e5351f6a6..02ecd670e 100644 --- a/internal/mode/static/manager.go +++ b/internal/mode/static/manager.go @@ -34,7 +34,8 @@ import ( gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/controller" "github.com/nginx/nginx-gateway-fabric/internal/framework/controller/filter" "github.com/nginx/nginx-gateway-fabric/internal/framework/controller/index" @@ -83,7 +84,8 @@ func init() { utilruntime.Must(gatewayv1alpha2.Install(scheme)) utilruntime.Must(apiv1.AddToScheme(scheme)) utilruntime.Must(discoveryV1.AddToScheme(scheme)) - utilruntime.Must(ngfAPI.AddToScheme(scheme)) + utilruntime.Must(ngfAPIv1alpha1.AddToScheme(scheme)) + utilruntime.Must(ngfAPIv1alpha2.AddToScheme(scheme)) utilruntime.Must(apiext.AddToScheme(scheme)) utilruntime.Must(appsv1.AddToScheme(scheme)) } @@ -314,15 +316,15 @@ func createPolicyManager( ) *policies.CompositeValidator { cfgs := []policies.ManagerConfig{ { - GVK: mustExtractGVK(&ngfAPI.ClientSettingsPolicy{}), + GVK: mustExtractGVK(&ngfAPIv1alpha1.ClientSettingsPolicy{}), Validator: clientsettings.NewValidator(validator), }, { - GVK: mustExtractGVK(&ngfAPI.ObservabilityPolicy{}), + GVK: mustExtractGVK(&ngfAPIv1alpha2.ObservabilityPolicy{}), Validator: observability.NewValidator(validator), }, { - GVK: mustExtractGVK(&ngfAPI.UpstreamSettingsPolicy{}), + GVK: mustExtractGVK(&ngfAPIv1alpha1.UpstreamSettingsPolicy{}), Validator: upstreamsettings.NewValidator(validator), }, } @@ -483,7 +485,7 @@ func registerControllers( }, }, { - objectType: &ngfAPI.NginxProxy{}, + objectType: &ngfAPIv1alpha1.NginxProxy{}, options: []controller.Option{ controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}), }, @@ -495,19 +497,19 @@ func registerControllers( }, }, { - objectType: &ngfAPI.ClientSettingsPolicy{}, + objectType: &ngfAPIv1alpha1.ClientSettingsPolicy{}, options: []controller.Option{ controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}), }, }, { - objectType: &ngfAPI.ObservabilityPolicy{}, + objectType: &ngfAPIv1alpha2.ObservabilityPolicy{}, options: []controller.Option{ controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}), }, }, { - objectType: &ngfAPI.UpstreamSettingsPolicy{}, + objectType: &ngfAPIv1alpha1.UpstreamSettingsPolicy{}, options: []controller.Option{ controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}), }, @@ -540,7 +542,7 @@ func registerControllers( if cfg.ConfigName != "" { controllerRegCfgs = append(controllerRegCfgs, ctlrCfg{ - objectType: &ngfAPI.NginxGateway{}, + objectType: &ngfAPIv1alpha1.NginxGateway{}, options: []controller.Option{ controller.WithNamespacedNameFilter(filter.CreateSingleResourceFilter(controlConfigNSName)), }, @@ -559,7 +561,7 @@ func registerControllers( if cfg.SnippetsFilters { controllerRegCfgs = append(controllerRegCfgs, ctlrCfg{ - objectType: &ngfAPI.SnippetsFilter{}, + objectType: &ngfAPIv1alpha1.SnippetsFilter{}, options: []controller.Option{ controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}), }, @@ -744,11 +746,11 @@ func prepareFirstEventBatchPreparerArgs(cfg config.Config) ([]client.Object, []c &discoveryV1.EndpointSliceList{}, &gatewayv1.HTTPRouteList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, &gatewayv1.GRPCRouteList{}, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, partialObjectMetadataList, } @@ -764,7 +766,7 @@ func prepareFirstEventBatchPreparerArgs(cfg config.Config) ([]client.Object, []c if cfg.SnippetsFilters { objectLists = append( objectLists, - &ngfAPI.SnippetsFilterList{}, + &ngfAPIv1alpha1.SnippetsFilterList{}, ) } @@ -792,7 +794,7 @@ func setInitialConfig( ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - var conf ngfAPI.NginxGateway + var conf ngfAPIv1alpha1.NginxGateway // Polling to wait for CRD to exist if the Deployment is created first. if err := wait.PollUntilContextCancel( ctx, diff --git a/internal/mode/static/manager_test.go b/internal/mode/static/manager_test.go index 7c995f90b..5361be4de 100644 --- a/internal/mode/static/manager_test.go +++ b/internal/mode/static/manager_test.go @@ -19,7 +19,8 @@ import ( gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3" gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/state/graph" ) @@ -62,12 +63,12 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) { &gatewayv1.HTTPRouteList{}, &gatewayv1.GatewayList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, &gatewayv1.GRPCRouteList{}, partialObjectMetadataList, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, }, }, { @@ -92,12 +93,12 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) { &discoveryV1.EndpointSliceList{}, &gatewayv1.HTTPRouteList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, &gatewayv1.GRPCRouteList{}, partialObjectMetadataList, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, }, }, { @@ -123,14 +124,14 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) { &discoveryV1.EndpointSliceList{}, &gatewayv1.HTTPRouteList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, partialObjectMetadataList, &gatewayv1alpha3.BackendTLSPolicyList{}, &gatewayv1alpha2.TLSRouteList{}, &gatewayv1.GRPCRouteList{}, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, }, }, { @@ -155,13 +156,13 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) { &discoveryV1.EndpointSliceList{}, &gatewayv1.HTTPRouteList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, partialObjectMetadataList, &gatewayv1.GRPCRouteList{}, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.SnippetsFilterList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.SnippetsFilterList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, }, }, { @@ -187,15 +188,15 @@ func TestPrepareFirstEventBatchPreparerArgs(t *testing.T) { &discoveryV1.EndpointSliceList{}, &gatewayv1.HTTPRouteList{}, &gatewayv1beta1.ReferenceGrantList{}, - &ngfAPI.NginxProxyList{}, + &ngfAPIv1alpha1.NginxProxyList{}, partialObjectMetadataList, &gatewayv1alpha3.BackendTLSPolicyList{}, &gatewayv1alpha2.TLSRouteList{}, &gatewayv1.GRPCRouteList{}, - &ngfAPI.ClientSettingsPolicyList{}, - &ngfAPI.ObservabilityPolicyList{}, - &ngfAPI.SnippetsFilterList{}, - &ngfAPI.UpstreamSettingsPolicyList{}, + &ngfAPIv1alpha1.ClientSettingsPolicyList{}, + &ngfAPIv1alpha2.ObservabilityPolicyList{}, + &ngfAPIv1alpha1.SnippetsFilterList{}, + &ngfAPIv1alpha1.UpstreamSettingsPolicyList{}, }, }, } diff --git a/internal/mode/static/nginx/config/policies/clientsettings/generator_test.go b/internal/mode/static/nginx/config/policies/clientsettings/generator_test.go index ffc00bd29..e3370a4a5 100644 --- a/internal/mode/static/nginx/config/policies/clientsettings/generator_test.go +++ b/internal/mode/static/nginx/config/policies/clientsettings/generator_test.go @@ -5,7 +5,8 @@ import ( . "github.com/onsi/gomega" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/http" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -14,12 +15,12 @@ import ( func TestGenerate(t *testing.T) { t.Parallel() - maxSize := helpers.GetPointer[ngfAPI.Size]("10m") - bodyTimeout := helpers.GetPointer[ngfAPI.Duration]("600ms") + maxSize := helpers.GetPointer[ngfAPIv1alpha1.Size]("10m") + bodyTimeout := helpers.GetPointer[ngfAPIv1alpha1.Duration]("600ms") keepaliveRequests := helpers.GetPointer[int32](900) - keepaliveTime := helpers.GetPointer[ngfAPI.Duration]("50s") - keepaliveServerTimeout := helpers.GetPointer[ngfAPI.Duration]("30s") - keepaliveHeaderTimeout := helpers.GetPointer[ngfAPI.Duration]("60s") + keepaliveTime := helpers.GetPointer[ngfAPIv1alpha1.Duration]("50s") + keepaliveServerTimeout := helpers.GetPointer[ngfAPIv1alpha1.Duration]("30s") + keepaliveHeaderTimeout := helpers.GetPointer[ngfAPIv1alpha1.Duration]("60s") tests := []struct { name string @@ -28,9 +29,9 @@ func TestGenerate(t *testing.T) { }{ { name: "body max size populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - Body: &ngfAPI.ClientBody{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + Body: &ngfAPIv1alpha1.ClientBody{ MaxSize: maxSize, }, }, @@ -41,9 +42,9 @@ func TestGenerate(t *testing.T) { }, { name: "body timeout populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - Body: &ngfAPI.ClientBody{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + Body: &ngfAPIv1alpha1.ClientBody{ Timeout: bodyTimeout, }, }, @@ -54,9 +55,9 @@ func TestGenerate(t *testing.T) { }, { name: "keepalive requests populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - KeepAlive: &ngfAPI.ClientKeepAlive{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ Requests: keepaliveRequests, }, }, @@ -67,9 +68,9 @@ func TestGenerate(t *testing.T) { }, { name: "keepalive time populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - KeepAlive: &ngfAPI.ClientKeepAlive{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ Time: keepaliveTime, }, }, @@ -80,10 +81,10 @@ func TestGenerate(t *testing.T) { }, { name: "keepalive timeout server populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - KeepAlive: &ngfAPI.ClientKeepAlive{ - Timeout: &ngfAPI.ClientKeepAliveTimeout{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ + Timeout: &ngfAPIv1alpha1.ClientKeepAliveTimeout{ Server: keepaliveServerTimeout, }, }, @@ -95,10 +96,10 @@ func TestGenerate(t *testing.T) { }, { name: "keepalive timeout server and header populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - KeepAlive: &ngfAPI.ClientKeepAlive{ - Timeout: &ngfAPI.ClientKeepAliveTimeout{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ + Timeout: &ngfAPIv1alpha1.ClientKeepAliveTimeout{ Server: keepaliveServerTimeout, Header: keepaliveHeaderTimeout, }, @@ -111,10 +112,10 @@ func TestGenerate(t *testing.T) { }, { name: "keepalive timeout header populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - KeepAlive: &ngfAPI.ClientKeepAlive{ - Timeout: &ngfAPI.ClientKeepAliveTimeout{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ + Timeout: &ngfAPIv1alpha1.ClientKeepAliveTimeout{ Header: keepaliveHeaderTimeout, }, }, @@ -124,16 +125,16 @@ func TestGenerate(t *testing.T) { }, { name: "all fields populated", - policy: &ngfAPI.ClientSettingsPolicy{ - Spec: ngfAPI.ClientSettingsPolicySpec{ - Body: &ngfAPI.ClientBody{ + policy: &ngfAPIv1alpha1.ClientSettingsPolicy{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + Body: &ngfAPIv1alpha1.ClientBody{ MaxSize: maxSize, Timeout: bodyTimeout, }, - KeepAlive: &ngfAPI.ClientKeepAlive{ + KeepAlive: &ngfAPIv1alpha1.ClientKeepAlive{ Requests: keepaliveRequests, Time: keepaliveTime, - Timeout: &ngfAPI.ClientKeepAliveTimeout{ + Timeout: &ngfAPIv1alpha1.ClientKeepAliveTimeout{ Server: keepaliveServerTimeout, Header: keepaliveHeaderTimeout, }, @@ -186,18 +187,18 @@ func TestGenerateNoPolicies(t *testing.T) { resFiles := generator.GenerateForServer([]policies.Policy{}, http.Server{}) g.Expect(resFiles).To(BeEmpty()) - resFiles = generator.GenerateForServer([]policies.Policy{&ngfAPI.ObservabilityPolicy{}}, http.Server{}) + resFiles = generator.GenerateForServer([]policies.Policy{&ngfAPIv1alpha2.ObservabilityPolicy{}}, http.Server{}) g.Expect(resFiles).To(BeEmpty()) resFiles = generator.GenerateForLocation([]policies.Policy{}, http.Location{}) g.Expect(resFiles).To(BeEmpty()) - resFiles = generator.GenerateForLocation([]policies.Policy{&ngfAPI.ObservabilityPolicy{}}, http.Location{}) + resFiles = generator.GenerateForLocation([]policies.Policy{&ngfAPIv1alpha2.ObservabilityPolicy{}}, http.Location{}) g.Expect(resFiles).To(BeEmpty()) resFiles = generator.GenerateForInternalLocation([]policies.Policy{}) g.Expect(resFiles).To(BeEmpty()) - resFiles = generator.GenerateForInternalLocation([]policies.Policy{&ngfAPI.ObservabilityPolicy{}}) + resFiles = generator.GenerateForInternalLocation([]policies.Policy{&ngfAPIv1alpha2.ObservabilityPolicy{}}) g.Expect(resFiles).To(BeEmpty()) } diff --git a/internal/mode/static/nginx/config/policies/observability/generator.go b/internal/mode/static/nginx/config/policies/observability/generator.go index 261defeef..dc09e2d8e 100644 --- a/internal/mode/static/nginx/config/policies/observability/generator.go +++ b/internal/mode/static/nginx/config/policies/observability/generator.go @@ -4,7 +4,7 @@ import ( "fmt" "text/template" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/http" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -83,7 +83,7 @@ func (g Generator) GenerateForLocation(pols []policies.Policy, location http.Loc includeGlobalAttrs bool, ) policies.GenerateResultFiles { for _, pol := range pols { - obs, ok := pol.(*ngfAPI.ObservabilityPolicy) + obs, ok := pol.(*ngfAPIv1alpha2.ObservabilityPolicy) if !ok { continue } @@ -118,7 +118,7 @@ func (g Generator) GenerateForLocation(pols []policies.Policy, location http.Loc // being specified in the external location that redirects to the internal location. func (g Generator) GenerateForInternalLocation(pols []policies.Policy) policies.GenerateResultFiles { for _, pol := range pols { - obs, ok := pol.(*ngfAPI.ObservabilityPolicy) + obs, ok := pol.(*ngfAPIv1alpha2.ObservabilityPolicy) if !ok { continue } @@ -139,13 +139,13 @@ func (g Generator) GenerateForInternalLocation(pols []policies.Policy) policies. return nil } -func getStrategy(obs *ngfAPI.ObservabilityPolicy) string { +func getStrategy(obs *ngfAPIv1alpha2.ObservabilityPolicy) string { var strategy string if obs.Spec.Tracing != nil { switch obs.Spec.Tracing.Strategy { - case ngfAPI.TraceStrategyParent: + case ngfAPIv1alpha2.TraceStrategyParent: strategy = "$otel_parent_sampled" - case ngfAPI.TraceStrategyRatio: + case ngfAPIv1alpha2.TraceStrategyRatio: strategy = "on" if obs.Spec.Tracing.Ratio != nil { if *obs.Spec.Tracing.Ratio > 0 { diff --git a/internal/mode/static/nginx/config/policies/observability/generator_test.go b/internal/mode/static/nginx/config/policies/observability/generator_test.go index 03ad174cb..85785d8e0 100644 --- a/internal/mode/static/nginx/config/policies/observability/generator_test.go +++ b/internal/mode/static/nginx/config/policies/observability/generator_test.go @@ -6,7 +6,8 @@ import ( . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/http" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -18,7 +19,7 @@ func TestGenerate(t *testing.T) { t.Parallel() ratio := helpers.GetPointer[int32](25) zeroRatio := helpers.GetPointer[int32](0) - context := helpers.GetPointer[ngfAPI.TraceContext](ngfAPI.TraceContextExtract) + context := helpers.GetPointer[ngfAPIv1alpha2.TraceContext](ngfAPIv1alpha2.TraceContextExtract) spanName := helpers.GetPointer("my-span") tests := []struct { @@ -31,10 +32,10 @@ func TestGenerate(t *testing.T) { }{ { name: "strategy set to default ratio", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, }, }, }, @@ -50,14 +51,14 @@ func TestGenerate(t *testing.T) { }, { name: "strategy set to custom ratio", - policy: &ngfAPI.ObservabilityPolicy{ + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "test-policy", Namespace: "test-namespace", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, Ratio: ratio, }, }, @@ -74,14 +75,14 @@ func TestGenerate(t *testing.T) { }, { name: "strategy set to zero ratio", - policy: &ngfAPI.ObservabilityPolicy{ + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "test-policy", Namespace: "test-namespace", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, Ratio: zeroRatio, }, }, @@ -98,10 +99,10 @@ func TestGenerate(t *testing.T) { }, { name: "strategy set to parent", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyParent, + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyParent, }, }, }, @@ -117,9 +118,9 @@ func TestGenerate(t *testing.T) { }, { name: "context is set", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Context: context, }, }, @@ -138,9 +139,9 @@ func TestGenerate(t *testing.T) { }, { name: "spanName is set", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ SpanName: spanName, }, }, @@ -158,10 +159,10 @@ func TestGenerate(t *testing.T) { }, { name: "span attributes set", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - SpanAttributes: []ngfAPI.SpanAttribute{ + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + SpanAttributes: []ngfAPIv1alpha1.SpanAttribute{ {Key: "test-key", Value: "test-value"}, }, }, @@ -181,9 +182,9 @@ func TestGenerate(t *testing.T) { }, { name: "global span attributes set", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{}, + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{}, }, }, telemetryConf: dataplane.Telemetry{ @@ -205,13 +206,13 @@ func TestGenerate(t *testing.T) { }, { name: "all fields populated", - policy: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + policy: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, Context: context, SpanName: spanName, - SpanAttributes: []ngfAPI.SpanAttribute{ + SpanAttributes: []ngfAPIv1alpha1.SpanAttribute{ {Key: "test-key", Value: "test-value"}, }, }, @@ -290,12 +291,12 @@ func TestGenerateNoPolicies(t *testing.T) { resFiles := generator.GenerateForLocation([]policies.Policy{}, http.Location{}) g.Expect(resFiles).To(BeEmpty()) - resFiles = generator.GenerateForLocation([]policies.Policy{&ngfAPI.ClientSettingsPolicy{}}, http.Location{}) + resFiles = generator.GenerateForLocation([]policies.Policy{&ngfAPIv1alpha1.ClientSettingsPolicy{}}, http.Location{}) g.Expect(resFiles).To(BeEmpty()) resFiles = generator.GenerateForInternalLocation([]policies.Policy{}) g.Expect(resFiles).To(BeEmpty()) - resFiles = generator.GenerateForInternalLocation([]policies.Policy{&ngfAPI.ClientSettingsPolicy{}}) + resFiles = generator.GenerateForInternalLocation([]policies.Policy{&ngfAPIv1alpha1.ClientSettingsPolicy{}}) g.Expect(resFiles).To(BeEmpty()) } diff --git a/internal/mode/static/nginx/config/policies/observability/validator.go b/internal/mode/static/nginx/config/policies/observability/validator.go index 8cf43c478..4d7182e12 100644 --- a/internal/mode/static/nginx/config/policies/observability/validator.go +++ b/internal/mode/static/nginx/config/policies/observability/validator.go @@ -4,7 +4,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/conditions" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/framework/kinds" @@ -29,7 +29,7 @@ func (v *Validator) Validate( policy policies.Policy, globalSettings *policies.GlobalSettings, ) []conditions.Condition { - obs := helpers.MustCastObject[*ngfAPI.ObservabilityPolicy](policy) + obs := helpers.MustCastObject[*ngfAPIv1alpha2.ObservabilityPolicy](policy) if globalSettings == nil || !globalSettings.NginxProxyValid { return []conditions.Condition{ @@ -62,13 +62,13 @@ func (v *Validator) Validate( // Conflicts returns true if the two ObservabilityPolicies conflict. func (v *Validator) Conflicts(polA, polB policies.Policy) bool { - a := helpers.MustCastObject[*ngfAPI.ObservabilityPolicy](polA) - b := helpers.MustCastObject[*ngfAPI.ObservabilityPolicy](polB) + a := helpers.MustCastObject[*ngfAPIv1alpha2.ObservabilityPolicy](polA) + b := helpers.MustCastObject[*ngfAPIv1alpha2.ObservabilityPolicy](polB) return a.Spec.Tracing != nil && b.Spec.Tracing != nil } -func (v *Validator) validateSettings(spec ngfAPI.ObservabilityPolicySpec) error { +func (v *Validator) validateSettings(spec ngfAPIv1alpha2.ObservabilityPolicySpec) error { var allErrs field.ErrorList fieldPath := field.NewPath("spec") @@ -76,7 +76,7 @@ func (v *Validator) validateSettings(spec ngfAPI.ObservabilityPolicySpec) error tracePath := fieldPath.Child("tracing") switch spec.Tracing.Strategy { - case ngfAPI.TraceStrategyRatio, ngfAPI.TraceStrategyParent: + case ngfAPIv1alpha2.TraceStrategyRatio, ngfAPIv1alpha2.TraceStrategyParent: default: allErrs = append( allErrs, @@ -84,18 +84,18 @@ func (v *Validator) validateSettings(spec ngfAPI.ObservabilityPolicySpec) error tracePath.Child("strategy"), spec.Tracing.Strategy, []string{ - string(ngfAPI.TraceStrategyRatio), - string(ngfAPI.TraceStrategyParent), + string(ngfAPIv1alpha2.TraceStrategyRatio), + string(ngfAPIv1alpha2.TraceStrategyParent), }), ) } if spec.Tracing.Context != nil { switch *spec.Tracing.Context { - case ngfAPI.TraceContextExtract, - ngfAPI.TraceContextInject, - ngfAPI.TraceContextPropagate, - ngfAPI.TraceContextIgnore: + case ngfAPIv1alpha2.TraceContextExtract, + ngfAPIv1alpha2.TraceContextInject, + ngfAPIv1alpha2.TraceContextPropagate, + ngfAPIv1alpha2.TraceContextIgnore: default: allErrs = append( allErrs, @@ -103,10 +103,10 @@ func (v *Validator) validateSettings(spec ngfAPI.ObservabilityPolicySpec) error tracePath.Child("context"), spec.Tracing.Context, []string{ - string(ngfAPI.TraceContextExtract), - string(ngfAPI.TraceContextInject), - string(ngfAPI.TraceContextPropagate), - string(ngfAPI.TraceContextIgnore), + string(ngfAPIv1alpha2.TraceContextExtract), + string(ngfAPIv1alpha2.TraceContextInject), + string(ngfAPIv1alpha2.TraceContextPropagate), + string(ngfAPIv1alpha2.TraceContextIgnore), }), ) } diff --git a/internal/mode/static/nginx/config/policies/observability/validator_test.go b/internal/mode/static/nginx/config/policies/observability/validator_test.go index 679906a39..5b0894110 100644 --- a/internal/mode/static/nginx/config/policies/observability/validator_test.go +++ b/internal/mode/static/nginx/config/policies/observability/validator_test.go @@ -8,7 +8,8 @@ import ( gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/conditions" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/framework/kinds" @@ -19,14 +20,14 @@ import ( staticConds "github.com/nginx/nginx-gateway-fabric/internal/mode/static/state/conditions" ) -type policyModFunc func(policy *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy +type policyModFunc func(policy *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy -func createValidPolicy() *ngfAPI.ObservabilityPolicy { - return &ngfAPI.ObservabilityPolicy{ +func createValidPolicy() *ngfAPIv1alpha2.ObservabilityPolicy { + return &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", }, - Spec: ngfAPI.ObservabilityPolicySpec{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ TargetRefs: []v1alpha2.LocalPolicyTargetReference{ { Group: gatewayv1.GroupName, @@ -34,11 +35,11 @@ func createValidPolicy() *ngfAPI.ObservabilityPolicy { Name: "route", }, }, - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, - Context: helpers.GetPointer(ngfAPI.TraceContextExtract), + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, + Context: helpers.GetPointer(ngfAPIv1alpha2.TraceContextExtract), SpanName: helpers.GetPointer("spanName"), - SpanAttributes: []ngfAPI.SpanAttribute{ + SpanAttributes: []ngfAPIv1alpha1.SpanAttribute{ {Key: "key", Value: "value"}, }, }, @@ -47,7 +48,7 @@ func createValidPolicy() *ngfAPI.ObservabilityPolicy { } } -func createModifiedPolicy(mod policyModFunc) *ngfAPI.ObservabilityPolicy { +func createModifiedPolicy(mod policyModFunc) *ngfAPIv1alpha2.ObservabilityPolicy { return mod(createValidPolicy()) } @@ -60,7 +61,7 @@ func TestValidator_Validate(t *testing.T) { tests := []struct { name string - policy *ngfAPI.ObservabilityPolicy + policy *ngfAPIv1alpha2.ObservabilityPolicy globalSettings *policies.GlobalSettings expConditions []conditions.Condition }{ @@ -89,7 +90,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid target ref; unsupported group", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.TargetRefs[0].Group = "Unsupported" return p }), @@ -101,7 +102,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid target ref; unsupported kind", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.TargetRefs[0].Kind = "Unsupported" return p }), @@ -113,7 +114,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid strategy", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.Tracing.Strategy = "invalid" return p }), @@ -125,8 +126,8 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid context", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { - p.Spec.Tracing.Context = helpers.GetPointer[ngfAPI.TraceContext]("invalid") + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { + p.Spec.Tracing.Context = helpers.GetPointer[ngfAPIv1alpha2.TraceContext]("invalid") return p }), globalSettings: globalSettings, @@ -137,7 +138,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid span name", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.Tracing.SpanName = helpers.GetPointer("invalid$$$") return p }), @@ -150,7 +151,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid span attribute key", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.Tracing.SpanAttributes[0].Key = "invalid$$$" return p }), @@ -163,7 +164,7 @@ func TestValidator_Validate(t *testing.T) { }, { name: "invalid span attribute value", - policy: createModifiedPolicy(func(p *ngfAPI.ObservabilityPolicy) *ngfAPI.ObservabilityPolicy { + policy: createModifiedPolicy(func(p *ngfAPIv1alpha2.ObservabilityPolicy) *ngfAPIv1alpha2.ObservabilityPolicy { p.Spec.Tracing.SpanAttributes[0].Value = "invalid$$$" return p }), @@ -211,33 +212,33 @@ func TestValidator_ValidatePanics(t *testing.T) { func TestValidator_Conflicts(t *testing.T) { t.Parallel() tests := []struct { - polA *ngfAPI.ObservabilityPolicy - polB *ngfAPI.ObservabilityPolicy + polA *ngfAPIv1alpha2.ObservabilityPolicy + polB *ngfAPIv1alpha2.ObservabilityPolicy name string conflicts bool }{ { name: "no conflicts", - polA: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{}, + polA: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{}, }, }, - polB: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{}, + polB: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{}, }, conflicts: false, }, { name: "conflicts", - polA: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{}, + polA: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{}, }, }, - polB: &ngfAPI.ObservabilityPolicy{ - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{}, + polB: &ngfAPIv1alpha2.ObservabilityPolicy{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{}, }, }, conflicts: true, diff --git a/internal/mode/static/nginx/config/policies/upstreamsettings/processor_test.go b/internal/mode/static/nginx/config/policies/upstreamsettings/processor_test.go index 835dfe8ee..80ca82b7b 100644 --- a/internal/mode/static/nginx/config/policies/upstreamsettings/processor_test.go +++ b/internal/mode/static/nginx/config/policies/upstreamsettings/processor_test.go @@ -6,7 +6,8 @@ import ( . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/http" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -23,18 +24,18 @@ func TestProcess(t *testing.T) { { name: "all fields populated", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - ZoneSize: helpers.GetPointer[ngfAPI.Size]("2m"), - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + ZoneSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("2m"), + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Connections: helpers.GetPointer(int32(1)), Requests: helpers.GetPointer(int32(1)), - Time: helpers.GetPointer[ngfAPI.Duration]("5s"), - Timeout: helpers.GetPointer[ngfAPI.Duration]("10s"), + Time: helpers.GetPointer[ngfAPIv1alpha1.Duration]("5s"), + Timeout: helpers.GetPointer[ngfAPIv1alpha1.Duration]("10s"), }), }, }, @@ -52,13 +53,13 @@ func TestProcess(t *testing.T) { { name: "zone size set", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - ZoneSize: helpers.GetPointer[ngfAPI.Size]("2m"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + ZoneSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("2m"), }, }, }, @@ -69,13 +70,13 @@ func TestProcess(t *testing.T) { { name: "keep alive connections set", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Connections: helpers.GetPointer(int32(1)), }), }, @@ -90,13 +91,13 @@ func TestProcess(t *testing.T) { { name: "keep alive requests set", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Requests: helpers.GetPointer(int32(1)), }), }, @@ -111,14 +112,14 @@ func TestProcess(t *testing.T) { { name: "keep alive time set", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Time: helpers.GetPointer[ngfAPI.Duration]("5s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Time: helpers.GetPointer[ngfAPIv1alpha1.Duration]("5s"), }), }, }, @@ -132,14 +133,14 @@ func TestProcess(t *testing.T) { { name: "keep alive timeout set", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Timeout: helpers.GetPointer[ngfAPI.Duration]("10s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Timeout: helpers.GetPointer[ngfAPIv1alpha1.Duration]("10s"), }), }, }, @@ -153,12 +154,12 @@ func TestProcess(t *testing.T) { { name: "no fields populated", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{}, + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{}, }, }, expUpstreamSettings: UpstreamSettings{}, @@ -166,56 +167,56 @@ func TestProcess(t *testing.T) { { name: "multiple UpstreamSettingsPolicies", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-zonesize", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - ZoneSize: helpers.GetPointer[ngfAPI.Size]("2m"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + ZoneSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("2m"), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-connections", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Connections: helpers.GetPointer(int32(1)), }), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-requests", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Requests: helpers.GetPointer(int32(1)), }), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-time", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Time: helpers.GetPointer[ngfAPI.Duration]("5s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Time: helpers.GetPointer[ngfAPIv1alpha1.Duration]("5s"), }), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-timeout", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Timeout: helpers.GetPointer[ngfAPI.Duration]("10s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Timeout: helpers.GetPointer[ngfAPIv1alpha1.Duration]("10s"), }), }, }, @@ -233,78 +234,78 @@ func TestProcess(t *testing.T) { { name: "multiple UpstreamSettingsPolicies along with other policies", policies: []policies.Policy{ - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-zonesize", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - ZoneSize: helpers.GetPointer[ngfAPI.Size]("2m"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + ZoneSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("2m"), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-connections", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Connections: helpers.GetPointer(int32(1)), }), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-requests", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ Requests: helpers.GetPointer(int32(1)), }), }, }, - &ngfAPI.ClientSettingsPolicy{ + &ngfAPIv1alpha1.ClientSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "client-settings-policy", Namespace: "test", }, - Spec: ngfAPI.ClientSettingsPolicySpec{ - Body: &ngfAPI.ClientBody{ - MaxSize: helpers.GetPointer[ngfAPI.Size]("1m"), + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ + Body: &ngfAPIv1alpha1.ClientBody{ + MaxSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("1m"), }, }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-time", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Time: helpers.GetPointer[ngfAPI.Duration]("5s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Time: helpers.GetPointer[ngfAPIv1alpha1.Duration]("5s"), }), }, }, - &ngfAPI.UpstreamSettingsPolicy{ + &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp-keepalive-timeout", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - KeepAlive: helpers.GetPointer(ngfAPI.UpstreamKeepAlive{ - Timeout: helpers.GetPointer[ngfAPI.Duration]("10s"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + KeepAlive: helpers.GetPointer(ngfAPIv1alpha1.UpstreamKeepAlive{ + Timeout: helpers.GetPointer[ngfAPIv1alpha1.Duration]("10s"), }), }, }, - &ngfAPI.ObservabilityPolicy{ + &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "observability-policy", Namespace: "test", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, Ratio: helpers.GetPointer(int32(1)), }, }, diff --git a/internal/mode/static/state/change_processor.go b/internal/mode/static/state/change_processor.go index 9992c7291..61d6475d9 100644 --- a/internal/mode/static/state/change_processor.go +++ b/internal/mode/static/state/change_processor.go @@ -16,7 +16,8 @@ import ( "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/apis/v1beta1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/gatewayclass" "github.com/nginx/nginx-gateway-fabric/internal/framework/kinds" ngftypes "github.com/nginx/nginx-gateway-fabric/internal/framework/types" @@ -108,11 +109,11 @@ func NewChangeProcessorImpl(cfg ChangeProcessorConfig) *ChangeProcessorImpl { CRDMetadata: make(map[types.NamespacedName]*metav1.PartialObjectMetadata), BackendTLSPolicies: make(map[types.NamespacedName]*v1alpha3.BackendTLSPolicy), ConfigMaps: make(map[types.NamespacedName]*apiv1.ConfigMap), - NginxProxies: make(map[types.NamespacedName]*ngfAPI.NginxProxy), + NginxProxies: make(map[types.NamespacedName]*ngfAPIv1alpha1.NginxProxy), GRPCRoutes: make(map[types.NamespacedName]*v1.GRPCRoute), TLSRoutes: make(map[types.NamespacedName]*v1alpha2.TLSRoute), NGFPolicies: make(map[graph.PolicyKey]policies.Policy), - SnippetsFilters: make(map[types.NamespacedName]*ngfAPI.SnippetsFilter), + SnippetsFilters: make(map[types.NamespacedName]*ngfAPIv1alpha1.SnippetsFilter), } processor := &ChangeProcessorImpl{ @@ -202,22 +203,22 @@ func NewChangeProcessorImpl(cfg ChangeProcessorConfig) *ChangeProcessorImpl { predicate: annotationChangedPredicate{annotation: gatewayclass.BundleVersionAnnotation}, }, { - gvk: cfg.MustExtractGVK(&ngfAPI.NginxProxy{}), + gvk: cfg.MustExtractGVK(&ngfAPIv1alpha1.NginxProxy{}), store: newObjectStoreMapAdapter(clusterStore.NginxProxies), predicate: funcPredicate{stateChanged: isReferenced}, }, { - gvk: cfg.MustExtractGVK(&ngfAPI.ClientSettingsPolicy{}), + gvk: cfg.MustExtractGVK(&ngfAPIv1alpha1.ClientSettingsPolicy{}), store: commonPolicyObjectStore, predicate: funcPredicate{stateChanged: isNGFPolicyRelevant}, }, { - gvk: cfg.MustExtractGVK(&ngfAPI.ObservabilityPolicy{}), + gvk: cfg.MustExtractGVK(&ngfAPIv1alpha2.ObservabilityPolicy{}), store: commonPolicyObjectStore, predicate: funcPredicate{stateChanged: isNGFPolicyRelevant}, }, { - gvk: cfg.MustExtractGVK(&ngfAPI.UpstreamSettingsPolicy{}), + gvk: cfg.MustExtractGVK(&ngfAPIv1alpha1.UpstreamSettingsPolicy{}), store: commonPolicyObjectStore, predicate: funcPredicate{stateChanged: isNGFPolicyRelevant}, }, @@ -227,7 +228,7 @@ func NewChangeProcessorImpl(cfg ChangeProcessorConfig) *ChangeProcessorImpl { predicate: nil, }, { - gvk: cfg.MustExtractGVK(&ngfAPI.SnippetsFilter{}), + gvk: cfg.MustExtractGVK(&ngfAPIv1alpha1.SnippetsFilter{}), store: newObjectStoreMapAdapter(clusterStore.SnippetsFilters), predicate: nil, // we always want to write status to SnippetsFilters so we don't filter them out }, diff --git a/internal/mode/static/state/change_processor_test.go b/internal/mode/static/state/change_processor_test.go index b61de8672..7211a5f04 100644 --- a/internal/mode/static/state/change_processor_test.go +++ b/internal/mode/static/state/change_processor_test.go @@ -19,7 +19,8 @@ import ( "sigs.k8s.io/gateway-api/apis/v1alpha3" "sigs.k8s.io/gateway-api/apis/v1beta1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/conditions" "github.com/nginx/nginx-gateway-fabric/internal/framework/controller/index" "github.com/nginx/nginx-gateway-fabric/internal/framework/gatewayclass" @@ -326,7 +327,8 @@ func createScheme() *runtime.Scheme { utilruntime.Must(apiv1.AddToScheme(scheme)) utilruntime.Must(discoveryV1.AddToScheme(scheme)) utilruntime.Must(apiext.AddToScheme(scheme)) - utilruntime.Must(ngfAPI.AddToScheme(scheme)) + utilruntime.Must(ngfAPIv1alpha1.AddToScheme(scheme)) + utilruntime.Must(ngfAPIv1alpha2.AddToScheme(scheme)) return scheme } @@ -2291,28 +2293,28 @@ var _ = Describe("ChangeProcessor", func() { Describe("NginxProxy resource changes", Ordered, func() { paramGC := gc.DeepCopy() paramGC.Spec.ParametersRef = &v1beta1.ParametersReference{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.NginxProxy, Name: "np", } - np := &ngfAPI.NginxProxy{ + np := &ngfAPIv1alpha1.NginxProxy{ ObjectMeta: metav1.ObjectMeta{ Name: "np", }, } - npUpdated := &ngfAPI.NginxProxy{ + npUpdated := &ngfAPIv1alpha1.NginxProxy{ ObjectMeta: metav1.ObjectMeta{ Name: "np", }, - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{ - Exporter: &ngfAPI.TelemetryExporter{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{ + Exporter: &ngfAPIv1alpha1.TelemetryExporter{ Endpoint: "my-svc:123", BatchSize: helpers.GetPointer(int32(512)), BatchCount: helpers.GetPointer(int32(4)), - Interval: helpers.GetPointer(ngfAPI.Duration("5s")), + Interval: helpers.GetPointer(ngfAPIv1alpha1.Duration("5s")), }, }, }, @@ -2347,9 +2349,9 @@ var _ = Describe("ChangeProcessor", func() { gw *v1.Gateway route *v1.HTTPRoute svc *apiv1.Service - csp, cspUpdated *ngfAPI.ClientSettingsPolicy - obs, obsUpdated *ngfAPI.ObservabilityPolicy - usp, uspUpdated *ngfAPI.UpstreamSettingsPolicy + csp, cspUpdated *ngfAPIv1alpha1.ClientSettingsPolicy + obs, obsUpdated *ngfAPIv1alpha2.ObservabilityPolicy + usp, uspUpdated *ngfAPIv1alpha1.UpstreamSettingsPolicy cspKey, obsKey, uspKey graph.PolicyKey ) @@ -2384,41 +2386,41 @@ var _ = Describe("ChangeProcessor", func() { }, } - csp = &ngfAPI.ClientSettingsPolicy{ + csp = &ngfAPIv1alpha1.ClientSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "csp", Namespace: "test", }, - Spec: ngfAPI.ClientSettingsPolicySpec{ + Spec: ngfAPIv1alpha1.ClientSettingsPolicySpec{ TargetRef: v1alpha2.LocalPolicyTargetReference{ Group: v1.GroupName, Kind: kinds.Gateway, Name: "gw", }, - Body: &ngfAPI.ClientBody{ - MaxSize: helpers.GetPointer[ngfAPI.Size]("10m"), + Body: &ngfAPIv1alpha1.ClientBody{ + MaxSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("10m"), }, }, } cspUpdated = csp.DeepCopy() - cspUpdated.Spec.Body.MaxSize = helpers.GetPointer[ngfAPI.Size]("20m") + cspUpdated.Spec.Body.MaxSize = helpers.GetPointer[ngfAPIv1alpha1.Size]("20m") cspKey = graph.PolicyKey{ NsName: types.NamespacedName{Name: "csp", Namespace: "test"}, GVK: schema.GroupVersionKind{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.ClientSettingsPolicy, Version: "v1alpha1", }, } - obs = &ngfAPI.ObservabilityPolicy{ + obs = &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obs", Namespace: "test", }, - Spec: ngfAPI.ObservabilityPolicySpec{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ TargetRefs: []v1alpha2.LocalPolicyTargetReference{ { Group: v1.GroupName, @@ -2426,31 +2428,31 @@ var _ = Describe("ChangeProcessor", func() { Name: "hr-1", }, }, - Tracing: &ngfAPI.Tracing{ - Strategy: ngfAPI.TraceStrategyRatio, + Tracing: &ngfAPIv1alpha2.Tracing{ + Strategy: ngfAPIv1alpha2.TraceStrategyRatio, }, }, } obsUpdated = obs.DeepCopy() - obsUpdated.Spec.Tracing.Strategy = ngfAPI.TraceStrategyParent + obsUpdated.Spec.Tracing.Strategy = ngfAPIv1alpha2.TraceStrategyParent obsKey = graph.PolicyKey{ NsName: types.NamespacedName{Name: "obs", Namespace: "test"}, GVK: schema.GroupVersionKind{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.ObservabilityPolicy, - Version: "v1alpha1", + Version: "v1alpha2", }, } - usp = &ngfAPI.UpstreamSettingsPolicy{ + usp = &ngfAPIv1alpha1.UpstreamSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "usp", Namespace: "test", }, - Spec: ngfAPI.UpstreamSettingsPolicySpec{ - ZoneSize: helpers.GetPointer[ngfAPI.Size]("10m"), + Spec: ngfAPIv1alpha1.UpstreamSettingsPolicySpec{ + ZoneSize: helpers.GetPointer[ngfAPIv1alpha1.Size]("10m"), TargetRefs: []v1alpha2.LocalPolicyTargetReference{ { Group: "core", @@ -2462,12 +2464,12 @@ var _ = Describe("ChangeProcessor", func() { } uspUpdated = usp.DeepCopy() - uspUpdated.Spec.ZoneSize = helpers.GetPointer[ngfAPI.Size]("20m") + uspUpdated.Spec.ZoneSize = helpers.GetPointer[ngfAPIv1alpha1.Size]("20m") uspKey = graph.PolicyKey{ NsName: types.NamespacedName{Name: "usp", Namespace: "test"}, GVK: schema.GroupVersionKind{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.UpstreamSettingsPolicy, Version: "v1alpha1", }, @@ -2531,9 +2533,9 @@ var _ = Describe("ChangeProcessor", func() { }) When("the policy is deleted", func() { It("removes the policy from the graph", func() { - processor.CaptureDeleteChange(&ngfAPI.ClientSettingsPolicy{}, client.ObjectKeyFromObject(csp)) - processor.CaptureDeleteChange(&ngfAPI.ObservabilityPolicy{}, client.ObjectKeyFromObject(obs)) - processor.CaptureDeleteChange(&ngfAPI.UpstreamSettingsPolicy{}, client.ObjectKeyFromObject(usp)) + processor.CaptureDeleteChange(&ngfAPIv1alpha1.ClientSettingsPolicy{}, client.ObjectKeyFromObject(csp)) + processor.CaptureDeleteChange(&ngfAPIv1alpha2.ObservabilityPolicy{}, client.ObjectKeyFromObject(obs)) + processor.CaptureDeleteChange(&ngfAPIv1alpha1.UpstreamSettingsPolicy{}, client.ObjectKeyFromObject(usp)) changed, graph := processor.Process() Expect(changed).To(Equal(state.ClusterStateChange)) @@ -2548,34 +2550,34 @@ var _ = Describe("ChangeProcessor", func() { Namespace: "test", } - sf := &ngfAPI.SnippetsFilter{ + sf := &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: sfNsName.Name, Namespace: sfNsName.Namespace, }, - Spec: ngfAPI.SnippetsFilterSpec{ - Snippets: []ngfAPI.Snippet{ + Spec: ngfAPIv1alpha1.SnippetsFilterSpec{ + Snippets: []ngfAPIv1alpha1.Snippet{ { - Context: ngfAPI.NginxContextMain, + Context: ngfAPIv1alpha1.NginxContextMain, Value: "main snippet", }, }, }, } - sfUpdated := &ngfAPI.SnippetsFilter{ + sfUpdated := &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: sfNsName.Name, Namespace: sfNsName.Namespace, }, - Spec: ngfAPI.SnippetsFilterSpec{ - Snippets: []ngfAPI.Snippet{ + Spec: ngfAPIv1alpha1.SnippetsFilterSpec{ + Snippets: []ngfAPIv1alpha1.Snippet{ { - Context: ngfAPI.NginxContextMain, + Context: ngfAPIv1alpha1.NginxContextMain, Value: "main snippet", }, { - Context: ngfAPI.NginxContextHTTP, + Context: ngfAPIv1alpha1.NginxContextHTTP, Value: "http snippet", }, }, @@ -2631,7 +2633,7 @@ var _ = Describe("ChangeProcessor", func() { secret, secretUpdated, unrelatedSecret, barSecret, barSecretUpdated *apiv1.Secret cm, cmUpdated, unrelatedCM *apiv1.ConfigMap btls, btlsUpdated *v1alpha3.BackendTLSPolicy - np, npUpdated *ngfAPI.NginxProxy + np, npUpdated *ngfAPIv1alpha1.NginxProxy ) BeforeEach(OncePerOrdered, func() { @@ -2930,12 +2932,12 @@ var _ = Describe("ChangeProcessor", func() { btlsUpdated = btls.DeepCopy() npNsName = types.NamespacedName{Name: "np-1"} - np = &ngfAPI.NginxProxy{ + np = &ngfAPIv1alpha1.NginxProxy{ ObjectMeta: metav1.ObjectMeta{ Name: npNsName.Name, }, - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{ ServiceName: helpers.GetPointer("my-svc"), }, }, @@ -3010,7 +3012,7 @@ var _ = Describe("ChangeProcessor", func() { processor.CaptureDeleteChange(&v1beta1.ReferenceGrant{}, rgNsName) processor.CaptureDeleteChange(&v1alpha3.BackendTLSPolicy{}, btlsNsName) processor.CaptureDeleteChange(&apiv1.ConfigMap{}, cmNsName) - processor.CaptureDeleteChange(&ngfAPI.NginxProxy{}, npNsName) + processor.CaptureDeleteChange(&ngfAPIv1alpha1.NginxProxy{}, npNsName) // these are non-changing changes processor.CaptureUpsertChange(gw2) diff --git a/internal/mode/static/state/dataplane/configuration.go b/internal/mode/static/state/dataplane/configuration.go index 68a46387f..33324dbf4 100644 --- a/internal/mode/static/state/dataplane/configuration.go +++ b/internal/mode/static/state/dataplane/configuration.go @@ -13,7 +13,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" v1 "sigs.k8s.io/gateway-api/apis/v1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/state/graph" @@ -62,7 +63,7 @@ func BuildConfiguration( Telemetry: buildTelemetry(g), BaseHTTPConfig: baseHTTPConfig, Logging: buildLogging(g), - MainSnippets: buildSnippetsForContext(g.SnippetsFilters, ngfAPI.NginxContextMain), + MainSnippets: buildSnippetsForContext(g.SnippetsFilters, ngfAPIv1alpha1.NginxContextMain), AuxiliarySecrets: buildAuxiliarySecrets(g.PlusSecrets), } @@ -809,7 +810,7 @@ func buildTelemetry(g *graph.Graph) Telemetry { // logic in this function ratioMap := make(map[string]int32) for _, pol := range g.NGFPolicies { - if obsPol, ok := pol.Source.(*ngfAPI.ObservabilityPolicy); ok { + if obsPol, ok := pol.Source.(*ngfAPIv1alpha2.ObservabilityPolicy); ok { if obsPol.Spec.Tracing != nil && obsPol.Spec.Tracing.Ratio != nil && *obsPol.Spec.Tracing.Ratio > 0 { ratioName := CreateRatioVarName(*obsPol.Spec.Tracing.Ratio) ratioMap[ratioName] = *obsPol.Spec.Tracing.Ratio @@ -825,7 +826,7 @@ func buildTelemetry(g *graph.Graph) Telemetry { return tel } -func setSpanAttributes(spanAttributes []ngfAPI.SpanAttribute) []SpanAttribute { +func setSpanAttributes(spanAttributes []ngfAPIv1alpha1.SpanAttribute) []SpanAttribute { spanAttrs := make([]SpanAttribute, 0, len(spanAttributes)) for _, spanAttr := range spanAttributes { sa := SpanAttribute{ @@ -850,7 +851,7 @@ func buildBaseHTTPConfig(g *graph.Graph) BaseHTTPConfig { // HTTP2 should be enabled by default HTTP2: true, IPFamily: Dual, - Snippets: buildSnippetsForContext(g.SnippetsFilters, ngfAPI.NginxContextHTTP), + Snippets: buildSnippetsForContext(g.SnippetsFilters, ngfAPIv1alpha1.NginxContextHTTP), } if g.NginxProxy == nil || !g.NginxProxy.Valid { return baseConfig @@ -862,9 +863,9 @@ func buildBaseHTTPConfig(g *graph.Graph) BaseHTTPConfig { if g.NginxProxy.Source.Spec.IPFamily != nil { switch *g.NginxProxy.Source.Spec.IPFamily { - case ngfAPI.IPv4: + case ngfAPIv1alpha1.IPv4: baseConfig.IPFamily = IPv4 - case ngfAPI.IPv6: + case ngfAPIv1alpha1.IPv6: baseConfig.IPFamily = IPv6 } } @@ -872,9 +873,9 @@ func buildBaseHTTPConfig(g *graph.Graph) BaseHTTPConfig { if g.NginxProxy.Source.Spec.RewriteClientIP != nil { if g.NginxProxy.Source.Spec.RewriteClientIP.Mode != nil { switch *g.NginxProxy.Source.Spec.RewriteClientIP.Mode { - case ngfAPI.RewriteClientIPModeProxyProtocol: + case ngfAPIv1alpha1.RewriteClientIPModeProxyProtocol: baseConfig.RewriteClientIPSettings.Mode = RewriteIPModeProxyProtocol - case ngfAPI.RewriteClientIPModeXForwardedFor: + case ngfAPIv1alpha1.RewriteClientIPModeXForwardedFor: baseConfig.RewriteClientIPSettings.Mode = RewriteIPModeXForwardedFor } } @@ -893,7 +894,7 @@ func buildBaseHTTPConfig(g *graph.Graph) BaseHTTPConfig { return baseConfig } -func createSnippetName(nc ngfAPI.NginxContext, nsname types.NamespacedName) string { +func createSnippetName(nc ngfAPIv1alpha1.NginxContext, nsname types.NamespacedName) string { return fmt.Sprintf( "SnippetsFilter_%s_%s_%s", nc, @@ -904,7 +905,7 @@ func createSnippetName(nc ngfAPI.NginxContext, nsname types.NamespacedName) stri func buildSnippetsForContext( snippetFilters map[types.NamespacedName]*graph.SnippetsFilter, - nc ngfAPI.NginxContext, + nc ngfAPIv1alpha1.NginxContext, ) []Snippet { if len(snippetFilters) == 0 { return nil @@ -950,7 +951,7 @@ func buildPolicies(graphPolicies []*graph.Policy) []policies.Policy { return finalPolicies } -func convertAddresses(addresses []ngfAPI.Address) []string { +func convertAddresses(addresses []ngfAPIv1alpha1.Address) []string { trustedAddresses := make([]string, len(addresses)) for i, addr := range addresses { trustedAddresses[i] = addr.Value diff --git a/internal/mode/static/state/dataplane/configuration_test.go b/internal/mode/static/state/dataplane/configuration_test.go index 45da72bf9..a455d5c73 100644 --- a/internal/mode/static/state/dataplane/configuration_test.go +++ b/internal/mode/static/state/dataplane/configuration_test.go @@ -19,7 +19,8 @@ import ( "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/apis/v1alpha3" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginx/nginx-gateway-fabric/internal/framework/kinds" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -337,7 +338,7 @@ func TestBuildConfiguration(t *testing.T) { ) sf1 := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "sf", Namespace: "test", @@ -345,16 +346,16 @@ func TestBuildConfiguration(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "location snippet", - ngfAPI.NginxContextHTTPServer: "server snippet", - ngfAPI.NginxContextMain: "main snippet", - ngfAPI.NginxContextHTTP: "http snippet", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "location snippet", + ngfAPIv1alpha1.NginxContextHTTPServer: "server snippet", + ngfAPIv1alpha1.NginxContextMain: "main snippet", + ngfAPIv1alpha1.NginxContextHTTP: "http snippet", }, } sfNotReferenced := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "sf-not-referenced", Namespace: "test", @@ -362,9 +363,9 @@ func TestBuildConfiguration(t *testing.T) { }, Valid: true, Referenced: false, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextMain: "main snippet no ref", - ngfAPI.NginxContextHTTP: "http snippet no ref", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextMain: "main snippet no ref", + ngfAPIv1alpha1.NginxContextHTTP: "http snippet no ref", }, } @@ -377,7 +378,7 @@ func TestBuildConfiguration(t *testing.T) { extRefFilter := graph.Filter{ FilterType: graph.FilterExtensionRef, ExtensionRef: &v1.LocalObjectReference{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.SnippetsFilter, Name: "sf", }, @@ -393,14 +394,14 @@ func TestBuildConfiguration(t *testing.T) { expExtRefFilter := SnippetsFilter{ LocationSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServerLocation, + ngfAPIv1alpha1.NginxContextHTTPServerLocation, client.ObjectKeyFromObject(extRefFilter.ResolvedExtensionRef.SnippetsFilter.Source), ), Contents: "location snippet", }, ServerSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServer, + ngfAPIv1alpha1.NginxContextHTTPServer, client.ObjectKeyFromObject(extRefFilter.ResolvedExtensionRef.SnippetsFilter.Source), ), Contents: "server snippet", @@ -826,39 +827,39 @@ func TestBuildConfiguration(t *testing.T) { } nginxProxy := &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{ - Exporter: &ngfAPI.TelemetryExporter{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{ + Exporter: &ngfAPIv1alpha1.TelemetryExporter{ Endpoint: "my-otel.svc:4563", BatchSize: helpers.GetPointer(int32(512)), BatchCount: helpers.GetPointer(int32(4)), - Interval: helpers.GetPointer(ngfAPI.Duration("5s")), + Interval: helpers.GetPointer(ngfAPIv1alpha1.Duration("5s")), }, ServiceName: helpers.GetPointer("my-svc"), }, DisableHTTP2: true, - IPFamily: helpers.GetPointer(ngfAPI.Dual), + IPFamily: helpers.GetPointer(ngfAPIv1alpha1.Dual), }, }, Valid: true, } nginxProxyIPv4 := &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{}, - IPFamily: helpers.GetPointer(ngfAPI.IPv4), + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{}, + IPFamily: helpers.GetPointer(ngfAPIv1alpha1.IPv4), }, }, Valid: true, } nginxProxyIPv6 := &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{}, - IPFamily: helpers.GetPointer(ngfAPI.IPv6), + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{}, + IPFamily: helpers.GetPointer(ngfAPIv1alpha1.IPv6), }, }, Valid: true, @@ -2090,12 +2091,12 @@ func TestBuildConfiguration(t *testing.T) { }) g.NginxProxy = &graph.NginxProxy{ Valid: false, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ DisableHTTP2: true, - IPFamily: helpers.GetPointer(ngfAPI.Dual), - Telemetry: &ngfAPI.Telemetry{ - Exporter: &ngfAPI.TelemetryExporter{ + IPFamily: helpers.GetPointer(ngfAPIv1alpha1.Dual), + Telemetry: &ngfAPIv1alpha1.Telemetry{ + Exporter: &ngfAPIv1alpha1.TelemetryExporter{ Endpoint: "some-endpoint", }, }, @@ -2266,17 +2267,17 @@ func TestBuildConfiguration(t *testing.T) { }) g.NginxProxy = &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - RewriteClientIP: &ngfAPI.RewriteClientIP{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + RewriteClientIP: &ngfAPIv1alpha1.RewriteClientIP{ SetIPRecursively: helpers.GetPointer(true), - TrustedAddresses: []ngfAPI.Address{ + TrustedAddresses: []ngfAPIv1alpha1.Address{ { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "1.1.1.1/32", }, }, - Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol), + Mode: helpers.GetPointer(ngfAPIv1alpha1.RewriteClientIPModeProxyProtocol), }, }, }, @@ -2313,9 +2314,9 @@ func TestBuildConfiguration(t *testing.T) { }) g.NginxProxy = &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelDebug)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelDebug)}, }, }, } @@ -2342,7 +2343,7 @@ func TestBuildConfiguration(t *testing.T) { conf.MainSnippets = []Snippet{ { Name: createSnippetName( - ngfAPI.NginxContextMain, + ngfAPIv1alpha1.NginxContextMain, client.ObjectKeyFromObject(sf1.Source), ), Contents: "main snippet", @@ -2351,7 +2352,7 @@ func TestBuildConfiguration(t *testing.T) { conf.BaseHTTPConfig.Snippets = []Snippet{ { Name: createSnippetName( - ngfAPI.NginxContextHTTP, + ngfAPIv1alpha1.NginxContextHTTP, client.ObjectKeyFromObject(sf1.Source), ), Contents: "http snippet", @@ -2534,14 +2535,14 @@ func TestCreateFilters(t *testing.T) { snippetsFilter1 := graph.Filter{ FilterType: graph.FilterExtensionRef, ExtensionRef: &v1.LocalObjectReference{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.SnippetsFilter, Name: "sf1", }, ResolvedExtensionRef: &graph.ExtensionRefFilter{ Valid: true, SnippetsFilter: &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "sf1", Namespace: "default", @@ -2549,11 +2550,11 @@ func TestCreateFilters(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "location snippet 1", - ngfAPI.NginxContextMain: "main snippet 1", - ngfAPI.NginxContextHTTPServer: "server snippet 1", - ngfAPI.NginxContextHTTP: "http snippet 1", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "location snippet 1", + ngfAPIv1alpha1.NginxContextMain: "main snippet 1", + ngfAPIv1alpha1.NginxContextHTTPServer: "server snippet 1", + ngfAPIv1alpha1.NginxContextHTTP: "http snippet 1", }, }, }, @@ -2562,14 +2563,14 @@ func TestCreateFilters(t *testing.T) { snippetsFilter2 := graph.Filter{ FilterType: graph.FilterExtensionRef, ExtensionRef: &v1.LocalObjectReference{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: kinds.SnippetsFilter, Name: "sf2", }, ResolvedExtensionRef: &graph.ExtensionRefFilter{ Valid: true, SnippetsFilter: &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "sf2", Namespace: "default", @@ -2577,11 +2578,11 @@ func TestCreateFilters(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "location snippet 2", - ngfAPI.NginxContextMain: "main snippet 2", - ngfAPI.NginxContextHTTPServer: "server snippet 2", - ngfAPI.NginxContextHTTP: "http snippet 2", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "location snippet 2", + ngfAPIv1alpha1.NginxContextMain: "main snippet 2", + ngfAPIv1alpha1.NginxContextHTTPServer: "server snippet 2", + ngfAPIv1alpha1.NginxContextHTTP: "http snippet 2", }, }, }, @@ -2628,14 +2629,14 @@ func TestCreateFilters(t *testing.T) { { LocationSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServerLocation, + ngfAPIv1alpha1.NginxContextHTTPServerLocation, types.NamespacedName{Namespace: "default", Name: "sf1"}, ), Contents: "location snippet 1", }, ServerSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServer, + ngfAPIv1alpha1.NginxContextHTTPServer, types.NamespacedName{Namespace: "default", Name: "sf1"}, ), Contents: "server snippet 1", @@ -2644,14 +2645,14 @@ func TestCreateFilters(t *testing.T) { { LocationSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServerLocation, + ngfAPIv1alpha1.NginxContextHTTPServerLocation, types.NamespacedName{Namespace: "default", Name: "sf2"}, ), Contents: "location snippet 2", }, ServerSnippet: &Snippet{ Name: createSnippetName( - ngfAPI.NginxContextHTTPServer, + ngfAPIv1alpha1.NginxContextHTTPServer, types.NamespacedName{Namespace: "default", Name: "sf2"}, ), Contents: "server snippet 2", @@ -3278,17 +3279,17 @@ func TestConvertBackendTLS(t *testing.T) { func TestBuildTelemetry(t *testing.T) { t.Parallel() telemetryConfigured := &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{ - Exporter: &ngfAPI.TelemetryExporter{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{ + Exporter: &ngfAPIv1alpha1.TelemetryExporter{ Endpoint: "my-otel.svc:4563", BatchSize: helpers.GetPointer(int32(512)), BatchCount: helpers.GetPointer(int32(4)), - Interval: helpers.GetPointer(ngfAPI.Duration("5s")), + Interval: helpers.GetPointer(ngfAPIv1alpha1.Duration("5s")), }, ServiceName: helpers.GetPointer("my-svc"), - SpanAttributes: []ngfAPI.SpanAttribute{ + SpanAttributes: []ngfAPIv1alpha1.SpanAttribute{ {Key: "key", Value: "value"}, }, }, @@ -3323,7 +3324,7 @@ func TestBuildTelemetry(t *testing.T) { { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{}, + Source: &ngfAPIv1alpha1.NginxProxy{}, }, }, expTelemetry: Telemetry{}, @@ -3332,10 +3333,10 @@ func TestBuildTelemetry(t *testing.T) { { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Telemetry: &ngfAPI.Telemetry{ - Exporter: &ngfAPI.TelemetryExporter{}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Telemetry: &ngfAPIv1alpha1.Telemetry{ + Exporter: &ngfAPIv1alpha1.TelemetryExporter{}, }, }, }, @@ -3373,13 +3374,13 @@ func TestBuildTelemetry(t *testing.T) { NginxProxy: telemetryConfigured, NGFPolicies: map[graph.PolicyKey]*graph.Policy{ {NsName: types.NamespacedName{Name: "obsPolicy"}}: { - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obsPolicy", Namespace: "custom-ns", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Ratio: helpers.GetPointer[int32](25), }, }, @@ -3408,46 +3409,46 @@ func TestBuildTelemetry(t *testing.T) { NginxProxy: telemetryConfigured, NGFPolicies: map[graph.PolicyKey]*graph.Policy{ {NsName: types.NamespacedName{Name: "obsPolicy"}}: { - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obsPolicy", Namespace: "custom-ns", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Ratio: helpers.GetPointer[int32](25), }, }, }, }, {NsName: types.NamespacedName{Name: "obsPolicy2"}}: { - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obsPolicy2", Namespace: "custom-ns", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Ratio: helpers.GetPointer[int32](50), }, }, }, }, {NsName: types.NamespacedName{Name: "obsPolicy3"}}: { - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obsPolicy3", Namespace: "custom-ns", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Ratio: helpers.GetPointer[int32](25), }, }, }, }, {NsName: types.NamespacedName{Name: "csPolicy"}}: { - Source: &ngfAPI.ClientSettingsPolicy{ + Source: &ngfAPIv1alpha1.ClientSettingsPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "csPolicy", Namespace: "custom-ns", @@ -3478,13 +3479,13 @@ func TestBuildTelemetry(t *testing.T) { NginxProxy: telemetryConfigured, NGFPolicies: map[graph.PolicyKey]*graph.Policy{ {NsName: types.NamespacedName{Name: "obsPolicy"}}: { - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "obsPolicy", Namespace: "custom-ns", }, - Spec: ngfAPI.ObservabilityPolicySpec{ - Tracing: &ngfAPI.Tracing{ + Spec: ngfAPIv1alpha2.ObservabilityPolicySpec{ + Tracing: &ngfAPIv1alpha2.Tracing{ Ratio: helpers.GetPointer[int32](0), }, }, @@ -3913,7 +3914,7 @@ func TestBuildRewriteIPSettings(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{}, + Source: &ngfAPIv1alpha1.NginxProxy{}, }, }, expRewriteIPSettings: RewriteClientIPSettings{}, @@ -3923,13 +3924,13 @@ func TestBuildRewriteIPSettings(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - RewriteClientIP: &ngfAPI.RewriteClientIP{ - Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol), - TrustedAddresses: []ngfAPI.Address{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + RewriteClientIP: &ngfAPIv1alpha1.RewriteClientIP{ + Mode: helpers.GetPointer(ngfAPIv1alpha1.RewriteClientIPModeProxyProtocol), + TrustedAddresses: []ngfAPIv1alpha1.Address{ { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "10.9.9.4/32", }, }, @@ -3950,13 +3951,13 @@ func TestBuildRewriteIPSettings(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - RewriteClientIP: &ngfAPI.RewriteClientIP{ - Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor), - TrustedAddresses: []ngfAPI.Address{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + RewriteClientIP: &ngfAPIv1alpha1.RewriteClientIP{ + Mode: helpers.GetPointer(ngfAPIv1alpha1.RewriteClientIPModeXForwardedFor), + TrustedAddresses: []ngfAPIv1alpha1.Address{ { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "76.89.90.11/24", }, }, @@ -3977,25 +3978,25 @@ func TestBuildRewriteIPSettings(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - RewriteClientIP: &ngfAPI.RewriteClientIP{ - Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor), - TrustedAddresses: []ngfAPI.Address{ + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + RewriteClientIP: &ngfAPIv1alpha1.RewriteClientIP{ + Mode: helpers.GetPointer(ngfAPIv1alpha1.RewriteClientIPModeXForwardedFor), + TrustedAddresses: []ngfAPIv1alpha1.Address{ { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "5.5.5.5/12", }, { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "1.1.1.1/26", }, { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "2.2.2.2/32", }, { - Type: ngfAPI.CIDRAddressType, + Type: ngfAPIv1alpha1.CIDRAddressType, Value: "3.3.3.3/24", }, }, @@ -4042,8 +4043,8 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{}, }, }, }, @@ -4054,9 +4055,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelDebug)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelDebug)}, }, }, }, @@ -4068,9 +4069,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelInfo)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelInfo)}, }, }, }, @@ -4082,9 +4083,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelNotice)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelNotice)}, }, }, }, @@ -4096,9 +4097,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelWarn)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelWarn)}, }, }, }, @@ -4110,9 +4111,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelError)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelError)}, }, }, }, @@ -4124,9 +4125,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelCrit)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelCrit)}, }, }, }, @@ -4138,9 +4139,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelAlert)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelAlert)}, }, }, }, @@ -4152,9 +4153,9 @@ func TestBuildLogging(t *testing.T) { g: &graph.Graph{ NginxProxy: &graph.NginxProxy{ Valid: true, - Source: &ngfAPI.NginxProxy{ - Spec: ngfAPI.NginxProxySpec{ - Logging: &ngfAPI.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPI.NginxLogLevelEmerg)}, + Source: &ngfAPIv1alpha1.NginxProxy{ + Spec: ngfAPIv1alpha1.NginxProxySpec{ + Logging: &ngfAPIv1alpha1.NginxLogging{ErrorLevel: helpers.GetPointer(ngfAPIv1alpha1.NginxLogLevelEmerg)}, }, }, }, @@ -4179,7 +4180,7 @@ func TestCreateSnippetName(t *testing.T) { g := NewWithT(t) name := createSnippetName( - ngfAPI.NginxContextHTTPServerLocation, + ngfAPIv1alpha1.NginxContextHTTPServerLocation, types.NamespacedName{Namespace: "some-ns", Name: "some-name"}, ) g.Expect(name).To(Equal("SnippetsFilter_http.server.location_some-ns_some-name")) @@ -4189,7 +4190,7 @@ func TestBuildSnippetForContext(t *testing.T) { t.Parallel() validUnreferenced := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "valid-unreferenced", Namespace: "default", @@ -4197,13 +4198,13 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: true, Referenced: false, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "valid unreferenced", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "valid unreferenced", }, } invalidUnreferenced := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "invalid-unreferenced", Namespace: "default", @@ -4211,13 +4212,13 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: false, Referenced: false, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "invalid unreferenced", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "invalid unreferenced", }, } invalidReferenced := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "invalid-referenced", Namespace: "default", @@ -4225,13 +4226,13 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: false, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "invalid referenced", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "invalid referenced", }, } validReferenced1 := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "valid-referenced1", Namespace: "default", @@ -4239,14 +4240,14 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTP: "http valid referenced 1", - ngfAPI.NginxContextMain: "main valid referenced 1", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTP: "http valid referenced 1", + ngfAPIv1alpha1.NginxContextMain: "main valid referenced 1", }, } validReferenced2 := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "valid-referenced2", Namespace: "other-ns", @@ -4254,14 +4255,14 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextMain: "main valid referenced 2", - ngfAPI.NginxContextHTTP: "http valid referenced 2", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextMain: "main valid referenced 2", + ngfAPIv1alpha1.NginxContextHTTP: "http valid referenced 2", }, } validReferenced3 := &graph.SnippetsFilter{ - Source: &ngfAPI.SnippetsFilter{ + Source: &ngfAPIv1alpha1.SnippetsFilter{ ObjectMeta: metav1.ObjectMeta{ Name: "valid-referenced3", Namespace: "other-ns", @@ -4269,29 +4270,29 @@ func TestBuildSnippetForContext(t *testing.T) { }, Valid: true, Referenced: true, - Snippets: map[ngfAPI.NginxContext]string{ - ngfAPI.NginxContextHTTPServerLocation: "location valid referenced 2", + Snippets: map[ngfAPIv1alpha1.NginxContext]string{ + ngfAPIv1alpha1.NginxContextHTTPServerLocation: "location valid referenced 2", }, } expMainSnippets := []Snippet{ { - Name: createSnippetName(ngfAPI.NginxContextMain, client.ObjectKeyFromObject(validReferenced1.Source)), + Name: createSnippetName(ngfAPIv1alpha1.NginxContextMain, client.ObjectKeyFromObject(validReferenced1.Source)), Contents: "main valid referenced 1", }, { - Name: createSnippetName(ngfAPI.NginxContextMain, client.ObjectKeyFromObject(validReferenced2.Source)), + Name: createSnippetName(ngfAPIv1alpha1.NginxContextMain, client.ObjectKeyFromObject(validReferenced2.Source)), Contents: "main valid referenced 2", }, } expHTTPSnippets := []Snippet{ { - Name: createSnippetName(ngfAPI.NginxContextHTTP, client.ObjectKeyFromObject(validReferenced1.Source)), + Name: createSnippetName(ngfAPIv1alpha1.NginxContextHTTP, client.ObjectKeyFromObject(validReferenced1.Source)), Contents: "http valid referenced 1", }, { - Name: createSnippetName(ngfAPI.NginxContextHTTP, client.ObjectKeyFromObject(validReferenced2.Source)), + Name: createSnippetName(ngfAPIv1alpha1.NginxContextHTTP, client.ObjectKeyFromObject(validReferenced2.Source)), Contents: "http valid referenced 2", }, } @@ -4310,25 +4311,25 @@ func TestBuildSnippetForContext(t *testing.T) { tests := []struct { name string snippetsFilters map[types.NamespacedName]*graph.SnippetsFilter - ctx ngfAPI.NginxContext + ctx ngfAPIv1alpha1.NginxContext expSnippets []Snippet }{ { name: "no snippets filters", snippetsFilters: nil, - ctx: ngfAPI.NginxContextMain, + ctx: ngfAPIv1alpha1.NginxContextMain, expSnippets: nil, }, { name: "main context: mix of invalid, unreferenced, and valid, referenced snippets filters", snippetsFilters: getSnippetsFilters(), - ctx: ngfAPI.NginxContextMain, + ctx: ngfAPIv1alpha1.NginxContextMain, expSnippets: expMainSnippets, }, { name: "http context: mix of invalid, unreferenced, and valid, referenced snippets filters", snippetsFilters: getSnippetsFilters(), - ctx: ngfAPI.NginxContextHTTP, + ctx: ngfAPIv1alpha1.NginxContextHTTP, expSnippets: expHTTPSnippets, }, } diff --git a/internal/mode/static/state/graph/policy_ancestor_test.go b/internal/mode/static/state/graph/policy_ancestor_test.go index 75391bc09..d3a1905b0 100644 --- a/internal/mode/static/state/graph/policy_ancestor_test.go +++ b/internal/mode/static/state/graph/policy_ancestor_test.go @@ -8,7 +8,7 @@ import ( v1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/framework/kinds" ) @@ -90,7 +90,7 @@ func TestNGFPolicyAncestorsFull(t *testing.T) { } return &Policy{ - Source: &ngfAPI.ObservabilityPolicy{ + Source: &ngfAPIv1alpha2.ObservabilityPolicy{ Status: v1alpha2.PolicyStatus{ Ancestors: currAncestors, }, diff --git a/site/content/how-to/monitoring/tracing.md b/site/content/how-to/monitoring/tracing.md index 2820c7f18..3b440a33c 100644 --- a/site/content/how-to/monitoring/tracing.md +++ b/site/content/how-to/monitoring/tracing.md @@ -267,7 +267,7 @@ To enable tracing for the coffee HTTPRoute, create the following policy: ```yaml kubectl apply -f - <}}) | Configure connection behavior between client and NGINX | Inherited | Gateway, HTTPRoute, GRPCRoute | No | Yes | v1alpha1 | -| [ObservabilityPolicy]({{}}) | Define settings related to tracing, metrics, or logging | Direct | HTTPRoute, GRPCRoute | Yes | No | v1alpha1 | +| [ObservabilityPolicy]({{}}) | Define settings related to tracing, metrics, or logging | Direct | HTTPRoute, GRPCRoute | Yes | No | v1alpha2 | | [UpstreamSettingsPolicy]({{}}) | Configure connection behavior between NGINX and upstream applications | Direct | Service | Yes | Yes | v1alpha1 | - {{}} {{< important >}} diff --git a/site/content/reference/api.md b/site/content/reference/api.md index 74ea08d3c..77eafa4ac 100644 --- a/site/content/reference/api.md +++ b/site/content/reference/api.md @@ -10,6 +10,9 @@ NGINX Gateway API Reference
  • gateway.nginx.org/v1alpha1
  • +
  • +gateway.nginx.org/v1alpha2 +
  • gateway.nginx.org/v1alpha1

    @@ -683,6 +686,7 @@ UpstreamKeepAlive

    TargetRefs identifies API object(s) to apply the policy to. Objects must be in the same namespace as the policy. Support: Service

    +

    TargetRefs must be distinct. The name field must be unique for all targetRef entries in the UpstreamSettingsPolicy.

    @@ -1825,7 +1829,8 @@ and the status of the SnippetsFilter with respect to each controller.

    (Appears on: Telemetry, -Tracing) +Tracing, +Tracing)

    SpanAttribute is a key value pair to be added to a tracing span.

    @@ -2290,6 +2295,326 @@ UpstreamKeepAlive

    TargetRefs identifies API object(s) to apply the policy to. Objects must be in the same namespace as the policy. Support: Service

    +

    TargetRefs must be distinct. The name field must be unique for all targetRef entries in the UpstreamSettingsPolicy.

    + + + + +
    +

    gateway.nginx.org/v1alpha2

    +

    +

    Package v1alpha2 contains API Schema definitions for the +gateway.nginx.org API group.

    +

    +Resource Types: + +

    ObservabilityPolicy + +

    +

    +

    ObservabilityPolicy is a Direct Attached Policy. It provides a way to configure observability settings for +the NGINX Gateway Fabric data plane. Used in conjunction with the NginxProxy CRD that is attached to the +GatewayClass parametersRef.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +gateway.nginx.org/v1alpha2 + +
    +kind
    +string +
    ObservabilityPolicy
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +ObservabilityPolicySpec + + +
    +

    Spec defines the desired state of the ObservabilityPolicy.

    +
    +
    + + + + + + + + + +
    +tracing
    + + +Tracing + + +
    +(Optional) +

    Tracing allows for enabling and configuring tracing.

    +
    +targetRefs
    + + +[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + + +
    +

    TargetRefs identifies the API object(s) to apply the policy to. +Objects must be in the same namespace as the policy. +Support: HTTPRoute, GRPCRoute.

    +

    TargetRefs must be distinct. This means that the multi-part key defined by kind and name must +be unique across all targetRef entries in the ObservabilityPolicy.

    +
    +
    +status
    + + +sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus + + +
    +

    Status defines the state of the ObservabilityPolicy.

    +
    +

    ObservabilityPolicySpec + +

    +

    +(Appears on: +ObservabilityPolicy) +

    +

    +

    ObservabilityPolicySpec defines the desired state of the ObservabilityPolicy.

    +

    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +tracing
    + + +Tracing + + +
    +(Optional) +

    Tracing allows for enabling and configuring tracing.

    +
    +targetRefs
    + + +[]sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference + + +
    +

    TargetRefs identifies the API object(s) to apply the policy to. +Objects must be in the same namespace as the policy. +Support: HTTPRoute, GRPCRoute.

    +

    TargetRefs must be distinct. This means that the multi-part key defined by kind and name must +be unique across all targetRef entries in the ObservabilityPolicy.

    +
    +

    TraceContext +(string alias)

    +

    +

    +(Appears on: +Tracing) +

    +

    +

    TraceContext specifies how to propagate traceparent/tracestate headers.

    +

    + + + + + + + + + + + + + + + + +
    ValueDescription

    "extract"

    TraceContextExtract uses an existing trace context from the request, so that the identifiers +of a trace and the parent span are inherited from the incoming request.

    +

    "ignore"

    TraceContextIgnore skips context headers processing.

    +

    "inject"

    TraceContextInject adds a new context to the request, overwriting existing headers, if any.

    +

    "propagate"

    TraceContextPropagate updates the existing context (combines extract and inject).

    +
    +

    TraceStrategy +(string alias)

    +

    +

    +(Appears on: +Tracing) +

    +

    +

    TraceStrategy defines the tracing strategy.

    +

    + + + + + + + + + + + + +
    ValueDescription

    "parent"

    TraceStrategyParent enables tracing and only records spans if the parent span was sampled.

    +

    "ratio"

    TraceStrategyRatio enables ratio-based tracing, defaulting to 100% sampling rate.

    +
    +

    Tracing + +

    +

    +(Appears on: +ObservabilityPolicySpec) +

    +

    +

    Tracing allows for enabling and configuring OpenTelemetry tracing.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/suite/manifests/tracing/policy-multiple.yaml b/tests/suite/manifests/tracing/policy-multiple.yaml index 851f573fd..cbafeafd2 100644 --- a/tests/suite/manifests/tracing/policy-multiple.yaml +++ b/tests/suite/manifests/tracing/policy-multiple.yaml @@ -1,4 +1,4 @@ -apiVersion: gateway.nginx.org/v1alpha1 +apiVersion: gateway.nginx.org/v1alpha2 kind: ObservabilityPolicy metadata: name: test-observability-policy diff --git a/tests/suite/manifests/tracing/policy-single.yaml b/tests/suite/manifests/tracing/policy-single.yaml index 6d8da1581..37904db3c 100644 --- a/tests/suite/manifests/tracing/policy-single.yaml +++ b/tests/suite/manifests/tracing/policy-single.yaml @@ -1,4 +1,4 @@ -apiVersion: gateway.nginx.org/v1alpha1 +apiVersion: gateway.nginx.org/v1alpha2 kind: ObservabilityPolicy metadata: name: test-observability-policy diff --git a/tests/suite/system_suite_test.go b/tests/suite/system_suite_test.go index 1f759d0db..684ad1d99 100644 --- a/tests/suite/system_suite_test.go +++ b/tests/suite/system_suite_test.go @@ -31,7 +31,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" v1 "sigs.k8s.io/gateway-api/apis/v1" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/tests/framework" ) @@ -117,7 +118,8 @@ func setup(cfg setupConfig, extraInstallArgs ...string) { Expect(coordination.AddToScheme(scheme)).To(Succeed()) Expect(v1.Install(scheme)).To(Succeed()) Expect(batchv1.AddToScheme(scheme)).To(Succeed()) - Expect(ngfAPI.AddToScheme(scheme)).To(Succeed()) + Expect(ngfAPIv1alpha1.AddToScheme(scheme)).To(Succeed()) + Expect(ngfAPIv1alpha2.AddToScheme(scheme)).To(Succeed()) options := client.Options{ Scheme: scheme, diff --git a/tests/suite/tracing_test.go b/tests/suite/tracing_test.go index 46ec5bfc1..5d39bd94e 100644 --- a/tests/suite/tracing_test.go +++ b/tests/suite/tracing_test.go @@ -17,7 +17,8 @@ import ( gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - ngfAPI "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha1 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha1" + ngfAPIv1alpha2 "github.com/nginx/nginx-gateway-fabric/apis/v1alpha2" "github.com/nginx/nginx-gateway-fabric/internal/mode/static/state/conditions" "github.com/nginx/nginx-gateway-fabric/tests/framework" ) @@ -101,7 +102,7 @@ var _ = Describe("Tracing", FlakeAttempts(2), Label("functional", "tracing"), fu } gwClass.Spec.ParametersRef = &gatewayv1.ParametersReference{ - Group: ngfAPI.GroupName, + Group: ngfAPIv1alpha1.GroupName, Kind: gatewayv1.Kind("NginxProxy"), Name: "nginx-proxy", } @@ -235,7 +236,7 @@ func verifyPolicyStatus() error { ctx, cancel := context.WithTimeout(context.Background(), timeoutConfig.GetTimeout) defer cancel() - var pol ngfAPI.ObservabilityPolicy + var pol ngfAPIv1alpha2.ObservabilityPolicy key := types.NamespacedName{Name: "test-observability-policy", Namespace: "helloworld"} if err := k8sClient.Get(ctx, key, &pol); err != nil { return err
    FieldDescription
    +strategy
    + + +TraceStrategy + + +
    +

    Strategy defines if tracing is ratio-based or parent-based.

    +
    +ratio
    + +int32 + +
    +(Optional) +

    Ratio is the percentage of traffic that should be sampled. Integer from 0 to 100. +By default, 100% of http requests are traced. Not applicable for parent-based tracing. +If ratio is set to 0, tracing is disabled.

    +
    +context
    + + +TraceContext + + +
    +(Optional) +

    Context specifies how to propagate traceparent/tracestate headers. +Default: https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context

    +
    +spanName
    + +string + +
    +(Optional) +

    SpanName defines the name of the Otel span. By default is the name of the location for a request. +If specified, applies to all locations that are created for a route. +Format: must have all ‘“’ escaped and must not contain any ‘$’ or end with an unescaped ‘\’ +Examples of invalid names: some-$value, quoted-“value”-name, unescaped

    +
    +spanAttributes
    + + +[]SpanAttribute + + +
    +(Optional) +

    SpanAttributes are custom key/value attributes that are added to each span.