Skip to content
Merged
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
36 changes: 25 additions & 11 deletions worker/appm/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ type appRuntimeStore struct {
volumeTypeListenerLock sync.Mutex
resourceCache *ResourceCache
initLocks sync.Map // map[serviceID]*sync.Mutex for AppService initialization
syncImagePullSecret func(string) error
}

// NewStore new app runtime store
Expand All @@ -176,6 +177,7 @@ func NewStore(dbmanager db.Manager) Storer {
podUpdateListeners: make(map[string]chan<- *corev1.Pod, 1),
volumeTypeListeners: make(map[string]chan<- *model.TenantServiceVolumeType, 1),
}
store.syncImagePullSecret = store.createOrUpdateImagePullSecret
crdClient, err := internalclientset.NewForConfig(store.k8sClient.RestConfig)
if err != nil {
logrus.Errorf("create crd client failure %s", err.Error())
Expand Down Expand Up @@ -1850,22 +1852,34 @@ func (a *appRuntimeStore) evtEventHandler() cache.ResourceEventHandlerFuncs {

func (a *appRuntimeStore) nsEventHandler() cache.ResourceEventHandlerFuncs {
return cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
ns := obj.(*corev1.Namespace)
a.syncNamespaceImagePullSecret(ns)
},
UpdateFunc: func(old, cur interface{}) {
ns := cur.(*corev1.Namespace)
a.syncNamespaceImagePullSecret(ns)
},
}
}

// check if the namespace is created by Rainbond
if !filterOutNotRainbondNamespace(ns) {
return
}
func (a *appRuntimeStore) syncNamespaceImagePullSecret(ns *corev1.Namespace) {
// check if the namespace is created by Rainbond
if !filterOutNotRainbondNamespace(ns) {
return
}

if ns.Status.Phase == corev1.NamespaceTerminating {
return
}
if ns.Status.Phase == corev1.NamespaceTerminating {
return
}

if err := a.createOrUpdateImagePullSecret(ns.Name); err != nil {
logrus.Errorf("create or update imagepullsecret: %v", err)
}
},
syncFn := a.syncImagePullSecret
if syncFn == nil {
syncFn = a.createOrUpdateImagePullSecret
}

if err := syncFn(ns.Name); err != nil {
logrus.Errorf("create or update imagepullsecret: %v", err)
}
}

Expand Down
57 changes: 57 additions & 0 deletions worker/appm/store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/goodrain/rainbond/worker/server/pb"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestGetAppStatus(t *testing.T) {
Expand Down Expand Up @@ -108,3 +110,58 @@ func TestGetAppStatus(t *testing.T) {
})
}
}

func TestNsEventHandlerProvidesAddFunc(t *testing.T) {
handler := (&appRuntimeStore{}).nsEventHandler()
assert.NotNil(t, handler.AddFunc, "namespace add events should trigger image pull secret sync")
}

func TestNsEventHandlerSyncsManagedNamespacesOnAddAndUpdate(t *testing.T) {
var synced []string
store := &appRuntimeStore{
syncImagePullSecret: func(namespace string) error {
synced = append(synced, namespace)
return nil
},
}
handler := store.nsEventHandler()
ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{"app.kubernetes.io/managed-by": "rainbond"},
},
Status: corev1.NamespaceStatus{Phase: corev1.NamespaceActive},
}

handler.AddFunc(ns)
handler.UpdateFunc(nil, ns)

assert.Equal(t, []string{"test", "test"}, synced)
}

func TestNsEventHandlerSkipsNamespacesThatShouldNotSync(t *testing.T) {
var synced []string
store := &appRuntimeStore{
syncImagePullSecret: func(namespace string) error {
synced = append(synced, namespace)
return nil
},
}
handler := store.nsEventHandler()
unmanaged := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{Name: "external"},
Status: corev1.NamespaceStatus{Phase: corev1.NamespaceActive},
}
terminating := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{"app.kubernetes.io/managed-by": "rainbond"},
},
Status: corev1.NamespaceStatus{Phase: corev1.NamespaceTerminating},
}

handler.AddFunc(unmanaged)
handler.UpdateFunc(nil, terminating)

assert.Empty(t, synced)
}
Loading