Skip to content

Commit

Permalink
Merge pull request #71 from gabemontero/secret-cm-watch-on-demand
Browse files Browse the repository at this point in the history
maintain secret/configmap watches/informers on demand as shares come and go; allow no resource refresh on per volume basis
  • Loading branch information
openshift-merge-robot committed Dec 6, 2021
2 parents 727f001 + 3ba0337 commit f96ba31
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 159 deletions.
6 changes: 3 additions & 3 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var rootCmd = &cobra.Command{
os.Exit(1)
}

go runOperator(cfg, driver)
go runOperator(cfg)
go watchForConfigChanges(cfgManager)
driver.Run()
},
Expand Down Expand Up @@ -127,8 +127,8 @@ func loadSharedresourceClientset() (sharev1clientset.Interface, error) {

// runOperator based on the informed configuration, it will spawn and run the Controller, until
// trapping OS signals.
func runOperator(cfg *config.Config, hp hostpath.HostPathDriver) {
c, err := controller.NewController(cfg.GetShareRelistInterval(), cfg.RefreshResources, cfg.IgnoredNamespaces, hp)
func runOperator(cfg *config.Config) {
c, err := controller.NewController(cfg.GetShareRelistInterval(), cfg.RefreshResources)
if err != nil {
fmt.Printf("Failed to set up controller: %s", err.Error())
os.Exit(1)
Expand Down
27 changes: 2 additions & 25 deletions config/config.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,3 @@
---
ignoredNamespaces:
- openshift-machine-api
- openshift-kube-apiserver
- openshift-kube-apiserver-operator
- openshift-kube-scheduler
- openshift-kube-controller-manager
- openshift-kube-controller-manager-operator
- openshift-kube-scheduler-operator
- openshift-console-operator
- openshift-controller-manager
- openshift-controller-manager-operator
- openshift-cloud-credential-operator
- openshift-authentication-operator
- openshift-service-ca
- openshift-kube-storage-version-migrator-operator
- openshift-config-operator
- openshift-etcd-operator
- openshift-apiserver-operator
- openshift-cluster-csi-drivers
- openshift-cluster-storage-operator
- openshift-cluster-version
- openshift-image-registry
- openshift-machine-config-operator
- openshift-sdn
- openshift-service-ca-operator
shareRelistInterval: 10m
refreshResources: true
3 changes: 0 additions & 3 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ shareRelistInterval: 10m

# toggles actively watching for resources, when disabled it will only read objects before mount
refreshResources: true

# list of namespace names ignored
ignoredNamespaces: []
```

When the file is not present, the driver assumes default values instead. And, when the configuration
Expand Down
10 changes: 5 additions & 5 deletions pkg/cache/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"sync"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog/v2"

"github.com/openshift/csi-driver-shared-resource/pkg/client"
"github.com/openshift/csi-driver-shared-resource/pkg/config"
)

/*
Expand Down Expand Up @@ -43,10 +43,7 @@ func UpsertConfigMap(configmap *corev1.ConfigMap) {
// first, find the shares pointing to this configmap, and call the callbacks, in case certain pods
// have had their permissions revoked; this will also handle if we had share events arrive before
// the corresponding configmap
sharecConfigMapList, err := client.GetListers().SharedConfigMaps.List(labels.Everything())
if err != nil {
klog.Warningf("error during UpsertConfigMap on shared configmaps lister list: %s", err.Error())
}
sharecConfigMapList := client.ListSharedConfigMap()
for _, share := range sharecConfigMapList {
if share.Spec.ConfigMapRef.Namespace == configmap.Namespace && share.Spec.ConfigMapRef.Name == configmap.Name {
shareSecretsUpdateCallbacks.Range(buildRanger(buildCallbackMap(share.Name, share)))
Expand All @@ -67,6 +64,9 @@ func DelConfigMap(configmap *corev1.ConfigMap) {
// if the corresponding share references a configmap, then the function registered here will be called to possibly change
// storage
func RegisterConfigMapUpsertCallback(volID, cmID string, f func(key, value interface{}) bool) {
if !config.LoadedConfig.RefreshResources {
return
}
configmapUpsertCallbacks.Store(volID, f)
ns, name, _ := SplitKey(cmID)
cm := client.GetConfigMap(ns, name)
Expand Down
10 changes: 5 additions & 5 deletions pkg/cache/secrets.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package cache

import (
"github.com/openshift/csi-driver-shared-resource/pkg/config"
"sync"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog/v2"

"github.com/openshift/csi-driver-shared-resource/pkg/client"
Expand Down Expand Up @@ -44,10 +44,7 @@ func UpsertSecret(secret *corev1.Secret) {
// first, find the shares pointing to this secret, and call the callbacks, in case certain pods
// have had their permissions revoked; this will also handle if we had share events arrive before
// the corresponding secret
sharedSecretsList, err := client.GetListers().SharedSecrets.List(labels.Everything())
if err != nil {
klog.Warningf("error during UpsertSecret on shared secrets lister list: %s", err.Error())
}
sharedSecretsList := client.ListSharedSecrets()
for _, share := range sharedSecretsList {
if share.Spec.SecretRef.Namespace == secret.Namespace && share.Spec.SecretRef.Name == secret.Name {
shareSecretsUpdateCallbacks.Range(buildRanger(buildCallbackMap(share.Name, share)))
Expand All @@ -69,6 +66,9 @@ func DelSecret(secret *corev1.Secret) {
// if the corresponding share references a secret, then the function registered here will be called to possibly change
// storage
func RegisterSecretUpsertCallback(volID, sID string, f func(key, value interface{}) bool) {
if !config.LoadedConfig.RefreshResources {
return
}
secretUpsertCallbacks.Store(volID, f)
ns, name, _ := SplitKey(sID)
s := client.GetSecret(ns, name)
Expand Down
29 changes: 26 additions & 3 deletions pkg/cache/shares.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package cache

import (
"github.com/openshift/csi-driver-shared-resource/pkg/client"
"sync"

"k8s.io/klog/v2"

sharev1alpha1 "github.com/openshift/api/sharedresource/v1alpha1"
"github.com/openshift/csi-driver-shared-resource/pkg/client"

"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog/v2"
)

/*
Expand Down Expand Up @@ -96,6 +97,28 @@ func UpdateSharedSecret(share *sharev1alpha1.SharedSecret) {
AddSharedSecret(share)
}

func NamespacesWithSharedConfigMaps() map[string]struct{} {
namespacesMap := map[string]struct{}{}
list, err := client.GetListers().SharedConfigMaps.List(labels.Everything())
if err == nil {
for _, scm := range list {
namespacesMap[scm.Spec.ConfigMapRef.Namespace] = struct{}{}
}
}
return namespacesMap
}

func NamespacesWithSharedSecrets() map[string]struct{} {
namespacesMap := map[string]struct{}{}
list, err := client.GetListers().SharedSecrets.List(labels.Everything())
if err == nil {
for _, ss := range list {
namespacesMap[ss.Spec.SecretRef.Namespace] = struct{}{}
}
}
return namespacesMap
}

// DelSharedConfigMap removes the SharedConfigMap from our various tracking maps and calls the registered callbacks
// to delete the config map content from any volumes using the SharedConfigMap
func DelSharedConfigMap(share *sharev1alpha1.SharedConfigMap) {
Expand Down
77 changes: 66 additions & 11 deletions pkg/client/listers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package client

import (
"context"
"sync"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
corelistersv1 "k8s.io/client-go/listers/core/v1"
"k8s.io/klog/v2"

Expand All @@ -12,24 +15,24 @@ import (
)

type Listers struct {
Secrets corelistersv1.SecretLister
ConfigMaps corelistersv1.ConfigMapLister
Secrets sync.Map
ConfigMaps sync.Map
SharedConfigMaps sharelisterv1alpha1.SharedConfigMapLister
SharedSecrets sharelisterv1alpha1.SharedSecretLister
}

var singleton Listers

func init() {
singleton = Listers{}
singleton = Listers{Secrets: sync.Map{}, ConfigMaps: sync.Map{}}
}

func SetSecretsLister(s corelistersv1.SecretLister) {
singleton.Secrets = s
func SetSecretsLister(namespace string, s corelistersv1.SecretLister) {
singleton.Secrets.Store(namespace, s)
}

func SetConfigMapsLister(c corelistersv1.ConfigMapLister) {
singleton.ConfigMaps = c
func SetConfigMapsLister(namespace string, c corelistersv1.ConfigMapLister) {
singleton.ConfigMaps.Store(namespace, c)
}

func SetSharedConfigMapsLister(s sharelisterv1alpha1.SharedConfigMapLister) {
Expand All @@ -45,8 +48,13 @@ func GetListers() *Listers {
}

func GetSecret(namespace, name string) *corev1.Secret {
if singleton.Secrets != nil {
s, err := singleton.Secrets.Secrets(namespace).Get(name)
var lister corelistersv1.SecretLister
obj, ok := singleton.Secrets.Load(namespace)
if ok {
lister = obj.(corelistersv1.SecretLister)
}
if lister != nil {
s, err := lister.Secrets(namespace).Get(name)
if err == nil {
return s
}
Expand All @@ -63,8 +71,13 @@ func GetSecret(namespace, name string) *corev1.Secret {
}

func GetConfigMap(namespace, name string) *corev1.ConfigMap {
if singleton.ConfigMaps != nil {
cm, err := singleton.ConfigMaps.ConfigMaps(namespace).Get(name)
var lister corelistersv1.ConfigMapLister
obj, ok := singleton.ConfigMaps.Load(namespace)
if ok {
lister = obj.(corelistersv1.ConfigMapLister)
}
if lister != nil {
cm, err := lister.ConfigMaps(namespace).Get(name)
if err == nil {
return cm
}
Expand Down Expand Up @@ -96,6 +109,27 @@ func GetSharedSecret(name string) *sharev1alpha1.SharedSecret {
return nil
}

func ListSharedSecrets() map[string]*sharev1alpha1.SharedSecret {
ret := map[string]*sharev1alpha1.SharedSecret{}
if singleton.SharedSecrets != nil {
list, err := singleton.SharedSecrets.List(labels.Everything())
if err == nil {
for _, ss := range list {
ret[ss.Name] = ss
}
}
}
if shareClient != nil && len(ret) == 0 {
list, err := shareClient.SharedresourceV1alpha1().SharedSecrets().List(context.TODO(), metav1.ListOptions{})
if err == nil {
for _, ss := range list.Items {
ret[ss.Name] = &ss
}
}
}
return ret
}

func GetSharedConfigMap(name string) *sharev1alpha1.SharedConfigMap {
if singleton.SharedConfigMaps != nil {
s, err := singleton.SharedConfigMaps.Get(name)
Expand All @@ -111,3 +145,24 @@ func GetSharedConfigMap(name string) *sharev1alpha1.SharedConfigMap {
}
return nil
}

func ListSharedConfigMap() map[string]*sharev1alpha1.SharedConfigMap {
ret := map[string]*sharev1alpha1.SharedConfigMap{}
if singleton.SharedSecrets != nil {
list, err := singleton.SharedConfigMaps.List(labels.Everything())
if err == nil {
for _, scm := range list {
ret[scm.Name] = scm
}
}
}
if shareClient != nil && len(ret) == 0 {
list, err := shareClient.SharedresourceV1alpha1().SharedConfigMaps().List(context.TODO(), metav1.ListOptions{})
if err == nil {
for _, scm := range list.Items {
ret[scm.Name] = &scm
}
}
}
return ret
}
3 changes: 0 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ const DefaultResyncDuration = 10 * time.Minute
type Config struct {
// ShareRelistInterval interval to relist all "Share" object instances.
ShareRelistInterval string `yaml:"shareRelistInterval,omitempty"`
// IgnoredNamespaces namespace names ignored by this controller.
IgnoredNamespaces []string `yaml:"ignoredNamespaces,omitempty"`
// RefreshResources toggles actively watching for resources, when disabled it will only read
// resources before mount.
RefreshResources bool `yaml:"refreshResources,omitempty"`
Expand All @@ -36,7 +34,6 @@ func (c *Config) GetShareRelistInterval() time.Duration {
func NewConfig() Config {
return Config{
ShareRelistInterval: DefaultResyncDuration.String(),
IgnoredNamespaces: []string{},
RefreshResources: true,
}
}
1 change: 0 additions & 1 deletion pkg/config/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func TestConfig_LocalConfigFile(t *testing.T) {
expectedCfg := NewConfig()
expectedCfg.RefreshResources = false
expectedCfg.ShareRelistInterval = "20m"
expectedCfg.IgnoredNamespaces = []string{"namespace-a", "namespace-b", "namespace-c"}
if !reflect.DeepEqual(&expectedCfg, cfg) {
t.Fatalf("configuration instance '%#v', is not equal to excepted", cfg)
}
Expand Down

0 comments on commit f96ba31

Please sign in to comment.