Skip to content

Instantly share code, notes, and snippets.

@ialidzhikov
Last active May 20, 2025 06:38
Show Gist options
  • Select an option

  • Save ialidzhikov/d9896a9d23d26a4b8c70eb29c0c055cf to your computer and use it in GitHub Desktop.

Select an option

Save ialidzhikov/d9896a9d23d26a4b8c70eb29c0c055cf to your computer and use it in GitHub Desktop.
Find Shoots with missing APIServerProxyUsesHTTPProxy constraint
#!/bin/bash
# Check if the correct number of arguments is provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <namespace> <shoot_name>"
exit 1
fi
NAMESPACE=$1
SHOOT_NAME=$2
# Retrieve the current constraints
CURRENT_CONSTRAINTS=$(kubectl -n "$NAMESPACE" get shoots "$SHOOT_NAME" -o jsonpath='{.status.constraints}' | jq '.')
# Define the new constraint to be added
NEW_CONSTRAINT='{
"type": "APIServerProxyUsesHTTPProxy",
"status": "True",
"lastTransitionTime": "2025-02-18T01:23:25Z",
"lastUpdateTime": "2025-02-18T01:23:25Z",
"reason": "APIServerProxyUsesHTTPProxy",
"message": "Manually patched. Nessesary for enablement of RemoveAPIServerProxyLegacyPort feature gate as cluster was failing to reconcile successfully since longtime and prevented feature gate enablement"
}'
echo "Current Constraints:"
echo "$CURRENT_CONSTRAINTS" | jq '.'
# Append the new constraint to the current constraints
UPDATED_CONSTRAINTS=$(echo "$CURRENT_CONSTRAINTS" | jq --argjson newConstraint "$NEW_CONSTRAINT" '. += [$newConstraint]')
echo "Updated Constraint:"
echo "$UPDATED_CONSTRAINTS" | jq '.'
# Ask for permission to patch
read -p "Do you want to proceed with patching the resource? (yes/no): " CONFIRMATION
if [[ "$CONFIRMATION" == "yes" ]]; then
# Patch the resource with the updated constraints
kubectl -n "$NAMESPACE" patch shoots "$SHOOT_NAME" --type=merge --patch "$(jq -n --argjson constraints "$UPDATED_CONSTRAINTS" '{"status": {"constraints": $constraints}}')" --subresource=status
echo "Resource patched successfully."
else
echo "Patching aborted."
fi
package main
import (
"context"
"fmt"
"os"
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
v1beta1helper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"
)
var endUserErrorCodes = sets.New(
gardencorev1beta1.ErrorInfraUnauthenticated,
gardencorev1beta1.ErrorInfraUnauthorized,
gardencorev1beta1.ErrorInfraDependencies,
gardencorev1beta1.ErrorInfraQuotaExceeded,
gardencorev1beta1.ErrorConfigurationProblem,
)
func main() {
ctx := context.Background()
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig == "" {
panic(fmt.Errorf("KUBECONFIG env var is not set"))
}
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(fmt.Errorf("failed to create client config: %w", err))
}
scheme := runtime.NewScheme()
gardencorev1beta1.AddToScheme(scheme)
client, err := client.New(config, client.Options{
Scheme: scheme,
})
if err != nil {
panic(fmt.Errorf("failed to create a client: %w", err))
}
shoots := &gardencorev1beta1.ShootList{}
if err := client.List(ctx, shoots); err != nil {
panic(fmt.Errorf("failed to list shoots: %w", err))
}
for _, shoot := range shoots.Items {
if v1beta1helper.IsWorkerless(&shoot) {
continue
}
if shoot.Status.LastOperation == nil || ((shoot.Status.LastOperation.Type == gardencorev1beta1.LastOperationTypeCreate || shoot.Status.LastOperation.Type == gardencorev1beta1.LastOperationTypeDelete) && shoot.Status.LastOperation.State != gardencorev1beta1.LastOperationStateSucceeded) {
continue
}
if cond := v1beta1helper.GetCondition(shoot.Status.Constraints, gardencorev1beta1.ShootAPIServerProxyUsesHTTPProxy); cond != nil && cond.Status == gardencorev1beta1.ConditionTrue {
continue
}
fmt.Printf("%s/%s: ", shoot.Namespace, shoot.Name)
lastOperation := shoot.Status.LastOperation
fmt.Printf("%s %s; ", lastOperation.Type, lastOperation.State)
if lastErrors := shoot.Status.LastErrors; lastErrors != nil {
for _, lastError := range lastErrors {
for _, code := range lastError.Codes {
if endUserErrorCodes.Has(code) {
fmt.Printf("%s;", code)
}
}
}
}
fmt.Println()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment