Skip to content
Draft
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
41 changes: 41 additions & 0 deletions apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -285,6 +286,9 @@ type WorkspaceConfig struct {
// Overrides defines configuration options for `container-overrides` and
// `pod-overrides` DevWorkspace attributes.
Overrides *OverrideConfig `json:"overrides,omitempty"`
// NetworkPolicy defines configuration options for the NetworkPolicy provisioned
// for each DevWorkspace.
NetworkPolicy *NetworkPolicyConfig `json:"networkPolicy,omitempty"`
}

type WebhookConfig struct {
Expand Down Expand Up @@ -320,6 +324,43 @@ type PersistentHomeConfig struct {
DisableInitContainer *bool `json:"disableInitContainer,omitempty"`
}

// NetworkPolicyConfig defines the NetworkPolicy the DevWorkspace Operator provisions for
// DevWorkspaces. One NetworkPolicy is created per DevWorkspace and applies to that
// workspace's pods only. The policy is owned by its DevWorkspace and is removed along
// with it.
//
// The name, labels, podSelector and policyTypes of the NetworkPolicy are controlled by
// the DevWorkspace Operator; only the ingress and egress rules are configurable.
type NetworkPolicyConfig struct {
// Enabled determines whether a NetworkPolicy is provisioned for each DevWorkspace.
// Disabled by default. Changing this field does not immediately affect existing
// DevWorkspaces: changing the DevWorkspaceOperatorConfig does not enqueue the
// DevWorkspaces it affects, so the new value is applied to a DevWorkspace the next
// time that DevWorkspace is reconciled for any reason. Restarting a workspace is not
// required. Both enabling and disabling apply to running and stopped DevWorkspaces
// alike.
Enabled *bool `json:"enabled,omitempty"`
// Ingress defines the ingress rules applied to DevWorkspace pods. If this field is not
// specified, the default ingress rules of the DevWorkspace Operator apply. On OpenShift,
// the defaults allow traffic from the operator's own namespace and from the OpenShift
// monitoring and ingress namespaces, and deny all other ingress traffic. On Kubernetes,
// the default allows all ingress traffic, since the namespace of the cluster's ingress
// controller is not known to the operator; administrators are expected to replace this
// with rules appropriate to their cluster.
// If this field is specified as an empty list, all ingress traffic to DevWorkspace pods
// is denied. If this field is specified as a non-empty list, exactly those rules apply
// and the default rules no longer apply.
// +kubebuilder:validation:Optional
Ingress []networkingv1.NetworkPolicyIngressRule `json:"ingress,omitempty"`
// Egress defines the egress rules applied to DevWorkspace pods. If this field is not
// specified, the default egress rule of the DevWorkspace Operator applies, which allows
// all egress traffic. If this field is specified as an empty list, all egress traffic
// from DevWorkspace pods is denied. If this field is specified as a non-empty list,
// exactly those rules apply and the default rule no longer applies.
// +kubebuilder:validation:Optional
Egress []networkingv1.NetworkPolicyEgressRule `json:"egress,omitempty"`
}

type Proxy struct {
// HttpProxy is the URL of the proxy for HTTP requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/. To ignore
// automatically detected proxy settings for the cluster, set this field to an empty string ("")
Expand Down
40 changes: 40 additions & 0 deletions apis/controller/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ type DevWorkspaceRoutingReconciler struct {
// +kubebuilder:rbac:groups=controller.devfile.io,resources=devworkspaceroutings/status,verbs=get;update;patch
// +kubebuilder:rbac:groups="",resources=services,verbs=*
// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=*
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=create;delete;update;patch;get;list;watch
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=*
// +kubebuidler:rbac:groups=route.openshift.io,resources=routes/status,verbs=get,list,watch
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes/custom-host,verbs=create
Expand Down
11 changes: 11 additions & 0 deletions controllers/workspace/devworkspace_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ import (
"github.com/devfile/devworkspace-operator/pkg/provision/storage"
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/networkpolicy"
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/rbac"
"github.com/go-logr/logr"
"github.com/google/uuid"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -91,6 +93,7 @@ type DevWorkspaceReconciler struct {
// +kubebuilder:rbac:groups="",resources=pods;serviceaccounts;secrets;configmaps;persistentvolumeclaims,verbs=*
// +kubebuilder:rbac:groups="",resources=namespaces;events,verbs=get;list;watch
// +kubebuilder:rbac:groups="batch",resources=jobs,verbs=get;create;list;watch;update;patch;delete
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=create;delete;update;patch;get;list;watch
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations;validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews;localsubjectaccessreviews,verbs=create
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update
Expand Down Expand Up @@ -165,6 +168,13 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
return reconcile.Result{Requeue: true}, err
}

// Sync the NetworkPolicy early, so that it follows the operator configuration for every
// workspace and not just the starting ones, and exists before any workspace pod does.
err = networkpolicy.SyncNetworkPolicy(workspace, clusterAPI)
if shouldReturn, reconcileResult, reconcileErr := r.checkDWError(workspace, err, "Error provisioning network policy", metrics.ReasonInfrastructureFailure, reqLogger, &reconcileStatus); shouldReturn {
return reconcileResult, reconcileErr
}

// Stop failed workspaces
if workspace.Status.Phase == devworkspacePhaseFailing && workspace.Spec.Started {
// If debug annotation is present, leave the deployment in place to let users
Expand Down Expand Up @@ -818,6 +828,7 @@ func (r *DevWorkspaceReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&corev1.ConfigMap{}).
Owns(&corev1.Secret{}).
Owns(&corev1.ServiceAccount{}).
Owns(&networkingv1.NetworkPolicy{}).
Watches(&corev1.Pod{}, handler.EnqueueRequestsFromMapFunc(dwRelatedPodsHandler)).
Watches(&corev1.PersistentVolumeClaim{}, handler.EnqueueRequestsFromMapFunc(r.dwPVCHandler)).
Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.runningWorkspacesHandler), automountWatcher).
Expand Down
Loading
Loading