Readme update and code refactor

Signed-off-by: faizanahmad055 <faizan.ahmad55@outlook.com>
This commit is contained in:
faizanahmad055
2026-01-04 02:40:42 +01:00
parent 85f1c13de9
commit 0f1d02e975
10 changed files with 104 additions and 39 deletions

View File

@@ -49,7 +49,7 @@ func newTestFixtures() testFixtures {
func setupTestClients() kube.Clients {
return kube.Clients{
KubernetesClient: fake.NewSimpleClientset(),
KubernetesClient: fake.NewClientset(),
ArgoRolloutClient: fakeargoclientset.NewSimpleClientset(),
}
}

View File

@@ -160,15 +160,8 @@ func startReloader(cmd *cobra.Command, args []string) {
var controllers []*controller.Controller
for k := range kube.ResourceMap {
if k == "secretproviderclasspodstatuses" {
if !options.EnableCSIIntegration {
logrus.Infof("EnableCSIIntegration is set to false, won't run secretproviderclasspodstatuses controller")
continue
}
if !kube.IsCSIInstalled {
logrus.Infof("Can't run secretproviderclasspodstatuses controller as CSI CRDs are not installed")
continue
}
if k == constants.SecretProviderClassController && !shouldRunCSIController() {
continue
}
if ignoredResourcesList.Contains(k) || (len(namespaceLabelSelector) == 0 && k == "namespaces") {
@@ -218,3 +211,15 @@ func startPProfServer() {
logrus.Errorf("Failed to start pprof server: %v", err)
}
}
func shouldRunCSIController() bool {
if !options.EnableCSIIntegration {
logrus.Info("Skipping secretproviderclasspodstatuses controller: EnableCSIIntegration is disabled")
return false
}
if !kube.IsCSIInstalled {
logrus.Info("Skipping secretproviderclasspodstatuses controller: CSI CRDs not installed")
return false
}
return true
}

View File

@@ -24,6 +24,8 @@ const (
EnvVarsReloadStrategy = "env-vars"
// AnnotationsReloadStrategy instructs Reloader to add pod template annotations to facilitate a restart
AnnotationsReloadStrategy = "annotations"
// SecretProviderClassController enables support for SecretProviderClassPodStatus resources
SecretProviderClassController = "secretproviderclasspodstatuses"
)
// Leadership election related consts

View File

@@ -2,9 +2,11 @@ package controller
import (
"fmt"
"slices"
"time"
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/handler"
"github.com/stakater/Reloader/internal/pkg/metrics"
"github.com/stakater/Reloader/internal/pkg/options"
@@ -21,7 +23,6 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/utils/strings/slices"
csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
)
@@ -80,13 +81,9 @@ func NewController(
}
}
getterRESTClient := client.CoreV1().RESTClient()
if resource == "secretproviderclasspodstatuses" {
csiClient, err := kube.GetCSIClient()
if err != nil {
logrus.Fatal(err)
}
getterRESTClient = csiClient.SecretsstoreV1().RESTClient()
getterRESTClient, err := getClientForResource(resource, client)
if err != nil {
return nil, fmt.Errorf("failed to initialize REST client for %s: %w", resource, err)
}
listWatcher := cache.NewFilteredListWatchFromClient(getterRESTClient, resource, namespace, optionsModifier)
@@ -301,3 +298,14 @@ func (c *Controller) handleErr(err error, key interface{}) {
logrus.Errorf("Dropping key out of the queue: %v", err)
logrus.Debugf("Dropping the key %q out of the queue: %v", key, err)
}
func getClientForResource(resource string, coreClient kubernetes.Interface) (cache.Getter, error) {
if resource == constants.SecretProviderClassController {
csiClient, err := kube.GetCSIClient()
if err != nil {
return nil, fmt.Errorf("failed to get CSI client: %w", err)
}
return csiClient.SecretsstoreV1().RESTClient(), nil
}
return coreClient.CoreV1().RESTClient(), nil
}

View File

@@ -2757,7 +2757,7 @@ func TestController_resourceInNamespaceSelector(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fakeClient := fake.NewSimpleClientset()
fakeClient := fake.NewClientset()
namespace, _ := fakeClient.CoreV1().Namespaces().Create(context.Background(), &tt.fields.namespace, metav1.CreateOptions{})
logrus.Infof("created fakeClient namespace for testing = %s", namespace.Name)

View File

@@ -244,7 +244,7 @@ func TestHandleMissingTimerSimple(t *testing.T) {
}()
t.Run(test.name, func(t *testing.T) {
fakeClient := testclient.NewSimpleClientset()
fakeClient := testclient.NewClientset()
clients := kube.Clients{
KubernetesClient: fakeClient,
}
@@ -337,7 +337,7 @@ func TestPauseDeployment(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeClient := testclient.NewSimpleClientset()
fakeClient := testclient.NewClientset()
clients := kube.Clients{
KubernetesClient: fakeClient,
}

View File

@@ -39,20 +39,31 @@ func (r ResourceUpdatedHandler) Handle() error {
// GetConfig gets configurations containing SHA, annotations, namespace and resource name
func (r ResourceUpdatedHandler) GetConfig() (common.Config, string) {
var oldSHAData string
var config common.Config
var (
oldSHAData string
config common.Config
)
switch res := r.Resource.(type) {
case *v1.ConfigMap:
oldSHAData = util.GetSHAfromConfigmap(r.OldResource.(*v1.ConfigMap))
if old, ok := r.OldResource.(*v1.ConfigMap); ok && old != nil {
oldSHAData = util.GetSHAfromConfigmap(old)
}
config = common.GetConfigmapConfig(res)
case *v1.Secret:
oldSHAData = util.GetSHAfromSecret(r.OldResource.(*v1.Secret).Data)
if old, ok := r.OldResource.(*v1.Secret); ok && old != nil {
oldSHAData = util.GetSHAfromSecret(old.Data)
}
config = common.GetSecretConfig(res)
case *csiv1.SecretProviderClassPodStatus:
oldSHAData = util.GetSHAfromSecretProviderClassPodStatus(r.OldResource.(*csiv1.SecretProviderClassPodStatus).Status)
if old, ok := r.OldResource.(*csiv1.SecretProviderClassPodStatus); ok && old != nil && old.Status.Objects != nil {
oldSHAData = util.GetSHAfromSecretProviderClassPodStatus(old.Status)
}
config = common.GetSecretProviderClassPodStatusConfig(res)
default:
logrus.Warnf("Invalid resource: Resource should be 'Secret', 'Configmap' or 'SecretProviderClassPodStatus' but found, %v", r.Resource)
logrus.Warnf("Invalid resource: Resource should be 'Secret', 'Configmap' or 'SecretProviderClassPodStatus' but found, %T", r.Resource)
}
return config, oldSHAData
}

View File

@@ -634,11 +634,10 @@ func updateEnvVar(container *v1.Container, envVar string, shaData string) consta
}
func secretProviderClassEnvReloaded(containers []v1.Container, envVar string, shaData string) bool {
for i := range containers {
envs := containers[i].Env
for j := range envs {
if envs[j].Name == envVar {
return envs[j].Value == shaData
for _, container := range containers {
for _, env := range container.Env {
if env.Name == envVar {
return env.Value == shaData
}
}
}
@@ -649,7 +648,11 @@ func populateAnnotationsFromSecretProviderClass(clients kube.Clients, config *co
obj, err := clients.CSIClient.SecretsstoreV1().SecretProviderClasses(config.Namespace).Get(context.TODO(), config.ResourceName, metav1.GetOptions{})
annotations := make(map[string]string)
if err != nil {
logrus.Infof("Couldn't find secretproviderclass '%s' in '%s' namespace for typed annotation", config.ResourceName, config.Namespace)
if apierrors.IsNotFound(err) {
logrus.Warnf("SecretProviderClass '%s' not found in namespace '%s'", config.ResourceName, config.Namespace)
} else {
logrus.Errorf("Failed to get SecretProviderClass '%s' in namespace '%s': %v", config.ResourceName, config.Namespace, err)
}
} else if obj.Annotations != nil {
annotations = obj.Annotations
}

View File

@@ -32,7 +32,7 @@ import (
var (
clients = kube.Clients{
KubernetesClient: testclient.NewSimpleClientset(),
KubernetesClient: testclient.NewClientset(),
CSIClient: csitestclient.NewSimpleClientset(),
}