1
16
17 package skipper
18
19 import (
20 "context"
21 "fmt"
22
23 "github.com/onsi/ginkgo/v2"
24
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/labels"
27 utilversion "k8s.io/apimachinery/pkg/util/version"
28 "k8s.io/client-go/discovery"
29 clientset "k8s.io/client-go/kubernetes"
30 "k8s.io/component-base/featuregate"
31 "k8s.io/kubernetes/test/e2e/framework"
32 e2enode "k8s.io/kubernetes/test/e2e/framework/node"
33 e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
34 )
35
36 func skipInternalf(caller int, format string, args ...interface{}) {
37 msg := fmt.Sprintf(format, args...)
38 ginkgo.Skip(msg, caller+1)
39 panic("unreachable")
40 }
41
42
43
44 func Skipf(format string, args ...interface{}) {
45 skipInternalf(1, format, args...)
46 panic("unreachable")
47 }
48
49
50 func SkipUnlessAtLeast(value int, minValue int, message string) {
51 if value < minValue {
52 skipInternalf(1, message)
53 }
54 }
55
56 var featureGate featuregate.FeatureGate
57
58
59
60
61 func InitFeatureGates(defaults featuregate.FeatureGate, overrides map[string]bool) error {
62 clone := defaults.DeepCopy()
63 if err := clone.SetFromMap(overrides); err != nil {
64 return err
65 }
66 featureGate = clone
67 return nil
68 }
69
70
71
72
73
74
75
76 func SkipUnlessFeatureGateEnabled(gate featuregate.Feature) {
77 if featureGate == nil {
78 framework.Failf("Feature gate checking is not enabled, don't use SkipUnlessFeatureGateEnabled(%v). Instead use the Feature tag.", gate)
79 }
80 if !featureGate.Enabled(gate) {
81 skipInternalf(1, "Only supported when %v feature is enabled", gate)
82 }
83 }
84
85
86 func SkipUnlessNodeCountIsAtLeast(minNodeCount int) {
87 if framework.TestContext.CloudConfig.NumNodes < minNodeCount {
88 skipInternalf(1, "Requires at least %d nodes (not %d)", minNodeCount, framework.TestContext.CloudConfig.NumNodes)
89 }
90 }
91
92
93 func SkipUnlessNodeCountIsAtMost(maxNodeCount int) {
94 if framework.TestContext.CloudConfig.NumNodes > maxNodeCount {
95 skipInternalf(1, "Requires at most %d nodes (not %d)", maxNodeCount, framework.TestContext.CloudConfig.NumNodes)
96 }
97 }
98
99
100 func SkipIfProviderIs(unsupportedProviders ...string) {
101 if framework.ProviderIs(unsupportedProviders...) {
102 skipInternalf(1, "Not supported for providers %v (found %s)", unsupportedProviders, framework.TestContext.Provider)
103 }
104 }
105
106
107 func SkipUnlessProviderIs(supportedProviders ...string) {
108 if !framework.ProviderIs(supportedProviders...) {
109 skipInternalf(1, "Only supported for providers %v (not %s)", supportedProviders, framework.TestContext.Provider)
110 }
111 }
112
113
114 func SkipUnlessMultizone(ctx context.Context, c clientset.Interface) {
115 zones, err := e2enode.GetClusterZones(ctx, c)
116 if err != nil {
117 skipInternalf(1, "Error listing cluster zones")
118 }
119 if zones.Len() <= 1 {
120 skipInternalf(1, "Requires more than one zone")
121 }
122 }
123
124
125 func SkipIfMultizone(ctx context.Context, c clientset.Interface) {
126 zones, err := e2enode.GetClusterZones(ctx, c)
127 if err != nil {
128 skipInternalf(1, "Error listing cluster zones")
129 }
130 if zones.Len() > 1 {
131 skipInternalf(1, "Requires at most one zone")
132 }
133 }
134
135
136 func SkipUnlessMasterOSDistroIs(supportedMasterOsDistros ...string) {
137 if !framework.MasterOSDistroIs(supportedMasterOsDistros...) {
138 skipInternalf(1, "Only supported for master OS distro %v (not %s)", supportedMasterOsDistros, framework.TestContext.MasterOSDistro)
139 }
140 }
141
142
143 func SkipUnlessNodeOSDistroIs(supportedNodeOsDistros ...string) {
144 if !framework.NodeOSDistroIs(supportedNodeOsDistros...) {
145 skipInternalf(1, "Only supported for node OS distro %v (not %s)", supportedNodeOsDistros, framework.TestContext.NodeOSDistro)
146 }
147 }
148
149
150 func SkipUnlessNodeOSArchIs(supportedNodeOsArchs ...string) {
151 if !framework.NodeOSArchIs(supportedNodeOsArchs...) {
152 skipInternalf(1, "Only supported for node OS arch %v (not %s)", supportedNodeOsArchs, framework.TestContext.NodeOSArch)
153 }
154 }
155
156
157 func SkipIfNodeOSDistroIs(unsupportedNodeOsDistros ...string) {
158 if framework.NodeOSDistroIs(unsupportedNodeOsDistros...) {
159 skipInternalf(1, "Not supported for node OS distro %v (is %s)", unsupportedNodeOsDistros, framework.TestContext.NodeOSDistro)
160 }
161 }
162
163
164 func SkipUnlessServerVersionGTE(v *utilversion.Version, c discovery.ServerVersionInterface) {
165 gte, err := serverVersionGTE(v, c)
166 if err != nil {
167 framework.Failf("Failed to get server version: %v", err)
168 }
169 if !gte {
170 skipInternalf(1, "Not supported for server versions before %q", v)
171 }
172 }
173
174
175 func SkipUnlessSSHKeyPresent() {
176 if _, err := e2essh.GetSigner(framework.TestContext.Provider); err != nil {
177 skipInternalf(1, "No SSH Key for provider %s: '%v'", framework.TestContext.Provider, err)
178 }
179 }
180
181
182 func serverVersionGTE(v *utilversion.Version, c discovery.ServerVersionInterface) (bool, error) {
183 serverVersion, err := c.ServerVersion()
184 if err != nil {
185 return false, fmt.Errorf("Unable to get server version: %w", err)
186 }
187 sv, err := utilversion.ParseSemantic(serverVersion.GitVersion)
188 if err != nil {
189 return false, fmt.Errorf("Unable to parse server version %q: %w", serverVersion.GitVersion, err)
190 }
191 return sv.AtLeast(v), nil
192 }
193
194
195 var AppArmorDistros = []string{"gci", "ubuntu"}
196
197
198 func SkipIfAppArmorNotSupported() {
199 SkipUnlessNodeOSDistroIs(AppArmorDistros...)
200 }
201
202
203 func SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem(ctx context.Context, componentName string, c clientset.Interface, ns string, labelSet labels.Set) {
204
205 label := labels.SelectorFromSet(labelSet)
206 listOpts := metav1.ListOptions{LabelSelector: label.String()}
207 pods, err := c.CoreV1().Pods(ns).List(ctx, listOpts)
208 framework.Logf("SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem: %v, %v", pods, err)
209 if err != nil {
210 skipInternalf(1, "Skipped because client failed to get component:%s pod err:%v", componentName, err)
211 }
212
213 if len(pods.Items) == 0 {
214 skipInternalf(1, "Skipped because component:%s is not running as pod.", componentName)
215 }
216
217
218 pod := pods.Items[0]
219 if err := c.CoreV1().Pods(ns).Delete(ctx, pod.Name, metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}); err != nil {
220 skipInternalf(1, "Skipped because client failed to delete component:%s pod, err:%v", componentName, err)
221 }
222 }
223
224
225 func SkipIfIPv6(unsupportedProviders ...string) {
226 if framework.TestContext.ClusterIsIPv6() && framework.ProviderIs(unsupportedProviders...) {
227 skipInternalf(1, "Not supported for IPv6 clusters and providers %v (found %s)", unsupportedProviders, framework.TestContext.Provider)
228 }
229 }
230
View as plain text