Merge pull request #39738 from shashidharatd/federation-e2e
Automatic merge from submit-queue Move Federation e2e test code to independent package **What this PR does / why we need it**: Move federation e2e test code to an independent package called e2e_federation. This will help in multiple ways. - easy to move the federation related code to a separate repo from core. - one step closer to register/unregister clusters to federation only once during e2e instead of every test case. we need to introduce singleton to register cluster during framework creation which will be handled in subsequent PR. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # Optimize federation e2e suite which takes long time to execute currently. **Special notes for your reviewer**: I have tried to segregate into multiple commits. request to review commit by commit. also mostly the change is about moving the functions to a new location/package. **Release note**: ```release-note ``` @madhusudancs @nikhiljindal @colhom
This commit is contained in:
@@ -14,6 +14,7 @@ filegroup(
|
|||||||
srcs = [
|
srcs = [
|
||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//test/e2e:all-srcs",
|
"//test/e2e:all-srcs",
|
||||||
|
"//test/e2e_federation:all-srcs",
|
||||||
"//test/e2e_node:all-srcs",
|
"//test/e2e_node:all-srcs",
|
||||||
"//test/fixtures:all-srcs",
|
"//test/fixtures:all-srcs",
|
||||||
"//test/images:all-srcs",
|
"//test/images:all-srcs",
|
||||||
|
@@ -38,17 +38,6 @@ go_library(
|
|||||||
"example_cluster_dns.go",
|
"example_cluster_dns.go",
|
||||||
"example_k8petstore.go",
|
"example_k8petstore.go",
|
||||||
"examples.go",
|
"examples.go",
|
||||||
"federated-ingress.go",
|
|
||||||
"federated-namespace.go",
|
|
||||||
"federated-secret.go",
|
|
||||||
"federated-service.go",
|
|
||||||
"federation-apiserver.go",
|
|
||||||
"federation-authn.go",
|
|
||||||
"federation-daemonset.go",
|
|
||||||
"federation-deployment.go",
|
|
||||||
"federation-event.go",
|
|
||||||
"federation-replicaset.go",
|
|
||||||
"federation-util.go",
|
|
||||||
"firewall.go",
|
"firewall.go",
|
||||||
"garbage_collector.go",
|
"garbage_collector.go",
|
||||||
"generated_clientset.go",
|
"generated_clientset.go",
|
||||||
@@ -109,9 +98,6 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
|
||||||
"//federation/client/clientset_generated/federation_clientset/typed/core/v1:go_default_library",
|
|
||||||
"//federation/pkg/federation-controller/util:go_default_library",
|
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/annotations:go_default_library",
|
"//pkg/api/annotations:go_default_library",
|
||||||
"//pkg/api/resource:go_default_library",
|
"//pkg/api/resource:go_default_library",
|
||||||
@@ -135,8 +121,6 @@ go_library(
|
|||||||
"//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library",
|
"//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library",
|
||||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||||
"//pkg/client/restclient:go_default_library",
|
"//pkg/client/restclient:go_default_library",
|
||||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
|
||||||
"//pkg/client/unversioned/clientcmd/api:go_default_library",
|
|
||||||
"//pkg/cloudprovider:go_default_library",
|
"//pkg/cloudprovider:go_default_library",
|
||||||
"//pkg/cloudprovider/providers/aws:go_default_library",
|
"//pkg/cloudprovider/providers/aws:go_default_library",
|
||||||
"//pkg/cloudprovider/providers/gce:go_default_library",
|
"//pkg/cloudprovider/providers/gce:go_default_library",
|
||||||
@@ -172,6 +156,7 @@ go_library(
|
|||||||
"//test/e2e/common:go_default_library",
|
"//test/e2e/common:go_default_library",
|
||||||
"//test/e2e/framework:go_default_library",
|
"//test/e2e/framework:go_default_library",
|
||||||
"//test/e2e/generated:go_default_library",
|
"//test/e2e/generated:go_default_library",
|
||||||
|
"//test/e2e_federation:go_default_library",
|
||||||
"//test/images/net/nat:go_default_library",
|
"//test/images/net/nat:go_default_library",
|
||||||
"//test/utils:go_default_library",
|
"//test/utils:go_default_library",
|
||||||
"//vendor:github.com/aws/aws-sdk-go/aws",
|
"//vendor:github.com/aws/aws-sdk-go/aws",
|
||||||
|
@@ -23,8 +23,9 @@ import (
|
|||||||
type Suite string
|
type Suite string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
E2E Suite = "e2e"
|
E2E Suite = "e2e"
|
||||||
NodeE2E Suite = "node e2e"
|
NodeE2E Suite = "node e2e"
|
||||||
|
FederationE2E Suite = "federation e2e"
|
||||||
)
|
)
|
||||||
|
|
||||||
var CurrentSuite Suite
|
var CurrentSuite Suite
|
||||||
|
@@ -42,6 +42,7 @@ import (
|
|||||||
commontest "k8s.io/kubernetes/test/e2e/common"
|
commontest "k8s.io/kubernetes/test/e2e/common"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
"k8s.io/kubernetes/test/e2e/generated"
|
"k8s.io/kubernetes/test/e2e/generated"
|
||||||
|
federationtest "k8s.io/kubernetes/test/e2e_federation"
|
||||||
testutils "k8s.io/kubernetes/test/utils"
|
testutils "k8s.io/kubernetes/test/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,6 +154,9 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte {
|
|||||||
// Reference common test to make the import valid.
|
// Reference common test to make the import valid.
|
||||||
commontest.CurrentSuite = commontest.E2E
|
commontest.CurrentSuite = commontest.E2E
|
||||||
|
|
||||||
|
// Reference federation test to make the import valid.
|
||||||
|
federationtest.FederationSuite = commontest.FederationE2E
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}, func(data []byte) {
|
}, func(data []byte) {
|
||||||
|
@@ -32,8 +32,6 @@ go_library(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
|
||||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/api/v1/service:go_default_library",
|
"//pkg/api/v1/service:go_default_library",
|
||||||
@@ -95,7 +93,6 @@ go_library(
|
|||||||
"//vendor:golang.org/x/net/websocket",
|
"//vendor:golang.org/x/net/websocket",
|
||||||
"//vendor:google.golang.org/api/compute/v1",
|
"//vendor:google.golang.org/api/compute/v1",
|
||||||
"//vendor:google.golang.org/api/googleapi",
|
"//vendor:google.golang.org/api/googleapi",
|
||||||
"//vendor:gopkg.in/yaml.v2",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||||
|
@@ -20,7 +20,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -34,7 +33,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
staging "k8s.io/client-go/kubernetes"
|
staging "k8s.io/client-go/kubernetes"
|
||||||
clientreporestclient "k8s.io/client-go/rest"
|
clientreporestclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
@@ -48,7 +46,6 @@ import (
|
|||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
yaml "gopkg.in/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -88,13 +85,6 @@ type Framework struct {
|
|||||||
|
|
||||||
// configuration for framework's client
|
// configuration for framework's client
|
||||||
options FrameworkOptions
|
options FrameworkOptions
|
||||||
|
|
||||||
// will this framework exercise a federated cluster as well
|
|
||||||
federated bool
|
|
||||||
|
|
||||||
// Federation specific params. These are set only if federated = true.
|
|
||||||
FederationClientset_1_5 *federation_clientset.Clientset
|
|
||||||
FederationNamespace *v1.Namespace
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestDataSummary interface {
|
type TestDataSummary interface {
|
||||||
@@ -118,12 +108,6 @@ func NewDefaultFramework(baseName string) *Framework {
|
|||||||
return NewFramework(baseName, options, nil)
|
return NewFramework(baseName, options, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultFederatedFramework(baseName string) *Framework {
|
|
||||||
f := NewDefaultFramework(baseName)
|
|
||||||
f.federated = true
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDefaultGroupVersionFramework(baseName string, groupVersion schema.GroupVersion) *Framework {
|
func NewDefaultGroupVersionFramework(baseName string, groupVersion schema.GroupVersion) *Framework {
|
||||||
f := NewDefaultFramework(baseName)
|
f := NewDefaultFramework(baseName)
|
||||||
f.options.GroupVersion = &groupVersion
|
f.options.GroupVersion = &groupVersion
|
||||||
@@ -203,25 +187,6 @@ func (f *Framework) BeforeEach() {
|
|||||||
f.ClientPool = dynamic.NewClientPool(config, api.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
|
f.ClientPool = dynamic.NewClientPool(config, api.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.federated {
|
|
||||||
if f.FederationClientset_1_5 == nil {
|
|
||||||
By("Creating a release 1.4 federation Clientset")
|
|
||||||
var err error
|
|
||||||
f.FederationClientset_1_5, err = LoadFederationClientset_1_5()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
}
|
|
||||||
By("Waiting for federation-apiserver to be ready")
|
|
||||||
err := WaitForFederationApiserverReady(f.FederationClientset_1_5)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
By("federation-apiserver is ready")
|
|
||||||
|
|
||||||
By("Creating a federation namespace")
|
|
||||||
ns, err := f.createFederationNamespace(f.BaseName)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
f.FederationNamespace = ns
|
|
||||||
By(fmt.Sprintf("Created federation namespace %s", ns.Name))
|
|
||||||
}
|
|
||||||
|
|
||||||
By("Building a namespace api object")
|
By("Building a namespace api object")
|
||||||
namespace, err := f.CreateNamespace(f.BaseName, map[string]string{
|
namespace, err := f.CreateNamespace(f.BaseName, map[string]string{
|
||||||
"e2e-framework": f.BaseName,
|
"e2e-framework": f.BaseName,
|
||||||
@@ -262,45 +227,6 @@ func (f *Framework) BeforeEach() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framework) deleteFederationNs() {
|
|
||||||
if !f.federated {
|
|
||||||
// Nothing to do if this is not a federation setup.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ns := f.FederationNamespace
|
|
||||||
By(fmt.Sprintf("Destroying federation namespace %q for this suite.", ns.Name))
|
|
||||||
timeout := 5 * time.Minute
|
|
||||||
if f.NamespaceDeletionTimeout != 0 {
|
|
||||||
timeout = f.NamespaceDeletionTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
clientset := f.FederationClientset_1_5
|
|
||||||
// First delete the namespace from federation apiserver.
|
|
||||||
// Also delete the corresponding namespaces from underlying clusters.
|
|
||||||
orphanDependents := false
|
|
||||||
if err := clientset.Core().Namespaces().Delete(ns.Name, &v1.DeleteOptions{OrphanDependents: &orphanDependents}); err != nil {
|
|
||||||
Failf("Error while deleting federation namespace %s: %s", ns.Name, err)
|
|
||||||
}
|
|
||||||
// Verify that it got deleted.
|
|
||||||
err := wait.PollImmediate(5*time.Second, timeout, func() (bool, error) {
|
|
||||||
if _, err := clientset.Core().Namespaces().Get(ns.Name, metav1.GetOptions{}); err != nil {
|
|
||||||
if apierrors.IsNotFound(err) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
Logf("Error while waiting for namespace to be terminated: %v", err)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
if !apierrors.IsNotFound(err) {
|
|
||||||
Failf("Couldn't delete ns %q: %s", ns.Name, err)
|
|
||||||
} else {
|
|
||||||
Logf("Namespace %v was already deleted", ns.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AfterEach deletes the namespace, after reading its events.
|
// AfterEach deletes the namespace, after reading its events.
|
||||||
func (f *Framework) AfterEach() {
|
func (f *Framework) AfterEach() {
|
||||||
RemoveCleanupAction(f.cleanupHandle)
|
RemoveCleanupAction(f.cleanupHandle)
|
||||||
@@ -327,8 +253,6 @@ func (f *Framework) AfterEach() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delete the federation namespace.
|
|
||||||
f.deleteFederationNs()
|
|
||||||
} else {
|
} else {
|
||||||
if TestContext.DeleteNamespace {
|
if TestContext.DeleteNamespace {
|
||||||
Logf("Found DeleteNamespace=false, skipping namespace deletion!")
|
Logf("Found DeleteNamespace=false, skipping namespace deletion!")
|
||||||
@@ -340,7 +264,6 @@ func (f *Framework) AfterEach() {
|
|||||||
|
|
||||||
// Paranoia-- prevent reuse!
|
// Paranoia-- prevent reuse!
|
||||||
f.Namespace = nil
|
f.Namespace = nil
|
||||||
f.FederationNamespace = nil
|
|
||||||
f.ClientSet = nil
|
f.ClientSet = nil
|
||||||
f.namespacesToDelete = nil
|
f.namespacesToDelete = nil
|
||||||
|
|
||||||
@@ -354,34 +277,12 @@ func (f *Framework) AfterEach() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if f.federated {
|
|
||||||
defer func() {
|
|
||||||
if f.FederationClientset_1_5 == nil {
|
|
||||||
Logf("Warning: framework is marked federated, but has no federation 1.4 clientset")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := f.FederationClientset_1_5.Federation().Clusters().DeleteCollection(nil, v1.ListOptions{}); err != nil {
|
|
||||||
Logf("Error: failed to delete Clusters: %+v", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print events if the test failed.
|
// Print events if the test failed.
|
||||||
if CurrentGinkgoTestDescription().Failed && TestContext.DumpLogsOnFailure {
|
if CurrentGinkgoTestDescription().Failed && TestContext.DumpLogsOnFailure {
|
||||||
// Pass both unversioned client and and versioned clientset, till we have removed all uses of the unversioned client.
|
// Pass both unversioned client and and versioned clientset, till we have removed all uses of the unversioned client.
|
||||||
DumpAllNamespaceInfo(f.ClientSet, f.Namespace.Name)
|
DumpAllNamespaceInfo(f.ClientSet, f.Namespace.Name)
|
||||||
By(fmt.Sprintf("Dumping a list of prepulled images on each node"))
|
By(fmt.Sprintf("Dumping a list of prepulled images on each node"))
|
||||||
LogContainersInPodsWithLabels(f.ClientSet, api.NamespaceSystem, ImagePullerLabels, "image-puller", Logf)
|
LogContainersInPodsWithLabels(f.ClientSet, api.NamespaceSystem, ImagePullerLabels, "image-puller", Logf)
|
||||||
if f.federated {
|
|
||||||
// Dump federation events in federation namespace.
|
|
||||||
DumpEventsInNamespace(func(opts v1.ListOptions, ns string) (*v1.EventList, error) {
|
|
||||||
return f.FederationClientset_1_5.Core().Events(ns).List(opts)
|
|
||||||
}, f.FederationNamespace.Name)
|
|
||||||
// Print logs of federation control plane pods (federation-apiserver and federation-controller-manager)
|
|
||||||
LogPodsWithLabels(f.ClientSet, "federation", map[string]string{"app": "federated-cluster"}, Logf)
|
|
||||||
// Print logs of kube-dns pod
|
|
||||||
LogPodsWithLabels(f.ClientSet, "kube-system", map[string]string{"k8s-app": "kube-dns"}, Logf)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
summaries := make([]TestDataSummary, 0)
|
summaries := make([]TestDataSummary, 0)
|
||||||
@@ -456,29 +357,6 @@ func (f *Framework) CreateNamespace(baseName string, labels map[string]string) (
|
|||||||
return ns, err
|
return ns, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framework) createFederationNamespace(baseName string) (*v1.Namespace, error) {
|
|
||||||
clientset := f.FederationClientset_1_5
|
|
||||||
namespaceObj := &v1.Namespace{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
GenerateName: fmt.Sprintf("e2e-tests-%v-", baseName),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
// Be robust about making the namespace creation call.
|
|
||||||
var got *v1.Namespace
|
|
||||||
if err := wait.PollImmediate(Poll, SingleCallTimeout, func() (bool, error) {
|
|
||||||
var err error
|
|
||||||
got, err = clientset.Core().Namespaces().Create(namespaceObj)
|
|
||||||
if err != nil {
|
|
||||||
Logf("Unexpected error while creating namespace: %v", err)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return got, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForPodTerminated waits for the pod to be terminated with the given reason.
|
// WaitForPodTerminated waits for the pod to be terminated with the given reason.
|
||||||
func (f *Framework) WaitForPodTerminated(podName, reason string) error {
|
func (f *Framework) WaitForPodTerminated(podName, reason string) error {
|
||||||
return waitForPodTerminatedInNamespace(f.ClientSet, podName, reason, f.Namespace.Name)
|
return waitForPodTerminatedInNamespace(f.ClientSet, podName, reason, f.Namespace.Name)
|
||||||
@@ -709,7 +587,7 @@ type KubeConfig struct {
|
|||||||
Users []KubeUser `yaml:"users"`
|
Users []KubeUser `yaml:"users"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kc *KubeConfig) findUser(name string) *KubeUser {
|
func (kc *KubeConfig) FindUser(name string) *KubeUser {
|
||||||
for _, user := range kc.Users {
|
for _, user := range kc.Users {
|
||||||
if user.Name == name {
|
if user.Name == name {
|
||||||
return &user
|
return &user
|
||||||
@@ -718,7 +596,7 @@ func (kc *KubeConfig) findUser(name string) *KubeUser {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kc *KubeConfig) findCluster(name string) *KubeCluster {
|
func (kc *KubeConfig) FindCluster(name string) *KubeCluster {
|
||||||
for _, cluster := range kc.Clusters {
|
for _, cluster := range kc.Clusters {
|
||||||
if cluster.Name == name {
|
if cluster.Name == name {
|
||||||
return &cluster
|
return &cluster
|
||||||
@@ -727,55 +605,6 @@ func (kc *KubeConfig) findCluster(name string) *KubeCluster {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type E2EContext struct {
|
|
||||||
// Raw context name,
|
|
||||||
RawName string `yaml:"rawName"`
|
|
||||||
// A valid dns subdomain which can be used as the name of kubernetes resources.
|
|
||||||
Name string `yaml:"name"`
|
|
||||||
Cluster *KubeCluster `yaml:"cluster"`
|
|
||||||
User *KubeUser `yaml:"user"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framework) GetUnderlyingFederatedContexts() []E2EContext {
|
|
||||||
if !f.federated {
|
|
||||||
Failf("getUnderlyingFederatedContexts called on non-federated framework")
|
|
||||||
}
|
|
||||||
|
|
||||||
kubeconfig := KubeConfig{}
|
|
||||||
configBytes, err := ioutil.ReadFile(TestContext.KubeConfig)
|
|
||||||
ExpectNoError(err)
|
|
||||||
err = yaml.Unmarshal(configBytes, &kubeconfig)
|
|
||||||
ExpectNoError(err)
|
|
||||||
|
|
||||||
e2eContexts := []E2EContext{}
|
|
||||||
for _, context := range kubeconfig.Contexts {
|
|
||||||
if strings.HasPrefix(context.Name, "federation") && context.Name != federatedKubeContext {
|
|
||||||
user := kubeconfig.findUser(context.Context.User)
|
|
||||||
if user == nil {
|
|
||||||
Failf("Could not find user for context %+v", context)
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster := kubeconfig.findCluster(context.Context.Cluster)
|
|
||||||
if cluster == nil {
|
|
||||||
Failf("Could not find cluster for context %+v", context)
|
|
||||||
}
|
|
||||||
|
|
||||||
dnsSubdomainName, err := GetValidDNSSubdomainName(context.Name)
|
|
||||||
if err != nil {
|
|
||||||
Failf("Could not convert context name %s to a valid dns subdomain name, error: %s", context.Name, err)
|
|
||||||
}
|
|
||||||
e2eContexts = append(e2eContexts, E2EContext{
|
|
||||||
RawName: context.Name,
|
|
||||||
Name: dnsSubdomainName,
|
|
||||||
Cluster: cluster,
|
|
||||||
User: user,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return e2eContexts
|
|
||||||
}
|
|
||||||
|
|
||||||
func kubectlExecWithRetry(namespace string, podName, containerName string, args ...string) ([]byte, []byte, error) {
|
func kubectlExecWithRetry(namespace string, podName, containerName string, args ...string) ([]byte, []byte, error) {
|
||||||
for numRetries := 0; numRetries < maxKubectlExecRetries; numRetries++ {
|
for numRetries := 0; numRetries < maxKubectlExecRetries; numRetries++ {
|
||||||
if numRetries > 0 {
|
if numRetries > 0 {
|
||||||
|
@@ -81,6 +81,8 @@ type TestContextType struct {
|
|||||||
FeatureGates string
|
FeatureGates string
|
||||||
// Node e2e specific test context
|
// Node e2e specific test context
|
||||||
NodeTestContextType
|
NodeTestContextType
|
||||||
|
// Federation e2e context
|
||||||
|
FederatedKubeContext string
|
||||||
|
|
||||||
// Viper-only parameters. These will in time replace all flags.
|
// Viper-only parameters. These will in time replace all flags.
|
||||||
|
|
||||||
@@ -129,7 +131,6 @@ type CloudConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var TestContext TestContextType
|
var TestContext TestContextType
|
||||||
var federatedKubeContext string
|
|
||||||
|
|
||||||
// Register flags common to all e2e test suites.
|
// Register flags common to all e2e test suites.
|
||||||
func RegisterCommonFlags() {
|
func RegisterCommonFlags() {
|
||||||
@@ -163,7 +164,7 @@ func RegisterClusterFlags() {
|
|||||||
flag.StringVar(&TestContext.KubeConfig, clientcmd.RecommendedConfigPathFlag, os.Getenv(clientcmd.RecommendedConfigPathEnvVar), "Path to kubeconfig containing embedded authinfo.")
|
flag.StringVar(&TestContext.KubeConfig, clientcmd.RecommendedConfigPathFlag, os.Getenv(clientcmd.RecommendedConfigPathEnvVar), "Path to kubeconfig containing embedded authinfo.")
|
||||||
flag.StringVar(&TestContext.KubeContext, clientcmd.FlagContext, "", "kubeconfig context to use/override. If unset, will use value from 'current-context'")
|
flag.StringVar(&TestContext.KubeContext, clientcmd.FlagContext, "", "kubeconfig context to use/override. If unset, will use value from 'current-context'")
|
||||||
flag.StringVar(&TestContext.KubeAPIContentType, "kube-api-content-type", "application/vnd.kubernetes.protobuf", "ContentType used to communicate with apiserver")
|
flag.StringVar(&TestContext.KubeAPIContentType, "kube-api-content-type", "application/vnd.kubernetes.protobuf", "ContentType used to communicate with apiserver")
|
||||||
flag.StringVar(&federatedKubeContext, "federated-kube-context", "e2e-federation", "kubeconfig context for federation.")
|
flag.StringVar(&TestContext.FederatedKubeContext, "federated-kube-context", "e2e-federation", "kubeconfig context for federation.")
|
||||||
|
|
||||||
flag.StringVar(&TestContext.KubeVolumeDir, "volume-dir", "/var/lib/kubelet", "Path to the directory containing the kubelet volumes.")
|
flag.StringVar(&TestContext.KubeVolumeDir, "volume-dir", "/var/lib/kubelet", "Path to the directory containing the kubelet volumes.")
|
||||||
flag.StringVar(&TestContext.CertDir, "cert-dir", "", "Path to the directory containing the certs. Default is empty, which doesn't use certs.")
|
flag.StringVar(&TestContext.CertDir, "cert-dir", "", "Path to the directory containing the certs. Default is empty, which doesn't use certs.")
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -60,8 +61,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
|
||||||
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
|
||||||
@@ -360,23 +359,6 @@ func SkipUnlessServerVersionGTE(v *utilversion.Version, c discovery.ServerVersio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detects whether the federation namespace exists in the underlying cluster
|
|
||||||
func SkipUnlessFederated(c clientset.Interface) {
|
|
||||||
federationNS := os.Getenv("FEDERATION_NAMESPACE")
|
|
||||||
if federationNS == "" {
|
|
||||||
federationNS = federationapi.FederationNamespaceSystem
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.Core().Namespaces().Get(federationNS, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
if apierrs.IsNotFound(err) {
|
|
||||||
Skipf("Could not find federation namespace %s: skipping federated test", federationNS)
|
|
||||||
} else {
|
|
||||||
Failf("Unexpected error getting namespace: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SkipIfMissingResource(clientPool dynamic.ClientPool, gvr schema.GroupVersionResource, namespace string) {
|
func SkipIfMissingResource(clientPool dynamic.ClientPool, gvr schema.GroupVersionResource, namespace string) {
|
||||||
dynamicClient, err := clientPool.ClientForGroupVersionResource(gvr)
|
dynamicClient, err := clientPool.ClientForGroupVersionResource(gvr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -800,18 +782,6 @@ func WaitForDefaultServiceAccountInNamespace(c clientset.Interface, namespace st
|
|||||||
return waitForServiceAccountInNamespace(c, namespace, "default", ServiceAccountProvisionTimeout)
|
return waitForServiceAccountInNamespace(c, namespace, "default", ServiceAccountProvisionTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForFederationApiserverReady waits for the federation apiserver to be ready.
|
|
||||||
// It tests the readiness by sending a GET request and expecting a non error response.
|
|
||||||
func WaitForFederationApiserverReady(c *federation_clientset.Clientset) error {
|
|
||||||
return wait.PollImmediate(time.Second, 1*time.Minute, func() (bool, error) {
|
|
||||||
_, err := c.Federation().Clusters().List(v1.ListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForPersistentVolumePhase waits for a PersistentVolume to be in a specific phase or until timeout occurs, whichever comes first.
|
// WaitForPersistentVolumePhase waits for a PersistentVolume to be in a specific phase or until timeout occurs, whichever comes first.
|
||||||
func WaitForPersistentVolumePhase(phase v1.PersistentVolumePhase, c clientset.Interface, pvName string, Poll, timeout time.Duration) error {
|
func WaitForPersistentVolumePhase(phase v1.PersistentVolumePhase, c clientset.Interface, pvName string, Poll, timeout time.Duration) error {
|
||||||
Logf("Waiting up to %v for PersistentVolume %s to have phase %s", timeout, pvName, phase)
|
Logf("Waiting up to %v for PersistentVolume %s to have phase %s", timeout, pvName, phase)
|
||||||
@@ -1781,7 +1751,7 @@ func ServiceResponding(c clientset.Interface, ns, name string) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func restclientConfig(kubeContext string) (*clientcmdapi.Config, error) {
|
func RestclientConfig(kubeContext string) (*clientcmdapi.Config, error) {
|
||||||
Logf(">>> kubeConfig: %s\n", TestContext.KubeConfig)
|
Logf(">>> kubeConfig: %s\n", TestContext.KubeConfig)
|
||||||
if TestContext.KubeConfig == "" {
|
if TestContext.KubeConfig == "" {
|
||||||
return nil, fmt.Errorf("KubeConfig must be specified to load client config")
|
return nil, fmt.Errorf("KubeConfig must be specified to load client config")
|
||||||
@@ -1804,43 +1774,13 @@ func LoadConfig() (*restclient.Config, error) {
|
|||||||
// This is a node e2e test, apply the node e2e configuration
|
// This is a node e2e test, apply the node e2e configuration
|
||||||
return &restclient.Config{Host: TestContext.Host}, nil
|
return &restclient.Config{Host: TestContext.Host}, nil
|
||||||
}
|
}
|
||||||
c, err := restclientConfig(TestContext.KubeContext)
|
c, err := RestclientConfig(TestContext.KubeContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: TestContext.Host}}).ClientConfig()
|
return clientcmd.NewDefaultClientConfig(*c, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: TestContext.Host}}).ClientConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadFederatedConfig(overrides *clientcmd.ConfigOverrides) (*restclient.Config, error) {
|
|
||||||
c, err := restclientConfig(federatedKubeContext)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error creating federation client config: %v", err.Error())
|
|
||||||
}
|
|
||||||
cfg, err := clientcmd.NewDefaultClientConfig(*c, overrides).ClientConfig()
|
|
||||||
if cfg != nil {
|
|
||||||
//TODO(colhom): this is only here because https://github.com/kubernetes/kubernetes/issues/25422
|
|
||||||
cfg.NegotiatedSerializer = api.Codecs
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return cfg, fmt.Errorf("error creating federation client config: %v", err.Error())
|
|
||||||
}
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadFederationClientset_1_5() (*federation_clientset.Clientset, error) {
|
|
||||||
config, err := LoadFederatedConfig(&clientcmd.ConfigOverrides{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := federation_clientset.NewForConfig(config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error creating federation clientset: %v", err.Error())
|
|
||||||
}
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadInternalClientset() (*internalclientset.Clientset, error) {
|
func LoadInternalClientset() (*internalclientset.Clientset, error) {
|
||||||
config, err := LoadConfig()
|
config, err := LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -5300,3 +5240,54 @@ func RcByNameContainer(name string, replicas int32, image string, labels map[str
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SimpleGET executes a get on the given url, returns error if non-200 returned.
|
||||||
|
func SimpleGET(c *http.Client, url, host string) (string, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Host = host
|
||||||
|
res, err := c.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
rawBody, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
body := string(rawBody)
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
err = fmt.Errorf(
|
||||||
|
"GET returned http error %v", res.StatusCode)
|
||||||
|
}
|
||||||
|
return body, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PollURL polls till the url responds with a healthy http code. If
|
||||||
|
// expectUnreachable is true, it breaks on first non-healthy http code instead.
|
||||||
|
func PollURL(route, host string, timeout time.Duration, interval time.Duration, httpClient *http.Client, expectUnreachable bool) error {
|
||||||
|
var lastBody string
|
||||||
|
pollErr := wait.PollImmediate(interval, timeout, func() (bool, error) {
|
||||||
|
var err error
|
||||||
|
lastBody, err = SimpleGET(httpClient, route, host)
|
||||||
|
if err != nil {
|
||||||
|
Logf("host %v path %v: %v unreachable", host, route, err)
|
||||||
|
return expectUnreachable, nil
|
||||||
|
}
|
||||||
|
return !expectUnreachable, nil
|
||||||
|
})
|
||||||
|
if pollErr != nil {
|
||||||
|
return fmt.Errorf("Failed to execute a successful GET within %v, Last response body for %v, host %v:\n%v\n\n%v\n",
|
||||||
|
timeout, route, host, lastBody, pollErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DescribeIng(ns string) {
|
||||||
|
Logf("\nOutput of kubectl describe ing:\n")
|
||||||
|
desc, _ := RunKubectl(
|
||||||
|
"describe", "ing", fmt.Sprintf("--namespace=%v", ns))
|
||||||
|
Logf(desc)
|
||||||
|
}
|
||||||
|
@@ -102,7 +102,7 @@ var _ = framework.KubeDescribe("Loadbalancing: L7", func() {
|
|||||||
// Platform specific cleanup
|
// Platform specific cleanup
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
if CurrentGinkgoTestDescription().Failed {
|
if CurrentGinkgoTestDescription().Failed {
|
||||||
describeIng(ns)
|
framework.DescribeIng(ns)
|
||||||
}
|
}
|
||||||
if jig.ing == nil {
|
if jig.ing == nil {
|
||||||
By("No ingress created, no cleanup necessary")
|
By("No ingress created, no cleanup necessary")
|
||||||
@@ -137,10 +137,10 @@ var _ = framework.KubeDescribe("Loadbalancing: L7", func() {
|
|||||||
|
|
||||||
By("waiting for Ingress to come up with ip: " + ip)
|
By("waiting for Ingress to come up with ip: " + ip)
|
||||||
httpClient := buildInsecureClient(reqTimeout)
|
httpClient := buildInsecureClient(reqTimeout)
|
||||||
framework.ExpectNoError(pollURL(fmt.Sprintf("https://%v/", ip), "", framework.LoadBalancerPollTimeout, jig.pollInterval, httpClient, false))
|
framework.ExpectNoError(framework.PollURL(fmt.Sprintf("https://%v/", ip), "", framework.LoadBalancerPollTimeout, jig.pollInterval, httpClient, false))
|
||||||
|
|
||||||
By("should reject HTTP traffic")
|
By("should reject HTTP traffic")
|
||||||
framework.ExpectNoError(pollURL(fmt.Sprintf("http://%v/", ip), "", framework.LoadBalancerPollTimeout, jig.pollInterval, httpClient, true))
|
framework.ExpectNoError(framework.PollURL(fmt.Sprintf("http://%v/", ip), "", framework.LoadBalancerPollTimeout, jig.pollInterval, httpClient, true))
|
||||||
|
|
||||||
By("should have correct firewall rule for ingress")
|
By("should have correct firewall rule for ingress")
|
||||||
fw := gceController.getFirewallRule()
|
fw := gceController.getFirewallRule()
|
||||||
@@ -192,7 +192,7 @@ var _ = framework.KubeDescribe("Loadbalancing: L7", func() {
|
|||||||
framework.ExpectNoError(gcloudDelete("firewall-rules", fmt.Sprintf("ingress-80-443-%v", ns), framework.TestContext.CloudConfig.ProjectID))
|
framework.ExpectNoError(gcloudDelete("firewall-rules", fmt.Sprintf("ingress-80-443-%v", ns), framework.TestContext.CloudConfig.ProjectID))
|
||||||
}
|
}
|
||||||
if CurrentGinkgoTestDescription().Failed {
|
if CurrentGinkgoTestDescription().Failed {
|
||||||
describeIng(ns)
|
framework.DescribeIng(ns)
|
||||||
}
|
}
|
||||||
if jig.ing == nil {
|
if jig.ing == nil {
|
||||||
By("No ingress created, no cleanup necessary")
|
By("No ingress created, no cleanup necessary")
|
||||||
|
@@ -181,33 +181,13 @@ func createComformanceTests(jig *testJig, ns string) []conformanceTests {
|
|||||||
})
|
})
|
||||||
By("Checking that " + pathToFail + " is not exposed by polling for failure")
|
By("Checking that " + pathToFail + " is not exposed by polling for failure")
|
||||||
route := fmt.Sprintf("http://%v%v", jig.address, pathToFail)
|
route := fmt.Sprintf("http://%v%v", jig.address, pathToFail)
|
||||||
framework.ExpectNoError(pollURL(route, updateURLMapHost, framework.LoadBalancerCleanupTimeout, jig.pollInterval, &http.Client{Timeout: reqTimeout}, true))
|
framework.ExpectNoError(framework.PollURL(route, updateURLMapHost, framework.LoadBalancerCleanupTimeout, jig.pollInterval, &http.Client{Timeout: reqTimeout}, true))
|
||||||
},
|
},
|
||||||
fmt.Sprintf("Waiting for path updates to reflect in L7"),
|
fmt.Sprintf("Waiting for path updates to reflect in L7"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pollURL polls till the url responds with a healthy http code. If
|
|
||||||
// expectUnreachable is true, it breaks on first non-healthy http code instead.
|
|
||||||
func pollURL(route, host string, timeout time.Duration, interval time.Duration, httpClient *http.Client, expectUnreachable bool) error {
|
|
||||||
var lastBody string
|
|
||||||
pollErr := wait.PollImmediate(interval, timeout, func() (bool, error) {
|
|
||||||
var err error
|
|
||||||
lastBody, err = simpleGET(httpClient, route, host)
|
|
||||||
if err != nil {
|
|
||||||
framework.Logf("host %v path %v: %v unreachable", host, route, err)
|
|
||||||
return expectUnreachable, nil
|
|
||||||
}
|
|
||||||
return !expectUnreachable, nil
|
|
||||||
})
|
|
||||||
if pollErr != nil {
|
|
||||||
return fmt.Errorf("Failed to execute a successful GET within %v, Last response body for %v, host %v:\n%v\n\n%v\n",
|
|
||||||
timeout, route, host, lastBody, pollErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateRSACerts generates a basic self signed certificate using a key length
|
// generateRSACerts generates a basic self signed certificate using a key length
|
||||||
// of rsaBits, valid for validFor time.
|
// of rsaBits, valid for validFor time.
|
||||||
func generateRSACerts(host string, isCA bool, keyOut, certOut io.Writer) error {
|
func generateRSACerts(host string, isCA bool, keyOut, certOut io.Writer) error {
|
||||||
@@ -327,13 +307,6 @@ func createSecret(kubeClient clientset.Interface, ing *extensions.Ingress) (host
|
|||||||
return host, cert, key, err
|
return host, cert, key, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeIng(ns string) {
|
|
||||||
framework.Logf("\nOutput of kubectl describe ing:\n")
|
|
||||||
desc, _ := framework.RunKubectl(
|
|
||||||
"describe", "ing", fmt.Sprintf("--namespace=%v", ns))
|
|
||||||
framework.Logf(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanupGCE(gceController *GCEIngressController) {
|
func cleanupGCE(gceController *GCEIngressController) {
|
||||||
pollErr := wait.Poll(5*time.Second, framework.LoadBalancerCleanupTimeout, func() (bool, error) {
|
pollErr := wait.Poll(5*time.Second, framework.LoadBalancerCleanupTimeout, func() (bool, error) {
|
||||||
if err := gceController.Cleanup(false); err != nil {
|
if err := gceController.Cleanup(false); err != nil {
|
||||||
@@ -821,7 +794,7 @@ func (j *testJig) update(update func(ing *extensions.Ingress)) {
|
|||||||
update(j.ing)
|
update(j.ing)
|
||||||
j.ing, err = j.client.Extensions().Ingresses(ns).Update(j.ing)
|
j.ing, err = j.client.Extensions().Ingresses(ns).Update(j.ing)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
describeIng(j.ing.Namespace)
|
framework.DescribeIng(j.ing.Namespace)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !apierrs.IsConflict(err) && !apierrs.IsServerTimeout(err) {
|
if !apierrs.IsConflict(err) && !apierrs.IsServerTimeout(err) {
|
||||||
@@ -889,7 +862,7 @@ func (j *testJig) waitForIngress(waitForNodePort bool) {
|
|||||||
}
|
}
|
||||||
route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
|
route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
|
||||||
framework.Logf("Testing route %v host %v with simple GET", route, rules.Host)
|
framework.Logf("Testing route %v host %v with simple GET", route, rules.Host)
|
||||||
framework.ExpectNoError(pollURL(route, rules.Host, framework.LoadBalancerPollTimeout, j.pollInterval, timeoutClient, false))
|
framework.ExpectNoError(framework.PollURL(route, rules.Host, framework.LoadBalancerPollTimeout, j.pollInterval, timeoutClient, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -898,7 +871,7 @@ func (j *testJig) waitForIngress(waitForNodePort bool) {
|
|||||||
// given url returns a non-healthy http code even once.
|
// given url returns a non-healthy http code even once.
|
||||||
func (j *testJig) verifyURL(route, host string, iterations int, interval time.Duration, httpClient *http.Client) error {
|
func (j *testJig) verifyURL(route, host string, iterations int, interval time.Duration, httpClient *http.Client) error {
|
||||||
for i := 0; i < iterations; i++ {
|
for i := 0; i < iterations; i++ {
|
||||||
b, err := simpleGET(httpClient, route, host)
|
b, err := framework.SimpleGET(httpClient, route, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf(b)
|
framework.Logf(b)
|
||||||
return err
|
return err
|
||||||
@@ -913,7 +886,7 @@ func (j *testJig) curlServiceNodePort(ns, name string, port int) {
|
|||||||
// TODO: Curl all nodes?
|
// TODO: Curl all nodes?
|
||||||
u, err := framework.GetNodePortURL(j.client, ns, name, port)
|
u, err := framework.GetNodePortURL(j.client, ns, name, port)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
framework.ExpectNoError(pollURL(u, "", 30*time.Second, j.pollInterval, &http.Client{Timeout: reqTimeout}, false))
|
framework.ExpectNoError(framework.PollURL(u, "", 30*time.Second, j.pollInterval, &http.Client{Timeout: reqTimeout}, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// getIngressNodePorts returns all related backend services' nodePorts.
|
// getIngressNodePorts returns all related backend services' nodePorts.
|
||||||
|
@@ -18,7 +18,6 @@ package e2e
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
@@ -197,7 +196,7 @@ func (s *ingManager) test(path string) error {
|
|||||||
url := fmt.Sprintf("%v/hostName", path)
|
url := fmt.Sprintf("%v/hostName", path)
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
return wait.Poll(pollInterval, framework.ServiceRespondingTimeout, func() (bool, error) {
|
return wait.Poll(pollInterval, framework.ServiceRespondingTimeout, func() (bool, error) {
|
||||||
body, err := simpleGET(httpClient, url, "")
|
body, err := framework.SimpleGET(httpClient, url, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Logf("%v\n%v\n%v", url, body, err)
|
framework.Logf("%v\n%v\n%v", url, body, err)
|
||||||
return false, nil
|
return false, nil
|
||||||
@@ -239,30 +238,6 @@ var _ = framework.KubeDescribe("ServiceLoadBalancer [Feature:ServiceLoadBalancer
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// simpleGET executes a get on the given url, returns error if non-200 returned.
|
|
||||||
func simpleGET(c *http.Client, url, host string) (string, error) {
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
req.Host = host
|
|
||||||
res, err := c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
rawBody, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
body := string(rawBody)
|
|
||||||
if res.StatusCode != http.StatusOK {
|
|
||||||
err = fmt.Errorf(
|
|
||||||
"GET returned http error %v", res.StatusCode)
|
|
||||||
}
|
|
||||||
return body, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// rcFromManifest reads a .json/yaml file and returns the rc in it.
|
// rcFromManifest reads a .json/yaml file and returns the rc in it.
|
||||||
func rcFromManifest(fileName string) *v1.ReplicationController {
|
func rcFromManifest(fileName string) *v1.ReplicationController {
|
||||||
var controller v1.ReplicationController
|
var controller v1.ReplicationController
|
||||||
|
64
test/e2e_federation/BUILD
Normal file
64
test/e2e_federation/BUILD
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"federated-daemonset.go",
|
||||||
|
"federated-deployment.go",
|
||||||
|
"federated-ingress.go",
|
||||||
|
"federated-namespace.go",
|
||||||
|
"federated-replicaset.go",
|
||||||
|
"federated-secret.go",
|
||||||
|
"federated-service.go",
|
||||||
|
"federation-apiserver.go",
|
||||||
|
"federation-authn.go",
|
||||||
|
"federation-event.go",
|
||||||
|
"federation-util.go",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
|
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||||
|
"//federation/client/clientset_generated/federation_clientset/typed/core/v1:go_default_library",
|
||||||
|
"//federation/pkg/federation-controller/util:go_default_library",
|
||||||
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/apis/extensions/v1beta1:go_default_library",
|
||||||
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
|
"//pkg/client/restclient:go_default_library",
|
||||||
|
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||||
|
"//pkg/client/unversioned/clientcmd/api:go_default_library",
|
||||||
|
"//pkg/util/intstr:go_default_library",
|
||||||
|
"//test/e2e/common:go_default_library",
|
||||||
|
"//test/e2e/framework:go_default_library",
|
||||||
|
"//test/e2e_federation/framework:go_default_library",
|
||||||
|
"//vendor:github.com/onsi/ginkgo",
|
||||||
|
"//vendor:github.com/onsi/gomega",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [
|
||||||
|
":package-srcs",
|
||||||
|
"//test/e2e_federation/framework:all-srcs",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -32,6 +32,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -44,58 +45,58 @@ const (
|
|||||||
var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation]", func() {
|
||||||
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
||||||
|
|
||||||
f := framework.NewDefaultFederatedFramework("federated-daemonset")
|
f := fedframework.NewDefaultFederatedFramework("federated-daemonset")
|
||||||
|
|
||||||
Describe("DaemonSet objects", func() {
|
Describe("DaemonSet objects", func() {
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
clusters = map[string]*cluster{}
|
clusters = map[string]*cluster{}
|
||||||
registerClusters(clusters, UserAgentName, "", f)
|
registerClusters(clusters, UserAgentName, "", f)
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
// Delete all daemonsets.
|
// Delete all daemonsets.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllDaemonSetsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllDaemonSetsOrFail(f.FederationClientset, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
daemonset := createDaemonSetOrFail(f.FederationClientset_1_5, nsName)
|
daemonset := createDaemonSetOrFail(f.FederationClientset, nsName)
|
||||||
defer func() { // Cleanup
|
defer func() { // Cleanup
|
||||||
By(fmt.Sprintf("Deleting daemonset %q in namespace %q", daemonset.Name, nsName))
|
By(fmt.Sprintf("Deleting daemonset %q in namespace %q", daemonset.Name, nsName))
|
||||||
err := f.FederationClientset_1_5.Extensions().DaemonSets(nsName).Delete(daemonset.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Extensions().DaemonSets(nsName).Delete(daemonset.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting daemonset %q in namespace %q", daemonset.Name, nsName)
|
framework.ExpectNoError(err, "Error deleting daemonset %q in namespace %q", daemonset.Name, nsName)
|
||||||
}()
|
}()
|
||||||
// wait for daemonset shards being created
|
// wait for daemonset shards being created
|
||||||
waitForDaemonSetShardsOrFail(nsName, daemonset, clusters)
|
waitForDaemonSetShardsOrFail(nsName, daemonset, clusters)
|
||||||
daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName)
|
daemonset = updateDaemonSetOrFail(f.FederationClientset, nsName)
|
||||||
waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters)
|
waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForDS(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that daemonsets were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that daemonsets were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForDS(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForDS(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
})
|
})
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -42,25 +43,25 @@ const (
|
|||||||
|
|
||||||
// Create/delete deployment api objects
|
// Create/delete deployment api objects
|
||||||
var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-deployment")
|
f := fedframework.NewDefaultFederatedFramework("federation-deployment")
|
||||||
|
|
||||||
Describe("Deployment objects", func() {
|
Describe("Deployment objects", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete all deployments.
|
// Delete all deployments.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllDeploymentsOrFail(f.FederationClientset, nsName)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deployment := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
|
deployment := createDeploymentOrFail(f.FederationClientset, nsName)
|
||||||
By(fmt.Sprintf("Creation of deployment %q in namespace %q succeeded. Deleting deployment.", deployment.Name, nsName))
|
By(fmt.Sprintf("Creation of deployment %q in namespace %q succeeded. Deleting deployment.", deployment.Name, nsName))
|
||||||
// Cleanup
|
// Cleanup
|
||||||
err := f.FederationClientset_1_5.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deployment.Name, deployment.Namespace)
|
framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deployment.Name, deployment.Namespace)
|
||||||
By(fmt.Sprintf("Deletion of deployment %q in namespace %q succeeded.", deployment.Name, nsName))
|
By(fmt.Sprintf("Deletion of deployment %q in namespace %q succeeded.", deployment.Name, nsName))
|
||||||
})
|
})
|
||||||
@@ -74,7 +75,7 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
|
|||||||
federationName string
|
federationName string
|
||||||
)
|
)
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
||||||
federationName = DefaultFederationName
|
federationName = DefaultFederationName
|
||||||
}
|
}
|
||||||
@@ -84,50 +85,50 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
|
|||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllDeploymentsOrFail(f.FederationClientset, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should create and update matching deployments in underling clusters", func() {
|
It("should create and update matching deployments in underling clusters", func() {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
dep := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
|
dep := createDeploymentOrFail(f.FederationClientset, nsName)
|
||||||
defer func() {
|
defer func() {
|
||||||
// cleanup. deletion of deployments is not supported for underlying clusters
|
// cleanup. deletion of deployments is not supported for underlying clusters
|
||||||
By(fmt.Sprintf("Preparing deployment %q/%q for deletion by setting replicas to zero", nsName, dep.Name))
|
By(fmt.Sprintf("Preparing deployment %q/%q for deletion by setting replicas to zero", nsName, dep.Name))
|
||||||
replicas := int32(0)
|
replicas := int32(0)
|
||||||
dep.Spec.Replicas = &replicas
|
dep.Spec.Replicas = &replicas
|
||||||
f.FederationClientset_1_5.Deployments(nsName).Update(dep)
|
f.FederationClientset.Deployments(nsName).Update(dep)
|
||||||
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
|
waitForDeploymentOrFail(f.FederationClientset, nsName, dep.Name, clusters)
|
||||||
f.FederationClientset_1_5.Deployments(nsName).Delete(dep.Name, &v1.DeleteOptions{})
|
f.FederationClientset.Deployments(nsName).Delete(dep.Name, &v1.DeleteOptions{})
|
||||||
}()
|
}()
|
||||||
|
|
||||||
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
|
waitForDeploymentOrFail(f.FederationClientset, nsName, dep.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly created and synced deployment %q/%q to clusters", nsName, dep.Name))
|
By(fmt.Sprintf("Successfuly created and synced deployment %q/%q to clusters", nsName, dep.Name))
|
||||||
updateDeploymentOrFail(f.FederationClientset_1_5, nsName)
|
updateDeploymentOrFail(f.FederationClientset, nsName)
|
||||||
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
|
waitForDeploymentOrFail(f.FederationClientset, nsName, dep.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
|
By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForDeployment(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForDeployment(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForDeployment(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -34,6 +34,7 @@ import (
|
|||||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -47,8 +48,13 @@ const (
|
|||||||
FederatedIngressServicePodName = "federated-ingress-service-test-pod"
|
FederatedIngressServicePodName = "federated-ingress-service-test-pod"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// timeout on a single http request.
|
||||||
|
reqTimeout = 10 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federated-ingress")
|
f := fedframework.NewDefaultFederatedFramework("federated-ingress")
|
||||||
|
|
||||||
// Create/delete ingress api objects
|
// Create/delete ingress api objects
|
||||||
// Validate federation apiserver, does not rely on underlying clusters or federation ingress controller.
|
// Validate federation apiserver, does not rely on underlying clusters or federation ingress controller.
|
||||||
@@ -56,17 +62,17 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
|||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
// Delete all ingresses.
|
// Delete all ingresses.
|
||||||
deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllIngressesOrFail(f.FederationClientset, nsName)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
framework.SkipUnlessProviderIs("gce", "gke") // TODO: Federated ingress is not yet supported on non-GCP platforms.
|
framework.SkipUnlessProviderIs("gce", "gke") // TODO: Federated ingress is not yet supported on non-GCP platforms.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
ingress := createIngressOrFail(f.FederationClientset_1_5, nsName)
|
ingress := createIngressOrFail(f.FederationClientset, nsName)
|
||||||
By(fmt.Sprintf("Creation of ingress %q in namespace %q succeeded. Deleting ingress.", ingress.Name, nsName))
|
By(fmt.Sprintf("Creation of ingress %q in namespace %q succeeded. Deleting ingress.", ingress.Name, nsName))
|
||||||
// Cleanup
|
// Cleanup
|
||||||
err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).Delete(ingress.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Extensions().Ingresses(nsName).Delete(ingress.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting ingress %q in namespace %q", ingress.Name, ingress.Namespace)
|
framework.ExpectNoError(err, "Error deleting ingress %q in namespace %q", ingress.Name, ingress.Namespace)
|
||||||
By(fmt.Sprintf("Deletion of ingress %q in namespace %q succeeded.", ingress.Name, nsName))
|
By(fmt.Sprintf("Deletion of ingress %q in namespace %q succeeded.", ingress.Name, nsName))
|
||||||
})
|
})
|
||||||
@@ -82,12 +88,12 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
|||||||
|
|
||||||
// register clusters in federation apiserver
|
// register clusters in federation apiserver
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
framework.SkipUnlessProviderIs("gce", "gke") // TODO: Federated ingress is not yet supported on non-GCP platforms.
|
framework.SkipUnlessProviderIs("gce", "gke") // TODO: Federated ingress is not yet supported on non-GCP platforms.
|
||||||
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
||||||
federationName = DefaultFederationName
|
federationName = DefaultFederationName
|
||||||
}
|
}
|
||||||
jig = newFederationTestJig(f.FederationClientset_1_5)
|
jig = newFederationTestJig(f.FederationClientset)
|
||||||
clusters = map[string]*cluster{}
|
clusters = map[string]*cluster{}
|
||||||
primaryClusterName = registerClusters(clusters, UserAgentName, federationName, f)
|
primaryClusterName = registerClusters(clusters, UserAgentName, federationName, f)
|
||||||
ns = f.FederationNamespace.Name
|
ns = f.FederationNamespace.Name
|
||||||
@@ -96,38 +102,38 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
|||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
// Delete all ingresses.
|
// Delete all ingresses.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllIngressesOrFail(f.FederationClientset, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should create and update matching ingresses in underlying clusters", func() {
|
It("should create and update matching ingresses in underlying clusters", func() {
|
||||||
ingress := createIngressOrFail(f.FederationClientset_1_5, ns)
|
ingress := createIngressOrFail(f.FederationClientset, ns)
|
||||||
// wait for ingress shards being created
|
// wait for ingress shards being created
|
||||||
waitForIngressShardsOrFail(ns, ingress, clusters)
|
waitForIngressShardsOrFail(ns, ingress, clusters)
|
||||||
ingress = updateIngressOrFail(f.FederationClientset_1_5, ns)
|
ingress = updateIngressOrFail(f.FederationClientset, ns)
|
||||||
waitForIngressShardsUpdatedOrFail(ns, ingress, clusters)
|
waitForIngressShardsUpdatedOrFail(ns, ingress, clusters)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForIngress(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that ingresses were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that ingresses were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForIngress(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForIngress(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -138,13 +144,13 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
|||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
// create backend pod
|
// create backend pod
|
||||||
createBackendPodsOrFail(clusters, ns, FederatedIngressServicePodName)
|
createBackendPodsOrFail(clusters, ns, FederatedIngressServicePodName)
|
||||||
// create backend service
|
// create backend service
|
||||||
service = createServiceOrFail(f.FederationClientset_1_5, ns, FederatedIngressServiceName)
|
service = createServiceOrFail(f.FederationClientset, ns, FederatedIngressServiceName)
|
||||||
// create ingress object
|
// create ingress object
|
||||||
jig.ing = createIngressOrFail(f.FederationClientset_1_5, ns)
|
jig.ing = createIngressOrFail(f.FederationClientset, ns)
|
||||||
// wait for services objects sync
|
// wait for services objects sync
|
||||||
waitForServiceShardsOrFail(ns, service, clusters)
|
waitForServiceShardsOrFail(ns, service, clusters)
|
||||||
// wait for ingress objects sync
|
// wait for ingress objects sync
|
||||||
@@ -154,14 +160,14 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
|||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
deleteBackendPodsOrFail(clusters, ns)
|
deleteBackendPodsOrFail(clusters, ns)
|
||||||
if service != nil {
|
if service != nil {
|
||||||
deleteServiceOrFail(f.FederationClientset_1_5, ns, service.Name, nil)
|
deleteServiceOrFail(f.FederationClientset, ns, service.Name, nil)
|
||||||
cleanupServiceShardsAndProviderResources(ns, service, clusters)
|
cleanupServiceShardsAndProviderResources(ns, service, clusters)
|
||||||
service = nil
|
service = nil
|
||||||
} else {
|
} else {
|
||||||
By("No service to delete. Service is nil")
|
By("No service to delete. Service is nil")
|
||||||
}
|
}
|
||||||
if jig.ing != nil {
|
if jig.ing != nil {
|
||||||
deleteIngressOrFail(f.FederationClientset_1_5, ns, jig.ing.Name, nil)
|
deleteIngressOrFail(f.FederationClientset, ns, jig.ing.Name, nil)
|
||||||
for clusterName, cluster := range clusters {
|
for clusterName, cluster := range clusters {
|
||||||
deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name)
|
deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name)
|
||||||
}
|
}
|
||||||
@@ -395,7 +401,7 @@ func updateIngressOrFail(clientset *fedclientset.Clientset, namespace string) (n
|
|||||||
for i := 0; i < MaxRetriesOnFederatedApiserver; i++ {
|
for i := 0; i < MaxRetriesOnFederatedApiserver; i++ {
|
||||||
newIng, err = clientset.Extensions().Ingresses(namespace).Update(ingress)
|
newIng, err = clientset.Extensions().Ingresses(namespace).Update(ingress)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
describeIng(namespace)
|
framework.DescribeIng(namespace)
|
||||||
return newIng
|
return newIng
|
||||||
}
|
}
|
||||||
if !errors.IsConflict(err) && !errors.IsServerTimeout(err) {
|
if !errors.IsConflict(err) && !errors.IsServerTimeout(err) {
|
||||||
@@ -422,7 +428,7 @@ func (j *federationTestJig) waitForFederatedIngress() {
|
|||||||
for _, p := range rules.IngressRuleValue.HTTP.Paths {
|
for _, p := range rules.IngressRuleValue.HTTP.Paths {
|
||||||
route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
|
route := fmt.Sprintf("%v://%v%v", proto, address, p.Path)
|
||||||
framework.Logf("Testing route %v host %v with simple GET", route, rules.Host)
|
framework.Logf("Testing route %v host %v with simple GET", route, rules.Host)
|
||||||
framework.ExpectNoError(pollURL(route, rules.Host, framework.LoadBalancerPollTimeout, framework.LoadBalancerPollInterval, timeoutClient, false))
|
framework.ExpectNoError(framework.PollURL(route, rules.Host, framework.LoadBalancerPollTimeout, framework.LoadBalancerPollInterval, timeoutClient, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
)
|
)
|
||||||
@@ -40,14 +41,14 @@ const (
|
|||||||
|
|
||||||
// Create/delete ingress api objects
|
// Create/delete ingress api objects
|
||||||
var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-namespace")
|
f := fedframework.NewDefaultFederatedFramework("federation-namespace")
|
||||||
|
|
||||||
Describe("Namespace objects", func() {
|
Describe("Namespace objects", func() {
|
||||||
var federationName string
|
var federationName string
|
||||||
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// TODO: Federation API server should be able to answer this.
|
// TODO: Federation API server should be able to answer this.
|
||||||
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
||||||
@@ -59,10 +60,10 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
|
|||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
deleteAllTestNamespaces(nil,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
f.FederationClientset.Core().Namespaces().Delete)
|
||||||
for _, cluster := range clusters {
|
for _, cluster := range clusters {
|
||||||
deleteAllTestNamespaces(nil,
|
deleteAllTestNamespaces(nil,
|
||||||
cluster.Core().Namespaces().List,
|
cluster.Core().Namespaces().List,
|
||||||
@@ -72,42 +73,42 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
|
nsName := createNamespace(f.FederationClientset.Core().Namespaces())
|
||||||
|
|
||||||
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
||||||
deleteAllTestNamespaces(nil,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
f.FederationClientset.Core().Namespaces().Delete)
|
||||||
By(fmt.Sprintf("Verified that deletion succeeded"))
|
By(fmt.Sprintf("Verified that deletion succeeded"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
|
verifyNsCascadingDeletion(f.FederationClientset.Core().Namespaces(), clusters, &orphanDependents)
|
||||||
By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
|
verifyNsCascadingDeletion(f.FederationClientset.Core().Namespaces(), clusters, &orphanDependents)
|
||||||
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, nil)
|
verifyNsCascadingDeletion(f.FederationClientset.Core().Namespaces(), clusters, nil)
|
||||||
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("all resources in the namespace should be deleted when namespace is deleted", func() {
|
It("all resources in the namespace should be deleted when namespace is deleted", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
|
nsName := createNamespace(f.FederationClientset.Core().Namespaces())
|
||||||
|
|
||||||
// Create resources in the namespace.
|
// Create resources in the namespace.
|
||||||
event := api_v1.Event{
|
event := api_v1.Event{
|
||||||
@@ -122,18 +123,18 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
By(fmt.Sprintf("Creating event %s in namespace %s", event.Name, nsName))
|
By(fmt.Sprintf("Creating event %s in namespace %s", event.Name, nsName))
|
||||||
_, err := f.FederationClientset_1_5.Core().Events(nsName).Create(&event)
|
_, err := f.FederationClientset.Core().Events(nsName).Create(&event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("Failed to create event %v in namespace %s, err: %s", event, nsName, err)
|
framework.Failf("Failed to create event %v in namespace %s, err: %s", event, nsName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
||||||
deleteAllTestNamespaces(nil,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
f.FederationClientset.Core().Namespaces().Delete)
|
||||||
|
|
||||||
By(fmt.Sprintf("Verify that event %s was deleted as well", event.Name))
|
By(fmt.Sprintf("Verify that event %s was deleted as well", event.Name))
|
||||||
latestEvent, err := f.FederationClientset_1_5.Core().Events(nsName).Get(event.Name, metav1.GetOptions{})
|
latestEvent, err := f.FederationClientset.Core().Events(nsName).Get(event.Name, metav1.GetOptions{})
|
||||||
if !errors.IsNotFound(err) {
|
if !errors.IsNotFound(err) {
|
||||||
framework.Failf("Event %s should have been deleted. Found: %v", event.Name, latestEvent)
|
framework.Failf("Event %s should have been deleted. Found: %v", event.Name, latestEvent)
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
@@ -44,25 +45,25 @@ const (
|
|||||||
|
|
||||||
// Create/delete replicaset api objects
|
// Create/delete replicaset api objects
|
||||||
var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-replicaset")
|
f := fedframework.NewDefaultFederatedFramework("federation-replicaset")
|
||||||
|
|
||||||
Describe("ReplicaSet objects", func() {
|
Describe("ReplicaSet objects", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete all replicasets.
|
// Delete all replicasets.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllReplicaSetsOrFail(f.FederationClientset, nsName)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
replicaset := createReplicaSetOrFail(f.FederationClientset_1_5, nsName)
|
replicaset := createReplicaSetOrFail(f.FederationClientset, nsName)
|
||||||
By(fmt.Sprintf("Creation of replicaset %q in namespace %q succeeded. Deleting replicaset.", replicaset.Name, nsName))
|
By(fmt.Sprintf("Creation of replicaset %q in namespace %q succeeded. Deleting replicaset.", replicaset.Name, nsName))
|
||||||
// Cleanup
|
// Cleanup
|
||||||
err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).Delete(replicaset.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Extensions().ReplicaSets(nsName).Delete(replicaset.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting replicaset %q in namespace %q", replicaset.Name, replicaset.Namespace)
|
framework.ExpectNoError(err, "Error deleting replicaset %q in namespace %q", replicaset.Name, replicaset.Namespace)
|
||||||
By(fmt.Sprintf("Deletion of replicaset %q in namespace %q succeeded.", replicaset.Name, nsName))
|
By(fmt.Sprintf("Deletion of replicaset %q in namespace %q succeeded.", replicaset.Name, nsName))
|
||||||
})
|
})
|
||||||
@@ -76,7 +77,7 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
|
|||||||
federationName string
|
federationName string
|
||||||
)
|
)
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
||||||
federationName = DefaultFederationName
|
federationName = DefaultFederationName
|
||||||
}
|
}
|
||||||
@@ -87,50 +88,50 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
|
|||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
// Delete all replicasets.
|
// Delete all replicasets.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllReplicaSetsOrFail(f.FederationClientset, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should create and update matching replicasets in underling clusters", func() {
|
It("should create and update matching replicasets in underling clusters", func() {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
rs := createReplicaSetOrFail(f.FederationClientset_1_5, nsName)
|
rs := createReplicaSetOrFail(f.FederationClientset, nsName)
|
||||||
defer func() {
|
defer func() {
|
||||||
// cleanup. deletion of replicasets is not supported for underlying clusters
|
// cleanup. deletion of replicasets is not supported for underlying clusters
|
||||||
By(fmt.Sprintf("Preparing replicaset %q/%q for deletion by setting replicas to zero", nsName, rs.Name))
|
By(fmt.Sprintf("Preparing replicaset %q/%q for deletion by setting replicas to zero", nsName, rs.Name))
|
||||||
replicas := int32(0)
|
replicas := int32(0)
|
||||||
rs.Spec.Replicas = &replicas
|
rs.Spec.Replicas = &replicas
|
||||||
f.FederationClientset_1_5.ReplicaSets(nsName).Update(rs)
|
f.FederationClientset.ReplicaSets(nsName).Update(rs)
|
||||||
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
|
waitForReplicaSetOrFail(f.FederationClientset, nsName, rs.Name, clusters)
|
||||||
f.FederationClientset_1_5.ReplicaSets(nsName).Delete(rs.Name, &v1.DeleteOptions{})
|
f.FederationClientset.ReplicaSets(nsName).Delete(rs.Name, &v1.DeleteOptions{})
|
||||||
}()
|
}()
|
||||||
|
|
||||||
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
|
waitForReplicaSetOrFail(f.FederationClientset, nsName, rs.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly created and synced replicaset %q/%q to clusters", nsName, rs.Name))
|
By(fmt.Sprintf("Successfuly created and synced replicaset %q/%q to clusters", nsName, rs.Name))
|
||||||
updateReplicaSetOrFail(f.FederationClientset_1_5, nsName)
|
updateReplicaSetOrFail(f.FederationClientset, nsName)
|
||||||
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
|
waitForReplicaSetOrFail(f.FederationClientset, nsName, rs.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name))
|
By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForReplicaSet(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that replica sets were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that replica sets were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForReplicaSet(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForReplicaSet(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
})
|
})
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -43,55 +44,55 @@ const (
|
|||||||
var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func() {
|
||||||
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
||||||
|
|
||||||
f := framework.NewDefaultFederatedFramework("federated-secret")
|
f := fedframework.NewDefaultFederatedFramework("federated-secret")
|
||||||
|
|
||||||
Describe("Secret objects", func() {
|
Describe("Secret objects", func() {
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
clusters = map[string]*cluster{}
|
clusters = map[string]*cluster{}
|
||||||
registerClusters(clusters, UserAgentName, "", f)
|
registerClusters(clusters, UserAgentName, "", f)
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
// Delete all secrets.
|
// Delete all secrets.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteAllSecretsOrFail(f.FederationClientset_1_5, nsName)
|
deleteAllSecretsOrFail(f.FederationClientset, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
secret := createSecretOrFail(f.FederationClientset_1_5, nsName)
|
secret := createSecretOrFail(f.FederationClientset, nsName)
|
||||||
// wait for secret shards being created
|
// wait for secret shards being created
|
||||||
waitForSecretShardsOrFail(nsName, secret, clusters)
|
waitForSecretShardsOrFail(nsName, secret, clusters)
|
||||||
secret = updateSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name)
|
secret = updateSecretOrFail(f.FederationClientset, nsName, secret.Name)
|
||||||
waitForSecretShardsUpdatedOrFail(nsName, secret, clusters)
|
waitForSecretShardsUpdatedOrFail(nsName, secret, clusters)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForSecret(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForSecret(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForSecret(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
})
|
})
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
)
|
)
|
||||||
@@ -50,14 +51,14 @@ var FederatedServiceLabels = map[string]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federated-service")
|
f := fedframework.NewDefaultFederatedFramework("federated-service")
|
||||||
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
||||||
var federationName string
|
var federationName string
|
||||||
var primaryClusterName string // The name of the "primary" cluster
|
var primaryClusterName string // The name of the "primary" cluster
|
||||||
|
|
||||||
var _ = Describe("Federated Services", func() {
|
var _ = Describe("Federated Services", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// TODO: Federation API server should be able to answer this.
|
// TODO: Federation API server should be able to answer this.
|
||||||
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
|
||||||
@@ -79,12 +80,12 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
// Placeholder
|
// Placeholder
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
if service != nil {
|
if service != nil {
|
||||||
By(fmt.Sprintf("Deleting service shards and their provider resources in underlying clusters for service %q in namespace %q", service.Name, nsName))
|
By(fmt.Sprintf("Deleting service shards and their provider resources in underlying clusters for service %q in namespace %q", service.Name, nsName))
|
||||||
@@ -95,51 +96,51 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should succeed", func() {
|
It("should succeed", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName = f.FederationNamespace.Name
|
nsName = f.FederationNamespace.Name
|
||||||
service = createServiceOrFail(f.FederationClientset_1_5, nsName, FederatedServiceName)
|
service = createServiceOrFail(f.FederationClientset, nsName, FederatedServiceName)
|
||||||
By(fmt.Sprintf("Creation of service %q in namespace %q succeeded. Deleting service.", service.Name, nsName))
|
By(fmt.Sprintf("Creation of service %q in namespace %q succeeded. Deleting service.", service.Name, nsName))
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
err := f.FederationClientset_1_5.Services(nsName).Delete(service.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Services(nsName).Delete(service.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, service.Namespace)
|
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, service.Namespace)
|
||||||
By(fmt.Sprintf("Deletion of service %q in namespace %q succeeded.", service.Name, nsName))
|
By(fmt.Sprintf("Deletion of service %q in namespace %q succeeded.", service.Name, nsName))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should create matching services in underlying clusters", func() {
|
It("should create matching services in underlying clusters", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName = f.FederationNamespace.Name
|
nsName = f.FederationNamespace.Name
|
||||||
service = createServiceOrFail(f.FederationClientset_1_5, nsName, FederatedServiceName)
|
service = createServiceOrFail(f.FederationClientset, nsName, FederatedServiceName)
|
||||||
defer func() { // Cleanup
|
defer func() { // Cleanup
|
||||||
By(fmt.Sprintf("Deleting service %q in namespace %q", service.Name, nsName))
|
By(fmt.Sprintf("Deleting service %q in namespace %q", service.Name, nsName))
|
||||||
err := f.FederationClientset_1_5.Services(nsName).Delete(service.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Services(nsName).Delete(service.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, nsName)
|
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, nsName)
|
||||||
}()
|
}()
|
||||||
waitForServiceShardsOrFail(nsName, service, clusters)
|
waitForServiceShardsOrFail(nsName, service, clusters)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := false
|
orphanDependents := false
|
||||||
verifyCascadingDeletionForService(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForService(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that services were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that services were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
orphanDependents := true
|
orphanDependents := true
|
||||||
verifyCascadingDeletionForService(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
|
verifyCascadingDeletionForService(f.FederationClientset, clusters, &orphanDependents, nsName)
|
||||||
By(fmt.Sprintf("Verified that services were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that services were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
verifyCascadingDeletionForService(f.FederationClientset_1_5, clusters, nil, nsName)
|
verifyCascadingDeletionForService(f.FederationClientset, clusters, nil, nsName)
|
||||||
By(fmt.Sprintf("Verified that services were not deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that services were not deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -151,7 +152,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
// Create kube-dns configmap for kube-dns to accept federation queries.
|
// Create kube-dns configmap for kube-dns to accept federation queries.
|
||||||
@@ -177,7 +178,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
|
|
||||||
createBackendPodsOrFail(clusters, nsName, FederatedServicePodName)
|
createBackendPodsOrFail(clusters, nsName, FederatedServicePodName)
|
||||||
|
|
||||||
service = createServiceOrFail(f.FederationClientset_1_5, nsName, FederatedServiceName)
|
service = createServiceOrFail(f.FederationClientset, nsName, FederatedServiceName)
|
||||||
obj, err := api.Scheme.DeepCopy(service)
|
obj, err := api.Scheme.DeepCopy(service)
|
||||||
// Cloning shouldn't fail. On the off-chance it does, we
|
// Cloning shouldn't fail. On the off-chance it does, we
|
||||||
// should shallow copy service to serviceShard before
|
// should shallow copy service to serviceShard before
|
||||||
@@ -210,13 +211,13 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deleteBackendPodsOrFail(clusters, nsName)
|
deleteBackendPodsOrFail(clusters, nsName)
|
||||||
|
|
||||||
if service != nil {
|
if service != nil {
|
||||||
deleteServiceOrFail(f.FederationClientset_1_5, nsName, service.Name, nil)
|
deleteServiceOrFail(f.FederationClientset, nsName, service.Name, nil)
|
||||||
service = nil
|
service = nil
|
||||||
} else {
|
} else {
|
||||||
By("No service to delete. Service is nil")
|
By("No service to delete. Service is nil")
|
||||||
@@ -239,7 +240,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to discover a federated service", func() {
|
It("should be able to discover a federated service", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
svcDNSNames := []string{
|
svcDNSNames := []string{
|
||||||
@@ -258,7 +259,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
By("Verified that DNS rules are working as expected")
|
By("Verified that DNS rules are working as expected")
|
||||||
|
|
||||||
By("Deleting the service to verify that DNS rules still work")
|
By("Deleting the service to verify that DNS rules still work")
|
||||||
err := f.FederationClientset_1_5.Services(nsName).Delete(FederatedServiceName, &v1.DeleteOptions{})
|
err := f.FederationClientset.Services(nsName).Delete(FederatedServiceName, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, service.Namespace)
|
framework.ExpectNoError(err, "Error deleting service %q in namespace %q", service.Name, service.Namespace)
|
||||||
// Service is deleted, unset the test block-global service variable.
|
// Service is deleted, unset the test block-global service variable.
|
||||||
service = nil
|
service = nil
|
||||||
@@ -271,7 +272,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
|
|
||||||
Context("non-local federated service", func() {
|
Context("non-local federated service", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete all the backend pods from the shard which is local to the discovery pod.
|
// Delete all the backend pods from the shard which is local to the discovery pod.
|
||||||
deleteOneBackendPodOrFail(clusters[primaryClusterName])
|
deleteOneBackendPodOrFail(clusters[primaryClusterName])
|
||||||
@@ -279,7 +280,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to discover a non-local federated service", func() {
|
It("should be able to discover a non-local federated service", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
svcDNSNames := []string{
|
svcDNSNames := []string{
|
||||||
@@ -295,7 +296,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
// TTL and/or running the pods in parallel.
|
// TTL and/or running the pods in parallel.
|
||||||
Context("[Slow] missing local service", func() {
|
Context("[Slow] missing local service", func() {
|
||||||
It("should never find DNS entries for a missing local service", func() {
|
It("should never find DNS entries for a missing local service", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
localSvcDNSNames := []string{
|
localSvcDNSNames := []string{
|
@@ -14,43 +14,43 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||||
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create/delete cluster api objects
|
// Create/delete cluster api objects
|
||||||
var _ = framework.KubeDescribe("Federation apiserver [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation apiserver [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-cluster")
|
f := fedframework.NewDefaultFederatedFramework("federation-cluster")
|
||||||
|
|
||||||
Describe("Cluster objects", func() {
|
Describe("Cluster objects", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete registered clusters.
|
// Delete registered clusters.
|
||||||
// This is if a test failed, it should not affect other tests.
|
// This is if a test failed, it should not affect other tests.
|
||||||
clusterList, err := f.FederationClientset_1_5.Federation().Clusters().List(v1.ListOptions{})
|
clusterList, err := f.FederationClientset.Federation().Clusters().List(v1.ListOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
for _, cluster := range clusterList.Items {
|
for _, cluster := range clusterList.Items {
|
||||||
err := f.FederationClientset_1_5.Federation().Clusters().Delete(cluster.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Federation().Clusters().Delete(cluster.Name, &v1.DeleteOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
contexts := f.GetUnderlyingFederatedContexts()
|
contexts := f.GetUnderlyingFederatedContexts()
|
||||||
|
|
||||||
@@ -69,14 +69,14 @@ var _ = framework.KubeDescribe("Federation apiserver [Feature:Federation]", func
|
|||||||
framework.Logf("Deleting %d clusters", len(contexts))
|
framework.Logf("Deleting %d clusters", len(contexts))
|
||||||
for _, context := range contexts {
|
for _, context := range contexts {
|
||||||
framework.Logf("Deleting cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
framework.Logf("Deleting cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
||||||
err := f.FederationClientset_1_5.Federation().Clusters().Delete(context.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Federation().Clusters().Delete(context.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, fmt.Sprintf("unexpected error in deleting cluster %s: %+v", context.Name, err))
|
framework.ExpectNoError(err, fmt.Sprintf("unexpected error in deleting cluster %s: %+v", context.Name, err))
|
||||||
framework.Logf("Successfully deleted cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
framework.Logf("Successfully deleted cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// There should not be any remaining cluster.
|
// There should not be any remaining cluster.
|
||||||
framework.Logf("Verifying that zero clusters remain")
|
framework.Logf("Verifying that zero clusters remain")
|
||||||
clusterList, err := f.FederationClientset_1_5.Federation().Clusters().List(v1.ListOptions{})
|
clusterList, err := f.FederationClientset.Federation().Clusters().List(v1.ListOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
if len(clusterList.Items) != 0 {
|
if len(clusterList.Items) != 0 {
|
||||||
framework.Failf("there should not have been any remaining clusters. Found: %+v", clusterList)
|
framework.Failf("there should not have been any remaining clusters. Found: %+v", clusterList)
|
||||||
@@ -86,16 +86,16 @@ var _ = framework.KubeDescribe("Federation apiserver [Feature:Federation]", func
|
|||||||
})
|
})
|
||||||
Describe("Admission control", func() {
|
Describe("Admission control", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be able to create resources if namespace does not exist", func() {
|
It("should not be able to create resources if namespace does not exist", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Creating a service in a non-existing namespace should fail.
|
// Creating a service in a non-existing namespace should fail.
|
||||||
svcNamespace := "federation-admission-test-ns"
|
svcNamespace := "federation-admission-test-ns"
|
||||||
svcName := "myns"
|
svcName := "myns"
|
||||||
clientset := f.FederationClientset_1_5
|
clientset := f.FederationClientset
|
||||||
framework.Logf("Trying to create service %s in namespace %s, expect to get error", svcName, svcNamespace)
|
framework.Logf("Trying to create service %s in namespace %s, expect to get error", svcName, svcNamespace)
|
||||||
if _, err := clientset.Core().Services(svcNamespace).Create(newService(svcName, svcNamespace)); err == nil {
|
if _, err := clientset.Core().Services(svcNamespace).Create(newService(svcName, svcNamespace)); err == nil {
|
||||||
framework.Failf("Expected to get an error while creating a service in a non-existing namespace")
|
framework.Failf("Expected to get an error while creating a service in a non-existing namespace")
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -24,29 +24,30 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-apiserver-authn")
|
f := fedframework.NewDefaultFederatedFramework("federation-apiserver-authn")
|
||||||
|
|
||||||
var _ = Describe("Federation API server authentication", func() {
|
var _ = Describe("Federation API server authentication", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should accept cluster resources when the client has right authentication credentials", func() {
|
It("should accept cluster resources when the client has right authentication credentials", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
svc := createServiceOrFail(f.FederationClientset_1_5, nsName, FederatedServiceName)
|
svc := createServiceOrFail(f.FederationClientset, nsName, FederatedServiceName)
|
||||||
deleteServiceOrFail(f.FederationClientset_1_5, nsName, svc.Name, nil)
|
deleteServiceOrFail(f.FederationClientset, nsName, svc.Name, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not accept cluster resources when the client has invalid authentication credentials", func() {
|
It("should not accept cluster resources when the client has invalid authentication credentials", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
contexts := f.GetUnderlyingFederatedContexts()
|
contexts := f.GetUnderlyingFederatedContexts()
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ var _ = framework.KubeDescribe("[Feature:Federation]", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should not accept cluster resources when the client has no authentication credentials", func() {
|
It("should not accept cluster resources when the client has no authentication credentials", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
fcs, err := invalidAuthFederationClientSet(nil)
|
fcs, err := invalidAuthFederationClientSet(nil)
|
||||||
framework.ExpectNoError(err)
|
framework.ExpectNoError(err)
|
||||||
@@ -94,7 +95,7 @@ func invalidAuthFederationClientSet(user *framework.KubeUser) (*federation_clien
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := framework.LoadFederatedConfig(overrides)
|
config, err := fedframework.LoadFederatedConfig(overrides)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
@@ -34,30 +35,30 @@ const (
|
|||||||
|
|
||||||
// Create/delete event api objects.
|
// Create/delete event api objects.
|
||||||
var _ = framework.KubeDescribe("Federation events [Feature:Federation]", func() {
|
var _ = framework.KubeDescribe("Federation events [Feature:Federation]", func() {
|
||||||
f := framework.NewDefaultFederatedFramework("federation-event")
|
f := fedframework.NewDefaultFederatedFramework("federation-event")
|
||||||
|
|
||||||
Describe("Event objects", func() {
|
Describe("Event objects", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
// Delete registered events.
|
// Delete registered events.
|
||||||
eventList, err := f.FederationClientset_1_5.Core().Events(nsName).List(v1.ListOptions{})
|
eventList, err := f.FederationClientset.Core().Events(nsName).List(v1.ListOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
for _, event := range eventList.Items {
|
for _, event := range eventList.Items {
|
||||||
err := f.FederationClientset_1_5.Core().Events(nsName).Delete(event.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Core().Events(nsName).Delete(event.Name, &v1.DeleteOptions{})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
fedframework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
event := createEventOrFail(f.FederationClientset_1_5, nsName)
|
event := createEventOrFail(f.FederationClientset, nsName)
|
||||||
By(fmt.Sprintf("Creation of event %q in namespace %q succeeded. Deleting event.", event.Name, nsName))
|
By(fmt.Sprintf("Creation of event %q in namespace %q succeeded. Deleting event.", event.Name, nsName))
|
||||||
// Cleanup
|
// Cleanup
|
||||||
err := f.FederationClientset_1_5.Core().Events(nsName).Delete(event.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Core().Events(nsName).Delete(event.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting event %q in namespace %q", event.Name, event.Namespace)
|
framework.ExpectNoError(err, "Error deleting event %q in namespace %q", event.Name, event.Namespace)
|
||||||
By(fmt.Sprintf("Deletion of event %q in namespace %q succeeded.", event.Name, nsName))
|
By(fmt.Sprintf("Deletion of event %q in namespace %q succeeded.", event.Name, nsName))
|
||||||
})
|
})
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package e2e
|
package e2e_federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -33,7 +33,9 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
|
"k8s.io/kubernetes/test/e2e/common"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
fedframework "k8s.io/kubernetes/test/e2e_federation/framework"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@@ -48,6 +50,8 @@ var (
|
|||||||
DNSTTL = 180 * time.Second // TODO: make k8s.io/kubernetes/federation/pkg/federation-controller/service.minDnsTtl exported, and import it here.
|
DNSTTL = 180 * time.Second // TODO: make k8s.io/kubernetes/federation/pkg/federation-controller/service.minDnsTtl exported, and import it here.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var FederationSuite common.Suite
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cluster keeps track of the assorted objects and state related to each cluster
|
cluster keeps track of the assorted objects and state related to each cluster
|
||||||
in the federation
|
in the federation
|
||||||
@@ -59,7 +63,7 @@ type cluster struct {
|
|||||||
backendPod *v1.Pod // The backend pod, if one's been created.
|
backendPod *v1.Pod // The backend pod, if one's been created.
|
||||||
}
|
}
|
||||||
|
|
||||||
func createClusterObjectOrFail(f *framework.Framework, context *framework.E2EContext) {
|
func createClusterObjectOrFail(f *fedframework.Framework, context *fedframework.E2EContext) {
|
||||||
framework.Logf("Creating cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
framework.Logf("Creating cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
||||||
cluster := federationapi.Cluster{
|
cluster := federationapi.Cluster{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -80,29 +84,29 @@ func createClusterObjectOrFail(f *framework.Framework, context *framework.E2ECon
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := f.FederationClientset_1_5.Federation().Clusters().Create(&cluster)
|
_, err := f.FederationClientset.Federation().Clusters().Create(&cluster)
|
||||||
framework.ExpectNoError(err, fmt.Sprintf("creating cluster: %+v", err))
|
framework.ExpectNoError(err, fmt.Sprintf("creating cluster: %+v", err))
|
||||||
framework.Logf("Successfully created cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
framework.Logf("Successfully created cluster object: %s (%s, secret: %s)", context.Name, context.Cluster.Cluster.Server, context.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func clusterIsReadyOrFail(f *framework.Framework, context *framework.E2EContext) {
|
func clusterIsReadyOrFail(f *fedframework.Framework, context *fedframework.E2EContext) {
|
||||||
c, err := f.FederationClientset_1_5.Federation().Clusters().Get(context.Name, metav1.GetOptions{})
|
c, err := f.FederationClientset.Federation().Clusters().Get(context.Name, metav1.GetOptions{})
|
||||||
framework.ExpectNoError(err, fmt.Sprintf("get cluster: %+v", err))
|
framework.ExpectNoError(err, fmt.Sprintf("get cluster: %+v", err))
|
||||||
if c.ObjectMeta.Name != context.Name {
|
if c.ObjectMeta.Name != context.Name {
|
||||||
framework.Failf("cluster name does not match input context: actual=%+v, expected=%+v", c, context)
|
framework.Failf("cluster name does not match input context: actual=%+v, expected=%+v", c, context)
|
||||||
}
|
}
|
||||||
err = isReady(context.Name, f.FederationClientset_1_5)
|
err = isReady(context.Name, f.FederationClientset)
|
||||||
framework.ExpectNoError(err, fmt.Sprintf("unexpected error in verifying if cluster %s is ready: %+v", context.Name, err))
|
framework.ExpectNoError(err, fmt.Sprintf("unexpected error in verifying if cluster %s is ready: %+v", context.Name, err))
|
||||||
framework.Logf("Cluster %s is Ready", context.Name)
|
framework.Logf("Cluster %s is Ready", context.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForAllClustersReady wait for all clusters defined in e2e context to be created
|
// waitForAllClustersReady wait for all clusters defined in e2e context to be created
|
||||||
// return ClusterList until the listed cluster items equals clusterCount
|
// return ClusterList until the listed cluster items equals clusterCount
|
||||||
func waitForAllClustersReady(f *framework.Framework, clusterCount int) *federationapi.ClusterList {
|
func waitForAllClustersReady(f *fedframework.Framework, clusterCount int) *federationapi.ClusterList {
|
||||||
var clusterList *federationapi.ClusterList
|
var clusterList *federationapi.ClusterList
|
||||||
if err := wait.PollImmediate(framework.Poll, FederatedServiceTimeout, func() (bool, error) {
|
if err := wait.PollImmediate(framework.Poll, FederatedServiceTimeout, func() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
clusterList, err = f.FederationClientset_1_5.Federation().Clusters().List(v1.ListOptions{})
|
clusterList, err = f.FederationClientset.Federation().Clusters().List(v1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -136,7 +140,7 @@ func createClientsetForCluster(c federationapi.Cluster, i int, userAgentName str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates the federation namespace in all underlying clusters.
|
// Creates the federation namespace in all underlying clusters.
|
||||||
func createNamespaceInClusters(clusters map[string]*cluster, f *framework.Framework) {
|
func createNamespaceInClusters(clusters map[string]*cluster, f *fedframework.Framework) {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
for name, c := range clusters {
|
for name, c := range clusters {
|
||||||
// The e2e Framework created the required namespace in federation control plane, but we need to create it in all the others, if it doesn't yet exist.
|
// The e2e Framework created the required namespace in federation control plane, but we need to create it in all the others, if it doesn't yet exist.
|
||||||
@@ -161,7 +165,7 @@ func createNamespaceInClusters(clusters map[string]*cluster, f *framework.Framew
|
|||||||
|
|
||||||
// Unregisters the given clusters from federation control plane.
|
// Unregisters the given clusters from federation control plane.
|
||||||
// Also deletes the federation namespace from each cluster.
|
// Also deletes the federation namespace from each cluster.
|
||||||
func unregisterClusters(clusters map[string]*cluster, f *framework.Framework) {
|
func unregisterClusters(clusters map[string]*cluster, f *fedframework.Framework) {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
for name, c := range clusters {
|
for name, c := range clusters {
|
||||||
if c.namespaceCreated {
|
if c.namespaceCreated {
|
||||||
@@ -174,16 +178,16 @@ func unregisterClusters(clusters map[string]*cluster, f *framework.Framework) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete the registered clusters in the federation API server.
|
// Delete the registered clusters in the federation API server.
|
||||||
clusterList, err := f.FederationClientset_1_5.Federation().Clusters().List(v1.ListOptions{})
|
clusterList, err := f.FederationClientset.Federation().Clusters().List(v1.ListOptions{})
|
||||||
framework.ExpectNoError(err, "Error listing clusters")
|
framework.ExpectNoError(err, "Error listing clusters")
|
||||||
for _, cluster := range clusterList.Items {
|
for _, cluster := range clusterList.Items {
|
||||||
err := f.FederationClientset_1_5.Federation().Clusters().Delete(cluster.Name, &v1.DeleteOptions{})
|
err := f.FederationClientset.Federation().Clusters().Delete(cluster.Name, &v1.DeleteOptions{})
|
||||||
framework.ExpectNoError(err, "Error deleting cluster %q", cluster.Name)
|
framework.ExpectNoError(err, "Error deleting cluster %q", cluster.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// can not be moved to util, as By and Expect must be put in Ginkgo test unit
|
// can not be moved to util, as By and Expect must be put in Ginkgo test unit
|
||||||
func registerClusters(clusters map[string]*cluster, userAgentName, federationName string, f *framework.Framework) string {
|
func registerClusters(clusters map[string]*cluster, userAgentName, federationName string, f *fedframework.Framework) string {
|
||||||
contexts := f.GetUnderlyingFederatedContexts()
|
contexts := f.GetUnderlyingFederatedContexts()
|
||||||
|
|
||||||
for _, context := range contexts {
|
for _, context := range contexts {
|
||||||
@@ -382,7 +386,7 @@ func cleanupServiceShardLoadBalancer(clusterName string, service *v1.Service, ti
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func podExitCodeDetector(f *framework.Framework, name, namespace string, code int32) func() error {
|
func podExitCodeDetector(f *fedframework.Framework, name, namespace string, code int32) func() error {
|
||||||
// If we ever get any container logs, stash them here.
|
// If we ever get any container logs, stash them here.
|
||||||
logs := ""
|
logs := ""
|
||||||
|
|
||||||
@@ -423,7 +427,7 @@ func podExitCodeDetector(f *framework.Framework, name, namespace string, code in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverService(f *framework.Framework, name string, exists bool, podName string) {
|
func discoverService(f *fedframework.Framework, name string, exists bool, podName string) {
|
||||||
command := []string{"sh", "-c", fmt.Sprintf("until nslookup '%s'; do sleep 10; done", name)}
|
command := []string{"sh", "-c", fmt.Sprintf("until nslookup '%s'; do sleep 10; done", name)}
|
||||||
By(fmt.Sprintf("Looking up %q", name))
|
By(fmt.Sprintf("Looking up %q", name))
|
||||||
|
|
48
test/e2e_federation/framework/BUILD
Normal file
48
test/e2e_federation/framework/BUILD
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"framework.go",
|
||||||
|
"util.go",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
|
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||||
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/v1:go_default_library",
|
||||||
|
"//pkg/api/validation:go_default_library",
|
||||||
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
|
"//pkg/client/restclient:go_default_library",
|
||||||
|
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||||
|
"//test/e2e/framework:go_default_library",
|
||||||
|
"//vendor:github.com/onsi/ginkgo",
|
||||||
|
"//vendor:github.com/onsi/gomega",
|
||||||
|
"//vendor:gopkg.in/yaml.v2",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/validation",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
213
test/e2e_federation/framework/framework.go
Normal file
213
test/e2e_federation/framework/framework.go
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 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 framework
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Framework extends e2e Framework and adds federation specific fields
|
||||||
|
type Framework struct {
|
||||||
|
*framework.Framework
|
||||||
|
|
||||||
|
FederationClientset *federation_clientset.Clientset
|
||||||
|
FederationNamespace *v1.Namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultFederatedFramework(baseName string) *Framework {
|
||||||
|
f := &Framework{framework.NewDefaultFramework(baseName), nil, &v1.Namespace{}}
|
||||||
|
|
||||||
|
BeforeEach(f.FederationBeforeEach)
|
||||||
|
AfterEach(f.FederationAfterEach)
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// FederationBeforeEach checks for federation apiserver is ready and makes a namespace.
|
||||||
|
func (f *Framework) FederationBeforeEach() {
|
||||||
|
if f.FederationClientset == nil {
|
||||||
|
By("Creating a release 1.5 federation Clientset")
|
||||||
|
var err error
|
||||||
|
f.FederationClientset, err = LoadFederationClientset()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
By("Waiting for federation-apiserver to be ready")
|
||||||
|
err := WaitForFederationApiserverReady(f.FederationClientset)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
By("federation-apiserver is ready")
|
||||||
|
|
||||||
|
By("Creating a federation namespace")
|
||||||
|
ns, err := f.createFederationNamespace(f.BaseName)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
f.FederationNamespace = ns
|
||||||
|
By(fmt.Sprintf("Created federation namespace %s", ns.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Framework) deleteFederationNs() {
|
||||||
|
ns := f.FederationNamespace
|
||||||
|
By(fmt.Sprintf("Destroying federation namespace %q for this suite.", ns.Name))
|
||||||
|
timeout := 5 * time.Minute
|
||||||
|
if f.NamespaceDeletionTimeout != 0 {
|
||||||
|
timeout = f.NamespaceDeletionTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
clientset := f.FederationClientset
|
||||||
|
// First delete the namespace from federation apiserver.
|
||||||
|
// Also delete the corresponding namespaces from underlying clusters.
|
||||||
|
orphanDependents := false
|
||||||
|
if err := clientset.Core().Namespaces().Delete(ns.Name, &v1.DeleteOptions{OrphanDependents: &orphanDependents}); err != nil {
|
||||||
|
framework.Failf("Error while deleting federation namespace %s: %s", ns.Name, err)
|
||||||
|
}
|
||||||
|
// Verify that it got deleted.
|
||||||
|
err := wait.PollImmediate(5*time.Second, timeout, func() (bool, error) {
|
||||||
|
if _, err := clientset.Core().Namespaces().Get(ns.Name, metav1.GetOptions{}); err != nil {
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
framework.Logf("Error while waiting for namespace to be terminated: %v", err)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if !apierrors.IsNotFound(err) {
|
||||||
|
framework.Failf("Couldn't delete ns %q: %s", ns.Name, err)
|
||||||
|
} else {
|
||||||
|
framework.Logf("Namespace %v was already deleted", ns.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FederationAfterEach deletes the namespace, after reading its events.
|
||||||
|
func (f *Framework) FederationAfterEach() {
|
||||||
|
// DeleteNamespace at the very end in defer, to avoid any
|
||||||
|
// expectation failures preventing deleting the namespace.
|
||||||
|
defer func() {
|
||||||
|
// Whether to delete namespace is determined by 3 factors: delete-namespace flag, delete-namespace-on-failure flag and the test result
|
||||||
|
// if delete-namespace set to false, namespace will always be preserved.
|
||||||
|
// if delete-namespace is true and delete-namespace-on-failure is false, namespace will be preserved if test failed.
|
||||||
|
if framework.TestContext.DeleteNamespace && (framework.TestContext.DeleteNamespaceOnFailure || !CurrentGinkgoTestDescription().Failed) {
|
||||||
|
// Delete the federation namespace.
|
||||||
|
f.deleteFederationNs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paranoia-- prevent reuse!
|
||||||
|
f.FederationNamespace = nil
|
||||||
|
|
||||||
|
if f.FederationClientset == nil {
|
||||||
|
framework.Logf("Warning: framework is marked federated, but has no federation 1.5 clientset")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := f.FederationClientset.Federation().Clusters().DeleteCollection(nil, v1.ListOptions{}); err != nil {
|
||||||
|
framework.Logf("Error: failed to delete Clusters: %+v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Print events if the test failed.
|
||||||
|
if CurrentGinkgoTestDescription().Failed && framework.TestContext.DumpLogsOnFailure {
|
||||||
|
// Dump federation events in federation namespace.
|
||||||
|
framework.DumpEventsInNamespace(func(opts v1.ListOptions, ns string) (*v1.EventList, error) {
|
||||||
|
return f.FederationClientset.Core().Events(ns).List(opts)
|
||||||
|
}, f.FederationNamespace.Name)
|
||||||
|
// Print logs of federation control plane pods (federation-apiserver and federation-controller-manager)
|
||||||
|
framework.LogPodsWithLabels(f.ClientSet, "federation", map[string]string{"app": "federated-cluster"}, framework.Logf)
|
||||||
|
// Print logs of kube-dns pod
|
||||||
|
framework.LogPodsWithLabels(f.ClientSet, "kube-system", map[string]string{"k8s-app": "kube-dns"}, framework.Logf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Framework) createFederationNamespace(baseName string) (*v1.Namespace, error) {
|
||||||
|
clientset := f.FederationClientset
|
||||||
|
namespaceObj := &v1.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
GenerateName: fmt.Sprintf("e2e-tests-%v-", baseName),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Be robust about making the namespace creation call.
|
||||||
|
var got *v1.Namespace
|
||||||
|
if err := wait.PollImmediate(framework.Poll, framework.SingleCallTimeout, func() (bool, error) {
|
||||||
|
var err error
|
||||||
|
got, err = clientset.Core().Namespaces().Create(namespaceObj)
|
||||||
|
if err != nil {
|
||||||
|
framework.Logf("Unexpected error while creating namespace: %v", err)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return got, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type E2EContext struct {
|
||||||
|
// Raw context name,
|
||||||
|
RawName string `yaml:"rawName"`
|
||||||
|
// A valid dns subdomain which can be used as the name of kubernetes resources.
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Cluster *framework.KubeCluster `yaml:"cluster"`
|
||||||
|
User *framework.KubeUser `yaml:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Framework) GetUnderlyingFederatedContexts() []E2EContext {
|
||||||
|
kubeconfig := framework.KubeConfig{}
|
||||||
|
configBytes, err := ioutil.ReadFile(framework.TestContext.KubeConfig)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
err = yaml.Unmarshal(configBytes, &kubeconfig)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
|
||||||
|
e2eContexts := []E2EContext{}
|
||||||
|
for _, context := range kubeconfig.Contexts {
|
||||||
|
if strings.HasPrefix(context.Name, "federation") && context.Name != framework.TestContext.FederatedKubeContext {
|
||||||
|
user := kubeconfig.FindUser(context.Context.User)
|
||||||
|
if user == nil {
|
||||||
|
framework.Failf("Could not find user for context %+v", context)
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster := kubeconfig.FindCluster(context.Context.Cluster)
|
||||||
|
if cluster == nil {
|
||||||
|
framework.Failf("Could not find cluster for context %+v", context)
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsSubdomainName, err := GetValidDNSSubdomainName(context.Name)
|
||||||
|
if err != nil {
|
||||||
|
framework.Failf("Could not convert context name %s to a valid dns subdomain name, error: %s", context.Name, err)
|
||||||
|
}
|
||||||
|
e2eContexts = append(e2eContexts, E2EContext{
|
||||||
|
RawName: context.Name,
|
||||||
|
Name: dnsSubdomainName,
|
||||||
|
Cluster: cluster,
|
||||||
|
User: user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e2eContexts
|
||||||
|
}
|
113
test/e2e_federation/framework/util.go
Normal file
113
test/e2e_federation/framework/util.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 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 framework
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
validationutil "k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||||
|
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Detects whether the federation namespace exists in the underlying cluster
|
||||||
|
func SkipUnlessFederated(c clientset.Interface) {
|
||||||
|
federationNS := os.Getenv("FEDERATION_NAMESPACE")
|
||||||
|
if federationNS == "" {
|
||||||
|
federationNS = federationapi.FederationNamespaceSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := c.Core().Namespaces().Get(federationNS, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
framework.Skipf("Could not find federation namespace %s: skipping federated test", federationNS)
|
||||||
|
} else {
|
||||||
|
framework.Failf("Unexpected error getting namespace: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForFederationApiserverReady waits for the federation apiserver to be ready.
|
||||||
|
// It tests the readiness by sending a GET request and expecting a non error response.
|
||||||
|
func WaitForFederationApiserverReady(c *federation_clientset.Clientset) error {
|
||||||
|
return wait.PollImmediate(time.Second, 1*time.Minute, func() (bool, error) {
|
||||||
|
_, err := c.Federation().Clusters().List(v1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFederationClientset() (*federation_clientset.Clientset, error) {
|
||||||
|
config, err := LoadFederatedConfig(&clientcmd.ConfigOverrides{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := federation_clientset.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating federation clientset: %v", err.Error())
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFederatedConfig(overrides *clientcmd.ConfigOverrides) (*restclient.Config, error) {
|
||||||
|
c, err := framework.RestclientConfig(framework.TestContext.FederatedKubeContext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating federation client config: %v", err.Error())
|
||||||
|
}
|
||||||
|
cfg, err := clientcmd.NewDefaultClientConfig(*c, overrides).ClientConfig()
|
||||||
|
if cfg != nil {
|
||||||
|
//TODO(colhom): this is only here because https://github.com/kubernetes/kubernetes/issues/25422
|
||||||
|
cfg.NegotiatedSerializer = api.Codecs
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return cfg, fmt.Errorf("error creating federation default client config: %v", err.Error())
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetValidDNSSubdomainName massages the given name to be a valid dns subdomain name.
|
||||||
|
// Most resources (such as secrets, clusters) require the names to be valid dns subdomain.
|
||||||
|
// This is a generic function (not specific to federation). Should be moved to a more generic location if others want to use it.
|
||||||
|
func GetValidDNSSubdomainName(name string) (string, error) {
|
||||||
|
// "_" are not allowed. Replace them by "-".
|
||||||
|
name = regexp.MustCompile("_").ReplaceAllLiteralString(name, "-")
|
||||||
|
maxLength := validationutil.DNS1123SubdomainMaxLength
|
||||||
|
if len(name) > maxLength {
|
||||||
|
name = name[0 : maxLength-1]
|
||||||
|
}
|
||||||
|
// Verify that name now passes the validation.
|
||||||
|
if errors := validation.NameIsDNSSubdomain(name, false); len(errors) != 0 {
|
||||||
|
return "", fmt.Errorf("errors in converting name to a valid DNS subdomain %s", errors)
|
||||||
|
}
|
||||||
|
return name, nil
|
||||||
|
}
|
Reference in New Issue
Block a user