Skip to content

Commit

Permalink
working
Browse files Browse the repository at this point in the history
  • Loading branch information
npolshakova committed Jan 30, 2025
1 parent e5c514f commit cda3374
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (d *directResponse) Equals(in any) bool {
type directResponseGwPass struct {
}

func (p *directResponseGwPass) AddHCM(ctx context.Context, listener ir.HttpFilterChainIR, out *envoyhttp.HttpConnectionManager) error {
func (p *directResponseGwPass) ApplyHCM(ctx context.Context, pCtx *ir.HcmContext, out *envoyhttp.HttpConnectionManager) error {
//TODO no op?
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func NewPlugin(ctx context.Context, commoncol *common.CommonCollections) extensi

return extensionplug.Plugin{
ContributesPolicies: map[schema.GroupKind]extensionsplug.PolicyPlugin{
v1alpha1.ListenerPolicyGVK.GroupKind(): {
v1alpha1.HTTPListenerPolicyGVK.GroupKind(): {
//AttachmentPoints: []ir.AttachmentPoints{ir.HttpAttachmentPoint},
NewGatewayTranslationPass: NewGatewayTranslationPass,
Policies: policyCol,
Expand All @@ -91,34 +91,25 @@ func convert(targetRef v1alpha1.LocalPolicyTargetReference) []ir.PolicyTargetRef
func NewGatewayTranslationPass(ctx context.Context, tctx ir.GwTranslationCtx) ir.ProxyTranslationPass {
return &httpListenerOptsPluginGwPass{}
}
func (p *httpListenerOptsPlugin) Name() string {
func (p *httpListenerOptsPluginGwPass) Name() string {
return "httplistenerpolicies"
}

func (p *httpListenerOptsPluginGwPass) AddHCM(
func (p *httpListenerOptsPluginGwPass) ApplyHCM(
ctx context.Context,
listener ir.HttpFilterChainIR,
pCtx *ir.HcmContext,
out *envoy_hcm.HttpConnectionManager) error {
for _, policies := range listener.AttachedPolicies.Policies {
fmt.Sprintf("ACCESSLOG policies %v\n", policies)
for _, policyAttachment := range policies {
println("!!!ACCESSLOG")
fmt.Sprintf("ACCESSLOG policyAttachment %v\n", policyAttachment)
// TODO: check section name

listenerPolicy, ok := policyAttachment.PolicyIr.(*httpListenerOptsPlugin)
if !ok {
return eris.Errorf("internal error: expected listener policy, got %T", policyAttachment.PolicyIr)
}
fmt.Sprintf("ACCESSLOG listenerPolicy %v\n", listenerPolicy)

// translate access logging configuration
if listenerPolicy.spec.AccessLoggingService != nil {
accessLog := convertAccessLogConfig(listenerPolicy.spec.AccessLoggingService)
if accessLog != nil {
out.AccessLog = append(out.GetAccessLog(), accessLog...)
}
}
policy, ok := pCtx.Policy.(*httpListenerOptsPlugin)
if !ok {
return eris.Errorf("internal error: expected httplistener policy, got %T", pCtx.Policy)
}
fmt.Sprintf("ACCESSLOG httplistener %v\n", policy)

// translate access logging configuration
if policy.spec.AccessLoggingService != nil {
accessLog := convertAccessLogConfig(policy.spec.AccessLoggingService)
if accessLog != nil {
out.AccessLog = append(out.GetAccessLog(), accessLog...)
}
}
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ func (p *listenerOptsPluginGwPass) ApplyListenerPlugin(ctx context.Context, pCtx
return
}

func (p *listenerOptsPluginGwPass) AddHCM(
func (p *listenerOptsPluginGwPass) ApplyHCM(
ctx context.Context,
listener ir.HttpFilterChainIR,
pCtx *ir.HcmContext,
out *envoy_hcm.HttpConnectionManager) error {
// no-op, hcm config is handled in http listener plugin
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (d *routeOptsPlugin) Equals(in any) bool {
type routeOptsPluginGwPass struct {
}

func (p *routeOptsPluginGwPass) AddHCM(ctx context.Context, listener ir.HttpFilterChainIR, out *envoyhttp.HttpConnectionManager) error {
func (p *routeOptsPluginGwPass) ApplyHCM(ctx context.Context, pCtx *ir.HcmContext, out *envoyhttp.HttpConnectionManager) error {
//TODO no op?
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions projects/gateway2/extensions2/plugins/upstream/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ func (p *plugin2) Name() string {
func (p *plugin2) ApplyListenerPlugin(ctx context.Context, pCtx *ir.ListenerContext, out *envoy_config_listener_v3.Listener) {
}

func (p *plugin2) AddHCM(ctx context.Context,
listener ir.HttpFilterChainIR,
func (p *plugin2) ApplyHCM(ctx context.Context,
pCtx *ir.HcmContext,
out *envoy_hcm.HttpConnectionManager) error { //no-op
return nil
}
Expand Down
8 changes: 6 additions & 2 deletions projects/gateway2/ir/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ type RouteContext struct {
In HttpRouteRuleMatchIR
}

type HcmContext struct {
Policy PolicyIR
}

type ProxyTranslationPass interface {
// Name() string
// called 1 time for each listener
Expand All @@ -48,8 +52,8 @@ type ProxyTranslationPass interface {
out *envoy_config_listener_v3.Listener,
)
// called 1 time per filter chain after listeners
AddHCM(ctx context.Context,
listener HttpFilterChainIR,
ApplyHCM(ctx context.Context,
pCtx *HcmContext,
out *envoy_hcm.HttpConnectionManager) error

ApplyVhostPlugin(
Expand Down
2 changes: 1 addition & 1 deletion projects/gateway2/krtcollections/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (d *builtinPlugin) Equals(in any) bool {
type builtinPluginGwPass struct {
}

func (p *builtinPluginGwPass) AddHCM(ctx context.Context, listener ir.HttpFilterChainIR, out *envoyhttp.HttpConnectionManager) error {
func (p *builtinPluginGwPass) ApplyHCM(ctx context.Context, pCtx *ir.HcmContext, out *envoyhttp.HttpConnectionManager) error {
// TODO: no-op?
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions projects/gateway2/setup/ggv2setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ func testScenario(
os.WriteFile(fout, d, 0644)
t.Fatal("wrote out file - nothing to test")
}
d, _ := dump.ToYaml()
fmt.Println(string(d))
dump.Compare(t, expectedXdsDump)
fmt.Println("test done")
}
Expand Down
122 changes: 119 additions & 3 deletions projects/gateway2/setup/testdata/accesslog-httplisteneropt-out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,65 @@ listeners:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
accessLog:
- name: envoy.access_loggers.file
typedConfig:
'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
logFormat:
formatters:
- name: envoy.formatter.req_without_query
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery
- name: envoy.formatter.metadata
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata
jsonFormat:
authority: '%REQ(:AUTHORITY)%'
bytes_received: '%BYTES_RECEIVED%'
bytes_sent: '%BYTES_SENT%'
method: '%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%'
path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
protocol: '%PROTOCOL%'
req_x_forwarded_for: '%REQ(X-FORWARDED-FOR)%'
request_id: '%REQ(X-REQUEST-ID)%'
resp_upstream_service_time: '%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%'
response_code: '%RESPONSE_CODE%'
response_flags: '%RESPONSE_FLAGS%'
start_time: '%START_TIME%'
total_duration: '%DURATION%'
upstreamCluster: '%UPSTREAM_CLUSTER%'
upstreamHost: '%UPSTREAM_HOST%'
user_agent: '%REQ(USER-AGENT)%'
path: /dev/stdout
- name: envoy.access_loggers.file
typedConfig:
'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
logFormat:
formatters:
- name: envoy.formatter.req_without_query
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery
- name: envoy.formatter.metadata
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata
jsonFormat:
authority: '%REQ(:AUTHORITY)%'
bytes_received: '%BYTES_RECEIVED%'
bytes_sent: '%BYTES_SENT%'
method: '%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%'
path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
protocol: '%PROTOCOL%'
req_x_forwarded_for: '%REQ(X-FORWARDED-FOR)%'
request_id: '%REQ(X-REQUEST-ID)%'
resp_upstream_service_time: '%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%'
response_code: '%RESPONSE_CODE%'
response_flags: '%RESPONSE_FLAGS%'
start_time: '%START_TIME%'
total_duration: '%DURATION%'
upstreamCluster: '%UPSTREAM_CLUSTER%'
upstreamHost: '%UPSTREAM_HOST%'
user_agent: '%REQ(USER-AGENT)%'
path: /dev/stdout
httpFilters:
- name: envoy.filters.http.router
typedConfig:
Expand All @@ -133,7 +192,6 @@ listeners:
statPrefix: http
name: http
name: http
perConnectionBufferLimitBytes: 42000
- address:
socketAddress:
address: '::'
Expand All @@ -144,6 +202,65 @@ listeners:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
accessLog:
- name: envoy.access_loggers.file
typedConfig:
'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
logFormat:
formatters:
- name: envoy.formatter.req_without_query
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery
- name: envoy.formatter.metadata
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata
jsonFormat:
authority: '%REQ(:AUTHORITY)%'
bytes_received: '%BYTES_RECEIVED%'
bytes_sent: '%BYTES_SENT%'
method: '%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%'
path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
protocol: '%PROTOCOL%'
req_x_forwarded_for: '%REQ(X-FORWARDED-FOR)%'
request_id: '%REQ(X-REQUEST-ID)%'
resp_upstream_service_time: '%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%'
response_code: '%RESPONSE_CODE%'
response_flags: '%RESPONSE_FLAGS%'
start_time: '%START_TIME%'
total_duration: '%DURATION%'
upstreamCluster: '%UPSTREAM_CLUSTER%'
upstreamHost: '%UPSTREAM_HOST%'
user_agent: '%REQ(USER-AGENT)%'
path: /dev/stdout
- name: envoy.access_loggers.file
typedConfig:
'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
logFormat:
formatters:
- name: envoy.formatter.req_without_query
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.req_without_query.v3.ReqWithoutQuery
- name: envoy.formatter.metadata
typedConfig:
'@type': type.googleapis.com/envoy.extensions.formatter.metadata.v3.Metadata
jsonFormat:
authority: '%REQ(:AUTHORITY)%'
bytes_received: '%BYTES_RECEIVED%'
bytes_sent: '%BYTES_SENT%'
method: '%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%'
path: '%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%'
protocol: '%PROTOCOL%'
req_x_forwarded_for: '%REQ(X-FORWARDED-FOR)%'
request_id: '%REQ(X-REQUEST-ID)%'
resp_upstream_service_time: '%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%'
response_code: '%RESPONSE_CODE%'
response_flags: '%RESPONSE_FLAGS%'
start_time: '%START_TIME%'
total_duration: '%DURATION%'
upstreamCluster: '%UPSTREAM_CLUSTER%'
upstreamHost: '%UPSTREAM_HOST%'
user_agent: '%REQ(USER-AGENT)%'
path: /dev/stdout
httpFilters:
- name: envoy.filters.http.router
typedConfig:
Expand All @@ -158,7 +275,6 @@ listeners:
statPrefix: http
name: other
name: other
perConnectionBufferLimitBytes: 42000
routes:
- ignorePortInHostMatching: true
name: http
Expand All @@ -185,4 +301,4 @@ routes:
name: other~www_example_com-route-0-httproute-reviews-gwtest-0-0-matcher-0
route:
cluster: kube_gwtest_reviews_8080
clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
3 changes: 1 addition & 2 deletions projects/gateway2/translator/gateway/gateway_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ func (t *translator) Translate(
routesForGw,
reporter,
)

// func() { panic("TODO: handle gw policy attachment") }()

return &ir.GatewayIR{
SourceObject: gateway.Obj,
Listeners: listeners,
Expand Down
38 changes: 29 additions & 9 deletions projects/gateway2/translator/irtranslator/fc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (

type filterChainTranslator struct {
listener ir.ListenerIR
gateway ir.GatewayIR
routeConfigName string

PluginPass TranslationPassPlugins
Expand Down Expand Up @@ -116,6 +117,7 @@ func (n *filterChainTranslator) computeNetworkFiltersForHttp(ctx context.Context
routeConfigName: n.routeConfigName,
PluginPass: n.PluginPass,
reporter: reporter,
gateway: n.gateway, // corresponds to Gateway API listener
}
networkFilters := sortNetworkFilters(n.computePreHCMFilters(ctx, l, reporter))
networkFilter, err := hcm.computeNetworkFilters(ctx, l)
Expand Down Expand Up @@ -180,7 +182,8 @@ type hcmNetworkFilterTranslator struct {
routeConfigName string
PluginPass TranslationPassPlugins
reporter reports.ListenerReporter
listener ir.HttpFilterChainIR // corresponds to Gateway API listener
listener ir.HttpFilterChainIR // policies attached to listener
gateway ir.GatewayIR // policies attached to gateway
}

// TODO: this runs before listeners? h.listener.attatchedPolicies is empty
Expand All @@ -194,15 +197,32 @@ func (h *hcmNetworkFilterTranslator) computeNetworkFilters(ctx context.Context,
var err error
httpConnectionManager.HttpFilters = h.computeHttpFilters(ctx, l)

pass := h.PluginPass
// 3. Allow any HCM plugins to make their changes, with respect to any changes the core plugin made
for _, hcmPlugin := range h.PluginPass {
if err := hcmPlugin.AddHCM(ctx, h.listener, httpConnectionManager); err != nil {
h.reporter.SetCondition(reports.ListenerCondition{
Type: gwv1.ListenerConditionProgrammed,
Reason: gwv1.ListenerReasonInvalid,
Status: metav1.ConditionFalse,
Message: "Error processing HCM plugin: " + err.Error(),
})
attachedPoliciesSlice := []ir.AttachedPolicies{
h.gateway.AttachedHttpPolicies,
l.AttachedPolicies,
}
for _, attachedPolicies := range attachedPoliciesSlice {
for gk, pols := range attachedPolicies.Policies {
pass := pass[gk]
if pass == nil {
// TODO: report user error - they attached a non http policy
continue
}
for _, pol := range pols {
pctx := &ir.HcmContext{
Policy: pol.PolicyIr,
}
if err := pass.ApplyHCM(ctx, pctx, httpConnectionManager); err != nil {
h.reporter.SetCondition(reports.ListenerCondition{
Type: gwv1.ListenerConditionProgrammed,
Reason: gwv1.ListenerReasonInvalid,
Status: metav1.ConditionFalse,
Message: "Error processing HCM plugin: " + err.Error(),
})
}
}
}
}
// TODO: should we enable websockets by default?
Expand Down
2 changes: 2 additions & 0 deletions projects/gateway2/translator/irtranslator/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (t *Translator) ComputeListener(ctx context.Context, pass TranslationPassPl
for _, hfc := range l.HttpFilterChain {
fct := filterChainTranslator{
listener: l,
gateway: gw,
routeConfigName: hfc.FilterChainName,
PluginPass: pass,
}
Expand Down Expand Up @@ -85,6 +86,7 @@ func (t *Translator) ComputeListener(ctx context.Context, pass TranslationPassPl

fct := filterChainTranslator{
listener: l,
gateway: gw,
PluginPass: pass,
}

Expand Down
Loading

0 comments on commit cda3374

Please sign in to comment.