Replace godep with dep

This commit is contained in:
Manuel de Brito Fontes 2017-10-06 17:26:14 -03:00
parent 1e7489927c
commit bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions

View file

@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"cluster.go",
"crudtester.go",
"framework.go",
"util.go",
],
deps = [
"//federation/apis/federation/v1beta1:go_default_library",
"//federation/client/clientset_generated/federation_clientset:go_default_library",
"//federation/pkg/federatedtypes:go_default_library",
"//federation/pkg/federatedtypes/crudtester:go_default_library",
"//federation/pkg/federation-controller/util:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/validation:go_default_library",
"//test/e2e/framework:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,240 @@
/*
Copyright 2017 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"
"strings"
"time"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
kubeclientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/test/e2e/framework"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
const federatedClustersWaitTimeout = 1 * time.Minute
// ClusterSlice is a slice of clusters
type ClusterSlice []*Cluster
// Cluster keeps track of the name and client of a cluster in the federation
type Cluster struct {
Name string
*kubeclientset.Clientset
}
// registeredClustersFromConfig configures clientsets for registered clusters from the e2e kubeconfig
func registeredClustersFromConfig(f *Framework) ClusterSlice {
contexts := f.GetUnderlyingFederatedContexts()
By("Obtaining a list of all the clusters")
clusterList := waitForAllRegisteredClusters(f, len(contexts))
framework.Logf("Checking that %d clusters are Ready", len(contexts))
for _, context := range contexts {
ClusterIsReadyOrFail(f, context.Name)
}
framework.Logf("%d clusters are Ready", len(contexts))
clusters := ClusterSlice{}
for i, c := range clusterList.Items {
framework.Logf("Creating a clientset for the cluster %s", c.Name)
Expect(framework.TestContext.KubeConfig).ToNot(Equal(""), "KubeConfig must be specified to load clusters' client config")
config := restConfigFromContext(c, i)
clusters = append(clusters, &Cluster{
Name: c.Name,
Clientset: clientsetFromConfig(f, config, c.Spec.ServerAddressByClientCIDRs[0].ServerAddress),
})
}
waitForNamespaceInFederatedClusters(clusters, f.FederationNamespace.Name)
return clusters
}
// waitForAllRegisteredClusters waits for all clusters defined in e2e context to be created
// return ClusterList until the listed cluster items equals clusterCount
func waitForAllRegisteredClusters(f *Framework, clusterCount int) *federationapi.ClusterList {
var clusterList *federationapi.ClusterList
if err := wait.PollImmediate(framework.Poll, federatedClustersWaitTimeout, func() (bool, error) {
var err error
clusterList, err = f.FederationClientset.Federation().Clusters().List(metav1.ListOptions{})
if err != nil {
return false, err
}
framework.Logf("%d clusters registered, waiting for %d", len(clusterList.Items), clusterCount)
if len(clusterList.Items) == clusterCount {
return true, nil
}
return false, nil
}); err != nil {
framework.Failf("Failed to list registered clusters: %+v", err)
}
return clusterList
}
func restConfigFromContext(c federationapi.Cluster, i int) *restclient.Config {
kubecfg, err := clientcmd.LoadFromFile(framework.TestContext.KubeConfig)
framework.ExpectNoError(err, "error loading KubeConfig: %v", err)
ccfg := clientcmd.NewNonInteractiveClientConfig(*kubecfg, c.Name, &clientcmd.ConfigOverrides{}, clientcmd.NewDefaultClientConfigLoadingRules())
cfg, err := ccfg.ClientConfig()
framework.ExpectNoError(err, "Error creating client config in cluster #%d (%q)", i, c.Name)
return cfg
}
func clientsetFromConfig(f *Framework, cfg *restclient.Config, host string) *kubeclientset.Clientset {
cfg.Host = host
cfg.QPS = f.Framework.Options.ClientQPS
cfg.Burst = f.Framework.Options.ClientBurst
return kubeclientset.NewForConfigOrDie(restclient.AddUserAgent(cfg, "federation-e2e"))
}
// waitForNamespaceInFederatedClusters waits for the federated namespace to be created in federated clusters
func waitForNamespaceInFederatedClusters(clusters ClusterSlice, nsName string) {
for _, c := range clusters {
name := c.Name
By(fmt.Sprintf("Waiting for namespace %q to be created in cluster %q", nsName, name))
err := wait.PollImmediate(framework.Poll, FederatedDefaultTestTimeout, func() (bool, error) {
_, err := c.Clientset.CoreV1().Namespaces().Get(nsName, metav1.GetOptions{})
if errors.IsNotFound(err) {
return false, nil
} else if err != nil {
framework.Logf("An error occurred waiting for namespace %q to be created in cluster %q: %v", nsName, name, err)
return false, nil
}
By(fmt.Sprintf("Namespace %q exists in cluster %q", nsName, name))
return true, nil
})
framework.ExpectNoError(err, "Failed to verify federated namespace %q creation in cluster %q", nsName, name)
}
}
// ClusterIsReadyOrFail checks whether the named cluster is ready
func ClusterIsReadyOrFail(f *Framework, clusterName string) {
By(fmt.Sprintf("Checking readiness of cluster %q", clusterName))
err := wait.PollImmediate(framework.Poll, FederatedDefaultTestTimeout, func() (bool, error) {
c, err := f.FederationClientset.Federation().Clusters().Get(clusterName, metav1.GetOptions{})
if err != nil {
return false, err
}
for _, condition := range c.Status.Conditions {
if condition.Type == federationapi.ClusterReady && condition.Status == v1.ConditionTrue {
return true, nil
}
}
return false, nil
})
framework.ExpectNoError(err, fmt.Sprintf("Unexpected error in verifying if cluster %q is ready: %+v", clusterName, err))
framework.Logf("Cluster %s is Ready", clusterName)
}
// Cache the cluster config to avoid having to retrieve it for each test
type clusterConfig struct {
name string
host string
config []byte
}
var cachedClusterConfigs []*clusterConfig
// registeredClustersFromSecrets configures clientsets for cluster access from secrets in the host cluster
func registeredClustersFromSecrets(f *Framework) ClusterSlice {
if cachedClusterConfigs == nil {
cachedClusterConfigs = clusterConfigFromSecrets(f)
}
clusters := ClusterSlice{}
for _, clusterConf := range cachedClusterConfigs {
restConfig := restConfigForCluster(clusterConf)
clientset := clientsetFromConfig(f, restConfig, clusterConf.host)
clusters = append(clusters, &Cluster{
Name: clusterConf.name,
Clientset: clientset,
})
}
waitForNamespaceInFederatedClusters(clusters, f.FederationNamespace.Name)
return clusters
}
// clusterConfigFromSecrets retrieves cluster configuration from
// secrets in the host cluster
func clusterConfigFromSecrets(f *Framework) []*clusterConfig {
By("Obtaining a list of registered clusters")
clusterList, err := f.FederationClientset.Federation().Clusters().List(metav1.ListOptions{})
framework.ExpectNoError(err, fmt.Sprintf("Error retrieving list of federated clusters: %+v", err))
if len(clusterList.Items) == 0 {
framework.Failf("No registered clusters found")
}
clusterConfigs := []*clusterConfig{}
for _, c := range clusterList.Items {
ClusterIsReadyOrFail(f, c.Name)
config := clusterConfigFromSecret(f, c.Name, c.Spec.SecretRef.Name)
clusterConfigs = append(clusterConfigs, &clusterConfig{
name: c.Name,
host: c.Spec.ServerAddressByClientCIDRs[0].ServerAddress,
config: config,
})
}
return clusterConfigs
}
// clusterConfigFromSecret retrieves configuration for a accessing a
// cluster from a secret in the host cluster
func clusterConfigFromSecret(f *Framework, clusterName string, secretName string) []byte {
By(fmt.Sprintf("Loading configuration for cluster %q", clusterName))
namespace := framework.FederationSystemNamespace()
secret, err := f.Framework.ClientSet.Core().Secrets(namespace).Get(secretName, metav1.GetOptions{})
framework.ExpectNoError(err, fmt.Sprintf("Error loading config secret \"%s/%s\" for cluster %q: %+v", namespace, secretName, clusterName, err))
config, ok := secret.Data[util.KubeconfigSecretDataKey]
if !ok || len(config) == 0 {
framework.Failf("Secret \"%s/%s\" for cluster %q has no value for key %q", namespace, secretName, clusterName, util.KubeconfigSecretDataKey)
}
return config
}
// restConfigForCluster creates a rest client config for the given cluster config
func restConfigForCluster(clusterConf *clusterConfig) *restclient.Config {
cfg, err := clientcmd.Load(clusterConf.config)
framework.ExpectNoError(err, fmt.Sprintf("Error loading configuration for cluster %q: %+v", clusterConf.name, err))
restConfig, err := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{}).ClientConfig()
framework.ExpectNoError(err, fmt.Sprintf("Error creating client for cluster %q: %+v", clusterConf.name, err))
return restConfig
}
func GetZoneFromClusterName(clusterName string) string {
// Ref: https://github.com/kubernetes/kubernetes/blob/master/cluster/kube-util.sh#L55
prefix := "federation-e2e-" + framework.TestContext.Provider + "-"
return strings.TrimPrefix(clusterName, prefix)
}

View file

@ -0,0 +1,44 @@
/*
Copyright 2017 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 (
. "github.com/onsi/ginkgo"
kubeclientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/federation/pkg/federatedtypes"
"k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester"
"k8s.io/kubernetes/test/e2e/framework"
)
// Adapt the methods to log/fail in e2e to the interface expected by CRUDHelper
type e2eTestLogger struct{}
func (e2eTestLogger) Fatal(msg string) {
Fail(msg)
}
func (e2eTestLogger) Fatalf(format string, args ...interface{}) {
framework.Failf(format, args...)
}
func (e2eTestLogger) Logf(format string, args ...interface{}) {
framework.Logf(format, args...)
}
func NewFederatedTypeCRUDTester(adapter federatedtypes.FederatedTypeAdapter, clusterClients []kubeclientset.Interface) *crudtester.FederatedTypeCRUDTester {
return crudtester.NewFederatedTypeCRUDTester(&e2eTestLogger{}, adapter, clusterClients, framework.Poll, FederatedDefaultTestTimeout)
}

View file

@ -0,0 +1,256 @@
/*
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"
"k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
kubeclientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"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
// To make sure that this framework cleans up after itself, no matter what,
// we install a Cleanup action before each test and clear it after. If we
// should abort, the AfterSuite hook should run all Cleanup actions.
cleanupHandle framework.CleanupActionHandle
FederationConfig *restclient.Config
FederationClientset *federation_clientset.Clientset
FederationNamespace *v1.Namespace
}
func NewDefaultFederatedFramework(baseName string) *Framework {
f := &Framework{}
// Register the federation cleanup before initializing the default
// e2e framework to ensure it gets called before the default
// framework's cleanup.
AfterEach(f.FederationAfterEach)
f.Framework = framework.NewDefaultFramework(baseName)
f.Framework.SkipNamespaceCreation = true
// Register the federation setup after initializing the default
// e2e framework to ensure it gets called after the default
// framework's setup.
BeforeEach(f.FederationBeforeEach)
return f
}
// FederationBeforeEach checks for federation apiserver is ready and makes a namespace.
func (f *Framework) FederationBeforeEach() {
// The fact that we need this feels like a bug in ginkgo.
// https://github.com/onsi/ginkgo/issues/222
f.cleanupHandle = framework.AddCleanupAction(f.FederationAfterEach)
if f.FederationConfig == nil {
By("Reading the federation configuration")
var err error
f.FederationConfig, err = LoadFederatedConfig(&clientcmd.ConfigOverrides{})
Expect(err).NotTo(HaveOccurred())
}
if f.FederationClientset == nil {
By("Creating a release 1.5 federation Clientset")
var err error
f.FederationClientset, err = LoadFederationClientset(f.FederationConfig)
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, &metav1.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() {
framework.RemoveCleanupAction(f.cleanupHandle)
// 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
}
}()
// Print events if the test failed.
if CurrentGinkgoTestDescription().Failed && framework.TestContext.DumpLogsOnFailure {
// Dump federation events in federation namespace.
framework.DumpEventsInNamespace(func(opts metav1.ListOptions, ns string) (*v1.EventList, error) {
return f.FederationClientset.Core().Events(ns).List(opts)
}, f.FederationNamespace.Name)
}
}
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
}
func (f *Framework) GetRegisteredClusters() ClusterSlice {
if framework.TestContext.FederationConfigFromCluster {
return registeredClustersFromSecrets(f)
} else {
return registeredClustersFromConfig(f)
}
}
func (f *Framework) GetClusterClients() []kubeclientset.Interface {
clusters := f.GetRegisteredClusters()
var clusterClients []kubeclientset.Interface
for _, c := range clusters {
clusterClients = append(clusterClients, c.Clientset)
}
return clusterClients
}

View file

@ -0,0 +1,150 @@
/*
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"
"path"
"regexp"
"strings"
"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"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/test/e2e/framework"
)
const FederatedDefaultTestTimeout = 5 * time.Minute
// Detects whether the federation namespace exists in the underlying cluster
func SkipUnlessFederated(c clientset.Interface) {
federationNS := framework.FederationSystemNamespace()
_, 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(metav1.ListOptions{})
if err != nil {
return false, nil
}
return true, nil
})
}
func LoadFederationClientset(config *restclient.Config) (*federation_clientset.Clientset, error) {
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, &clientcmd.ConfigOverrides{}).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
}
func FederationControlPlaneUpgrade(version string) error {
version = "v" + version
_, _, err := framework.RunCmd(path.Join(framework.TestContext.RepoRoot, "federation/cluster/upgrade.sh"), version)
return err
}
func CheckFederationVersion(c federation_clientset.Interface, want string) error {
framework.Logf("Checking federation version")
v, err := c.Discovery().ServerVersion()
if err != nil {
return fmt.Errorf("CheckFederationVersion() couldn't get the master version: %v", err)
}
// We do prefix trimming and then matching because:
// want looks like: 0.19.3-815-g50e67d4
// got looks like: v0.19.3-815-g50e67d4034e858-dirty
got := strings.TrimPrefix(v.GitVersion, "v")
if !strings.HasPrefix(got, want) {
return fmt.Errorf("federation had apiserver version %s which does not start with %s",
got, want)
}
framework.Logf("Federation is at version %s", want)
return nil
}
func MasterUpgrade(context, version string) error {
switch framework.TestContext.Provider {
case "gce":
return masterUpgradeGCE(context, version)
default:
return fmt.Errorf("MasterUpgrade() is not implemented for provider %s", framework.TestContext.Provider)
}
}
func masterUpgradeGCE(context, rawVersion string) error {
version := "v" + rawVersion
// TODO: this breaks if we want to upgrade 2 clusters in same zone. use alternate methods in future to get zone of a cluster
zone := strings.TrimPrefix(context, "federation-e2e-"+framework.TestContext.Provider+"-")
env := append(os.Environ(), "KUBE_CONTEXT="+context, "ZONE="+zone)
_, _, err := framework.RunCmdEnv(env, path.Join(framework.TestContext.RepoRoot, "cluster/gce/upgrade.sh"), "-M", version)
return err
}