This change updates all dependencies. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
188 lines
5.8 KiB
Go
188 lines
5.8 KiB
Go
// Copyright 2025 Cloudbase Solutions SRL
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"github.com/google/go-github/v72/github"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
var (
|
|
orgName = os.Getenv("ORG_NAME")
|
|
repoName = os.Getenv("REPO_NAME")
|
|
|
|
ghToken = os.Getenv("GH_TOKEN")
|
|
)
|
|
|
|
func main() {
|
|
controllerID, ctrlIDFound := os.LookupEnv("GARM_CONTROLLER_ID")
|
|
if ctrlIDFound {
|
|
_ = GhOrgRunnersCleanup(ghToken, orgName, controllerID)
|
|
_ = GhRepoRunnersCleanup(ghToken, orgName, repoName, controllerID)
|
|
} else {
|
|
slog.Warn("Env variable GARM_CONTROLLER_ID is not set, skipping GitHub runners cleanup")
|
|
}
|
|
|
|
baseURL, baseURLFound := os.LookupEnv("GARM_BASE_URL")
|
|
if ctrlIDFound && baseURLFound {
|
|
webhookURL := fmt.Sprintf("%s/webhooks/%s", baseURL, controllerID)
|
|
_ = GhOrgWebhookCleanup(ghToken, webhookURL, orgName)
|
|
_ = GhRepoWebhookCleanup(ghToken, webhookURL, orgName, repoName)
|
|
} else {
|
|
slog.Warn("Env variables GARM_CONTROLLER_ID & GARM_BASE_URL are not set, skipping webhooks cleanup")
|
|
}
|
|
}
|
|
|
|
func GhOrgRunnersCleanup(ghToken, orgName, controllerID string) error {
|
|
slog.Info("Cleanup Github runners", "controller_id", controllerID, "org_name", orgName)
|
|
|
|
client := getGithubClient(ghToken)
|
|
ghOrgRunners, _, err := client.Actions.ListOrganizationRunners(context.Background(), orgName, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Remove organization runners
|
|
controllerLabel := fmt.Sprintf("runner-controller-id:%s", controllerID)
|
|
for _, orgRunner := range ghOrgRunners.Runners {
|
|
for _, label := range orgRunner.Labels {
|
|
if label.GetName() == controllerLabel {
|
|
if _, err := client.Actions.RemoveOrganizationRunner(context.Background(), orgName, orgRunner.GetID()); err != nil {
|
|
// We don't fail if we can't remove a single runner. This
|
|
// is a best effort to try and remove all the orphan runners.
|
|
slog.With(slog.Any("error", err)).Info("Failed to remove organization runner", "org_runner", orgRunner.GetName())
|
|
break
|
|
}
|
|
slog.Info("Removed organization runner", "org_runner", orgRunner.GetName())
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GhRepoRunnersCleanup(ghToken, orgName, repoName, controllerID string) error {
|
|
slog.Info("Cleanup Github runners", "controller_id", controllerID, "org_name", orgName, "repo_name", repoName)
|
|
|
|
client := getGithubClient(ghToken)
|
|
ghRepoRunners, _, err := client.Actions.ListRunners(context.Background(), orgName, repoName, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Remove repository runners
|
|
controllerLabel := fmt.Sprintf("runner-controller-id:%s", controllerID)
|
|
for _, repoRunner := range ghRepoRunners.Runners {
|
|
for _, label := range repoRunner.Labels {
|
|
if label.GetName() == controllerLabel {
|
|
if _, err := client.Actions.RemoveRunner(context.Background(), orgName, repoName, repoRunner.GetID()); err != nil {
|
|
// We don't fail if we can't remove a single runner. This
|
|
// is a best effort to try and remove all the orphan runners.
|
|
slog.With(slog.Any("error", err)).Error("Failed to remove repository runner", "runner_name", repoRunner.GetName())
|
|
break
|
|
}
|
|
slog.Info("Removed repository runner", "runner_name", repoRunner.GetName())
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GhOrgWebhookCleanup(ghToken, webhookURL, orgName string) error {
|
|
slog.Info("Cleanup Github webhook", "webhook_url", webhookURL, "org_name", orgName)
|
|
hook, err := getGhOrgWebhook(webhookURL, ghToken, orgName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Remove organization webhook
|
|
if hook != nil {
|
|
client := getGithubClient(ghToken)
|
|
if _, err := client.Organizations.DeleteHook(context.Background(), orgName, hook.GetID()); err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Github webhook removed", "webhook_url", webhookURL, "org_name", orgName)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GhRepoWebhookCleanup(ghToken, webhookURL, orgName, repoName string) error {
|
|
slog.Info("Cleanup Github webhook", "webhook_url", webhookURL, "org_name", orgName, "repo_name", repoName)
|
|
|
|
hook, err := getGhRepoWebhook(webhookURL, ghToken, orgName, repoName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Remove repository webhook
|
|
if hook != nil {
|
|
client := getGithubClient(ghToken)
|
|
if _, err := client.Repositories.DeleteHook(context.Background(), orgName, repoName, hook.GetID()); err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Github webhook with", "webhook_url", webhookURL, "org_name", orgName, "repo_name", repoName)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getGhOrgWebhook(url, ghToken, orgName string) (*github.Hook, error) {
|
|
client := getGithubClient(ghToken)
|
|
ghOrgHooks, _, err := client.Organizations.ListHooks(context.Background(), orgName, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, hook := range ghOrgHooks {
|
|
hookURL := hook.Config.GetURL()
|
|
if hookURL == url {
|
|
return hook, nil
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func getGhRepoWebhook(url, ghToken, orgName, repoName string) (*github.Hook, error) {
|
|
client := getGithubClient(ghToken)
|
|
ghRepoHooks, _, err := client.Repositories.ListHooks(context.Background(), orgName, repoName, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, hook := range ghRepoHooks {
|
|
hookURL := hook.Config.GetURL()
|
|
if hookURL == url {
|
|
return hook, nil
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func getGithubClient(oauthToken string) *github.Client {
|
|
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: oauthToken})
|
|
tc := oauth2.NewClient(context.Background(), ts)
|
|
return github.NewClient(tc)
|
|
}
|