Skip to content
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

Pull out ArgoCD options setup into main #45

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion cmd/telefonistka/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package telefonistka

import (
"os"
"strconv"

"github.com/argoproj/argo-cd/v2/pkg/apiclient"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/spf13/cobra"
"github.com/wayfair-incubator/telefonistka/internal/pkg/githubapi"
Expand All @@ -29,7 +31,17 @@ func init() { //nolint:gochecknoinits
func event(eventType string, eventFilePath string) {
mainGhClientCache, _ := lru.New[string, githubapi.GhClientPair](128)
prApproverGhClientCache, _ := lru.New[string, githubapi.GhClientPair](128)
githubapi.ReciveEventFile(eventFilePath, eventType, mainGhClientCache, prApproverGhClientCache)
plaintext, _ := strconv.ParseBool(getEnv("ARGOCD_PLAINTEXT", "false"))
insecure, _ := strconv.ParseBool(getEnv("ARGOCD_INSECURE", "false"))
serverAddr := getEnv("ARGOCD_SERVER_ADDR", "localhost:8080")
token := getEnv("ARGOCD_TOKEN", "")
argoOpts := apiclient.ClientOptions{
ServerAddr: serverAddr,
AuthToken: token,
PlainText: plaintext,
Insecure: insecure,
}
githubapi.ReciveEventFile(eventFilePath, eventType, mainGhClientCache, prApproverGhClientCache, &argoOpts)
}

func getEnv(key, fallback string) string {
Expand Down
18 changes: 15 additions & 3 deletions cmd/telefonistka/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package telefonistka
import (
"net/http"
"os"
"strconv"
"time"

"github.com/alexliesenfeld/health"
"github.com/argoproj/argo-cd/v2/pkg/apiclient"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -36,9 +38,9 @@ func init() { //nolint:gochecknoinits
rootCmd.AddCommand(serveCmd)
}

func handleWebhook(githubWebhookSecret []byte, mainGhClientCache *lru.Cache[string, githubapi.GhClientPair], prApproverGhClientCache *lru.Cache[string, githubapi.GhClientPair]) func(http.ResponseWriter, *http.Request) {
func handleWebhook(githubWebhookSecret []byte, mainGhClientCache *lru.Cache[string, githubapi.GhClientPair], prApproverGhClientCache *lru.Cache[string, githubapi.GhClientPair], argoOpts *apiclient.ClientOptions) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
err := githubapi.ReciveWebhook(r, mainGhClientCache, prApproverGhClientCache, githubWebhookSecret)
err := githubapi.ReciveWebhook(r, mainGhClientCache, prApproverGhClientCache, githubWebhookSecret, argoOpts)
if err != nil {
log.Errorf("error handling webhook: %v", err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
Expand All @@ -49,6 +51,16 @@ func handleWebhook(githubWebhookSecret []byte, mainGhClientCache *lru.Cache[stri
}

func serve() {
plaintext, _ := strconv.ParseBool(getEnv("ARGOCD_PLAINTEXT", "false"))
insecure, _ := strconv.ParseBool(getEnv("ARGOCD_INSECURE", "false"))
serverAddr := getEnv("ARGOCD_SERVER_ADDR", "localhost:8080")
token := getEnv("ARGOCD_TOKEN", "")
argoOpts := apiclient.ClientOptions{
ServerAddr: serverAddr,
AuthToken: token,
PlainText: plaintext,
Insecure: insecure,
}
githubWebhookSecret := []byte(getCrucialEnv("GITHUB_WEBHOOK_SECRET"))
livenessChecker := health.NewChecker() // No checks for the moment, other then the http server availability
readinessChecker := health.NewChecker()
Expand All @@ -60,7 +72,7 @@ func serve() {
go githubapi.MainGhMetricsLoop(mainGhClientCache)

mux := http.NewServeMux()
mux.HandleFunc("/webhook", handleWebhook(githubWebhookSecret, mainGhClientCache, prApproverGhClientCache))
mux.HandleFunc("/webhook", handleWebhook(githubWebhookSecret, mainGhClientCache, prApproverGhClientCache, &argoOpts))
mux.Handle("/metrics", promhttp.Handler())
mux.Handle("/live", health.NewHandler(livenessChecker))
mux.Handle("/ready", health.NewHandler(readinessChecker))
Expand Down
25 changes: 3 additions & 22 deletions internal/pkg/argocd/argocd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -165,24 +163,7 @@ func diffLiveVsTargetObject(live, target *unstructured.Unstructured) (string, er
return string(patch), nil
}

func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}

func CreateArgoCdClients() (ac argoCdClients, err error) {
plaintext, _ := strconv.ParseBool(getEnv("ARGOCD_PLAINTEXT", "false"))
insecure, _ := strconv.ParseBool(getEnv("ARGOCD_INSECURE", "false"))

opts := &apiclient.ClientOptions{
ServerAddr: getEnv("ARGOCD_SERVER_ADDR", "localhost:8080"),
AuthToken: getEnv("ARGOCD_TOKEN", ""),
PlainText: plaintext,
Insecure: insecure,
}

func CreateArgoCdClients(opts *apiclient.ClientOptions) (ac argoCdClients, err error) {
client, err := apiclient.NewClient(opts)
if err != nil {
return ac, fmt.Errorf("Error creating ArgoCD API client: %w", err)
Expand Down Expand Up @@ -317,10 +298,10 @@ func findArgocdApp(ctx context.Context, componentPath string, repo string, appCl
return f(ctx, componentPath, repo, appClient)
}

func SetArgoCDAppRevision(ctx context.Context, componentPath string, revision string, repo string, useSHALabelForArgoDicovery bool) error {
func SetArgoCDAppRevision(ctx context.Context, componentPath string, revision string, repo string, useSHALabelForArgoDicovery bool, opts *apiclient.ClientOptions) error {
var foundApp *argoappv1.Application
var err error
ac, err := CreateArgoCdClients()
ac, err := CreateArgoCdClients(opts)
if err != nil {
return fmt.Errorf("Error creating ArgoCD clients: %w", err)
}
Expand Down
34 changes: 18 additions & 16 deletions internal/pkg/githubapi/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"text/template"
"time"

"github.com/argoproj/argo-cd/v2/pkg/apiclient"
"github.com/cenkalti/backoff/v4"
"github.com/google/go-github/v62/github"
lru "github.com/hashicorp/golang-lru/v2"
Expand Down Expand Up @@ -124,7 +125,7 @@ func shouldSyncBranchCheckBoxBeDisplayed(componentPathList []string, allowSyncfr
return false
}

func HandlePREvent(eventPayload *github.PullRequestEvent, ghPrClientDetails GhPrClientDetails, mainGithubClientPair GhClientPair, approverGithubClientPair GhClientPair, ctx context.Context) {
func HandlePREvent(eventPayload *github.PullRequestEvent, ghPrClientDetails GhPrClientDetails, mainGithubClientPair GhClientPair, approverGithubClientPair GhClientPair, ctx context.Context, argoOpts *apiclient.ClientOptions) {
defer func() {
if r := recover(); r != nil {
ghPrClientDetails.PrLogger.Errorf("Recovered: %v", r)
Expand Down Expand Up @@ -153,9 +154,9 @@ func HandlePREvent(eventPayload *github.PullRequestEvent, ghPrClientDetails GhPr

switch stat {
case "merged":
err = handleMergedPrEvent(ghPrClientDetails, approverGithubClientPair.v3Client)
err = handleMergedPrEvent(ghPrClientDetails, approverGithubClientPair.v3Client, argoOpts)
case "changed":
err = handleChangedPREvent(ctx, mainGithubClientPair, ghPrClientDetails, eventPayload)
err = handleChangedPREvent(ctx, mainGithubClientPair, ghPrClientDetails, eventPayload, argoOpts)
case "show-plan":
err = handleShowPlanPREvent(ctx, ghPrClientDetails, eventPayload)
}
Expand Down Expand Up @@ -193,7 +194,7 @@ func handleShowPlanPREvent(ctx context.Context, ghPrClientDetails GhPrClientDeta
return nil
}

func handleChangedPREvent(ctx context.Context, mainGithubClientPair GhClientPair, ghPrClientDetails GhPrClientDetails, eventPayload *github.PullRequestEvent) error {
func handleChangedPREvent(ctx context.Context, mainGithubClientPair GhClientPair, ghPrClientDetails GhPrClientDetails, eventPayload *github.PullRequestEvent, argoOpts *apiclient.ClientOptions) error {
botIdentity, _ := GetBotGhIdentity(mainGithubClientPair.v4Client, ctx)
err := MimizeStalePrComments(ghPrClientDetails, mainGithubClientPair.v4Client, botIdentity)
if err != nil {
Expand Down Expand Up @@ -224,7 +225,8 @@ func handleChangedPREvent(ctx context.Context, mainGithubClientPair GhClientPair
ghPrClientDetails.PrLogger.Debugf("ArgoCD diff disabled for %s\n", componentPath)
}
}
argoClients, err := argocd.CreateArgoCdClients()

argoClients, err := argocd.CreateArgoCdClients(argoOpts)
if err != nil {
return fmt.Errorf("error creating ArgoCD clients: %w", err)
}
Expand Down Expand Up @@ -326,7 +328,7 @@ func generateArgoCdDiffComments(diffCommentData DiffCommentData, githubCommentMa
}

// ReciveEventFile this one is similar to ReciveWebhook but it's used for CLI triggering, i simulates a webhook event to use the same code path as the webhook handler.
func ReciveEventFile(eventType string, eventFilePath string, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair]) {
func ReciveEventFile(eventType string, eventFilePath string, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair], argoOpts *apiclient.ClientOptions) {
log.Infof("Event type: %s", eventType)
log.Infof("Proccesing file: %s", eventFilePath)

Expand All @@ -345,11 +347,11 @@ func ReciveEventFile(eventType string, eventFilePath string, mainGhClientCache *
r.Header.Set("Content-Type", "application/json")
r.Header.Set("X-GitHub-Event", eventType)

handleEvent(eventPayloadInterface, mainGhClientCache, prApproverGhClientCache, r, payload)
handleEvent(eventPayloadInterface, mainGhClientCache, prApproverGhClientCache, r, payload, argoOpts)
}

// ReciveWebhook is the main entry point for the webhook handling it starts parases the webhook payload and start a thread to handle the event success/failure are dependant on the payload parsing only
func ReciveWebhook(r *http.Request, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair], githubWebhookSecret []byte) error {
func ReciveWebhook(r *http.Request, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair], githubWebhookSecret []byte, argoOpts *apiclient.ClientOptions) error {
payload, err := github.ValidatePayload(r, githubWebhookSecret)
if err != nil {
log.Errorf("error reading request body: err=%s\n", err)
Expand All @@ -366,11 +368,11 @@ func ReciveWebhook(r *http.Request, mainGhClientCache *lru.Cache[string, GhClien
}
prom.InstrumentWebhookHit("successful")

go handleEvent(eventPayloadInterface, mainGhClientCache, prApproverGhClientCache, r, payload)
go handleEvent(eventPayloadInterface, mainGhClientCache, prApproverGhClientCache, r, payload, argoOpts)
return nil
}

func handleEvent(eventPayloadInterface interface{}, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair], r *http.Request, payload []byte) {
func handleEvent(eventPayloadInterface interface{}, mainGhClientCache *lru.Cache[string, GhClientPair], prApproverGhClientCache *lru.Cache[string, GhClientPair], r *http.Request, payload []byte, argoOpts *apiclient.ClientOptions) {
// We don't use the request context as it might have a short deadline and we don't want to stop event handling based on that
// But we do want to stop the event handling after a certain point, so:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
Expand Down Expand Up @@ -428,7 +430,7 @@ func handleEvent(eventPayloadInterface interface{}, mainGhClientCache *lru.Cache
PrSHA: *eventPayload.PullRequest.Head.SHA,
}

HandlePREvent(eventPayload, ghPrClientDetails, mainGithubClientPair, approverGithubClientPair, ctx)
HandlePREvent(eventPayload, ghPrClientDetails, mainGithubClientPair, approverGithubClientPair, ctx, argoOpts)

case *github.IssueCommentEvent:
repoOwner := *eventPayload.Repo.Owner.Login
Expand All @@ -452,7 +454,7 @@ func handleEvent(eventPayloadInterface interface{}, mainGhClientCache *lru.Cache
PrAuthor: *eventPayload.Issue.User.Login,
PrLogger: prLogger,
}
_ = handleCommentPrEvent(ghPrClientDetails, eventPayload, botIdentity)
_ = handleCommentPrEvent(ghPrClientDetails, eventPayload, botIdentity, argoOpts)
} else {
log.Debug("Ignoring self comment")
}
Expand Down Expand Up @@ -493,7 +495,7 @@ func isSyncFromBranchAllowedForThisPath(allowedPathRegex string, path string) bo
return allowedPathsRegex.MatchString(path)
}

func handleCommentPrEvent(ghPrClientDetails GhPrClientDetails, ce *github.IssueCommentEvent, botIdentity string) error {
func handleCommentPrEvent(ghPrClientDetails GhPrClientDetails, ce *github.IssueCommentEvent, botIdentity string, argoOpts *apiclient.ClientOptions) error {
defaultBranch, _ := ghPrClientDetails.GetDefaultBranch()
config, err := GetInRepoConfig(ghPrClientDetails, defaultBranch)
if err != nil {
Expand All @@ -518,7 +520,7 @@ func handleCommentPrEvent(ghPrClientDetails GhPrClientDetails, ce *github.IssueC

for _, componentPath := range componentPathList {
if isSyncFromBranchAllowedForThisPath(config.Argocd.AllowSyncfromBranchPathRegex, componentPath) {
err := argocd.SetArgoCDAppRevision(ghPrClientDetails.Ctx, componentPath, ghPrClientDetails.Ref, ghPrClientDetails.RepoURL, config.Argocd.UseSHALabelForAppDiscovery)
err := argocd.SetArgoCDAppRevision(ghPrClientDetails.Ctx, componentPath, ghPrClientDetails.Ref, ghPrClientDetails.RepoURL, config.Argocd.UseSHALabelForAppDiscovery, argoOpts)
if err != nil {
ghPrClientDetails.PrLogger.Errorf("Failed to sync ArgoCD app from branch: err=%s\n", err)
}
Expand Down Expand Up @@ -617,7 +619,7 @@ func BumpVersion(ghPrClientDetails GhPrClientDetails, defaultBranch string, file
return nil
}

func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubClient *github.Client) error {
func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubClient *github.Client, argoOpts *apiclient.ClientOptions) error {
defaultBranch, _ := ghPrClientDetails.GetDefaultBranch()
config, err := GetInRepoConfig(ghPrClientDetails, defaultBranch)
if err != nil {
Expand Down Expand Up @@ -723,7 +725,7 @@ func handleMergedPrEvent(ghPrClientDetails GhPrClientDetails, prApproverGithubCl
for _, componentPath := range componentPathList {
if isSyncFromBranchAllowedForThisPath(config.Argocd.AllowSyncfromBranchPathRegex, componentPath) {
ghPrClientDetails.PrLogger.Infof("Ensuring ArgoCD app %s is set to HEAD\n", componentPath)
err := argocd.SetArgoCDAppRevision(ghPrClientDetails.Ctx, componentPath, "HEAD", ghPrClientDetails.RepoURL, config.Argocd.UseSHALabelForAppDiscovery)
err := argocd.SetArgoCDAppRevision(ghPrClientDetails.Ctx, componentPath, "HEAD", ghPrClientDetails.RepoURL, config.Argocd.UseSHALabelForAppDiscovery, argoOpts)
if err != nil {
ghPrClientDetails.PrLogger.Errorf("Failed to set ArgoCD app @ %s, to HEAD: err=%s\n", componentPath, err)
}
Expand Down
Loading