Skip to content
Open
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ test: manifests generate fmt vet setup-envtest ## Run tests.

.PHONY: controller-test
controller-test: manifests generate fmt vet setup-envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test -v github.com/cloudoperators/repo-guard/internal/controller
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test -v github.com/cloudoperators/repo-guard/internal/controller github.com/cloudoperators/repo-guard/internal/metrics

# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'.
# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ require (
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.21 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand Down
13 changes: 9 additions & 4 deletions internal/controller/githuborganization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ type GithubOrganizationReconciler struct {
func (r *GithubOrganizationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
l := log.FromContext(ctx)
done := ghmetrics.StartReconcileTimer("GithubOrganization")
var githubOrganization *v1.GithubOrganization
defer func() {
// reflect final metrics for organization status/operations
if githubOrganization != nil {
ghmetrics.SetGithubOrganizationMetrics(githubOrganization)
}
result := "success"
if err != nil {
result = "error"
Expand All @@ -72,7 +77,7 @@ func (r *GithubOrganizationReconciler) Reconcile(ctx context.Context, req ctrl.R
done(result)
}()

githubOrganization := &v1.GithubOrganization{}
githubOrganization = &v1.GithubOrganization{}
err = r.Get(ctx, req.NamespacedName, githubOrganization)
if err != nil {
if errors.IsNotFound(err) {
Expand Down Expand Up @@ -120,7 +125,7 @@ func (r *GithubOrganizationReconciler) Reconcile(ctx context.Context, req ctrl.R
return reconcile.Result{}, err
}
// reflect new status in metrics before proceeding
ghmetrics.SetGithubOrganizationMetrics(githubOrganization)
// (defer will also update it at the end)
Comment on lines 127 to +128
}
}

Expand Down Expand Up @@ -158,7 +163,7 @@ func (r *GithubOrganizationReconciler) Reconcile(ctx context.Context, req ctrl.R
return reconcile.Result{}, err
}
// reflect new status/operations in metrics
ghmetrics.SetGithubOrganizationMetrics(githubOrganization)
// (defer will also update it at the end)
Comment on lines 165 to +166
return reconcile.Result{}, nil
}
}
Expand Down Expand Up @@ -194,7 +199,7 @@ func (r *GithubOrganizationReconciler) Reconcile(ctx context.Context, req ctrl.R
if err != nil {
return reconcile.Result{}, err
}
ghmetrics.SetGithubOrganizationMetrics(githubOrganization)
// (defer will also update it at the end)
return reconcile.Result{}, nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/githubteam_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (r *GithubTeamReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return reconcile.Result{}, err
}
// reflect new status in metrics before proceeding
ghmetrics.SetGithubTeamMetrics(githubTeam)
// (defer will also update it at the end)
}
}

Expand Down
96 changes: 96 additions & 0 deletions internal/metrics/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
// SPDX-License-Identifier: Apache-2.0

package metrics

import (
"strings"
"testing"

v1 "github.com/cloudoperators/repo-guard/api/v1"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
)

func TestSetGithubOrganizationMetrics(t *testing.T) {
org := &v1.GithubOrganization{
Spec: v1.GithubOrganizationSpec{
Github: "github.com",
Organization: "sapcc",
},
Status: v1.GithubOrganizationStatus{
OrganizationStatus: v1.GithubOrganizationStateFailed,
Operations: v1.GithubOrganizationStatusOperations{
GithubTeamOperations: []v1.GithubTeamOperation{
{
Operation: v1.GithubTeamOperationTypeAdd,
Team: "team1",
State: v1.GithubUserOperationStatePending,
},
},
},
},
}

SetGithubOrganizationMetrics(org)

// Check GithubOrganizationStatus
// We expect status="failed" to be 1, others to be 0
expectedStatus := `
# HELP repo_guard_githuborganization_status Current status of a GithubOrganization resource (one-hot gauge).
# TYPE repo_guard_githuborganization_status gauge
repo_guard_githuborganization_status{github="github.com",organization="sapcc",status="complete"} 0
repo_guard_githuborganization_status{github="github.com",organization="sapcc",status="dry-run"} 0
repo_guard_githuborganization_status{github="github.com",organization="sapcc",status="failed"} 1
repo_guard_githuborganization_status{github="github.com",organization="sapcc",status="pending"} 0
repo_guard_githuborganization_status{github="github.com",organization="sapcc",status="ratelimited"} 0
`
err := testutil.CollectAndCompare(GithubOrganizationStatus, strings.NewReader(expectedStatus), "repo_guard_githuborganization_status")
assert.NoError(t, err)

// Check GithubOrganizationOperations
// We expect teams/add/pending to be 1
// The dashboard query for "Org Pending Ops" is:
// sum(repo_guard_githuborganization_operations{state="pending", github=~"$github", organization=~"$org"}) or vector(0)

count := testutil.ToFloat64(GithubOrganizationOperations.WithLabelValues("github.com", "sapcc", "teams", "add", "pending"))
assert.Equal(t, 1.0, count)
}

func TestSetGithubTeamMetrics(t *testing.T) {
team := &v1.GithubTeam{
Spec: v1.GithubTeamSpec{
Organization: "sapcc",
Team: "team1",
},
Status: v1.GithubTeamStatus{
TeamStatus: v1.GithubTeamStatePendingOperations,
Operations: []v1.GithubUserOperation{
{
Operation: v1.GithubUserOperationTypeAdd,
User: "user1",
State: v1.GithubUserOperationStatePending,
},
},
},
}

SetGithubTeamMetrics(team)

// Check GithubTeamStatus
expectedStatus := `
# HELP repo_guard_githubteam_status Current status of a GithubTeam resource (one-hot gauge).
# TYPE repo_guard_githubteam_status gauge
repo_guard_githubteam_status{organization="sapcc",status="complete",team="team1"} 0
repo_guard_githubteam_status{organization="sapcc",status="dry-run",team="team1"} 0
repo_guard_githubteam_status{organization="sapcc",status="failed",team="team1"} 0
repo_guard_githubteam_status{organization="sapcc",status="pending",team="team1"} 1
repo_guard_githubteam_status{organization="sapcc",status="ratelimited",team="team1"} 0
`
err := testutil.CollectAndCompare(GithubTeamStatus, strings.NewReader(expectedStatus), "repo_guard_githubteam_status")
assert.NoError(t, err)

// Check GithubTeamOperations
count := testutil.ToFloat64(GithubTeamOperations.WithLabelValues("sapcc", "team1", "add", "pending"))
assert.Equal(t, 1.0, count)
}
Loading