Skip to content

Commit 44cc215

Browse files
scotwellsclaude
andcommitted
Gate the programmed-set debug endpoint to the test environment
The endpoint that reports what the last build intended to change exists only so a test can confirm the proxy is running exactly that set. Serve it (and do the per-build recording that backs it) only when the --enable-programmed-set flag is passed, so production exposes nothing and does no extra work on the build path. The flag joins the extension-server flag surface and is wired through the deployment the same way as the others: an arg that reads an env var (ENABLE_PROGRAMMED_SET), defaulting off, so an overlay can turn it on with a strategic-merge patch on env instead of rewriting the args list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JbCy8vy66RdNYzGSgqH6P6
1 parent e6ffdae commit 44cc215

4 files changed

Lines changed: 60 additions & 17 deletions

File tree

config/extension-server/deployment.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ spec:
5858
- --tls-key=$(TLS_KEY)
5959
- --tls-client-ca=$(TLS_CLIENT_CA)
6060
- --server-config=$(SERVER_CONFIG)
61+
- --enable-programmed-set=$(ENABLE_PROGRAMMED_SET)
6162
env:
6263
- name: GRPC_ADDR
6364
value: ":5005"
@@ -73,6 +74,11 @@ spec:
7374
# mounted path to apply Coraza directives.
7475
- name: SERVER_CONFIG
7576
value: ""
77+
# Off in production. The test-environment overlay sets this to "true"
78+
# to serve the read-only /debug/programmed-set endpoint the parity
79+
# test reads.
80+
- name: ENABLE_PROGRAMMED_SET
81+
value: "false"
7682
ports:
7783
- name: grpc
7884
containerPort: 5005

internal/extensionserver/cmd/run.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ func envBool(key string, def bool) bool {
6868
// --tls-key=/tls/tls.key
6969
// --tls-client-ca=/tls/ca.crt
7070
// --server-config=/config/config.yaml (optional; provides Coraza WAF config)
71+
// --enable-programmed-set=false (default off; test environments set true)
7172
type options struct {
72-
grpcAddr string
73-
healthAddr string
74-
tlsCert string
75-
tlsKey string
76-
tlsClientCA string
77-
serverCfgFile string
73+
grpcAddr string
74+
healthAddr string
75+
tlsCert string
76+
tlsKey string
77+
tlsClientCA string
78+
serverCfgFile string
79+
enableProgrammedSet bool
7880
}
7981

8082
// NewCommand returns the "extension-server" subcommand.
@@ -99,6 +101,8 @@ func NewCommand() *cobra.Command {
99101
fs.StringVar(&o.tlsKey, "tls-key", "", "Path to server TLS key (PEM)")
100102
fs.StringVar(&o.tlsClientCA, "tls-client-ca", "", "Path to client CA certificate (PEM) for mTLS")
101103
fs.StringVar(&o.serverCfgFile, "server-config", "", "Path to operator config file (optional; provides Coraza WAF settings)")
104+
fs.BoolVar(&o.enableProgrammedSet, "enable-programmed-set", false,
105+
"Serve the read-only /debug/programmed-set endpoint used by the parity test (test environments only)")
102106

103107
cmd := &cobra.Command{
104108
Use: "envoy-gateway-extension-server",
@@ -258,6 +262,9 @@ func run(o options) {
258262
ConnectorInternalListener: serverConfig.Gateway.ConnectorTunnelListenerName(),
259263
CorazaRouteBaseDirectives: coraza.RouteBaseDirectives,
260264
LocalReply: buildLocalReplyConfig(serverConfig.Gateway.ErrorPage, log),
265+
// The programmed-set debug endpoint is for the test environment only; it
266+
// stays off in production unless --enable-programmed-set is passed.
267+
EnableProgrammedSet: o.enableProgrammedSet,
261268
}
262269

263270
// --- gRPC panic recovery interceptor ---
@@ -450,9 +457,12 @@ func run(o options) {
450457
}
451458
})
452459
mux.Handle("/metrics", promhttp.Handler())
453-
// Debug endpoint that reports what the last build changed, so a test can
454-
// confirm the proxy is running exactly that. Read-only; keeps only the last build.
455-
mux.HandleFunc(extserver.ProgrammedSetEndpointPath, extSrv.ProgrammedSetHandler())
460+
// Read-only debug endpoint that reports what the last build changed, so a test
461+
// can confirm the proxy is running exactly that. Test environment only; it is
462+
// not served in production. Keeps only the last build.
463+
if srvCfg.EnableProgrammedSet {
464+
mux.HandleFunc(extserver.ProgrammedSetEndpointPath, extSrv.ProgrammedSetHandler())
465+
}
456466
healthServer := &http.Server{
457467
Addr: healthAddr,
458468
Handler: mux,

internal/extensionserver/server/programmedset_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ func TestPostTranslateModify_RecordsProgrammedSet(t *testing.T) {
306306
cl := fake.NewClientBuilder().WithScheme(scheme).
307307
WithObjects(ns, tpp, proxy).
308308
WithStatusSubresource(connector).WithObjects(connector).Build()
309-
srv := New(cl, testServerConfig(), discardLogger())
309+
// Recording only happens when the test-environment endpoint is enabled.
310+
cfg := testServerConfig()
311+
cfg.EnableProgrammedSet = true
312+
srv := New(cl, cfg, discardLogger())
310313

311314
req := &pb.PostTranslateModifyRequest{
312315
Clusters: []*clusterv3.Cluster{{Name: connCluster}, {Name: "infra-cluster"}},
@@ -342,3 +345,19 @@ func TestPostTranslateModify_RecordsProgrammedSet(t *testing.T) {
342345
require.Len(t, ps.Keys[FamilyWAFRoute], 1)
343346
assert.Contains(t, ps.Keys[FamilyWAFRoute][0], "test-project/test-tpp/Observe")
344347
}
348+
349+
// TestPostTranslateModify_NoRecordingWhenDisabled proves the production default:
350+
// with the test-only endpoint off, a build records nothing, so the snapshot
351+
// stays empty and no per-build work is done.
352+
func TestPostTranslateModify_NoRecordingWhenDisabled(t *testing.T) {
353+
cl := fake.NewClientBuilder().WithScheme(testServerScheme(t)).Build()
354+
// testServerConfig() leaves EnableProgrammedSet at its false default.
355+
srv := New(cl, testServerConfig(), discardLogger())
356+
357+
_, err := srv.PostTranslateModify(context.Background(), &pb.PostTranslateModifyRequest{})
358+
require.NoError(t, err)
359+
360+
ps := srv.programmed.snapshot()
361+
assert.Equal(t, uint64(0), ps.BuildID, "no build was recorded")
362+
assert.Empty(t, ps.Keys, "nothing recorded while the endpoint is disabled")
363+
}

internal/extensionserver/server/server.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type ServerConfig struct {
3737
// empty, local-reply injection is a no-op. Sourced from
3838
// GatewayConfig.ErrorPage + the embedded/override HTML body.
3939
LocalReply mutate.LocalReplyConfig
40+
// EnableProgrammedSet turns on the read-only /debug/programmed-set endpoint
41+
// and the per-build recording that backs it. It exists only to let a test
42+
// confirm the proxy is running exactly the set the build intended, so it is
43+
// off in production and enabled only in the test environment. When off, the
44+
// build does no extra work and the endpoint is not served.
45+
EnableProgrammedSet bool
4046
}
4147

4248
// Server implements pb.EnvoyGatewayExtensionServer for the NSO production
@@ -332,13 +338,15 @@ func (s *Server) PostTranslateModify(
332338
extmetrics.ConnectorRoutesTotal.Add(float64(vhCount))
333339
extmetrics.ConnectorOfflineRoutesTotal.Add(float64(offlineRtCount))
334340

335-
// Record what this build changed so a test can later confirm the proxy is
336-
// running exactly that. This only reads the configuration just produced; it
337-
// changes nothing.
338-
s.programmed.record(
339-
listeners, routes, clusters, s.cfg.Coraza.FilterName,
340-
prunedChains, prunedSecrets, listenersLeftIntact,
341-
)
341+
// In the test environment, record what this build changed so a test can later
342+
// confirm the proxy is running exactly that. This only reads the configuration
343+
// just produced; it changes nothing. Off in production, where it does no work.
344+
if s.cfg.EnableProgrammedSet {
345+
s.programmed.record(
346+
listeners, routes, clusters, s.cfg.Coraza.FilterName,
347+
prunedChains, prunedSecrets, listenersLeftIntact,
348+
)
349+
}
342350

343351
s.log.Info("PostTranslateModify",
344352
"clusters", len(clusters),

0 commit comments

Comments
 (0)