support watch namespaces matched namespace selector (#7472)

skip caching namespaces at cluster scope if only watching single namespace

add --watch-namespace-selector in user guide

add e2e test
This commit is contained in:
zryfish 2021-11-13 03:46:28 +08:00 committed by GitHub
parent 67e13bf692
commit 7203a0b8bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 461 additions and 19 deletions

View file

@ -55,7 +55,15 @@ func (f *Framework) NewEchoDeploymentWithReplicas(replicas int) {
// replicas is configurable and
// name is configurable
func (f *Framework) NewEchoDeploymentWithNameAndReplicas(name string, replicas int) {
deployment := newDeployment(name, f.Namespace, "k8s.gcr.io/ingress-nginx/e2e-test-echo@sha256:131ece0637b29231470cfaa04690c2966a2e0b147d3c9df080a0857b78982410", 80, int32(replicas),
f.newEchoDeployment(f.Namespace, name, replicas)
}
func (f *Framework) NewEchoDeploymentWithNamespaceAndReplicas(namespace string, replicas int) {
f.newEchoDeployment(namespace, EchoService, replicas)
}
func (f *Framework) newEchoDeployment(namespace, name string, replicas int) {
deployment := newDeployment(name, namespace, "k8s.gcr.io/ingress-nginx/e2e-test-echo@sha256:131ece0637b29231470cfaa04690c2966a2e0b147d3c9df080a0857b78982410", 80, int32(replicas),
nil,
[]corev1.VolumeMount{},
[]corev1.Volume{},
@ -66,7 +74,7 @@ func (f *Framework) NewEchoDeploymentWithNameAndReplicas(name string, replicas i
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: f.Namespace,
Namespace: namespace,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
@ -85,7 +93,7 @@ func (f *Framework) NewEchoDeploymentWithNameAndReplicas(name string, replicas i
f.EnsureService(service)
err := WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, f.Namespace, replicas)
err := WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, namespace, replicas)
assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready")
}

View file

@ -126,7 +126,7 @@ func (f *Framework) AfterEach() {
defer func(kubeClient kubernetes.Interface, ns string) {
go func() {
defer ginkgo.GinkgoRecover()
err := deleteKubeNamespace(kubeClient, ns)
err := DeleteKubeNamespace(kubeClient, ns)
assert.Nil(ginkgo.GinkgoT(), err, "deleting namespace %v", f.Namespace)
}()
}(f.KubeClientSet, f.Namespace)
@ -588,6 +588,12 @@ func NewSingleIngress(name, path, host, ns, service string, port int, annotation
return newSingleIngressWithRules(name, path, host, ns, service, port, annotations, nil)
}
func NewSingleIngressWithIngressClass(name, path, host, ns, service, ingressClass string, port int, annotations map[string]string) *networking.Ingress {
ing := newSingleIngressWithRules(name, path, host, ns, service, port, annotations, nil)
ing.Spec.IngressClassName = &ingressClass
return ing
}
// NewSingleIngressWithMultiplePaths creates a simple ingress rule with multiple paths
func NewSingleIngressWithMultiplePaths(name string, paths []string, host, ns, service string, port int, annotations map[string]string) *networking.Ingress {
pathtype := networking.PathTypePrefix

View file

@ -38,7 +38,7 @@ import (
// EnsureSecret creates a Secret object or returns it if it already exists.
func (f *Framework) EnsureSecret(secret *api.Secret) *api.Secret {
err := createSecretWithRetries(f.KubeClientSet, f.Namespace, secret)
err := createSecretWithRetries(f.KubeClientSet, secret.Namespace, secret)
assert.Nil(ginkgo.GinkgoT(), err, "creating secret")
s, err := f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Get(context.TODO(), secret.Name, metav1.GetOptions{})
@ -50,10 +50,10 @@ func (f *Framework) EnsureSecret(secret *api.Secret) *api.Secret {
// EnsureConfigMap creates a ConfigMap object or returns it if it already exists.
func (f *Framework) EnsureConfigMap(configMap *api.ConfigMap) (*api.ConfigMap, error) {
cm, err := f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
cm, err := f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
if err != nil {
if k8sErrors.IsAlreadyExists(err) {
return f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
return f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
}
return nil, err
}
@ -72,13 +72,13 @@ func (f *Framework) GetIngress(namespace string, name string) *networking.Ingres
// EnsureIngress creates an Ingress object and returns it, throws error if it already exists.
func (f *Framework) EnsureIngress(ingress *networking.Ingress) *networking.Ingress {
fn := func() {
err := createIngressWithRetries(f.KubeClientSet, f.Namespace, ingress)
err := createIngressWithRetries(f.KubeClientSet, ingress.Namespace, ingress)
assert.Nil(ginkgo.GinkgoT(), err, "creating ingress")
}
f.WaitForReload(fn)
ing := f.GetIngress(f.Namespace, ingress.Name)
ing := f.GetIngress(ingress.Namespace, ingress.Name)
if ing.Annotations == nil {
ing.Annotations = make(map[string]string)
}
@ -88,10 +88,10 @@ func (f *Framework) EnsureIngress(ingress *networking.Ingress) *networking.Ingre
// UpdateIngress updates an Ingress object and returns the updated object.
func (f *Framework) UpdateIngress(ingress *networking.Ingress) *networking.Ingress {
err := updateIngressWithRetries(f.KubeClientSet, f.Namespace, ingress)
err := updateIngressWithRetries(f.KubeClientSet, ingress.Namespace, ingress)
assert.Nil(ginkgo.GinkgoT(), err, "updating ingress")
ing := f.GetIngress(f.Namespace, ingress.Name)
ing := f.GetIngress(ingress.Namespace, ingress.Name)
if ing.Annotations == nil {
ing.Annotations = make(map[string]string)
}
@ -113,15 +113,15 @@ func (f *Framework) GetService(namespace string, name string) *core.Service {
// EnsureService creates a Service object and returns it, throws error if it already exists.
func (f *Framework) EnsureService(service *core.Service) *core.Service {
err := createServiceWithRetries(f.KubeClientSet, f.Namespace, service)
err := createServiceWithRetries(f.KubeClientSet, service.Namespace, service)
assert.Nil(ginkgo.GinkgoT(), err, "creating service")
return f.GetService(f.Namespace, service.Name)
return f.GetService(service.Namespace, service.Name)
}
// EnsureDeployment creates a Deployment object and returns it, throws error if it already exists.
func (f *Framework) EnsureDeployment(deployment *appsv1.Deployment) *appsv1.Deployment {
err := createDeploymentWithRetries(f.KubeClientSet, f.Namespace, deployment)
err := createDeploymentWithRetries(f.KubeClientSet, deployment.Namespace, deployment)
assert.Nil(ginkgo.GinkgoT(), err, "creating deployment")
d, err := f.KubeClientSet.AppsV1().Deployments(deployment.Namespace).Get(context.TODO(), deployment.Name, metav1.GetOptions{})

View file

@ -85,14 +85,15 @@ func RestclientConfig(config, context string) (*api.Config, error) {
// RunID unique identifier of the e2e run
var RunID = uuid.NewUUID()
// CreateKubeNamespace creates a new namespace in the cluster
func CreateKubeNamespace(baseName string, c kubernetes.Interface) (string, error) {
func createNamespace(baseName string, labels map[string]string, c kubernetes.Interface) (string, error) {
ts := time.Now().UnixNano()
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
GenerateName: fmt.Sprintf("e2e-tests-%v-%v-", baseName, ts),
Labels: labels,
},
}
// Be robust about making the namespace creation call.
var got *corev1.Namespace
var err error
@ -111,8 +112,20 @@ func CreateKubeNamespace(baseName string, c kubernetes.Interface) (string, error
return got.Name, nil
}
// deleteKubeNamespace deletes a namespace and all the objects inside
func deleteKubeNamespace(c kubernetes.Interface, namespace string) error {
// CreateKubeNamespace creates a new namespace in the cluster
func CreateKubeNamespace(baseName string, c kubernetes.Interface) (string, error) {
return createNamespace(baseName, nil, c)
}
// CreateKubeNamespaceWithLabel creates a new namespace with given labels in the cluster
func CreateKubeNamespaceWithLabel(baseName string, labels map[string]string, c kubernetes.Interface) (string, error) {
return createNamespace(baseName, labels, c)
}
// DeleteKubeNamespace deletes a namespace and all the objects inside
func DeleteKubeNamespace(c kubernetes.Interface, namespace string) error {
grace := int64(0)
pb := metav1.DeletePropagationBackground
return c.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{