Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
abf6995
feat: Define private DNS access and publication APIs
scotwells Oct 9, 2026
1c14a23
refactor: Keep DNS changes ready for review
scotwells Oct 9, 2026
ad550b6
fix: Pin private zone lifetimes and bound dynamic TTLs
scotwells Oct 9, 2026
e29c489
Install private DNS CRDs and validate stacked pull requests
scotwells Oct 12, 2026
d6c23b1
Validate private DNS API contracts with schemas and CEL
scotwells Oct 12, 2026
76db28d
Authorize private DNS resource access through API server policies
scotwells Oct 12, 2026
dda160b
Keep private DNS admission constants and roles consistent
scotwells Oct 12, 2026
7c1951e
Use the DNSNamingPolicy resource name in IAM definitions
scotwells Oct 12, 2026
3c0a261
Validate inactive contribution epoch binding without publisher observ…
scotwells Oct 12, 2026
a94ef2a
fix: Keep DNS APIs context scoped
scotwells Oct 13, 2026
ecf33ff
fix: Keep DNS API state persistent
scotwells Oct 13, 2026
9badbca
refactor: Simplify private DNS publication APIs
scotwells Oct 13, 2026
b5cff18
refactor: Keep DNS permissions aligned with APIs
scotwells Oct 13, 2026
e26515d
fix: Keep DNS review branches buildable
scotwells Oct 13, 2026
7badaf4
fix: Align DNS validation and permission checks
scotwells Oct 13, 2026
c2ff425
docs: Describe DNS mapping validation
scotwells Oct 13, 2026
63ae179
feat: Simplify private DNS publication and access
scotwells Oct 13, 2026
9b8b32b
fix: allow DNS contribution refresh and cleanup
scotwells Oct 22, 2026
469e97d
chore: Remove committed internal DNS kind output
scotwells Oct 22, 2026
3df4347
feat: Serve the private DNS reference checks from the dns-operator we…
scotwells Oct 22, 2026
ef37146
fix: Pin private DNS reference identity and bound registration lists
scotwells Oct 22, 2026
bcf021f
fix: leave the deployed internal DNS webhook registration to the cont…
scotwells Oct 22, 2026
1ebeca9
fix: tighten private DNS project API bounds and admission checks
scotwells Oct 22, 2026
1b642a7
style: gofmt the private DNS project API fields
scotwells Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ on:
branches:
- main
pull_request:
branches:
- main

jobs:
e2e:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ go.work.sum
.claude/settings.local.json
.claude/worktrees/
.mcp.json

# Local kind output from the internal DNS end-to-end harness (includes kubeconfigs)
.internal-dns-e2e/
17 changes: 17 additions & 0 deletions api/v1alpha1/internaldns_access_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package v1alpha1

import (
"encoding/json"
"testing"
)

func TestResolverAccessHasNoExpiryOrClusterIdentity(t *testing.T) {
a := DNSResolverAccessVersion{Epoch: 1, Sequence: 2}
b, err := json.Marshal(a)
if err != nil {
t.Fatal(err)
}
if string(b) != `{"epoch":1,"sequence":2}` {
t.Fatalf("unexpected access fence: %s", b)
}
}
67 changes: 67 additions & 0 deletions api/v1alpha1/internaldns_context_boundary_envtest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: AGPL-3.0-only

package v1alpha1

import (
"context"
"testing"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func validateResolverContextBoundaries(t *testing.T, cl client.Client) {
t.Helper()
for _, kind := range []string{"DNSZoneAssociation", "DNSNamingPolicy"} {
t.Run(kind+"-context-boundary", func(t *testing.T) {
newObject := func(name string) *unstructured.Unstructured {
return &unstructured.Unstructured{Object: map[string]any{
"apiVersion": GroupVersion.String(), "kind": kind,
"metadata": map[string]any{"name": name, "namespace": "validation"},
"spec": map[string]any{
"dnsZoneRef": map[string]any{"name": "zone", "uid": "zone-uid"},
"additionalNames": []any{},
},
}}
}
ctx := context.Background()
for _, ref := range []map[string]any{nil, {"name": ""}, {"name": "", "uid": "context-uid"}} {
o := newObject("context-required")
if ref != nil {
if err := unstructured.SetNestedMap(o.Object, ref, "spec", "resolverContextRef"); err != nil {
t.Fatal(err)
}
}
if err := unstructured.SetNestedMap(o.Object, map[string]any{"name": "network", "uid": "network-uid"}, "spec", "vpcRef"); err != nil {
t.Fatal(err)
}
if err := cl.Create(ctx, o); !apierrors.IsInvalid(err) {
t.Fatalf("expected rejection without a named DNS context, got %v", err)
}
}
o := newObject("context-selected")
if err := unstructured.SetNestedMap(o.Object, map[string]any{"name": "context", "uid": "context-uid"}, "spec", "resolverContextRef"); err != nil {
t.Fatal(err)
}
if err := unstructured.SetNestedMap(o.Object, map[string]any{"name": "network", "uid": "network-uid"}, "spec", "vpcRef"); err != nil {
t.Fatal(err)
}
if err := cl.Create(ctx, o); err != nil {
t.Fatal(err)
}
if err := cl.Get(ctx, client.ObjectKeyFromObject(o), o); err != nil {
t.Fatal(err)
}
if _, found, err := unstructured.NestedMap(o.Object, "spec", "vpcRef"); err != nil || found {
t.Fatalf("network reference was retained in the DNS API: found=%t err=%v", found, err)
}
if err := unstructured.SetNestedMap(o.Object, map[string]any{"name": "", "uid": "context-uid"}, "spec", "resolverContextRef"); err != nil {
t.Fatal(err)
}
if err := cl.Update(ctx, o); !apierrors.IsInvalid(err) {
t.Fatalf("expected rejection when clearing the DNS context, got %v", err)
}
})
}
}
Loading
Loading