Moving to scaleset client for the controller (#4390)
This commit is contained in:
@@ -3,13 +3,12 @@ package actionsgithubcom
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -19,7 +18,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -28,9 +26,10 @@ import (
|
||||
|
||||
"github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
|
||||
"github.com/actions/actions-runner-controller/build"
|
||||
"github.com/actions/actions-runner-controller/github/actions"
|
||||
"github.com/actions/actions-runner-controller/github/actions/fake"
|
||||
"github.com/actions/actions-runner-controller/github/actions/testserver"
|
||||
"github.com/actions/actions-runner-controller/controllers/actions.github.com/multiclient"
|
||||
scalefake "github.com/actions/actions-runner-controller/controllers/actions.github.com/multiclient/fake"
|
||||
"github.com/actions/actions-runner-controller/controllers/actions.github.com/secretresolver"
|
||||
"github.com/actions/scaleset"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -63,6 +62,10 @@ var _ = Describe("Test AutoScalingRunnerSet controller", Ordered, func() {
|
||||
autoscalingNS, mgr = createNamespace(GinkgoT(), k8sClient)
|
||||
configSecret = createDefaultSecret(GinkgoT(), k8sClient, autoscalingNS.Name)
|
||||
|
||||
// Track runner group mappings for dynamic responses
|
||||
runnerGroupMap := map[int]string{1: "testgroup"} // ID -> Name mapping
|
||||
runnerGroupMapLock := &sync.RWMutex{} // Thread-safe access
|
||||
|
||||
controller = &AutoscalingRunnerSetReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
@@ -70,10 +73,30 @@ var _ = Describe("Test AutoScalingRunnerSet controller", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient(
|
||||
scalefake.WithClient(
|
||||
scalefake.NewClient(
|
||||
scalefake.WithGetRunnerGroupByNameFunc(func(ctx context.Context, groupName string) (*scaleset.RunnerGroup, error) {
|
||||
// Support both "testgroup" and "testgroup2"
|
||||
// Update the mapping when a new group is requested
|
||||
runnerGroupMapLock.Lock()
|
||||
runnerGroupMap[1] = groupName
|
||||
runnerGroupMapLock.Unlock()
|
||||
return &scaleset.RunnerGroup{ID: 1, Name: groupName}, nil
|
||||
}),
|
||||
scalefake.WithGetRunnerScaleSet(nil, nil),
|
||||
scalefake.WithCreateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithUpdateRunnerScaleSetFunc(func(ctx context.Context, scaleSetID int, rs *scaleset.RunnerScaleSet) (*scaleset.RunnerScaleSet, error) {
|
||||
// Return a RunnerScaleSet with the group name corresponding to the runner group ID
|
||||
runnerGroupMapLock.RLock()
|
||||
groupName := runnerGroupMap[rs.RunnerGroupID]
|
||||
runnerGroupMapLock.RUnlock()
|
||||
return &scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: rs.RunnerGroupID, RunnerGroupName: groupName}, nil
|
||||
}),
|
||||
scalefake.WithDeleteRunnerScaleSet(nil),
|
||||
),
|
||||
),
|
||||
)),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
@@ -681,25 +704,34 @@ var _ = Describe("Test AutoScalingController updates", Ordered, func() {
|
||||
autoscalingNS, mgr = createNamespace(GinkgoT(), k8sClient)
|
||||
configSecret = createDefaultSecret(GinkgoT(), k8sClient, autoscalingNS.Name)
|
||||
|
||||
multiClient := fake.NewMultiClient(
|
||||
fake.WithDefaultClient(
|
||||
fake.NewFakeClient(
|
||||
fake.WithUpdateRunnerScaleSet(
|
||||
&actions.RunnerScaleSet{
|
||||
Id: 1,
|
||||
multiClient := scalefake.NewMultiClient(
|
||||
scalefake.WithClient(
|
||||
scalefake.NewClient(
|
||||
scalefake.WithGenerateJitRunnerConfig(
|
||||
&scaleset.RunnerScaleSetJitRunnerConfig{
|
||||
Runner: &scaleset.RunnerReference{ID: 1, Name: "test-runner"},
|
||||
EncodedJITConfig: "fake-jit-config",
|
||||
},
|
||||
nil,
|
||||
),
|
||||
scalefake.WithGetRunnerGroupByName(&scaleset.RunnerGroup{ID: 1, Name: "testgroup"}, nil),
|
||||
scalefake.WithGetRunnerScaleSet(nil, nil),
|
||||
scalefake.WithCreateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "testset", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithUpdateRunnerScaleSet(
|
||||
&scaleset.RunnerScaleSet{
|
||||
ID: 1,
|
||||
Name: "testset_update",
|
||||
RunnerGroupId: 1,
|
||||
RunnerGroupID: 1,
|
||||
RunnerGroupName: "testgroup",
|
||||
Labels: []actions.Label{{Type: "test", Name: "test"}},
|
||||
RunnerSetting: actions.RunnerSetting{},
|
||||
Labels: []scaleset.Label{{Type: "test", Name: "test"}},
|
||||
RunnerSetting: scaleset.RunnerSetting{},
|
||||
CreatedOn: time.Now(),
|
||||
RunnerJitConfigUrl: "test.test.test",
|
||||
RunnerJitConfigURL: "test.test.test",
|
||||
Statistics: nil,
|
||||
},
|
||||
nil,
|
||||
),
|
||||
),
|
||||
nil,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -710,10 +742,7 @@ var _ = Describe("Test AutoScalingController updates", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: multiClient,
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), multiClient),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
@@ -830,10 +859,7 @@ var _ = Describe("Test AutoscalingController creation failures", Ordered, func()
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient()),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
@@ -953,7 +979,6 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
ctx = context.Background()
|
||||
autoscalingNS, mgr = createNamespace(GinkgoT(), k8sClient)
|
||||
configSecret = createDefaultSecret(GinkgoT(), k8sClient, autoscalingNS.Name)
|
||||
multiClient := actions.NewMultiClient(logr.Discard())
|
||||
controller = &AutoscalingRunnerSetReconciler{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
@@ -961,10 +986,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: multiClient,
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), multiclient.NewScaleset()),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -976,10 +998,11 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
|
||||
It("should be able to make requests to a server using a proxy", func() {
|
||||
serverSuccessfullyCalled := false
|
||||
proxy := testserver.New(GinkgoT(), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
serverSuccessfullyCalled = true
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer proxy.Close()
|
||||
|
||||
min := 1
|
||||
max := 10
|
||||
@@ -1029,23 +1052,17 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
})
|
||||
|
||||
It("should be able to make requests to a server using a proxy with user info", func() {
|
||||
serverSuccessfullyCalled := false
|
||||
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
header := r.Header.Get("Proxy-Authorization")
|
||||
Expect(header).NotTo(BeEmpty())
|
||||
|
||||
header = strings.TrimPrefix(header, "Basic ")
|
||||
decoded, err := base64.StdEncoding.DecodeString(header)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(decoded)).To(Equal("test:password"))
|
||||
|
||||
serverSuccessfullyCalled = true
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
GinkgoT().Cleanup(func() {
|
||||
proxy.Close()
|
||||
})
|
||||
|
||||
controller.ResourceBuilder.SecretResolver = secretresolver.New(k8sClient, scalefake.NewMultiClient(
|
||||
scalefake.WithClient(
|
||||
scalefake.NewClient(
|
||||
scalefake.WithGetRunnerGroupByName(&scaleset.RunnerGroup{ID: 1, Name: "testgroup"}, nil),
|
||||
scalefake.WithGetRunnerScaleSet(nil, nil),
|
||||
scalefake.WithCreateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithUpdateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithDeleteRunnerScaleSet(nil),
|
||||
),
|
||||
),
|
||||
))
|
||||
secretCredentials := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "proxy-credentials",
|
||||
@@ -1057,6 +1074,11 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
},
|
||||
}
|
||||
|
||||
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer proxy.Close()
|
||||
|
||||
err := k8sClient.Create(ctx, secretCredentials)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to create secret credentials")
|
||||
|
||||
@@ -1078,7 +1100,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
RunnerGroup: "testgroup",
|
||||
Proxy: &v1alpha1.ProxyConfig{
|
||||
HTTP: &v1alpha1.ProxyServerConfig{
|
||||
Url: proxy.URL,
|
||||
Url: "http://test:password@" + proxy.Listener.Addr().String(),
|
||||
CredentialSecretRef: "proxy-credentials",
|
||||
},
|
||||
},
|
||||
@@ -1098,14 +1120,24 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
err = k8sClient.Create(ctx, autoscalingRunnerSet)
|
||||
Expect(err).NotTo(HaveOccurred(), "failed to create AutoScalingRunnerSet")
|
||||
|
||||
// wait for server to be called
|
||||
// Verify proxy config with credentials is propagated to EphemeralRunnerSet
|
||||
Eventually(
|
||||
func() (bool, error) {
|
||||
return serverSuccessfullyCalled, nil
|
||||
func() (*v1alpha1.EphemeralRunnerSet, error) {
|
||||
runnerSetList := new(v1alpha1.EphemeralRunnerSetList)
|
||||
err := k8sClient.List(ctx, runnerSetList, client.InNamespace(autoscalingNS.Name))
|
||||
if err != nil || len(runnerSetList.Items) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return &runnerSetList.Items[0], nil
|
||||
},
|
||||
autoscalingRunnerSetTestTimeout,
|
||||
1*time.Nanosecond,
|
||||
).Should(BeTrue(), "server was not called")
|
||||
autoscalingRunnerSetTestInterval,
|
||||
).Should(WithTransform(func(ers *v1alpha1.EphemeralRunnerSet) *v1alpha1.ProxyConfig {
|
||||
if ers != nil {
|
||||
return ers.Spec.EphemeralRunnerSpec.Proxy
|
||||
}
|
||||
return nil
|
||||
}, Not(BeNil())), "EphemeralRunnerSet should have proxy configuration with credentials")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1149,10 +1181,17 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient(
|
||||
scalefake.WithClient(
|
||||
scalefake.NewClient(
|
||||
scalefake.WithGetRunnerGroupByName(&scaleset.RunnerGroup{ID: 1, Name: "testgroup"}, nil),
|
||||
scalefake.WithGetRunnerScaleSet(nil, nil),
|
||||
scalefake.WithCreateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithUpdateRunnerScaleSet(&scaleset.RunnerScaleSet{ID: 1, Name: "test-asrs", RunnerGroupID: 1, RunnerGroupName: "testgroup"}, nil),
|
||||
scalefake.WithDeleteRunnerScaleSet(nil),
|
||||
),
|
||||
),
|
||||
)),
|
||||
},
|
||||
}
|
||||
err = controller.SetupWithManager(mgr)
|
||||
@@ -1162,10 +1201,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
})
|
||||
|
||||
It("should be able to make requests to a server using root CAs", func() {
|
||||
controller.SecretResolver = &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: actions.NewMultiClient(logr.Discard()),
|
||||
}
|
||||
controller.SecretResolver = secretresolver.New(k8sClient, multiclient.NewScaleset())
|
||||
|
||||
certsFolder := filepath.Join(
|
||||
"../../",
|
||||
@@ -1177,7 +1213,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
keyPath := filepath.Join(certsFolder, "server.key")
|
||||
|
||||
serverSuccessfullyCalled := false
|
||||
server := testserver.NewUnstarted(GinkgoT(), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
serverSuccessfullyCalled = true
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
@@ -1186,6 +1222,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
|
||||
server.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||
server.StartTLS()
|
||||
defer server.Close()
|
||||
|
||||
min := 1
|
||||
max := 10
|
||||
@@ -1198,7 +1235,7 @@ var _ = Describe("Test client optional configuration", Ordered, func() {
|
||||
},
|
||||
},
|
||||
Spec: v1alpha1.AutoscalingRunnerSetSpec{
|
||||
GitHubConfigUrl: server.ConfigURLForOrg("my-org"),
|
||||
GitHubConfigUrl: server.URL + "/my-org",
|
||||
GitHubConfigSecret: configSecret.Name,
|
||||
GitHubServerTLS: &v1alpha1.TLSConfig{
|
||||
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
||||
@@ -1391,10 +1428,7 @@ var _ = Describe("Test external permissions cleanup", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient()),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
@@ -1554,10 +1588,7 @@ var _ = Describe("Test external permissions cleanup", Ordered, func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient()),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
@@ -1767,10 +1798,7 @@ var _ = Describe("Test resource version and build version mismatch", func() {
|
||||
ControllerNamespace: autoscalingNS.Name,
|
||||
DefaultRunnerScaleSetListenerImage: "ghcr.io/actions/arc",
|
||||
ResourceBuilder: ResourceBuilder{
|
||||
SecretResolver: &SecretResolver{
|
||||
k8sClient: k8sClient,
|
||||
multiClient: fake.NewMultiClient(),
|
||||
},
|
||||
SecretResolver: secretresolver.New(mgr.GetClient(), scalefake.NewMultiClient()),
|
||||
},
|
||||
}
|
||||
err := controller.SetupWithManager(mgr)
|
||||
|
||||
Reference in New Issue
Block a user