Skip to content

Commit

Permalink
feat: sync Secrets, ConfigMaps and PersistentVolumesClaims to users n…
Browse files Browse the repository at this point in the history
…amespaces

Signed-off-by: Anatolii Bazko <[email protected]>
  • Loading branch information
tolusha committed Jan 15, 2024
1 parent 8dc7d82 commit 2e88480
Show file tree
Hide file tree
Showing 17 changed files with 823 additions and 505 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ genenerate-env:
| select(.name=="che-operator")
| .env[]
| select(has("value"))
| "export \(.name)=\"\(.value)\""' \
| "export \(.name)=\(.value)"' \
| sed 's|"|\\"|g' \
| sed -E 's|(.*)=(.*)|\1="\2"|g' \
> $(BASH_ENV_FILE)
echo "export WATCH_NAMESPACE=$(ECLIPSE_CHE_NAMESPACE)" >> $(BASH_ENV_FILE)
echo "[INFO] Created $(BASH_ENV_FILE)"
Expand All @@ -348,6 +350,8 @@ genenerate-env:
| .env[]
| select(has("value"))
| "\(.name)=\"\(.value)\""' \
| sed 's|"|\\"|g' \
| sed -E 's|(.*)=(.*)|\1="\2"|g' \
> $(VSCODE_ENV_FILE)
echo "WATCH_NAMESPACE=$(ECLIPSE_CHE_NAMESPACE)" >> $(VSCODE_ENV_FILE)
echo "[INFO] Created $(VSCODE_ENV_FILE)"
Expand Down
22 changes: 5 additions & 17 deletions controllers/che/checluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import (

chev2 "github.com/eclipse-che/che-operator/api/v2"
networking "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/api/errors"
)

// CheClusterReconciler reconciles a CheCluster object
Expand Down Expand Up @@ -251,16 +250,11 @@ func (r *CheClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}

// Fetch the CheCluster instance
checluster, err := r.GetCR(req)

if err != nil {
if errors.IsNotFound(err) {
r.Log.Info("CheCluster Custom Resource not found.")
// Request object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
return ctrl.Result{}, nil
}
checluster, err := deploy.FindCheClusterCRInNamespace(r.nonCachedClient, req.NamespacedName.Namespace)
if checluster == nil {
r.Log.Info("CheCluster Custom Resource not found.")
return ctrl.Result{}, nil
} else if err != nil {

Check warning on line 257 in controllers/che/checluster_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/che/checluster_controller.go#L253-L257

Added lines #L253 - L257 were not covered by tests
// Error reading the object - requeue the request.
return ctrl.Result{}, err
}
Expand Down Expand Up @@ -305,9 +299,3 @@ func (r *CheClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{Requeue: !done}, nil
}
}

func (r *CheClusterReconciler) GetCR(request ctrl.Request) (*chev2.CheCluster, error) {
checluster := &chev2.CheCluster{}
err := r.client.Get(context.TODO(), request.NamespacedName, checluster)
return checluster, err
}
15 changes: 4 additions & 11 deletions controllers/che/cheobj_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/eclipse-che/che-operator/pkg/common/constants"
"github.com/eclipse-che/che-operator/pkg/deploy"
"github.com/eclipse-che/che-operator/pkg/deploy/tls"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -29,11 +28,8 @@ func IsTrustedBundleConfigMap(cl client.Client, watchNamespace string, obj clien
return false, ctrl.Request{}
}

checluster, num, _ := deploy.FindCheClusterCRInNamespace(cl, watchNamespace)
if num != 1 {
if num > 1 {
logrus.Warn("More than one checluster Custom Resource found.")
}
checluster, _ := deploy.FindCheClusterCRInNamespace(cl, watchNamespace)
if checluster == nil {
return false, ctrl.Request{}
}

Expand Down Expand Up @@ -71,11 +67,8 @@ func IsEclipseCheRelatedObj(cl client.Client, watchNamespace string, obj client.
return false, ctrl.Request{}
}

checluster, num, _ := deploy.FindCheClusterCRInNamespace(cl, watchNamespace)
if num != 1 {
if num > 1 {
logrus.Warn("More than one checluster Custom Resource found.")
}
checluster, _ := deploy.FindCheClusterCRInNamespace(cl, watchNamespace)
if checluster == nil {
return false, ctrl.Request{}
}

Expand Down
8 changes: 8 additions & 0 deletions controllers/usernamespace/namespacecache.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ type namespaceInfo struct {
CheCluster *types.NamespacedName
}

func GetNamespaceCache(client client.Client) *namespaceCache {
return &namespaceCache{
client: client,
knownNamespaces: map[string]namespaceInfo{},
lock: sync.Mutex{},
}

Check warning on line 56 in controllers/usernamespace/namespacecache.go

View check run for this annotation

Codecov / codecov/patch

controllers/usernamespace/namespacecache.go#L51-L56

Added lines #L51 - L56 were not covered by tests
}

func NewNamespaceCache() *namespaceCache {
return &namespaceCache{
knownNamespaces: map[string]namespaceInfo{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/devfile/devworkspace-operator/pkg/infrastructure"
chev2 "github.com/eclipse-che/che-operator/api/v2"
"github.com/eclipse-che/che-operator/controllers/che"
"github.com/eclipse-che/che-operator/controllers/devworkspace"
"github.com/eclipse-che/che-operator/controllers/devworkspace/defaults"
"github.com/eclipse-che/che-operator/pkg/deploy"
projectv1 "github.com/openshift/api/project/v1"
Expand All @@ -55,27 +54,28 @@ const (
)

type CheUserNamespaceReconciler struct {
client client.Client
scheme *runtime.Scheme
namespaceCache namespaceCache
}

type eventRule struct {
check func(metav1.Object) bool
namespaces func(metav1.Object) []string
scheme *runtime.Scheme
client client.Client
nonCachedClient client.Client
namespaceCache *namespaceCache
}

var _ reconcile.Reconciler = (*CheUserNamespaceReconciler)(nil)

func NewReconciler() *CheUserNamespaceReconciler {
return &CheUserNamespaceReconciler{namespaceCache: *NewNamespaceCache()}
func NewCheUserNamespaceReconciler(
client client.Client,
noncachedClient client.Client,
scheme *runtime.Scheme,
namespaceCache *namespaceCache) *CheUserNamespaceReconciler {

return &CheUserNamespaceReconciler{
scheme: scheme,
client: client,
nonCachedClient: noncachedClient,
namespaceCache: namespaceCache}

Check warning on line 75 in controllers/usernamespace/usernamespace_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/usernamespace/usernamespace_controller.go#L69-L75

Added lines #L69 - L75 were not covered by tests
}

func (r *CheUserNamespaceReconciler) SetupWithManager(mgr ctrl.Manager) error {
r.scheme = mgr.GetScheme()
r.client = mgr.GetClient()
r.namespaceCache.client = r.client

var obj client.Object
if infrastructure.IsOpenShift() {
obj = &projectv1.Project{}
Expand All @@ -101,26 +101,6 @@ func (r *CheUserNamespaceReconciler) watchRulesForSecrets(ctx context.Context) h
}))
}

func asReconcileRequestsForNamespaces(obj metav1.Object, rules []eventRule) []reconcile.Request {
for _, r := range rules {
if r.check(obj) {
nss := r.namespaces(obj)
ret := make([]reconcile.Request, len(nss))
for i, n := range nss {
ret[i] = reconcile.Request{
NamespacedName: types.NamespacedName{
Name: n,
},
}
}

return ret
}
}

return []reconcile.Request{}
}

func (r *CheUserNamespaceReconciler) commonRules(ctx context.Context, namesInCheClusterNamespace ...string) []eventRule {
return []eventRule{
{
Expand Down Expand Up @@ -203,18 +183,18 @@ func (r *CheUserNamespaceReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, nil
}

checluster := findManagingCheCluster(*info.CheCluster)
if checluster == nil {
return ctrl.Result{Requeue: true}, nil
checluster, err := deploy.FindCheClusterCRInNamespace(r.nonCachedClient, "")
if checluster == nil || err != nil {
// CheCluster is not found or error occurred, requeue the request
return ctrl.Result{}, err

Check warning on line 189 in controllers/usernamespace/usernamespace_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/usernamespace/usernamespace_controller.go#L188-L189

Added lines #L188 - L189 were not covered by tests
}

// let's construct the deployContext to be able to use methods from v1 operator
deployContext := &chetypes.DeployContext{
CheCluster: checluster,
ClusterAPI: chetypes.ClusterAPI{
Client: r.client,
NonCachingClient: r.client,
DiscoveryClient: nil,
NonCachingClient: r.nonCachedClient,
Scheme: r.scheme,
},
}
Expand Down Expand Up @@ -257,30 +237,6 @@ func (r *CheUserNamespaceReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, nil
}

func findManagingCheCluster(key types.NamespacedName) *chev2.CheCluster {
instances := devworkspace.GetCurrentCheClusterInstances()
if len(instances) == 0 {
return nil
}

if len(instances) == 1 {
for k, v := range instances {
if key.Name == "" || (key.Name == k.Name && key.Namespace == k.Namespace) {
return &v
}
return nil
}
}

ret, ok := instances[key]

if ok {
return &ret
} else {
return nil
}
}

func (r *CheUserNamespaceReconciler) reconcileSelfSignedCert(ctx context.Context, deployContext *chetypes.DeployContext, targetNs string, checluster *chev2.CheCluster) error {
if err := deleteLegacyObject("server-cert", &corev1.Secret{}, targetNs, checluster, deployContext); err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ func setup(infraType devworkspaceinfra.Type, objs ...runtime.Object) (*runtime.S
cl := fake.NewFakeClientWithScheme(scheme, objs...)

r := &CheUserNamespaceReconciler{
client: cl,
scheme: scheme,
namespaceCache: namespaceCache{
client: cl,
nonCachedClient: cl,
scheme: scheme,
namespaceCache: &namespaceCache{
client: cl,
knownNamespaces: map[string]namespaceInfo{},
lock: sync.Mutex{},
Expand Down Expand Up @@ -214,96 +215,6 @@ func TestSkipsUnlabeledNamespaces(t *testing.T) {
})
}

func TestRequiresLabelsToMatchOneOfMultipleCheCluster(t *testing.T) {
test := func(t *testing.T, infraType devworkspaceinfra.Type, namespace metav1.Object) {
ctx := context.TODO()
scheme, cl, r := setup(infraType, namespace.(runtime.Object))
setupCheCluster(t, ctx, cl, scheme, "che1", "che")
setupCheCluster(t, ctx, cl, scheme, "che2", "che")

res, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: namespace.GetName()}})
assert.NoError(t, err, "Reconciliation should have succeeded.")

assert.True(t, res.Requeue, "The reconciliation request should have been requeued.")
}

t.Run("k8s", func(t *testing.T) {
test(t, devworkspaceinfra.Kubernetes, &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "ns",
Labels: map[string]string{
workspaceNamespaceOwnerUidLabel: "uid",
},
},
})
})

t.Run("openshift", func(t *testing.T) {
test(t, devworkspaceinfra.OpenShiftv4, &projectv1.Project{
ObjectMeta: metav1.ObjectMeta{
Name: "prj",
Labels: map[string]string{
workspaceNamespaceOwnerUidLabel: "uid",
},
},
})
})
}

func TestMatchingCheClusterCanBeSelectedUsingLabels(t *testing.T) {
test := func(t *testing.T, infraType devworkspaceinfra.Type, namespace string, objs ...runtime.Object) {
ctx := context.TODO()
scheme, cl, r := setup(infraType, objs...)
setupCheCluster(t, ctx, cl, scheme, "che1", "che")
setupCheCluster(t, ctx, cl, scheme, "che2", "che")

res, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: namespace}})
assert.NoError(t, err, "Reconciliation shouldn't have failed")

assert.False(t, res.Requeue, "The reconciliation request should have succeeded but is requesting a requeue.")
}

t.Run("k8s", func(t *testing.T) {
test(t, devworkspaceinfra.Kubernetes,
"ns",
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "ns",
Labels: map[string]string{
workspaceNamespaceOwnerUidLabel: "uid",
cheNameLabel: "che",
cheNamespaceLabel: "che1",
},
},
})
})

t.Run("openshift", func(t *testing.T) {
test(t, devworkspaceinfra.OpenShiftv4,
"ns",
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "ns",
Labels: map[string]string{
workspaceNamespaceOwnerUidLabel: "uid",
cheNameLabel: "che",
cheNamespaceLabel: "che1",
},
},
},
&projectv1.Project{
ObjectMeta: metav1.ObjectMeta{
Name: "prj",
Labels: map[string]string{
workspaceNamespaceOwnerUidLabel: "uid",
cheNameLabel: "che",
cheNamespaceLabel: "che1",
},
},
})
})
}

func TestCreatesDataInNamespace(t *testing.T) {
infrastructure.InitializeForTesting(infrastructure.Kubernetes)

Expand Down
Loading

0 comments on commit 2e88480

Please sign in to comment.