mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Merge pull request #108432 from iXinqi/add-write-file-test
Add gMSA Reading and Writing Files Test Case
This commit is contained in:
commit
0b3629ae7d
@ -32,6 +32,8 @@ limitations under the License.
|
|||||||
// * the cluster comprises at least one Linux node that accepts workloads - it
|
// * the cluster comprises at least one Linux node that accepts workloads - it
|
||||||
// can be the master, but any other Linux node is fine too. This is needed for
|
// can be the master, but any other Linux node is fine too. This is needed for
|
||||||
// the webhook's pod.
|
// the webhook's pod.
|
||||||
|
// * in order to run "can read and write file to remote folder" test case, a folder (e.g. "write_test") need to be created
|
||||||
|
// in that AD domain and it should be shared with that GMSA account.
|
||||||
// All these assumptions are fulfilled by an AKS extension when setting up the AKS
|
// All these assumptions are fulfilled by an AKS extension when setting up the AKS
|
||||||
// cluster we run daily e2e tests against, but they do make running this test
|
// cluster we run daily e2e tests against, but they do make running this test
|
||||||
// outside of that very specific context pretty hard.
|
// outside of that very specific context pretty hard.
|
||||||
@ -44,12 +46,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
|
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
|
||||||
@ -81,6 +85,9 @@ const (
|
|||||||
|
|
||||||
// The name of the expected domain
|
// The name of the expected domain
|
||||||
gmsaDomain = "k8sgmsa.lan"
|
gmsaDomain = "k8sgmsa.lan"
|
||||||
|
|
||||||
|
// The shared folder on the expected domain for file-writing test
|
||||||
|
gmsaSharedFolder = "write_test"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = SIGDescribe("[Feature:Windows] GMSA Full [Serial] [Slow]", func() {
|
var _ = SIGDescribe("[Feature:Windows] GMSA Full [Serial] [Slow]", func() {
|
||||||
@ -163,6 +170,73 @@ var _ = SIGDescribe("[Feature:Windows] GMSA Full [Serial] [Slow]", func() {
|
|||||||
return true
|
return true
|
||||||
}, 1*time.Minute, 1*time.Second).Should(gomega.BeTrue())
|
}, 1*time.Minute, 1*time.Second).Should(gomega.BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ginkgo.It("can read and write file to remote SMB folder", func() {
|
||||||
|
defer ginkgo.GinkgoRecover()
|
||||||
|
|
||||||
|
ginkgo.By("finding the worker node that fulfills this test's assumptions")
|
||||||
|
nodes := findPreconfiguredGmsaNodes(f.ClientSet)
|
||||||
|
if len(nodes) != 1 {
|
||||||
|
e2eskipper.Skipf("Expected to find exactly one node with the %q label, found %d", gmsaFullNodeLabel, len(nodes))
|
||||||
|
}
|
||||||
|
node := nodes[0]
|
||||||
|
|
||||||
|
ginkgo.By("retrieving the contents of the GMSACredentialSpec custom resource manifest from the node")
|
||||||
|
crdManifestContents := retrieveCRDManifestFileContents(f, node)
|
||||||
|
|
||||||
|
ginkgo.By("downloading the GMSA webhook deploy script")
|
||||||
|
deployScriptPath, err := downloadFile(gmsaWebhookDeployScriptURL)
|
||||||
|
defer func() { os.Remove(deployScriptPath) }()
|
||||||
|
if err != nil {
|
||||||
|
framework.Failf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("deploying the GMSA webhook")
|
||||||
|
webhookCleanUp, err := deployGmsaWebhook(f, deployScriptPath)
|
||||||
|
defer webhookCleanUp()
|
||||||
|
if err != nil {
|
||||||
|
framework.Failf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("creating the GMSA custom resource")
|
||||||
|
customResourceCleanup, err := createGmsaCustomResource(f.Namespace.Name, crdManifestContents)
|
||||||
|
defer customResourceCleanup()
|
||||||
|
if err != nil {
|
||||||
|
framework.Failf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("creating an RBAC role to grant use access to that GMSA resource")
|
||||||
|
rbacRoleName, rbacRoleCleanup, err := createRBACRoleForGmsa(f)
|
||||||
|
defer rbacRoleCleanup()
|
||||||
|
if err != nil {
|
||||||
|
framework.Failf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ginkgo.By("creating a service account")
|
||||||
|
serviceAccountName := createServiceAccount(f)
|
||||||
|
|
||||||
|
ginkgo.By("binding the RBAC role to the service account")
|
||||||
|
bindRBACRoleToServiceAccount(f, serviceAccountName, rbacRoleName)
|
||||||
|
|
||||||
|
ginkgo.By("creating a pod using the GMSA cred spec")
|
||||||
|
podName := createPodWithGmsa(f, serviceAccountName)
|
||||||
|
|
||||||
|
ginkgo.By("getting the ip of GMSA domain")
|
||||||
|
gmsaDomainIP := getGmsaDomainIP(f, podName)
|
||||||
|
|
||||||
|
ginkgo.By("checking that file can be read and write from the remote folder successfully")
|
||||||
|
filePath := fmt.Sprintf("\\\\%s\\%s\\write-test-%s.txt", gmsaDomainIP, gmsaSharedFolder, string(uuid.NewUUID())[0:4])
|
||||||
|
gomega.Eventually(func() bool {
|
||||||
|
// The filePath is a remote folder, do not change the format of it
|
||||||
|
_, _ = runKubectlExecInNamespace(f.Namespace.Name, podName, "--", "powershell.exe", "-Command", "echo 'This is a test file.' > "+filePath)
|
||||||
|
output, err := runKubectlExecInNamespace(f.Namespace.Name, podName, "powershell.exe", "--", "cat", filePath)
|
||||||
|
if err != nil {
|
||||||
|
framework.Logf("unable to get file from AD server: %s", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains(output, "This is a test file.")
|
||||||
|
}, 1*time.Minute, 1*time.Second).Should(gomega.BeTrue())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -420,3 +494,16 @@ func runKubectlExecInNamespace(namespace string, args ...string) (string, error)
|
|||||||
namespaceOption := fmt.Sprintf("--namespace=%s", namespace)
|
namespaceOption := fmt.Sprintf("--namespace=%s", namespace)
|
||||||
return framework.RunKubectl(namespace, append([]string{"exec", namespaceOption}, args...)...)
|
return framework.RunKubectl(namespace, append([]string{"exec", namespaceOption}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGmsaDomainIP(f *framework.Framework, podName string) string {
|
||||||
|
output, _ := runKubectlExecInNamespace(f.Namespace.Name, podName, "powershell.exe", "--", "nslookup", gmsaDomain)
|
||||||
|
re := regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`)
|
||||||
|
idx := strings.Index(output, gmsaDomain)
|
||||||
|
|
||||||
|
submatchall := re.FindAllString(output[idx:], -1)
|
||||||
|
if len(submatchall) < 1 {
|
||||||
|
framework.Logf("fail to get the ip of the gmsa domain")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return submatchall[0]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user