Skip to content

Commit 20dbffb

Browse files
authored
chore: networkpolicy provisioning (#1710)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
1 parent 69738f0 commit 20dbffb

23 files changed

Lines changed: 3068 additions & 2 deletions

‎apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
2222
appsv1 "k8s.io/api/apps/v1"
2323
corev1 "k8s.io/api/core/v1"
24+
networkingv1 "k8s.io/api/networking/v1"
2425
"k8s.io/apimachinery/pkg/api/resource"
2526
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2627
)
@@ -285,6 +286,9 @@ type WorkspaceConfig struct {
285286
// Overrides defines configuration options for `container-overrides` and
286287
// `pod-overrides` DevWorkspace attributes.
287288
Overrides *OverrideConfig `json:"overrides,omitempty"`
289+
// NetworkPolicy defines configuration options for the NetworkPolicy provisioned
290+
// for each DevWorkspace.
291+
NetworkPolicy *NetworkPolicyConfig `json:"networkPolicy,omitempty"`
288292
}
289293

290294
type WebhookConfig struct {
@@ -320,6 +324,43 @@ type PersistentHomeConfig struct {
320324
DisableInitContainer *bool `json:"disableInitContainer,omitempty"`
321325
}
322326

327+
// NetworkPolicyConfig defines the NetworkPolicy the DevWorkspace Operator provisions for
328+
// DevWorkspaces. One NetworkPolicy is created per DevWorkspace and applies to that
329+
// workspace's pods only. The policy is owned by its DevWorkspace and is removed along
330+
// with it.
331+
//
332+
// The name, labels, podSelector and policyTypes of the NetworkPolicy are controlled by
333+
// the DevWorkspace Operator; only the ingress and egress rules are configurable.
334+
type NetworkPolicyConfig struct {
335+
// Enabled determines whether a NetworkPolicy is provisioned for each DevWorkspace.
336+
// Disabled by default. Changing this field does not immediately affect existing
337+
// DevWorkspaces: changing the DevWorkspaceOperatorConfig does not enqueue the
338+
// DevWorkspaces it affects, so the new value is applied to a DevWorkspace the next
339+
// time that DevWorkspace is reconciled for any reason. Restarting a workspace is not
340+
// required. Both enabling and disabling apply to running and stopped DevWorkspaces
341+
// alike.
342+
Enabled *bool `json:"enabled,omitempty"`
343+
// Ingress defines the ingress rules applied to DevWorkspace pods. If this field is not
344+
// specified, the default ingress rules of the DevWorkspace Operator apply. On OpenShift,
345+
// the defaults allow traffic from the operator's own namespace and from the OpenShift
346+
// monitoring, ingress, and host-network namespaces, and deny all other ingress traffic.
347+
// On Kubernetes, the default allows all ingress traffic, since the namespace of the
348+
// cluster's ingress controller is not known to the operator; administrators are expected
349+
// to replace this with rules appropriate to their cluster.
350+
// If this field is specified as an empty list, all ingress traffic to DevWorkspace pods
351+
// is denied. If this field is specified as a non-empty list, exactly those rules apply
352+
// and the default rules no longer apply.
353+
// +kubebuilder:validation:Optional
354+
Ingress []networkingv1.NetworkPolicyIngressRule `json:"ingress,omitempty"`
355+
// Egress defines the egress rules applied to DevWorkspace pods. If this field is not
356+
// specified, the default egress rule of the DevWorkspace Operator applies, which allows
357+
// all egress traffic. If this field is specified as an empty list, all egress traffic
358+
// from DevWorkspace pods is denied. If this field is specified as a non-empty list,
359+
// exactly those rules apply and the default rule no longer applies.
360+
// +kubebuilder:validation:Optional
361+
Egress []networkingv1.NetworkPolicyEgressRule `json:"egress,omitempty"`
362+
}
363+
323364
type Proxy struct {
324365
// HttpProxy is the URL of the proxy for HTTP requests, in the format http://USERNAME:PASSWORD@SERVER:PORT/. To ignore
325366
// automatically detected proxy settings for the cluster, set this field to an empty string ("")

‎apis/controller/v1alpha1/zz_generated.deepcopy.go‎

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

‎controllers/controller/devworkspacerouting/devworkspacerouting_controller.go‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ type DevWorkspaceRoutingReconciler struct {
6666
// +kubebuilder:rbac:groups=controller.devfile.io,resources=devworkspaceroutings/status,verbs=get;update;patch
6767
// +kubebuilder:rbac:groups="",resources=services,verbs=*
6868
// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=*
69-
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=create;delete;update;patch;get;list;watch
7069
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=*
7170
// +kubebuidler:rbac:groups=route.openshift.io,resources=routes/status,verbs=get,list,watch
7271
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes/custom-host,verbs=create

‎controllers/workspace/devworkspace_controller.go‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ import (
5050
"github.com/devfile/devworkspace-operator/pkg/provision/storage"
5151
"github.com/devfile/devworkspace-operator/pkg/provision/sync"
5252
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
53+
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/networkpolicy"
5354
"github.com/devfile/devworkspace-operator/pkg/provision/workspace/rbac"
5455
"github.com/go-logr/logr"
5556
"github.com/google/uuid"
5657
appsv1 "k8s.io/api/apps/v1"
5758
batchv1 "k8s.io/api/batch/v1"
5859
corev1 "k8s.io/api/core/v1"
60+
networkingv1 "k8s.io/api/networking/v1"
5961
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
6062
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6163
"k8s.io/apimachinery/pkg/runtime"
@@ -91,6 +93,7 @@ type DevWorkspaceReconciler struct {
9193
// +kubebuilder:rbac:groups="",resources=pods;serviceaccounts;secrets;configmaps;persistentvolumeclaims,verbs=*
9294
// +kubebuilder:rbac:groups="",resources=namespaces;events,verbs=get;list;watch
9395
// +kubebuilder:rbac:groups="batch",resources=jobs,verbs=get;create;list;watch;update;patch;delete
96+
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=create;delete;update;patch;get;list;watch
9497
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations;validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete
9598
// +kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews;localsubjectaccessreviews,verbs=create
9699
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=get;list;watch;create;update
@@ -167,6 +170,13 @@ func (r *DevWorkspaceReconciler) Reconcile(ctx context.Context, req ctrl.Request
167170
return reconcile.Result{Requeue: true}, err
168171
}
169172

173+
// Sync the NetworkPolicy early, so that it follows the operator configuration for every
174+
// workspace and not just the starting ones, and exists before any workspace pod does.
175+
err = networkpolicy.SyncNetworkPolicy(workspace, clusterAPI)
176+
if shouldReturn, reconcileResult, reconcileErr := r.checkDWError(workspace, err, "Error provisioning network policy", metrics.ReasonInfrastructureFailure, reqLogger, &reconcileStatus); shouldReturn {
177+
return reconcileResult, reconcileErr
178+
}
179+
170180
// Stop failed workspaces
171181
if workspace.Status.Phase == devworkspacePhaseFailing && workspace.Spec.Started {
172182
// If debug annotation is present, leave the deployment in place to let users
@@ -820,6 +830,7 @@ func (r *DevWorkspaceReconciler) SetupWithManager(mgr ctrl.Manager) error {
820830
Owns(&corev1.ConfigMap{}).
821831
Owns(&corev1.Secret{}).
822832
Owns(&corev1.ServiceAccount{}).
833+
Owns(&networkingv1.NetworkPolicy{}).
823834
Watches(&corev1.Pod{}, handler.EnqueueRequestsFromMapFunc(dwRelatedPodsHandler)).
824835
Watches(&corev1.PersistentVolumeClaim{}, handler.EnqueueRequestsFromMapFunc(r.dwPVCHandler)).
825836
Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.runningWorkspacesHandler), automountWatcher).

0 commit comments

Comments
 (0)