diff --git a/docs/multicluster/user-guide.md b/docs/multicluster/user-guide.md index 1f8006ecb4d..549bc24ae4a 100644 --- a/docs/multicluster/user-guide.md +++ b/docs/multicluster/user-guide.md @@ -494,7 +494,7 @@ metadata: spec: kind: AntreaClusterNetworkPolicy name: strict-namespace-isolation # In each importing cluster, an ACNP of name antrea-mc-strict-namespace-isolation will be created with the spec below - clusternetworkpolicy: + clusterNetworkPolicy: priority: 1 tier: securityops appliedTo: diff --git a/multicluster/apis/multicluster/v1alpha1/resourceexport_types.go b/multicluster/apis/multicluster/v1alpha1/resourceexport_types.go index 7f7d04f5a0f..eb3e7f84876 100644 --- a/multicluster/apis/multicluster/v1alpha1/resourceexport_types.go +++ b/multicluster/apis/multicluster/v1alpha1/resourceexport_types.go @@ -36,7 +36,7 @@ type EndpointsExport struct { // ExternalEntityExport exports ExternalEntity. type ExternalEntityExport struct { - ExternalEntitySpec v1alpha2.ExternalEntitySpec `json:"externalentityspec,omitempty"` + ExternalEntitySpec v1alpha2.ExternalEntitySpec `json:"externalEntitySpec,omitempty"` } // RawResourceExport exports opaque resources. @@ -60,11 +60,11 @@ type ResourceExportSpec struct { // If exported resource is Endpoints. Endpoints *EndpointsExport `json:"endpoints,omitempty"` // If exported resource is ClusterInfo. - ClusterInfo *ClusterInfo `json:"clusterinfo,omitempty"` + ClusterInfo *ClusterInfo `json:"clusterInfo,omitempty"` // If exported resource is ExternalEntity. - ExternalEntity *ExternalEntityExport `json:"externalentity,omitempty"` + ExternalEntity *ExternalEntityExport `json:"externalEntity,omitempty"` // If exported resource is AntreaClusterNetworkPolicy. - ClusterNetworkPolicy *v1alpha1.ClusterNetworkPolicySpec `json:"clusternetworkpolicy,omitempty"` + ClusterNetworkPolicy *v1alpha1.ClusterNetworkPolicySpec `json:"clusterNetworkPolicy,omitempty"` // If exported resource kind is unknown. Raw *RawResourceExport `json:"raw,omitempty"` } diff --git a/multicluster/build/yamls/antrea-multicluster-leader-global.yml b/multicluster/build/yamls/antrea-multicluster-leader-global.yml index 7443f2e8467..a5eb1217570 100644 --- a/multicluster/build/yamls/antrea-multicluster-leader-global.yml +++ b/multicluster/build/yamls/antrea-multicluster-leader-global.yml @@ -364,7 +364,7 @@ spec: description: ClusterID specifies the member cluster this resource exported from. type: string - clusterinfo: + clusterInfo: description: If exported resource is ClusterInfo. properties: clusterID: @@ -383,7 +383,7 @@ spec: description: ServiceCIDR is the IP ranges used by Service ClusterIP. type: string type: object - clusternetworkpolicy: + clusterNetworkPolicy: description: If exported resource is AntreaClusterNetworkPolicy. properties: appliedTo: @@ -2765,10 +2765,10 @@ spec: type: object type: array type: object - externalentity: + externalEntity: description: If exported resource is ExternalEntity. properties: - externalentityspec: + externalEntitySpec: description: ExternalEntitySpec defines the desired state for ExternalEntity. properties: diff --git a/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml b/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml index 8b88b27af4e..0b9440868d0 100644 --- a/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml +++ b/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml @@ -59,7 +59,7 @@ spec: description: ClusterID specifies the member cluster this resource exported from. type: string - clusterinfo: + clusterInfo: description: If exported resource is ClusterInfo. properties: clusterID: @@ -78,7 +78,7 @@ spec: description: ServiceCIDR is the IP ranges used by Service ClusterIP. type: string type: object - clusternetworkpolicy: + clusterNetworkPolicy: description: If exported resource is AntreaClusterNetworkPolicy. properties: appliedTo: @@ -2460,10 +2460,10 @@ spec: type: object type: array type: object - externalentity: + externalEntity: description: If exported resource is ExternalEntity. properties: - externalentityspec: + externalEntitySpec: description: ExternalEntitySpec defines the desired state for ExternalEntity. properties: diff --git a/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller.go b/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller.go index a0308609314..578daa4260b 100644 --- a/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller.go +++ b/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller.go @@ -43,6 +43,10 @@ var ( ) func (r *ResourceImportReconciler) handleResImpUpdateForClusterNetworkPolicy(ctx context.Context, resImp *multiclusterv1alpha1.ResourceImport) (ctrl.Result, error) { + if resImp.Spec.ClusterNetworkPolicy == nil { + klog.V(2).InfoS("Skip reconciling ResourceImport for ClusterNetworkPolicy since it has no valid spec", "resourceimport", klog.KObj(resImp)) + return ctrl.Result{}, nil + } acnpName := types.NamespacedName{ Namespace: "", Name: common.AntreaMCSPrefix + resImp.Spec.Name, diff --git a/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller_test.go b/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller_test.go index a4c44b30573..3ede4c49559 100644 --- a/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller_test.go +++ b/multicluster/controllers/multicluster/commonarea/acnp_resourceimport_controller_test.go @@ -46,6 +46,10 @@ var ( Namespace: leaderNamespace, Name: "default-acnp-no-matching-tier", }} + acnpImpNoSpecReq = ctrl.Request{NamespacedName: types.NamespacedName{ + Namespace: leaderNamespace, + Name: "default-acnp-no-spec", + }} allowAction = v1alpha1.RuleActionAllow dropAction = v1alpha1.RuleActionDrop @@ -87,6 +91,16 @@ var ( }, }, } + acnpResImportNoSpec = &mcsv1alpha1.ResourceImport{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: leaderNamespace, + Name: "default-acnp-no-spec", + }, + Spec: mcsv1alpha1.ResourceImportSpec{ + Name: "default-acnp-no-spec", + Kind: common.AntreaClusterNetworkPolicyKind, + }, + } acnpResImportNoMatchingTier = &mcsv1alpha1.ResourceImport{ ObjectMeta: metav1.ObjectMeta{ Namespace: leaderNamespace, @@ -108,7 +122,7 @@ var ( func TestResourceImportReconciler_handleCopySpanACNPCreateEvent(t *testing.T) { fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(securityOpsTier).Build() - fakeRemoteClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(acnpResImport, acnpResImportNoMatchingTier).Build() + fakeRemoteClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(acnpResImport, acnpResImportNoMatchingTier, acnpResImportNoSpec).Build() remoteCluster := NewFakeRemoteCommonArea(fakeRemoteClient, "leader-cluster", localClusterID, "default") tests := []struct { @@ -129,6 +143,12 @@ func TestResourceImportReconciler_handleCopySpanACNPCreateEvent(t *testing.T) { req: acnpImpNoMatchingTierReq, expectedSuccess: false, }, + { + name: "import ACNP of empty spec", + acnpImportName: "acnp-no-spec", + req: acnpImpNoSpecReq, + expectedSuccess: false, + }, } r := NewResourceImportReconciler(fakeClient, scheme, fakeClient, localClusterID, "default", remoteCluster) for _, tt := range tests { diff --git a/multicluster/controllers/multicluster/commonarea/clusterinfo_importer.go b/multicluster/controllers/multicluster/commonarea/clusterinfo_importer.go index f80cc2ff47a..6134adc265c 100644 --- a/multicluster/controllers/multicluster/commonarea/clusterinfo_importer.go +++ b/multicluster/controllers/multicluster/commonarea/clusterinfo_importer.go @@ -33,6 +33,10 @@ import ( func (r *ResourceImportReconciler) handleResImpUpdateForClusterInfo(ctx context.Context, req ctrl.Request, resImp *mcsv1alpha1.ResourceImport) (ctrl.Result, error) { klog.V(2).InfoS("Reconciling ClusterInfo of ResourceImport", "resourceimport", req.NamespacedName) var err error + if resImp.Spec.ClusterInfo == nil { + klog.V(2).InfoS("Skip reconciling ResourceImport for ClusterInfo since it has no valid spec", "resourceimport", req.NamespacedName) + return ctrl.Result{}, nil + } clusterInfo := *resImp.Spec.ClusterInfo // If ClusterInfo is from local cluster, skip it. diff --git a/multicluster/controllers/multicluster/commonarea/clusterinfo_importer_test.go b/multicluster/controllers/multicluster/commonarea/clusterinfo_importer_test.go index 275fd49c2fa..9d9c53998dc 100644 --- a/multicluster/controllers/multicluster/commonarea/clusterinfo_importer_test.go +++ b/multicluster/controllers/multicluster/commonarea/clusterinfo_importer_test.go @@ -93,6 +93,31 @@ func TestResourceImportReconciler_handleClusterInfo(t *testing.T) { Namespace: "default", }, } + ciResImportEmptySpec := &mcsv1alpha1.ResourceImport{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "cluster-a-default-clusterinfo-empty", + }, + Spec: mcsv1alpha1.ResourceImportSpec{ + Kind: common.ClusterInfoKind, + Name: "node-1", + Namespace: "default", + }, + } + ciResImportLocal := &mcsv1alpha1.ResourceImport{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "cluster-d-default-clusterinfo-empty", + }, + Spec: mcsv1alpha1.ResourceImportSpec{ + Kind: common.ClusterInfoKind, + Name: "node-1", + Namespace: "default", + ClusterInfo: &mcsv1alpha1.ClusterInfo{ + ClusterID: "cluster-d", + }, + }, + } ciImportA := mcsv1alpha1.ClusterInfoImport{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", @@ -135,6 +160,16 @@ func TestResourceImportReconciler_handleClusterInfo(t *testing.T) { existingCIResImport: ciResImportA, expectedCIImport: &ciImportA, }, + { + name: "skip import empty ResourceImport", + existingCIResImport: ciResImportEmptySpec, + expectedCIImport: nil, + }, + { + name: "skip import ResourceImport from local", + existingCIResImport: ciResImportLocal, + expectedCIImport: nil, + }, { name: "update ClusterInfoImport successfully", existingCIResImport: ciResImportB, diff --git a/multicluster/controllers/multicluster/leader_clusterset_controller.go b/multicluster/controllers/multicluster/leader_clusterset_controller.go index 414d897f977..608ab21f4ab 100644 --- a/multicluster/controllers/multicluster/leader_clusterset_controller.go +++ b/multicluster/controllers/multicluster/leader_clusterset_controller.go @@ -159,7 +159,6 @@ func (r *LeaderClusterSetReconciler) updateStatus() { status := multiclusterv1alpha1.ClusterSetStatus{} status.ObservedGeneration = r.clusterSetConfig.Generation clusterStatuses := r.StatusManager.GetMemberClusterStatuses() - klog.InfoS("size of cluster", "size", len(clusterStatuses)) status.ClusterStatuses = clusterStatuses sizeOfMembers := len(clusterStatuses) status.TotalClusters = int32(sizeOfMembers)