func getKubeadmConfig()

in kinder/pkg/cluster/manager/actions/kubeadm-config.go [199:337]


func getKubeadmConfig(c *status.Cluster, n *status.Node, data kubeadm.ConfigData, options kubeadmConfigOptions) (string, error) {
	kubeadmVersion, err := n.KubeadmVersion()
	if err != nil {
		return "", err
	}
	log.Debugf("kubeadm version %s", kubeadmVersion)

	kubeadmConfigVersion := options.configVersion
	if len(kubeadmConfigVersion) == 0 {
		kubeadmConfigVersion = kubeadm.GetKubeadmConfigVersion(kubeadmVersion)
	}
	log.Debugf("using kubeadm config version %s", kubeadmConfigVersion)

	// generate the "raw config", using the kubeadm config template provided by kind
	rawconfig, err := kubeadm.Config(kubeadmConfigVersion, data)
	if err != nil {
		return "", err
	}

	// apply all the kinder specific settings using patches
	var patches = []string{}
	var jsonPatches = []kubeadm.PatchJSON6902{}

	// add patches for instructing kubeadm to use the CRI runtime engine  installed on a node
	// NB. this is a no-op in case of containerd, because it is already the default in the raw config
	// TODO: currently we are always specifying the CRI kubeadm should use; it will be nice in the future to
	// have the possibility to test the kubeadm CRI autodetection
	nodeCRI, err := n.CRI()
	if err != nil {
		return "", err
	}

	criConfigHelper, err := nodes.NewConfigHelper(nodeCRI)
	if err != nil {
		return "", err
	}

	criPatches, err := criConfigHelper.GetKubeadmConfigPatches(kubeadmConfigVersion, data.ControlPlane)
	if err != nil {
		return "", err
	}

	patches = append(patches, criPatches...)

	// if requested automatic copy certs and the node is a controlplane node,
	// add patches for adding the certificateKey value
	// NB. this is a no-op in case of kubeadm config API older than v1beta2, because
	// this feature was not supported before (the --certificate-key flag should be used instead)
	if options.copyCertsMode == CopyCertsModeAuto && n.IsControlPlane() {
		automaticCopyCertsPatches, err := kubeadm.GetAutomaticCopyCertsPatches(kubeadmConfigVersion)
		if err != nil {
			return "", err
		}

		patches = append(patches, automaticCopyCertsPatches...)
	}

	// add patches directory to the config
	patchesDirectoryPatches, err := kubeadm.GetPatchesDirectoryPatches(kubeadmConfigVersion)
	// skip if kubeadm config version is not v1beta3
	if err == nil {
		patches = append(patches, patchesDirectoryPatches...)
	}

	// if requested to use file discovery and not the first control-plane, add patches for using file discovery
	if options.discoveryMode != TokenDiscovery && !(n == c.BootstrapControlPlane()) {
		// remove token from config
		removeTokenPatch, err := kubeadm.GetRemoveTokenPatch(kubeadmConfigVersion)
		if err != nil {
			return "", err
		}
		jsonPatches = append(jsonPatches, removeTokenPatch)

		// create the discovery file on the node
		// NB. this requires that kubeadm init is already completed on the BootstrapControlPlane in order
		// to have CAs and admin.conf already in place
		if err := createDiscoveryFile(c, n, options.discoveryMode); err != nil {
			return "", errors.Wrapf(err, "failed to generate a discovery file. Please ensure that kubeadm-init is already completed")
		}

		// add discovery file path to the config
		fileDiscoveryPatch, err := kubeadm.GetFileDiscoveryPatch(kubeadmConfigVersion)
		if err != nil {
			return "", err
		}
		patches = append(patches, fileDiscoveryPatch)

		// if the file discovery does not contains the authorization credentials, add tls discovery token
		if options.discoveryMode == FileDiscoveryWithoutCredentials {
			tlsBootstrapPatch, err := kubeadm.GetTLSBootstrapPatch(kubeadmConfigVersion)
			if err != nil {
				return "", err
			}
			patches = append(patches, tlsBootstrapPatch)
		}
	}

	// if the cluster is using an external etcd node, add patches for configuring access
	// to external etcd cluster
	if c.ExternalEtcd() != nil {
		externalEtcdIP, externalEtcdIPV6, err := c.ExternalEtcd().IP()
		if err != nil {
			return "", errors.Wrapf(err, "failed to get IP for node: %s", c.ExternalEtcd().Name())
		}

		// configure the right protocol addresses
		if c.Settings.IPFamily == status.IPv6Family {
			externalEtcdIP = externalEtcdIPV6
		}

		externalEtcdPatch, err := kubeadm.GetExternalEtcdPatch(kubeadmConfigVersion, externalEtcdIP)
		if err != nil {
			return "", err
		}

		patches = append(patches, externalEtcdPatch)
	}

	// apply patches
	patched, err := kubeadm.Build(rawconfig, patches, jsonPatches)
	if err != nil {
		return "", err
	}

	// Select the objects that are relevant for a specific node;
	// if the node is the bootstrap control plane, then all the objects used as init time
	if n == c.BootstrapControlPlane() {
		return selectYamlFramentByKind(patched,
			"ClusterConfiguration",
			"InitConfiguration",
			"KubeletConfiguration",
			"KubeProxyConfiguration"), nil
	}

	// otherwise select only the JoinConfiguration
	return selectYamlFramentByKind(patched,
		"JoinConfiguration",
	), nil
}