-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new forgejo scaler #6495
base: main
Are you sure you want to change the base?
new forgejo scaler #6495
Conversation
03fd3a1
to
39fd60d
Compare
39fd60d
to
a7366bc
Compare
Signed-off-by: jaime Merino <[email protected]>
Signed-off-by: jaime merino <[email protected]ª>
5b9d520
to
f13dbc7
Compare
Signed-off-by: jaime merino <[email protected]ª>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your contribution! I've left some comment inline. Additionally to them:
- Please, add an e2e test covering the scaler. You get more info about how to do it here
- Could you open a PR to docs adding the scaler in next version?
- All commits must be signed and that's why DCO check is failing, please rebase your branch signing all the commits (how to do that it's explained in the check page)
@@ -0,0 +1,43 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is just a type definition file, I think that it's better if it's merged with the scaler code. We create packages when there is complex logic or specialized helpers, but just to define some structs, we prefer to keep all together
orgJobMetricPath = "/api/v1/orgs/%s/actions/runners/jobs" // /api/v1/orgs/{org}/actions/runners/jobs | ||
repoJobMetricPath = "/api/v1/repos/%s/%s/actions/runners/jobs" // {address}/api/v1/repos/{owner}/{repo}/actions/runners/jobs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
orgJobMetricPath = "/api/v1/orgs/%s/actions/runners/jobs" // /api/v1/orgs/{org}/actions/runners/jobs | |
repoJobMetricPath = "/api/v1/repos/%s/%s/actions/runners/jobs" // {address}/api/v1/repos/{owner}/{repo}/actions/runners/jobs | |
orgJobMetricPath = "/api/v1/orgs/%s/actions/runners/jobs" | |
repoJobMetricPath = "/api/v1/repos/%s/%s/actions/runners/jobs" |
func parseForgejoRunnerMetadata(config *scalersconfig.ScalerConfig) (*ForgejoRunnerConfig, error) { | ||
meta := &ForgejoRunnerConfig{} | ||
|
||
if val, ok := config.TriggerMetadata["token"]; ok && val != "" { | ||
meta.RunnerMeta.Token = val | ||
} else { | ||
return nil, fmt.Errorf("no token given") | ||
} | ||
|
||
if val, ok := config.TriggerMetadata["address"]; ok && val != "" { | ||
meta.RunnerMeta.Address = val | ||
} else { | ||
return nil, fmt.Errorf("no address given") | ||
} | ||
|
||
if val, ok := config.TriggerMetadata["labels"]; ok && val != "" { | ||
meta.RunnerMeta.Labels = val | ||
} else { | ||
return nil, fmt.Errorf("no labels given") | ||
} | ||
|
||
global := false | ||
if val, ok := config.TriggerMetadata["global"]; ok && val == stringTrue { | ||
global = true | ||
} | ||
|
||
meta.RunnerMeta.Global = global | ||
|
||
return meta, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, use the new declarative way to define the scaler metadata. We are moving all the scalers to there to build tools around the approach.
You can see an example with other scalers like https://github.com/kedacore/keda/pull/5818/files
externalMetric := &v2.ExternalMetricSource{ | ||
Metric: v2.MetricIdentifier{ | ||
Name: GenerateMetricNameWithIndex( | ||
1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value is provided via config.TriggerIndex
during the scaler building process, please propagate it until here as it's required to ensure that each scaler has a unique name within the ScaledObject|Job
Metric: v2.MetricIdentifier{ | ||
Name: GenerateMetricNameWithIndex( | ||
1, | ||
kedautil.NormalizeString(fmt.Sprintf("forgejo-runner-%s", s.metadata.RunnerMeta.Address)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be used as metric name, so we must ensure that it's a sanitized string (it'll be sent via url). What about just using "forgejo-runner"
or concated labels?
adminJobMetricPath = "/api/v1/admin/runners/jobs" | ||
orgJobMetricPath = "/api/v1/orgs/%s/actions/runners/jobs" // /api/v1/orgs/{org}/actions/runners/jobs | ||
repoJobMetricPath = "/api/v1/repos/%s/%s/actions/runners/jobs" // {address}/api/v1/repos/{owner}/{repo}/actions/runners/jobs | ||
UserJobMetricPath = "/api/v1/user/actions/runners/jobs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserJobMetricPath = "/api/v1/user/actions/runners/jobs" | |
userJobMetricPath = "/api/v1/user/actions/runners/jobs" |
|
||
metric := GenerateMetricInMili(metricName, float64(len(jobList.Jobs))) | ||
|
||
metric.Value.Add(resource.Quantity{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this? I'd say that it's required because GenerateMetricInMili
returns a formatted metric
err = json.Unmarshal(b, &jobList) | ||
return jobList, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea about fogejo API, does it only return pending jobs, or it also returns active/completed jobs somehow? My question is related with the point about if we need to filter the jobs somehow, or just counting them is enough.
@@ -0,0 +1,266 @@ | |||
package scalers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use Pascal case for test naming to be consistent with other test cases
{"no address given", map[string]string{ | ||
"token": "some-token", "name": "some-name", "labels": "some-label", "metric_path": "path", | ||
}, true, "no address given", false}, | ||
{"no token given", map[string]string{ | ||
"address": "https://api.github.com", "name": "some-name", "labels": "some-label", "metric_path": "path", | ||
}, true, "no token given", false}, | ||
{"no label given", map[string]string{ | ||
"address": "https://api.github.com", "token": "some-token", "name": "some-name", "metric_path": "path", | ||
}, true, "no labels given", false}, | ||
{"no name given use default", map[string]string{ | ||
"address": "https://api.github.com", "token": "some-token", "labels": "some-label", "metric_path": "path", | ||
}, false, "", false}, | ||
{"no metric path given use default", map[string]string{ | ||
"address": "https://api.github.com", "token": "some-token", "name": "some-name", "labels": "some-label", | ||
}, false, "", false}, | ||
// properly formed | ||
{"properly formed", map[string]string{ | ||
"address": "https://api.github.com", | ||
"token": "some-token", | ||
"name": "some-name", | ||
"labels": "some-labels", | ||
"metric_path": "path", | ||
}, false, "", false}, | ||
{"properly formed with global", map[string]string{ | ||
"address": "https://api.github.com", | ||
"token": "some-token", | ||
"name": "some-name", | ||
"labels": "some-labels", | ||
"global": "true", | ||
"metric_path": "path", | ||
}, false, "", true}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that the url isn't relevant for this test case but let's use other unrelated with GitHub to avoid misunderstandings or confusions with GitHub scaler
{"no address given", map[string]string{ | |
"token": "some-token", "name": "some-name", "labels": "some-label", "metric_path": "path", | |
}, true, "no address given", false}, | |
{"no token given", map[string]string{ | |
"address": "https://api.github.com", "name": "some-name", "labels": "some-label", "metric_path": "path", | |
}, true, "no token given", false}, | |
{"no label given", map[string]string{ | |
"address": "https://api.github.com", "token": "some-token", "name": "some-name", "metric_path": "path", | |
}, true, "no labels given", false}, | |
{"no name given use default", map[string]string{ | |
"address": "https://api.github.com", "token": "some-token", "labels": "some-label", "metric_path": "path", | |
}, false, "", false}, | |
{"no metric path given use default", map[string]string{ | |
"address": "https://api.github.com", "token": "some-token", "name": "some-name", "labels": "some-label", | |
}, false, "", false}, | |
// properly formed | |
{"properly formed", map[string]string{ | |
"address": "https://api.github.com", | |
"token": "some-token", | |
"name": "some-name", | |
"labels": "some-labels", | |
"metric_path": "path", | |
}, false, "", false}, | |
{"properly formed with global", map[string]string{ | |
"address": "https://api.github.com", | |
"token": "some-token", | |
"name": "some-name", | |
"labels": "some-labels", | |
"global": "true", | |
"metric_path": "path", | |
}, false, "", true}, | |
} | |
{"no address given", map[string]string{ | |
"token": "some-token", "name": "some-name", "labels": "some-label", "metric_path": "path", | |
}, true, "no address given", false}, | |
{"no token given", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", "name": "some-name", "labels": "some-label", "metric_path": "path", | |
}, true, "no token given", false}, | |
{"no label given", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", "token": "some-token", "name": "some-name", "metric_path": "path", | |
}, true, "no labels given", false}, | |
{"no name given use default", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", "token": "some-token", "labels": "some-label", "metric_path": "path", | |
}, false, "", false}, | |
{"no metric path given use default", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", "token": "some-token", "name": "some-name", "labels": "some-label", | |
}, false, "", false}, | |
// properly formed | |
{"properly formed", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", | |
"token": "some-token", | |
"name": "some-name", | |
"labels": "some-labels", | |
"metric_path": "path", | |
}, false, "", false}, | |
{"properly formed with global", map[string]string{ | |
"address": "https://api.myforgejoinstance.com", | |
"token": "some-token", | |
"name": "some-name", | |
"labels": "some-labels", | |
"global": "true", | |
"metric_path": "path", | |
}, false, "", true}, | |
} |
This PR adds a new forgejo autoscaler with the same characteristics of the github autoscaler.
Here is the issue for this feature #6488
Another important discussions on this topic:
Checklist