Skip to content

Commit 88ff432

Browse files
authored
Merge pull request #17887 from upodroid/fix-tests
fix podidentitywebhook test
2 parents e1d829d + 3f73c6a commit 88ff432

9 files changed

Lines changed: 136 additions & 47 deletions

File tree

tests/e2e/kubetest2-kops/aws/s3.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ const (
5353
)
5454

5555
// NewAWSClient returns a new instance of awsClient configured to work in the default region (us-east-2).
56-
func NewClient(ctx context.Context) (*Client, error) {
56+
func NewClient(ctx context.Context, region string) (*Client, error) {
5757
cfg, err := awsconfig.LoadDefaultConfig(ctx,
58-
awsconfig.WithRegion(defaultRegion))
58+
awsconfig.WithRegion(region))
5959
if err != nil {
6060
return nil, fmt.Errorf("loading AWS config: %w", err)
6161
}
@@ -71,8 +71,8 @@ func (c Client) BucketName(ctx context.Context, bucketType BucketType) (string,
7171
// Construct the bucket name based on the ProwJob ID (if running in Prow) or AWS account ID (if running outside
7272
// Prow) and the current timestamp
7373
var identifier string
74-
if jobID := os.Getenv("PROW_JOB_ID"); len(jobID) >= 4 {
75-
identifier = jobID[:4]
74+
if jobID := os.Getenv("BUILD_ID"); len(jobID) >= 4 {
75+
identifier = jobID[len(jobID)-4:]
7676
} else {
7777
callerIdentity, err := c.stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
7878
if err != nil {
@@ -95,15 +95,18 @@ func (c Client) BucketName(ctx context.Context, bucketType BucketType) (string,
9595
}
9696

9797
// EnsureS3Bucket creates a new S3 bucket with the given name and public read permissions.
98-
func (c Client) EnsureS3Bucket(ctx context.Context, bucketName string, publicRead bool) error {
98+
func (c Client) EnsureS3Bucket(ctx context.Context, region, bucketName string, publicRead bool) error {
9999
bucketName = strings.TrimPrefix(bucketName, "s3://")
100-
klog.Infof("Creating bucket %s in region %s", bucketName, defaultRegion)
100+
klog.Infof("Creating bucket %s in region %s", bucketName, region)
101+
bucketConfig := &types.CreateBucketConfiguration{}
102+
if region != "us-east-1" {
103+
bucketConfig.LocationConstraint = types.BucketLocationConstraint(region)
104+
}
101105
_, err := c.s3Client.CreateBucket(ctx, &s3.CreateBucketInput{
102-
Bucket: aws.String(bucketName),
103-
CreateBucketConfiguration: &types.CreateBucketConfiguration{
104-
LocationConstraint: defaultRegion,
105-
},
106-
})
106+
Bucket: aws.String(bucketName),
107+
CreateBucketConfiguration: bucketConfig,
108+
},
109+
)
107110
if err != nil {
108111
var exists *types.BucketAlreadyExists
109112
if errors.As(err, &exists) {
@@ -130,15 +133,16 @@ func (c Client) EnsureS3Bucket(ctx context.Context, bucketName string, publicRea
130133
klog.Infof("Bucket %s created successfully", bucketName)
131134

132135
if publicRead {
133-
// We assume it will take 5-10 seconds for the bucket to be created and wait for it.
134-
time.Sleep(10 * time.Second)
135136
err = c.setPublicAccessBlock(ctx, bucketName)
136137
if err != nil {
137138
klog.Errorf("Failed to disable public access block policies on bucket %s, err: %v", bucketName, err)
138139

139140
return fmt.Errorf("disabling public access block policies for bucket %s: %w", bucketName, err)
140141
}
141142

143+
// Wait for public access block settings to propagate before setting the policy
144+
time.Sleep(10 * time.Second)
145+
142146
err = c.setPublicReadPolicy(ctx, bucketName)
143147
if err != nil {
144148
klog.Errorf("Failed to set public read policy on bucket %s, err: %v", bucketName, err)

tests/e2e/kubetest2-kops/deployer/build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (d *deployer) verifyBuildFlags() error {
115115
} else if d.boskos != nil {
116116
d.StageLocation = d.stagingStore()
117117
klog.Infof("creating staging bucket %s to hold kops/kubernetes build artifacts", d.StageLocation)
118-
if err := gce.EnsureGCSBucket(d.StageLocation, d.GCPProject, true); err != nil {
118+
if err := gce.EnsureGCSBucket(d.StageLocation, d.region, d.GCPProject, true); err != nil {
119119
return err
120120
}
121121
} else {

tests/e2e/kubetest2-kops/deployer/common.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,15 @@ func (d *deployer) initialize() error {
5151
}
5252
}
5353

54+
var err error
55+
d.zones, err = d.getZones()
56+
if err != nil {
57+
return err
58+
}
5459
switch d.CloudProvider {
5560
case "aws":
56-
client, err := aws.NewClient(context.Background())
61+
d.region = d.zones[0][:len(d.zones[0])-1]
62+
client, err := aws.NewClient(context.Background(), d.region)
5763
if err != nil {
5864
return fmt.Errorf("init failed to build AWS client: %w", err)
5965
}
@@ -90,6 +96,10 @@ func (d *deployer) initialize() error {
9096
}
9197
d.SSHUser = "root"
9298
case "gce":
99+
d.region, err = gce.ZoneToRegion(d.zones[0])
100+
if err != nil {
101+
return err
102+
}
93103
if d.GCPProject == "" {
94104
klog.V(1).Info("No GCP project provided, acquiring from Boskos")
95105

@@ -170,7 +180,7 @@ func (d *deployer) initialize() error {
170180
// verifyKopsFlags ensures common fields are set for kops commands
171181
func (d *deployer) verifyKopsFlags() error {
172182
if d.ClusterName == "" {
173-
name, err := defaultClusterName(d.CloudProvider)
183+
name, err := d.defaultClusterName()
174184
if err != nil {
175185
return err
176186
}
@@ -311,7 +321,7 @@ func (d *deployer) featureFlags() string {
311321
}
312322

313323
// defaultClusterName returns a kops cluster name to use when ClusterName is not set
314-
func defaultClusterName(cloudProvider string) (string, error) {
324+
func (d *deployer) defaultClusterName() (string, error) {
315325
dnsDomain := os.Getenv("KOPS_DNS_DOMAIN")
316326
jobName := os.Getenv("JOB_NAME")
317327
jobType := os.Getenv("JOB_TYPE")
@@ -328,9 +338,13 @@ func defaultClusterName(cloudProvider string) (string, error) {
328338
}
329339

330340
var suffix string
331-
switch cloudProvider {
341+
switch d.CloudProvider {
332342
case "aws":
333-
suffix = dnsDomain
343+
if strings.Contains(d.CreateArgs, "--dns=none") {
344+
suffix = "k8s.local"
345+
} else {
346+
suffix = dnsDomain
347+
}
334348
case "azure":
335349
// Azure uses --dns=none and the domain is not needed
336350
suffix = ""
@@ -349,7 +363,7 @@ func defaultClusterName(cloudProvider string) (string, error) {
349363

350364
// GCP has char limit of 64
351365
gcpLimit := 63 - (len(suffix) + 1) // 1 for the dot
352-
if len(jobName) > gcpLimit && cloudProvider == "gce" {
366+
if len(jobName) > gcpLimit && d.CloudProvider == "gce" {
353367
jobName = jobName[:gcpLimit]
354368
}
355369

tests/e2e/kubetest2-kops/deployer/deployer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ type deployer struct {
100100
stateStoreName string
101101
discoveryStoreName string
102102
stagingStoreName string
103+
region string
104+
zones []string
103105

104106
// boskos struct field will be non-nil when the deployer is
105107
// using boskos to acquire a GCP project

tests/e2e/kubetest2-kops/deployer/up.go

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ func (d *deployer) Up() error {
7070
switch d.CloudProvider {
7171
case "aws":
7272
ctx := context.Background()
73-
if err := d.aws.EnsureS3Bucket(ctx, d.stateStore(), false); err != nil {
73+
if err := d.aws.EnsureS3Bucket(ctx, d.region, d.stateStore(), false); err != nil {
7474
return err
7575
}
76-
if err := d.aws.EnsureS3Bucket(ctx, d.discoveryStore(), true); err != nil {
76+
if err := d.aws.EnsureS3Bucket(ctx, d.region, d.discoveryStore(), true); err != nil {
7777
return err
7878
}
7979
case "gce":
80-
if err := gce.EnsureGCSBucket(d.stateStore(), d.GCPProject, false); err != nil {
80+
if err := gce.EnsureGCSBucket(d.stateStore(), d.region, d.GCPProject, false); err != nil {
8181
return err
8282
}
8383
}
@@ -93,18 +93,13 @@ func (d *deployer) Up() error {
9393
adminAccess = publicIP
9494
}
9595

96-
zones, err := d.zones()
97-
if err != nil {
98-
return err
99-
}
100-
10196
// Write out the env file for kops
10297
if err := d.writeEnvFile(ctx); err != nil {
10398
return fmt.Errorf("error writing env file %q: %v", d.EnvFile, err)
10499
}
105100

106101
if d.TemplatePath != "" {
107-
values, err := d.templateValues(zones, adminAccess)
102+
values, err := d.templateValues(d.zones, adminAccess)
108103
if err != nil {
109104
return err
110105
}
@@ -116,13 +111,13 @@ func (d *deployer) Up() error {
116111
}
117112
} else {
118113
if d.terraform != nil {
119-
if err := d.createCluster(zones, adminAccess, true); err != nil {
114+
if err := d.createCluster(d.zones, adminAccess, true); err != nil {
120115
return err
121116
}
122117
} else {
123118
// For the non-terraform case, we want to see the preview output.
124119
// So run a create (which logs the output), then do an update
125-
if err := d.createCluster(zones, adminAccess, false); err != nil {
120+
if err := d.createCluster(d.zones, adminAccess, false); err != nil {
126121
return err
127122
}
128123
if err := d.updateCluster(true); err != nil {
@@ -383,7 +378,35 @@ func (d *deployer) verifyUpFlags() error {
383378
return nil
384379
}
385380

386-
func (d *deployer) zones() ([]string, error) {
381+
func extractZones(args string) []string {
382+
// Zones are specified by --zones=zone1,zone2
383+
prefix := "--zones="
384+
startIdx := strings.Index(args, prefix)
385+
386+
if startIdx == -1 {
387+
return []string{}
388+
}
389+
390+
startIdx += len(prefix)
391+
392+
endIdx := strings.Index(args[startIdx:], " ")
393+
var zonesValue string
394+
395+
if endIdx == -1 {
396+
zonesValue = args[startIdx:]
397+
} else {
398+
zonesValue = args[startIdx : startIdx+endIdx]
399+
}
400+
return strings.Split(zonesValue, ",")
401+
}
402+
403+
func (d *deployer) getZones() ([]string, error) {
404+
if d.CreateArgs != "" {
405+
zones := extractZones(d.CreateArgs)
406+
if len(zones) > 0 {
407+
return zones, nil
408+
}
409+
}
387410
switch d.CloudProvider {
388411
case "aws":
389412
return aws.RandomZones(d.ControlPlaneCount)

tests/e2e/kubetest2-kops/gce/gcs.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func GCSBucketName(projectID, prefix string) string {
4040
return bucket
4141
}
4242

43-
func EnsureGCSBucket(bucketPath, projectID string, public bool) error {
43+
func EnsureGCSBucket(bucketPath, region, projectID string, public bool) error {
4444
lsArgs := []string{
4545
"gsutil", "ls", "-b",
4646
}
@@ -66,6 +66,9 @@ func EnsureGCSBucket(bucketPath, projectID string, public bool) error {
6666
if projectID != "" {
6767
mbArgs = append(mbArgs, "-p", projectID)
6868
}
69+
if region != "" {
70+
mbArgs = append(mbArgs, "-l", region)
71+
}
6972
mbArgs = append(mbArgs, bucketPath)
7073

7174
klog.Info(strings.Join(mbArgs, " "))

tests/e2e/kubetest2-kops/gce/zones.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ package gce
1818

1919
import (
2020
"errors"
21+
"fmt"
2122
"math/rand"
2223
"sort"
24+
"strings"
2325
)
2426

2527
var allZones = []string{
@@ -77,3 +79,13 @@ func RandomZones(count int) ([]string, error) {
7779
sort.Strings(chosenZones)
7880
return chosenZones, nil
7981
}
82+
83+
// ZoneToRegion maps a GCE zone name to a GCE region name, returning an error if it cannot be mapped
84+
func ZoneToRegion(zone string) (string, error) {
85+
tokens := strings.Split(zone, "-")
86+
if len(tokens) <= 2 {
87+
return "", fmt.Errorf("invalid GCE Zone: %v", zone)
88+
}
89+
region := tokens[0] + "-" + tokens[1]
90+
return region, nil
91+
}

tests/e2e/scenarios/podidentitywebhook/run-test.sh

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,30 @@
1515
# limitations under the License.
1616

1717
REPO_ROOT=$(git rev-parse --show-toplevel);
18-
source "${REPO_ROOT}"/tests/e2e/scenarios/lib/common.sh
1918
TEST_ROOT="${REPO_ROOT}/tests/e2e/scenarios/podidentitywebhook"
2019

2120
# shellcheck disable=SC2034
2221
KOPS_TEMPLATE="${TEST_ROOT}/cluster.yaml.tmpl"
2322

24-
kops-acquire-latest
25-
26-
kops-up
27-
28-
kubectl apply -f "${TEST_ROOT}"/pod.yaml
29-
30-
kubectl -n default wait --for=condition=Ready pod/pod-identity-webhook-test
31-
32-
# This command will exit code 253 if there are no credentials
33-
kubectl exec -it -n default pod-identity-webhook-test -- aws sts get-caller-identity
34-
35-
36-
23+
make test-e2e-install
24+
export KOPS_STATE_STORE=
25+
export CLUSTER_NAME=
26+
27+
KUBETEST2_ARGS=()
28+
KUBETEST2_ARGS+=("-v=2")
29+
30+
if [[ "${JOB_TYPE}" == "presubmit" && "${REPO_OWNER}/${REPO_NAME}" == "kubernetes/kops" ]]; then
31+
KUBETEST2_ARGS+=("--build")
32+
KUBETEST2_ARGS+=("--kops-binary-path=${GOPATH}/src/k8s.io/kops/.build/dist/linux/$(go env GOARCH)/kops")
33+
else
34+
KUBETEST2_ARGS+=("--kops-version-marker=${KOPS_VERSION_MARKER:-https://storage.googleapis.com/k8s-staging-kops/kops/releases/markers/master/latest-ci.txt}")
35+
fi
36+
37+
kubetest2 kops \
38+
--up --down \
39+
"${KUBETEST2_ARGS[@]}" \
40+
--cloud-provider=aws \
41+
--create-args="--zones=us-east-1a" \
42+
--template-path="${KOPS_TEMPLATE}" \
43+
--kubernetes-version=https://dl.k8s.io/release/stable.txt \
44+
--test=exec -- "${TEST_ROOT}/test.sh"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2026 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
REPO_ROOT=$(git rev-parse --show-toplevel);
18+
kubectl apply -f "${REPO_ROOT}/tests/e2e/scenarios/podidentitywebhook/pod.yaml"
19+
20+
kubectl -n default wait --for=condition=Ready pod/pod-identity-webhook-test
21+
22+
# This command will exit code 253 if there are no credentials
23+
kubectl exec -it -n default pod-identity-webhook-test -- aws sts get-caller-identity

0 commit comments

Comments
 (0)