4092a25f4f
Uses internetsystemsconsortium/bind9 as the default base image instead of a self-hosted one, verified against internetsystemsconsortium/bind9:9.20 (runs as root; named/rndc/nsupdate at /usr/sbin,/usr/sbin,/usr/bin). - project operator config at /etc/bind-operator instead of overmounting the image's /etc/bind (keeps bind.keys / base config intact) - reference named/rndc/nsupdate by absolute path (exec PATH may exclude /usr/sbin) - centralise filesystem + binary paths in internal/bind/consts.go - default spec.image to internetsystemsconsortium/bind9:9.20
114 lines
3.3 KiB
Go
114 lines
3.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
|
|
bindv1alpha1 "git.unkin.net/unkin/bind-operator/api/v1alpha1"
|
|
"git.unkin.net/unkin/bind-operator/internal/bind"
|
|
)
|
|
|
|
func intstrFromInt(i int) intstr.IntOrString { return intstr.FromInt(i) }
|
|
|
|
func podReady(pod *corev1.Pod) bool {
|
|
for _, c := range pod.Status.Conditions {
|
|
if c.Type == corev1.PodReady {
|
|
return c.Status == corev1.ConditionTrue
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// entrypointScript selects the primary or secondary named.conf based on the
|
|
// pod's StatefulSet ordinal and launches named in the foreground.
|
|
func entrypointScript() string {
|
|
return fmt.Sprintf(`#!/bin/sh
|
|
set -eu
|
|
ORD="${HOSTNAME##*-}"
|
|
if [ "$ORD" = "0" ]; then
|
|
cp %[1]s %[3]s
|
|
else
|
|
cp %[2]s %[3]s
|
|
fi
|
|
mkdir -p %[4]s/zones %[4]s/catalog
|
|
exec %[5]s -g -c %[3]s
|
|
`, bind.NamedConfPrimary, bind.NamedConfSecondary, bind.NamedConfRun, bind.DataDir, bind.NamedBin)
|
|
}
|
|
|
|
func (r *BindClusterReconciler) upsertService(ctx context.Context, c *bindv1alpha1.BindCluster, desired *corev1.Service) error {
|
|
if err := ctrl.SetControllerReference(c, desired, r.Scheme); err != nil {
|
|
return err
|
|
}
|
|
var existing corev1.Service
|
|
err := r.Get(ctx, types.NamespacedName{Namespace: desired.Namespace, Name: desired.Name}, &existing)
|
|
if apierrors.IsNotFound(err) {
|
|
return r.Create(ctx, desired)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
existing.Spec.Ports = desired.Spec.Ports
|
|
existing.Spec.Selector = desired.Spec.Selector
|
|
existing.Spec.Type = desired.Spec.Type
|
|
existing.Spec.LoadBalancerIP = desired.Spec.LoadBalancerIP
|
|
if desired.Annotations != nil {
|
|
if existing.Annotations == nil {
|
|
existing.Annotations = map[string]string{}
|
|
}
|
|
for k, v := range desired.Annotations {
|
|
existing.Annotations[k] = v
|
|
}
|
|
}
|
|
return r.Update(ctx, &existing)
|
|
}
|
|
|
|
func (r *BindClusterReconciler) upsertConfigMap(ctx context.Context, c *bindv1alpha1.BindCluster, name string, data map[string]string) error {
|
|
desired := &corev1.ConfigMap{}
|
|
desired.Name = name
|
|
desired.Namespace = c.Namespace
|
|
desired.Labels = commonLabels(c.Name)
|
|
desired.Data = data
|
|
if err := ctrl.SetControllerReference(c, desired, r.Scheme); err != nil {
|
|
return err
|
|
}
|
|
var existing corev1.ConfigMap
|
|
err := r.Get(ctx, types.NamespacedName{Namespace: c.Namespace, Name: name}, &existing)
|
|
if apierrors.IsNotFound(err) {
|
|
return r.Create(ctx, desired)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
existing.Data = data
|
|
existing.Labels = commonLabels(c.Name)
|
|
return r.Update(ctx, &existing)
|
|
}
|
|
|
|
func (r *BindClusterReconciler) upsertSecret(ctx context.Context, c *bindv1alpha1.BindCluster, name string, data map[string][]byte) error {
|
|
desired := &corev1.Secret{}
|
|
desired.Name = name
|
|
desired.Namespace = c.Namespace
|
|
desired.Labels = commonLabels(c.Name)
|
|
desired.Data = data
|
|
if err := ctrl.SetControllerReference(c, desired, r.Scheme); err != nil {
|
|
return err
|
|
}
|
|
var existing corev1.Secret
|
|
err := r.Get(ctx, types.NamespacedName{Namespace: c.Namespace, Name: name}, &existing)
|
|
if apierrors.IsNotFound(err) {
|
|
return r.Create(ctx, desired)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
existing.Data = data
|
|
existing.Labels = commonLabels(c.Name)
|
|
return r.Update(ctx, &existing)
|
|
}
|