You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: common.go
    path of file: ./repos/kubernetes/cmd/kubeadm/app/util/config
    
    the code of the file until where you have to start completion: /*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package config contains utilities for managing the kubeadm configuration API.
package config

import (
	"bytes"
	"fmt"
	"net"
	"reflect"
	"strings"

	"github.com/pkg/errors"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	netutil "k8s.io/apimachinery/pkg/util/net"
	"k8s.io/apimachinery/pkg/util/version"
	apimachineryversion "k8s.io/apimachinery/pkg/version"
	componentversion "k8s.io/component-base/version"
	"k8s.io/klog/v2"
	netutils "k8s.io/utils/net"

	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
	kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
	kubeadmapiv1old "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
	kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
	"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
	"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

// LoadOrDefaultConfigurationOptions holds the common LoadOrDefaultConfiguration options.
type LoadOrDefaultConfigurationOptions struct {
	// AllowExperimental indicates whether the experimental / work in progress APIs can be used.
	AllowExperimental bool
	// SkipCRIDetect indicates whether to skip the CRI socket detection when no CRI socket is provided.
	SkipCRIDetect bool
}

// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some ext
    
func NormalizeKubernetesVersion(cfg *kubeadmapi.ClusterConfiguration) error {
	isCIVersion := kubeadmutil.KubernetesIsCIVersion(cfg.KubernetesVersion)

	// Requested version is automatic CI build, thus use KubernetesCI Image Repository for core images
	if isCIVersion && cfg.ImageRepository == kubeadmapiv1.DefaultImageRepository {
		cfg.CIImageRepository = constants.DefaultCIImageRepository
	}

	// Parse and validate the version argument and resolve possible CI version labels
	ver, err := kubeadmutil.KubernetesReleaseVersion(cfg.KubernetesVersion)
	if err != nil {
		return err
	}

	// Requested version is automatic CI build, thus mark CIKubernetesVersion as `ci/<resolved-version>`
	if isCIVersion {
		cfg.CIKubernetesVersion = fmt.Sprintf("%s%s", constants.CIKubernetesVersionPrefix, ver)
	}

	cfg.KubernetesVersion = ver

	// Parse the given kubernetes version and make sure it's higher than the lowest supported
	k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
	if err != nil {
		return errors.Wrapf(err, "couldn't parse Kubernetes version %q", cfg.KubernetesVersion)
	}

	// During the k8s release process, a kubeadm version in the main branch could be 1.23.0-pre,
	// while the 1.22.0 version is not released yet. The MinimumControlPlaneVersion validation
	// in such a case will not pass, since the value of MinimumControlPlaneVersion would be
	// calculated as kubeadm version - 1 (1.22) and k8sVersion would still be at 1.21.x
	// (fetched from the 'stable' marker). Handle this case by only showing a warning.
	mcpVersion := constants.MinimumControlPlaneVersion
	versionInfo := componentversion.Get()
	if isKubeadmPrereleaseVersion(&versionInfo, k8sVersion, mcpVersion) {
		klog.V(1).Infof("WARNING: tolerating control plane version %s as a pre-release version", cfg.KubernetesVersion)

		return nil
	}
	// If not a pre-release version, handle the validation normally.
	if k8sVersion.LessThan(mcpVersion) {
		return errors.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= %s. Current version: %s",
			mcpVersion, cfg.KubernetesVersion)
	}
	return nil
}