Skip to content

Commit 319dd49

Browse files
committed
refactor
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
1 parent 0c6e8c6 commit 319dd49

7 files changed

Lines changed: 229 additions & 79 deletions

File tree

internal/controller/filter_config_bundle.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func splitBytes(raw []byte, chunkSize int) [][]byte {
4343
return chunks
4444
}
4545

46-
func (c *GatewayController) writeFilterConfigBundle(ctx context.Context, indexSecretName, configSecretNamespace string, payload []byte, uuid string) error {
46+
func (c *GatewayController) writeFilterConfigBundle(ctx context.Context, gatewayName, gatewayNamespace, configSecretNamespace string, payload []byte, uuid string) error {
47+
indexSecretName := FilterConfigBundleIndexSecretName(gatewayName, gatewayNamespace)
4748
chunks := splitBytes(payload, filterConfigBundlePartSizeBytes)
4849
if len(chunks) > maxFilterConfigBundleSlots {
4950
return fmt.Errorf("filter config requires %d shards, exceeds max supported slots %d", len(chunks), maxFilterConfigBundleSlots)
@@ -56,8 +57,8 @@ func (c *GatewayController) writeFilterConfigBundle(ctx context.Context, indexSe
5657
}
5758

5859
// Create parts Secrets
59-
for i := 0; i < maxFilterConfigBundleSlots; i++ {
60-
partName := filterConfigBundlePartSecretName(indexSecretName, i)
60+
for i := range maxFilterConfigBundleSlots {
61+
partName := filterConfigBundlePartSecretName(gatewayName, gatewayNamespace, i)
6162
chunkPayload := ""
6263
partSize := 0
6364
if i < len(chunks) {

internal/controller/gateway.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,7 @@ func (c *GatewayController) reconcileFilterConfigSecret(
448448
if err != nil {
449449
return false, fmt.Errorf("failed to marshal extproc config: %w", err)
450450
}
451-
configBundleIndexSecretName := FilterConfigBundleIndexSecretName(gatewayName, gatewayNamespace)
452-
if err = c.writeFilterConfigBundle(ctx, configBundleIndexSecretName, configSecretNamespace, marshaled, uuid); err != nil {
451+
if err = c.writeFilterConfigBundle(ctx, gatewayName, gatewayNamespace, configSecretNamespace, marshaled, uuid); err != nil {
453452
return false, err
454453
}
455454
// TODO(huabing): this can be removed in the next release.
@@ -466,7 +465,7 @@ func (c *GatewayController) writeLegacyFilterConfigSecret(
466465
configSecretNamespace string,
467466
marshaled []byte,
468467
) error {
469-
legacySecretName := LegacyFilterConfigSecretName(gatewayName, gatewayNamespace)
468+
legacySecretName := legacyFilterConfigSecretName(gatewayName, gatewayNamespace)
470469

471470
// Create legacy secret only if the content still fit Kubernetes limits.
472471
if len(legacySecretName) > k8sObjectNameMaxLen || len(marshaled) > corev1.MaxSecretSize {

internal/controller/gateway_mutator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func (g *gatewayMutator) mutatePod(ctx context.Context, pod *corev1.Pod, gateway
288288
// Prefer bundled config when available/valid, and fall back to legacy config for compatibility.
289289
// If neither exists, skip mutation to avoid blocking Envoy pod creation.
290290
// The controller will later trigger new pod mutations by updating pod/deployment annotations when the config secrets are created.
291-
legacyConfigSecretName := LegacyFilterConfigSecretName(gatewayName, gatewayNamespace)
291+
legacyConfigSecretName := legacyFilterConfigSecretName(gatewayName, gatewayNamespace)
292292
bundleConfigIndexSecretName := FilterConfigBundleIndexSecretName(gatewayName, gatewayNamespace)
293293

294294
bundleConfigIndexSecret, err := g.kube.CoreV1().Secrets(pod.Namespace).Get(ctx, bundleConfigIndexSecretName, metav1.GetOptions{})
@@ -322,7 +322,7 @@ func (g *gatewayMutator) mutatePod(ctx context.Context, pod *corev1.Pod, gateway
322322
}
323323

324324
// Now we construct the AI Gateway managed containers and volumes.
325-
filterConfigVolumeName := filterConfigVolumeName(gatewayName, gatewayNamespace)
325+
filterConfigVolumeName := legacyFilterConfigVolumeName(gatewayName, gatewayNamespace)
326326
filterConfigBundleVolumeName := filterConfigBundleVolumeName(gatewayName, gatewayNamespace)
327327
const extProcUDSVolumeName = mutationNamePrefix + "extproc-uds"
328328
volumes := []corev1.Volume{
@@ -361,7 +361,7 @@ func (g *gatewayMutator) mutatePod(ctx context.Context, pod *corev1.Pod, gateway
361361
projections = append(projections, corev1.VolumeProjection{
362362
Secret: &corev1.SecretProjection{
363363
LocalObjectReference: corev1.LocalObjectReference{
364-
Name: filterConfigBundlePartSecretName(bundleConfigIndexSecretName, i),
364+
Name: filterConfigBundlePartSecretName(gatewayName, gatewayNamespace, i),
365365
},
366366
Items: []corev1.KeyToPath{
367367
{

internal/controller/gateway_mutator_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ func TestGatewayMutator_mutatePod(t *testing.T) {
417417
require.NoError(t, idxErr)
418418
_, err = g.kube.CoreV1().Secrets("test-namespace").Create(t.Context(),
419419
&corev1.Secret{
420-
ObjectMeta: metav1.ObjectMeta{Name: LegacyFilterConfigSecretName(
420+
ObjectMeta: metav1.ObjectMeta{Name: legacyFilterConfigSecretName(
421421
gwName, gwNamespace,
422422
), Namespace: "test-namespace"},
423423
Data: map[string][]byte{
@@ -527,7 +527,7 @@ func TestGatewayMutator_mutatePod_BundleOnly(t *testing.T) {
527527
require.Contains(t, extProcContainer.Args, "-configBundlePath")
528528
require.NotContains(t, extProcContainer.Args, "-configPath")
529529

530-
legacySecretName := LegacyFilterConfigSecretName(gwName, gwNamespace)
530+
legacySecretName := legacyFilterConfigSecretName(gwName, gwNamespace)
531531
for i := range pod.Spec.Volumes {
532532
v := pod.Spec.Volumes[i]
533533
if v.Secret != nil {
@@ -560,7 +560,7 @@ func TestGatewayMutator_mutatePod_LegacyOnly(t *testing.T) {
560560

561561
_, err = g.kube.CoreV1().Secrets(gwNamespace).Create(t.Context(),
562562
&corev1.Secret{
563-
ObjectMeta: metav1.ObjectMeta{Name: LegacyFilterConfigSecretName(gwName, gwNamespace), Namespace: gwNamespace},
563+
ObjectMeta: metav1.ObjectMeta{Name: legacyFilterConfigSecretName(gwName, gwNamespace), Namespace: gwNamespace},
564564
Data: map[string][]byte{FilterConfigKeyInSecret: []byte("version: dev\n")},
565565
}, metav1.CreateOptions{})
566566
require.NoError(t, err)

internal/controller/gateway_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,12 +1270,14 @@ func TestGatewayController_writeFilterConfigBundleShards(t *testing.T) {
12701270
"docker.io/envoyproxy/ai-gateway-extproc:latest", "info", false, nil, true)
12711271

12721272
namespace := "ns"
1273-
secretName := "cfg"
1273+
gatewayName := "cfg-gw"
1274+
gatewayNamespace := "cfg-ns"
12741275
payload := []byte(strings.Repeat("x", filterConfigBundlePartSizeBytes*2+10))
1275-
err := c.writeFilterConfigBundle(t.Context(), secretName, namespace, payload, "uuid-1")
1276+
err := c.writeFilterConfigBundle(t.Context(), gatewayName, gatewayNamespace, namespace, payload, "uuid-1")
12761277
require.NoError(t, err)
12771278

1278-
indexSecret, err := kube.CoreV1().Secrets(namespace).Get(t.Context(), secretName, metav1.GetOptions{})
1279+
indexSecretName := FilterConfigBundleIndexSecretName(gatewayName, gatewayNamespace)
1280+
indexSecret, err := kube.CoreV1().Secrets(namespace).Get(t.Context(), indexSecretName, metav1.GetOptions{})
12791281
require.NoError(t, err)
12801282
indexRaw, ok := indexSecret.StringData[FilterConfigBundleIndexKey]
12811283
if !ok {
@@ -1296,7 +1298,7 @@ func TestGatewayController_writeFilterConfigBundleShards(t *testing.T) {
12961298
require.True(t, partOK)
12971299
}
12981300
lastSlot, err := kube.CoreV1().Secrets(namespace).Get(t.Context(),
1299-
filterConfigBundlePartSecretName(secretName, maxFilterConfigBundleSlots-1), metav1.GetOptions{})
1301+
filterConfigBundlePartSecretName(gatewayName, gatewayNamespace, maxFilterConfigBundleSlots-1), metav1.GetOptions{})
13001302
require.NoError(t, err)
13011303
require.Empty(t, lastSlot.StringData[FilterConfigBundlePartKey])
13021304
_, legacyOK := indexSecret.StringData[FilterConfigKeyInSecret]
@@ -1311,7 +1313,7 @@ func TestGatewayController_writeFilterConfigBundleShards_Overflow(t *testing.T)
13111313
"docker.io/envoyproxy/ai-gateway-extproc:latest", "info", false, nil, true)
13121314

13131315
payload := []byte(strings.Repeat("x", filterConfigBundlePartSizeBytes*(maxFilterConfigBundleSlots+1)))
1314-
err := c.writeFilterConfigBundle(t.Context(), "cfg", "ns", payload, "uuid-1")
1316+
err := c.writeFilterConfigBundle(t.Context(), "cfg-gw", "cfg-ns", "ns", payload, "uuid-1")
13151317
require.ErrorContains(t, err, "exceeds max supported slots")
13161318
}
13171319

internal/controller/secret_name.go

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ func shortStableHash(value string) string {
2323
return hex.EncodeToString(sum[:6])
2424
}
2525

26-
func boundedBaseWithHash(base, hash string, maxLen int) string {
26+
// truncate base to fit maxLen and append hash, hash is included in maxLen
27+
func truncateAndAppendHash(base, hash string, maxLen int) string {
2728
base = strings.Trim(base, "-")
2829
name := fmt.Sprintf("%s-%s", base, hash)
2930
if len(name) <= maxLen {
@@ -43,46 +44,43 @@ func boundedBaseWithHash(base, hash string, maxLen int) string {
4344
return fmt.Sprintf("%s-%s", trimmedBase, hash)
4445
}
4546

47+
// example: gateway-ns1-c6d39be275c7
4648
func FilterConfigBundleIndexSecretName(gwName, gwNamespace string) string {
4749
rawIdentity := fmt.Sprintf("%s/%s", gwNamespace, gwName)
48-
return boundedBaseWithHash(LegacyFilterConfigSecretName(gwName, gwNamespace), shortStableHash(rawIdentity), k8sObjectNameMaxLen)
50+
return truncateAndAppendHash(legacyFilterConfigSecretName(gwName, gwNamespace), shortStableHash(rawIdentity), k8sObjectNameMaxLen)
4951
}
5052

51-
func filterConfigBundlePartSecretName(baseSecretName string, idx int) string {
53+
// example: gateway-ns1-c6d39be275c7-part-000
54+
func filterConfigBundlePartSecretName(gwName, gwNamespace string, idx int) string {
55+
rawIdentity := fmt.Sprintf("%s/%s", gwNamespace, gwName)
56+
hash := shortStableHash(rawIdentity)
57+
base := fmt.Sprintf("%s-%s", gwName, gwNamespace)
5258
suffix := fmt.Sprintf("-part-%03d", idx)
53-
maxNameLen := k8sObjectNameMaxLen - len(suffix)
54-
55-
// Preserve full identity hash (the trailing "-<12hex>") when deriving part names.
56-
lastDash := strings.LastIndex(baseSecretName, "-")
57-
if lastDash > 0 {
58-
hash := baseSecretName[lastDash+1:]
59-
if len(hash) == 12 {
60-
prefix := baseSecretName[:lastDash]
61-
return boundedBaseWithHash(prefix, hash, maxNameLen) + suffix
62-
}
63-
}
59+
maxNameLen := k8sObjectNameMaxLen - len(hash) - len(suffix) - 1
6460

65-
// Fallback for unexpected base names that do not carry a hash suffix.
66-
if len(baseSecretName) > maxNameLen {
67-
baseSecretName = strings.TrimRight(baseSecretName[:maxNameLen], "-")
61+
if len(base) > maxNameLen {
62+
base = strings.TrimRight(base[:maxNameLen], "-")
6863
}
69-
return baseSecretName + suffix
64+
return base + "-" + hash + suffix
7065
}
7166

72-
func LegacyFilterConfigSecretName(gwName, gwNamespace string) string {
73-
return fmt.Sprintf("%s-%s", gwName, gwNamespace)
67+
// example: ai-gateway-gateway-ns1-c6d39be275c7-bundle
68+
func filterConfigBundleVolumeName(gwName, gwNamespace string) string {
69+
const suffix = "-bundle"
70+
rawIdentity := fmt.Sprintf("%s/%s", gwNamespace, gwName)
71+
volumeBase := fmt.Sprintf("%s%s-%s", mutationNamePrefix, gwName, gwNamespace)
72+
base := truncateAndAppendHash(volumeBase, shortStableHash(rawIdentity), k8sVolumeNameMaxLen-len(suffix))
73+
return base + suffix
7474
}
7575

76-
func filterConfigVolumeName(gwName, gwNamespace string) string {
77-
rawIdentity := fmt.Sprintf("%s/%s", gwNamespace, gwName)
78-
legacyVolumeBase := mutationNamePrefix + LegacyFilterConfigSecretName(gwName, gwNamespace)
79-
return boundedBaseWithHash(legacyVolumeBase, shortStableHash(rawIdentity), k8sVolumeNameMaxLen)
76+
// example: gateway-ns1
77+
func legacyFilterConfigSecretName(gwName, gwNamespace string) string {
78+
return fmt.Sprintf("%s-%s", gwName, gwNamespace)
8079
}
8180

82-
func filterConfigBundleVolumeName(gwName, gwNamespace string) string {
83-
const suffix = "-bundle"
81+
// example: ai-gateway-gw-default-3d45476e8d68
82+
func legacyFilterConfigVolumeName(gwName, gwNamespace string) string {
8483
rawIdentity := fmt.Sprintf("%s/%s", gwNamespace, gwName)
85-
legacyVolumeBase := mutationNamePrefix + LegacyFilterConfigSecretName(gwName, gwNamespace)
86-
base := boundedBaseWithHash(legacyVolumeBase, shortStableHash(rawIdentity), k8sVolumeNameMaxLen-len(suffix))
87-
return base + suffix
84+
volumeBase := fmt.Sprintf("%s%s-%s", mutationNamePrefix, gwName, gwNamespace)
85+
return truncateAndAppendHash(volumeBase, shortStableHash(rawIdentity), k8sVolumeNameMaxLen)
8886
}

0 commit comments

Comments
 (0)