From 122956401db183e71e2c2a9d54d3619d8307fb62 Mon Sep 17 00:00:00 2001 From: Yang Ding Date: Fri, 4 Mar 2022 13:25:09 -0800 Subject: [PATCH] Use events for acnp import status report Signed-off-by: Yang Ding --- docs/multicluster/architecture.md | 42 ++++- .../antrea-multicluster-leader-global.yml | 136 ++++++++++++--- .../antrea-multicluster-leader-namespaced.yml | 30 ++++ .../yamls/antrea-multicluster-member.yml | 146 +++++++++++++--- ...cluster.crd.antrea.io_resourceexports.yaml | 86 ++++++++-- ...cluster.crd.antrea.io_resourceimports.yaml | 86 ++++++++-- .../leader-ns/member_cluster_role.yaml | 10 ++ multicluster/config/rbac/role.yaml | 10 ++ .../commonarea/acnpimport_controller.go | 157 +++++++----------- .../commonarea/acnpimport_controller_test.go | 19 +-- .../commonarea/resourceimport_controller.go | 1 + 11 files changed, 545 insertions(+), 178 deletions(-) diff --git a/docs/multicluster/architecture.md b/docs/multicluster/architecture.md index 66d09007b95..0813ede36e9 100644 --- a/docs/multicluster/architecture.md +++ b/docs/multicluster/architecture.md @@ -136,4 +136,44 @@ isolation for that cluster. Note that because the Tier that an ACNP refers to must exist before the ACNP is applied, an importing cluster may fail to create the ACNP to be replicated, if the tier in the ResourceExport spec cannot be -found in that particular cluster. +found in that particular cluster. The ACNP creation status of each member cluster will be reported back +to the Common Area as K8s Events, and can be checked by describing the ResourceImport of the original +ResourceExport: + +``` +kubectl describe resourceimport -A +--- +Name: strict-namespace-isolation-antreaclusternetworkpolicy +Namespace: antrea-mcs-ns +Labels: +Annotations: +API Version: multicluster.crd.antrea.io/v1alpha1 +Kind: ResourceImport +Spec: + Clusternetworkpolicy: + Applied To: + Namespace Selector: + Ingress: + Action: Pass + Enable Logging: false + From: + Namespaces: + Match: Self + Pod Selector: + Match Labels: + k8s-app: kube-dns + Action: Drop + Enable Logging: false + From: + Namespace Selector: + Priority: 1 + Tier: random + Kind: AntreaClusterNetworkPolicy + Name: strict-namespace-isolation + ... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal ACNPImportSucceeded 2m11s resourceimport-controller ACNP successfully created in the importing cluster test-cluster-east + Warning ACNPImportFailed 2m11s resourceimport-controller ACNP Tier does not exist in the importing cluster test-cluster-west +``` diff --git a/multicluster/build/yamls/antrea-multicluster-leader-global.yml b/multicluster/build/yamls/antrea-multicluster-leader-global.yml index a77af88cd0e..257e3004b49 100644 --- a/multicluster/build/yamls/antrea-multicluster-leader-global.yml +++ b/multicluster/build/yamls/antrea-multicluster-leader-global.yml @@ -530,6 +530,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -657,6 +665,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -779,6 +795,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -922,21 +946,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1068,6 +1096,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -1190,6 +1226,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -1333,21 +1377,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1913,6 +1961,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -2040,6 +2096,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -2162,6 +2226,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -2305,21 +2377,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -2451,6 +2527,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -2573,6 +2657,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -2716,21 +2808,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: diff --git a/multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml b/multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml index 3d74e21880f..05e15670bfc 100644 --- a/multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml +++ b/multicluster/build/yamls/antrea-multicluster-leader-namespaced.yml @@ -33,6 +33,16 @@ rules: - patch - update - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update - apiGroups: - "" resources: @@ -356,6 +366,26 @@ metadata: name: antrea-mc-member-cluster-role namespace: changeme rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update - apiGroups: - multicluster.crd.antrea.io resources: diff --git a/multicluster/build/yamls/antrea-multicluster-member.yml b/multicluster/build/yamls/antrea-multicluster-member.yml index 55cbe9cda7c..faad9dc25f2 100644 --- a/multicluster/build/yamls/antrea-multicluster-member.yml +++ b/multicluster/build/yamls/antrea-multicluster-member.yml @@ -530,6 +530,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -657,6 +665,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -779,6 +795,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -922,21 +946,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1068,6 +1096,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -1190,6 +1226,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -1333,21 +1377,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1913,6 +1961,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -2040,6 +2096,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -2162,6 +2226,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -2305,21 +2377,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -2451,6 +2527,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -2573,6 +2657,14 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -2716,21 +2808,25 @@ spec: description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched by this field, as workloads in AppliedTo/To/From fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: description: Rule is matched if traffic is intended for a Service listed in this field. Currently only ClusterIP types Services are supported in this field. This field can only be used when AntreaProxy is enabled. This field can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to a v1.Service. + description: NamespacedName refers to a Namespace scoped resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -3356,6 +3452,16 @@ rules: - patch - update - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update - apiGroups: - "" resources: 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 7539481a70a..32993f38ba1 100644 --- a/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml +++ b/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceexports.yaml @@ -239,6 +239,16 @@ spec: contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched + by this field, as workloads in AppliedTo/To/From fields. + Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -458,6 +468,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -669,6 +689,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -911,6 +941,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: @@ -921,17 +961,13 @@ spec: can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to - a v1.Service. + description: NamespacedName refers to a Namespace scoped + resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1155,6 +1191,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -1366,6 +1412,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -1608,6 +1664,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: @@ -1618,17 +1684,13 @@ spec: can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to - a v1.Service. + description: NamespacedName refers to a Namespace scoped + resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: diff --git a/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceimports.yaml b/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceimports.yaml index ef9b9827319..8790288ea66 100644 --- a/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceimports.yaml +++ b/multicluster/config/crd/bases/multicluster.crd.antrea.io_resourceimports.yaml @@ -241,6 +241,16 @@ spec: contains only "value". The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount matched + by this field, as workloads in AppliedTo/To/From fields. + Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array egress: @@ -460,6 +470,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -671,6 +691,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -913,6 +943,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: @@ -923,17 +963,13 @@ spec: can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to - a v1.Service. + description: NamespacedName refers to a Namespace scoped + resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: @@ -1157,6 +1193,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array enableLogging: @@ -1368,6 +1414,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array name: @@ -1610,6 +1666,16 @@ spec: The requirements are ANDed. type: object type: object + serviceAccount: + description: Select all Pods with the ServiceAccount + matched by this field, as workloads in AppliedTo/To/From + fields. Cannot be set with any other selector. + properties: + name: + type: string + namespace: + type: string + type: object type: object type: array toServices: @@ -1620,17 +1686,13 @@ spec: can't be used with To or Ports. If this field and To are both empty or missing, this rule matches all destinations. items: - description: ServiceReference represents a reference to - a v1.Service. + description: NamespacedName refers to a Namespace scoped + resource. All fields must be used together. properties: name: - description: Name of the Service type: string namespace: - description: Namespace of the Service type: string - required: - - name type: object type: array required: diff --git a/multicluster/config/overlays/leader-ns/member_cluster_role.yaml b/multicluster/config/overlays/leader-ns/member_cluster_role.yaml index 66201435698..0357f3f2131 100644 --- a/multicluster/config/overlays/leader-ns/member_cluster_role.yaml +++ b/multicluster/config/overlays/leader-ns/member_cluster_role.yaml @@ -6,6 +6,16 @@ metadata: name: member-cluster-role namespace: changeme rules: + - apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update - apiGroups: - multicluster.crd.antrea.io resources: diff --git a/multicluster/config/rbac/role.yaml b/multicluster/config/rbac/role.yaml index 2f69305e473..b876d9672de 100644 --- a/multicluster/config/rbac/role.yaml +++ b/multicluster/config/rbac/role.yaml @@ -18,6 +18,16 @@ rules: - patch - update - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - update - apiGroups: - "" resources: diff --git a/multicluster/controllers/multicluster/commonarea/acnpimport_controller.go b/multicluster/controllers/multicluster/commonarea/acnpimport_controller.go index 8134cead088..b7b82129491 100644 --- a/multicluster/controllers/multicluster/commonarea/acnpimport_controller.go +++ b/multicluster/controllers/multicluster/commonarea/acnpimport_controller.go @@ -1,12 +1,9 @@ /* Copyright 2022 Antrea 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. @@ -19,6 +16,7 @@ package commonarea import ( "context" "errors" + "math/rand" corev1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" @@ -34,16 +32,28 @@ import ( "antrea.io/antrea/pkg/apis/crd/v1alpha1" ) +const ( + nameSuffixLength int = 5 + acnpImportStatusPrefix string = "acnp-import-status-" + acnpImportSucceeded string = "ACNPImportSucceeded" + acnpImportFailed string = "ACNPImportFailed" +) + +var ( + resourceImportAPIVersion = "multicluster.crd.antrea.io/v1alpha1" + resourceImportKind = "ResourceImport" + acnpEventReportingController = "resourceimport-controller" + // TODO(yang): add run-time pod suffix + acnpEventReportingInstance = "antrea-mc-controller" + lettersAndDigits = []rune("abcdefghijklmnopqrstuvwxyz0123456789") +) + func (r *ResourceImportReconciler) handleResImpUpdateForClusterNetworkPolicy(ctx context.Context, resImp *multiclusterv1alpha1.ResourceImport) (ctrl.Result, error) { - acnpImpName := types.NamespacedName{ - Namespace: "", - Name: resImp.Spec.Name, - } acnpName := types.NamespacedName{ Namespace: "", Name: common.AntreaMCSPrefix + resImp.Spec.Name, } - klog.InfoS("Updating ACNP and ACNPImport corresponding to ResourceImport", + klog.InfoS("Updating ACNP corresponding to ResourceImport", "acnp", acnpName.String(), "resourceimport", klog.KObj(resImp)) acnp := &v1alpha1.ClusterNetworkPolicy{} @@ -86,85 +96,63 @@ func (r *ResourceImportReconciler) handleResImpUpdateForClusterNetworkPolicy(ctx return ctrl.Result{}, err } } - acnpImp := &multiclusterv1alpha1.ACNPImport{} - err = r.localClusterClient.Get(ctx, acnpImpName, acnpImp) - acnpImpNotFound := apierrors.IsNotFound(err) - if err != nil && !acnpImpNotFound { - klog.ErrorS(err, "failed to get existing ACNPImports") - return ctrl.Result{}, err - } - // acnpImport status will be realizable=False if Tier is not found on this member cluster, and realizable=True otherwise. - acnpImpObj, isRealizable := getACNPImport(resImp, tierNotFound) - if acnpImpNotFound { - err := r.localClusterClient.Create(ctx, acnpImpObj, &client.CreateOptions{}) - if err != nil { - klog.ErrorS(err, "failed to create ACNPImport", "acnpimport", klog.KObj(acnpImpObj)) - return ctrl.Result{}, err - } - r.installedResImports.Add(*resImp) + + statusEvent := &corev1.Event{ + ObjectMeta: metav1.ObjectMeta{ + Name: randName(acnpImportStatusPrefix + r.localClusterID + "-"), + Namespace: resImp.Namespace, + }, + InvolvedObject: corev1.ObjectReference{ + APIVersion: resourceImportAPIVersion, + Kind: resourceImportKind, + Name: resImp.Name, + Namespace: resImp.Namespace, + UID: resImp.GetUID(), + }, + FirstTimestamp: metav1.Now(), + LastTimestamp: metav1.Now(), + ReportingController: acnpEventReportingController, + ReportingInstance: acnpEventReportingInstance, + Action: "reconciled", } - patchACNPImportStatus := false - if len(acnpImp.Status.Conditions) == 0 { - acnpImp.Status = acnpImpObj.Status - patchACNPImportStatus = true + if tierNotFound { + statusEvent.Type = corev1.EventTypeWarning + statusEvent.Reason = acnpImportFailed + statusEvent.Message = "ACNP Tier does not exist in the importing cluster " + r.localClusterID } else { - for _, c := range acnpImp.Status.Conditions { - if c.Type == multiclusterv1alpha1.ACNPImportRealizable && c.Status != isRealizable { - acnpImp.Status = acnpImpObj.Status - patchACNPImportStatus = true - } - } + statusEvent.Type = corev1.EventTypeNormal + statusEvent.Reason = acnpImportSucceeded + statusEvent.Message = "ACNP successfully created in the importing cluster " + r.localClusterID } - // Patch ACNPImport status if realizable state has changed. - if patchACNPImportStatus { - if err := r.localClusterClient.Status().Update(ctx, acnpImp); err != nil { - klog.ErrorS(err, "failed to update acnpImport status", "acnpImport", klog.KObj(acnpImp)) - } + if err = r.remoteCommonArea.Create(ctx, statusEvent, &client.CreateOptions{}); err != nil { + klog.ErrorS(err, "failed to create acnp import event for resourceimport", "resImp", klog.KObj(resImp)) + return ctrl.Result{}, err } return ctrl.Result{}, nil } func (r *ResourceImportReconciler) handleResImpDeleteForClusterNetworkPolicy(ctx context.Context, resImp *multiclusterv1alpha1.ResourceImport) (ctrl.Result, error) { - acnpImpName := types.NamespacedName{ - Namespace: "", - Name: resImp.Spec.Name, - } acnpName := types.NamespacedName{ Namespace: "", Name: common.AntreaMCSPrefix + resImp.Spec.Name, } - klog.InfoS("Deleting ACNP and ACNPImport corresponding to ResourceImport", + klog.InfoS("Deleting ACNP corresponding to ResourceImport", "acnp", acnpName.String(), "resourceimport", klog.KObj(resImp)) - var err error - cleanupACNPImport := func() (ctrl.Result, error) { - acnpImp := &multiclusterv1alpha1.ACNPImport{} - err = r.localClusterClient.Get(ctx, acnpImpName, acnpImp) - if err != nil { - return ctrl.Result{}, client.IgnoreNotFound(err) - } - err = r.localClusterClient.Delete(ctx, acnpImp, &client.DeleteOptions{}) - if err != nil { - return ctrl.Result{}, client.IgnoreNotFound(err) - } - return ctrl.Result{}, nil - } - acnp := &v1alpha1.ClusterNetworkPolicy{} - err = r.localClusterClient.Get(ctx, acnpName, acnp) + err := r.localClusterClient.Get(ctx, acnpName, acnp) if err != nil { if apierrors.IsNotFound(err) { klog.V(2).InfoS("ACNP corresponding to ResourceImport has already been deleted", "acnp", acnpName.String(), "resourceimport", klog.KObj(resImp)) - return cleanupACNPImport() + return ctrl.Result{}, nil } return ctrl.Result{}, err } - err = r.localClusterClient.Delete(ctx, acnp, &client.DeleteOptions{}) - if err != nil { + if err = r.localClusterClient.Delete(ctx, acnp, &client.DeleteOptions{}); err != nil { return ctrl.Result{}, err } - return cleanupACNPImport() + return ctrl.Result{}, nil } func getMCAntreaClusterPolicy(resImp *multiclusterv1alpha1.ResourceImport) *v1alpha1.ClusterNetworkPolicy { @@ -182,37 +170,16 @@ func getMCAntreaClusterPolicy(resImp *multiclusterv1alpha1.ResourceImport) *v1al } } -func getACNPImport(resImp *multiclusterv1alpha1.ResourceImport, tierNotFound bool) (*multiclusterv1alpha1.ACNPImport, corev1.ConditionStatus) { - if resImp.Spec.ClusterNetworkPolicy == nil { - return nil, corev1.ConditionFalse - } - status, isRealizable := getACNPImportStatus(tierNotFound) - return &multiclusterv1alpha1.ACNPImport{ - ObjectMeta: metav1.ObjectMeta{ - Name: resImp.Spec.Name, - }, - Status: multiclusterv1alpha1.ACNPImportStatus{ - Conditions: []multiclusterv1alpha1.ACNPImportCondition{status}, - }, - }, isRealizable +func randSeq(n int) string { + b := make([]rune, n) + for i := range b { + // #nosec G404: random number generator not used for security purposes + randIdx := rand.Intn(len(lettersAndDigits)) + b[i] = lettersAndDigits[randIdx] + } + return string(b) } -func getACNPImportStatus(tierNotFound bool) (multiclusterv1alpha1.ACNPImportCondition, corev1.ConditionStatus) { - tierNotFoundReason := "TierNotFound" - tierNotFoundMessage := "ACNP Tier does not exist in the importing cluster" - time := metav1.Now() - if tierNotFound { - return multiclusterv1alpha1.ACNPImportCondition{ - Type: multiclusterv1alpha1.ACNPImportRealizable, - Status: corev1.ConditionFalse, - LastTransitionTime: &time, - Reason: &tierNotFoundReason, - Message: &tierNotFoundMessage, - }, corev1.ConditionFalse - } - return multiclusterv1alpha1.ACNPImportCondition{ - Type: multiclusterv1alpha1.ACNPImportRealizable, - Status: corev1.ConditionTrue, - LastTransitionTime: &time, - }, corev1.ConditionTrue -} +func randName(prefix string) string { + return prefix + randSeq(nameSuffixLength) +} \ No newline at end of file diff --git a/multicluster/controllers/multicluster/commonarea/acnpimport_controller_test.go b/multicluster/controllers/multicluster/commonarea/acnpimport_controller_test.go index 8a9b7ed5eef..73021dd1384 100644 --- a/multicluster/controllers/multicluster/commonarea/acnpimport_controller_test.go +++ b/multicluster/controllers/multicluster/commonarea/acnpimport_controller_test.go @@ -148,20 +148,7 @@ func TestResourceImportReconciler_handleCopySpanACNPCreateEvent(t *testing.T) { } else if !tt.expectedSuccess && (err == nil || !apierrors.IsNotFound(err)) { t.Errorf("ResourceImport Reconciler should not import an ACNP whose Tier does not exist in current cluster. Expected NotFound error. Actual err = %v", err) } - acnpImport := &mcsv1alpha1.ACNPImport{} - if err := fakeClient.Get(ctx, types.NamespacedName{Namespace: "", Name: tt.acnpImportName}, acnpImport); err != nil { - t.Errorf("ResourceImport Reconciler should create ACNPImport for ACNP type resouc") - } - status := acnpImport.Status.Conditions - if len(status) > 0 && status[0].Type == mcsv1alpha1.ACNPImportRealizable { - if tt.expectedSuccess && status[0].Status != corev1.ConditionTrue { - t.Errorf("ACNPImport %v realizable status should be True but is %v instead", acnpImportName, status[0].Status) - } else if !tt.expectedSuccess && status[0].Status != corev1.ConditionFalse { - t.Errorf("ACNPImport %v realizable status should be False but is %v instead", acnpImportName, status[0].Status) - } - } else { - t.Errorf("No realizable status provided for ACNPImport %v", acnpImportName) - } + //TODO(yang): add Event creation tests } }) } @@ -197,10 +184,6 @@ func TestResourceImportReconciler_handleCopySpanACNPDeleteEvent(t *testing.T) { if err := fakeClient.Get(ctx, types.NamespacedName{Namespace: "", Name: common.AntreaMCSPrefix + acnpImportName}, acnp); !apierrors.IsNotFound(err) { t.Errorf("ResourceImport Reconciler should delete ACNP successfully but got error = %v", err) } - acnpImport := &mcsv1alpha1.ACNPImport{} - if err := fakeClient.Get(ctx, types.NamespacedName{Namespace: "", Name: acnpImportName}, acnpImport); !apierrors.IsNotFound(err) { - t.Errorf("ResourceImport Reconciler should delete ACNPImport successfully but got error = %v", err) - } } func TestResourceImportReconciler_handleCopySpanACNPUpdateEvent(t *testing.T) { diff --git a/multicluster/controllers/multicluster/commonarea/resourceimport_controller.go b/multicluster/controllers/multicluster/commonarea/resourceimport_controller.go index 5bd849be1da..f0a2ad8e2e7 100644 --- a/multicluster/controllers/multicluster/commonarea/resourceimport_controller.go +++ b/multicluster/controllers/multicluster/commonarea/resourceimport_controller.go @@ -88,6 +88,7 @@ func NewResourceImportReconciler(client client.Client, scheme *runtime.Scheme, l //+kubebuilder:rbac:groups=multicluster.x-k8s.io,resources=serviceimports/status,verbs=get;update;patch //+kubebuilder:rbac:groups="",resources=endpoints,verbs=get;list;watch;update;create;patch;delete //+kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;update;create;patch;delete +//+kubebuilder:rbac:groups="",resources=events,verbs=get;list;update;create;patch // Reconcile will attempt to ensure that the imported Resource is installed in local cluster as per the // ResourceImport object.