test_context.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package framework
  14. import (
  15. "flag"
  16. "fmt"
  17. "io/ioutil"
  18. "os"
  19. "sort"
  20. "strings"
  21. "time"
  22. "github.com/onsi/ginkgo/config"
  23. "github.com/pkg/errors"
  24. restclient "k8s.io/client-go/rest"
  25. "k8s.io/client-go/tools/clientcmd"
  26. clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
  27. cliflag "k8s.io/component-base/cli/flag"
  28. "k8s.io/klog"
  29. kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
  30. e2elog "k8s.io/kubernetes/test/e2e/framework/log"
  31. )
  32. const (
  33. defaultHost = "http://127.0.0.1:8080"
  34. // DefaultNumNodes is the number of nodes. If not specified, then number of nodes is auto-detected
  35. DefaultNumNodes = -1
  36. )
  37. // TestContextType contains test settings and global state. Due to
  38. // historic reasons, it is a mixture of items managed by the test
  39. // framework itself, cloud providers and individual tests.
  40. // The goal is to move anything not required by the framework
  41. // into the code which uses the settings.
  42. //
  43. // The recommendation for those settings is:
  44. // - They are stored in their own context structure or local
  45. // variables.
  46. // - The standard `flag` package is used to register them.
  47. // The flag name should follow the pattern <part1>.<part2>....<partn>
  48. // where the prefix is unlikely to conflict with other tests or
  49. // standard packages and each part is in lower camel case. For
  50. // example, test/e2e/storage/csi/context.go could define
  51. // storage.csi.numIterations.
  52. // - framework/config can be used to simplify the registration of
  53. // multiple options with a single function call:
  54. // var storageCSI {
  55. // NumIterations `default:"1" usage:"number of iterations"`
  56. // }
  57. // _ config.AddOptions(&storageCSI, "storage.csi")
  58. // - The direct use Viper in tests is possible, but discouraged because
  59. // it only works in test suites which use Viper (which is not
  60. // required) and the supported options cannot be
  61. // discovered by a test suite user.
  62. //
  63. // Test suite authors can use framework/viper to make all command line
  64. // parameters also configurable via a configuration file.
  65. type TestContextType struct {
  66. KubeConfig string
  67. KubeContext string
  68. KubeAPIContentType string
  69. KubeVolumeDir string
  70. CertDir string
  71. Host string
  72. // TODO: Deprecating this over time... instead just use gobindata_util.go , see #23987.
  73. RepoRoot string
  74. DockershimCheckpointDir string
  75. // ListImages will list off all images that are used then quit
  76. ListImages bool
  77. // Provider identifies the infrastructure provider (gce, gke, aws)
  78. Provider string
  79. // Tooling is the tooling in use (e.g. kops, gke). Provider is the cloud provider and might not uniquely identify the tooling.
  80. Tooling string
  81. CloudConfig CloudConfig
  82. KubectlPath string
  83. OutputDir string
  84. ReportDir string
  85. ReportPrefix string
  86. Prefix string
  87. MinStartupPods int
  88. // Timeout for waiting for system pods to be running
  89. SystemPodsStartupTimeout time.Duration
  90. EtcdUpgradeStorage string
  91. EtcdUpgradeVersion string
  92. GCEUpgradeScript string
  93. ContainerRuntime string
  94. ContainerRuntimeEndpoint string
  95. ContainerRuntimeProcessName string
  96. ContainerRuntimePidFile string
  97. // SystemdServices are comma separated list of systemd services the test framework
  98. // will dump logs for.
  99. SystemdServices string
  100. // DumpSystemdJournal controls whether to dump the full systemd journal.
  101. DumpSystemdJournal bool
  102. ImageServiceEndpoint string
  103. MasterOSDistro string
  104. NodeOSDistro string
  105. VerifyServiceAccount bool
  106. DeleteNamespace bool
  107. DeleteNamespaceOnFailure bool
  108. AllowedNotReadyNodes int
  109. CleanStart bool
  110. // If set to 'true' or 'all' framework will start a goroutine monitoring resource usage of system add-ons.
  111. // It will read the data every 30 seconds from all Nodes and print summary during afterEach. If set to 'master'
  112. // only master Node will be monitored.
  113. GatherKubeSystemResourceUsageData string
  114. GatherLogsSizes bool
  115. GatherMetricsAfterTest string
  116. GatherSuiteMetricsAfterTest bool
  117. MaxNodesToGather int
  118. AllowGatheringProfiles bool
  119. // If set to 'true' framework will gather ClusterAutoscaler metrics when gathering them for other components.
  120. IncludeClusterAutoscalerMetrics bool
  121. // Currently supported values are 'hr' for human-readable and 'json'. It's a comma separated list.
  122. OutputPrintType string
  123. // NodeSchedulableTimeout is the timeout for waiting for all nodes to be schedulable.
  124. NodeSchedulableTimeout time.Duration
  125. // SystemDaemonsetStartupTimeout is the timeout for waiting for all system daemonsets to be ready.
  126. SystemDaemonsetStartupTimeout time.Duration
  127. // CreateTestingNS is responsible for creating namespace used for executing e2e tests.
  128. // It accepts namespace base name, which will be prepended with e2e prefix, kube client
  129. // and labels to be applied to a namespace.
  130. CreateTestingNS CreateTestingNSFn
  131. // If set to true test will dump data about the namespace in which test was running.
  132. DumpLogsOnFailure bool
  133. // Disables dumping cluster log from master and nodes after all tests.
  134. DisableLogDump bool
  135. // Path to the GCS artifacts directory to dump logs from nodes. Logexporter gets enabled if this is non-empty.
  136. LogexporterGCSPath string
  137. // featureGates is a map of feature names to bools that enable or disable alpha/experimental features.
  138. FeatureGates map[string]bool
  139. // Node e2e specific test context
  140. NodeTestContextType
  141. // Monitoring solution that is used in current cluster.
  142. ClusterMonitoringMode string
  143. // Separate Prometheus monitoring deployed in cluster
  144. EnablePrometheusMonitoring bool
  145. // Indicates what path the kubernetes-anywhere is installed on
  146. KubernetesAnywherePath string
  147. // The DNS Domain of the cluster.
  148. ClusterDNSDomain string
  149. // The configration of NodeKiller.
  150. NodeKiller NodeKillerConfig
  151. }
  152. // NodeKillerConfig describes configuration of NodeKiller -- a utility to
  153. // simulate node failures.
  154. type NodeKillerConfig struct {
  155. // Enabled determines whether NodeKill should do anything at all.
  156. // All other options below are ignored if Enabled = false.
  157. Enabled bool
  158. // FailureRatio is a percentage of all nodes that could fail simultinously.
  159. FailureRatio float64
  160. // Interval is time between node failures.
  161. Interval time.Duration
  162. // JitterFactor is factor used to jitter node failures.
  163. // Node will be killed between [Interval, Interval + (1.0 + JitterFactor)].
  164. JitterFactor float64
  165. // SimulatedDowntime is a duration between node is killed and recreated.
  166. SimulatedDowntime time.Duration
  167. }
  168. // NodeTestContextType is part of TestContextType, it is shared by all node e2e test.
  169. type NodeTestContextType struct {
  170. // NodeE2E indicates whether it is running node e2e.
  171. NodeE2E bool
  172. // Name of the node to run tests on.
  173. NodeName string
  174. // NodeConformance indicates whether the test is running in node conformance mode.
  175. NodeConformance bool
  176. // PrepullImages indicates whether node e2e framework should prepull images.
  177. PrepullImages bool
  178. // KubeletConfig is the kubelet configuration the test is running against.
  179. KubeletConfig kubeletconfig.KubeletConfiguration
  180. // ImageDescription is the description of the image on which the test is running.
  181. ImageDescription string
  182. // SystemSpecName is the name of the system spec (e.g., gke) that's used in
  183. // the node e2e test. If empty, the default one (system.DefaultSpec) is
  184. // used. The system specs are in test/e2e_node/system/specs/.
  185. SystemSpecName string
  186. // ExtraEnvs is a map of environment names to values.
  187. ExtraEnvs map[string]string
  188. }
  189. // CloudConfig holds the cloud configuration for e2e test suites.
  190. type CloudConfig struct {
  191. APIEndpoint string
  192. ProjectID string
  193. Zone string // for multizone tests, arbitrarily chosen zone
  194. Region string
  195. MultiZone bool
  196. MultiMaster bool
  197. Cluster string
  198. MasterName string
  199. NodeInstanceGroup string // comma-delimited list of groups' names
  200. NumNodes int
  201. ClusterIPRange string
  202. ClusterTag string
  203. Network string
  204. ConfigFile string // for azure and openstack
  205. NodeTag string
  206. MasterTag string
  207. Provider ProviderInterface
  208. }
  209. // TestContext should be used by all tests to access common context data.
  210. var TestContext TestContextType
  211. // RegisterCommonFlags registers flags common to all e2e test suites.
  212. func RegisterCommonFlags() {
  213. // Turn on verbose by default to get spec names
  214. config.DefaultReporterConfig.Verbose = true
  215. // Turn on EmitSpecProgress to get spec progress (especially on interrupt)
  216. config.GinkgoConfig.EmitSpecProgress = true
  217. // Randomize specs as well as suites
  218. config.GinkgoConfig.RandomizeAllSpecs = true
  219. flag.StringVar(&TestContext.GatherKubeSystemResourceUsageData, "gather-resource-usage", "false", "If set to 'true' or 'all' framework will be monitoring resource usage of system all add-ons in (some) e2e tests, if set to 'master' framework will be monitoring master node only, if set to 'none' of 'false' monitoring will be turned off.")
  220. flag.BoolVar(&TestContext.GatherLogsSizes, "gather-logs-sizes", false, "If set to true framework will be monitoring logs sizes on all machines running e2e tests.")
  221. flag.IntVar(&TestContext.MaxNodesToGather, "max-nodes-to-gather-from", 20, "The maximum number of nodes to gather extended info from on test failure.")
  222. flag.StringVar(&TestContext.GatherMetricsAfterTest, "gather-metrics-at-teardown", "false", "If set to 'true' framework will gather metrics from all components after each test. If set to 'master' only master component metrics would be gathered.")
  223. flag.BoolVar(&TestContext.GatherSuiteMetricsAfterTest, "gather-suite-metrics-at-teardown", false, "If set to true framwork will gather metrics from all components after the whole test suite completes.")
  224. flag.BoolVar(&TestContext.AllowGatheringProfiles, "allow-gathering-profiles", true, "If set to true framework will allow to gather CPU/memory allocation pprof profiles from the master.")
  225. flag.BoolVar(&TestContext.IncludeClusterAutoscalerMetrics, "include-cluster-autoscaler", false, "If set to true, framework will include Cluster Autoscaler when gathering metrics.")
  226. flag.StringVar(&TestContext.OutputPrintType, "output-print-type", "json", "Format in which summaries should be printed: 'hr' for human readable, 'json' for JSON ones.")
  227. flag.BoolVar(&TestContext.DumpLogsOnFailure, "dump-logs-on-failure", true, "If set to true test will dump data about the namespace in which test was running.")
  228. flag.BoolVar(&TestContext.DisableLogDump, "disable-log-dump", false, "If set to true, logs from master and nodes won't be gathered after test run.")
  229. flag.StringVar(&TestContext.LogexporterGCSPath, "logexporter-gcs-path", "", "Path to the GCS artifacts directory to dump logs from nodes. Logexporter gets enabled if this is non-empty.")
  230. flag.BoolVar(&TestContext.DeleteNamespace, "delete-namespace", true, "If true tests will delete namespace after completion. It is only designed to make debugging easier, DO NOT turn it off by default.")
  231. flag.BoolVar(&TestContext.DeleteNamespaceOnFailure, "delete-namespace-on-failure", true, "If true, framework will delete test namespace on failure. Used only during test debugging.")
  232. flag.IntVar(&TestContext.AllowedNotReadyNodes, "allowed-not-ready-nodes", 0, "If non-zero, framework will allow for that many non-ready nodes when checking for all ready nodes.")
  233. flag.StringVar(&TestContext.Host, "host", "", fmt.Sprintf("The host, or apiserver, to connect to. Will default to %s if this argument and --kubeconfig are not set", defaultHost))
  234. flag.StringVar(&TestContext.ReportPrefix, "report-prefix", "", "Optional prefix for JUnit XML reports. Default is empty, which doesn't prepend anything to the default name.")
  235. flag.StringVar(&TestContext.ReportDir, "report-dir", "", "Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
  236. flag.Var(cliflag.NewMapStringBool(&TestContext.FeatureGates), "feature-gates", "A set of key=value pairs that describe feature gates for alpha/experimental features.")
  237. flag.StringVar(&TestContext.ContainerRuntime, "container-runtime", "docker", "The container runtime of cluster VM instances (docker/remote).")
  238. flag.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "unix:///var/run/dockershim.sock", "The container runtime endpoint of cluster VM instances.")
  239. flag.StringVar(&TestContext.ContainerRuntimeProcessName, "container-runtime-process-name", "dockerd", "The name of the container runtime process.")
  240. flag.StringVar(&TestContext.ContainerRuntimePidFile, "container-runtime-pid-file", "/var/run/docker.pid", "The pid file of the container runtime.")
  241. flag.StringVar(&TestContext.SystemdServices, "systemd-services", "docker", "The comma separated list of systemd services the framework will dump logs for.")
  242. flag.BoolVar(&TestContext.DumpSystemdJournal, "dump-systemd-journal", false, "Whether to dump the full systemd journal.")
  243. flag.StringVar(&TestContext.ImageServiceEndpoint, "image-service-endpoint", "", "The image service endpoint of cluster VM instances.")
  244. flag.StringVar(&TestContext.DockershimCheckpointDir, "dockershim-checkpoint-dir", "/var/lib/dockershim/sandbox", "The directory for dockershim to store sandbox checkpoints.")
  245. flag.StringVar(&TestContext.KubernetesAnywherePath, "kubernetes-anywhere-path", "/workspace/k8s.io/kubernetes-anywhere", "Which directory kubernetes-anywhere is installed to.")
  246. flag.BoolVar(&TestContext.ListImages, "list-images", false, "If true, will show list of images used for runnning tests.")
  247. }
  248. // RegisterClusterFlags registers flags specific to the cluster e2e test suite.
  249. func RegisterClusterFlags() {
  250. flag.BoolVar(&TestContext.VerifyServiceAccount, "e2e-verify-service-account", true, "If true tests will verify the service account before running.")
  251. flag.StringVar(&TestContext.KubeConfig, clientcmd.RecommendedConfigPathFlag, os.Getenv(clientcmd.RecommendedConfigPathEnvVar), "Path to kubeconfig containing embedded authinfo.")
  252. flag.StringVar(&TestContext.KubeContext, clientcmd.FlagContext, "", "kubeconfig context to use/override. If unset, will use value from 'current-context'")
  253. flag.StringVar(&TestContext.KubeAPIContentType, "kube-api-content-type", "application/vnd.kubernetes.protobuf", "ContentType used to communicate with apiserver")
  254. flag.StringVar(&TestContext.KubeVolumeDir, "volume-dir", "/var/lib/kubelet", "Path to the directory containing the kubelet volumes.")
  255. flag.StringVar(&TestContext.CertDir, "cert-dir", "", "Path to the directory containing the certs. Default is empty, which doesn't use certs.")
  256. flag.StringVar(&TestContext.RepoRoot, "repo-root", "../../", "Root directory of kubernetes repository, for finding test files.")
  257. flag.StringVar(&TestContext.Provider, "provider", "", "The name of the Kubernetes provider (gce, gke, local, skeleton (the fallback if not set), etc.)")
  258. flag.StringVar(&TestContext.Tooling, "tooling", "", "The tooling in use (kops, gke, etc.)")
  259. flag.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.")
  260. flag.StringVar(&TestContext.OutputDir, "e2e-output-dir", "/tmp", "Output directory for interesting/useful test data, like performance data, benchmarks, and other metrics.")
  261. flag.StringVar(&TestContext.Prefix, "prefix", "e2e", "A prefix to be added to cloud resources created during testing.")
  262. flag.StringVar(&TestContext.MasterOSDistro, "master-os-distro", "debian", "The OS distribution of cluster master (debian, ubuntu, gci, coreos, or custom).")
  263. flag.StringVar(&TestContext.NodeOSDistro, "node-os-distro", "debian", "The OS distribution of cluster VM instances (debian, ubuntu, gci, coreos, or custom).")
  264. flag.StringVar(&TestContext.ClusterMonitoringMode, "cluster-monitoring-mode", "standalone", "The monitoring solution that is used in the cluster.")
  265. flag.BoolVar(&TestContext.EnablePrometheusMonitoring, "prometheus-monitoring", false, "Separate Prometheus monitoring deployed in cluster.")
  266. flag.StringVar(&TestContext.ClusterDNSDomain, "dns-domain", "cluster.local", "The DNS Domain of the cluster.")
  267. // TODO: Flags per provider? Rename gce-project/gce-zone?
  268. cloudConfig := &TestContext.CloudConfig
  269. flag.StringVar(&cloudConfig.MasterName, "kube-master", "", "Name of the kubernetes master. Only required if provider is gce or gke")
  270. flag.StringVar(&cloudConfig.APIEndpoint, "gce-api-endpoint", "", "The GCE APIEndpoint being used, if applicable")
  271. flag.StringVar(&cloudConfig.ProjectID, "gce-project", "", "The GCE project being used, if applicable")
  272. flag.StringVar(&cloudConfig.Zone, "gce-zone", "", "GCE zone being used, if applicable")
  273. flag.StringVar(&cloudConfig.Region, "gce-region", "", "GCE region being used, if applicable")
  274. flag.BoolVar(&cloudConfig.MultiZone, "gce-multizone", false, "If true, start GCE cloud provider with multizone support.")
  275. flag.BoolVar(&cloudConfig.MultiMaster, "gce-multimaster", false, "If true, the underlying GCE/GKE cluster is assumed to be multi-master.")
  276. flag.StringVar(&cloudConfig.Cluster, "gke-cluster", "", "GKE name of cluster being used, if applicable")
  277. flag.StringVar(&cloudConfig.NodeInstanceGroup, "node-instance-group", "", "Name of the managed instance group for nodes. Valid only for gce, gke or aws. If there is more than one group: comma separated list of groups.")
  278. flag.StringVar(&cloudConfig.Network, "network", "e2e", "The cloud provider network for this e2e cluster.")
  279. flag.IntVar(&cloudConfig.NumNodes, "num-nodes", DefaultNumNodes, fmt.Sprintf("Number of nodes in the cluster. If the default value of '%q' is used the number of schedulable nodes is auto-detected.", DefaultNumNodes))
  280. flag.StringVar(&cloudConfig.ClusterIPRange, "cluster-ip-range", "10.64.0.0/14", "A CIDR notation IP range from which to assign IPs in the cluster.")
  281. flag.StringVar(&cloudConfig.NodeTag, "node-tag", "", "Network tags used on node instances. Valid only for gce, gke")
  282. flag.StringVar(&cloudConfig.MasterTag, "master-tag", "", "Network tags used on master instances. Valid only for gce, gke")
  283. flag.StringVar(&cloudConfig.ClusterTag, "cluster-tag", "", "Tag used to identify resources. Only required if provider is aws.")
  284. flag.StringVar(&cloudConfig.ConfigFile, "cloud-config-file", "", "Cloud config file. Only required if provider is azure.")
  285. flag.IntVar(&TestContext.MinStartupPods, "minStartupPods", 0, "The number of pods which we need to see in 'Running' state with a 'Ready' condition of true, before we try running tests. This is useful in any cluster which needs some base pod-based services running before it can be used.")
  286. flag.DurationVar(&TestContext.SystemPodsStartupTimeout, "system-pods-startup-timeout", 10*time.Minute, "Timeout for waiting for all system pods to be running before starting tests.")
  287. flag.DurationVar(&TestContext.NodeSchedulableTimeout, "node-schedulable-timeout", 30*time.Minute, "Timeout for waiting for all nodes to be schedulable.")
  288. flag.DurationVar(&TestContext.SystemDaemonsetStartupTimeout, "system-daemonsets-startup-timeout", 5*time.Minute, "Timeout for waiting for all system daemonsets to be ready.")
  289. flag.StringVar(&TestContext.EtcdUpgradeStorage, "etcd-upgrade-storage", "", "The storage version to upgrade to (either 'etcdv2' or 'etcdv3') if doing an etcd upgrade test.")
  290. flag.StringVar(&TestContext.EtcdUpgradeVersion, "etcd-upgrade-version", "", "The etcd binary version to upgrade to (e.g., '3.0.14', '2.3.7') if doing an etcd upgrade test.")
  291. flag.StringVar(&TestContext.GCEUpgradeScript, "gce-upgrade-script", "", "Script to use to upgrade a GCE cluster.")
  292. flag.BoolVar(&TestContext.CleanStart, "clean-start", false, "If true, purge all namespaces except default and system before running tests. This serves to Cleanup test namespaces from failed/interrupted e2e runs in a long-lived cluster.")
  293. nodeKiller := &TestContext.NodeKiller
  294. flag.BoolVar(&nodeKiller.Enabled, "node-killer", false, "Whether NodeKiller should kill any nodes.")
  295. flag.Float64Var(&nodeKiller.FailureRatio, "node-killer-failure-ratio", 0.01, "Percentage of nodes to be killed")
  296. flag.DurationVar(&nodeKiller.Interval, "node-killer-interval", 1*time.Minute, "Time between node failures.")
  297. flag.Float64Var(&nodeKiller.JitterFactor, "node-killer-jitter-factor", 60, "Factor used to jitter node failures.")
  298. flag.DurationVar(&nodeKiller.SimulatedDowntime, "node-killer-simulated-downtime", 10*time.Minute, "A delay between node death and recreation")
  299. }
  300. // RegisterNodeFlags registers flags specific to the node e2e test suite.
  301. func RegisterNodeFlags() {
  302. // Mark the test as node e2e when node flags are api.Registry.
  303. TestContext.NodeE2E = true
  304. flag.StringVar(&TestContext.NodeName, "node-name", "", "Name of the node to run tests on.")
  305. // TODO(random-liu): Move kubelet start logic out of the test.
  306. // TODO(random-liu): Move log fetch logic out of the test.
  307. // There are different ways to start kubelet (systemd, initd, docker, manually started etc.)
  308. // and manage logs (journald, upstart etc.).
  309. // For different situation we need to mount different things into the container, run different commands.
  310. // It is hard and unnecessary to deal with the complexity inside the test suite.
  311. flag.BoolVar(&TestContext.NodeConformance, "conformance", false, "If true, the test suite will not start kubelet, and fetch system log (kernel, docker, kubelet log etc.) to the report directory.")
  312. flag.BoolVar(&TestContext.PrepullImages, "prepull-images", true, "If true, prepull images so image pull failures do not cause test failures.")
  313. flag.StringVar(&TestContext.ImageDescription, "image-description", "", "The description of the image which the test will be running on.")
  314. flag.StringVar(&TestContext.SystemSpecName, "system-spec-name", "", "The name of the system spec (e.g., gke) that's used in the node e2e test. The system specs are in test/e2e_node/system/specs/. This is used by the test framework to determine which tests to run for validating the system requirements.")
  315. flag.Var(cliflag.NewMapStringString(&TestContext.ExtraEnvs), "extra-envs", "The extra environment variables needed for node e2e tests. Format: a list of key=value pairs, e.g., env1=val1,env2=val2")
  316. }
  317. // HandleFlags sets up all flags and parses the command line.
  318. func HandleFlags() {
  319. RegisterCommonFlags()
  320. RegisterClusterFlags()
  321. flag.Parse()
  322. }
  323. func createKubeConfig(clientCfg *restclient.Config) *clientcmdapi.Config {
  324. clusterNick := "cluster"
  325. userNick := "user"
  326. contextNick := "context"
  327. config := clientcmdapi.NewConfig()
  328. credentials := clientcmdapi.NewAuthInfo()
  329. credentials.Token = clientCfg.BearerToken
  330. credentials.TokenFile = clientCfg.BearerTokenFile
  331. credentials.ClientCertificate = clientCfg.TLSClientConfig.CertFile
  332. if len(credentials.ClientCertificate) == 0 {
  333. credentials.ClientCertificateData = clientCfg.TLSClientConfig.CertData
  334. }
  335. credentials.ClientKey = clientCfg.TLSClientConfig.KeyFile
  336. if len(credentials.ClientKey) == 0 {
  337. credentials.ClientKeyData = clientCfg.TLSClientConfig.KeyData
  338. }
  339. config.AuthInfos[userNick] = credentials
  340. cluster := clientcmdapi.NewCluster()
  341. cluster.Server = clientCfg.Host
  342. cluster.CertificateAuthority = clientCfg.CAFile
  343. if len(cluster.CertificateAuthority) == 0 {
  344. cluster.CertificateAuthorityData = clientCfg.CAData
  345. }
  346. cluster.InsecureSkipTLSVerify = clientCfg.Insecure
  347. config.Clusters[clusterNick] = cluster
  348. context := clientcmdapi.NewContext()
  349. context.Cluster = clusterNick
  350. context.AuthInfo = userNick
  351. config.Contexts[contextNick] = context
  352. config.CurrentContext = contextNick
  353. return config
  354. }
  355. // AfterReadingAllFlags makes changes to the context after all flags
  356. // have been read.
  357. func AfterReadingAllFlags(t *TestContextType) {
  358. // Only set a default host if one won't be supplied via kubeconfig
  359. if len(t.Host) == 0 && len(t.KubeConfig) == 0 {
  360. // Check if we can use the in-cluster config
  361. if clusterConfig, err := restclient.InClusterConfig(); err == nil {
  362. if tempFile, err := ioutil.TempFile(os.TempDir(), "kubeconfig-"); err == nil {
  363. kubeConfig := createKubeConfig(clusterConfig)
  364. clientcmd.WriteToFile(*kubeConfig, tempFile.Name())
  365. t.KubeConfig = tempFile.Name()
  366. klog.Infof("Using a temporary kubeconfig file from in-cluster config : %s", tempFile.Name())
  367. }
  368. }
  369. if len(t.KubeConfig) == 0 {
  370. klog.Warningf("Unable to find in-cluster config, using default host : %s", defaultHost)
  371. t.Host = defaultHost
  372. }
  373. }
  374. // Allow 1% of nodes to be unready (statistically) - relevant for large clusters.
  375. if t.AllowedNotReadyNodes == 0 {
  376. t.AllowedNotReadyNodes = t.CloudConfig.NumNodes / 100
  377. }
  378. // Make sure that all test runs have a valid TestContext.CloudConfig.Provider.
  379. // TODO: whether and how long this code is needed is getting discussed
  380. // in https://github.com/kubernetes/kubernetes/issues/70194.
  381. if TestContext.Provider == "" {
  382. // Some users of the e2e.test binary pass --provider=.
  383. // We need to support that, changing it would break those usages.
  384. e2elog.Logf("The --provider flag is not set. Continuing as if --provider=skeleton had been used.")
  385. TestContext.Provider = "skeleton"
  386. }
  387. var err error
  388. TestContext.CloudConfig.Provider, err = SetupProviderConfig(TestContext.Provider)
  389. if err != nil {
  390. if os.IsNotExist(errors.Cause(err)) {
  391. // Provide a more helpful error message when the provider is unknown.
  392. var providers []string
  393. for _, name := range GetProviders() {
  394. // The empty string is accepted, but looks odd in the output below unless we quote it.
  395. if name == "" {
  396. name = `""`
  397. }
  398. providers = append(providers, name)
  399. }
  400. sort.Strings(providers)
  401. klog.Errorf("Unknown provider %q. The following providers are known: %v", TestContext.Provider, strings.Join(providers, " "))
  402. } else {
  403. klog.Errorf("Failed to setup provider config for %q: %v", TestContext.Provider, err)
  404. }
  405. os.Exit(1)
  406. }
  407. }