diff --git a/cluster/validation.go b/cluster/validation.go index 2c8705d4..1a6ed93b 100644 --- a/cluster/validation.go +++ b/cluster/validation.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/blang/semver" + "github.com/rancher/rke/k8s" "github.com/rancher/rke/log" "github.com/rancher/rke/metadata" "github.com/rancher/rke/pki" @@ -674,6 +675,30 @@ func validatePodSecurityPolicy(c *Cluster) error { return errors.New("PodSecurityPolicy has been removed and can not be enabled since k8s v1.25") } } + // check if there is any PSP resource when upgrading a cluster to k8s v1.25 and above + if parsedRangeAtLeast125(parsedVersion) { + kubeClient, err := k8s.NewClient(c.LocalKubeConfigPath, c.K8sWrapTransport) + if err != nil { + // we can not tell this is invoked when creating a new cluster or updating an existing one, so skip this check + logrus.Debugf("Skip the check for PSP resource due to the failure of initializing the kubernetes client") + return nil + } + pspList, _ := k8s.GetPSPList(kubeClient) + // ignore the error because the "no such resource type" error is definitely returned in k8s v1.25 and above + items := pspList.Items + if len(items) == 0 { + return nil + } + // a PSP "psp.flannel.unprivileged" from old Flannel templates is created when using Flannel as the network plugin + // we should ignore it if it is the only PSP in the cluster + if len(items) == 1 && items[0].Name == "psp.flannel.unprivileged" && c.Network.Plugin == FlannelNetworkPlugin { + return nil + } + msg := fmt.Sprintf("PodSecurityPolicy(PSP) resource is detected in the cluster, "+ + "please remove them before upgrading the cluster version to %s", c.Version) + return errors.New(msg) + } + return nil } diff --git a/k8s/psp.go b/k8s/psp.go index 64afd643..444beacf 100644 --- a/k8s/psp.go +++ b/k8s/psp.go @@ -30,3 +30,9 @@ func updatePodSecurityPolicy(k8sClient *kubernetes.Clientset, p interface{}) err return nil } + +// GetPSPList returns the PodSecurityPolicyList containing all PSPs in the cluster and an error. +// The list could be empty if there is no PSP in the cluster. +func GetPSPList(k8sClient *kubernetes.Clientset) (*v1beta1.PodSecurityPolicyList, error) { + return k8sClient.PolicyV1beta1().PodSecurityPolicies().List(context.TODO(), metav1.ListOptions{}) +} diff --git a/types/kdm/zz_generated_deepcopy.go b/types/kdm/zz_generated_deepcopy.go index 555d5d0d..313fbacf 100644 --- a/types/kdm/zz_generated_deepcopy.go +++ b/types/kdm/zz_generated_deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2022 Rancher Labs, Inc. +Copyright 2023 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/types/rke_types.go b/types/rke_types.go index ce774b36..a5ae114b 100644 --- a/types/rke_types.go +++ b/types/rke_types.go @@ -296,7 +296,7 @@ type KubeAPIService struct { // Enabled/Disable PodSecurityPolicy PodSecurityPolicy bool `yaml:"pod_security_policy" json:"podSecurityPolicy,omitempty"` // setting the default configuration for PodSecurityAdmission - PodSecurityConfiguration string `yaml:"pod_security_configuration" json:"podSecurityConfiguration,omitempty" norman:"default=privileged"` + PodSecurityConfiguration string `yaml:"pod_security_configuration" json:"podSecurityConfiguration,omitempty"` // Enable/Disable AlwaysPullImages admissions plugin AlwaysPullImages bool `yaml:"always_pull_images" json:"alwaysPullImages,omitempty"` // Secrets encryption provider config diff --git a/types/zz_generated_deepcopy.go b/types/zz_generated_deepcopy.go index e3fd9b53..616215a5 100644 --- a/types/zz_generated_deepcopy.go +++ b/types/zz_generated_deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2022 Rancher Labs, Inc. +Copyright 2023 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.