// Package kubesource turns fancy-dns custom resources (DNSZone, ClientGroup, // BlockList) into the runtime's own configuration types. It is read-only: the // runtime watches the cluster and never writes to it. // // Objects are decoded from unstructured data into the plain structs below, so // there is no generated clientset or deepcopy code to keep in step with the // CRD manifests in deploy/k8s/crds. package kubesource import ( "k8s.io/apimachinery/pkg/runtime/schema" "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" ) // APIGroup and Version name the custom resources. const ( APIGroup = "fancydns.k6n.net" Version = "v1alpha1" ) // The resources the runtime watches. var ( ZoneGVR = schema.GroupVersionResource{Group: APIGroup, Version: Version, Resource: "dnszones"} GroupGVR = schema.GroupVersionResource{Group: APIGroup, Version: Version, Resource: "clientgroups"} ListGVR = schema.GroupVersionResource{Group: APIGroup, Version: Version, Resource: "blocklists"} allGVRs = []schema.GroupVersionResource{ZoneGVR, GroupGVR, ListGVR} kindNames = map[string]string{ZoneGVR.Resource: "DNSZone", GroupGVR.Resource: "ClientGroup", ListGVR.Resource: "BlockList"} ) // DNSZoneSpec declares one authoritative zone. The zone's name is spec.zone, // not metadata.name, because a DNS name is not always a legal object name. type DNSZoneSpec struct { Zone string `json:"zone"` // TTL is the zone's $TTL and SOA minimum; 0 means the writer's default. TTL uint32 `json:"ttl,omitempty"` // SOA is the SOA rdata ("ns1.example.com. hostmaster.example.com. ..."), // or empty to synthesise one from the first apex NS record. SOA string `json:"soa,omitempty"` Records []ZoneRecord `json:"records,omitempty"` } // ZoneRecord is one resource record. Value is presentation-format RDATA. type ZoneRecord struct { Name string `json:"name"` Type string `json:"type"` TTL uint32 `json:"ttl,omitempty"` Value string `json:"value"` } // ClientGroupSpec mirrors config.Group. The group's name is metadata.name. // Groups are evaluated first-match-wins, so Priority orders them: lower runs // first, ties break on name. type ClientGroupSpec struct { Priority int32 `json:"priority,omitempty"` Comment string `json:"comment,omitempty"` Match config.Match `json:"match"` Policy string `json:"policy"` AllowDomains []string `json:"allow_domains,omitempty"` DenyDomains []string `json:"deny_domains,omitempty"` SkipBlocklist bool `json:"skip_blocklist,omitempty"` SkipCache bool `json:"skip_cache,omitempty"` RateLimit int `json:"rate_limit,omitempty"` MaxConcurrent int `json:"max_concurrent,omitempty"` LogQueries bool `json:"log_queries,omitempty"` Upstreams []string `json:"upstreams,omitempty"` } // BlockListSpec mirrors config.ListSource for a remote list. There is no path // field on purpose: a namespace-scoped object must not be able to name a file // the runtime reads or writes. file:// URLs are refused for the same reason. type BlockListSpec struct { URL string `json:"url"` Format string `json:"format,omitempty"` Mirror []string `json:"mirror,omitempty"` Disabled bool `json:"disabled,omitempty"` Refresh string `json:"refresh,omitempty"` Timeout string `json:"timeout,omitempty"` MaxBytes int64 `json:"max_bytes,omitempty"` Categories []string `json:"categories,omitempty"` Comment string `json:"comment,omitempty"` InsecureSkipTLSVerify bool `json:"insecure_skip_tls_verify,omitempty"` }