Skip to content

Commit

Permalink
Add ObservabilityPolicy CRD (nginx#1848)
Browse files Browse the repository at this point in the history
Problem: Users want to be able to configure observability settings for their HTTPRoutes, such as tracing.

Solution: Add the ObservabilityPolicy CRD, which is a direct policy that will attach to HTTPRoutes to configure these settings. Note: this pR contains the CRD only. A subsequent PR will add the implementation.

Also removed some regex restrictions in the NginxProxy CRD.
  • Loading branch information
miledxz committed Apr 19, 2024
1 parent e8e1e60 commit f2c147f
Show file tree
Hide file tree
Showing 8 changed files with 817 additions and 60 deletions.
17 changes: 0 additions & 17 deletions apis/v1alpha1/nginxproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,3 @@ type TelemetryExporter struct {
// +kubebuilder:validation:Pattern=`^(?:http?:\/\/)?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*(?::\d{1,5})?$`
Endpoint string `json:"endpoint"`
}

// SpanAttribute is a key value pair to be added to a tracing span.
type SpanAttribute struct {
// Key is the key for a span attribute.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9_-]+$`
Key string `json:"key"`

// Value is the value for a span attribute.
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9_-]+$`
Value string `json:"value"`
}
126 changes: 126 additions & 0 deletions apis/v1alpha1/observabilitypolicy_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
)

// +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 {
// TargetRef identifies an API object to apply the policy to.
// Object must be in the same namespace as the policy.
//
// Support: HTTPRoute
TargetRef gatewayv1alpha2.PolicyTargetReference `json:"targetRef"`

// Tracing allows for enabling and configuring tracing.
//
// +optional
Tracing *Tracing `json:"tracing,omitempty"`
}

// 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.
//
// +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 []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"
)
2 changes: 2 additions & 0 deletions apis/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&NginxGatewayList{},
&NginxProxy{},
&NginxProxyList{},
&ObservabilityPolicy{},
&ObservabilityPolicyList{},
&ClientSettingsPolicy{},
&ClientSettingsPolicyList{},
)
Expand Down
19 changes: 19 additions & 0 deletions apis/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,22 @@ package v1alpha1
//
// +kubebuilder:validation:Pattern=`^\d{1,4}(ms|s)?$`
type Duration string

// SpanAttribute is a key value pair to be added to a tracing span.
type SpanAttribute struct {
// Key is the key for a span attribute.
// Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\'
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Pattern=`^([^"$\\]|\\[^$])*$`
Key string `json:"key"`

// Value is the value for a span attribute.
// Format: must have all '"' escaped and must not contain any '$' or end with an unescaped '\'
//
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Pattern=`^([^"$\\]|\\[^$])*$`
Value string `json:"value"`
}
115 changes: 115 additions & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions config/crd/bases/gateway.nginx.org_nginxproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,20 @@ spec:
a tracing span.
properties:
key:
description: Key is the key for a span attribute.
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: ^[a-zA-Z0-9_-]+$
pattern: ^([^"$\\]|\\[^$])*$
type: string
value:
description: Value is the value for a span attribute.
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: ^[a-zA-Z0-9_-]+$
pattern: ^([^"$\\]|\\[^$])*$
type: string
required:
- key
Expand Down
Loading

0 comments on commit f2c147f

Please sign in to comment.