Added support for CSI secret provider

Signed-off-by: Zanis <22601571+ZanisO@users.noreply.github.com>
This commit is contained in:
Zanis
2024-12-24 22:45:19 +00:00
parent 574129d637
commit f6887b4d8a
12 changed files with 83 additions and 5 deletions

View File

@@ -54,6 +54,7 @@ func NewReloaderCommand() *cobra.Command {
cmd.PersistentFlags().StringVar(&options.ReloadOnDelete, "reload-on-delete", "false", "Add support to watch delete events")
cmd.PersistentFlags().BoolVar(&options.EnableHA, "enable-ha", false, "Adds support for running multiple replicas via leadership election")
cmd.PersistentFlags().BoolVar(&options.SyncAfterRestart, "sync-after-restart", false, "Sync add events after reloader restarts")
cmd.PersistentFlags().BoolVar(&options.EnableCSIIntegration, "enable-csi-integration", false, "Watch SecretProviderClassPodStatus for changes")
return cmd
}
@@ -176,6 +177,10 @@ func startReloader(cmd *cobra.Command, args []string) {
var controllers []*controller.Controller
for k := range kube.ResourceMap {
if k == "secretproviderclasspodstatuses" && !options.EnableCSIIntegration {
continue
}
if ignoredResourcesList.Contains(k) || (len(namespaceLabelSelector) == 0 && k == "namespaces") {
continue
}

View File

@@ -8,6 +8,8 @@ const (
ConfigmapEnvVarPostfix = "CONFIGMAP"
// SecretEnvVarPostfix is a postfix for secret envVar
SecretEnvVarPostfix = "SECRET"
// SecretEnvVarSecretProviderClassPodStatus is a postfix for secretproviderclasspodstatus envVar
SecretProviderClassEnvVarPostfix = "SECRETPROVIDERCLASS"
// EnvVarPrefix is a Prefix for environment variable
EnvVarPrefix = "STAKATER_"

View File

@@ -79,7 +79,16 @@ func NewController(
}
}
listWatcher := cache.NewFilteredListWatchFromClient(client.CoreV1().RESTClient(), resource, namespace, optionsModifier)
getterRESTClient := client.CoreV1().RESTClient()
if resource == "secretproviderclasspodstatuses" {
csiClient, err := kube.GetCSIClient()
if err != nil {
logrus.Fatal(err)
}
getterRESTClient = csiClient.SecretsstoreV1().RESTClient()
}
listWatcher := cache.NewFilteredListWatchFromClient(getterRESTClient, resource, namespace, optionsModifier)
_, informer := cache.NewInformerWithOptions(cache.InformerOptions{
ListerWatcher: listWatcher,

View File

@@ -7,6 +7,7 @@ import (
"github.com/stakater/Reloader/internal/pkg/util"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/record"
csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
)
// ResourceUpdatedHandler contains updated objects
@@ -45,6 +46,9 @@ func (r ResourceUpdatedHandler) GetConfig() (util.Config, string) {
} else if _, ok := r.Resource.(*v1.Secret); ok {
oldSHAData = util.GetSHAfromSecret(r.OldResource.(*v1.Secret).Data)
config = util.GetSecretConfig(r.Resource.(*v1.Secret))
} else if _, ok := r.Resource.(*csiv1.SecretProviderClassPodStatus); ok {
oldSHAData = util.GetSHAfromSecretProviderClassPodStatus(r.OldResource.(*csiv1.SecretProviderClassPodStatus).Status)
config = util.GetSecretProviderClassPodStatusConfig(r.Resource.(*csiv1.SecretProviderClassPodStatus))
} else {
logrus.Warnf("Invalid resource: Resource should be 'Secret' or 'Configmap' but found, %v", r.Resource)
}

View File

@@ -219,6 +219,7 @@ func PerformAction(clients kube.Clients, config util.Config, upgradeFuncs callba
typedAutoAnnotationEnabledValue, foundTypedAuto := annotations[config.TypedAutoAnnotation]
excludeConfigmapAnnotationValue, foundExcludeConfigmap := annotations[options.ConfigmapExcludeReloaderAnnotation]
excludeSecretAnnotationValue, foundExcludeSecret := annotations[options.SecretExcludeReloaderAnnotation]
excludeSecretProviderClassProviderAnnotationValue, foundExcludeSecretProviderClass := annotations[options.SecretProviderClassExcludeReloaderAnnotation]
if !found && !foundAuto && !foundTypedAuto && !foundSearchAnn {
annotations = upgradeFuncs.PodAnnotationsFunc(i)
@@ -239,6 +240,10 @@ func PerformAction(clients kube.Clients, config util.Config, upgradeFuncs callba
if foundExcludeSecret {
isResourceExcluded = checkIfResourceIsExcluded(config.ResourceName, excludeSecretAnnotationValue)
}
case constants.SecretProviderClassEnvVarPostfix:
if foundExcludeSecretProviderClass {
isResourceExcluded = checkIfResourceIsExcluded(config.ResourceName, excludeSecretProviderClassProviderAnnotationValue)
}
}
if isResourceExcluded {
@@ -355,6 +360,10 @@ func getVolumeMountName(volumes []v1.Volume, mountType string, volumeName string
}
}
}
} else if mountType == constants.SecretProviderClassEnvVarPostfix {
if volumes[i].CSI != nil && volumes[i].CSI.VolumeAttributes["secretProviderClass"] == volumeName {
return volumes[i].Name
}
}
}

View File

@@ -30,6 +30,8 @@ var (
ConfigmapExcludeReloaderAnnotation = "configmaps.exclude.reloader.stakater.com/reload"
// SecretExcludeReloaderAnnotation is a comma separated list of secrets that excludes detecting changes on secrets
SecretExcludeReloaderAnnotation = "secrets.exclude.reloader.stakater.com/reload"
// SecretProviderClassExcludeReloaderAnnotation is a comma separated list of secret provider classes that excludes detecting changes on secret provider class
SecretProviderClassExcludeReloaderAnnotation = "secretproviderclass.exclude.reloader.stakater.com/reload"
// AutoSearchAnnotation is an annotation to detect changes in
// configmaps or triggers with the SearchMatchAnnotation
AutoSearchAnnotation = "reloader.stakater.com/search"
@@ -55,6 +57,8 @@ var (
EnableHA = false
// Url to send a request to instead of triggering a reload
WebhookUrl = ""
// EnableCsiIntegration Adds support to watch SecretProviderClassPodStatus and restart deployment based on it
EnableCSIIntegration = false
)
func ToArgoRolloutStrategy(s string) ArgoRolloutStrategy {

View File

@@ -4,9 +4,10 @@ import (
"github.com/stakater/Reloader/internal/pkg/constants"
"github.com/stakater/Reloader/internal/pkg/options"
v1 "k8s.io/api/core/v1"
csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
)
//Config contains rolling upgrade configuration parameters
// Config contains rolling upgrade configuration parameters
type Config struct {
Namespace string
ResourceName string
@@ -42,3 +43,13 @@ func GetSecretConfig(secret *v1.Secret) Config {
Type: constants.SecretEnvVarPostfix,
}
}
func GetSecretProviderClassPodStatusConfig(podStatus *csiv1.SecretProviderClassPodStatus) Config {
return Config{
Namespace: podStatus.Namespace,
ResourceName: podStatus.Status.SecretProviderClassName,
ResourceAnnotations: podStatus.Annotations,
SHAValue: GetSHAfromSecretProviderClassPodStatus(podStatus.Status),
Type: constants.SecretProviderClassEnvVarPostfix,
}
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/stakater/Reloader/internal/pkg/crypto"
v1 "k8s.io/api/core/v1"
csiv1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
)
// ConvertToEnvVarName converts the given text into a usable env var
@@ -52,6 +53,16 @@ func GetSHAfromSecret(data map[string][]byte) string {
return crypto.GenerateSHA(strings.Join(values, ";"))
}
func GetSHAfromSecretProviderClassPodStatus(data csiv1.SecretProviderClassPodStatusStatus) string {
values := []string{}
for _, v := range data.Objects {
values = append(values, v.ID+"="+v.Version)
}
values = append(values, "SecretProviderClassName="+data.SecretProviderClassName)
sort.Strings(values)
return crypto.GenerateSHA(strings.Join(values, ";"))
}
type List []string
type Map map[string]string