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
4 changes: 1 addition & 3 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
uses: actions/setup-go@v6
with:
check-latest: true
go-version: 1.26.2
go-version: 1.26.3
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v9
with:
Expand All @@ -44,8 +44,6 @@ jobs:
uses: crate-ci/typos@v1
env:
CLICOLOR: "1"
- name: Delete typos binary
run: rm -f typos
- name: Check if source code files have license header
run: make check-addlicense
- name: REUSE Compliance Check
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
uses: actions/setup-go@v6
with:
check-latest: true
go-version: 1.26.2
go-version: 1.26.3
- name: Build all binaries
run: make build-all
code_coverage:
Expand Down Expand Up @@ -65,9 +65,9 @@ jobs:
uses: actions/setup-go@v6
with:
check-latest: true
go-version: 1.26.2
go-version: 1.26.3
- name: Run tests and generate coverage report
run: make test-with-envtest
run: make build/cover.out
- name: Archive code coverage results
uses: actions/upload-artifact@v7
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
uses: actions/setup-go@v6
with:
check-latest: true
go-version: 1.26.2
go-version: 1.26.3
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/container-registry-ghcr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
name: Container Registry GHCR
"on":
push:
branches:
- main
tags:
- '*'
workflow_dispatch: {}
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ prepare-static-check: FORCE install-goimports install-golangci-lint install-shel
# To add additional flags or values (before the default ones), specify the variable in the environment, e.g. `GO_BUILDFLAGS='-tags experimental' make`.
# To override the default flags or values, specify the variable on the command line, e.g. `make GO_BUILDFLAGS='-tags experimental'`.
GO_BUILDFLAGS +=
GO_LDFLAGS +=
GO_TESTFLAGS +=
GO_TESTENV +=
GO_BUILDENV +=
GO_LDFLAGS +=
GO_TESTFLAGS +=
GO_TESTENV +=
GO_BUILDENV +=

build-all: build/shoot-grafter

Expand Down
1 change: 1 addition & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ path = [
"go.mod",
"go.sum",
"Makefile.maker.yaml",
"vendor/modules.txt",
]
SPDX-FileCopyrightText = "SAP SE or an SAP affiliate company and Greenhouse contributors"
SPDX-License-Identifier = "Apache-2.0"
Expand Down
41 changes: 24 additions & 17 deletions controller/careinstruction/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,41 @@ import (
"shoot-grafter/api/v1alpha1"
)

const (
labelCareInstruction = "care_instruction"
labelNamespace = "namespace"
labelGardenNamespace = "garden_namespace"
labelShootName = "shoot_name"
)

var (
TotalTargetShootsGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "shoot_grafter_total_target_shoots",
Help: "Total number of shoots matching the CareInstruction label selector",
},
[]string{"care_instruction", "namespace", "garden_namespace"},
[]string{labelCareInstruction, labelNamespace, labelGardenNamespace},
)
CreatedClustersGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "shoot_grafter_created_clusters",
Help: "Number of clusters created by the CareInstruction",
},
[]string{"care_instruction", "namespace", "garden_namespace"},
[]string{labelCareInstruction, labelNamespace, labelGardenNamespace},
)
FailedClustersGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "shoot_grafter_failed_clusters",
Help: "Number of clusters failed to be created by the CareInstruction",
},
[]string{"care_instruction", "namespace", "garden_namespace"},
[]string{labelCareInstruction, labelNamespace, labelGardenNamespace},
)
ShootOnboardedGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "shoot_grafter_shoot_onboarded",
Help: "Is shoot onboarded by the CareInstruction",
},
[]string{"care_instruction", "namespace", "garden_namespace", "shoot_name"},
[]string{labelCareInstruction, labelNamespace, labelGardenNamespace, labelShootName},
)
)

Expand All @@ -59,29 +66,29 @@ func UpdateCareInstructionMetrics(careInstruction *v1alpha1.CareInstruction) {

func updateTotalTargetShootsMetric(careInstruction *v1alpha1.CareInstruction) {
metricLabels := prometheus.Labels{
"care_instruction": careInstruction.Name,
"namespace": careInstruction.Namespace,
"garden_namespace": careInstruction.Spec.GardenNamespace,
labelCareInstruction: careInstruction.Name,
labelNamespace: careInstruction.Namespace,
labelGardenNamespace: careInstruction.Spec.GardenNamespace,
}
totalTargetShoots := careInstruction.Status.TotalTargetShoots
TotalTargetShootsGauge.With(metricLabels).Set(float64(totalTargetShoots))
}

func updateCreatedClustersMetric(careInstruction *v1alpha1.CareInstruction) {
metricLabels := prometheus.Labels{
"care_instruction": careInstruction.Name,
"namespace": careInstruction.Namespace,
"garden_namespace": careInstruction.Spec.GardenNamespace,
labelCareInstruction: careInstruction.Name,
labelNamespace: careInstruction.Namespace,
labelGardenNamespace: careInstruction.Spec.GardenNamespace,
}
createdCount := careInstruction.Status.CreatedClusters
CreatedClustersGauge.With(metricLabels).Set(float64(createdCount))
}

func updateFailedClustersMetric(careInstruction *v1alpha1.CareInstruction) {
metricLabels := prometheus.Labels{
"care_instruction": careInstruction.Name,
"namespace": careInstruction.Namespace,
"garden_namespace": careInstruction.Spec.GardenNamespace,
labelCareInstruction: careInstruction.Name,
labelNamespace: careInstruction.Namespace,
labelGardenNamespace: careInstruction.Spec.GardenNamespace,
}
failedCount := careInstruction.Status.FailedClusters
FailedClustersGauge.With(metricLabels).Set(float64(failedCount))
Expand All @@ -90,10 +97,10 @@ func updateFailedClustersMetric(careInstruction *v1alpha1.CareInstruction) {
func updateOnboardedShootsMetrics(careInstruction *v1alpha1.CareInstruction) {
for _, ss := range careInstruction.Status.Shoots {
metricLabels := prometheus.Labels{
"care_instruction": careInstruction.Name,
"namespace": careInstruction.Namespace,
"garden_namespace": careInstruction.Spec.GardenNamespace,
"shoot_name": ss.Name,
labelCareInstruction: careInstruction.Name,
labelNamespace: careInstruction.Namespace,
labelGardenNamespace: careInstruction.Spec.GardenNamespace,
labelShootName: ss.Name,
}
if ss.Status == v1alpha1.ShootStatusOnboarded {
ShootOnboardedGauge.With(metricLabels).Set(float64(1))
Expand Down
14 changes: 8 additions & 6 deletions controller/shoot/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"sigs.k8s.io/yaml"
)

const configYAMLKey = "config.yaml"

// configureOIDCAuthentication configures OIDC authentication for the Shoot by:
// 1. Fetching the AuthenticationConfiguration ConfigMap from Greenhouse cluster
// 2. Merging it with any existing configuration on the Garden cluster
Expand Down Expand Up @@ -47,14 +49,14 @@ func (r *ShootController) configureOIDCAuthentication(ctx context.Context, shoot
}

// Verify the ConfigMap contains config.yaml
if greenhouseAuthConfigMap.Data == nil || greenhouseAuthConfigMap.Data["config.yaml"] == "" {
if greenhouseAuthConfigMap.Data == nil || greenhouseAuthConfigMap.Data[configYAMLKey] == "" {
return fmt.Errorf("AuthenticationConfiguration ConfigMap %s does not contain config.yaml",
r.CareInstruction.Spec.AuthenticationConfigMapName)
}

// Parse the Greenhouse authentication configuration
var greenhouseAuthConfig apiserverv1beta1.AuthenticationConfiguration
if err := yaml.Unmarshal([]byte(greenhouseAuthConfigMap.Data["config.yaml"]), &greenhouseAuthConfig); err != nil {
if err := yaml.Unmarshal([]byte(greenhouseAuthConfigMap.Data[configYAMLKey]), &greenhouseAuthConfig); err != nil {
return fmt.Errorf("failed to parse Greenhouse AuthenticationConfiguration: %w", err)
}

Expand Down Expand Up @@ -90,7 +92,7 @@ func (r *ShootController) configureOIDCAuthentication(ctx context.Context, shoot
Namespace: shoot.Namespace,
},
Data: map[string]string{
"config.yaml": "",
configYAMLKey: "",
},
}
}
Expand Down Expand Up @@ -162,8 +164,8 @@ func (r *ShootController) mergeAuthenticationConfigurations(gardenConfigMap *cor
var gardenAuthConfig apiserverv1beta1.AuthenticationConfiguration

// Parse existing Garden configuration if present
if gardenConfigMap.Data != nil && gardenConfigMap.Data["config.yaml"] != "" {
existingConfigYAML := gardenConfigMap.Data["config.yaml"]
if gardenConfigMap.Data != nil && gardenConfigMap.Data[configYAMLKey] != "" {
existingConfigYAML := gardenConfigMap.Data[configYAMLKey]
if err := yaml.Unmarshal([]byte(existingConfigYAML), &gardenAuthConfig); err != nil {
return fmt.Errorf("failed to parse existing Garden AuthenticationConfiguration: %w", err)
}
Expand Down Expand Up @@ -212,7 +214,7 @@ func (r *ShootController) mergeAuthenticationConfigurations(gardenConfigMap *cor
if gardenConfigMap.Data == nil {
gardenConfigMap.Data = make(map[string]string)
}
gardenConfigMap.Data["config.yaml"] = string(mergedConfigYAML)
gardenConfigMap.Data[configYAMLKey] = string(mergedConfigYAML)

return nil
}
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ require (
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/mod v0.34.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/term v0.38.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/term v0.42.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.40.0 // indirect
golang.org/x/tools v0.43.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
Expand Down
32 changes: 16 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -367,46 +367,46 @@ go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfP
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
Loading