Documentation ¶
Index ¶
- func ConnectInitial() error
- func Flag()
- func ParseContext(value string) error
- type ClusterRoleBindingGet
- type ClusterType
- type ConfigMapValidate
- type ContainerValidate
- type Curl
- type CurlOpts
- type CurlResponse
- type DeployScale
- type DeploymentAnnotate
- type DeploymentCreate
- type DeploymentCreateSimple
- type DeploymentGet
- type DeploymentOpts
- type DeploymentValidate
- type DeploymentWait
- type KubeConfig
- func (k KubeConfig) GetDiscoveryClient() *discovery.DiscoveryClient
- func (k KubeConfig) GetDynamicClient() dynamic.Interface
- func (k KubeConfig) GetKubeClient() *kubernetes.Clientset
- func (k KubeConfig) GetKubeconfigFile() string
- func (k KubeConfig) GetName() string
- func (k KubeConfig) GetOcAppsClient() *openshiftapps.Clientset
- func (k KubeConfig) GetRestConfig() *rest.Config
- func (k KubeConfig) GetRouteClient() *routev1client.RouteV1Client
- type Kubectl
- type Lookup
- type Namespace
- func (n Namespace) ClusterRoleBindingInterface() rbacv1.ClusterRoleBindingInterface
- func (n Namespace) ConfigMapInterface() clientcorev1.ConfigMapInterface
- func (n Namespace) DeploymentInterface() appsv1.DeploymentInterface
- func (n Namespace) GetKind() ClusterType
- func (n Namespace) GetKubeConfig() *KubeConfig
- func (n Namespace) GetNamespace(ctx context.Context) (*corev1.Namespace, error)
- func (n Namespace) GetNamespaceName() string
- func (n Namespace) KubeClient() kubernetes.Interface
- func (n Namespace) NetworkPolicyInterface() networkingv1.NetworkPolicyInterface
- func (n Namespace) PodInterface() clientcorev1.PodInterface
- func (n Namespace) SecretInterface() clientcorev1.SecretInterface
- func (n Namespace) ServiceInterface() clientcorev1.ServiceInterface
- func (n Namespace) StatefulSetInterface() appsv1.StatefulSetInterface
- type NamespaceCreateRaw
- type NamespaceCreateTestBase
- type NamespaceDeleteRaw
- type NamespaceDeleteTestBase
- type Namespacer
- type NetworkPolicyValidate
- type NginxDeploy
- type PodAnnotate
- type PodExecute
- type PodGet
- type PodSelector
- type Pods
- type PostgresPing
- type PsycopgPing
- type SecretCreate
- type SecretDelete
- type SecretGet
- type SecretMount
- type ServiceAnnotate
- type ServiceCreate
- type ServiceDelete
- type ServiceGet
- type ServiceRemoveAnnotation
- type StatefulSetCreate
- type StatefulSetRemove
- type TestBase
- func (t *TestBase) Add(ns *Namespace, receivedErr error)
- func (t *TestBase) GetAllNamespaces() []*Namespace
- func (t *TestBase) GetDomainNamespaces(domain ClusterType) []*Namespace
- func (t *TestBase) GetNamespace(name string) *Namespace
- func (t *TestBase) Next(kind ClusterType, suffix string) (name string, cluster *KubeConfig)
- type Undeploy
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConnectInitial ¶
func ConnectInitial() error
Connect to the clusters declared with -kube or on KUBECONFIG
This can be called many times, but will be only executed once.
func Flag ¶
func Flag()
Flag adds the flag "-kube" to the list of flags to be parsed on the command line; call it right before flag.Parse(), on TestMain, if you want your test to interact with multiple Kubernetes clusters.
func ParseContext ¶
ParseContext will parse the provided value, with the format [kind=]/path/to/file.
If kind is not provided, it will be set as 'pub' by default.
It is used by Flag(), to add the --kube flag to the available flags, and that is its main objective.
One can, however, programatically call it from individual tests to add kubeconfig files.
Be aware, however, that this will affect a package variable (ie, it will affect any other tests in the same run)
Types ¶
type ClusterRoleBindingGet ¶
type ClusterRoleBindingGet struct { // Even if not a namespaced resource, the Namespace is // required, so the frame can have access to the KubeClient // // The Namespace will then also be used to confirm that the // acquired binding points to this namespace Namespace *Namespace Name string Ctx context.Context ClusterRole string ExpectAbsent bool Result *rbacv1.ClusterRoleBinding frame2.Log frame2.DefaultRunDealer }
func (*ClusterRoleBindingGet) Validate ¶
func (c *ClusterRoleBindingGet) Validate() error
type ClusterType ¶
type ClusterType string
The type of cluster:
- Public - Private - DMZ
Currently, only the first two are implemented
const ( Public ClusterType = "pub" Private ClusterType = "prv" DMZ ClusterType = "dmz" )
type ConfigMapValidate ¶
type ConfigMapValidate struct { Namespace *Namespace Name string Ctx context.Context LogContents bool Values map[string]string AbsentKeys []string // JSON verification for the keys on the map JSON map[string]f2general.JSON // Function to run against the CM, to validate. Provides a way // to execute more complex validations not available above, inline CMValidator func(corev1.ConfigMap) error Result *[]corev1.ConfigMap frame2.Log frame2.DefaultRunDealer }
TODO: Uniformize fields and struct name, between this and SecretGet
func (*ConfigMapValidate) Validate ¶
func (c *ConfigMapValidate) Validate() error
type ContainerValidate ¶
type ContainerValidate struct { Namespace *Namespace PodSelector string ContainerName string // If empty, check all containers on selected pods ExpectNone bool // If true, it will be an error if any pods are found ExpectExactly int // if greater than 0, exactly this number of pods must be found CPULimit string CPURequest string MemoryLimit string MemoryRequest string CheckUnrequested bool // Normally an empty CPU/Memory Limit/Request is not checked RestartCount int32 RestartCheck bool StatusCheck bool Return *v1.Container frame2.Log frame2.DefaultRunDealer }
func (ContainerValidate) Run ¶
func (c ContainerValidate) Run() error
func (ContainerValidate) Validate ¶
func (c ContainerValidate) Validate() error
type Curl ¶
type Curl struct { Namespace *Namespace // A default of 60s is set for the timeout, if the original value is // zero. CurlOptions CurlOpts Url string Fail400Plus bool Podname string // Passed to tools.Curl. Generally safe to leave empty. Check tools.Curl docs DeployCurl bool // TODO: Add cli.Expect to inspect results? frame2.Log }
If CurlOptions.Timeout is zero, a default is set, instead.
type CurlOpts ¶
type CurlOpts struct { Silent bool Insecure bool Username string Password string Timeout int Verbose bool }
CurlOpts allows specifying arguments to run curl on a pod
type CurlResponse ¶
type CurlResponse struct { HttpVersion string StatusCode int ReasonPhrase string Headers map[string]string Body string Output string }
CurlResponse wraps a response for a curl execution
type DeployScale ¶
type DeployScale struct { Namespace *Namespace DeploymentGet DeploymentValidate // Do not populate the Namespace within the DeploymentGet; it will be auto-populated Replicas int32 Ctx context.Context }
func (DeployScale) Execute ¶
func (d DeployScale) Execute() error
type DeploymentAnnotate ¶
type DeploymentAnnotate struct { Namespace *Namespace Name string Annotations map[string]string Ctx context.Context }
func (DeploymentAnnotate) Execute ¶
func (kda DeploymentAnnotate) Execute() error
type DeploymentCreate ¶
type DeploymentCreate struct { Namespace *Namespace Deployment *appsv1.Deployment Result *appsv1.Deployment Ctx context.Context frame2.DefaultRunDealer }
Executes a fully specified K8S deployment
See DeploymentCreateSimple for a simpler interface ¶
For an example/template on creating a *v1.Deployment by hand, check test/utils/base/cluster_context.go (k8s.NewDeployment)
func (*DeploymentCreate) Execute ¶
func (d *DeploymentCreate) Execute() error
type DeploymentCreateSimple ¶
type DeploymentCreateSimple struct { Name string Namespace *Namespace DeploymentOpts DeploymentOpts Wait time.Duration // Waits for the deployment to be ready. Otherwise, returns as soon as the create instruction has been issued. If the wait lapses, return an error. Ctx context.Context Result *appsv1.Deployment frame2.DefaultRunDealer }
This simply makes a request to k8s.NewDeployment
See DeploymentCreate for a more complete interface
func (*DeploymentCreateSimple) Execute ¶
func (d *DeploymentCreateSimple) Execute() error
type DeploymentGet ¶
type DeploymentGet struct { Namespace *Namespace Name string Ctx context.Context Result *appsv1.Deployment frame2.Log frame2.DefaultRunDealer }
func (*DeploymentGet) Validate ¶
func (d *DeploymentGet) Validate() error
type DeploymentOpts ¶
type DeploymentOpts struct { Image string Labels map[string]string RestartPolicy corev1.RestartPolicy Command []string Args []string EnvVars []corev1.EnvVar ResourceReq corev1.ResourceRequirements SecretMounts []SecretMount }
This is not a frame; This struct is used by DeploymentCreateSimple and f2ocp.DeploymentConfigOpts
type DeploymentValidate ¶
type DeploymentValidate struct { Namespace *Namespace Name string Ctx context.Context MinReadyReplicas int Result *appsv1.Deployment frame2.Log frame2.DefaultRunDealer }
func (*DeploymentValidate) Validate ¶
func (d *DeploymentValidate) Validate() error
type DeploymentWait ¶
type DeploymentWait struct { Name string Namespace *Namespace Ctx context.Context // On this field, do not set the context. Use the DeploymentWait.Ctx, // instead, it will be used for the underlying Retry RetryOptions frame2.RetryOptions frame2.DefaultRunDealer *frame2.Log }
Wait for the named deployment to be available. By default, it waits for up to two minutes, and ensures that the deployment reports as ready for at least 10s.
That behavior can be changed using the RetryOptions field. On that field, the Ctx field cannot be set; if a different timeout is desired, set it on the Action's Ctx itself, and it will be used for the RetryOptions.
This is basically a wrapper around DeploymentValidate, with some pre-seleced RetryOptions, MinReadyReplicas. You may get a more flexible frame using DeploymentValidate directly
func (DeploymentWait) Validate ¶
func (w DeploymentWait) Validate() error
type KubeConfig ¶
TODO: make this an Executor?
func NewKubeConfig ¶
func NewKubeConfig(name, path string) (*KubeConfig, error)
func (KubeConfig) GetDiscoveryClient ¶
func (k KubeConfig) GetDiscoveryClient() *discovery.DiscoveryClient
func (KubeConfig) GetDynamicClient ¶
func (k KubeConfig) GetDynamicClient() dynamic.Interface
func (KubeConfig) GetKubeClient ¶
func (k KubeConfig) GetKubeClient() *kubernetes.Clientset
Returns the KubeClient for interacting with the cluster defined on this KubeConfig
func (KubeConfig) GetKubeconfigFile ¶
func (k KubeConfig) GetKubeconfigFile() string
func (KubeConfig) GetName ¶
func (k KubeConfig) GetName() string
func (KubeConfig) GetOcAppsClient ¶
func (k KubeConfig) GetOcAppsClient() *openshiftapps.Clientset
func (KubeConfig) GetRestConfig ¶
func (k KubeConfig) GetRestConfig() *rest.Config
func (KubeConfig) GetRouteClient ¶
func (k KubeConfig) GetRouteClient() *routev1client.RouteV1Client
type Kubectl ¶
type Lookup ¶
type Lookup struct { Namespace *Namespace Name string Cmd f2general.Cmd frame2.Log frame2.DefaultRunDealer }
Executes nslookup within a pod, to check whether a name is valid within a namespace or cluster
type Namespace ¶
type Namespace struct {
// contains filtered or unexported fields
}
This is to be used as an embedded field; implement the whole of Namespacer here
Consider this: the PodInterface below (and others) might be interesting, but they'd pollute the frame's namespace if embedded
This is not a frame: not an executor or a validator
func (Namespace) ClusterRoleBindingInterface ¶
func (n Namespace) ClusterRoleBindingInterface() rbacv1.ClusterRoleBindingInterface
func (Namespace) ConfigMapInterface ¶
func (n Namespace) ConfigMapInterface() clientcorev1.ConfigMapInterface
func (Namespace) DeploymentInterface ¶
func (n Namespace) DeploymentInterface() appsv1.DeploymentInterface
func (Namespace) GetKind ¶
func (n Namespace) GetKind() ClusterType
func (Namespace) GetKubeConfig ¶
func (n Namespace) GetKubeConfig() *KubeConfig
func (Namespace) GetNamespace ¶
Inquires the server and returns the latest representation of the K8S Namespace
func (Namespace) GetNamespaceName ¶
func (Namespace) KubeClient ¶
func (n Namespace) KubeClient() kubernetes.Interface
func (Namespace) NetworkPolicyInterface ¶
func (n Namespace) NetworkPolicyInterface() networkingv1.NetworkPolicyInterface
func (Namespace) PodInterface ¶
func (n Namespace) PodInterface() clientcorev1.PodInterface
This is a helper to get access to the Pods API for this namespace
func (Namespace) SecretInterface ¶
func (n Namespace) SecretInterface() clientcorev1.SecretInterface
func (Namespace) ServiceInterface ¶
func (n Namespace) ServiceInterface() clientcorev1.ServiceInterface
func (Namespace) StatefulSetInterface ¶
func (n Namespace) StatefulSetInterface() appsv1.StatefulSetInterface
type NamespaceCreateRaw ¶
type NamespaceCreateRaw struct { Name string Cluster *KubeConfig AutoTearDown bool Annotations map[string]string Labels map[string]string frame2.DefaultRunDealer frame2.Log Return corev1.Namespace }
This will simply create a namespace on the given cluster, with the requested name.
For most uses, you may want to use NamespaceCreateTestBase, instead.
Created namespaces will be labeled with frame2.id
func (*NamespaceCreateRaw) Execute ¶
func (c *NamespaceCreateRaw) Execute() error
func (*NamespaceCreateRaw) Teardown ¶
func (c *NamespaceCreateRaw) Teardown() frame2.Executor
type NamespaceCreateTestBase ¶
type NamespaceCreateTestBase struct { Id string TestBase *TestBase Kind ClusterType AutoTearDown bool // Annotations to be applied after the namespace creation Annotations map[string]string // Labels to be applied after the namespace creation Labels map[string]string frame2.DefaultRunDealer frame2.Log Return Namespace }
This creates a K8S namespace, based on a TestBase; the namespace name will include the provided Id, but it will also contain other information (such as the TestBase Id, a sequence number, etc)
The namespace also receives a label frame2.id, with which it is easy to identify (and possibly modify or remove) any namespaces created by a test run.
f2k8s.ConnectInitial must have been called prior to this
func (*NamespaceCreateTestBase) Execute ¶
func (c *NamespaceCreateTestBase) Execute() (err error)
type NamespaceDeleteRaw ¶
type NamespaceDeleteRaw struct { Namespace string Cluster *KubeConfig // A wait duration of zero will use the default wait // for namespace removals; if you want to not wait at all // use a very small duration (such as time.Nanosecond) Wait time.Duration frame2.DefaultRunDealer frame2.Log }
This is a direct call to K8S to remove a namespace. For namespaces created with NamespaceCreateTestBase, you want to use NamespaceDeleteTestBase, instead
func (*NamespaceDeleteRaw) Execute ¶
func (d *NamespaceDeleteRaw) Execute() error
type NamespaceDeleteTestBase ¶
type NamespaceDeleteTestBase struct { Namespace *Namespace // A wait duration of zero will use the default wait // for namespace removals; if you want to not wait at all // use a very small duration (such as time.Nanosecond) Wait time.Duration frame2.DefaultRunDealer frame2.Log }
func (*NamespaceDeleteTestBase) Execute ¶
func (d *NamespaceDeleteTestBase) Execute() error
type Namespacer ¶
type Namespacer interface { GetNamespace() string Kube() configv1.KubeClientConfig }
type NetworkPolicyValidate ¶
type NetworkPolicyValidate struct { Namespace *Namespace Name string Ctx context.Context Values map[string]string // Function to run against the Network Policy, to validate. Provides a way // to execute more complex validations not available above, inline NMValidator func(corev1.ConfigMap) error Result *[]corev1.ConfigMap frame2.Log frame2.DefaultRunDealer }
func (*NetworkPolicyValidate) Validate ¶
func (n *NetworkPolicyValidate) Validate() error
type NginxDeploy ¶
type NginxDeploy struct { Namespace *Namespace Name string // default "nginx" Labels map[string]string // default app: nginx SecretMount []SecretMount ExposeService bool SkupperExpose bool // TODO Wait time.Duration }
func (NginxDeploy) Execute ¶
func (n NginxDeploy) Execute() error
type PodAnnotate ¶
func (PodAnnotate) Run ¶
func (pa PodAnnotate) Run() error
type PodExecute ¶
type PodExecute struct { Pod *PodGet Container string Command []string Ctx context.Context Expect frame2.Expect // Configures checks on Stdout and Stderr // TODO: use common code with execute.Command ForceOutput bool // Shows this command's output on log, regardless of environment config frame2.Log *f2general.CmdResult }
func (*PodExecute) Execute ¶
func (e *PodExecute) Execute() error
func (*PodExecute) Validate ¶
func (e *PodExecute) Validate() error
type PodGet ¶
type PodGet struct { Namespace *Namespace Name string Labels map[string]string Ctx context.Context Result *corev1.Pod frame2.Log frame2.DefaultRunDealer }
TODO move to frames.k8svalidate and refactor to share code with k8svalidate.Pods
This will return a single pod. If name is provided, that will be used. Otherwise, the pods with the given label will be listed, and the first in the list will be returned
type PodSelector ¶
type PodSelector struct { Namespace *Namespace Selector string ExpectNone bool // If true, it will be an error if any pods are found ExpectExactly int // if greater than 0, exactly this number of pods must be found // Return value Pods []v1.Pod }
func (*PodSelector) Execute ¶
func (p *PodSelector) Execute() error
type Pods ¶
type Pods struct { Namespace *Namespace Labels map[string]string Ctx context.Context // Ignored if zero ExpectMin int // Ignored if zero ExpectMax int // Ignored if zero // TODO: use min == max, instead? ExpectExactly int // Expect no results ExpectNone bool //ExpectCondition corev1.PodConditionType ExpectPhase corev1.PodPhase // List of labels expected to _not_ be set on the Pod, regardless of value NegativeLabelList []string // Other labels expected to be on the Pod, besides those used on the // selector, with their expected values OtherLabels map[string]string // Labels listed on this map must not have the mapped value. If the // label does not exist at all on the pod, the NegativeLabels test is // considered successful, unless NegativeLabelsExist is set to true NegativeLabels map[string]string NegativeLabelsExist bool // List of annotations expected to be set on the Pod, regardless of value AnnotationList []string // List of annotations expected to _not_ be set on the Pod, regardless of value NegativeAnnotationList []string // Other annotations expected to be on the Pod, besides those used on the // selector, with their expected values OtherAnnotations map[string]string // Annotations listed on this map must not have the mapped value. If the // label does not exist at all on the pod, the NegativeAnnotations test is // considered successful, unless NegativeAnnotationsExist is set to true NegativeAnnotations map[string]string NegativeAnnotationsExist bool // A list of strings, all of which must map to a container name on the pod ContainerList []string // If true, the ContainerList is the complete list of expected containers; // any additional containers will cause the validation to fail ContainerListComplete bool // These containers must not be present on the pod NegativeContainerList []string // Function to run against each pod, to validate. Provides a way // to execute more complex validations not available above PodValidator func(corev1.Pod) error // A complex validation on the list as a whole. Allows, for example // to aggregate values from the different pods for verification ListValidator func([]corev1.Pod) error // List of labels expected to be set on the Pod, regardless of value LabelList []string Result *[]corev1.Pod frame2.Log frame2.DefaultRunDealer }
type PostgresPing ¶
type PostgresPing struct { Namespace *Namespace Podname string Labels map[string]string Container string DbName string DbHost string DbPort string // default is 5432 Username string Ctx context.Context frame2.Log frame2.DefaultRunDealer }
func (*PostgresPing) Validate ¶
func (p *PostgresPing) Validate() error
type PsycopgPing ¶
type PsycopgPing struct { Namespace *Namespace Podname string Labels map[string]string Container string DbName string DbHost string DbPort string // default is 5432 Username string Password string Ctx context.Context frame2.Log frame2.DefaultRunDealer }
If the postgres client is not installed, but Python module psycopg is, this is an alternative to PostgresPing
Unfortunately, psycopg still does not export libpq.PQping, so we have to do a full connection, which requires username and password.
func (*PsycopgPing) Validate ¶
func (p *PsycopgPing) Validate() error
type SecretCreate ¶
type SecretCreate struct { Namespace *Namespace Secret *core.Secret *frame2.Log frame2.DefaultRunDealer }
func (SecretCreate) Execute ¶
func (s SecretCreate) Execute() error
type SecretDelete ¶
type SecretDelete struct { Namespace *Namespace Name string Secret *core.Secret // return *frame2.Log frame2.DefaultRunDealer }
func (SecretDelete) Execute ¶
func (s SecretDelete) Execute() error
type SecretGet ¶
type SecretGet struct { Namespace *Namespace Name string // TODO change all these for a f2general.MapCheck // Look for expected contents of the secret (exact) Expect map[string][]byte // If true, the Expect map should be the full contents // of the secret. If it is empty and ExpectAll is true, // for example, the secret must be empty. ExpectAll bool // Checks that all listed keys are present on the // secret, regardless of their values Keys []string // Checks that listed keys are _not_ present on the // Secret AbsentKeys []string // If set, the Secret is expected to not be present; // fail if it exists ExpectAbsent bool Labels f2general.MapCheck Annotations f2general.MapCheck // Function to run against the Secret, to validate. Provides a way // to execute more complex validations not available above, inline SecretValidator func(core.Secret) error Secret *core.Secret *frame2.Log frame2.DefaultRunDealer }
TODO: Uniformize fields and struct name, between this and ConfigMapValidate
type SecretMount ¶
type ServiceAnnotate ¶
type ServiceAnnotate struct { Namespace *Namespace Name string Annotations map[string]string Ctx context.Context }
func (ServiceAnnotate) Execute ¶
func (ksa ServiceAnnotate) Execute() error
type ServiceCreate ¶
type ServiceCreate struct { Namespace *Namespace Name string Annotations map[string]string Labels map[string]string Selector map[string]string Ports []int32 Type apiv1.ServiceType PublishNotReadyAddresses bool Ctx context.Context // Cluster IP; set this to "None" and Type to ClusterIP for a headless service // https://kubernetes.io/docs/concepts/services-networking/service/#headless-services ClusterIP string AutoTeardown bool Wait time.Duration }
Creates a Kubernetes service, with simplified configurations
func (ServiceCreate) Execute ¶
func (ks ServiceCreate) Execute() error
func (ServiceCreate) Teardown ¶
func (ks ServiceCreate) Teardown() frame2.Executor
type ServiceDelete ¶
func (ServiceDelete) Execute ¶
func (ksd ServiceDelete) Execute() error
type ServiceGet ¶
type ServiceGet struct { Namespace *Namespace Name string Ctx context.Context frame2.Log // Return Service *apiv1.Service }
Retrieve a K8S Service by name and namespace
func (*ServiceGet) Validate ¶
func (kg *ServiceGet) Validate() error
type ServiceRemoveAnnotation ¶
type ServiceRemoveAnnotation struct { Namespace *Namespace Name string Annotations []string Ctx context.Context }
func (ServiceRemoveAnnotation) Execute ¶
func (ksr ServiceRemoveAnnotation) Execute() error
type StatefulSetCreate ¶
type StatefulSetCreate struct { Namespace *Namespace StatefulSet *apps.StatefulSet AutoTeardown bool Ctx context.Context Result *apps.StatefulSet }
Executes a fully specified K8S Statefulset
func (*StatefulSetCreate) Execute ¶
func (k *StatefulSetCreate) Execute() error
func (*StatefulSetCreate) Teardown ¶
func (k *StatefulSetCreate) Teardown() frame2.Executor
type StatefulSetRemove ¶
func (*StatefulSetRemove) Execute ¶
func (k *StatefulSetRemove) Execute() error
type TestBase ¶
type TestBase struct {
// contains filtered or unexported fields
}
This contains a list of namespaces to be used by the test
Use NewTestBase() as a constructor.
TODO description
func NewTestBase ¶
func (*TestBase) Add ¶
This must be called only and always right after Next(); it will panic otherwise.
Adds a namespace to the lists (if receivedErr is nil)
func (*TestBase) GetAllNamespaces ¶
func (*TestBase) GetDomainNamespaces ¶
func (t *TestBase) GetDomainNamespaces(domain ClusterType) []*Namespace
Return all namespaces of a given domain, such as "prv" or "dmz"
func (*TestBase) GetNamespace ¶
Return the named namespace, if it was created by this TestBase; nil otherwise
func (*TestBase) Next ¶
func (t *TestBase) Next(kind ClusterType, suffix string) (name string, cluster *KubeConfig)
Returns the name and cluster for the next namespace of `kind` in this TestBase, with the expectation that the caller will then immediately create the namespace.
Right after this call, the caller _must_ defer t.Add(), as t.Next() locks a mutex and t.Add() unlocks it — even if the namespace creation operation was not successful. Failing to do so may create deadlocks
If the optional suffix is provided, it will be appended to the end of the name.
Panics if kind is empty. If there are not clusters of the corresponding kind, however, it will use the "pub" list to return a cluster. This allows, for example, tests to request 'pub' and 'prv' namespaces, but run on a single cluster.