-
Notifications
You must be signed in to change notification settings - Fork 193
Extend AntreaConfig to Support Antrea-NSX Registration Workflow #3816
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,13 +7,17 @@ package controllers | |
import ( | ||
"context" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/go-logr/logr" | ||
yaml "gopkg.in/yaml.v3" | ||
corev1 "k8s.io/api/core/v1" | ||
rbacv1 "k8s.io/api/rbac/v1" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/types" | ||
vsphere "sigs.k8s.io/cluster-api-provider-vsphere/apis/vmware/v1beta1" | ||
clusterapiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" | ||
clusterapiutil "sigs.k8s.io/cluster-api/util" | ||
clusterapipatchutil "sigs.k8s.io/cluster-api/util/patch" | ||
|
@@ -24,6 +28,8 @@ import ( | |
"sigs.k8s.io/controller-runtime/pkg/handler" | ||
"sigs.k8s.io/controller-runtime/pkg/source" | ||
|
||
nsxoperatorapi "github.com/vmware-tanzu/nsx-operator/pkg/apis/v1alpha1" | ||
|
||
cutil "github.com/vmware-tanzu/tanzu-framework/addons/controllers/utils" | ||
addonconfig "github.com/vmware-tanzu/tanzu-framework/addons/pkg/config" | ||
"github.com/vmware-tanzu/tanzu-framework/addons/pkg/constants" | ||
|
@@ -32,6 +38,24 @@ import ( | |
cniv1alpha1 "github.com/vmware-tanzu/tanzu-framework/apis/addonconfigs/cni/v1alpha1" | ||
) | ||
|
||
const ( | ||
antreaTargetNameSpace = "vmware-system-antrea" | ||
antreaSecretName = "supervisor-cred" | ||
nsxServiceAccountAPIGroup = "nsx.vmware.com" | ||
nsxServiceAccountKind = "nsxserviceaccounts" | ||
clusterNameLabel = "tkg.tanzu.vmware.com/cluster-name" | ||
) | ||
|
||
// vsphereAntreaConfigProviderServiceAccountAggregatedClusterRole is the cluster role to assign permissions to capv provider | ||
var vsphereAntreaConfigProviderServiceAccountAggregatedClusterRole = &rbacv1.ClusterRole{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: constants.VsphereAntreaConfigProviderServiceAccountAggregatedClusterRole, | ||
Labels: map[string]string{ | ||
constants.CAPVClusterRoleAggregationRuleLabelSelectorKey: constants.CAPVClusterRoleAggregationRuleLabelSelectorValue, | ||
}, | ||
}, | ||
} | ||
|
||
// AntreaConfigReconciler reconciles a AntreaConfig object | ||
type AntreaConfigReconciler struct { | ||
client.Client | ||
|
@@ -42,6 +66,8 @@ type AntreaConfigReconciler struct { | |
|
||
// +kubebuilder:rbac:groups=addons.tanzu.vmware.com,resources=antreaconfigs,verbs=get;list;watch;create;update;patch;delete | ||
// +kubebuilder:rbac:groups=addons.tanzu.vmware.com,resources=antreaconfigs/status,verbs=get;update;patch | ||
// +kubebuilder:rbac:groups=vmware.infrastructure.cluster.x-k8s.io,resources=providerserviceaccounts,verbs=get;create;list;watch;update;patch;delete | ||
// +kubebuilder:rbac:groups=nsx.vmware.com,resources=nsxserviceaccounts,verbs=get;create;list;watch;update;patch;delete | ||
|
||
// Reconcile is part of the main kubernetes reconciliation loop which aims to | ||
// move the current state of the cluster closer to the desired state. | ||
|
@@ -130,6 +156,7 @@ func (r *AntreaConfigReconciler) ReconcileAntreaConfig( | |
|
||
// If AntreaConfig is marked for deletion, then no reconciliation is needed | ||
if !antreaConfig.GetDeletionTimestamp().IsZero() { | ||
r.deregisterAntreaNSX(ctx, antreaConfig, cluster) | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
|
@@ -167,10 +194,191 @@ func (r *AntreaConfigReconciler) ReconcileAntreaConfigNormal( | |
return err | ||
} | ||
|
||
if antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef != nil && antreaConfig.Spec.AntreaNsx.BootstrapFrom.Inline != nil { | ||
err := fmt.Errorf("providerRef and inline should not be both set in AntreaConfig.spec.antreaNsx.bootstrapFrom") | ||
antreaConfig.Status.Message = err.Error() | ||
} else { | ||
// clear the message here. | ||
antreaConfig.Status.Message = "" | ||
} | ||
// update status.secretRef | ||
dataValueSecretName := util.GenerateDataValueSecretName(cluster.Name, constants.AntreaAddonName) | ||
antreaConfig.Status.SecretRef = dataValueSecretName | ||
|
||
return r.registerAntreaNSX(ctx, antreaConfig, cluster) | ||
} | ||
|
||
func getClusterName(antreaConfig *cniv1alpha1.AntreaConfig) (name string, exists bool) { | ||
name, exists = antreaConfig.Labels[clusterNameLabel] | ||
if !exists { | ||
index := strings.Index(antreaConfig.Name, "-antrea-package") | ||
if index > 0 { | ||
name = antreaConfig.Name[:index] | ||
exists = true | ||
} | ||
} | ||
return | ||
} | ||
|
||
func (r *AntreaConfigReconciler) getProviderServiceAccountName(clusterName string) string { | ||
return fmt.Sprintf("%s-antrea", clusterName) | ||
} | ||
|
||
func (r *AntreaConfigReconciler) getNSXServiceAccountName(clusterName string) string { | ||
return fmt.Sprintf("%s-antrea", clusterName) | ||
} | ||
|
||
func (r *AntreaConfigReconciler) ensureNsxServiceAccount(ctx context.Context, antreaConfig *cniv1alpha1.AntreaConfig, cluster *clusterapiv1beta1.Cluster) error { | ||
account := &nsxoperatorapi.NSXServiceAccount{} | ||
|
||
account.Name = r.getNSXServiceAccountName(cluster.Name) | ||
account.Namespace = antreaConfig.Namespace | ||
account.OwnerReferences = []metav1.OwnerReference{ | ||
{ | ||
APIVersion: cluster.APIVersion, | ||
Kind: cluster.Kind, | ||
Name: cluster.Name, | ||
UID: cluster.UID, | ||
}, | ||
} | ||
|
||
err := r.Client.Get(ctx, types.NamespacedName{ | ||
Namespace: account.Namespace, | ||
Name: account.Name, | ||
}, account) | ||
if err == nil { | ||
r.Log.Info("NSXServiceAccount %s/%s already exists", account.Namespace, account.Name) | ||
return nil | ||
} | ||
if err != nil && !apierrors.IsNotFound(err) { | ||
r.Log.Info("Found no existing NSXServiceAccount %s/%s", account.Namespace, account.Name) | ||
return err | ||
} | ||
|
||
result, err := controllerutil.CreateOrPatch(ctx, r.Client, account, nil) | ||
if err != nil { | ||
r.Log.Error(err, "Error creating or patching NSXServiceAccount", account.Namespace, account.Name) | ||
} else { | ||
r.Log.Info(fmt.Sprintf("NSXServiceAccount %s/%s created %s", account.Namespace, account.Name, result)) | ||
} | ||
return err | ||
} | ||
|
||
func (r *AntreaConfigReconciler) ensureProviderServiceAccount(ctx context.Context, antreaConfig *cniv1alpha1.AntreaConfig, cluster *clusterapiv1beta1.Cluster) error { | ||
provider := &vsphere.ProviderServiceAccount{} | ||
vsphereCluster, err := cutil.VSphereClusterParavirtualForCAPICluster(ctx, r.Client, cluster) | ||
if err != nil { | ||
return err | ||
} | ||
clusterName, _ := getClusterName(antreaConfig) | ||
nsxSAName := clusterName + "-antrea" | ||
nsxSecretName := clusterName + "-antrea-nsx-cert" | ||
clusterName = vsphereCluster.Name | ||
providerServiceAccountRBACRules := []rbacv1.PolicyRule{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to our offline discussion, we add -antrea to the resource names.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
{ | ||
APIGroups: []string{nsxServiceAccountAPIGroup}, | ||
Resources: []string{nsxServiceAccountKind}, | ||
ResourceNames: []string{nsxSAName}, | ||
Verbs: []string{"get", "list", "watch"}, | ||
}, | ||
{ | ||
APIGroups: []string{""}, | ||
Resources: []string{"secrets"}, | ||
ResourceNames: []string{fmt.Sprintf(nsxSecretName)}, | ||
Verbs: []string{"get", "list", "watch"}, | ||
}, | ||
} | ||
_, err = controllerutil.CreateOrPatch(ctx, r.Client, vsphereAntreaConfigProviderServiceAccountAggregatedClusterRole, func() error { | ||
vsphereAntreaConfigProviderServiceAccountAggregatedClusterRole.Rules = providerServiceAccountRBACRules | ||
return nil | ||
}) | ||
if err != nil { | ||
r.Log.Error(err, "Error creating or patching cluster role", "name", vsphereAntreaConfigProviderServiceAccountAggregatedClusterRole) | ||
return err | ||
} | ||
provider.Name = r.getProviderServiceAccountName(clusterName) | ||
provider.Namespace = antreaConfig.Namespace | ||
provider.Spec = vsphere.ProviderServiceAccountSpec{ | ||
Ref: &corev1.ObjectReference{ | ||
APIVersion: cluster.APIVersion, | ||
Kind: cluster.Kind, | ||
Name: clusterName, | ||
UID: cluster.UID, | ||
}, | ||
TargetNamespace: antreaTargetNameSpace, | ||
TargetSecretName: antreaSecretName, | ||
Rules: providerServiceAccountRBACRules, | ||
} | ||
result, err := controllerutil.CreateOrPatch(ctx, r.Client, provider, func() error { | ||
return controllerutil.SetControllerReference(vsphereCluster, provider, r.Scheme) | ||
}) | ||
if err != nil { | ||
r.Log.Error(err, "Error creating or patching ProviderServiceAccount", provider.Namespace, provider.Name) | ||
} else { | ||
r.Log.Info(fmt.Sprintf("ProviderServiceAccount %s/%s created %s: %+v", provider.Namespace, provider.Name, result, provider)) | ||
} | ||
return err | ||
} | ||
|
||
func (r *AntreaConfigReconciler) registerAntreaNSX(ctx context.Context, antreaConfig *cniv1alpha1.AntreaConfig, cluster *clusterapiv1beta1.Cluster) error { | ||
if !antreaConfig.Spec.AntreaNsx.Enable || antreaConfig.Spec.AntreaNsx.BootstrapFrom.Inline != nil { | ||
r.Log.Info("antreaNsx is not enabled or inline is set, there is no ProviderServiceAccount or NsxServiceAccount to be created") | ||
r.deregisterAntreaNSX(ctx, antreaConfig, cluster) | ||
return nil | ||
} | ||
if antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef != nil { | ||
if strings.ToLower(antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef.Kind) != nsxServiceAccountKind || | ||
strings.ToLower(antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef.ApiGroup) != nsxServiceAccountAPIGroup { | ||
err := fmt.Errorf("either ProviderRef.Kind(%s) or ProviderRef.ApiGroup(%s) is invalid, expcted:ProviderRef.Kind(%s) ProviderRef.ApiGroup(%s)", | ||
antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef.Kind, antreaConfig.Spec.AntreaNsx.BootstrapFrom.ProviderRef.ApiGroup, | ||
nsxServiceAccountKind, nsxServiceAccountAPIGroup) | ||
antreaConfig.Status.Message = err.Error() | ||
return err | ||
} | ||
} | ||
antreaConfig.Status.Message = "" | ||
err := r.ensureProviderServiceAccount(ctx, antreaConfig, cluster) | ||
if err != nil { | ||
return err | ||
} | ||
err = r.ensureNsxServiceAccount(ctx, antreaConfig, cluster) | ||
return err | ||
} | ||
|
||
func (r *AntreaConfigReconciler) deregisterAntreaNSX(ctx context.Context, antreaConfig *cniv1alpha1.AntreaConfig, cluster *clusterapiv1beta1.Cluster) error { | ||
if !antreaConfig.Spec.AntreaNsx.Enable { | ||
r.Log.Info("antreaNsx is not enabled, there is no ProviderServiceAccount or NsxServiceAccount to be deleted") | ||
return nil | ||
} | ||
vsphereCluster, err := cutil.VSphereClusterParavirtualForCAPICluster(ctx, r.Client, cluster) | ||
if err != nil { | ||
if apierrors.IsNotFound(err) { | ||
return nil | ||
} | ||
return err | ||
} | ||
clusterName, exists := getClusterName(antreaConfig) | ||
if !exists { | ||
return fmt.Errorf("invalid antreaConfig Name") | ||
} | ||
account := &nsxoperatorapi.NSXServiceAccount{} | ||
|
||
account.Name = r.getNSXServiceAccountName(clusterName) | ||
account.Namespace = antreaConfig.Namespace | ||
err = r.Client.Delete(ctx, account) | ||
if err != nil && !apierrors.IsNotFound(err) { | ||
r.Log.Error(err, "failed to delete NSXServiceAccount", account.Namespace, account.Name) | ||
return err | ||
} | ||
|
||
provider := &vsphere.ProviderServiceAccount{} | ||
provider.Name = r.getProviderServiceAccountName(vsphereCluster.Name) | ||
provider.Namespace = vsphereCluster.Namespace | ||
err = r.Client.Delete(ctx, provider) | ||
if err != nil && !apierrors.IsNotFound(err) { | ||
r.Log.Error(err, "failed to delete ProviderServiceAccount", provider.Namespace, provider.Name) | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
|
@@ -200,7 +408,7 @@ func (r *AntreaConfigReconciler) ReconcileAntreaConfigDataValue( | |
antreaDataValuesSecret.StringData = make(map[string]string) | ||
|
||
// marshall the yaml contents | ||
antreaConfigYaml, err := mapAntreaConfigSpec(cluster, antreaConfig) | ||
antreaConfigYaml, err := mapAntreaConfigSpec(cluster, antreaConfig, r.Client) | ||
if err != nil { | ||
return err | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,15 +20,55 @@ import ( | |
) | ||
|
||
// AntreaConfigSpec defines the desired state of AntreaConfig | ||
type antreaConfigSpec struct { | ||
InfraProvider string `yaml:"infraProvider"` | ||
Antrea antrea `yaml:"antrea,omitempty"` | ||
type AntreaConfigSpec struct { | ||
InfraProvider string `yaml:"infraProvider"` | ||
Antrea antrea `yaml:"antrea,omitempty"` | ||
AntreaNsx antreaNsx `yaml:"antreaNsx,omitempty"` | ||
} | ||
|
||
type antrea struct { | ||
AntreaConfigDataValue antreaConfigDataValue `yaml:"config,omitempty"` | ||
} | ||
|
||
type antreaNsx struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should antrea_configs_exist in clusterbootstrap.yaml be updated to include these ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it should be in another pull request #4098 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry that I misunderstood your comments. because this is not default setting for clusterbootstrap, when user wants to use this feature, they can edit antreaConfig manually. @jeffwubj |
||
Enable bool `yaml:"enable,omitempty"` | ||
BootstrapFrom antreaNsxBootstrapFrom `yaml:"bootstrapFrom,omitempty"` | ||
AntreaNsxConfig antreaNsxConfig `yaml:"config,omitempty"` | ||
} | ||
|
||
type antreaNsxBootstrapFrom struct { | ||
// ProviderRef is used with uTKG, which will be filled by NCP operator | ||
ProviderRef *antreaNsxProvider `yaml:"providerRef,omitempty"` | ||
// Inline is used with TKGm, user need to fill in manually | ||
Inline *antreaNsxInline `yaml:"inline,omitempty"` | ||
} | ||
|
||
type antreaNsxProvider struct { | ||
// Api version for nsxServiceAccount, its value is "nsx.vmware.com/v1alpha1" now | ||
ApiVersion string `yaml:"apiVersion,omitempty"` | ||
// Its value is NsxServiceAccount | ||
Kind string `yaml:"kind,omitempty"` | ||
// Name is the name for NsxServiceAccount | ||
Name string `yaml:"name,omitempty"` | ||
} | ||
|
||
type nsxCertRef struct { | ||
// TLSCert is cert file to access nsx manager | ||
TLSCert string `yaml:"tls.crt,omitempty"` | ||
// TLSKey is key file to access nsx manager | ||
TLSKey string `yaml:"tls.key,omitempty"` | ||
} | ||
|
||
type antreaNsxInline struct { | ||
NsxManagers []string `yaml:"nsxManagers,omitempty"` | ||
ClusterName string `yaml:"clusterName,omitempty"` | ||
NsxCertRef nsxCertRef `yaml:"NsxCert,omitempty"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to put the cert and key in a Secret, so it's flexible to set different RBAC rules for AntreaConfig and Secret. For example, we can have a role which can view and create AntreaConfig, but the role cannot read the Secret. So here the NsxCertRef can be just a string, the value is the name of the Secret. We can rename this field to NSXSecretName. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
} | ||
|
||
type antreaNsxConfig struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find that this type doesn't agree with AntreaNsxConfig in antreaconfig_types.go.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
InfraType string `yaml:"infraType,omitempty"` | ||
} | ||
|
||
type antreaEgress struct { | ||
EgressExceptCIDRs []string `yaml:"exceptCIDRs,omitempty"` | ||
} | ||
|
@@ -73,9 +113,9 @@ type antreaConfigDataValue struct { | |
Multicast antreaMulticast `yaml:"multicast,omitempty"` | ||
MultiCluster antreaMultiCluster `yaml:"multicluster,omitempty"` | ||
KubeAPIServerOverride string `yaml:"kubeAPIServerOverride,omitempty"` | ||
transportInterface string `yaml:"transportInterface,omitempty"` | ||
transportInterfaceCIDRs []string `yaml:"transportInterfaceCIDRs,omitempty"` | ||
multicastInterfaces []string `yaml:"multicastInterfaces,omitempty"` | ||
TransportInterface string `yaml:"transportInterface,omitempty"` | ||
TransportInterfaceCIDRs []string `yaml:"transportInterfaceCIDRs,omitempty"` | ||
MulticastInterfaces []string `yaml:"multicastInterfaces,omitempty"` | ||
TunnelType string `yaml:"tunnelType,omitempty"` | ||
TrafficEncryptionMode string `yaml:"trafficEncryptionMode,omitempty"` | ||
EnableUsageReporting bool `yaml:"enableUsageReporting,omitempty"` | ||
|
@@ -161,8 +201,8 @@ func (r *AntreaConfigReconciler) ClusterToAntreaConfig(o client.Object) []ctrl.R | |
return requests | ||
} | ||
|
||
func mapAntreaConfigSpec(cluster *clusterv1beta1.Cluster, config *cniv1alpha1.AntreaConfig) (*antreaConfigSpec, error) { | ||
configSpec := &antreaConfigSpec{} | ||
func mapAntreaConfigSpec(cluster *clusterv1beta1.Cluster, config *cniv1alpha1.AntreaConfig, client client.Client) (*AntreaConfigSpec, error) { | ||
configSpec := &AntreaConfigSpec{} | ||
|
||
// Derive InfraProvider from the cluster | ||
infraProvider, err := util.GetInfraProvider(cluster) | ||
|
@@ -197,9 +237,9 @@ func mapAntreaConfigSpec(cluster *clusterv1beta1.Cluster, config *cniv1alpha1.An | |
configSpec.Antrea.AntreaConfigDataValue.MultiCluster.Enable = config.Spec.Antrea.AntreaConfigDataValue.MultiCluster.Enable | ||
configSpec.Antrea.AntreaConfigDataValue.MultiCluster.Namespace = config.Spec.Antrea.AntreaConfigDataValue.MultiCluster.Namespace | ||
configSpec.Antrea.AntreaConfigDataValue.KubeAPIServerOverride = config.Spec.Antrea.AntreaConfigDataValue.KubeAPIServerOverride | ||
configSpec.Antrea.AntreaConfigDataValue.transportInterface = config.Spec.Antrea.AntreaConfigDataValue.TransportInterface | ||
configSpec.Antrea.AntreaConfigDataValue.transportInterfaceCIDRs = config.Spec.Antrea.AntreaConfigDataValue.TransportInterfaceCIDRs | ||
configSpec.Antrea.AntreaConfigDataValue.multicastInterfaces = config.Spec.Antrea.AntreaConfigDataValue.MulticastInterfaces | ||
configSpec.Antrea.AntreaConfigDataValue.TransportInterface = config.Spec.Antrea.AntreaConfigDataValue.TransportInterface | ||
configSpec.Antrea.AntreaConfigDataValue.TransportInterfaceCIDRs = config.Spec.Antrea.AntreaConfigDataValue.TransportInterfaceCIDRs | ||
configSpec.Antrea.AntreaConfigDataValue.MulticastInterfaces = config.Spec.Antrea.AntreaConfigDataValue.MulticastInterfaces | ||
configSpec.Antrea.AntreaConfigDataValue.TunnelType = config.Spec.Antrea.AntreaConfigDataValue.TunnelType | ||
configSpec.Antrea.AntreaConfigDataValue.EnableUsageReporting = config.Spec.Antrea.AntreaConfigDataValue.EnableUsageReporting | ||
configSpec.Antrea.AntreaConfigDataValue.WireGuard.Port = config.Spec.Antrea.AntreaConfigDataValue.WireGuard.Port | ||
|
@@ -227,5 +267,8 @@ func mapAntreaConfigSpec(cluster *clusterv1beta1.Cluster, config *cniv1alpha1.An | |
configSpec.Antrea.AntreaConfigDataValue.FeatureGates.MultiCluster = config.Spec.Antrea.AntreaConfigDataValue.FeatureGates.MultiCluster | ||
configSpec.Antrea.AntreaConfigDataValue.FeatureGates.SecondaryNetwork = config.Spec.Antrea.AntreaConfigDataValue.FeatureGates.SecondaryNetwork | ||
configSpec.Antrea.AntreaConfigDataValue.FeatureGates.TrafficControl = config.Spec.Antrea.AntreaConfigDataValue.FeatureGates.TrafficControl | ||
|
||
//todo add nsx config here once antreaNsx ia packaged into antrea | ||
|
||
return configSpec, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of ReconcileAntreaConfigDataValue should also be modified to pass Antrea-NSX configs to values.yaml like below:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Antrea Package needs to be updated to support the new fields in values.yaml, too. I'm now sure if existing Antrea Package can ignore these new fields. We can have a try on manually editing the values.yaml in workload cluster and see if Antrea PackageInstall reconciles successfully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done