-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
🏃[e2e] clusterctl e2e discovery #2820
Changes from all commits
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 |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// +build e2e | ||
|
||
/* | ||
Copyright 2020 The Kubernetes Authors. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package discovery | ||
|
||
import ( | ||
"context" | ||
|
||
. "github.com/onsi/gomega" | ||
|
||
appsv1 "k8s.io/api/apps/v1" | ||
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" | ||
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3" | ||
"sigs.k8s.io/cluster-api/test/framework" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
// Provides methods for discovering Cluster API objects existing in the management cluster. | ||
|
||
// GetControllerDeploymentsInput is the input for GetControllerDeployments. | ||
type GetControllerDeploymentsInput struct { | ||
Lister framework.Lister | ||
} | ||
|
||
// GetControllerDeployments returns all the deployment for the cluster API controllers existing in a management cluster. | ||
func GetControllerDeployments(ctx context.Context, input GetControllerDeploymentsInput) []*appsv1.Deployment { | ||
deploymentList := &appsv1.DeploymentList{} | ||
Expect(input.Lister.List(ctx, deploymentList, capiProviderOptions()...)).To(Succeed(), "Failed to list deployments for the cluster API controllers") | ||
|
||
deployments := make([]*appsv1.Deployment, len(deploymentList.Items)) | ||
for i := range deploymentList.Items { | ||
deployments[i] = &deploymentList.Items[i] | ||
} | ||
return deployments | ||
} | ||
|
||
// GetClusterByNameInput is the input for GetClusterByName. | ||
type GetClusterByNameInput struct { | ||
Getter framework.Getter | ||
Name string | ||
Namespace string | ||
} | ||
|
||
// GetClusterByName returns a Cluster object given his name | ||
func GetClusterByName(ctx context.Context, input GetClusterByNameInput) *clusterv1.Cluster { | ||
cluster := &clusterv1.Cluster{} | ||
key := client.ObjectKey{ | ||
Namespace: input.Namespace, | ||
Name: input.Name, | ||
} | ||
Expect(input.Getter.Get(ctx, key, cluster)).To(Succeed(), "Failed to get Cluster object %s/%s", input.Namespace, input.Name) | ||
return cluster | ||
} | ||
|
||
// GetKubeadmControlPlaneByClusterInput is the input for GetKubeadmControlPlaneByCluster. | ||
type GetKubeadmControlPlaneByClusterInput struct { | ||
Lister framework.Lister | ||
ClusterName string | ||
Namespace string | ||
} | ||
|
||
// GetKubeadmControlPlaneByCluster returns the KubeadmControlPlane objects for a cluster. | ||
// Important! this method relies on labels that are created by the CAPI controllers during the first reconciliation, so | ||
// it is necessary to ensure this is already happened before calling it. | ||
func GetKubeadmControlPlaneByCluster(ctx context.Context, input GetKubeadmControlPlaneByClusterInput) *controlplanev1.KubeadmControlPlane { | ||
controlPlaneList := &controlplanev1.KubeadmControlPlaneList{} | ||
Expect(input.Lister.List(ctx, controlPlaneList, byClusterOptions(input.ClusterName, input.Namespace)...)).To(Succeed(), "Failed to list KubeadmControlPlane object for Cluster %s/%s", input.Namespace, input.ClusterName) | ||
Expect(len(controlPlaneList.Items)).ToNot(BeNumerically(">", 1), "Cluster %s/%s should not have more than 1 KubeadmControlPlane object", input.Namespace, input.ClusterName) | ||
if len(controlPlaneList.Items) == 1 { | ||
return &controlPlaneList.Items[0] | ||
} | ||
return nil | ||
} | ||
|
||
// GetMachineDeploymentsByClusterInput is the input for GetMachineDeploymentsByCluster. | ||
type GetMachineDeploymentsByClusterInput struct { | ||
Lister framework.Lister | ||
ClusterName string | ||
Namespace string | ||
} | ||
|
||
// GetMachineDeploymentsByCluster returns the MachineDeployments objects for a cluster. | ||
// Important! this method relies on labels that are created by the CAPI controllers during the first reconciliation, so | ||
// it is necessary to ensure this is already happened before calling it. | ||
func GetMachineDeploymentsByCluster(ctx context.Context, input GetMachineDeploymentsByClusterInput) []*clusterv1.MachineDeployment { | ||
deploymentList := &clusterv1.MachineDeploymentList{} | ||
Expect(input.Lister.List(ctx, deploymentList, byClusterOptions(input.ClusterName, input.Namespace)...)).To(Succeed(), "Failed to list MachineDeployments object for Cluster %s/%s", input.Namespace, input.ClusterName) | ||
|
||
deployments := make([]*clusterv1.MachineDeployment, len(deploymentList.Items)) | ||
for i := range deploymentList.Items { | ||
deployments[i] = &deploymentList.Items[i] | ||
} | ||
return deployments | ||
} | ||
|
||
// capiProviderOptions returns a set of ListOptions that allows to identify all the objects belonging to Cluster API providers. | ||
func capiProviderOptions() []client.ListOption { | ||
return []client.ListOption{ | ||
client.HasLabels{clusterv1.ProviderLabelName}, | ||
} | ||
} | ||
|
||
// byClusterOptions returns a set of ListOptions that allows to identify all the objects belonging to a Cluster. | ||
func byClusterOptions(name, namespace string) []client.ListOption { | ||
return []client.ListOption{ | ||
client.InNamespace(namespace), | ||
client.MatchingLabels{ | ||
clusterv1.ClusterLabelName: name, | ||
}, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ import ( | |
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
appsv1 "k8s.io/api/apps/v1" | ||
corev1 "k8s.io/api/core/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
"k8s.io/apimachinery/pkg/runtime" | ||
"sigs.k8s.io/cluster-api/test/framework/management/kind" | ||
|
@@ -125,3 +128,33 @@ func InitManagementCluster(ctx context.Context, input *InitManagementClusterInpu | |
|
||
return managementCluster | ||
} | ||
|
||
// WaitForDeploymentsAvailableInput is the input for WaitForDeploymentsAvailable. | ||
type WaitForDeploymentsAvailableInput struct { | ||
Getter Getter | ||
Deployment *appsv1.Deployment | ||
} | ||
|
||
// WaitForDeploymentsAvailable waits until the Deployment has status.Available = True, that signals that | ||
// all the desired replicas are in place. | ||
// This can be used to check if Cluster API controllers installed in the management cluster are working. | ||
func WaitForDeploymentsAvailable(ctx context.Context, input WaitForDeploymentsAvailableInput, intervals ...interface{}) { | ||
By(fmt.Sprintf("waiting for deployment %s/%s to be available", input.Deployment.GetNamespace(), input.Deployment.GetName())) | ||
Eventually(func() bool { | ||
deployment := &appsv1.Deployment{} | ||
key := client.ObjectKey{ | ||
Namespace: input.Deployment.GetNamespace(), | ||
Name: input.Deployment.GetName(), | ||
} | ||
if err := input.Getter.Get(ctx, key, deployment); err != nil { | ||
return false | ||
} | ||
for _, c := range deployment.Status.Conditions { | ||
if c.Type == appsv1.DeploymentAvailable && c.Status == corev1.ConditionTrue { | ||
return true | ||
} | ||
} | ||
return false | ||
|
||
}, intervals...).Should(BeTrue(), "Deployment %s/%s failed to get status.Available = True condition") | ||
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. Should this have been a 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. @wfernandes good catch! |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this rely on the owner ref, instead of labels?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK ownerRef can't be used as a filter option for List.
Additionally, also ownerRef are set by CPAI controller during first reconciliation, so the same note will apply no matter of the change