From 208d10faf7bd39efc62bc31cffdee1a3ea6d1800 Mon Sep 17 00:00:00 2001 From: qiuwei Date: Wed, 22 May 2024 15:44:39 +0800 Subject: [PATCH] feat: use the code way to install core-dns Signed-off-by: qiuwei --- hack/globalnode_patch.sh | 16 ++ pkg/kubenest/controlplane/coredns/coredns.go | 154 ++++++++++++++++ pkg/kubenest/controlplane/coredns/rbac.go | 77 ++++++++ pkg/kubenest/controlplane/service.go | 24 +++ .../coredns/host/manifest_configmap.go | 34 ++++ .../coredns/host/manifest_deployment.go | 133 ++++++++++++++ .../coredns/host/manifest_service.go | 34 ++++ .../coredns/host/manifests_rbac.go | 57 ++++++ .../virtualcluster/manifest_endpoints.go | 21 +++ .../virtualcluster/manifest_service.go | 30 +++ pkg/kubenest/tasks/coredns.go | 172 +++--------------- 11 files changed, 601 insertions(+), 151 deletions(-) create mode 100644 hack/globalnode_patch.sh create mode 100644 pkg/kubenest/controlplane/coredns/coredns.go create mode 100644 pkg/kubenest/controlplane/coredns/rbac.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/host/manifest_configmap.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/host/manifest_deployment.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/host/manifest_service.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/host/manifests_rbac.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_endpoints.go create mode 100644 pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_service.go diff --git a/hack/globalnode_patch.sh b/hack/globalnode_patch.sh new file mode 100644 index 000000000..f978f9951 --- /dev/null +++ b/hack/globalnode_patch.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# define the node name prefix +node_prefix="test-ylc-m-" + +# Generate the name of the globalnode that needs to change state and update the state to "reserved" +# Change the node label you want in the for loop, such as 01-09 in this case +for ((i=1; i<=9; i++)) +do + # Use printf to format strings so that the number part is always two digits long + node_number=$(printf "%02d" $i) + node_name="$node_prefix$node_number" + + # Update the status of the corresponding globalnode to "free" using the kubectl patch command. + kubectl patch globalnode $node_name --type=json -p '[{"op":"replace", "path":"/spec/state", "value":"free"}]' +done \ No newline at end of file diff --git a/pkg/kubenest/controlplane/coredns/coredns.go b/pkg/kubenest/controlplane/coredns/coredns.go new file mode 100644 index 000000000..0aacbd683 --- /dev/null +++ b/pkg/kubenest/controlplane/coredns/coredns.go @@ -0,0 +1,154 @@ +package coredns + +import ( + "fmt" + + "github.com/pkg/errors" + appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/dynamic" + clientset "k8s.io/client-go/kubernetes" + + "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/coredns/host" + "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/coredns/virtualcluster" + "github.com/kosmos.io/kosmos/pkg/kubenest/util" +) + +func EnsureHostCoreDns(client clientset.Interface, name, namespace string) error { + //create core-dns cm for host + err := installCoreDnsConfigMap(client, namespace) + if err != nil { + return err + } + //create core-dns rbac + err = EnsureCoreDnsRBAC(client, namespace, name) + if err != nil { + return err + } + //service in host has been created in the NewVirtualClusterServiceTask + //create core-dns deployment + err = installCoreDnsDeployment(client, name, namespace) + if err != nil { + return err + } + return nil +} + +func EnsureVirtualClusterCoreDns(dynamicClient dynamic.Interface, templateMapping map[string]interface{}) error { + // create core-dns endpoints for virtualcluster + err := installCoreDnsEndpointsInVirtualCluster(dynamicClient, templateMapping) + if err != nil { + return err + } + // create core-dns service in virtualcluster + err = installCoreDnsServiceInVirtualCluster(dynamicClient, templateMapping) + if err != nil { + return err + } + return nil +} + +func installCoreDnsDeployment(client clientset.Interface, name, namespace string) error { + imageRepository, _ := util.GetImageMessage() + coreDnsDeploymentBytes, err := util.ParseTemplate(host.CoreDnsDeployment, struct { + Namespace, Name, ImageRepository string + }{ + Namespace: namespace, + Name: name, + ImageRepository: imageRepository, + }) + if err != nil { + return fmt.Errorf("error when parsing core-dns deployment template: %w", err) + } + coreDnsDeployment := &appsv1.Deployment{} + if err := yaml.Unmarshal([]byte(coreDnsDeploymentBytes), coreDnsDeployment); err != nil { + return fmt.Errorf("error when decoding core-dns deployment: %w", err) + } + + if err := util.CreateOrUpdateDeployment(client, coreDnsDeployment); err != nil { + return fmt.Errorf("error when creating deployment for %s, err: %w", coreDnsDeployment.Name, err) + } + return nil +} + +func getCoreDnsConfigMapManifest(namespace string) (*v1.ConfigMap, error) { + coreDnsConfigMapBytes, err := util.ParseTemplate(host.CoreDnsCM, struct { + Namespace string + }{ + Namespace: namespace, + }) + if err != nil { + return nil, fmt.Errorf("error when parsing core-dns configMap template: %w", err) + } + + config := &v1.ConfigMap{} + if err := yaml.Unmarshal([]byte(coreDnsConfigMapBytes), config); err != nil { + return nil, fmt.Errorf("err when decoding core-dns configMap: %w", err) + } + + return config, nil +} + +func installCoreDnsConfigMap(client clientset.Interface, namespace string) error { + config, err := getCoreDnsConfigMapManifest(namespace) + if err != nil { + return err + } + + if err := util.CreateOrUpdateConfigMap(client, config); err != nil { + return fmt.Errorf("error when creating configMap for %s, err: %w", config.Name, err) + } + return nil +} + +func installCoreDnsServiceInVirtualCluster(dynamicClient dynamic.Interface, templateMapping map[string]interface{}) error { + coreDnsServiceInVcBytes, err := util.ParseTemplate(virtualcluster.CoreDnsService, templateMapping) + if err != nil { + return fmt.Errorf("error when parsing core-dns service in virtual cluster template: %w", err) + } + var obj unstructured.Unstructured + if err := yaml.Unmarshal([]byte(coreDnsServiceInVcBytes), &obj); err != nil { + return fmt.Errorf("err when decoding core-dns service in virtual cluster: %w", err) + } + + err = util.CreateObject(dynamicClient, obj.GetNamespace(), obj.GetName(), &obj) + if err != nil { + return fmt.Errorf("error when creating core-dns service in virtual cluster err: %w", err) + } + return nil +} + +func installCoreDnsEndpointsInVirtualCluster(dynamicClient dynamic.Interface, templateMapping map[string]interface{}) error { + coreDnsEndpointsInVcBytes, err := util.ParseTemplate(virtualcluster.CoreDnsEndpoints, templateMapping) + if err != nil { + return fmt.Errorf("error when parsing core-dns service in virtual cluster template: %w", err) + } + var obj unstructured.Unstructured + if err := yaml.Unmarshal([]byte(coreDnsEndpointsInVcBytes), &obj); err != nil { + return fmt.Errorf("err when decoding core-dns service in virtual cluster: %w", err) + } + + err = util.CreateObject(dynamicClient, obj.GetNamespace(), obj.GetName(), &obj) + if err != nil { + return fmt.Errorf("error when creating core-dns service in virtual cluster err: %w", err) + } + return nil +} + +func DeleteCoreDnsDeployment(client clientset.Interface, name, namespace string) error { + // delete deployment + deployName := fmt.Sprintf("%s-%s", name, "coredns") + if err := util.DeleteDeployment(client, deployName, namespace); err != nil { + return errors.Wrapf(err, "Failed to delete deployment %s/%s", deployName, namespace) + } + + // delete configmap + cmName := "coredns" + if err := util.DeleteConfigmap(client, cmName, namespace); err != nil { + return errors.Wrapf(err, "Failed to delete configmap %s/%s", cmName, namespace) + } + + return nil +} diff --git a/pkg/kubenest/controlplane/coredns/rbac.go b/pkg/kubenest/controlplane/coredns/rbac.go new file mode 100644 index 000000000..8e4d34e3f --- /dev/null +++ b/pkg/kubenest/controlplane/coredns/rbac.go @@ -0,0 +1,77 @@ +package coredns + +import ( + "fmt" + + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/util/yaml" + clientset "k8s.io/client-go/kubernetes" + + "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/coredns/host" + "github.com/kosmos.io/kosmos/pkg/kubenest/util" +) + +func EnsureCoreDnsRBAC(client clientset.Interface, namespace string, name string) error { + if err := grantCoreDnsClusterSA(client, namespace); err != nil { + return err + } + if err := grantCoreDnsClusterRoleBinding(client, namespace, name); err != nil { + return err + } + if err := grantCoreDnsClusterRole(client, name); err != nil { + return err + } + return nil +} + +func grantCoreDnsClusterSA(client clientset.Interface, namespace string) error { + coreDnsClusterSABytes, err := util.ParseTemplate(host.CoreDnsSA, struct { + Namespace string + }{ + Namespace: namespace, + }) + if err != nil { + return fmt.Errorf("error when parsing core-dns sa template: %w", err) + } + serviceAccount := &v1.ServiceAccount{} + if err := yaml.Unmarshal([]byte(coreDnsClusterSABytes), serviceAccount); err != nil { + return fmt.Errorf("err when decoding core-dns view Clusterrole: %w", err) + } + return util.CreateOrUpdateClusterSA(client, serviceAccount, namespace) +} + +func grantCoreDnsClusterRoleBinding(client clientset.Interface, namespace string, name string) error { + coreDnsClusterRoleBindingBytes, err := util.ParseTemplate(host.CoreDnsClusterRoleBinding, struct { + Name string + Namespace string + }{ + Name: name, + Namespace: namespace, + }) + if err != nil { + return fmt.Errorf("error when parsing core-dns role binding template: %w", err) + } + viewClusterRoleBinding := &rbacv1.ClusterRoleBinding{} + + if err := yaml.Unmarshal([]byte(coreDnsClusterRoleBindingBytes), viewClusterRoleBinding); err != nil { + return fmt.Errorf("err when decoding core-dns Clusterrole Binding: %w", err) + } + return util.CreateOrUpdateClusterRoleBinding(client, viewClusterRoleBinding) +} + +func grantCoreDnsClusterRole(client clientset.Interface, name string) error { + viewClusterRole := &rbacv1.ClusterRole{} + coreDnsClusterRoleBytes, err := util.ParseTemplate(host.CoreDnsClusterRole, struct { + Name string + }{ + Name: name, + }) + if err != nil { + return fmt.Errorf("error when parsing core-dns cluster role template: %w", err) + } + if err := yaml.Unmarshal([]byte(coreDnsClusterRoleBytes), viewClusterRole); err != nil { + return fmt.Errorf("err when decoding core-dns Clusterrole: %w", err) + } + return util.CreateOrUpdateClusterRole(client, viewClusterRole) +} diff --git a/pkg/kubenest/controlplane/service.go b/pkg/kubenest/controlplane/service.go index 63f5d76e4..c626e1ce1 100644 --- a/pkg/kubenest/controlplane/service.go +++ b/pkg/kubenest/controlplane/service.go @@ -14,6 +14,7 @@ import ( "github.com/kosmos.io/kosmos/pkg/kubenest/constants" "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/apiserver" + "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/coredns/host" "github.com/kosmos.io/kosmos/pkg/kubenest/manifest/controlplane/etcd" "github.com/kosmos.io/kosmos/pkg/kubenest/util" ) @@ -30,6 +31,7 @@ func DeleteVirtualClusterService(client clientset.Interface, name, namespace str fmt.Sprintf("%s-%s", name, "apiserver"), fmt.Sprintf("%s-%s", name, "etcd"), fmt.Sprintf("%s-%s", name, "etcd-client"), + "kube-dns", } for _, service := range services { err := client.CoreV1().Services(namespace).Delete(context.TODO(), service, metav1.DeleteOptions{}) @@ -47,6 +49,7 @@ func DeleteVirtualClusterService(client clientset.Interface, name, namespace str } func createServerService(client clientset.Interface, name, namespace string, port int32) error { + //apiserver service apiserverServiceBytes, err := util.ParseTemplate(apiserver.ApiserverService, struct { ServiceName, Namespace, ServiceType string ServicePort int32 @@ -68,6 +71,7 @@ func createServerService(client clientset.Interface, name, namespace string, por return fmt.Errorf("err when creating virtual cluster apiserver service for %s, err: %w", apiserverService.Name, err) } + //etcd service etcdServicePeerBytes, err := util.ParseTemplate(etcd.EtcdPeerService, struct { ServiceName, Namespace string EtcdListenClientPort, EtcdListenPeerPort int32 @@ -90,6 +94,7 @@ func createServerService(client clientset.Interface, name, namespace string, por return fmt.Errorf("error when creating etcd client service, err: %w", err) } + //etcd-client service etcdClientServiceBytes, err := util.ParseTemplate(etcd.EtcdClientService, struct { ServiceName, Namespace string EtcdListenClientPort int32 @@ -111,6 +116,25 @@ func createServerService(client clientset.Interface, name, namespace string, por return fmt.Errorf("err when creating etcd client service, err: %w", err) } + //core-dns service + coreDnsServiceBytes, err := util.ParseTemplate(host.CoreDnsService, struct { + Namespace string + }{ + Namespace: namespace, + }) + if err != nil { + return fmt.Errorf("error when parsing core-dns serive template: %w", err) + } + + coreDnsService := &corev1.Service{} + if err := yaml.Unmarshal([]byte(coreDnsServiceBytes), coreDnsService); err != nil { + return fmt.Errorf("err when decoding core-dns service: %w", err) + } + + if err := createOrUpdateService(client, coreDnsService); err != nil { + return fmt.Errorf("err when creating core-dns service, err: %w", err) + } + return nil } diff --git a/pkg/kubenest/manifest/controlplane/coredns/host/manifest_configmap.go b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_configmap.go new file mode 100644 index 000000000..ea733a7a9 --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_configmap.go @@ -0,0 +1,34 @@ +package host + +const ( + CoreDnsCM = ` +apiVersion: v1 +data: + Corefile: | + .:53 { + errors + health { + lameduck 5s + } + ready + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + fallthrough in-addr.arpa ip6.arpa + ttl 30 + kubeconfig /etc/apiserver/kubeconfig + } + prometheus :9153 + forward . /etc/resolv.conf { + max_concurrent 1000 + } + cache 30 + loop + reload + loadbalance + } +kind: ConfigMap +metadata: + name: coredns + namespace: {{ .Namespace }} +` +) diff --git a/pkg/kubenest/manifest/controlplane/coredns/host/manifest_deployment.go b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_deployment.go new file mode 100644 index 000000000..21fd576ae --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_deployment.go @@ -0,0 +1,133 @@ +package host + +const ( + CoreDnsDeployment = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: kube-dns + name: {{ .Name }}-coredns + namespace: {{ .Namespace }} +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s-app: kube-dns + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + k8s-app: kube-dns + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: k8s-app + operator: In + values: + - kube-dns + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - args: + - -conf + - /etc/coredns/Corefile + image: {{ .ImageRepository }}/coredns:v1.9.3 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 5 + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + name: coredns + ports: + - containerPort: 53 + name: dns + protocol: UDP + - containerPort: 53 + name: dns-tcp + protocol: TCP + - containerPort: 9153 + name: metrics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /ready + port: 8181 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + memory: 170Mi + requests: + cpu: 100m + memory: 70Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_BIND_SERVICE + drop: + - all + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/coredns + name: config-volume + readOnly: true + - mountPath: /etc/apiserver/kubeconfig + name: kubeconfig + subPath: kubeconfig + dnsPolicy: Default + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: coredns + serviceAccountName: coredns + terminationGracePeriodSeconds: 30 + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + volumes: + - configMap: + defaultMode: 420 + items: + - key: Corefile + path: Corefile + name: coredns + name: config-volume + - name: kubeconfig + secret: + defaultMode: 420 + secretName: {{ .Name }}-admin-config + + +` +) diff --git a/pkg/kubenest/manifest/controlplane/coredns/host/manifest_service.go b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_service.go new file mode 100644 index 000000000..c704f5a2a --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/host/manifest_service.go @@ -0,0 +1,34 @@ +package host + +const ( + CoreDnsService = ` +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: kube-dns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: CoreDNS + name: kube-dns + namespace: {{ .Namespace }} +spec: + ports: + - name: dns + port: 53 + protocol: UDP + targetPort: 53 + - name: dns-tcp + port: 53 + protocol: TCP + targetPort: 53 + - name: metrics + port: 9153 + protocol: TCP + targetPort: 9153 + selector: + k8s-app: kube-dns + sessionAffinity: None + type: NodePort + +` +) diff --git a/pkg/kubenest/manifest/controlplane/coredns/host/manifests_rbac.go b/pkg/kubenest/manifest/controlplane/coredns/host/manifests_rbac.go new file mode 100644 index 000000000..fbd3072d7 --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/host/manifests_rbac.go @@ -0,0 +1,57 @@ +package host + +const ( + CoreDnsSA = ` +apiVersion: v1 +kind: ServiceAccount +metadata: + name: coredns + namespace: {{ .Namespace }} +` + + CoreDnsClusterRoleBinding = ` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system:coredns-{{ .Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:coredns-{{ .Name }} +subjects: +- kind: ServiceAccount + name: coredns + namespace: {{ .Namespace }} +` + + CoreDnsClusterRole = ` +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:coredns-{{ .Name }} +rules: +- apiGroups: + - "" + resources: + - endpoints + - services + - pods + - namespaces + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch +` +) diff --git a/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_endpoints.go b/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_endpoints.go new file mode 100644 index 000000000..b9ac2de84 --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_endpoints.go @@ -0,0 +1,21 @@ +package virtualcluster + +const ( + CoreDnsEndpoints = ` +apiVersion: v1 +kind: Endpoints +metadata: + name: kube-dns + namespace: kube-system +subsets: +- addresses: + - ip: {{ .HostNodeAddress }} + ports: + - name: dns + port: {{ .DNSPort }} + protocol: UDP + - name: metrics + port: {{ .MetricsPort }} + protocol: TCP +` +) diff --git a/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_service.go b/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_service.go new file mode 100644 index 000000000..29fd8b482 --- /dev/null +++ b/pkg/kubenest/manifest/controlplane/coredns/virtualcluster/manifest_service.go @@ -0,0 +1,30 @@ +package virtualcluster + +const ( + CoreDnsService = ` +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: kube-dns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: CoreDNS + name: kube-dns + namespace: kube-system +spec: + ports: + - name: dns + port: 53 + protocol: UDP + targetPort: {{ .DNSPort }} + - name: dns-tcp + port: 53 + protocol: TCP + targetPort: {{ .DNSTCPPort }} + - name: metrics + port: 9153 + protocol: TCP + targetPort: {{ .MetricsPort }} + +` +) diff --git a/pkg/kubenest/tasks/coredns.go b/pkg/kubenest/tasks/coredns.go index c29624163..a1e646675 100644 --- a/pkg/kubenest/tasks/coredns.go +++ b/pkg/kubenest/tasks/coredns.go @@ -4,22 +4,17 @@ import ( "context" "fmt" "os" - "path/filepath" "time" "github.com/pkg/errors" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/dynamic" - clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog/v2" "github.com/kosmos.io/kosmos/pkg/kubenest/constants" - "github.com/kosmos.io/kosmos/pkg/kubenest/util" + "github.com/kosmos.io/kosmos/pkg/kubenest/controlplane/coredns" "github.com/kosmos.io/kosmos/pkg/kubenest/workflow" ) @@ -69,28 +64,6 @@ func UninstallCoreDNSTask() workflow.Task { } } -func getCoreDnsHostComponentsConfig(client clientset.Interface, keyName string) ([]ComponentConfig, error) { - cm, err := client.CoreV1().ConfigMaps(constants.KosmosNs).Get(context.Background(), constants.ManifestComponentsConfigMap, metav1.GetOptions{}) - if err != nil { - if apierrors.IsNotFound(err) { - return nil, nil - } - return nil, err - } - - yamlData, ok := cm.Data[keyName] - if !ok { - return nil, errors.Wrap(err, "Read manifests components config error") - } - - var components []ComponentConfig - err = yaml.Unmarshal([]byte(yamlData), &components) - if err != nil { - return nil, errors.Wrap(err, "Unmarshal manifests component config error") - } - return components, nil -} - // in host func runCoreDnsHostTask(r workflow.RunData) error { data, ok := r.(InitData) @@ -98,28 +71,17 @@ func runCoreDnsHostTask(r workflow.RunData) error { return errors.New("Virtual cluster manifests-components task invoked with an invalid data struct") } - dynamicClient := data.DynamicClient() + err := coredns.EnsureHostCoreDns( + data.RemoteClient(), + data.GetName(), + data.GetNamespace(), + ) - components, err := getCoreDnsHostComponentsConfig(data.RemoteClient(), constants.HostCoreDnsComponents) if err != nil { - return err + return fmt.Errorf("failed to install core-dns in host, err: %w", err) } - imageRepository, _ := util.GetImageMessage() - - for _, component := range components { - klog.V(2).Infof("Deploy component %s", component.Name) - - templatedMapping := map[string]interface{}{ - "Namespace": data.GetNamespace(), - "Name": data.GetName(), - "ImageRepository": imageRepository, - } - err = applyYMLTemplate(dynamicClient, component.Path, templatedMapping) - if err != nil { - return err - } - } + klog.V(2).InfoS("[VirtualClusterCoreDns] Successfully installed core-dns in host", "core-dns", klog.KObj(data)) return nil } @@ -129,28 +91,15 @@ func uninstallCorednsHostTask(r workflow.RunData) error { return errors.New("Virtual cluster manifests-components task invoked with an invalid data struct") } - dynamicClient := data.DynamicClient() + err := coredns.DeleteCoreDnsDeployment( + data.RemoteClient(), + data.GetName(), + data.GetNamespace(), + ) - components, err := getCoreDnsHostComponentsConfig(data.RemoteClient(), constants.HostCoreDnsComponents) if err != nil { return err } - - imageRepository, _ := util.GetImageMessage() - - for _, component := range components { - klog.V(2).Infof("Delete component %s", component.Name) - - templatedMapping := map[string]interface{}{ - "Namespace": data.GetNamespace(), - "Name": data.GetName(), - "ImageRepository": imageRepository, - } - err = deleteYMLTemplate(dynamicClient, component.Path, templatedMapping) - if err != nil { - return err - } - } return nil } @@ -201,11 +150,6 @@ func runCoreDnsVirtualTask(r workflow.RunData) error { return err } - components, err := getCoreDnsHostComponentsConfig(data.RemoteClient(), constants.VirtualCoreDnsComponents) - if err != nil { - return err - } - kubesvc, err := data.RemoteClient().CoreV1().Services(data.GetNamespace()).Get(context.TODO(), constants.KubeDNSSVCName, metav1.GetOptions{}) if err != nil { return err @@ -231,93 +175,19 @@ func runCoreDnsVirtualTask(r workflow.RunData) error { return fmt.Errorf("get master node ip from env failed") } - for _, component := range components { - klog.V(2).Infof("Deploy component %s", component.Name) - - templatedMapping := map[string]interface{}{ - "Namespace": data.GetNamespace(), - "Name": data.GetName(), - "DNSPort": DNSPort, - "DNSTCPPort": DNSTCPPort, - "MetricsPort": MetricsPort, - "HostNodeAddress": HostNodeAddress, - } - err = applyYMLTemplate(dynamicClient, component.Path, templatedMapping) - if err != nil { - return err - } + templatedMapping := map[string]interface{}{ + "Namespace": data.GetNamespace(), + "Name": data.GetName(), + "DNSPort": DNSPort, + "DNSTCPPort": DNSTCPPort, + "MetricsPort": MetricsPort, + "HostNodeAddress": HostNodeAddress, } - return nil -} -// nolint:dupl -func applyYMLTemplate(dynamicClient dynamic.Interface, manifestGlob string, templateMapping map[string]interface{}) error { - manifests, err := filepath.Glob(manifestGlob) - klog.V(2).Infof("Component Manifests %s", manifestGlob) + err = coredns.EnsureVirtualClusterCoreDns(dynamicClient, templatedMapping) if err != nil { return err } - if manifests == nil { - return errors.Errorf("No matching file for pattern %v", manifestGlob) - } - for _, manifest := range manifests { - klog.V(2).Infof("Applying %s", manifest) - var obj unstructured.Unstructured - bytesData, err := os.ReadFile(manifest) - if err != nil { - return errors.Wrapf(err, "Read file %s error", manifest) - } - - templateBytes, err := util.ParseTemplate(string(bytesData), templateMapping) - if err != nil { - return errors.Wrapf(err, "Parse template %s error", manifest) - } - - err = yaml.Unmarshal([]byte(templateBytes), &obj) - if err != nil { - return errors.Wrapf(err, "Unmarshal manifest bytes data error") - } - err = util.CreateObject(dynamicClient, obj.GetNamespace(), obj.GetName(), &obj) - if err != nil { - return errors.Wrapf(err, "Create object error") - } - } - return nil -} - -// nolint:dupl -func deleteYMLTemplate(dynamicClient dynamic.Interface, manifestGlob string, templateMapping map[string]interface{}) error { - manifests, err := filepath.Glob(manifestGlob) - klog.V(2).Infof("Component Manifests %s", manifestGlob) - if err != nil { - return err - } - if manifests == nil { - return errors.Errorf("No matching file for pattern %v", manifestGlob) - } - for _, manifest := range manifests { - klog.V(2).Infof("Deleting %s", manifest) - var obj unstructured.Unstructured - bytesData, err := os.ReadFile(manifest) - if err != nil { - return errors.Wrapf(err, "Read file %s error", manifest) - } - - templateBytes, err := util.ParseTemplate(string(bytesData), templateMapping) - if err != nil { - return errors.Wrapf(err, "Parse template %s error", manifest) - } - - err = yaml.Unmarshal([]byte(templateBytes), &obj) - if err != nil { - return errors.Wrapf(err, "Unmarshal manifest bytes data error") - } - - err = util.DeleteObject(dynamicClient, obj.GetNamespace(), obj.GetName(), &obj) - if err != nil { - return errors.Wrapf(err, "Delete object error") - } - } return nil }