From 80c84b4124e4a353a3137bb1b40302b8f6604db5 Mon Sep 17 00:00:00 2001 From: jsui Date: Sat, 27 Mar 2021 15:44:08 +0800 Subject: [PATCH] Separate platform specific functions for different adaptors Separate the reconcile functions in antreainstall_controller for different adaptors(k8s/openshift4). Also, separate the config functions and manifest files under directory deploy for different adaptors and refactor the related testing code in config_test. This commit rebases the latest main branch and fixes some conflicts. --- controllers/antreainstall_controller.go | 422 ++++++++++++------ controllers/config/config.go | 113 +++-- controllers/config/config_test.go | 149 +++++-- controllers/sharedinfo/sharedinfo.go | 8 +- deploy/{ => kubernetes}/namespace.yaml | 0 ....antrea.vmware.com_antreainstalls_crd.yaml | 0 ...antrea.vmware.com_v1_antreainstall_cr.yaml | 200 +++++++++ deploy/{ => kubernetes}/operator.yaml | 0 deploy/{ => kubernetes}/role.yaml | 0 deploy/{ => kubernetes}/role_binding.yaml | 0 deploy/{ => kubernetes}/service_account.yaml | 0 deploy/openshift/namespace.yaml | 5 + ....antrea.vmware.com_antreainstalls_crd.yaml | 95 ++++ ...antrea.vmware.com_v1_antreainstall_cr.yaml | 0 deploy/openshift/operator.yaml | 40 ++ deploy/openshift/role.yaml | 117 +++++ deploy/openshift/role_binding.yaml | 12 + deploy/openshift/service_account.yaml | 5 + go.mod | 1 + go.sum | 8 + main.go | 14 +- 21 files changed, 960 insertions(+), 229 deletions(-) rename deploy/{ => kubernetes}/namespace.yaml (100%) rename deploy/{ => kubernetes}/operator.antrea.vmware.com_antreainstalls_crd.yaml (100%) create mode 100644 deploy/kubernetes/operator.antrea.vmware.com_v1_antreainstall_cr.yaml rename deploy/{ => kubernetes}/operator.yaml (100%) rename deploy/{ => kubernetes}/role.yaml (100%) rename deploy/{ => kubernetes}/role_binding.yaml (100%) rename deploy/{ => kubernetes}/service_account.yaml (100%) create mode 100644 deploy/openshift/namespace.yaml create mode 100644 deploy/openshift/operator.antrea.vmware.com_antreainstalls_crd.yaml rename deploy/{ => openshift}/operator.antrea.vmware.com_v1_antreainstall_cr.yaml (100%) create mode 100644 deploy/openshift/operator.yaml create mode 100644 deploy/openshift/role.yaml create mode 100644 deploy/openshift/role_binding.yaml create mode 100644 deploy/openshift/service_account.yaml diff --git a/controllers/antreainstall_controller.go b/controllers/antreainstall_controller.go index 8b06efb1..686e31dd 100644 --- a/controllers/antreainstall_controller.go +++ b/controllers/antreainstall_controller.go @@ -5,6 +5,7 @@ package controllers import ( "context" + "errors" "fmt" "reflect" @@ -39,130 +40,50 @@ import ( var log = ctrl.Log.WithName("controllers") -// AntreaInstallReconciler reconciles a AntreaInstall object -type AntreaInstallReconciler struct { - Client client.Client - Log logr.Logger - Scheme *runtime.Scheme - Status *statusmanager.StatusManager - Mapper meta.RESTMapper +type Adaptor interface { + SetupWithManager(r *AntreaInstallReconciler, mgr ctrl.Manager) error + Reconcile(r *AntreaInstallReconciler, request ctrl.Request) (reconcile.Result, error) + UpdateStatusManagerAndSharedInfo(r *AntreaInstallReconciler, objs []*uns.Unstructured, clusterConfig *configv1.Network) error +} - SharedInfo *sharedinfo.SharedInfo - AppliedClusterConfig *configv1.Network - AppliedOperConfig *operatorv1.AntreaInstall +type AdaptorK8s struct { + Config configutil.Config } -func (r *AntreaInstallReconciler) SetupWithManager(mgr ctrl.Manager) error { +type AdaptorOc struct { + Config configutil.Config +} + +func (k8s *AdaptorK8s) SetupWithManager(r *AntreaInstallReconciler, mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&operatorv1.AntreaInstall{}). - Watches(&source.Kind{Type: &configv1.Network{}}, &handler.EnqueueRequestForObject{}). Complete(r) } -// +kubebuilder:rbac:groups=operator.antrea.vmware.com,resources=antreainstalls,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=operator.antrea.vmware.com,resources=antreainstalls/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=config.openshift.io,resources=clusteroperators,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=config.openshift.io,resources=clusteroperators/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=config.openshift.io,resources=networks;networks/finalizers,verbs=get;list;watch;patch;update -// +kubebuilder:rbac:groups=operator.openshift.io,resources=networks,verbs=get;list;watch;patch;update -// +kubebuilder:rbac:groups="",resources=nodes,verbs=get;watch;list -// +kubebuilder:rbac:groups="",resources=namespaces;pods;configmaps;services;serviceaccounts,verbs=create;delete;get;list;patch;update;watch;deletecollection -// +kubebuilder:rbac:groups=apps,resources=deployments;daemonsets,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings;roles;rolebindings,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups=apiregistration.k8s.io,resources=apiservices,verbs=get;create;update;delete -// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create -// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create -// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=get;watch;list -// +kubebuilder:rbac:groups=ops.antrea.tanzu.vmware.com,resources=traceflows;traceflows/status,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=clusterinformation.antrea.tanzu.vmware.com,resources=antreaagentinfos;antreacontrollerinfos,verbs=get;list;create;update;delete -// +kubebuilder:rbac:groups=networking.antrea.tanzu.vmware.com,resources=networkpolicies;appliedtogroups;addressgroups,verbs=get;watch;list;delete -// +kubebuilder:rbac:groups=security.antrea.tanzu.vmware.com,resources=clusternetworkpolicies,verbs=get;watch;list;delete -// +kubebuilder:rbac:groups=system.antrea.tanzu.vmware.com,resources=controllerinfos;agentinfos;supportbundles;supportbundles/download,verbs=get;watch;list;post;delete -// +kubebuilder:rbac:urls=/agentinfo;/addressgroups;/appliedtogroups;/networkpolicies;/ovsflows;/ovstracing;/podinterfaces,verbs=get -// +kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,resourceNames=hostnetwork,verbs=use - -func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) { - reqLogger := r.Log.WithValues("Request.NamespacedName", request.NamespacedName) - if request.Namespace == "" && request.Name == operatortypes.ClusterConfigName { - reqLogger.Info("Reconciling antrea-operator Cluster Network CR change") - } else if request.Namespace == operatortypes.OperatorNameSpace && request.Name == operatortypes.OperatorConfigName { - reqLogger.Info("Reconciling antrea-operator antrea-install CR change") - } else { - return reconcile.Result{}, nil - } - - // Fetch Cluster Network CR. - clusterConfig := &configv1.Network{} - err := r.Client.Get(context.TODO(), types.NamespacedName{Name: operatortypes.ClusterConfigName}, clusterConfig) - if err != nil { - if apierrors.IsNotFound(err) { - msg := "Cluster Network CR not found" - log.Info(msg) - r.Status.SetDegraded(statusmanager.ClusterConfig, "NoClusterConfig", msg) - return reconcile.Result{}, nil - } - r.Status.SetDegraded(statusmanager.ClusterConfig, "InvalidClusterConfig", fmt.Sprintf("Failed to get cluster network CRD: %v", err)) - log.Error(err, "failed to get Cluster Network CR") - return reconcile.Result{Requeue: true}, err - } - if request.Name == clusterConfig.Name && r.AppliedClusterConfig != nil { - if reflect.DeepEqual(clusterConfig.Spec, r.AppliedClusterConfig.Spec) { - log.Info("no configuration change") - return reconcile.Result{}, nil - } - } - - // Fetch the Network.operator.openshift.io instance - operatorNetwork := &ocoperv1.Network{} - err = r.Client.Get(context.TODO(), types.NamespacedName{Name: operatortypes.ClusterOperatorNetworkName}, operatorNetwork) - if err != nil { - if apierrors.IsNotFound(err) { - r.Status.SetDegraded(statusmanager.OperatorConfig, "NoClusterNetworkOperatorConfig", fmt.Sprintf("Cluster network operator configuration not found")) - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Unable to retrieve Network.operator.openshift.io object") - return reconcile.Result{Requeue: true}, err - } - - // Fetch antrea-install CR. - operConfig := &operatorv1.AntreaInstall{} - err = r.Client.Get(context.TODO(), types.NamespacedName{Namespace: operatortypes.OperatorNameSpace, Name: operatortypes.OperatorConfigName}, operConfig) - if err != nil { - if apierrors.IsNotFound(err) { - msg := fmt.Sprintf("%s CR not found", operatortypes.OperatorConfigName) - log.Info(msg) - r.Status.SetDegraded(statusmanager.ClusterConfig, "NoAntreaInstallCR", msg) - return reconcile.Result{}, nil - } - log.Error(err, "failed to get antrea-install CR") - r.Status.SetDegraded(statusmanager.OperatorConfig, "InvalidAntreaInstallCR", fmt.Sprintf("Failed to get operator CR: %v", err)) - return reconcile.Result{Requeue: true}, err - } - if request.Name == operConfig.Name && r.AppliedOperConfig != nil { - if reflect.DeepEqual(operConfig.Spec, r.AppliedOperConfig.Spec) { - log.Info("no configuration change") - return reconcile.Result{}, nil - } - } +func (oc *AdaptorOc) SetupWithManager(r *AntreaInstallReconciler, mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&operatorv1.AntreaInstall{}). + Watches(&source.Kind{Type: &configv1.Network{}}, &handler.EnqueueRequestForObject{}). + Complete(r) +} +func applyConfig(r *AntreaInstallReconciler, config configutil.Config, clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall, operatorNetwork *ocoperv1.Network) (reconcile.Result, error) { // Fill default configurations. - if err = configutil.FillConfigs(clusterConfig, operConfig); err != nil { + if err := config.FillConfigs(clusterConfig, operConfig); err != nil { log.Error(err, "failed to fill configurations") r.Status.SetDegraded(statusmanager.OperatorConfig, "FillConfigurationsError", fmt.Sprintf("Failed to fill configurations: %v", err)) return reconcile.Result{Requeue: true}, err } // Validate configurations. - if err = configutil.ValidateConfig(clusterConfig, operConfig); err != nil { + if err := config.ValidateConfig(clusterConfig, operConfig); err != nil { log.Error(err, "failed to validate configurations") r.Status.SetDegraded(statusmanager.OperatorConfig, "InvalidOperatorConfig", fmt.Sprintf("The operator configuration is invalid: %v", err)) return reconcile.Result{Requeue: true}, err } // Generate render data. - renderData, err := configutil.GenerateRenderData(operatorNetwork, operConfig) + renderData, err := config.GenerateRenderData(operatorNetwork, operConfig) if err != nil { log.Error(err, "failed to generate render data") r.Status.SetDegraded(statusmanager.OperatorConfig, "RenderConfigError", fmt.Sprintf("Failed to render operator configurations: %v", err)) @@ -170,6 +91,7 @@ func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (ctrl.Result, } // Compare configurations change. + // TODO why not r.AppliedOperConfig? appliedConfig, err := r.getAppliedOperConfig() if err != nil { log.Error(err, "failed to get applied config") @@ -191,7 +113,7 @@ func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (ctrl.Result, // Update status and sharedInfo. r.SharedInfo.Lock() defer r.SharedInfo.Unlock() - if err = r.updateStatusManagerAndSharedInfo(objs, clusterConfig); err != nil { + if err = r.UpdateStatusManagerAndSharedInfo(r, objs, clusterConfig); err != nil { return reconcile.Result{Requeue: true}, err } @@ -220,6 +142,130 @@ func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (ctrl.Result, } } } + return reconcile.Result{}, nil +} + +func fetchAntreaInstall(r *AntreaInstallReconciler, request ctrl.Request) (operConfig *operatorv1.AntreaInstall, err error, found bool, change bool) { + // Fetch antrea-install CR. + err = r.Client.Get(context.TODO(), types.NamespacedName{Namespace: operatortypes.OperatorNameSpace, Name: operatortypes.OperatorConfigName}, operConfig) + if err != nil { + if apierrors.IsNotFound(err) { + msg := fmt.Sprintf("%s CR not found", operatortypes.OperatorConfigName) + log.Info(msg) + r.Status.SetDegraded(statusmanager.ClusterConfig, "NoAntreaInstallCR", msg) + return nil, err, false, false + } + log.Error(err, "failed to get antrea-install CR") + r.Status.SetDegraded(statusmanager.OperatorConfig, "InvalidAntreaInstallCR", fmt.Sprintf("Failed to get operator CR: %v", err)) + return nil, err, true, false + } + if request.Name == operConfig.Name && r.AppliedOperConfig != nil { + if reflect.DeepEqual(operConfig.Spec, r.AppliedOperConfig.Spec) { + log.Info("no configuration change") + return operConfig, nil, true, false + } + } + return operConfig, nil, true, true +} + +func isOperatorRequest(r *AntreaInstallReconciler, request ctrl.Request) bool { + reqLogger := r.Log.WithValues("Request.NamespacedName", request.NamespacedName) + if request.Namespace == "" && request.Name == operatortypes.ClusterConfigName { + reqLogger.Info("Reconciling antrea-operator Cluster Network CR change") + return true + } + if request.Namespace == operatortypes.OperatorNameSpace && request.Name == operatortypes.OperatorConfigName { + reqLogger.Info("Reconciling antrea-operator antrea-install CR change") + return true + } + return false +} + +func (k8s *AdaptorK8s) Reconcile(r *AntreaInstallReconciler, request ctrl.Request) (reconcile.Result, error) { + if !isOperatorRequest(r, request) { + return reconcile.Result{}, nil + } + + // Fetch antrea-install CR. + operConfig, err, found, change := fetchAntreaInstall(r, request) + if err != nil && !found { + return reconcile.Result{}, nil + } + if err != nil { + return reconcile.Result{Requeue: true}, err + } + if !change { + return reconcile.Result{}, nil + } + + // Apply configuration. + if result, err := applyConfig(r, k8s.Config, nil, operConfig, nil); err != nil { + return result, err + } + + r.Status.SetNotDegraded(statusmanager.ClusterConfig) + r.Status.SetNotDegraded(statusmanager.OperatorConfig) + + r.AppliedOperConfig = operConfig + + return reconcile.Result{}, nil +} + +func (oc *AdaptorOc) Reconcile(r *AntreaInstallReconciler, request ctrl.Request) (reconcile.Result, error) { + if !isOperatorRequest(r, request) { + return reconcile.Result{}, nil + } + + // Fetch Cluster Network CR. + clusterConfig := &configv1.Network{} + err := r.Client.Get(context.TODO(), types.NamespacedName{Name: operatortypes.ClusterConfigName}, clusterConfig) + if err != nil { + if apierrors.IsNotFound(err) { + msg := "Cluster Network CR not found" + log.Info(msg) + r.Status.SetDegraded(statusmanager.ClusterConfig, "NoClusterConfig", msg) + return reconcile.Result{}, nil + } + r.Status.SetDegraded(statusmanager.ClusterConfig, "InvalidClusterConfig", fmt.Sprintf("Failed to get cluster network CRD: %v", err)) + log.Error(err, "failed to get Cluster Network CR") + return reconcile.Result{Requeue: true}, err + } + if request.Name == clusterConfig.Name && r.AppliedClusterConfig != nil { + if reflect.DeepEqual(clusterConfig.Spec, r.AppliedClusterConfig.Spec) { + log.Info("no configuration change") + return reconcile.Result{}, nil + } + } + + // Fetch the Network.operator.openshift.io instance + operatorNetwork := &ocoperv1.Network{} + err = r.Client.Get(context.TODO(), types.NamespacedName{Name: operatortypes.ClusterOperatorNetworkName}, operatorNetwork) + if err != nil { + if apierrors.IsNotFound(err) { + r.Status.SetDegraded(statusmanager.OperatorConfig, "NoClusterNetworkOperatorConfig", fmt.Sprintf("Cluster network operator configuration not found")) + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + log.Error(err, "Unable to retrieve Network.operator.openshift.io object") + return reconcile.Result{Requeue: true}, err + } + + // Fetch antrea-install CR. + operConfig, err, found, change := fetchAntreaInstall(r, request) + if err != nil && !found { + return reconcile.Result{}, nil + } + if err != nil { + return reconcile.Result{Requeue: true}, err + } + if !change { + return reconcile.Result{}, nil + } + + // Apply configuration. + if result, err := applyConfig(r, oc.Config, clusterConfig, operConfig, operatorNetwork); err != nil { + return result, err + } // Update cluster network CR status. clusterNetworkConfigChanged := configutil.HasClusterNetworkConfigChange(r.AppliedClusterConfig, clusterConfig) @@ -241,57 +287,77 @@ func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (ctrl.Result, r.AppliedClusterConfig = clusterConfig r.AppliedOperConfig = operConfig - return ctrl.Result{}, nil + return reconcile.Result{}, nil } -func (r *AntreaInstallReconciler) updateStatusManagerAndSharedInfo(objs []*uns.Unstructured, clusterConfig *configv1.Network) error { - var daemonSets, deployments []types.NamespacedName - var relatedObjects []configv1.ObjectReference - var daemonSetObject, deploymentObject *uns.Unstructured - for _, obj := range objs { - if obj.GetAPIVersion() == "apps/v1" && obj.GetKind() == "DaemonSet" { - daemonSets = append(daemonSets, types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}) - daemonSetObject = obj - } else if obj.GetAPIVersion() == "apps/v1" && obj.GetKind() == "Deployment" { - deployments = append(deployments, types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}) - deploymentObject = obj - } - restMapping, err := r.Mapper.RESTMapping(obj.GroupVersionKind().GroupKind()) - if err != nil { - log.Error(err, "failed to get REST mapping for storing related object") - continue - } - relatedObjects = append(relatedObjects, configv1.ObjectReference{ - Group: obj.GetObjectKind().GroupVersionKind().Group, - Resource: restMapping.Resource.Resource, - Name: obj.GetName(), - Namespace: obj.GetNamespace(), - }) - if err := controllerutil.SetControllerReference(clusterConfig, obj, r.Scheme); err != nil { - log.Error(err, "failed to set owner reference", "resource", obj.GetName()) - r.Status.SetDegraded(statusmanager.OperatorConfig, "ApplyObjectsError", fmt.Sprintf("Failed to set owner reference: %v", err)) - return err - } +// AntreaInstallReconciler reconciles a AntreaInstall object +type AntreaInstallReconciler struct { + Client client.Client + Log logr.Logger + Scheme *runtime.Scheme + Status *statusmanager.StatusManager + Mapper meta.RESTMapper + + Adaptor + + SharedInfo *sharedinfo.SharedInfo + AppliedClusterConfig *configv1.Network + AppliedOperConfig *operatorv1.AntreaInstall +} + +func New(mgr ctrl.Manager, statusManager *statusmanager.StatusManager, info *sharedinfo.SharedInfo) (*AntreaInstallReconciler, error) { + r := AntreaInstallReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("AntreaInstall"), + Scheme: mgr.GetScheme(), + Status: statusManager, + Mapper: mgr.GetRESTMapper(), + SharedInfo: info, } - if daemonSetObject == nil || deploymentObject == nil { - var missedResources []string - if daemonSetObject == nil { - missedResources = append(missedResources, fmt.Sprintf("DaemonSet: %s", operatortypes.AntreaAgentDaemonSetName)) + switch info.AntreaPlatform { + case "openshift": + r.Adaptor = &AdaptorOc{ + Config: &configutil.ConfigOc{}, } - if deploymentObject == nil { - missedResources = append(missedResources, fmt.Sprintf("Deployment: %s", operatortypes.AntreaControllerDeploymentName)) + case "kubernetes": + r.Adaptor = &AdaptorK8s{ + Config: &configutil.ConfigK8s{}, } - err := fmt.Errorf("configuration of resources %v is missing", missedResources) - log.Error(nil, err.Error()) - r.Status.SetDegraded(statusmanager.OperatorConfig, "ApplyObjectsError", err.Error()) - return err + default: + return nil, errors.New("invalid platform: platform should be openshift or kubernetes") } - r.Status.SetDaemonSets(daemonSets) - r.Status.SetDeployments(deployments) - r.Status.SetRelatedObjects(relatedObjects) - r.SharedInfo.AntreaAgentDaemonSetSpec = daemonSetObject.DeepCopy() - r.SharedInfo.AntreaControllerDeploymentSpec = deploymentObject.DeepCopy() - return nil + return &r, nil +} + +func (r *AntreaInstallReconciler) SetupWithManager(mgr ctrl.Manager) error { + return r.Adaptor.SetupWithManager(r, mgr) +} + +// +kubebuilder:rbac:groups=operator.antrea.vmware.com,resources=antreainstalls,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=operator.antrea.vmware.com,resources=antreainstalls/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=config.openshift.io,resources=clusteroperators,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=config.openshift.io,resources=clusteroperators/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=config.openshift.io,resources=networks;networks/finalizers,verbs=get;list;watch;patch;update +// +kubebuilder:rbac:groups=operator.openshift.io,resources=networks,verbs=get;list;watch;patch;update +// +kubebuilder:rbac:groups="",resources=nodes,verbs=get;watch;list +// +kubebuilder:rbac:groups="",resources=namespaces;pods;configmaps;services;serviceaccounts,verbs=create;delete;get;list;patch;update;watch;deletecollection +// +kubebuilder:rbac:groups=apps,resources=deployments;daemonsets,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings;roles;rolebindings,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups=apiregistration.k8s.io,resources=apiservices,verbs=get;create;update;delete +// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create +// +kubebuilder:rbac:groups=authentication.k8s.io,resources=tokenreviews,verbs=create +// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=get;watch;list +// +kubebuilder:rbac:groups=ops.antrea.tanzu.vmware.com,resources=traceflows;traceflows/status,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=clusterinformation.antrea.tanzu.vmware.com,resources=antreaagentinfos;antreacontrollerinfos,verbs=get;list;create;update;delete +// +kubebuilder:rbac:groups=networking.antrea.tanzu.vmware.com,resources=networkpolicies;appliedtogroups;addressgroups,verbs=get;watch;list;delete +// +kubebuilder:rbac:groups=security.antrea.tanzu.vmware.com,resources=clusternetworkpolicies,verbs=get;watch;list;delete +// +kubebuilder:rbac:groups=system.antrea.tanzu.vmware.com,resources=controllerinfos;agentinfos;supportbundles;supportbundles/download,verbs=get;watch;list;post;delete +// +kubebuilder:rbac:urls=/agentinfo;/addressgroups;/appliedtogroups;/networkpolicies;/ovsflows;/ovstracing;/podinterfaces,verbs=get +// +kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,resourceNames=hostnetwork,verbs=use + +func (r *AntreaInstallReconciler) Reconcile(request ctrl.Request) (reconcile.Result, error) { + return r.Adaptor.Reconcile(r, request) } func (r *AntreaInstallReconciler) getAppliedOperConfig() (*operatorv1.AntreaInstall, error) { @@ -359,3 +425,63 @@ func updateNetworkStatus(c client.Client, clusterConfig *configv1.Network, defau log.Info("Successfully updated Network Status") return nil } + +func updateStatusManagerAndSharedInfo(r *AntreaInstallReconciler, objs []*uns.Unstructured, clusterConfig *configv1.Network) error { + var daemonSets, deployments []types.NamespacedName + var relatedObjects []configv1.ObjectReference + var daemonSetObject, deploymentObject *uns.Unstructured + for _, obj := range objs { + if obj.GetAPIVersion() == "apps/v1" && obj.GetKind() == "DaemonSet" { + daemonSets = append(daemonSets, types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}) + daemonSetObject = obj + } else if obj.GetAPIVersion() == "apps/v1" && obj.GetKind() == "Deployment" { + deployments = append(deployments, types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetName()}) + deploymentObject = obj + } + restMapping, err := r.Mapper.RESTMapping(obj.GroupVersionKind().GroupKind()) + if err != nil { + log.Error(err, "failed to get REST mapping for storing related object") + continue + } + relatedObjects = append(relatedObjects, configv1.ObjectReference{ + Group: obj.GetObjectKind().GroupVersionKind().Group, + Resource: restMapping.Resource.Resource, + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + }) + if clusterConfig != nil { + if err := controllerutil.SetControllerReference(clusterConfig, obj, r.Scheme); err != nil { + log.Error(err, "failed to set owner reference", "resource", obj.GetName()) + r.Status.SetDegraded(statusmanager.OperatorConfig, "ApplyObjectsError", fmt.Sprintf("Failed to set owner reference: %v", err)) + return err + } + } + } + if daemonSetObject == nil || deploymentObject == nil { + var missedResources []string + if daemonSetObject == nil { + missedResources = append(missedResources, fmt.Sprintf("DaemonSet: %s", operatortypes.AntreaAgentDaemonSetName)) + } + if deploymentObject == nil { + missedResources = append(missedResources, fmt.Sprintf("Deployment: %s", operatortypes.AntreaControllerDeploymentName)) + } + err := fmt.Errorf("configuration of resources %v is missing", missedResources) + log.Error(nil, err.Error()) + r.Status.SetDegraded(statusmanager.OperatorConfig, "ApplyObjectsError", err.Error()) + return err + } + r.Status.SetDaemonSets(daemonSets) + r.Status.SetDeployments(deployments) + r.Status.SetRelatedObjects(relatedObjects) + r.SharedInfo.AntreaAgentDaemonSetSpec = daemonSetObject.DeepCopy() + r.SharedInfo.AntreaControllerDeploymentSpec = deploymentObject.DeepCopy() + return nil +} + +func (a *AdaptorK8s) UpdateStatusManagerAndSharedInfo(r *AntreaInstallReconciler, objs []*uns.Unstructured, clusterConfig *configv1.Network) error { + return updateStatusManagerAndSharedInfo(r, objs, clusterConfig) +} + +func (a *AdaptorOc) UpdateStatusManagerAndSharedInfo(r *AntreaInstallReconciler, objs []*uns.Unstructured, clusterConfig *configv1.Network) error { + return updateStatusManagerAndSharedInfo(r, objs, clusterConfig) +} diff --git a/controllers/config/config.go b/controllers/config/config.go index 5476a18e..e8664d51 100644 --- a/controllers/config/config.go +++ b/controllers/config/config.go @@ -4,8 +4,10 @@ package config import ( + "errors" "fmt" + gocni "github.com/containerd/go-cni" configv1 "github.com/openshift/api/config/v1" ocoperv1 "github.com/openshift/api/operator/v1" "github.com/openshift/cluster-network-operator/pkg/network" @@ -20,45 +22,44 @@ import ( var log = ctrl.Log.WithName("config") -func FillConfigs(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { +type Config interface { + FillConfigs(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error + ValidateConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error + GenerateRenderData(operatorNetwork *ocoperv1.Network, operConfig *operatorv1.AntreaInstall) (*render.RenderData, error) +} + +type ConfigOc struct{} + +type ConfigK8s struct{} + +func fillConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { antreaAgentConfig := make(map[string]interface{}) err := yaml.Unmarshal([]byte(operConfig.Spec.AntreaAgentConfig), &antreaAgentConfig) if err != nil { return fmt.Errorf("failed to parse AntreaAgentConfig: %v", err) } - // Set service CIDR. - if len(clusterConfig.Spec.ServiceNetwork) == 0 { - return fmt.Errorf("service network can not be empty") - } - serviceCIDR, ok := antreaAgentConfig[types.ServiceCIDROption] - if ok { - found := false - for _, serviceNet := range clusterConfig.Spec.ServiceNetwork { - if serviceNet == serviceCIDR { - found = true - break - } + if clusterConfig == nil { + if _, ok := antreaAgentConfig[types.ServiceCIDROption]; !ok { + return errors.New("serviceCIDR should be specified on kubernetes.") } - if !found { + } else { + if serviceCIDR, ok := antreaAgentConfig[types.ServiceCIDROption].(string); !ok { + antreaAgentConfig[types.ServiceCIDROption] = clusterConfig.Spec.ServiceNetwork[0] + } else if found := inSlice(serviceCIDR, clusterConfig.Spec.ServiceNetwork); !found { log.Info("WARNING: option: %s is overwritten by cluster config") antreaAgentConfig[types.ServiceCIDROption] = clusterConfig.Spec.ServiceNetwork[0] } - } else { - antreaAgentConfig[types.ServiceCIDROption] = clusterConfig.Spec.ServiceNetwork[0] } - // Set default MTU. - _, ok = antreaAgentConfig[types.DefaultMTUOption] + _, ok := antreaAgentConfig[types.DefaultMTUOption] if !ok { antreaAgentConfig[types.DefaultMTUOption] = types.DefaultMTU } - // Set Antrea image. if operConfig.Spec.AntreaImage == "" { operConfig.Spec.AntreaImage = types.DefaultAntreaImage } - updatedAntreaAgentConfig, err := yaml.Marshal(antreaAgentConfig) if err != nil { return fmt.Errorf("failed to fill configurations in AntreaAgentConfig: %v", err) @@ -67,40 +68,53 @@ func FillConfigs(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaI return nil } -func ValidateConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { +func (c *ConfigOc) FillConfigs(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { + return fillConfig(clusterConfig, operConfig) +} + +func (c *ConfigK8s) FillConfigs(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { + return fillConfig(clusterConfig, operConfig) +} + +func validateConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { var errs []error - // Validate antrea config + if operConfig.Spec.AntreaImage == "" { + errs = append(errs, fmt.Errorf("antreaImage option can not be empty")) + } + antreaAgentConfig := make(map[string]interface{}) err := yaml.Unmarshal([]byte(operConfig.Spec.AntreaAgentConfig), &antreaAgentConfig) if err != nil { errs = append(errs, fmt.Errorf("failed to parse AntreaAgentConfig: %v", err)) + return fmt.Errorf("invalidate configuration: %v", errs) + } + + if clusterConfig == nil { + if _, ok := antreaAgentConfig[types.ServiceCIDROption]; !ok { + errs = append(errs, fmt.Errorf("serviceCIDR option can not be empty")) + } } else { - serviceCIDR, ok := antreaAgentConfig[types.ServiceCIDROption].(string) - if ok { - found := false - for _, serviceNet := range clusterConfig.Spec.ServiceNetwork { - if serviceNet == serviceCIDR { - found = true - break - } - } - if !found { - errs = append(errs, fmt.Errorf("invalid serviceCIDR option: %s, available values are: %s", serviceCIDR, clusterConfig.Spec.ServiceNetwork)) - } - } else { + if serviceCIDR, ok := antreaAgentConfig[types.ServiceCIDROption].(string); !ok { errs = append(errs, fmt.Errorf("serviceCIDR option can not be empty")) + } else if found := inSlice(serviceCIDR, clusterConfig.Spec.ServiceNetwork); !found { + errs = append(errs, fmt.Errorf("invalid serviceCIDR option: %s, available values are: %s", serviceCIDR, clusterConfig.Spec.ServiceNetwork)) } } - if operConfig.Spec.AntreaImage == "" { - errs = append(errs, fmt.Errorf("antreaImage option can not be empty")) - } if len(errs) > 0 { return fmt.Errorf("invalidate configuration: %v", errs) } return nil } +func (c *ConfigOc) ValidateConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { + return validateConfig(clusterConfig, operConfig) +} + +func (c *ConfigK8s) ValidateConfig(clusterConfig *configv1.Network, operConfig *operatorv1.AntreaInstall) error { + return validateConfig(clusterConfig, operConfig) +} + func NeedApplyChange(preConfig, curConfig *operatorv1.AntreaInstall) (agentNeedChange, controllerNeedChange, imageChange bool) { if preConfig == nil { return true, true, false @@ -224,16 +238,29 @@ func pluginCNIConfDir(conf *ocoperv1.NetworkSpec) string { return network.SystemCNIConfDir } -func GenerateRenderData(operatorNetwork *ocoperv1.Network, operConfig *operatorv1.AntreaInstall) (*render.RenderData, error) { +func generateRenderData(operatorNetwork *ocoperv1.Network, operConfig *operatorv1.AntreaInstall) *render.RenderData { renderData := render.MakeRenderData() - renderData.Data[types.ReleaseVersion] = version.Version renderData.Data[types.AntreaAgentConfigRenderKey] = operConfig.Spec.AntreaAgentConfig renderData.Data[types.AntreaCNIConfigRenderKey] = operConfig.Spec.AntreaCNIConfig renderData.Data[types.AntreaControllerConfigRenderKey] = operConfig.Spec.AntreaControllerConfig renderData.Data[types.AntreaImageRenderKey] = operConfig.Spec.AntreaImage - renderData.Data[types.CNIConfDirRenderKey] = pluginCNIConfDir(&operatorNetwork.Spec) - renderData.Data[types.CNIBinDirRenderKey] = network.CNIBinDir + if operatorNetwork == nil { + renderData.Data[types.CNIConfDirRenderKey] = gocni.DefaultNetDir + renderData.Data[types.CNIBinDirRenderKey] = gocni.DefaultCNIDir + } else { + renderData.Data[types.CNIConfDirRenderKey] = pluginCNIConfDir(&operatorNetwork.Spec) + renderData.Data[types.CNIBinDirRenderKey] = network.CNIBinDir + } + return &renderData +} + +func (c *ConfigK8s) GenerateRenderData(operatorNetwork *ocoperv1.Network, operConfig *operatorv1.AntreaInstall) (*render.RenderData, error) { + renderData := generateRenderData(operatorNetwork, operConfig) + return renderData, nil +} - return &renderData, nil +func (c *ConfigOc) GenerateRenderData(operatorNetwork *ocoperv1.Network, operConfig *operatorv1.AntreaInstall) (*render.RenderData, error) { + renderData := generateRenderData(operatorNetwork, operConfig) + return renderData, nil } diff --git a/controllers/config/config_test.go b/controllers/config/config_test.go index b4cc9015..2041e0e9 100644 --- a/controllers/config/config_test.go +++ b/controllers/config/config_test.go @@ -7,6 +7,7 @@ import ( "fmt" "testing" + gocni "github.com/containerd/go-cni" "github.com/ghodss/yaml" . "github.com/onsi/gomega" configv1 "github.com/openshift/api/config/v1" @@ -44,33 +45,38 @@ var mockOperatorNetwork = ocoperv1.Network{ var mockOperConfig = operatorv1.AntreaInstall{ Spec: operatorv1.AntreaInstallSpec{ - AntreaAgentConfig: "", + AntreaAgentConfig: `{ + "serviceCIDR": "10.96.0.0/12" + }`, AntreaCNIConfig: `{ - "cniVersion":"0.3.0", - "name": "antrea", - "plugins": [ - { - "type": "antrea", - "ipam": { - "type": "host-local" - } - }, - { - "type": "portmap", - "capabilities": {"portMappings": true} - } - ] -}`, + "cniVersion":"0.3.0", + "name": "antrea", + "plugins": [ + { + "type": "antrea", + "ipam": { + "type": "host-local" + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] + }`, AntreaControllerConfig: "apiPort: 10349", }, } -func TestFillDefaults(t *testing.T) { +var oc = &ConfigOc{} +var k8s = &ConfigK8s{} + +func TestFillDefaultsOc(t *testing.T) { g := NewGomegaWithT(t) clusterConfig := mockClusterConfig.DeepCopy() operConfig := mockOperConfig.DeepCopy() - err := FillConfigs(clusterConfig, operConfig) + err := oc.FillConfigs(clusterConfig, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) antreaAgentConfig := make(map[string]interface{}) @@ -81,14 +87,28 @@ func TestFillDefaults(t *testing.T) { g.Expect(operConfig.Spec.AntreaImage).Should(Equal(operatortypes.DefaultAntreaImage)) } -func TestValidateConfig(t *testing.T) { +func TestFillDefaultsK8s(t *testing.T) { + g := NewGomegaWithT(t) + + operConfig := mockOperConfig.DeepCopy() + err := k8s.FillConfigs(nil, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + + antreaAgentConfig := make(map[string]interface{}) + err = yaml.Unmarshal([]byte(operConfig.Spec.AntreaAgentConfig), &antreaAgentConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + g.Expect(int(antreaAgentConfig[operatortypes.DefaultMTUOption].(float64))).Should(Equal(operatortypes.DefaultMTU)) + g.Expect(operConfig.Spec.AntreaImage).Should(Equal(operatortypes.DefaultAntreaImage)) +} + +func TestValidateConfigOc(t *testing.T) { g := NewGomegaWithT(t) clusterConfig := mockClusterConfig.DeepCopy() operConfig := mockOperConfig.DeepCopy() - err := FillConfigs(clusterConfig, operConfig) + err := oc.FillConfigs(clusterConfig, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) - err = ValidateConfig(clusterConfig, operConfig) + err = oc.ValidateConfig(clusterConfig, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) // Validate service CIDR @@ -96,7 +116,7 @@ func TestValidateConfig(t *testing.T) { operConfig = mockOperConfig.DeepCopy() clusterConfig.Spec.ServiceNetwork = []string{"10.96.0.0.0/12"} operConfig.Spec.AntreaAgentConfig = "serviceCIDR: 10.96.0.0.1/12" - err = ValidateConfig(clusterConfig, operConfig) + err = oc.ValidateConfig(clusterConfig, operConfig) g.Expect(err).Should(HaveOccurred()) g.Expect(err.Error()).Should(ContainSubstring("invalid serviceCIDR option")) g.Expect(err.Error()).Should(ContainSubstring("available values are")) @@ -105,20 +125,76 @@ func TestValidateConfig(t *testing.T) { clusterConfig = mockClusterConfig.DeepCopy() operConfig = mockOperConfig.DeepCopy() operConfig.Spec.AntreaAgentConfig = `serviceCIDR:---` - err = ValidateConfig(clusterConfig, operConfig) + err = oc.ValidateConfig(clusterConfig, operConfig) g.Expect(err).Should(HaveOccurred()) g.Expect(err.Error()).Should(ContainSubstring("failed to parse AntreaAgentConfig")) } -func TestRender(t *testing.T) { +func TestValidateConfigK8s(t *testing.T) { + g := NewGomegaWithT(t) + + operConfig := mockOperConfig.DeepCopy() + err := k8s.FillConfigs(nil, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + err = k8s.ValidateConfig(nil, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + + // Validate service CIDR and antrea image + operConfig = mockOperConfig.DeepCopy() + err = k8s.ValidateConfig(nil, operConfig) + g.Expect(err).Should(HaveOccurred()) + g.Expect(err.Error()).Should(ContainSubstring("antreaImage option can not be empty")) + + // Validate antrea-agent config + operConfig = mockOperConfig.DeepCopy() + operConfig.Spec.AntreaAgentConfig = `serviceCIDR:---` + err = k8s.ValidateConfig(nil, operConfig) + g.Expect(err).Should(HaveOccurred()) + g.Expect(err.Error()).Should(ContainSubstring("failed to parse AntreaAgentConfig")) +} + +func TestRenderOc(t *testing.T) { g := NewGomegaWithT(t) clusterConfig := mockClusterConfig.DeepCopy() operConfig := mockOperConfig.DeepCopy() operatorNetwork := mockOperatorNetwork.DeepCopy() - err := FillConfigs(clusterConfig, operConfig) + err := oc.FillConfigs(clusterConfig, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + renderData, err := oc.GenerateRenderData(operatorNetwork, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + objs, err := render.RenderDir("../../antrea-manifest", renderData) + g.Expect(err).ShouldNot(HaveOccurred()) + + for _, obj := range objs { + if obj.GetKind() == "ConfigMap" && obj.GetNamespace() == "kube-system" && obj.GetName() == "antrea-config" { + var data map[string]interface{} + data = obj.Object["data"].(map[string]interface{}) + g.Expect(data[operatortypes.AntreaAgentConfigOption]).Should(Equal(operConfig.Spec.AntreaAgentConfig)) + g.Expect(data[operatortypes.AntreaCNIConfigOption]).Should(Equal(operConfig.Spec.AntreaCNIConfig)) + g.Expect(data[operatortypes.AntreaControllerConfigOption]).Should(Equal(operConfig.Spec.AntreaControllerConfig)) + } else if obj.GetKind() == "Deployment" && obj.GetNamespace() == "kube-system" && obj.GetName() == "antrea-controller" { + antreaDeployment := &appsv1.Deployment{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), antreaDeployment) + g.Expect(err).ShouldNot(HaveOccurred()) + g.Expect(antreaDeployment.Spec.Template.Spec.Containers[0].Image).Should(Equal(operatortypes.DefaultAntreaImage)) + g.Expect(antreaDeployment.Annotations["release.openshift.io/version"]).Should(Equal(version.Version)) + } else if obj.GetKind() == "DaemonSet" && obj.GetNamespace() == "kube-system" && obj.GetName() == "antrea-agent" { + antreaDaemonSet := &appsv1.DaemonSet{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), antreaDaemonSet) + g.Expect(err).ShouldNot(HaveOccurred()) + g.Expect(antreaDaemonSet.Annotations["release.openshift.io/version"]).Should(Equal(version.Version)) + } + } +} + +func TestRenderK8s(t *testing.T) { + g := NewGomegaWithT(t) + + operConfig := mockOperConfig.DeepCopy() + err := k8s.FillConfigs(nil, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) - renderData, err := GenerateRenderData(operatorNetwork, operConfig) + renderData, err := k8s.GenerateRenderData(nil, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) objs, err := render.RenderDir("../../antrea-manifest", renderData) g.Expect(err).ShouldNot(HaveOccurred()) @@ -223,13 +299,13 @@ func TestBuildNetworkStatus(t *testing.T) { g.Expect(updatedClusterConfig.ClusterNetworkMTU).Should(Equal(defaultMtu)) } -func TestGenerateRenderData(t *testing.T) { +func TestGenerateRenderDataOc(t *testing.T) { g := NewGomegaWithT(t) operConfig := mockOperConfig.DeepCopy() operConfig.Spec.AntreaImage = operatortypes.DefaultAntreaImage operatorNetwork := mockOperatorNetwork.DeepCopy() - renderData, err := GenerateRenderData(operatorNetwork, operConfig) + renderData, err := oc.GenerateRenderData(operatorNetwork, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(renderData.Data[operatortypes.AntreaAgentConfigRenderKey]).Should(Equal(operConfig.Spec.AntreaAgentConfig)) g.Expect(renderData.Data[operatortypes.AntreaCNIConfigRenderKey]).Should(Equal(operConfig.Spec.AntreaCNIConfig)) @@ -244,7 +320,22 @@ func TestGenerateRenderData(t *testing.T) { disableMultiNetwork := true operatorNetwork.Spec.DisableMultiNetwork = &disableMultiNetwork - renderData, err = GenerateRenderData(operatorNetwork, operConfig) + renderData, err = oc.GenerateRenderData(operatorNetwork, operConfig) g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(renderData.Data[operatortypes.CNIConfDirRenderKey]).Should(Equal(network.SystemCNIConfDir)) } + +func TestGenerateRenderDataK8s(t *testing.T) { + g := NewGomegaWithT(t) + + operConfig := mockOperConfig.DeepCopy() + operConfig.Spec.AntreaImage = operatortypes.DefaultAntreaImage + renderData, err := k8s.GenerateRenderData(nil, operConfig) + g.Expect(err).ShouldNot(HaveOccurred()) + g.Expect(renderData.Data[operatortypes.AntreaAgentConfigRenderKey]).Should(Equal(operConfig.Spec.AntreaAgentConfig)) + g.Expect(renderData.Data[operatortypes.AntreaCNIConfigRenderKey]).Should(Equal(operConfig.Spec.AntreaCNIConfig)) + g.Expect(renderData.Data[operatortypes.AntreaControllerConfigRenderKey]).Should(Equal(operConfig.Spec.AntreaControllerConfig)) + g.Expect(renderData.Data[operatortypes.AntreaImageRenderKey]).Should(Equal(operConfig.Spec.AntreaImage)) + g.Expect(renderData.Data[operatortypes.CNIConfDirRenderKey]).Should(Equal(gocni.DefaultNetDir)) + g.Expect(renderData.Data[operatortypes.CNIBinDirRenderKey]).Should(Equal(gocni.DefaultCNIDir)) +} diff --git a/controllers/sharedinfo/sharedinfo.go b/controllers/sharedinfo/sharedinfo.go index 4f4ae0f9..cec00491 100644 --- a/controllers/sharedinfo/sharedinfo.go +++ b/controllers/sharedinfo/sharedinfo.go @@ -5,6 +5,7 @@ package sharedinfo import ( "context" + "errors" "sync" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -38,5 +39,10 @@ func New(mgr manager.Manager) (*SharedInfo, error) { log.Error(err, "failed to get antrea-install", "namespace", operatortypes.OperatorNameSpace, "name", operatortypes.OperatorConfigName) return nil, err } - return &SharedInfo{AntreaPlatform: antreaInstall.Spec.AntreaPlatform}, nil + switch antreaInstall.Spec.AntreaPlatform { + case "openshift", "kubernetes": + return &SharedInfo{AntreaPlatform: antreaInstall.Spec.AntreaPlatform}, nil + default: + return nil, errors.New("invalid platform: platform should be openshift or kubernetes") + } } diff --git a/deploy/namespace.yaml b/deploy/kubernetes/namespace.yaml similarity index 100% rename from deploy/namespace.yaml rename to deploy/kubernetes/namespace.yaml diff --git a/deploy/operator.antrea.vmware.com_antreainstalls_crd.yaml b/deploy/kubernetes/operator.antrea.vmware.com_antreainstalls_crd.yaml similarity index 100% rename from deploy/operator.antrea.vmware.com_antreainstalls_crd.yaml rename to deploy/kubernetes/operator.antrea.vmware.com_antreainstalls_crd.yaml diff --git a/deploy/kubernetes/operator.antrea.vmware.com_v1_antreainstall_cr.yaml b/deploy/kubernetes/operator.antrea.vmware.com_v1_antreainstall_cr.yaml new file mode 100644 index 00000000..fe84cd51 --- /dev/null +++ b/deploy/kubernetes/operator.antrea.vmware.com_v1_antreainstall_cr.yaml @@ -0,0 +1,200 @@ +apiVersion: operator.antrea.vmware.com/v1 +kind: AntreaInstall +metadata: + name: antrea-install + namespace: antrea-operator +spec: + antreaAgentConfig: | + # FeatureGates is a map of feature names to bools that enable or disable experimental features. + featureGates: + # Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent. + # It should be enabled on Windows, otherwise NetworkPolicy will not take effect on + # Service traffic. + # AntreaProxy: true + + # Enable EndpointSlice support in AntreaProxy. Don't enable this feature unless that EndpointSlice + # API version v1beta1 is supported and set as enabled in Kubernetes. If AntreaProxy is not enabled, + # this flag will not take effect. + # EndpointSlice: false + + # Enable traceflow which provides packet tracing feature to diagnose network issue. + # Traceflow: true + + # Enable NodePortLocal feature to make the pods reachable externally through NodePort + # NodePortLocal: false + + # Enable Antrea ClusterNetworkPolicy feature to complement K8s NetworkPolicy for cluster admins + # to define security policies which apply to the entire cluster, and Antrea NetworkPolicy + # feature that supports priorities, rule actions and externalEntities in the future. + # AntreaPolicy: false + + # Enable flowexporter which exports polled conntrack connections as IPFIX flow records from each + # agent to a configured collector. + # FlowExporter: false + + # Enable collecting and exposing NetworkPolicy statistics. + # NetworkPolicyStats: false + + # Name of the OpenVSwitch bridge antrea-agent will create and use. + # Make sure it doesn't conflict with your existing OpenVSwitch bridges. + #ovsBridge: br-int + + # Datapath type to use for the OpenVSwitch bridge created by Antrea. Supported values are: + # - system + # - netdev + # 'system' is the default value and corresponds to the kernel datapath. Use 'netdev' to run + # OVS in userspace mode. Userspace mode requires the tun device driver to be available. + #ovsDatapathType: system + + # Name of the interface antrea-agent will create and use for host <--> pod communication. + # Make sure it doesn't conflict with your existing interfaces. + #hostGateway: antrea-gw0 + + # Determines how traffic is encapsulated. It has the following options: + # encap(default): Inter-node Pod traffic is always encapsulated and Pod to external network + # traffic is SNAT'd. + # noEncap: Inter-node Pod traffic is not encapsulated; Pod to external network traffic is + # SNAT'd if noSNAT is not set to true. Underlying network must be capable of + # supporting Pod traffic across IP subnets. + # hybrid: noEncap if source and destination Nodes are on the same subnet, otherwise encap. + # networkPolicyOnly: Antrea enforces NetworkPolicy only, and utilizes CNI chaining and delegates Pod + # IPAM and connectivity to the primary CNI. + # + #trafficEncapMode: encap + + # Whether or not to SNAT (using the Node IP) the egress traffic from a Pod to the external network. + # This option is for the noEncap traffic mode only, and the default value is false. In the noEncap + # mode, if the cluster's Pod CIDR is reachable from the external network, then the Pod traffic to + # the external network needs not be SNAT'd. In the networkPolicyOnly mode, antrea-agent never + # performs SNAT and this option will be ignored; for other modes it must be set to false. + #noSNAT: false + + # Tunnel protocols used for encapsulating traffic across Nodes. Supported values: + # - geneve (default) + # - vxlan + # - gre + # - stt + #tunnelType: geneve + + # Default MTU to use for the host gateway interface and the network interface of each Pod. + # If omitted, antrea-agent will discover the MTU of the Node's primary interface and + # also adjust MTU to accommodate for tunnel encapsulation overhead (if applicable). + #defaultMTU: 1450 + + # Whether or not to enable IPsec encryption of tunnel traffic. IPsec encryption is only supported + # for the GRE tunnel type. + #enableIPSecTunnel: false + + # The port for the antrea-agent APIServer to serve on. + # Note that if it's set to another value, the `containerPort` of the `api` port of the + # `antrea-agent` container must be set to the same value. + #apiPort: 10350 + + # Enable metrics exposure via Prometheus. Initializes Prometheus metrics listener. + #enablePrometheusMetrics: true + + # Provide the IPFIX collector address as a string with format :[][:]. + # HOST can either be the DNS name or the IP of the Flow Collector. For example, + # "flow-aggregator.flow-aggregator.svc" can be provided as DNS name to connect + # to the Antrea Flow Aggregator service. If IP, it can be either IPv4 or IPv6. + # However, IPv6 address should be wrapped with []. + # If PORT is empty, we default to 4739, the standard IPFIX port. + # If no PROTO is given, we consider "tcp" as default. We support "tcp" and "udp" + # L4 transport protocols. + #flowCollectorAddr: "flow-aggregator.flow-aggregator.svc:4739:tcp" + + # Provide flow poll interval as a duration string. This determines how often the flow exporter dumps connections from the conntrack module. + # Flow poll interval should be greater than or equal to 1s (one second). + # Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". + #flowPollInterval: "5s" + + # Provide flow export frequency, which is the number of poll cycles elapsed before flow exporter exports flow records to + # the flow collector. + # Flow export frequency should be greater than or equal to 1. + #flowExportFrequency: 12 + + # Enable TLS communication from flow exporter to flow aggregator. + #enableTLSToFlowAggregator: true + + # Provide the port range used by NodePortLocal. When the NodePortLocal feature is enabled, a port from that range will be assigned + # whenever a Pod's container defines a specific port to be exposed (each container can define a list of ports as pod.spec.containers[].ports), + # and all Node traffic directed to that port will be forwarded to the Pod. + #nplPortRange: 40000-41000 + + # Provide the address of Kubernetes apiserver, to override any value provided in kubeconfig or InClusterConfig. + # Defaults to "". It must be a host string, a host:port pair, or a URL to the base of the apiserver. + #kubeAPIServerOverride: "" + + # Comma-separated list of Cipher Suites. If omitted, the default Go Cipher Suites will be used. + # https://golang.org/pkg/crypto/tls/#pkg-constants + # Note that TLS1.3 Cipher Suites cannot be added to the list. But the apiserver will always + # prefer TLS1.3 Cipher Suites whenever possible. + #tlsCipherSuites: + + # TLS min version from: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13. + #tlsMinVersion: + + # Provide the service ip range(--service-cluster-ip-range). + #serviceCIDR: "10.96.0.0/12" + antreaCNIConfig: | + { + "cniVersion":"0.3.0", + "name": "antrea", + "plugins": [ + { + "type": "antrea", + "ipam": { + "type": "host-local" + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + }, + { + "type": "bandwidth", + "capabilities": {"bandwidth": true} + } + ] + } + antreaControllerConfig: | + # FeatureGates is a map of feature names to bools that enable or disable experimental features. + featureGates: + # Enable traceflow which provides packet tracing feature to diagnose network issue. + # Traceflow: true + + # Enable Antrea ClusterNetworkPolicy feature to complement K8s NetworkPolicy for cluster admins + # to define security policies which apply to the entire cluster, and Antrea NetworkPolicy + # feature that supports priorities, rule actions and externalEntities in the future. + # AntreaPolicy: false + + # Enable collecting and exposing NetworkPolicy statistics. + # NetworkPolicyStats: false + + # The port for the antrea-controller APIServer to serve on. + # Note that if it's set to another value, the `containerPort` of the `api` port of the + # `antrea-controller` container must be set to the same value. + #apiPort: 10349 + + # Enable metrics exposure via Prometheus. Initializes Prometheus metrics listener. + #enablePrometheusMetrics: true + + # Indicates whether to use auto-generated self-signed TLS certificate. + # If false, A Secret named "antrea-controller-tls" must be provided with the following keys: + # ca.crt: + # tls.crt: + # tls.key: + # And the Secret must be mounted to directory "/var/run/antrea/antrea-controller-tls" of the + # antrea-controller container. + #selfSignedCert: true + + # Comma-separated list of Cipher Suites. If omitted, the default Go Cipher Suites will be used. + # https://golang.org/pkg/crypto/tls/#pkg-constants + # Note that TLS1.3 Cipher Suites cannot be added to the list. But the apiserver will always + # prefer TLS1.3 Cipher Suites whenever possible. + #tlsCipherSuites: + + # TLS min version from: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13. + #tlsMinVersion: + antreaImage: projects.registry.vmware.com/antrea/antrea-ubi:v0.13.1 + antreaPlatform: kubernetes diff --git a/deploy/operator.yaml b/deploy/kubernetes/operator.yaml similarity index 100% rename from deploy/operator.yaml rename to deploy/kubernetes/operator.yaml diff --git a/deploy/role.yaml b/deploy/kubernetes/role.yaml similarity index 100% rename from deploy/role.yaml rename to deploy/kubernetes/role.yaml diff --git a/deploy/role_binding.yaml b/deploy/kubernetes/role_binding.yaml similarity index 100% rename from deploy/role_binding.yaml rename to deploy/kubernetes/role_binding.yaml diff --git a/deploy/service_account.yaml b/deploy/kubernetes/service_account.yaml similarity index 100% rename from deploy/service_account.yaml rename to deploy/kubernetes/service_account.yaml diff --git a/deploy/openshift/namespace.yaml b/deploy/openshift/namespace.yaml new file mode 100644 index 00000000..c163eb57 --- /dev/null +++ b/deploy/openshift/namespace.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: {name: antrea-operator, openshift.io/run-level: '0'} + name: antrea-operator \ No newline at end of file diff --git a/deploy/openshift/operator.antrea.vmware.com_antreainstalls_crd.yaml b/deploy/openshift/operator.antrea.vmware.com_antreainstalls_crd.yaml new file mode 100644 index 00000000..368207be --- /dev/null +++ b/deploy/openshift/operator.antrea.vmware.com_antreainstalls_crd.yaml @@ -0,0 +1,95 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: antreainstalls.operator.antrea.vmware.com +spec: + group: operator.antrea.vmware.com + names: + kind: AntreaInstall + listKind: AntreaInstallList + plural: antreainstalls + singular: antreainstall + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: AntreaInstall is the Schema for the antreainstalls API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AntreaInstallSpec defines the desired state of AntreaInstall + properties: + antreaAgentConfig: + description: AntreaAgentConfig holds the configurations for antrea-agent. + type: string + antreaCNIConfig: + description: AntreaCNIConfig holds the configuration of CNI. + type: string + antreaControllerConfig: + description: AntreaControllerConfig holds the configurations for antrea-controller. + type: string + antreaImage: + description: AntreaImage is the Docker image name used by antrea-agent and antrea-controller. + type: string + antreaPlatform: + description: AntreaPlatform is the platform on which antrea will be deployed. + type: string + required: + - antreaAgentConfig + - antreaCNIConfig + - antreaControllerConfig + - antreaPlatform + type: object + status: + description: AntreaInstallStatus defines the observed state of AntreaInstall + properties: + conditions: + description: Conditions describes the state of Antrea installation. + items: + description: ClusterOperatorStatusCondition represents the state of the operator's managed and monitored components. + properties: + lastTransitionTime: + description: lastTransitionTime is the time of the last update to the current status property. + format: date-time + type: string + message: + description: message provides additional information about the current condition. This is only to be consumed by humans. + type: string + reason: + description: reason is the CamelCase reason for the condition's current status. + type: string + status: + description: status of the condition, one of True, False, Unknown. + type: string + type: + description: type specifies the aspect reported by this condition. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/operator.antrea.vmware.com_v1_antreainstall_cr.yaml b/deploy/openshift/operator.antrea.vmware.com_v1_antreainstall_cr.yaml similarity index 100% rename from deploy/operator.antrea.vmware.com_v1_antreainstall_cr.yaml rename to deploy/openshift/operator.antrea.vmware.com_v1_antreainstall_cr.yaml diff --git a/deploy/openshift/operator.yaml b/deploy/openshift/operator.yaml new file mode 100644 index 00000000..f416033b --- /dev/null +++ b/deploy/openshift/operator.yaml @@ -0,0 +1,40 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: antrea-operator + namespace: antrea-operator +spec: + replicas: 1 + selector: + matchLabels: + name: antrea-operator + template: + metadata: + labels: + name: antrea-operator + spec: + hostNetwork: true + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - effect: NoSchedule + key: node.kubernetes.io/not-ready + serviceAccountName: antrea-operator + containers: + - name: antrea-operator + # Replace this with the built image name + image: REPLACE_IMAGE + command: + - antrea-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "antrea-operator" diff --git a/deploy/openshift/role.yaml b/deploy/openshift/role.yaml new file mode 100644 index 00000000..adea8720 --- /dev/null +++ b/deploy/openshift/role.yaml @@ -0,0 +1,117 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: antrea-operator +rules: +- apiGroups: [""] + resources: [endpoints] + verbs: [get, list, watch] +- apiGroups: [""] + resources: [pods, configmaps, namespaces, serviceaccounts, secrets, services] + verbs: [create, get, list, patch, delete, update, watch, deletecollection] +- apiGroups: [apps] + resources: [deployments, daemonsets] + verbs: [create, get, list, patch, delete, update, watch] +- apiGroups: [admissionregistration.k8s.io] + resources: [mutatingwebhookconfigurations, validatingwebhookconfigurations] + verbs: [get, update, create] +- apiGroups: [apiextensions.k8s.io] + resources: [customresourcedefinitions] + verbs: [create, get, list, patch, update, watch, delete] +- apiGroups: [discovery.k8s.io] + resources: [endpointslices] + verbs: [get, watch, list] +- apiGroups: [rbac.authorization.k8s.io] + resources: [clusterroles, clusterrolebindings] + verbs: [create, get, list, patch, update, watch, delete] +- apiGroups: [config.openshift.io] + resources: [clusteroperators] + verbs: [create, get, list, patch, update, watch, delete] +- apiGroups: [config.openshift.io] + resources: [clusteroperators/status] + verbs: [get, patch, update] +- apiGroups: [config.openshift.io] + resources: [networks, networks/finalizers] + verbs: [get, list, watch, patch, update] +- apiGroups: [operator.openshift.io] + resources: [networks] + verbs: [get, list, watch, patch, update] +- apiGroups: [operator.antrea.vmware.com] + resources: [antreainstalls, antreainstalls/status] + verbs: [get, list, watch, create,patch, update] +# Required by antrea-agent, antrea-controller and antctl +- apiGroups: [""] + resources: [nodes] + verbs: [get, watch, list] +- apiGroups: [""] + resources: [pods, endpoints] + verbs: [get, watch, list, delete] +- apiGroups: [authentication.k8s.io] + resources: [tokenreviews] + verbs: [create] +- apiGroups: [authorization.k8s.io] + resources: [subjectaccessreviews] + verbs: [create] +- apiGroups: [apiregistration.k8s.io] + resources: [apiservices] + verbs: [get, create, update, delete] +- apiGroups: [controlplane.antrea.tanzu.vmware.com] + resources: [networkpolicies, appliedtogroups, addressgroups] + verbs: [get, list, watch] +- apiGroups: [controlplane.antrea.tanzu.vmware.com] + resources: [nodestatssummaries] + verbs: [create] +- apiGroups: [controlplane.antrea.tanzu.vmware.com] + resources: [networkpolicies/status] + verbs: [create, get] +- apiGroups: [core.antrea.tanzu.vmware.com] + resources: [clustergroups] + verbs: [get, create, update, delete, list, watch, patch] +- apiGroups: [core.antrea.tanzu.vmware.com] + resources: [externalentities] + verbs: [get, watch, list] +- apiGroups: [core.antrea.tanzu.vmware.com] + resources: [clustergroups/status] + verbs: [update] +- apiGroups: [networking.k8s.io] + resources: [networkpolicies] + verbs: [get, watch, list] +- apiGroups: [ops.antrea.tanzu.vmware.com] + resources: [traceflows, traceflows/status] + verbs: [create, get, list, patch, update, watch, delete, delete] +- apiGroups: [clusterinformation.antrea.tanzu.vmware.com] + resources: [antreaagentinfos, antreacontrollerinfos] + verbs: [get, list, create, update, delete, delete] +- apiGroups: [networking.antrea.tanzu.vmware.com] + resources: [networkpolicies, appliedtogroups, addressgroups] + verbs: [get, watch, list, delete] +- apiGroups: [security.antrea.tanzu.vmware.com] + resources: [clusternetworkpolicies, networkpolicies] + verbs: [get, create, update, delete, list, watch, patch] +- apiGroups: [security.antrea.tanzu.vmware.com] + resources: [clusternetworkpolicies/status, networkpolicies/status] + verbs: [update] +- apiGroups: [security.antrea.tanzu.vmware.com] + resources: [tiers] + verbs: [get, watch, list, create, update] +- apiGroups: [stats.antrea.tanzu.vmware.com] + resources: [networkpolicystats, antreaclusternetworkpolicystats, antreanetworkpolicystats] + verbs: [get, list] +- apiGroups: [system.antrea.tanzu.vmware.com] + resources: [controllerinfos, agentinfos, supportbundles, supportbundles/download] + verbs: [get, watch, list, post, delete] +- apiGroups: [security.openshift.io] + resourceNames: [hostnetwork] + resources: [securitycontextconstraints] + verbs: [use] +- nonResourceURLs: + - /agentinfo + - /addressgroups + - /appliedtogroups + - /loglevel + - /networkpolicies + - /ovsflows + - /ovstracing + - /podinterfaces + verbs: + - get diff --git a/deploy/openshift/role_binding.yaml b/deploy/openshift/role_binding.yaml new file mode 100644 index 00000000..d2715669 --- /dev/null +++ b/deploy/openshift/role_binding.yaml @@ -0,0 +1,12 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: antrea-operator +subjects: +- kind: ServiceAccount + name: antrea-operator + namespace: antrea-operator +roleRef: + kind: ClusterRole + name: antrea-operator + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/openshift/service_account.yaml b/deploy/openshift/service_account.yaml new file mode 100644 index 00000000..9f00bf74 --- /dev/null +++ b/deploy/openshift/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: antrea-operator + namespace: antrea-operator diff --git a/go.mod b/go.mod index 04dde978..2bac511f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/vmware/antrea-operator-for-kubernetes go 1.13 require ( + github.com/containerd/go-cni v1.0.1 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-logr/logr v0.1.0 github.com/onsi/gomega v1.10.1 diff --git a/go.sum b/go.sum index e1cdfe28..e356b3fa 100644 --- a/go.sum +++ b/go.sum @@ -145,11 +145,15 @@ github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-cni v1.0.1 h1:VXr2EkOPD0v1gu7CKfof6XzEIDzsE/dI9yj/W7PSWLs= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE= github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -823,10 +827,12 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= @@ -1333,7 +1339,9 @@ k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+ k8s.io/kubectl v0.17.2/go.mod h1:y4rfLV0n6aPmvbRCqZQjvOp3ezxsFgpqL+zF5jH/lxk= k8s.io/kubectl v0.17.3/go.mod h1:NUn4IBY7f7yCMwSop2HCXlw/MVYP4HJBiUmOR3n9w28= k8s.io/kubectl v0.17.4/go.mod h1:im5QWmh6fvtmJkkNm4HToLe8z9aM3jihYK5X/wOybcY= +k8s.io/kubernetes v1.13.0 h1:qTfB+u5M92k2fCCCVP2iuhgwwSOv1EkAkvQY1tQODD8= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/kubernetes v1.20.4 h1:gPeOspTx01shAQuFhae+O7ZfU0WKlD7RE5L0pooU0g8= k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw= k8s.io/metrics v0.17.3/go.mod h1:HEJGy1fhHOjHggW9rMDBJBD3YuGroH3Y1pnIRw9FFaI= k8s.io/metrics v0.17.4/go.mod h1:6rylW2iD3M9VppnEAAtJASY1XS8Pt9tcYh+tHxBeV3I= diff --git a/main.go b/main.go index af004c57..48c8d191 100644 --- a/main.go +++ b/main.go @@ -71,14 +71,12 @@ func main() { setupLog.Error(err, "unable to get status manager") os.Exit(1) } - if err = (&controllers.AntreaInstallReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("AntreaInstall"), - Scheme: mgr.GetScheme(), - Status: statusManager, - Mapper: mgr.GetRESTMapper(), - SharedInfo: sharedInfo, - }).SetupWithManager(mgr); err != nil { + controller, err := controllers.New(mgr, statusManager, sharedInfo) + if err != nil { + setupLog.Error(err, "unable to get controller") + os.Exit(1) + } + if err = controller.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "AntreaInstall") os.Exit(1) }