Skip to content

Commit

Permalink
Skip k8s version check for Trident install
Browse files Browse the repository at this point in the history
* For tridentctl: ./tridentctl install --skip-k8s-version-check=True
* For torc: Add the following below the debug flag in bundle.yaml: --skip-k8s-version-check=True
* For helm: helm install trident trident-operator-21.04.0-custom.tgz --set tridentSkipK8sVersionCheck=true
  • Loading branch information
nazneeninc authored Mar 30, 2021
1 parent 503e040 commit ce3d442
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 89 deletions.
22 changes: 21 additions & 1 deletion cli/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ var (
useIPv6 bool
silenceAutosupport bool
enableNodePrep bool
skipK8sVersionCheck bool
pvName string
pvcName string
tridentImage string
Expand Down Expand Up @@ -129,6 +130,7 @@ func init() {
installCmd.Flags().BoolVar(&useYAML, "use-custom-yaml", false, "Use any existing YAML files that exist in setup directory.")
installCmd.Flags().BoolVar(&silent, "silent", false, "Disable most output during installation.")
installCmd.Flags().BoolVar(&csi, "csi", false, "Install CSI Trident (override for Kubernetes 1.13 only, requires feature gates).")
installCmd.Flags().BoolVar(&skipK8sVersionCheck, "skip-k8s-version-check", false, "Skip k8s version check for Trident compatibility")
installCmd.Flags().BoolVar(&inCluster, "in-cluster", false, "Run the installer as a pod in the cluster.")
installCmd.Flags().BoolVar(&useIPv6, "use-ipv6", false, "Use IPv6 for Trident's communication.")
installCmd.Flags().BoolVar(&silenceAutosupport, "silence-autosupport", tridentconfig.BuildType != "stable", "Don't send autosupport bundles to NetApp automatically.")
Expand All @@ -152,6 +154,9 @@ func init() {
if err := installCmd.Flags().MarkHidden("in-cluster"); err != nil {
fmt.Fprintln(os.Stderr, err)
}
if err := installCmd.Flags().MarkHidden("skip-k8s-version-check"); err != nil {
fmt.Fprintln(os.Stderr, err)
}
if err := installCmd.Flags().MarkHidden("autosupport-custom-url"); err != nil {
fmt.Fprintln(os.Stderr, err)
}
Expand Down Expand Up @@ -268,6 +273,21 @@ func discoverInstallationEnvironment() error {
return fmt.Errorf("could not initialize Kubernetes client; %v", err)
}

// Before the installation ensure K8s version is valid
err = tridentconfig.ValidateKubernetesVersion(tridentconfig.KubernetesVersionMin, client.ServerVersion())
if !skipK8sVersionCheck {
if err != nil {
log.Errorf("Kubernetes version '%s' is unsupported; err: %v", client.ServerVersion().String(), err)
return err
}
} else if err != nil && utils.IsUnsupportedKubernetesVersionError(err) {
log.Warningf("Trident is running on an unsupported Kubernetes version. Skipping the Kubernetes version "+
"check is not recommended for production environments: %v", client.ServerVersion().String())
} else {
log.Warningf("Skipping the Kubernetes version check is not recommended for production environments; "+
"Kubernetes version: %v", client.ServerVersion().String())
}

// Prepare input file paths
if err = prepareYAMLFilePaths(); err != nil {
return err
Expand All @@ -290,7 +310,7 @@ func discoverInstallationEnvironment() error {

log.WithFields(log.Fields{
"installationNamespace": TridentPodNamespace,
"kubernetesVersion": client.Version().String(),
"kubernetesVersion": client.ServerVersion().String(),
}).Debug("Validated installation environment.")

return nil
Expand Down
17 changes: 3 additions & 14 deletions cli/k8s_client/k8s_cli_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/tools/clientcmd"

tridentconfig "github.com/netapp/trident/config"
crdclient "github.com/netapp/trident/persistent_store/crd/client/clientset/versioned"
"github.com/netapp/trident/utils"
)
Expand Down Expand Up @@ -96,16 +95,6 @@ func NewKubectlClient(namespace string, k8sTimeout time.Duration) (Interface, er
return nil, err
}

k8sMMVersion := k8sVersion.ToMajorMinorVersion()
minSupportedMMVersion := utils.MustParseSemantic(tridentconfig.KubernetesVersionMin).ToMajorMinorVersion()
maxSupportedMMVersion := utils.MustParseSemantic(tridentconfig.KubernetesVersionMax).ToMajorMinorVersion()

if k8sMMVersion.LessThan(minSupportedMMVersion) || k8sMMVersion.GreaterThan(maxSupportedMMVersion) {
return nil, fmt.Errorf("%s %s supports Kubernetes versions in the range [%s, %s]",
strings.Title(tridentconfig.OrchestratorName), tridentconfig.OrchestratorVersion.ShortString(),
minSupportedMMVersion.ToMajorMinorString(), maxSupportedMMVersion.ToMajorMinorString())
}

client := &KubectlClient{
cli: cli,
flavor: flavor,
Expand All @@ -123,9 +112,9 @@ func NewKubectlClient(namespace string, k8sTimeout time.Duration) (Interface, er
}

log.WithFields(log.Fields{
"cli": cli,
"flavor": flavor,
"version": k8sVersion.String(),
"cli": client.cli,
"flavor": client.flavor,
"version": client.ServerVersion().String(),
"timeout": client.timeout,
"namespace": client.namespace,
}).Debug("Initialized Kubernetes CLI client.")
Expand Down
8 changes: 4 additions & 4 deletions cli/k8s_client/k8s_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ func NewKubeClient(config *rest.Config, namespace string, k8sTimeout time.Durati
log.WithFields(log.Fields{
"cli": kubeClient.cli,
"flavor": kubeClient.flavor,
"version": versionInfo.String(),
"version": kubeClient.Version().String(),
"timeout": kubeClient.timeout,
"namespace": namespace,
"namespace": kubeClient.namespace,
}).Debug("Initialized Kubernetes API client.")

return kubeClient, nil
Expand Down Expand Up @@ -2647,7 +2647,7 @@ func (k *KubeClient) addFinalizerToCRDObject(crdName string, gvk *schema.GroupVe
var err error

log.WithFields(log.Fields{
"CRD": crdName,
"CRD": crdName,
"kind": gvk.Kind,
}).Debugf("Adding finalizers to CRD.")

Expand Down Expand Up @@ -2759,7 +2759,7 @@ func (k *KubeClient) AddFinalizerToCRD(crdName string) error {
}

log.WithFields(log.Fields{
"CRD": crdName,
"CRD": crdName,
"kind": gvk.Kind,
}).Debugf("Adding finalizers to CRD.")

Expand Down
80 changes: 69 additions & 11 deletions cli/k8s_client/yaml_factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ package k8sclient

import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"

"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"

"github.com/netapp/trident/utils"
)

const (
Expand Down Expand Up @@ -84,16 +86,15 @@ func TestYAMLFactory(t *testing.T) {
// TestAPIVersion validates that we get correct APIVersion value
func TestAPIVersion(t *testing.T) {

yamlsOutputs := map[string]string {
GetClusterRoleYAML(FlavorK8s, Name, nil, nil, false): "rbac.authorization.k8s.io/v1",
GetClusterRoleYAML(FlavorK8s, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
GetClusterRoleYAML(FlavorOpenshift, Name, nil, nil, false): "authorization.openshift.io/v1",
GetClusterRoleYAML(FlavorOpenshift, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorK8s, Name, nil, nil, false):"rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorK8s, Name, nil, nil, true):"rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorOpenshift, Name, nil, nil, false):"authorization.openshift.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorOpenshift, Name, nil, nil, true):"rbac.authorization.k8s.io/v1",

yamlsOutputs := map[string]string{
GetClusterRoleYAML(FlavorK8s, Name, nil, nil, false): "rbac.authorization.k8s.io/v1",
GetClusterRoleYAML(FlavorK8s, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
GetClusterRoleYAML(FlavorOpenshift, Name, nil, nil, false): "authorization.openshift.io/v1",
GetClusterRoleYAML(FlavorOpenshift, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorK8s, Name, nil, nil, false): "rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorK8s, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorOpenshift, Name, nil, nil, false): "authorization.openshift.io/v1",
GetClusterRoleBindingYAML(Namespace, FlavorOpenshift, Name, nil, nil, true): "rbac.authorization.k8s.io/v1",
}

for result, value := range yamlsOutputs {
Expand All @@ -112,3 +113,60 @@ func TestGetRegistryVal(t *testing.T) {
assert.Exactly(t, "registry.barnacle.netapp.com/foo/bar",
getRegistryVal("registry.barnacle.netapp.com/foo/bar", true))
}

// Simple validation of the CSI Deployment YAML
func TestValidateGetCSIDeploymentYAMLSuccess(t *testing.T) {

labels := make(map[string]string)
labels["app"] = "trident"

ownerRef := make(map[string]string)
ownerRef["uid"] = "123456789"
ownerRef["kind"] = "TridentProvisioner"

imagePullSecrets := []string{"thisisasecret"}

version := utils.MustParseSemantic("1.17.0")

yamlsOutputs := []string{
GetCSIDeploymentYAML("trident-csi", "netapp/trident:20.10.0-custom", "netapp/trident-autosupport:20.10.0-custom",
"http://127.0.0.1/", "http://172.16.150.125:8888/", "0000-0000", "21e160d3-721f-4ec4-bcd4-c5e0d31d1a6e",
"k8s.gcr.io", "text", imagePullSecrets, labels, nil, true, true, false, version, true),
}
for i, yamlData := range yamlsOutputs {

_, err := yaml.YAMLToJSON([]byte(yamlData))
if err != nil {
t.Fatalf("expected constant %v to be valid YAML", i)
}
}
}

// Simple validation of the CSI Deployment YAML
func TestValidateGetCSIDeploymentYAMLFail(t *testing.T) {

labels := make(map[string]string)
labels["app"] = "trident"

ownerRef := make(map[string]string)
ownerRef["uid"] = "123456789"
ownerRef["kind"] = "TridentProvisioner"

imagePullSecrets := []string{"thisisasecret"}

version := utils.MustParseSemantic("1.17.0")

yamlsOutputs := []string{
GetCSIDeploymentYAML("\ntrident-csi", "netapp/trident:20.10.0-custom", "netapp/trident-autosupport:20.10.0-custom",
"http://127.0.0.1/", "http://172.16.150.125:8888/", "0000-0000", "21e160d3-721f-4ec4-bcd4-c5e0d31d1a6e",
"k8s.gcr.io", "text", imagePullSecrets, labels, nil, true, true, false, version, true),
}

for i, yamlData := range yamlsOutputs {

_, err := yaml.YAMLToJSON([]byte(yamlData))
if err == nil {
t.Fatalf("expected constant %v to be invalid YAML", i)
}
}
}
27 changes: 27 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

log "github.com/sirupsen/logrus"
k8sversion "k8s.io/apimachinery/pkg/version"

"github.com/netapp/trident/utils"
)
Expand Down Expand Up @@ -233,3 +234,29 @@ func version() string {

return version
}

func ValidateKubernetesVersion(k8sMinVersion string, k8sVersion *utils.Version) error {

k8sMMVersion := k8sVersion.ToMajorMinorVersion()
minSupportedMMVersion := utils.MustParseSemantic(k8sMinVersion).ToMajorMinorVersion()
maxSupportedMMVersion := utils.MustParseSemantic(KubernetesVersionMax).ToMajorMinorVersion()

if k8sMMVersion.LessThan(minSupportedMMVersion) || k8sMMVersion.GreaterThan(maxSupportedMMVersion) {
return utils.UnsupportedKubernetesVersionError(
fmt.Errorf("trident supports k8s versions in the range [%s, %s]",
minSupportedMMVersion.ToMajorMinorString(), maxSupportedMMVersion.ToMajorMinorString()))
}

return nil
}

func ValidateKubernetesVersionFromInfo(k8sMinVersion string, versionInfo *k8sversion.Info) error {

k8sVersion, err := utils.ParseSemantic(versionInfo.GitVersion)
if err != nil {
return err
}

return ValidateKubernetesVersion(k8sMinVersion, k8sVersion)

}
11 changes: 11 additions & 0 deletions helm/trident-operator/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,14 @@ Trident EnableNodePrep
{{- "false" }}
{{- end }}
{{- end }}

{{/*
Trident SkipK8sVersionCheck
*/}}
{{- define "trident.skipK8sVersionCheck" -}}
{{- if .Values.tridentSkipK8sVersionCheck | printf "%v" | eq "true" }}
{{- "true" }}
{{- else }}
{{- "false" }}
{{- end }}
{{- end }}
1 change: 1 addition & 0 deletions helm/trident-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ spec:
- command:
- /trident-operator
- --debug={{ include "trident-operator.debug" $ }}
- --skip-k8s-version-check={{ include "trident.skipK8sVersionCheck" $ }}
env:
- name: POD_NAME
valueFrom:
Expand Down
3 changes: 3 additions & 0 deletions helm/trident-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ tridentImageTag: ""

# tridentEnableNodePrep attempts to automatically install required packages on nodes
tridentEnableNodePrep: false

# tridentSkipK8sVersionCheck allows overriding the k8s version limit for Trident.
tridentSkipK8sVersionCheck: false
29 changes: 0 additions & 29 deletions operator/clients/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@ package clients
import (
"fmt"
"io/ioutil"
"strings"
"time"

k8sclient "github.com/netapp/trident/cli/k8s_client"
commonconfig "github.com/netapp/trident/config"
tridentutils "github.com/netapp/trident/utils"
log "github.com/sirupsen/logrus"
k8sversion "k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

operatorconfig "github.com/netapp/trident/operator/config"
"github.com/netapp/trident/operator/controllers/orchestrator/client/clientset/versioned"
versionedTprov "github.com/netapp/trident/operator/controllers/provisioner/client/clientset/versioned"
)
Expand Down Expand Up @@ -76,11 +73,6 @@ func CreateK8SClients(apiServerIP, kubeConfigPath string) (*Clients, error) {
return nil, fmt.Errorf("could not get Kubernetes version: %v", err)
}

// Validate the Kubernetes server version
if err := ValidateKubernetesVersion(clients.K8SVersion); err != nil {
return nil, err
}

log.WithFields(log.Fields{
"namespace": clients.Namespace,
"version": clients.K8SVersion.String(),
Expand Down Expand Up @@ -152,24 +144,3 @@ func createK8SClientsInCluster() (*Clients, error) {
Namespace: namespace,
}, nil
}

func ValidateKubernetesVersion(versionInfo *k8sversion.Info) error {

k8sVersion, err := tridentutils.ParseSemantic(versionInfo.GitVersion)
if err != nil {
return err
}

k8sMMVersion := k8sVersion.ToMajorMinorVersion()
minSupportedMMVersion := tridentutils.MustParseSemantic(commonconfig.KubernetesCSIVersionMinForced).ToMajorMinorVersion()
maxSupportedMMVersion := tridentutils.MustParseSemantic(commonconfig.KubernetesVersionMax).ToMajorMinorVersion()

if k8sMMVersion.LessThan(minSupportedMMVersion) || k8sMMVersion.GreaterThan(maxSupportedMMVersion) {
return tridentutils.UnsupportedKubernetesVersionError(
fmt.Errorf("%s %s supports Kubernetes versions in the range [%s, %s]",
strings.Title(operatorconfig.OperatorName), operatorconfig.OperatorVersion.ShortString(),
minSupportedMMVersion.ToMajorMinorString(), maxSupportedMMVersion.ToMajorMinorString()))
}

return nil
}
Loading

0 comments on commit ce3d442

Please sign in to comment.