Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ spec:
x-kubernetes-list-type: map
serial:
description: Serial increases on each content change.
format: int32
format: int64
maximum: 4294967295
minimum: 1
type: integer
Expand Down Expand Up @@ -212,7 +212,7 @@ spec:
format: date-time
type: string
serial:
format: int32
format: int64
maximum: 4294967295
minimum: 1
type: integer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ spec:
x-kubernetes-list-type: map
serial:
description: Serial increases on each content change.
format: int32
format: int64
maximum: 4294967295
minimum: 1
type: integer
Expand Down Expand Up @@ -212,7 +212,7 @@ spec:
format: date-time
type: string
serial:
format: int32
format: int64
maximum: 4294967295
minimum: 1
type: integer
Expand Down
84 changes: 84 additions & 0 deletions pkg/go/api/hosted/v1alpha1/envtest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package v1alpha1

import (
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
)

// The in-process schema validator does not apply the apiserver's
// format-aware bound check; a uint32 serial generated with format int32 and
// maximum 4294967295 was rejected live ("Maximum boundary value must be of
// type integer with format int32"). Admit the full serial range through a
// real apiserver.
func TestHostedZoneSerialRangeAdmittedByAPIServer(t *testing.T) {
assets := os.Getenv("KUBEBUILDER_ASSETS")
if assets == "" {
t.Skip("KUBEBUILDER_ASSETS is required for the real CRD admission test")
}
environment := &envtest.Environment{
BinaryAssetsDirectory: assets,
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "..", "app", "operator", "config", "crd", "bases")},
ErrorIfCRDPathMissing: true,
ControlPlaneStartTimeout: 30 * time.Second,
ControlPlaneStopTimeout: 15 * time.Second,
}
t.Cleanup(func() {
if err := environment.Stop(); err != nil {
t.Errorf("stop envtest: %v", err)
}
})
cfg, err := environment.Start()
if err != nil {
t.Fatal(err)
}
s := runtime.NewScheme()
if err := scheme.AddToScheme(s); err != nil {
t.Fatal(err)
}
if err := AddToScheme(s); err != nil {
t.Fatal(err)
}
c, err := client.New(cfg, client.Options{Scheme: s})
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
if err := c.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "dns"}}); err != nil {
t.Fatal(err)
}
digest := "sha256:" + strings.Repeat("a", 64)
for _, serial := range []uint32{1, 2147483648, ^uint32(0)} {
zone := &HostedZone{
ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "dns"},
Spec: HostedZoneSpec{
DomainName: "example.test",
Serial: serial,
SOA: SOA{MName: "ns.example.test", RName: "hostmaster.example.test", Refresh: 3600, Retry: 900, Expire: 1209600, Minimum: 300},
NameServers: []NameServer{{Name: "ns.example.test", Addresses: []string{"192.0.2.53"}}},
Records: []HostedZoneRecord{{Name: "@", Type: "A", TTL: 60, Values: []string{"192.0.2.1"}}},
ContentDigest: digest,
},
}
if err := c.Create(ctx, zone); err != nil {
t.Fatalf("serial %d rejected: %v", serial, err)
}
zone.Status.Servers = []HostedZoneServerStatus{{Endpoint: "dns/server", Serial: serial, ContentDigest: digest, ObservedAt: metav1.Now()}}
if err := c.Status().Update(ctx, zone); err != nil {
t.Fatalf("status serial %d rejected: %v", serial, err)
}
if err := c.Delete(ctx, zone); err != nil {
t.Fatal(err)
}
}
}
2 changes: 2 additions & 0 deletions pkg/go/api/hosted/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type HostedZoneSpec struct {
// Serial increases on each content change.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=4294967295
// +kubebuilder:validation:Format=int64
Serial uint32 `json:"serial"`

SOA SOA `json:"soa"`
Expand Down Expand Up @@ -185,6 +186,7 @@ type HostedZoneServerStatus struct {
Endpoint string `json:"endpoint"`
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=4294967295
// +kubebuilder:validation:Format=int64
Serial uint32 `json:"serial"`
// +kubebuilder:validation:Pattern=`^sha256:[0-9a-f]{64}$`
ContentDigest string `json:"contentDigest"`
Expand Down
Loading