parent
b6c33cee32
commit
b305e38b17
|
|
@ -18,6 +18,7 @@ package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -40,6 +41,8 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
scaleTargetKey = "scaleTarget"
|
scaleTargetKey = "scaleTarget"
|
||||||
|
|
||||||
|
keyPrefixEnterprise = "enterprises/"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HorizontalRunnerAutoscalerGitHubWebhook autoscales a HorizontalRunnerAutoscaler and the RunnerDeployment on each
|
// HorizontalRunnerAutoscalerGitHubWebhook autoscales a HorizontalRunnerAutoscaler and the RunnerDeployment on each
|
||||||
|
|
@ -141,6 +144,20 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
"delivery", r.Header.Get("X-GitHub-Delivery"),
|
"delivery", r.Header.Get("X-GitHub-Delivery"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var enterpriseEvent struct {
|
||||||
|
Enterprise struct {
|
||||||
|
Slug string `json:"slug,omitempty"`
|
||||||
|
} `json:"enterprise,omitempty"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(payload, &enterpriseEvent); err != nil {
|
||||||
|
var s string
|
||||||
|
if payload != nil {
|
||||||
|
s = string(payload)
|
||||||
|
}
|
||||||
|
autoscaler.Log.Error(err, "could not parse webhook payload for extracting enterprise slug", "webhookType", webhookType, "payload", s)
|
||||||
|
}
|
||||||
|
enterpriseSlug := enterpriseEvent.Enterprise.Slug
|
||||||
|
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *gogithub.PushEvent:
|
case *gogithub.PushEvent:
|
||||||
target, err = autoscaler.getScaleUpTarget(
|
target, err = autoscaler.getScaleUpTarget(
|
||||||
|
|
@ -149,6 +166,9 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
e.Repo.GetName(),
|
e.Repo.GetName(),
|
||||||
e.Repo.Owner.GetLogin(),
|
e.Repo.Owner.GetLogin(),
|
||||||
e.Repo.Owner.GetType(),
|
e.Repo.Owner.GetType(),
|
||||||
|
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||||
|
// we need, so we parse it by ourselves.
|
||||||
|
enterpriseSlug,
|
||||||
autoscaler.MatchPushEvent(e),
|
autoscaler.MatchPushEvent(e),
|
||||||
)
|
)
|
||||||
case *gogithub.PullRequestEvent:
|
case *gogithub.PullRequestEvent:
|
||||||
|
|
@ -158,6 +178,9 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
e.Repo.GetName(),
|
e.Repo.GetName(),
|
||||||
e.Repo.Owner.GetLogin(),
|
e.Repo.Owner.GetLogin(),
|
||||||
e.Repo.Owner.GetType(),
|
e.Repo.Owner.GetType(),
|
||||||
|
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||||
|
// we need, so we parse it by ourselves.
|
||||||
|
enterpriseSlug,
|
||||||
autoscaler.MatchPullRequestEvent(e),
|
autoscaler.MatchPullRequestEvent(e),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -174,6 +197,9 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
e.Repo.GetName(),
|
e.Repo.GetName(),
|
||||||
e.Repo.Owner.GetLogin(),
|
e.Repo.Owner.GetLogin(),
|
||||||
e.Repo.Owner.GetType(),
|
e.Repo.Owner.GetType(),
|
||||||
|
// Most go-github Event types don't seem to contain Enteprirse(.Slug) fields
|
||||||
|
// we need, so we parse it by ourselves.
|
||||||
|
enterpriseSlug,
|
||||||
autoscaler.MatchCheckRunEvent(e),
|
autoscaler.MatchCheckRunEvent(e),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -191,6 +217,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
"repository.name", e.Repo.GetName(),
|
"repository.name", e.Repo.GetName(),
|
||||||
"repository.owner.login", e.Repo.Owner.GetLogin(),
|
"repository.owner.login", e.Repo.Owner.GetLogin(),
|
||||||
"repository.owner.type", e.Repo.Owner.GetType(),
|
"repository.owner.type", e.Repo.Owner.GetType(),
|
||||||
|
"enterprise.slug", enterpriseSlug,
|
||||||
"action", e.GetAction(),
|
"action", e.GetAction(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -205,6 +232,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) Handle(w http.Respons
|
||||||
e.Repo.GetName(),
|
e.Repo.GetName(),
|
||||||
e.Repo.Owner.GetLogin(),
|
e.Repo.Owner.GetLogin(),
|
||||||
e.Repo.Owner.GetType(),
|
e.Repo.Owner.GetType(),
|
||||||
|
enterpriseSlug,
|
||||||
labels,
|
labels,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -391,7 +419,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleTarget(ctx co
|
||||||
"Found too many scale targets: "+
|
"Found too many scale targets: "+
|
||||||
"It must be exactly one to avoid ambiguity. "+
|
"It must be exactly one to avoid ambiguity. "+
|
||||||
"Either set Namespace for the webhook-based autoscaler to let it only find HRAs in the namespace, "+
|
"Either set Namespace for the webhook-based autoscaler to let it only find HRAs in the namespace, "+
|
||||||
"or update Repository or Organization fields in your RunnerDeployment resources to fix the ambiguity.",
|
"or update Repository, Organization, or Enterprise fields in your RunnerDeployment resources to fix the ambiguity.",
|
||||||
"scaleTargets", strings.Join(scaleTargetIDs, ","))
|
"scaleTargets", strings.Join(scaleTargetIDs, ","))
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -400,7 +428,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleTarget(ctx co
|
||||||
return &targets[0], nil
|
return &targets[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleUpTarget(ctx context.Context, log logr.Logger, repo, owner, ownerType string, f func(v1alpha1.ScaleUpTrigger) bool) (*ScaleTarget, error) {
|
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleUpTarget(ctx context.Context, log logr.Logger, repo, owner, ownerType, enterprise string, f func(v1alpha1.ScaleUpTrigger) bool) (*ScaleTarget, error) {
|
||||||
repositoryRunnerKey := owner + "/" + repo
|
repositoryRunnerKey := owner + "/" + repo
|
||||||
|
|
||||||
if target, err := autoscaler.getScaleTarget(ctx, repositoryRunnerKey, f); err != nil {
|
if target, err := autoscaler.getScaleTarget(ctx, repositoryRunnerKey, f); err != nil {
|
||||||
|
|
@ -423,17 +451,37 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getScaleUpTarget(ctx
|
||||||
} else if target != nil {
|
} else if target != nil {
|
||||||
log.Info("scale up target is organizational runners", "organization", owner)
|
log.Info("scale up target is organizational runners", "organization", owner)
|
||||||
return target, nil
|
return target, nil
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if enterprise == "" {
|
||||||
log.V(1).Info("no repository runner or organizational runner found",
|
log.V(1).Info("no repository runner or organizational runner found",
|
||||||
"repository", repositoryRunnerKey,
|
"repository", repositoryRunnerKey,
|
||||||
"organization", owner,
|
"organization", owner,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if target, err := autoscaler.getScaleTarget(ctx, enterpriseKey(enterprise), f); err != nil {
|
||||||
|
log.Error(err, "finding enterprise runner", "enterprise", enterprise)
|
||||||
|
return nil, err
|
||||||
|
} else if target != nil {
|
||||||
|
log.Info("scale up target is enterprise runners", "enterprise", enterprise)
|
||||||
|
return target, nil
|
||||||
|
} else {
|
||||||
|
log.V(1).Info("no repository/organizational/enterprise runner found",
|
||||||
|
"repository", repositoryRunnerKey,
|
||||||
|
"organization", owner,
|
||||||
|
"enterprises", enterprise,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getJobScaleUpTargetForRepoOrOrg(ctx context.Context, log logr.Logger, repo, owner, ownerType string, labels []string) (*ScaleTarget, error) {
|
func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getJobScaleUpTargetForRepoOrOrg(
|
||||||
|
ctx context.Context, log logr.Logger, repo, owner, ownerType, enterprise string, labels []string,
|
||||||
|
) (*ScaleTarget, error) {
|
||||||
repositoryRunnerKey := owner + "/" + repo
|
repositoryRunnerKey := owner + "/" + repo
|
||||||
|
|
||||||
if target, err := autoscaler.getJobScaleTarget(ctx, repositoryRunnerKey, labels); err != nil {
|
if target, err := autoscaler.getJobScaleTarget(ctx, repositoryRunnerKey, labels); err != nil {
|
||||||
|
|
@ -456,11 +504,28 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) getJobScaleUpTargetFo
|
||||||
} else if target != nil {
|
} else if target != nil {
|
||||||
log.Info("job scale up target is organizational runners", "organization", owner)
|
log.Info("job scale up target is organizational runners", "organization", owner)
|
||||||
return target, nil
|
return target, nil
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if enterprise == "" {
|
||||||
log.V(1).Info("no repository runner or organizational runner found",
|
log.V(1).Info("no repository runner or organizational runner found",
|
||||||
"repository", repositoryRunnerKey,
|
"repository", repositoryRunnerKey,
|
||||||
"organization", owner,
|
"organization", owner,
|
||||||
)
|
)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if target, err := autoscaler.getJobScaleTarget(ctx, enterpriseKey(enterprise), labels); err != nil {
|
||||||
|
log.Error(err, "finding enterprise runner", "enterprise", enterprise)
|
||||||
|
return nil, err
|
||||||
|
} else if target != nil {
|
||||||
|
log.Info("scale up target is enterprise runners", "enterprise", enterprise)
|
||||||
|
return target, nil
|
||||||
|
} else {
|
||||||
|
log.V(1).Info("no repository/organizational/enterprise runner found",
|
||||||
|
"repository", repositoryRunnerKey,
|
||||||
|
"organization", owner,
|
||||||
|
"enterprises", enterprise,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -649,7 +714,13 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) SetupWithManager(mgr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{rd.Spec.Template.Spec.Repository, rd.Spec.Template.Spec.Organization}
|
keys := []string{rd.Spec.Template.Spec.Repository, rd.Spec.Template.Spec.Organization}
|
||||||
|
|
||||||
|
if enterprise := rd.Spec.Template.Spec.Enterprise; enterprise != "" {
|
||||||
|
keys = append(keys, enterpriseKey(enterprise))
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys
|
||||||
case "RunnerSet":
|
case "RunnerSet":
|
||||||
var rs v1alpha1.RunnerSet
|
var rs v1alpha1.RunnerSet
|
||||||
|
|
||||||
|
|
@ -657,7 +728,13 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) SetupWithManager(mgr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{rs.Spec.Repository, rs.Spec.Organization}
|
keys := []string{rs.Spec.Repository, rs.Spec.Organization}
|
||||||
|
|
||||||
|
if enterprise := rs.Spec.Enterprise; enterprise != "" {
|
||||||
|
keys = append(keys, enterpriseKey(enterprise))
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -670,3 +747,7 @@ func (autoscaler *HorizontalRunnerAutoscalerGitHubWebhook) SetupWithManager(mgr
|
||||||
Named(name).
|
Named(name).
|
||||||
Complete(autoscaler)
|
Complete(autoscaler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enterpriseKey(name string) string {
|
||||||
|
return keyPrefixEnterprise + name
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ var (
|
||||||
// This tests ues testing.Logf extensively for debugging purpose.
|
// This tests ues testing.Logf extensively for debugging purpose.
|
||||||
// But messages logged via Logf shows up only when the test failed by default.
|
// But messages logged via Logf shows up only when the test failed by default.
|
||||||
// To always enable logging, do not forget to pass `-test.v` to `go test`.
|
// To always enable logging, do not forget to pass `-test.v` to `go test`.
|
||||||
// If you're using VS Code, open `Workspace Settings` and search for `go test flags`, edit the `settings.json` and put the below:
|
// If you're using VS Code, open `Workspace Settings` and search for `go test flags`, edit the `.vscode/settings.json` and put the below:
|
||||||
// "go.testFlags": ["-v"]
|
// "go.testFlags": ["-v"]
|
||||||
//
|
//
|
||||||
// This function requires a few environment variables to be set to provide some test data.
|
// This function requires a few environment variables to be set to provide some test data.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue