func tolerationsForDNS(dns *operatorv1.DNS) []corev1.Toleration {
	if len(dns.Spec.NodePlacement.Tolerations) != 0 {
		return dns.Spec.NodePlacement.Tolerations
	}
	return []corev1.Toleration{{
		Key:      "node-role.kubernetes.io/master",
		Operator: corev1.TolerationOpExists,
	}}
}
tolerationsForDNS takes a dns and returns the tolerations that it specifies,
or default tolerations if it doesn't specify tolerations.
package controller
import (
	"context"
	"fmt"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	operatorv1 "github.com/openshift/api/operator/v1"
	"github.com/openshift/cluster-dns-operator/pkg/manifests"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
)
func (r *reconciler) ensureDNSDaemonSet(dns *operatorv1.DNS) (bool, *appsv1.DaemonSet, error) {
	haveDS, current, err := r.currentDNSDaemonSet(dns)
	if err != nil {
		return false, nil, err
	}
	desired, err := desiredDNSDaemonSet(dns, r.CoreDNSImage, r.KubeRBACProxyImage)
	if err != nil {
		return haveDS, current, fmt.Errorf("failed to build dns daemonset: %v", err)
	}
	switch {
	case !haveDS:
		if err := r.createDNSDaemonSet(desired); err != nil {
			return false, nil, err
		}
		return r.currentDNSDaemonSet(dns)
	case haveDS:
		if updated, err := r.updateDNSDaemonSet(current, desired); err != nil {
			return true, current, err
		} else if updated {
			return r.currentDNSDaemonSet(dns)
		}
	}
	return true, current, nil
}
func (r *reconciler) ensureDNSDaemonSetDeleted(dns *operatorv1.DNS) error {
	daemonset := &appsv1.DaemonSet{}
	name := DNSDaemonSetName(dns)
	daemonset.Name = name.Name
	daemonset.Namespace = name.Namespace
	if err := r.client.Delete(context.TODO(), daemonset); err != nil {
		if !errors.IsNotFound(err) {
			return err
		}
	} else {
		logrus.Infof("deleted dns daemonset: %s", dns.Name)
	}
	return nil
}
func desiredDNSDaemonSet(dns *operatorv1.DNS, coreDNSImage, kubeRBACProxyImage string) (*appsv1.DaemonSet, error) {
	daemonset := manifests.DNSDaemonSet()
	name := DNSDaemonSetName(dns)
	daemonset.Name = name.Name
	daemonset.Namespace = name.Namespace
	daemonset.SetOwnerReferences([]metav1.OwnerReference{dnsOwnerRef(dns)})
	daemonset.Labels = map[string]string{
		manifests.OwningDNSLabel: DNSDaemonSetLabel(dns),
	}
	daemonset.Spec.Selector = DNSDaemonSetPodSelector(dns)
	daemonset.Spec.Template.Labels = daemonset.Spec.Selector.MatchLabels
	daemonset.Spec.Template.Spec.NodeSelector = nodeSelectorForDNS(dns)
	daemonset.Spec.Template.Spec.Tolerations = tolerationsForDNS(dns)
	coreFileVolumeFound := false
	for i := range daemonset.Spec.Template.Spec.Volumes {
		switch daemonset.Spec.Template.Spec.Volumes[i].Name {
		case "config-volume":
			daemonset.Spec.Template.Spec.Volumes[i].ConfigMap.Name = DNSConfigMapName(dns).Name
			coreFileVolumeFound = true
			break
		case "metrics-tls":
			daemonset.Spec.Template.Spec.Volumes[i].Secret = &corev1.SecretVolumeSource{
				SecretName: DNSMetricsSecretName(dns),
			}
		}
	}
	if !coreFileVolumeFound {
		return nil, fmt.Errorf("volume 'config-volume' is not found")
	}
	for i, c := range daemonset.Spec.Template.Spec.Containers {
		switch c.Name {
		case "dns":
			daemonset.Spec.Template.Spec.Containers[i].Image = coreDNSImage
		case "kube-rbac-proxy":
			daemonset.Spec.Template.Spec.Containers[i].Image = kubeRBACProxyImage
		}
	}
	return daemonset, nil
}
func nodeSelectorForDNS(dns *operatorv1.DNS) map[string]string {
	if len(dns.Spec.NodePlacement.NodeSelector) != 0 {
		return dns.Spec.NodePlacement.NodeSelector
	}
	return map[string]string{"kubernetes.io/os": "linux"}
}