Skip to content

Commit da8145e

Browse files
committed
Reapply reverted changes from PR #954
Reapply changes from PR #954 (commits ac944d5..25d533b) that had been reverted (PR #972) The original PR was reverted due to required changes in the Che Operator. As those are now applied, the original PR can be re-applied. Signed-off-by: Angel Misevski <[email protected]>
1 parent 37810ec commit da8145e

23 files changed

+1604
-202
lines changed

controllers/workspace/devworkspace_controller.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/devfile/devworkspace-operator/pkg/provision/storage"
4040
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
4141
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
42+
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/rbac"
4243
"github.com/devfile/devworkspace-operator/pkg/timing"
4344
"github.com/go-logr/logr"
4445
"github.com/google/uuid"
@@ -85,7 +86,8 @@ type DevWorkspaceReconciler struct {
8586
// +kubebuilder:rbac:groups="batch",resources=jobs,verbs=get;create;list;watch;update;patch;delete
8687
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations;validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete
8788
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews;localsubjectaccessreviews,verbs=create
88-
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings;clusterroles;clusterrolebindings,verbs=get;list;watch;create;update
89+
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update
90+
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;delete
8991
// +kubebuilder:rbac:groups=oauth.openshift.io,resources=oauthclients,verbs=get;list;watch;create;update;patch;delete;deletecollection
9092
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create
9193
// +kubebuilder:rbac:groups=config.openshift.io,resources=proxies,verbs=get,resourceNames=cluster
@@ -286,7 +288,7 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
286288

287289
// Set finalizer on DevWorkspace if necessary
288290
// Note: we need to check the flattened workspace to see if a finalizer is needed, as plugins could require storage
289-
if storageProvisioner.NeedsStorage(&workspace.Spec.Template) {
291+
if storageProvisioner.NeedsStorage(&workspace.Spec.Template) && !coputil.HasFinalizer(clusterWorkspace, constants.StorageCleanupFinalizer) {
290292
coputil.AddFinalizer(clusterWorkspace, constants.StorageCleanupFinalizer)
291293
if err := r.Update(ctx, clusterWorkspace.DevWorkspace); err != nil {
292294
return reconcile.Result{}, err
@@ -344,9 +346,24 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
344346

345347
timing.SetTime(timingInfo, timing.ComponentsReady)
346348

347-
rbacStatus := wsprovision.SyncRBAC(workspace, clusterAPI)
348-
if rbacStatus.Err != nil || !rbacStatus.Continue {
349-
return reconcile.Result{Requeue: true}, rbacStatus.Err
349+
// Add finalizer to ensure workspace rolebinding gets cleaned up when workspace
350+
// is deleted.
351+
if !coputil.HasFinalizer(clusterWorkspace, constants.RBACCleanupFinalizer) {
352+
coputil.AddFinalizer(clusterWorkspace, constants.RBACCleanupFinalizer)
353+
if err := r.Update(ctx, clusterWorkspace.DevWorkspace); err != nil {
354+
return reconcile.Result{}, err
355+
}
356+
}
357+
if err := rbac.SyncRBAC(workspace, clusterAPI); err != nil {
358+
switch rbacErr := err.(type) {
359+
case *rbac.RetryError:
360+
reqLogger.Info(rbacErr.Error())
361+
return reconcile.Result{Requeue: true}, nil
362+
case *rbac.FailError:
363+
return r.failWorkspace(workspace, fmt.Sprintf("Error provisioning rbac: %s", rbacErr), metrics.ReasonInfrastructureFailure, reqLogger, &reconcileStatus)
364+
default:
365+
return reconcile.Result{}, err
366+
}
350367
}
351368

352369
// Step two: Create routing, and wait for routing to be ready
@@ -435,12 +452,6 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
435452
}
436453
return reconcile.Result{Requeue: serviceAcctStatus.Requeue}, serviceAcctStatus.Err
437454
}
438-
if wsprovision.NeedsServiceAccountFinalizer(&workspace.Spec.Template) {
439-
coputil.AddFinalizer(clusterWorkspace, constants.ServiceAccountCleanupFinalizer)
440-
if err := r.Update(ctx, clusterWorkspace.DevWorkspace); err != nil {
441-
return reconcile.Result{}, err
442-
}
443-
}
444455
serviceAcctName = serviceAcctStatus.ServiceAccountName
445456
reconcileStatus.setConditionTrue(dw.DevWorkspaceServiceAccountReady, "DevWorkspace serviceaccount ready")
446457
}

controllers/workspace/finalize.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
2626
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
27+
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/rbac"
2728

2829
"github.com/go-logr/logr"
2930
coputil "github.com/redhat-cop/operator-utils/pkg/util"
@@ -70,6 +71,8 @@ func (r *DevWorkspaceReconciler) finalize(ctx context.Context, log logr.Logger,
7071
return r.finalizeStorage(ctx, log, workspace, finalizeStatus)
7172
case constants.ServiceAccountCleanupFinalizer:
7273
return r.finalizeServiceAccount(ctx, log, workspace, finalizeStatus)
74+
case constants.RBACCleanupFinalizer:
75+
return r.finalizeRBAC(ctx, log, workspace, finalizeStatus)
7376
}
7477
}
7578
return reconcile.Result{}, nil
@@ -130,6 +133,46 @@ func (r *DevWorkspaceReconciler) finalizeStorage(ctx context.Context, log logr.L
130133
return reconcile.Result{}, r.Update(ctx, workspace.DevWorkspace)
131134
}
132135

136+
func (r *DevWorkspaceReconciler) finalizeRBAC(ctx context.Context, log logr.Logger, workspace *common.DevWorkspaceWithConfig, finalizeStatus *currentStatus) (reconcile.Result, error) {
137+
terminating, err := r.namespaceIsTerminating(ctx, workspace.Namespace)
138+
if err != nil {
139+
return reconcile.Result{}, err
140+
} else if terminating {
141+
// Namespace is terminating, it's redundant to update roles/rolebindings since they will be removed with the workspace
142+
log.Info("Namespace is terminating; clearing storage finalizer")
143+
coputil.RemoveFinalizer(workspace, constants.RBACCleanupFinalizer)
144+
return reconcile.Result{}, r.Update(ctx, workspace.DevWorkspace)
145+
}
146+
147+
if err := rbac.FinalizeRBAC(workspace, sync.ClusterAPI{
148+
Ctx: ctx,
149+
Client: r.Client,
150+
Scheme: r.Scheme,
151+
Logger: log,
152+
}); err != nil {
153+
switch rbacErr := err.(type) {
154+
case *rbac.RetryError:
155+
log.Info(rbacErr.Error())
156+
return reconcile.Result{Requeue: true}, nil
157+
case *rbac.FailError:
158+
if workspace.Status.Phase != dw.DevWorkspaceStatusError {
159+
// Avoid repeatedly logging error unless it's relevant
160+
log.Error(rbacErr, "Failed to finalize workspace RBAC")
161+
}
162+
finalizeStatus.phase = dw.DevWorkspaceStatusError
163+
finalizeStatus.setConditionTrue(dw.DevWorkspaceError, err.Error())
164+
return reconcile.Result{}, nil
165+
default:
166+
return reconcile.Result{}, err
167+
}
168+
}
169+
log.Info("RBAC cleanup successful; clearing finalizer")
170+
coputil.RemoveFinalizer(workspace, constants.RBACCleanupFinalizer)
171+
return reconcile.Result{}, r.Update(ctx, workspace.DevWorkspace)
172+
}
173+
174+
// Deprecated: Only required to support old workspaces that use the service account finalizer. The service account finalizer should
175+
// not be added to new workspaces.
133176
func (r *DevWorkspaceReconciler) finalizeServiceAccount(ctx context.Context, log logr.Logger, workspace *common.DevWorkspaceWithConfig, finalizeStatus *currentStatus) (reconcile.Result, error) {
134177
retry, err := wsprovision.FinalizeServiceAccount(workspace, ctx, r.NonCachingClient)
135178
if err != nil {

deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/deployment/kubernetes/combined.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/deployment/openshift/combined.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/templates/components/rbac/role.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,20 @@ rules:
200200
resources:
201201
- clusterrolebindings
202202
- clusterroles
203+
verbs:
204+
- create
205+
- get
206+
- list
207+
- update
208+
- watch
209+
- apiGroups:
210+
- rbac.authorization.k8s.io
211+
resources:
203212
- rolebindings
204213
- roles
205214
verbs:
206215
- create
216+
- delete
207217
- get
208218
- list
209219
- update

pkg/cache/cache.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package cache
1616
import (
1717
"fmt"
1818

19-
"github.com/devfile/devworkspace-operator/pkg/common"
2019
"github.com/devfile/devworkspace-operator/pkg/constants"
2120
"github.com/devfile/devworkspace-operator/pkg/infrastructure"
2221
routev1 "github.com/openshift/api/route/v1"
@@ -25,7 +24,6 @@ import (
2524
corev1 "k8s.io/api/core/v1"
2625
networkingv1 "k8s.io/api/networking/v1"
2726
rbacv1 "k8s.io/api/rbac/v1"
28-
"k8s.io/apimachinery/pkg/fields"
2927
"k8s.io/apimachinery/pkg/labels"
3028
"sigs.k8s.io/controller-runtime/pkg/cache"
3129
)
@@ -48,6 +46,10 @@ func GetCacheFunc() (cache.NewCacheFunc, error) {
4846
if err != nil {
4947
return nil, err
5048
}
49+
rbacObjectSelector, err := labels.Parse("controller.devfile.io/workspace-rbac=true")
50+
if err != nil {
51+
return nil, err
52+
}
5153

5254
selectors := cache.SelectorsByObject{
5355
&appsv1.Deployment{}: {
@@ -75,10 +77,10 @@ func GetCacheFunc() (cache.NewCacheFunc, error) {
7577
Label: secretObjectSelector,
7678
},
7779
&rbacv1.Role{}: {
78-
Field: fields.SelectorFromSet(fields.Set{"metadata.name": common.WorkspaceRoleName()}),
80+
Label: rbacObjectSelector,
7981
},
8082
&rbacv1.RoleBinding{}: {
81-
Field: fields.SelectorFromSet(fields.Set{"metadata.name": common.WorkspaceRolebindingName()}),
83+
Label: rbacObjectSelector,
8284
},
8385
}
8486

pkg/common/naming.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,45 @@ func MetadataConfigMapName(workspaceId string) string {
119119
// can potentially push the name over the 63 character limit (if the original
120120
// object has a long name)
121121
func AutoMountConfigMapVolumeName(volumeName string) string {
122-
return fmt.Sprintf("%s", volumeName)
122+
return volumeName
123123
}
124124

125125
func AutoMountSecretVolumeName(volumeName string) string {
126-
return fmt.Sprintf("%s", volumeName)
126+
return volumeName
127127
}
128128

129129
func AutoMountPVCVolumeName(pvcName string) string {
130-
return fmt.Sprintf("%s", pvcName)
130+
return pvcName
131131
}
132132

133133
func WorkspaceRoleName() string {
134-
return "workspace"
134+
return "devworkspace-default-role"
135135
}
136136

137137
func WorkspaceRolebindingName() string {
138+
return "devworkspace-default-rolebinding"
139+
}
140+
141+
func WorkspaceSCCRoleName(sccName string) string {
142+
return fmt.Sprintf("devworkspace-use-%s", sccName)
143+
}
144+
145+
func WorkspaceSCCRolebindingName(sccName string) string {
146+
return fmt.Sprintf("devworkspace-use-%s", sccName)
147+
}
148+
149+
// OldWorkspaceRoleName returns the name used for the workspace serviceaccount role
150+
//
151+
// Deprecated: use WorkspaceRoleName() instead.
152+
// TODO: remove for DevWorkspace Operator v0.19
153+
func OldWorkspaceRoleName() string {
154+
return "workspace"
155+
}
156+
157+
// OldWorkspaceRolebindingName returns the name used for the workspace serviceaccount rolebinding
158+
//
159+
// Deprecated: use WorkspaceRoleBindingName() instead.
160+
// TODO: remove for DevWorkspace Operator v0.19
161+
func OldWorkspaceRolebindingName() string {
138162
return constants.ServiceAccount + "dw"
139163
}

0 commit comments

Comments
 (0)