Skip to content

Commit

Permalink
Merge pull request #175 from mihaelabalutoiu/add-cleanup-webhooks
Browse files Browse the repository at this point in the history
Cleaning up leftover Github webhooks for `org/repo`
  • Loading branch information
gabriel-samfira authored Aug 29, 2023
2 parents 0da5f10 + f9c3f30 commit b1dd54c
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 15 deletions.
12 changes: 12 additions & 0 deletions test/integration/e2e/client_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ func getRepoWebhook(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoW
return &getRepoWebhookResponse.Payload, nil
}

func uninstallRepoWebhook(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) error {
return apiCli.Repositories.UninstallRepoWebhook(
clientRepositories.NewUninstallRepoWebhookParams().WithRepoID(repoID),
apiAuthToken)
}

func createRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string, poolParams params.CreatePoolParams) (*params.Pool, error) {
createRepoPoolResponse, err := apiCli.Repositories.CreateRepoPool(
clientRepositories.NewCreateRepoPoolParams().WithRepoID(repoID).WithBody(poolParams),
Expand Down Expand Up @@ -290,6 +296,12 @@ func getOrgWebhook(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWr
return &getOrgWebhookResponse.Payload, nil
}

func uninstallOrgWebhook(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) error {
return apiCli.Organizations.UninstallOrgWebhook(
clientOrganizations.NewUninstallOrgWebhookParams().WithOrgID(orgID),
apiAuthToken)
}

func createOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string, poolParams params.CreatePoolParams) (*params.Pool, error) {
createOrgPoolResponse, err := apiCli.Organizations.CreateOrgPool(
clientOrganizations.NewCreateOrgPoolParams().WithOrgID(orgID).WithBody(poolParams),
Expand Down
113 changes: 113 additions & 0 deletions test/integration/e2e/github_client_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,119 @@ func GhRepoRunnersCleanup(ghToken, orgName, repoName, controllerID string) error
return nil
}

func ValidateOrgWebhookInstalled(ghToken, url, orgName string) {
hook, err := getGhOrgWebhook(url, ghToken, orgName)
if err != nil {
panic(err)
}
if hook == nil {
panic(fmt.Errorf("github webhook with url %s, for org %s was not properly installed", url, orgName))
}
}

func ValidateOrgWebhookUninstalled(ghToken, url, orgName string) {
hook, err := getGhOrgWebhook(url, ghToken, orgName)
if err != nil {
panic(err)
}
if hook != nil {
panic(fmt.Errorf("github webhook with url %s, for org %s was not properly uninstalled", url, orgName))
}
}

func ValidateRepoWebhookInstalled(ghToken, url, orgName, repoName string) {
hook, err := getGhRepoWebhook(url, ghToken, orgName, repoName)
if err != nil {
panic(err)
}
if hook == nil {
panic(fmt.Errorf("github webhook with url %s, for repo %s/%s was not properly installed", url, orgName, repoName))
}
}

func ValidateRepoWebhookUninstalled(ghToken, url, orgName, repoName string) {
hook, err := getGhRepoWebhook(url, ghToken, orgName, repoName)
if err != nil {
panic(err)
}
if hook != nil {
panic(fmt.Errorf("github webhook with url %s, for repo %s/%s was not properly uninstalled", url, orgName, repoName))
}
}

func GhOrgWebhookCleanup(ghToken, webhookURL, orgName string) error {
log.Printf("Cleanup Github webhook with url %s for org %s", webhookURL, 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
}
log.Printf("Github webhook with url %s for org %s was removed", webhookURL, orgName)
}

return nil
}

func GhRepoWebhookCleanup(ghToken, webhookURL, orgName, repoName string) error {
log.Printf("Cleanup Github webhook with url %s for repo %s/%s", webhookURL, orgName, 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
}
log.Printf("Github webhook with url %s for repo %s/%s was removed", webhookURL, orgName, 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, ok := hook.Config["url"].(string)
if ok && 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, ok := hook.Config["url"].(string)
if ok && 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)
Expand Down
7 changes: 7 additions & 0 deletions test/integration/e2e/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ func InstallOrgWebhook(id string) *params.HookInfo {
return webhookInfo
}

func UninstallOrgWebhook(id string) {
log.Printf("Uninstall org %s webhook", id)
if err := uninstallOrgWebhook(cli, authToken, id); err != nil {
panic(err)
}
}

func CreateOrgPool(orgID string, poolParams params.CreatePoolParams) *params.Pool {
log.Printf("Create org %s pool", orgID)
pool, err := createOrgPool(cli, authToken, orgID, poolParams)
Expand Down
7 changes: 7 additions & 0 deletions test/integration/e2e/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ func InstallRepoWebhook(id string) *params.HookInfo {
return webhookInfo
}

func UninstallRepoWebhook(id string) {
log.Printf("Uninstall repo %s webhook", id)
if err := uninstallRepoWebhook(cli, authToken, id); err != nil {
panic(err)
}
}

func CreateRepoPool(repoID string, poolParams params.CreatePoolParams) *params.Pool {
log.Printf("Create repo %s pool", repoID)
pool, err := createRepoPool(cli, authToken, repoID, poolParams)
Expand Down
7 changes: 4 additions & 3 deletions test/integration/gh_cleanup/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"log"
"os"

Expand All @@ -25,9 +26,9 @@ func main() {

baseURL, baseUrlFound := os.LookupEnv("GARM_BASE_URL")
if ctrlIdFound && baseUrlFound {
log.Printf("TODO: Cleanup org & repo webhooks staring with: %s/webhooks/%s", baseURL, controllerID)
// TODO: Cleanup org webhooks that start with "{baseURL}/webhooks/{controllerID}"
// TODO: Cleanup repo webhooks that start with "{baseURL}/webhooks/{controllerID}"
webhookURL := fmt.Sprintf("%s/webhooks/%s", baseURL, controllerID)
_ = e2e.GhOrgWebhookCleanup(ghToken, webhookURL, orgName)
_ = e2e.GhRepoWebhookCleanup(ghToken, webhookURL, orgName, repoName)
} else {
log.Println("Env variables GARM_CONTROLLER_ID & GARM_BASE_URL are not set, skipping webhooks cleanup")
}
Expand Down
24 changes: 12 additions & 12 deletions test/integration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ func main() {
//////////////////
repo := e2e.CreateRepo(orgName, repoName, credentialsName, repoWebhookSecret)
repo = e2e.UpdateRepo(repo.ID, fmt.Sprintf("%s-clone", credentialsName))
e2e.InstallRepoWebhook(repo.ID)
// TODO:
// * Check that the webhook is properly installed in GitHub.
// * Uninstall webhook
// * Check that webhook is properly removed from GitHub.
// * Install webhook again.
hookRepoInfo := e2e.InstallRepoWebhook(repo.ID)
e2e.ValidateRepoWebhookInstalled(ghToken, hookRepoInfo.URL, orgName, repoName)
e2e.UninstallRepoWebhook(repo.ID)
e2e.ValidateRepoWebhookUninstalled(ghToken, hookRepoInfo.URL, orgName, repoName)
_ = e2e.InstallRepoWebhook(repo.ID)
e2e.ValidateRepoWebhookInstalled(ghToken, hookRepoInfo.URL, orgName, repoName)

repoPool := e2e.CreateRepoPool(repo.ID, repoPoolParams)
repoPool = e2e.GetRepoPool(repo.ID, repoPool.ID)
Expand All @@ -106,12 +106,12 @@ func main() {
///////////////////
org := e2e.CreateOrg(orgName, credentialsName, orgWebhookSecret)
org = e2e.UpdateOrg(org.ID, fmt.Sprintf("%s-clone", credentialsName))
e2e.InstallOrgWebhook(org.ID)
// TODO:
// * Check that the webhook is properly installed in GitHub.
// * Uninstall webhook
// * Check that webhook is properly removed from GitHub.
// * Install webhook again.
orgHookInfo := e2e.InstallOrgWebhook(org.ID)
e2e.ValidateOrgWebhookInstalled(ghToken, orgHookInfo.URL, orgName)
e2e.UninstallOrgWebhook(org.ID)
e2e.ValidateOrgWebhookUninstalled(ghToken, orgHookInfo.URL, orgName)
_ = e2e.InstallOrgWebhook(org.ID)
e2e.ValidateOrgWebhookInstalled(ghToken, orgHookInfo.URL, orgName)

orgPool := e2e.CreateOrgPool(org.ID, orgPoolParams)
orgPool = e2e.GetOrgPool(org.ID, orgPool.ID)
Expand Down

0 comments on commit b1dd54c

Please sign in to comment.