-
Notifications
You must be signed in to change notification settings - Fork 30
Align tests and schemas #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b632bff
1ecbd41
c5335f3
dbe39dc
755da5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,8 @@ import ( | |
| "errors" | ||
| "fmt" | ||
| "net/url" | ||
| "strconv" | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/rancher/shepherd/clients/rancher" | ||
| v1 "github.com/rancher/shepherd/clients/rancher/v1" | ||
|
|
@@ -15,6 +15,7 @@ import ( | |
| "github.com/rancher/shepherd/extensions/sshkeys" | ||
| "github.com/rancher/tests/actions/clusters" | ||
| "github.com/sirupsen/logrus" | ||
| "github.com/stretchr/testify/require" | ||
| "golang.org/x/crypto/ssh" | ||
| corev1 "k8s.io/api/core/v1" | ||
| ) | ||
|
|
@@ -86,56 +87,68 @@ func VerifyNetworkPolicy(client *rancher.Client, clusterID string, namespaceName | |
| return nil | ||
| } | ||
|
|
||
| // VerifyNodePortConnectivity verifies that the node port is accessible by curling the worker node external IP | ||
| func VerifyNodePortConnectivity(client *rancher.Client, clusterID string, nodePort int, workloadName string) error { | ||
| steveClient, err := client.Steve.ProxyDownstream(clusterID) | ||
| // verifyConnectivityFromWorkerNodes verifies if any worker node in the cluster is able to access the provided ip:port | ||
| // and retrieve the expected content from name.html. | ||
| func verifyConnectivityFromWorkerNodes(client *rancher.Client, clusterID string, ip string, port int, workloadName string) error { | ||
| query, err := url.ParseQuery(clusters.LabelWorker) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| query, err := url.ParseQuery(clusters.LabelWorker) | ||
| steveClient, err := client.Steve.ProxyDownstream(clusterID) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build worker node query: %w", err) | ||
| return err | ||
| } | ||
|
|
||
| nodeList, err := steveClient.SteveType(stevetypes.Node).List(query) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to list worker nodes: %w", err) | ||
| return err | ||
| } | ||
|
|
||
| if len(nodeList.Data) == 0 { | ||
| return errors.New("no worker nodes found") | ||
| } | ||
|
|
||
| for _, machine := range nodeList.Data { | ||
| newNode := &corev1.Node{} | ||
| err = v1.ConvertToK8sType(machine.JSONResp, newNode) | ||
| sshNode, err := sshkeys.GetSSHNodeFromMachine(client, &machine) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to convert node %s: %w", machine.Name, err) | ||
| } | ||
|
|
||
| nodeIP := kubeapinodes.GetNodeIP(newNode, corev1.NodeExternalIP) | ||
| if nodeIP == "" { | ||
| nodeIP = kubeapinodes.GetNodeIP(newNode, corev1.NodeInternalIP) | ||
| logrus.Debugf("Could not SSH into worker node %s: %s", machine.Name, err.Error()) | ||
| continue | ||
| } | ||
|
|
||
| logrus.Debugf("Curling node port %d on node %s (%s)", nodePort, machine.Name, nodeIP) | ||
| execCmd := []string{"curl", fmt.Sprintf("%s:%s/name.html", nodeIP, strconv.Itoa(nodePort))} | ||
| log, err := kubectl.Command(client, nil, clusterID, execCmd, "") | ||
| if err != nil { | ||
| return fmt.Errorf("curl command failed on node %s: %w", machine.Name, err) | ||
| logrus.Debugf("Curling '%s:%d/name.html' from node %s", ip, port, machine.Name) | ||
| log, err := sshNode.ExecuteCommand(fmt.Sprintf("curl -s %s:%d/name.html", ip, port)) | ||
| if err != nil && !errors.Is(err, &ssh.ExitMissingError{}) { | ||
| logrus.Debugf("Curl failed on node %s: %v", machine.Name, err) | ||
| continue | ||
| } | ||
|
|
||
| if strings.Contains(log, workloadName) { | ||
| if strings.Contains(log, workloadName) { // This should be one of the pod's names. | ||
| return nil | ||
| } else { | ||
| logrus.Debugf("Curl result %s doesn't contain expected content '%s'", log, workloadName) | ||
| } | ||
| } | ||
|
|
||
| return fmt.Errorf("unable to access node port %d for workload %s", nodePort, workloadName) | ||
| return fmt.Errorf("Unable to connect to %s:%d/name.html from any worker node", ip, port) | ||
| } | ||
|
|
||
| // VerifyHostPortConnectivity verifies that the host port is accessible on worker nodes by SSHing directly into each node | ||
| func VerifyHostPortConnectivity(client *rancher.Client, clusterID string, hostPort int, workloadName string) error { | ||
| func verifyConnectivityFromPod(client *rancher.Client, clusterID string, ip string, port int, workloadName string) error { | ||
| execCmd := []string{"curl", "-s", fmt.Sprintf("%s:%d/name.html", ip, port)} | ||
| log, err := kubectl.Command(client, nil, clusterID, execCmd, "") | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if !strings.Contains(log, workloadName) { // This should be one of the pod's names. | ||
| return fmt.Errorf("Curl result %s doesn't include the workload name %s", log, workloadName) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // VerifyNodePortConnectivity verifies that the node port is accessible by curling the worker node external IP | ||
| func VerifyNodePortConnectivity(client *rancher.Client, clusterID string, nodePort int, workloadName string) error { | ||
| steveClient, err := client.Steve.ProxyDownstream(clusterID) | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -156,28 +169,55 @@ func VerifyHostPortConnectivity(client *rancher.Client, clusterID string, hostPo | |
| } | ||
|
|
||
| for _, machine := range nodeList.Data { | ||
| sshNode, err := sshkeys.GetSSHNodeFromMachine(client, &machine) | ||
| newNode := &corev1.Node{} | ||
| err = v1.ConvertToK8sType(machine.JSONResp, newNode) | ||
| if err != nil { | ||
| logrus.Debugf("Could not SSH into worker node %s, skipping: %v", machine.Name, err) | ||
| continue | ||
| return fmt.Errorf("failed to convert node %s: %w", machine.Name, err) | ||
| } | ||
|
|
||
| logrus.Debugf("Curling host port %d on worker node %s", hostPort, machine.Name) | ||
| output, err := sshNode.ExecuteCommand(fmt.Sprintf("curl localhost:%d/name.html", hostPort)) | ||
| if err != nil { | ||
| continue | ||
| nodeIP := kubeapinodes.GetNodeIP(newNode, corev1.NodeExternalIP) | ||
| if nodeIP == "" { | ||
| nodeIP = kubeapinodes.GetNodeIP(newNode, corev1.NodeInternalIP) | ||
| } | ||
|
|
||
| if strings.Contains(output, workloadName) { | ||
| return nil | ||
| } | ||
| logrus.Debugf("Curling node port %d on node %s (%s)", nodePort, machine.Name, nodeIP) | ||
| verifyConnectivityFromPod(client, clusterID, nodeIP, nodePort, workloadName) | ||
| } | ||
|
|
||
| return fmt.Errorf("unable to access host port %d for workload %s on any worker node", hostPort, workloadName) | ||
| return fmt.Errorf("unable to access node port %d for workload %s", nodePort, workloadName) | ||
| } | ||
|
|
||
| // VerifyLoadBalancerConnectivity verifies that the Load Balancer service is accessible by curling its IP:port. | ||
| // This includes | ||
| func VerifyLoadBalancerConnectivity(t *testing.T, client *rancher.Client, clusterID string, serviceID string, workloadName string) { | ||
| steveClient, err := client.Steve.ProxyDownstream(clusterID) | ||
| require.NoError(t, err) | ||
|
|
||
| service, err := steveClient.SteveType(stevetypes.Service).ByID(serviceID) | ||
| require.NoError(t, err) | ||
|
|
||
| k8sService := &corev1.Service{} | ||
| err = v1.ConvertToK8sType(service, k8sService) | ||
| require.NoError(t, err) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually just return the error from the action and verify it in the test. As an example: https://github.com/hamistao/tests/blob/a1642af8087366191e6d61b758e7cf7ea600028e/actions/networking/verify.go#L49
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you suggesting that I remove I decided to include this parameter here so we could have the IP and port in the logging as well, which I think is nice.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can use logrus here instead if you prefer
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't seen the |
||
| require.Equal(t, corev1.ServiceTypeLoadBalancer, k8sService.Spec.Type) | ||
| require.NotEmpty(t, k8sService.Spec.Ports) | ||
| require.NotEmpty(t, k8sService.Status.LoadBalancer.Ingress) | ||
|
|
||
| port := k8sService.Spec.Ports[0].Port | ||
| ip := k8sService.Status.LoadBalancer.Ingress[0].IP | ||
| t.Logf("Testing connectivity with load balancer %s by curling %s:%d/name.html", k8sService.Name, ip, port) | ||
|
|
||
| err = verifyConnectivityFromPod(client, clusterID, ip, int(port), workloadName) | ||
| require.NoError(t, err) | ||
| } | ||
|
|
||
| // VerifyHostPortConnectivity verifies that the host port is accessible on worker nodes by SSHing directly into each node | ||
| func VerifyHostPortConnectivity(client *rancher.Client, clusterID string, hostPort int, workloadName string) error { | ||
| return verifyConnectivityFromWorkerNodes(client, clusterID, "localhost", hostPort, workloadName) | ||
| } | ||
|
|
||
| // VerifyClusterConnectivity verifies that the ClusterIP service is accessible via SSH from a worker node | ||
| func VerifyClusterConnectivity(client *rancher.Client, clusterID string, serviceID string, path string, content string) error { | ||
| func VerifyClusterConnectivity(client *rancher.Client, clusterID string, serviceID string, port int, content string) error { | ||
| steveClient, err := client.Steve.ProxyDownstream(clusterID) | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -194,40 +234,5 @@ func VerifyClusterConnectivity(client *rancher.Client, clusterID string, service | |
| return err | ||
| } | ||
|
|
||
| clusterIP := newService.Spec.ClusterIP | ||
|
|
||
| query, err := url.ParseQuery(clusters.LabelWorker) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| nodeList, err := steveClient.SteveType(stevetypes.Node).List(query) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if len(nodeList.Data) == 0 { | ||
| return errors.New("no worker nodes found") | ||
| } | ||
|
|
||
| for _, machine := range nodeList.Data { | ||
| sshNode, err := sshkeys.GetSSHNodeFromMachine(client, &machine) | ||
| if err != nil { | ||
| logrus.Debugf("Could not SSH into worker node %s, trying next node: %v", machine.Name, err) | ||
| continue | ||
| } | ||
|
|
||
| logrus.Debugf("Curling cluster IP %s:%s from node %s", clusterIP, path, machine.Name) | ||
| log, err := sshNode.ExecuteCommand(fmt.Sprintf("curl %s:%s", clusterIP, path)) | ||
| if err != nil && !errors.Is(err, &ssh.ExitMissingError{}) { | ||
| logrus.Debugf("Curl failed on node %s: %v, trying next node", machine.Name, err) | ||
| continue | ||
| } | ||
|
|
||
| if strings.Contains(log, content) { | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| return fmt.Errorf("unable to connect to the cluster IP %s:%s from any worker node", clusterIP, path) | ||
| return verifyConnectivityFromWorkerNodes(client, clusterID, newService.Spec.ClusterIP, port, content) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| - projects: [RANCHERINT] | ||
| - projects: [ RANCHERINT ] | ||
| suite: AppCo | ||
| cases: | ||
| - title: "Install in SideCar Mode" | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.