package templates import ( "os" "strings" buildinfo "undecided.project/monok8s/pkg/buildinfo" ) type TemplateValues struct { Hostname string NodeName string KubernetesVersion string ClusterName string ClusterDomain string PodSubnet string ServiceSubnet string APIServerAdvertiseAddress string APIServerEndpoint string BootstrapToken string DiscoveryTokenCACertHash string ControlPlaneCertKey string ContainerRuntimeEndpoint string CNIPlugin string ClusterRole string // worker, control-plane InitControlPlane bool AllowSchedulingOnControlPlane bool SkipImageCheck bool MgmtIface string MgmtAddress string MgmtGateway string DNSNameservers []string DNSSearchDomains []string SubjectAltNames []string NodeLabels map[string]string NodeAnnotations map[string]string } func defaultTemplateValues() TemplateValues { return TemplateValues{ Hostname: "monok8s-master-1", NodeName: "monok8s-master-1", KubernetesVersion: buildinfo.Version, ClusterName: "monok8s", ClusterDomain: "cluster.local", PodSubnet: "10.244.0.0/16", ServiceSubnet: "10.96.0.0/12", APIServerAdvertiseAddress: "10.0.0.10", APIServerEndpoint: "10.0.0.10:6443", BootstrapToken: "abcd12.ef3456789abcdef0", DiscoveryTokenCACertHash: "sha256:9f1c2b3a4d5e6f7890abc1234567890abcdef1234567890abcdef1234567890ab", ControlPlaneCertKey: "", ContainerRuntimeEndpoint: "unix:///var/run/crio/crio.sock", CNIPlugin: "default", InitControlPlane: true, ClusterRole: "control-plane", AllowSchedulingOnControlPlane: true, SkipImageCheck: false, MgmtIface: "eth1", MgmtAddress: "10.0.0.10/24", MgmtGateway: "10.0.0.1", DNSNameservers: []string{"1.1.1.1", "8.8.8.8"}, DNSSearchDomains: []string{"lan"}, SubjectAltNames: []string{"10.0.0.10", "localhost", "monok8s-master-1"}, NodeLabels: map[string]string{ "monok8s.io/label": "value", }, NodeAnnotations: map[string]string{ "monok8s.io/annotation": "value", }, } } func LoadTemplateValuesFromEnv() TemplateValues { v := defaultTemplateValues() v.Hostname = getenvDefault("MKS_HOSTNAME", v.Hostname) v.NodeName = getenvDefault("MKS_NODE_NAME", v.Hostname) v.KubernetesVersion = getenvDefault("MKS_KUBERNETES_VERSION", v.KubernetesVersion) v.ClusterName = getenvDefault("MKS_CLUSTER_NAME", v.ClusterName) v.ClusterDomain = getenvDefault("MKS_CLUSTER_DOMAIN", v.ClusterDomain) v.PodSubnet = getenvDefault("MKS_POD_SUBNET", v.PodSubnet) v.ServiceSubnet = getenvDefault("MKS_SERVICE_SUBNET", v.ServiceSubnet) v.APIServerAdvertiseAddress = getenvDefault("MKS_APISERVER_ADVERTISE_ADDRESS", v.APIServerAdvertiseAddress) v.APIServerEndpoint = getenvDefault("MKS_API_SERVER_ENDPOINT", v.APIServerEndpoint) v.BootstrapToken = getenvDefault("MKS_BOOTSTRAP_TOKEN", v.BootstrapToken) v.DiscoveryTokenCACertHash = getenvDefault("MKS_DISCOVERY_TOKEN_CA_CERT_HASH", v.DiscoveryTokenCACertHash) v.ControlPlaneCertKey = getenvDefault("MKS_CONTROL_PLANE_CERT_KEY", v.ControlPlaneCertKey) v.ContainerRuntimeEndpoint = getenvDefault("MKS_CONTAINER_RUNTIME_ENDPOINT", v.ContainerRuntimeEndpoint) v.CNIPlugin = getenvDefault("MKS_CNI_PLUGIN", v.CNIPlugin) v.InitControlPlane = getenvBoolDefault("MKS_INIT_CONTROL_PLANE", v.InitControlPlane) v.ClusterRole = getenvDefault("MKS_CLUSTER_ROLE", v.ClusterRole) v.AllowSchedulingOnControlPlane = getenvBoolDefault("MKS_ALLOW_SCHEDULING_ON_CONTROL_PLANE", v.AllowSchedulingOnControlPlane) v.SkipImageCheck = getenvBoolDefault("MKS_SKIP_IMAGE_CHECK", v.SkipImageCheck) v.MgmtIface = getenvDefault("MKS_MGMT_IFACE", v.MgmtIface) v.MgmtAddress = getenvDefault("MKS_MGMT_ADDRESS", v.MgmtAddress) v.MgmtGateway = getenvDefault("MKS_MGMT_GATEWAY", v.MgmtGateway) if xs := splitWhitespaceList(os.Getenv("MKS_DNS_NAMESERVERS")); len(xs) > 0 { v.DNSNameservers = xs } if xs := splitWhitespaceList(os.Getenv("MKS_DNS_SEARCH_DOMAINS")); len(xs) > 0 { v.DNSSearchDomains = xs } if xs := splitCommaList(os.Getenv("MKS_SANS")); len(xs) > 0 { v.SubjectAltNames = xs } if m := parseKeyValueMap(os.Getenv("MKS_NODE_LABELS")); len(m) > 0 { v.NodeLabels = m } if m := parseKeyValueMap(os.Getenv("MKS_NODE_ANNOTATIONS")); len(m) > 0 { v.NodeAnnotations = m } return v } func getenvDefault(key, def string) string { s := strings.TrimSpace(os.Getenv(key)) if s == "" { return def } return s } func getenvBoolDefault(key string, def bool) bool { s := strings.TrimSpace(strings.ToLower(os.Getenv(key))) if s == "" { return def } switch s { case "1", "true", "yes", "y", "on": return true case "0", "false", "no", "n", "off": return false default: return def } } func splitCommaList(s string) []string { if strings.TrimSpace(s) == "" { return nil } parts := strings.Split(s, ",") out := make([]string, 0, len(parts)) for _, p := range parts { p = strings.TrimSpace(p) if p != "" { out = append(out, p) } } return out } func splitWhitespaceList(s string) []string { if strings.TrimSpace(s) == "" { return nil } return strings.Fields(s) } func parseKeyValueMap(s string) map[string]string { out := map[string]string{} if strings.TrimSpace(s) == "" { return out } for _, item := range strings.Split(s, ",") { item = strings.TrimSpace(item) if item == "" { continue } k, val, ok := strings.Cut(item, "=") if !ok { continue } k = strings.TrimSpace(k) val = strings.TrimSpace(val) if k == "" { continue } out[k] = val } return out }