From cf3e9a8f021c80ebbe435b91061134543b380f51 Mon Sep 17 00:00:00 2001 From: Vu Dinh Date: Thu, 10 Jan 2019 16:17:27 -0500 Subject: [PATCH] Add minimum kube version to CSV & check it against server version CSV must contain minimum kube version under spec.minKubeVersion. OLM will retrieve that info from CSV and check it against server version to determine its capability. If not compatible, OLM will not install operator(s). Signed-off-by: Vu Dinh --- pkg/controller/operators/olm/requirements.go | 97 ++++++++++---------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/pkg/controller/operators/olm/requirements.go b/pkg/controller/operators/olm/requirements.go index e70bf657046..f2e5428669c 100644 --- a/pkg/controller/operators/olm/requirements.go +++ b/pkg/controller/operators/olm/requirements.go @@ -15,10 +15,53 @@ import ( "github.com/coreos/go-semver/semver" ) +func (a *Operator) minKubeVersionStatus(minKubeVersion string) (met bool, statuses []v1alpha1.RequirementStatus) { + status := v1alpha1.RequirementStatus{ + Group: "operators.coreos.com", + Version: "v1alpha1", + Kind: "ClusterServiceVersion", + Name: csv.Spec.DisplayName, + } + + // Retrieve server k8s version + serverVersionInfo, err := a.client.Discovery().ServerVersion() + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "Server version discovery error" + met = false + statuses = append(statuses, status) + a.Log.Debugf("Unable to get server k8s version: %v", serverVersionInfo) + } + + // copy necessary fields into comparable for semver + majorInt, err := strconv.ParseInt(serverVersionInfo.Major, 10, 64) + minorInt, err := strconv.ParseInt(serverVersionInfo.Minor, 10, 64) + + serverVersionComparable := semver.Version{ + Major: majorInt, + Minor: minorInt, + } + + csvVersionInfo, err := semver.NewVersion(minKubeVersion) + if err != nil { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "CSV version parsing error" + met = false + statuses = append(statuses, status) + a.Log.Debugf("Unable to parse CSV k8s version: %v", csvVersionInfo) + } + + if csvVersionInfo.Compare(serverVersionComparable) < 0 { + status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied + status.Message = "CSV version requirement not met" + met = false + statuses = append(statuses, status) + } +} + func (a *Operator) requirementStatus(strategyDetailsDeployment *install.StrategyDetailsDeployment, crdDescs []v1alpha1.CRDDescription, ownedAPIServiceDescs []v1alpha1.APIServiceDescription, requiredAPIServiceDescs []v1alpha1.APIServiceDescription, - requiredNativeAPIs []metav1.GroupVersionKind, - minKubeVersion string) (met bool, statuses []v1alpha1.RequirementStatus) { + requiredNativeAPIs []metav1.GroupVersionKind) (met bool, statuses []v1alpha1.RequirementStatus) (met bool, statuses []v1alpha1.RequirementStatus) { met = true // Check for CRDs @@ -180,49 +223,6 @@ func (a *Operator) requirementStatus(strategyDetailsDeployment *install.Strategy } } - status := v1alpha1.RequirementStatus{ - Group: "apiextensions.k8s.io", - Version: "v1beta1", - Kind: "CustomResourceDefinition", - // TODO: refactor? - Name: "TODO: csv name, needs refactoring to get name", - } - - serverVersionInfo, err := a.client.Discovery().ServerVersion() - if err != nil { - // TODO: this status may be wrong - status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied - status.Message = "Server version discovery error" - met = false - statuses = append(statuses, status) - } - - // copy necessary fields into comparable for semver - majorInt, err := strconv.ParseInt(serverVersionInfo.Major, 10, 64) - minorInt, err := strconv.ParseInt(serverVersionInfo.Minor, 10, 64) - - serverVersionComparable := semver.Version{ - Major: majorInt, - Minor: minorInt, - } - - csvVersionInfo, err := semver.NewVersion(minKubeVersion) - if err != nil { - // TODO: this status may be wrong - status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied - status.Message = "CSV version parsing error" - met = false - statuses = append(statuses, status) - } - - if csvVersionInfo.Compare(serverVersionComparable) < 0 { - // TODO: this status may be wrong - status.Status = v1alpha1.RequirementStatusReasonPresentNotSatisfied - status.Message = "CSV version requirement not met" - met = false - statuses = append(statuses, status) - } - return } @@ -338,7 +338,10 @@ func (a *Operator) requirementAndPermissionStatus(csv *v1alpha1.ClusterServiceVe return false, nil, fmt.Errorf("could not cast install strategy as type %T", strategyDetailsDeployment) } - reqMet, reqStatuses := a.requirementStatus(strategyDetailsDeployment, csv.GetAllCRDDescriptions(), csv.GetOwnedAPIServiceDescriptions(), csv.GetRequiredAPIServiceDescriptions(), csv.Spec.NativeAPIs, csv.Spec.MinKubeVersion) + // Check kubernetes version requirement between CSV and server + minKubeMet, minKubeStatus := a.minKubeVersionStatus(csv.Spec.minKubeVersion) + reqMet, reqStatuses = a.requirementStatus(strategyDetailsDeployment, csv.GetAllCRDDescriptions(), csv.GetOwnedAPIServiceDescriptions(), csv.GetRequiredAPIServiceDescriptions(), csv.Spec.NativeAPIs) + reqStatuses = append(minKubeStatus, reqStatuses) rbacLister := a.lister.RbacV1() roleLister := rbacLister.RoleLister() @@ -354,7 +357,7 @@ func (a *Operator) requirementAndPermissionStatus(csv *v1alpha1.ClusterServiceVe // Aggregate requirement and permissions statuses statuses := append(reqStatuses, permStatuses...) - met := reqMet && permMet + met := minKubeMet && reqMet && permMet if !met { a.Log.WithField("reqMet", reqMet).WithField("permMet", permMet).Debug("permissions not met") }