diff --git a/charts/spiderpool/templates/tls.yaml b/charts/spiderpool/templates/tls.yaml index 196d30b5ae..2521f3b3cc 100644 --- a/charts/spiderpool/templates/tls.yaml +++ b/charts/spiderpool/templates/tls.yaml @@ -36,6 +36,34 @@ webhooks: resources: - spidersubnets sideEffects: None +{{- if .Values.multus.enableMultusConfig }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.spiderpoolController.name | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace }} + path: /mutate-spiderpool-spidernet-io-v2beta1-spidermultusconfig + port: {{ .Values.spiderpoolController.webhookPort }} + {{- if (eq .Values.spiderpoolController.tls.method "provided") }} + caBundle: {{ .Values.spiderpoolController.tls.provided.tlsCa | required "missing spiderpoolController.tls.provided.tlsCa" }} + {{- else if (eq .Values.spiderpoolController.tls.method "auto") }} + caBundle: {{ .ca.Cert | b64enc }} + {{- end }} + failurePolicy: Fail + name: spidermultusconfig.spiderpool.spidernet.io + rules: + - apiGroups: + - spiderpool.spidernet.io + apiVersions: + - v2beta1 + operations: + - CREATE + - UPDATE + resources: + - spidermultusconfigs + sideEffects: None +{{- end }} - admissionReviewVersions: - v1 clientConfig: diff --git a/pkg/constant/k8s.go b/pkg/constant/k8s.go index b8944692e3..3315ccd0f0 100644 --- a/pkg/constant/k8s.go +++ b/pkg/constant/k8s.go @@ -147,3 +147,11 @@ const ( ResourceNameAnnot = "k8s.v1.cni.cncf.io/resourceName" ResourceNameOvsCniValue = "ovs-cni.network.kubevirt.io" ) + +const ( + MacvlanCNI = "macvlan" + IPVlanCNI = "ipvlan" + SriovCNI = "sriov" + OvsCNI = "ovs" + CustomCNI = "custom" +) diff --git a/pkg/coordinatormanager/coordinator_mutate.go b/pkg/coordinatormanager/coordinator_mutate.go index 702bb4bcde..7bcf5957b3 100644 --- a/pkg/coordinatormanager/coordinator_mutate.go +++ b/pkg/coordinatormanager/coordinator_mutate.go @@ -6,12 +6,14 @@ package coordinatormanager import ( "context" "fmt" - "k8s.io/utils/pointer" "net/netip" "strings" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + coordinator_cmd "github.com/spidernet-io/spiderpool/cmd/coordinator/cmd" "github.com/spidernet-io/spiderpool/pkg/constant" spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1" "github.com/spidernet-io/spiderpool/pkg/logutils" @@ -22,7 +24,7 @@ func mutateCoordinator(ctx context.Context, coord *spiderpoolv2beta1.SpiderCoord logger.Info("Start to mutate Coordinator") if coord.Spec.Mode == nil { - coord.Spec.Mode = pointer.String("underlay") + coord.Spec.Mode = pointer.String(string(coordinator_cmd.ModeAuto)) } if coord.Spec.TunePodRoutes == nil { coord.Spec.TunePodRoutes = pointer.Bool(true) diff --git a/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidercoordinator_types.go b/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidercoordinator_types.go index ff8abc1524..9f1f87c844 100644 --- a/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidercoordinator_types.go +++ b/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidercoordinator_types.go @@ -11,7 +11,7 @@ import ( type CoordinatorSpec struct { // +kubebuilder:validation:Enum=auto;underlay;overlay;disabled // +kubebuilder:validation:Optional - Mode *string `json:"mode,omitempty"` + Mode *string `json:"mode"` // CoordinatorSpec is used by SpiderCoordinator and SpiderMultusConfig // in spidermultusconfig CRD , podCIDRType should not be required, which could be merged from SpiderCoordinator CR @@ -21,16 +21,16 @@ type CoordinatorSpec struct { PodCIDRType *string `json:"podCIDRType,omitempty"` // +kubebuilder:validation:Optional - HijackCIDR []string `json:"hijackCIDR,omitempty"` + HijackCIDR []string `json:"hijackCIDR"` // +kubebuilder:validation:Optional - PodMACPrefix *string `json:"podMACPrefix,omitempty"` + PodMACPrefix *string `json:"podMACPrefix"` // +kubebuilder:validation:Optional - TunePodRoutes *bool `json:"tunePodRoutes,omitempty"` + TunePodRoutes *bool `json:"tunePodRoutes"` // +kubebuilder:validation:Optional - PodDefaultRouteNIC *string `json:"podDefaultRouteNIC,omitempty"` + PodDefaultRouteNIC *string `json:"podDefaultRouteNIC"` // +kubebuilder:validation:Optional HostRuleTable *int `json:"hostRuleTable,omitempty"` @@ -39,10 +39,10 @@ type CoordinatorSpec struct { HostRPFilter *int `json:"hostRPFilter,omitempty"` // +kubebuilder:validation:Optional - DetectIPConflict *bool `json:"detectIPConflict,omitempty"` + DetectIPConflict *bool `json:"detectIPConflict"` // +kubebuilder:validation:Optional - DetectGateway *bool `json:"detectGateway,omitempty"` + DetectGateway *bool `json:"detectGateway"` } // CoordinationStatus defines the observed state of SpiderCoordinator. diff --git a/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidermultus_types.go b/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidermultus_types.go index 709d372621..a9b4484075 100644 --- a/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidermultus_types.go +++ b/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1/spidermultus_types.go @@ -52,7 +52,7 @@ type MultusCNIConfigSpec struct { DisableIPAM *bool `json:"disableIPAM"` // +kubebuilder:validation:Optional - CoordinatorConfig *CoordinatorSpec `json:"coordinator,omitempty"` + CoordinatorConfig *CoordinatorSpec `json:"coordinator"` // OtherCniTypeConfig only used for CniType custom, valid json format, can be empty // +kubebuilder:validation:Optional @@ -66,13 +66,13 @@ type SpiderMacvlanCniConfig struct { // +kubebuilder:validation:Optional // +kubebuilder:validation:Minimum=0 // +kubebuilder:validation:Maximum=4094 - VlanID *int32 `json:"vlanID,omitempty"` + VlanID *int32 `json:"vlanID"` // +kubebuilder:validation:Optional - Bond *BondConfig `json:"bond,omitempty"` + Bond *BondConfig `json:"bond"` // +kubebuilder:validation:Optional - SpiderpoolConfigPools *SpiderpoolPools `json:"ippools,omitempty"` + SpiderpoolConfigPools *SpiderpoolPools `json:"ippools"` } type SpiderIPvlanCniConfig struct { @@ -82,13 +82,13 @@ type SpiderIPvlanCniConfig struct { // +kubebuilder:validation:Optional // +kubebuilder:validation:Minimum=0 // +kubebuilder:validation:Maximum=4094 - VlanID *int32 `json:"vlanID,omitempty"` + VlanID *int32 `json:"vlanID"` // +kubebuilder:validation:Optional - Bond *BondConfig `json:"bond,omitempty"` + Bond *BondConfig `json:"bond"` // +kubebuilder:validation:Optional - SpiderpoolConfigPools *SpiderpoolPools `json:"ippools,omitempty"` + SpiderpoolConfigPools *SpiderpoolPools `json:"ippools"` } type SpiderSRIOVCniConfig struct { @@ -98,14 +98,14 @@ type SpiderSRIOVCniConfig struct { // +kubebuilder:validation:Optional // +kubebuilder:validation:Minimum=0 // +kubebuilder:validation:Maximum=4094 - VlanID *int32 `json:"vlanID,omitempty"` + VlanID *int32 `json:"vlanID"` // +kubebuilder:default=false // +kubebuilder:validation:Optional EnableRdma bool `json:"enableRdma"` // +kubebuilder:validation:Optional - SpiderpoolConfigPools *SpiderpoolPools `json:"ippools,omitempty"` + SpiderpoolConfigPools *SpiderpoolPools `json:"ippools"` } type SpiderOvsCniConfig struct { @@ -119,7 +119,7 @@ type SpiderOvsCniConfig struct { // PCI address of a VF in valid sysfs format DeviceID string `json:"deviceID"` // +kubebuilder:validation:Optional - SpiderpoolConfigPools *SpiderpoolPools `json:"ippools,omitempty"` + SpiderpoolConfigPools *SpiderpoolPools `json:"ippools"` } type Trunk struct { @@ -147,16 +147,16 @@ type BondConfig struct { Mode int32 `json:"mode"` // +kubebuilder:validation:Optional - Options *string `json:"options,omitempty"` + Options *string `json:"options"` } // SpiderpoolPools could specify the IPAM spiderpool CNI configuration default IPv4&IPv6 pools. type SpiderpoolPools struct { // +kubebuilder:validation:Optional - IPv4IPPool []string `json:"ipv4,omitempty"` + IPv4IPPool []string `json:"ipv4"` // +kubebuilder:validation:Optional - IPv6IPPool []string `json:"ipv6,omitempty"` + IPv6IPPool []string `json:"ipv6"` } func init() { diff --git a/pkg/multuscniconfig/multusconfig_informer.go b/pkg/multuscniconfig/multusconfig_informer.go index 9a1aebd5c7..18dad916fd 100644 --- a/pkg/multuscniconfig/multusconfig_informer.go +++ b/pkg/multuscniconfig/multusconfig_informer.go @@ -386,7 +386,7 @@ func generateNetAttachDef(netAttachName string, multusConf *spiderpoolv2beta1.Sp macvlanCNIConf := generateMacvlanCNIConf(disableIPAM, *multusConfSpec) // head insertion plugins = append([]interface{}{macvlanCNIConf}, plugins...) - if multusConfSpec.MacvlanConfig.VlanID != nil && *multusConfSpec.MacvlanConfig.VlanID != 0 { + if len(multusConfSpec.MacvlanConfig.Master) > 0 || (multusConfSpec.MacvlanConfig.VlanID != nil && *multusConfSpec.MacvlanConfig.VlanID != 0) { // we need to set Subvlan as first at the CNI plugin chain subVlanCNIConf := generateIfacer(multusConfSpec.MacvlanConfig.Master, *multusConfSpec.MacvlanConfig.VlanID, @@ -402,7 +402,7 @@ func generateNetAttachDef(netAttachName string, multusConf *spiderpoolv2beta1.Sp ipvlanCNIConf := generateIPvlanCNIConf(disableIPAM, *multusConfSpec) // head insertion plugins = append([]interface{}{ipvlanCNIConf}, plugins...) - if multusConfSpec.IPVlanConfig.VlanID != nil && *multusConfSpec.IPVlanConfig.VlanID != 0 { + if len(multusConfSpec.IPVlanConfig.Master) > 0 || (multusConfSpec.IPVlanConfig.VlanID != nil && *multusConfSpec.IPVlanConfig.VlanID != 0) { // we need to set Subvlan as first at the CNI plugin chain subVlanCNIConf := generateIfacer(multusConfSpec.IPVlanConfig.Master, *multusConfSpec.IPVlanConfig.VlanID, diff --git a/pkg/multuscniconfig/multusconfig_mutate.go b/pkg/multuscniconfig/multusconfig_mutate.go new file mode 100644 index 0000000000..95425d5ea8 --- /dev/null +++ b/pkg/multuscniconfig/multusconfig_mutate.go @@ -0,0 +1,168 @@ +// Copyright 2022 Authors of spidernet-io +// SPDX-License-Identifier: Apache-2.0 +package multuscniconfig + +import ( + "context" + + "k8s.io/utils/pointer" + + coordinator_cmd "github.com/spidernet-io/spiderpool/cmd/coordinator/cmd" + "github.com/spidernet-io/spiderpool/pkg/constant" + spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1" + "github.com/spidernet-io/spiderpool/pkg/logutils" +) + +func mutateSpiderMultusConfig(ctx context.Context, smc *spiderpoolv2beta1.SpiderMultusConfig) error { + logger := logutils.FromContext(ctx) + logger.Info("Start to mutate Spidermulutconfig") + + switch smc.Spec.CniType { + case constant.MacvlanCNI: + setMacvlanDefaultConfig(smc.Spec.MacvlanConfig) + case constant.IPVlanCNI: + setIPVlanDefaultConfig(smc.Spec.IPVlanConfig) + case constant.SriovCNI: + setSriovDefaultConfig(smc.Spec.SriovConfig) + case constant.OvsCNI: + setOvsDefaultConfig(smc.Spec.OvsConfig) + case constant.CustomCNI: + if smc.Spec.CustomCNIConfig == nil { + smc.Spec.CustomCNIConfig = pointer.String("") + } + } + + smc.Spec.CoordinatorConfig = setCoordinatorDefaultConfig(smc.Spec.CoordinatorConfig) + return nil +} + +func setMacvlanDefaultConfig(macvlanConfig *spiderpoolv2beta1.SpiderMacvlanCniConfig) { + if macvlanConfig == nil { + return + } + + if macvlanConfig.VlanID == nil { + macvlanConfig.VlanID = pointer.Int32(0) + } + + macvlanConfig.Bond = setBondDefaultConfig(macvlanConfig.Bond) + + if macvlanConfig.SpiderpoolConfigPools == nil { + macvlanConfig.SpiderpoolConfigPools = &spiderpoolv2beta1.SpiderpoolPools{ + IPv4IPPool: []string{}, + IPv6IPPool: []string{}, + } + } +} + +func setBondDefaultConfig(bond *spiderpoolv2beta1.BondConfig) *spiderpoolv2beta1.BondConfig { + if bond == nil { + return &spiderpoolv2beta1.BondConfig{ + Name: "", + Mode: 0, + Options: pointer.String(""), + } + } + + if bond.Options == nil { + bond.Options = pointer.String("") + } + return bond +} + +func setIPVlanDefaultConfig(ipvlanConfig *spiderpoolv2beta1.SpiderIPvlanCniConfig) { + if ipvlanConfig == nil { + return + } + + if ipvlanConfig.VlanID == nil { + ipvlanConfig.VlanID = pointer.Int32(0) + } + + ipvlanConfig.Bond = setBondDefaultConfig(ipvlanConfig.Bond) + + if ipvlanConfig.SpiderpoolConfigPools == nil { + ipvlanConfig.SpiderpoolConfigPools = &spiderpoolv2beta1.SpiderpoolPools{ + IPv4IPPool: []string{}, + IPv6IPPool: []string{}, + } + } +} + +func setSriovDefaultConfig(sriovConfig *spiderpoolv2beta1.SpiderSRIOVCniConfig) { + if sriovConfig == nil { + return + } + + if sriovConfig.VlanID == nil { + sriovConfig.VlanID = pointer.Int32(0) + } + + if sriovConfig.SpiderpoolConfigPools == nil { + sriovConfig.SpiderpoolConfigPools = &spiderpoolv2beta1.SpiderpoolPools{ + IPv4IPPool: []string{}, + IPv6IPPool: []string{}, + } + } +} + +func setOvsDefaultConfig(ovsConfig *spiderpoolv2beta1.SpiderOvsCniConfig) { + if ovsConfig == nil { + return + } + + if ovsConfig.VlanTag == nil { + ovsConfig.VlanTag = pointer.Int32(0) + } + + if ovsConfig.SpiderpoolConfigPools == nil { + ovsConfig.SpiderpoolConfigPools = &spiderpoolv2beta1.SpiderpoolPools{ + IPv4IPPool: []string{}, + IPv6IPPool: []string{}, + } + } +} + +func setCoordinatorDefaultConfig(coordinator *spiderpoolv2beta1.CoordinatorSpec) *spiderpoolv2beta1.CoordinatorSpec { + if coordinator == nil { + return &spiderpoolv2beta1.CoordinatorSpec{ + Mode: pointer.String(string(coordinator_cmd.ModeAuto)), + HijackCIDR: []string{}, + DetectGateway: pointer.Bool(false), + DetectIPConflict: pointer.Bool(false), + PodMACPrefix: pointer.String(""), + PodDefaultRouteNIC: pointer.String(""), + TunePodRoutes: pointer.Bool(true), + } + } + + if coordinator.Mode == nil { + coordinator.Mode = pointer.String(string(coordinator_cmd.ModeAuto)) + } + + if len(coordinator.HijackCIDR) == 0 { + coordinator.HijackCIDR = []string{} + } + + if coordinator.DetectGateway == nil { + coordinator.DetectGateway = pointer.Bool(false) + } + + if coordinator.DetectIPConflict == nil { + coordinator.DetectIPConflict = pointer.Bool(false) + } + + if coordinator.PodMACPrefix == nil { + coordinator.PodMACPrefix = pointer.String("") + } + + if coordinator.PodDefaultRouteNIC == nil { + coordinator.PodDefaultRouteNIC = pointer.String("") + } + + if coordinator.TunePodRoutes == nil { + coordinator.TunePodRoutes = pointer.Bool(false) + } + + return coordinator +} diff --git a/pkg/multuscniconfig/multusconfig_webhook.go b/pkg/multuscniconfig/multusconfig_webhook.go index 3beda4188e..2c20b26461 100644 --- a/pkg/multuscniconfig/multusconfig_webhook.go +++ b/pkg/multuscniconfig/multusconfig_webhook.go @@ -31,12 +31,29 @@ func (mcw *MultusConfigWebhook) SetupWebhookWithManager(mgr ctrl.Manager) error return ctrl.NewWebhookManagedBy(mgr). For(&spiderpoolv2beta1.SpiderMultusConfig{}). + WithDefaulter(mcw). WithValidator(mcw). Complete() } var _ webhook.CustomValidator = &MultusConfigWebhook{} +// Default implements admission.CustomDefaulter. +func (*MultusConfigWebhook) Default(ctx context.Context, obj runtime.Object) error { + smc := obj.(*spiderpoolv2beta1.SpiderMultusConfig) + + mutateLogger := logger.Named("Mutating").With( + zap.String("Spidermultusconfig", smc.Name)) + mutateLogger.Sugar().Debugf("Request Spidermultusconfig: %+v", *smc) + + if err := mutateSpiderMultusConfig(logutils.IntoContext(ctx, mutateLogger), smc); err != nil { + mutateLogger.Sugar().Errorf("Failed to mutate Spidermultusconfig: %v", err) + } + + mutateLogger.Sugar().Debugf("Finish Spidermultusconfig: %+v", smc) + return nil +} + func (mcw *MultusConfigWebhook) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) { multusConfig := obj.(*spiderpoolv2beta1.SpiderMultusConfig) diff --git a/test/Makefile.defs b/test/Makefile.defs index 653905b8a9..0ad7086750 100644 --- a/test/Makefile.defs +++ b/test/Makefile.defs @@ -57,8 +57,6 @@ INSTALL_SPIDERDOCTOR ?= true INSTALL_KUBEVIRT ?= false -CNI_PACKAGE_VERSION ?= v1.3.0 - #============ ginkgo-custom-flag ==================== E2E_CLUSTER_NAME ?= spider diff --git a/test/scripts/install-multus.sh b/test/scripts/install-multus.sh index 5e96033db5..2d334eeab7 100755 --- a/test/scripts/install-multus.sh +++ b/test/scripts/install-multus.sh @@ -366,7 +366,7 @@ Install::SpiderpoolCR kubectl get spidercoordinator default -o yaml --kubeconfig ${E2E_KUBECONFIG} kubectl get sp -o wide --kubeconfig ${E2E_KUBECONFIG} -kubectl get spidermultusconfig -n kube-system --kubeconfig ${E2E_KUBECONFIG} +kubectl get spidermultusconfig -n kube-system --kubeconfig ${E2E_KUBECONFIG} -o yaml kubectl get network-attachment-definitions.k8s.cni.cncf.io --kubeconfig ${E2E_KUBECONFIG} -n kube-system -o yaml echo "$CURRENT_FILENAME : done" \ No newline at end of file diff --git a/test/scripts/prepare.sh b/test/scripts/prepare.sh index a98f86438f..a13f68286c 100755 --- a/test/scripts/prepare.sh +++ b/test/scripts/prepare.sh @@ -7,9 +7,6 @@ DOWNLOAD_DIR="$1" mkdir -p $DOWNLOAD_DIR echo "Download Package to $DOWNLOAD_DIR " -[ -z "$CNI_PACKAGE_VERSION" ] && echo "error, miss CNI_PACKAGE_VERSION " && exit 1 -echo "Using CNI_PACKAGE_VERSION: $CNI_PACKAGE_VERSION" - [ -z "$ARCH" ] && echo "error, miss ARCH " && exit 1 echo "Using ARCH: $ARCH" @@ -17,20 +14,6 @@ echo "Using ARCH: $ARCH" echo "all images: $IMAGE_LIST" #================================= - -OS=$(uname | tr 'A-Z' 'a-z') - -# prepare cni-plugins -PACKAGE_NAME="cni-plugins-linux-${ARCH}-${CNI_PACKAGE_VERSION}.tgz" -if [ ! -f "${DOWNLOAD_DIR}/${PACKAGE_NAME}" ]; then - echo "begin to download cni-plugins ${PACKAGE_NAME} " - wget -P ${DOWNLOAD_DIR} https://github.com/containernetworking/plugins/releases/download/${CNI_PACKAGE_VERSION}/${PACKAGE_NAME} -else - echo "${DOWNLOAD_DIR}/${PACKAGE_NAME} exist, Skip download" -fi - -#================================= - for image in $IMAGE_LIST ; do PREFIX_IMAGE=$(echo $image | awk -F ':' '{print $1}') SUFFIX_IMAGE=$(echo $image | awk -F ':' '{print $2}')