Skip to content

Commit 6a9290a

Browse files
committed
Support tracing via the ObservabilityPolicy
Problem: As a user, I want to be able to enable tracing for requests flowing through NGF to my backend applications, so I can understand and debug my requests. Solution: Using the ObservabilityPolicy, an app dev can now enable and configure tracing for their Route(s). The policy will only be applied if the NginxProxy configuration containing the tracing collector endpoint has been defined and attached to the GatewayClass. The policy can be attached to one or more HTTP or GRPC Routes. Updated span attributes from the NginxProxy to be applied at the location block context, otherwise they are overwritten. Also added functional tests to ensure that the complete solution is working.
1 parent 18671fb commit 6a9290a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1754
-520
lines changed

apis/v1alpha1/observabilitypolicy_types.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ type ObservabilityPolicySpec struct {
4242
// +optional
4343
Tracing *Tracing `json:"tracing,omitempty"`
4444

45-
// TargetRef identifies an API object to apply the policy to.
46-
// Object must be in the same namespace as the policy.
47-
//
45+
// TargetRefs identifies the API object(s) to apply the policy to.
46+
// Objects must be in the same namespace as the policy.
4847
// Support: HTTPRoute
49-
TargetRef gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRef"`
48+
//
49+
// +kubebuilder:validation:MaxItems=16
50+
// +kubebuilder:validation:XValidation:message="TargetRef Kind must be: HTTPRoute or GRPCRoute",rule="(self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute'))"
51+
// +kubebuilder:validation:XValidation:message="TargetRef Group must be gateway.networking.k8s.io.",rule="self.all(t, t.group=='gateway.networking.k8s.io')"
52+
//nolint:lll
53+
TargetRefs []gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRefs"`
5054
}
5155

5256
// Tracing allows for enabling and configuring OpenTelemetry tracing.

apis/v1alpha1/policy_methods.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
// Figure out a way to generate these methods for all our policies.
99
// These methods implement the policies.Policy interface which extends client.Object to add the following methods.
1010

11-
func (p *ClientSettingsPolicy) GetTargetRef() v1alpha2.LocalPolicyTargetReference {
12-
return p.Spec.TargetRef
11+
func (p *ClientSettingsPolicy) GetTargetRefs() []v1alpha2.LocalPolicyTargetReference {
12+
return []v1alpha2.LocalPolicyTargetReference{p.Spec.TargetRef}
1313
}
1414

1515
func (p *ClientSettingsPolicy) GetPolicyStatus() v1alpha2.PolicyStatus {
@@ -19,3 +19,15 @@ func (p *ClientSettingsPolicy) GetPolicyStatus() v1alpha2.PolicyStatus {
1919
func (p *ClientSettingsPolicy) SetPolicyStatus(status v1alpha2.PolicyStatus) {
2020
p.Status = status
2121
}
22+
23+
func (p *ObservabilityPolicy) GetTargetRefs() []v1alpha2.LocalPolicyTargetReference {
24+
return p.Spec.TargetRefs
25+
}
26+
27+
func (p *ObservabilityPolicy) GetPolicyStatus() v1alpha2.PolicyStatus {
28+
return p.Status
29+
}
30+
31+
func (p *ObservabilityPolicy) SetPolicyStatus(status v1alpha2.PolicyStatus) {
32+
p.Status = status
33+
}

apis/v1alpha1/zz_generated.deepcopy.go

+6-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/nginx-gateway-fabric/templates/rbac.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ rules:
122122
resources:
123123
- nginxproxies
124124
- clientsettingspolicies
125+
- observabilitypolicies
125126
verbs:
126127
- list
127128
- watch
@@ -130,6 +131,7 @@ rules:
130131
resources:
131132
- nginxgateways/status
132133
- clientsettingspolicies/status
134+
- observabilitypolicies/status
133135
verbs:
134136
- update
135137
{{- if .Values.nginxGateway.leaderElection.enable }}

config/crd/bases/gateway.nginx.org_observabilitypolicies.yaml

+40-28
Original file line numberDiff line numberDiff line change
@@ -50,35 +50,47 @@ spec:
5050
spec:
5151
description: Spec defines the desired state of the ObservabilityPolicy.
5252
properties:
53-
targetRef:
53+
targetRefs:
5454
description: |-
55-
TargetRef identifies an API object to apply the policy to.
56-
Object must be in the same namespace as the policy.
57-
58-
55+
TargetRefs identifies the API object(s) to apply the policy to.
56+
Objects must be in the same namespace as the policy.
5957
Support: HTTPRoute
60-
properties:
61-
group:
62-
description: Group is the group of the target resource.
63-
maxLength: 253
64-
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
65-
type: string
66-
kind:
67-
description: Kind is kind of the target resource.
68-
maxLength: 63
69-
minLength: 1
70-
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
71-
type: string
72-
name:
73-
description: Name is the name of the target resource.
74-
maxLength: 253
75-
minLength: 1
76-
type: string
77-
required:
78-
- group
79-
- kind
80-
- name
81-
type: object
58+
items:
59+
description: |-
60+
LocalPolicyTargetReference identifies an API object to apply a direct or
61+
inherited policy to. This should be used as part of Policy resources
62+
that can target Gateway API resources. For more information on how this
63+
policy attachment model works, and a sample Policy resource, refer to
64+
the policy attachment documentation for Gateway API.
65+
properties:
66+
group:
67+
description: Group is the group of the target resource.
68+
maxLength: 253
69+
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
70+
type: string
71+
kind:
72+
description: Kind is kind of the target resource.
73+
maxLength: 63
74+
minLength: 1
75+
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
76+
type: string
77+
name:
78+
description: Name is the name of the target resource.
79+
maxLength: 253
80+
minLength: 1
81+
type: string
82+
required:
83+
- group
84+
- kind
85+
- name
86+
type: object
87+
maxItems: 16
88+
type: array
89+
x-kubernetes-validations:
90+
- message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute'
91+
rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute'))
92+
- message: TargetRef Group must be gateway.networking.k8s.io.
93+
rule: self.all(t, t.group=='gateway.networking.k8s.io')
8294
tracing:
8395
description: Tracing allows for enabling and configuring tracing.
8496
properties:
@@ -155,7 +167,7 @@ spec:
155167
- message: ratio can only be specified if strategy is of type ratio
156168
rule: '!(has(self.ratio) && self.strategy != ''ratio'')'
157169
required:
158-
- targetRef
170+
- targetRefs
159171
type: object
160172
status:
161173
description: Status defines the state of the ObservabilityPolicy.

deploy/crds.yaml

+40-28
Original file line numberDiff line numberDiff line change
@@ -832,35 +832,47 @@ spec:
832832
spec:
833833
description: Spec defines the desired state of the ObservabilityPolicy.
834834
properties:
835-
targetRef:
835+
targetRefs:
836836
description: |-
837-
TargetRef identifies an API object to apply the policy to.
838-
Object must be in the same namespace as the policy.
839-
840-
837+
TargetRefs identifies the API object(s) to apply the policy to.
838+
Objects must be in the same namespace as the policy.
841839
Support: HTTPRoute
842-
properties:
843-
group:
844-
description: Group is the group of the target resource.
845-
maxLength: 253
846-
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
847-
type: string
848-
kind:
849-
description: Kind is kind of the target resource.
850-
maxLength: 63
851-
minLength: 1
852-
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
853-
type: string
854-
name:
855-
description: Name is the name of the target resource.
856-
maxLength: 253
857-
minLength: 1
858-
type: string
859-
required:
860-
- group
861-
- kind
862-
- name
863-
type: object
840+
items:
841+
description: |-
842+
LocalPolicyTargetReference identifies an API object to apply a direct or
843+
inherited policy to. This should be used as part of Policy resources
844+
that can target Gateway API resources. For more information on how this
845+
policy attachment model works, and a sample Policy resource, refer to
846+
the policy attachment documentation for Gateway API.
847+
properties:
848+
group:
849+
description: Group is the group of the target resource.
850+
maxLength: 253
851+
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
852+
type: string
853+
kind:
854+
description: Kind is kind of the target resource.
855+
maxLength: 63
856+
minLength: 1
857+
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
858+
type: string
859+
name:
860+
description: Name is the name of the target resource.
861+
maxLength: 253
862+
minLength: 1
863+
type: string
864+
required:
865+
- group
866+
- kind
867+
- name
868+
type: object
869+
maxItems: 16
870+
type: array
871+
x-kubernetes-validations:
872+
- message: 'TargetRef Kind must be: HTTPRoute or GRPCRoute'
873+
rule: (self.exists(t, t.kind=='HTTPRoute') || self.exists(t, t.kind=='GRPCRoute'))
874+
- message: TargetRef Group must be gateway.networking.k8s.io.
875+
rule: self.all(t, t.group=='gateway.networking.k8s.io')
864876
tracing:
865877
description: Tracing allows for enabling and configuring tracing.
866878
properties:
@@ -937,7 +949,7 @@ spec:
937949
- message: ratio can only be specified if strategy is of type ratio
938950
rule: '!(has(self.ratio) && self.strategy != ''ratio'')'
939951
required:
940-
- targetRef
952+
- targetRefs
941953
type: object
942954
status:
943955
description: Status defines the state of the ObservabilityPolicy.

deploy/manifests/nginx-gateway-experimental.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ rules:
104104
resources:
105105
- nginxproxies
106106
- clientsettingspolicies
107+
- observabilitypolicies
107108
verbs:
108109
- list
109110
- watch
@@ -112,6 +113,7 @@ rules:
112113
resources:
113114
- nginxgateways/status
114115
- clientsettingspolicies/status
116+
- observabilitypolicies/status
115117
verbs:
116118
- update
117119
- apiGroups:

deploy/manifests/nginx-gateway.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ rules:
101101
resources:
102102
- nginxproxies
103103
- clientsettingspolicies
104+
- observabilitypolicies
104105
verbs:
105106
- list
106107
- watch
@@ -109,6 +110,7 @@ rules:
109110
resources:
110111
- nginxgateways/status
111112
- clientsettingspolicies/status
113+
- observabilitypolicies/status
112114
verbs:
113115
- update
114116
- apiGroups:

deploy/manifests/nginx-plus-gateway-experimental.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ rules:
110110
resources:
111111
- nginxproxies
112112
- clientsettingspolicies
113+
- observabilitypolicies
113114
verbs:
114115
- list
115116
- watch
@@ -118,6 +119,7 @@ rules:
118119
resources:
119120
- nginxgateways/status
120121
- clientsettingspolicies/status
122+
- observabilitypolicies/status
121123
verbs:
122124
- update
123125
- apiGroups:

deploy/manifests/nginx-plus-gateway.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ rules:
107107
resources:
108108
- nginxproxies
109109
- clientsettingspolicies
110+
- observabilitypolicies
110111
verbs:
111112
- list
112113
- watch
@@ -115,6 +116,7 @@ rules:
115116
resources:
116117
- nginxgateways/status
117118
- clientsettingspolicies/status
119+
- observabilitypolicies/status
118120
verbs:
119121
- update
120122
- apiGroups:

docs/proposals/observability.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Enhancement Proposal-1778: Observability Policy
22

33
- Issue: https://github.com/nginxinc/nginx-gateway-fabric/issues/1778
4-
- Status: Implementable
4+
- Status: Completed
55

66
## Summary
77

@@ -65,10 +65,10 @@ type ObservabilityPolicy struct {
6565
}
6666

6767
type ObservabilityPolicySpec struct {
68-
// TargetRef identifies an API object to apply the policy to.
69-
// Object must be in the same namespace as the policy.
68+
// TargetRefs identifies API object(s) to apply the policy to.
69+
// Objects must be in the same namespace as the policy.
7070
// Support: HTTPRoute
71-
TargetRef gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRef"`
71+
TargetRefs []gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRefs"`
7272

7373
// Tracing allows for enabling and configuring tracing.
7474
//
@@ -154,8 +154,8 @@ metadata:
154154
name: example-observability-policy
155155
namespace: default
156156
spec:
157-
targetRef:
158-
group: gateway.networking.k8s.io
157+
targetRefs:
158+
- group: gateway.networking.k8s.io
159159
kind: HTTPRoute
160160
name: example-route
161161
tracing:

internal/mode/static/manager.go

+13
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
ngxruntime "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime"
5454
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/policies"
5555
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/policies/clientsettings"
56+
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/policies/observability"
5657
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state"
5758
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver"
5859
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/validation"
@@ -292,6 +293,11 @@ func createPolicyManager(
292293
Validator: clientsettings.NewValidator(validator),
293294
Generator: clientsettings.Generate,
294295
},
296+
{
297+
GVK: mustExtractGVK(&ngfAPI.ObservabilityPolicy{}),
298+
Validator: observability.NewValidator(validator),
299+
Generator: observability.Generate,
300+
},
295301
}
296302

297303
return policies.NewManager(mustExtractGVK, cfgs...)
@@ -461,6 +467,12 @@ func registerControllers(
461467
controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}),
462468
},
463469
},
470+
{
471+
objectType: &ngfAPI.ObservabilityPolicy{},
472+
options: []controller.Option{
473+
controller.WithK8sPredicate(k8spredicate.GenerationChangedPredicate{}),
474+
},
475+
},
464476
}
465477

466478
if cfg.ExperimentalFeatures {
@@ -642,6 +654,7 @@ func prepareFirstEventBatchPreparerArgs(
642654
&ngfAPI.NginxProxyList{},
643655
&gatewayv1.GRPCRouteList{},
644656
&ngfAPI.ClientSettingsPolicyList{},
657+
&ngfAPI.ObservabilityPolicyList{},
645658
partialObjectMetadataList,
646659
}
647660

0 commit comments

Comments
 (0)