Skip to content

Commit 33fde10

Browse files
committed
Add support of Boskos for AWS
wrote with the assistance of Gemini 2.5 Signed-off-by: Arnaud Meukam <[email protected]>
1 parent e0629cc commit 33fde10

File tree

4 files changed

+126
-36
lines changed

4 files changed

+126
-36
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package deployer
18+
19+
import (
20+
"encoding/json"
21+
"fmt"
22+
"os"
23+
24+
"k8s.io/klog/v2"
25+
"sigs.k8s.io/kubetest2/pkg/boskos"
26+
)
27+
28+
func (d *deployer) acquireBoskosAWSAccount() error {
29+
klog.V(1).Info("Acquiring AWS account from Boskos")
30+
31+
boskosClient, err := boskos.NewClient(d.BoskosLocation)
32+
if err != nil {
33+
return fmt.Errorf("failed to make boskos client: %s", err)
34+
}
35+
d.boskos = boskosClient
36+
37+
resource, err := boskos.Acquire(
38+
d.boskos,
39+
d.BoskosAWSResourceType,
40+
d.BoskosAcquireTimeout,
41+
d.BoskosHeartbeatInterval,
42+
d.boskosHeartbeatClose,
43+
)
44+
if err != nil {
45+
return fmt.Errorf("init failed to get aws account from boskos: %s", err)
46+
}
47+
d.boskosAWSAccount = resource.Name
48+
klog.V(1).Infof("Got aws account %s from boskos", d.boskosAWSAccount)
49+
50+
var data struct {
51+
AccessKeyID string `json:"access_key_id"`
52+
SecretAccessKey string `json:"secret_access_key"`
53+
SessionToken string `json:"session_token"`
54+
}
55+
if err := json.Unmarshal([]byte(resource.UserData), &data); err != nil {
56+
return fmt.Errorf("failed to unmarshal boskos user data: %s", err)
57+
}
58+
59+
os.Setenv("AWS_ACCESS_KEY_ID", data.AccessKeyID)
60+
os.Setenv("AWS_SECRET_ACCESS_KEY", data.SecretAccessKey)
61+
os.Setenv("AWS_SESSION_TOKEN", data.SessionToken)
62+
63+
return nil
64+
}
65+
66+
func (d *deployer) acquireBoskosGCPProject() error {
67+
klog.V(1).Info("No GCP project provided, acquiring from Boskos")
68+
69+
boskosClient, err := boskos.NewClient(d.BoskosLocation)
70+
if err != nil {
71+
return fmt.Errorf("failed to make boskos client: %s", err)
72+
}
73+
d.boskos = boskosClient
74+
75+
resource, err := boskos.Acquire(
76+
d.boskos,
77+
d.BoskosGCPResourceType,
78+
d.BoskosAcquireTimeout,
79+
d.BoskosHeartbeatInterval,
80+
d.boskosHeartbeatClose,
81+
)
82+
if err != nil {
83+
return fmt.Errorf("init failed to get project from boskos: %s", err)
84+
}
85+
d.GCPProject = resource.Name
86+
klog.V(1).Infof("Got project %s from boskos", d.GCPProject)
87+
return nil
88+
}
89+
90+
func (d *deployer) releaseBoskosResources() error {
91+
if d.boskos == nil {
92+
return nil
93+
}
94+
klog.V(2).Info("releasing boskos project")
95+
resources := []string{}
96+
if d.GCPProject != "" {
97+
resources = append(resources, d.GCPProject)
98+
}
99+
if d.boskosAWSAccount != "" {
100+
resources = append(resources, d.boskosAWSAccount)
101+
}
102+
err := boskos.Release(
103+
d.boskos,
104+
resources,
105+
d.boskosHeartbeatClose,
106+
)
107+
if err != nil {
108+
return fmt.Errorf("down failed to release boskos project: %s", err)
109+
}
110+
return nil
111+
}

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
3030
"k8s.io/kops/tests/e2e/pkg/target"
3131
"k8s.io/kops/tests/e2e/pkg/util"
32-
"sigs.k8s.io/kubetest2/pkg/boskos"
3332
)
3433

3534
func (d *deployer) init() error {
@@ -53,6 +52,11 @@ func (d *deployer) initialize() error {
5352

5453
switch d.CloudProvider {
5554
case "aws":
55+
if d.UseBoskosAWS {
56+
if err := d.acquireBoskosAWSAccount(); err != nil {
57+
return err
58+
}
59+
}
5660
client, err := aws.NewClient(context.Background())
5761
if err != nil {
5862
return fmt.Errorf("init failed to build AWS client: %w", err)
@@ -91,26 +95,9 @@ func (d *deployer) initialize() error {
9195
d.SSHUser = "root"
9296
case "gce":
9397
if d.GCPProject == "" {
94-
klog.V(1).Info("No GCP project provided, acquiring from Boskos")
95-
96-
boskosClient, err := boskos.NewClient(d.BoskosLocation)
97-
if err != nil {
98-
return fmt.Errorf("failed to make boskos client: %s", err)
99-
}
100-
d.boskos = boskosClient
101-
102-
resource, err := boskos.Acquire(
103-
d.boskos,
104-
d.BoskosResourceType,
105-
d.BoskosAcquireTimeout,
106-
d.BoskosHeartbeatInterval,
107-
d.boskosHeartbeatClose,
108-
)
109-
if err != nil {
110-
return fmt.Errorf("init failed to get project from boskos: %s", err)
98+
if err := d.acquireBoskosGCPProject(); err != nil {
99+
return err
111100
}
112-
d.GCPProject = resource.Name
113-
klog.V(1).Infof("Got project %s from boskos", d.GCPProject)
114101

115102
if d.SSHPrivateKeyPath == "" {
116103
d.SSHPrivateKeyPath = os.Getenv("GCE_SSH_PRIVATE_KEY_FILE")

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ type deployer struct {
105105
// boskos struct field will be non-nil when the deployer is
106106
// using boskos to acquire a GCP project
107107
boskos *client.Client
108+
boskosAWSAccount string
108109
BoskosLocation string `flag:"boskos-location" desc:"If set, manually specifies the location of the Boskos server."`
109110
BoskosAcquireTimeout time.Duration `flag:"boskos-acquire-timeout" desc:"How long should boskos wait to acquire a resource before timing out"`
110111
BoskosHeartbeatInterval time.Duration `flag:"boskos-heartbeat-interval" desc:"How often should boskos send a heartbeat to Boskos to hold the acquired resource. 0 means no heartbeat."`
111-
BoskosResourceType string `flag:"boskos-resource-type" desc:"If set, manually specifies the resource type of GCP projects to acquire from Boskos."`
112+
BoskosGCPResourceType string `flag:"boskos-gcp-resource-type" desc:"If set, manually specifies the resource type of GCP projects to acquire from Boskos."`
113+
BoskosAWSResourceType string `flag:"boskos-aws-resource-type" desc:"If set, manually specifies the resource type of AWS accounts to acquire from Boskos."`
114+
UseBoskosAWS bool `flag:"use-boskos-aws" desc:"If set, use boskos to acquire AWS accounts."`
115+
112116
// this channel serves as a signal channel for the hearbeat goroutine
113117
// so that it can be explicitly closed
114118
boskosHeartbeatClose chan struct{}
@@ -139,7 +143,8 @@ func New(opts types.Options) (types.Deployer, *pflag.FlagSet) {
139143
ValidationCount: 10,
140144
ValidationInterval: 10 * time.Second,
141145
BoskosLocation: "http://boskos.test-pods.svc.cluster.local.",
142-
BoskosResourceType: "gce-project",
146+
BoskosGCPResourceType: "gce-project",
147+
BoskosAWSResourceType: "aws-account",
143148
BoskosAcquireTimeout: 5 * time.Minute,
144149
BoskosHeartbeatInterval: 5 * time.Minute,
145150
Tags: []string{

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ package deployer
1818

1919
import (
2020
"context"
21-
"fmt"
2221
"strings"
2322

2423
"k8s.io/klog/v2"
2524
"k8s.io/kops/tests/e2e/kubetest2-kops/gce"
2625
"k8s.io/kops/tests/e2e/pkg/kops"
27-
"sigs.k8s.io/kubetest2/pkg/boskos"
2826
"sigs.k8s.io/kubetest2/pkg/exec"
2927
)
3028

@@ -86,16 +84,5 @@ func (d *deployer) Down() error {
8684
}
8785
}
8886

89-
if d.boskos != nil {
90-
klog.V(2).Info("releasing boskos project")
91-
err := boskos.Release(
92-
d.boskos,
93-
[]string{d.GCPProject},
94-
d.boskosHeartbeatClose,
95-
)
96-
if err != nil {
97-
return fmt.Errorf("down failed to release boskos project: %s", err)
98-
}
99-
}
100-
return nil
87+
return d.releaseBoskosResources()
10188
}

0 commit comments

Comments
 (0)