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
16 changes: 16 additions & 0 deletions install/0000_50_cluster-update-console-plugin_10_namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Namespace
metadata:
name: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
workload.openshift.io/allowed: management
labels:
openshift.io/cluster-monitoring: "true"
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: cluster-update-console-plugin
namespace: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: This NetworkPolicy is used to deny all ingress and egress traffic by default in this namespace, matching all Pods, and serving as a baseline.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Comment on lines +12 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail

printf '\n## File list\n'
git ls-files install/0000_50_cluster-update-console-plugin_20_networkpolicy.yaml install/0000_50_cluster-update-console-plugin_90_consoleplugin.yaml

printf '\n## NetworkPolicy file\n'
cat -n install/0000_50_cluster-update-console-plugin_20_networkpolicy.yaml

printf '\n## ConsolePlugin file\n'
cat -n install/0000_50_cluster-update-console-plugin_90_consoleplugin.yaml

printf '\n## Related NetworkPolicies under install\n'
fd -a '.*networkpolicy.*\.ya?ml$' install

printf '\n## Search for network policy and console plugin references\n'
rg -n --hidden --glob 'install/**' -e 'kind: NetworkPolicy|kind: ConsolePlugin|namespaceSelector|podSelector|policyTypes|ingress:|egress:' install

Repository: openshift/cluster-version-operator

Length of output: 2985


🏁 Script executed:

set -euo pipefail
echo hi

Repository: openshift/cluster-version-operator

Length of output: 175


🏁 Script executed:

set -euo pipefail

echo '--- networkpolicy file ---'
cat -n install/0000_50_cluster-update-console-plugin_20_networkpolicy.yaml

echo '--- consoleplugin file ---'
cat -n install/0000_50_cluster-update-console-plugin_90_consoleplugin.yaml

echo '--- install networkpolicy files ---'
fd -a '.*networkpolicy.*\.ya?ml$' install

echo '--- relevant references ---'
rg -n --hidden --glob 'install/**' -e 'kind: NetworkPolicy|kind: ConsolePlugin|namespaceSelector|podSelector|policyTypes|ingress:|egress:' install

Repository: openshift/cluster-version-operator

Length of output: 2805


🏁 Script executed:

pwd

Repository: openshift/cluster-version-operator

Length of output: 191


🌐 Web query:

OpenShift ConsolePlugin backend service network policy source ingress router namespace

💡 Result:

To configure network policies for an OpenShift ConsolePlugin, you must account for the traffic flow initiated by the OpenShift web console backend. The console backend proxies requests to your plugin service and, if configured, to additional in-cluster services via the ConsolePlugin service proxy [1][2][3]. Key points for network policy configuration: 1. Console Backend to Plugin Service: The OpenShift console backend initiates connections to your plugin's service (specified in spec.backend.service) to fetch assets and extension manifests [4][5][6]. Your network policy in the plugin's namespace must allow ingress traffic from the namespace where the OpenShift console is running (typically the openshift-console namespace) to the plugin service's port [4][7]. 2. Service Proxy Traffic: If your plugin uses the ConsolePlugin service proxy feature (spec.proxy) to communicate with other in-cluster services, the console backend acts as the proxy [1][2][3]. Requests to these services originate from the console backend pod, not directly from your plugin's pod [1][2]. Consequently, network policies for those target services must also allow ingress from the openshift-console namespace [1][2]. 3. Router/Ingress Considerations: ConsolePlugin backend services do not require an OpenShift Route or Ingress to be exposed to the outside world [4][5]. The console backend communicates with them over the internal cluster network using the service name and namespace [4][6]. Because the console backend uses the service CA bundle for secure communication, your plugin service must support HTTPS and be configured with a serving certificate (often via the service-ca operator) [4][7][3]. In summary, you should ensure that your network policies permit ingress to your plugin service specifically from the OpenShift console namespace [4][1]. You do not need to expose these services via a router/ingress [4]. If your plugin proxies requests to other services, verify that those target services allow ingress from the console namespace as well [1][2].

Citations:


Allow ingress from openshift-console. This namespace-wide default-deny policy has no ingress rule, so the ConsolePlugin backend service in openshift-cluster-update-console-plugin will be unreachable from the console unless another policy adds that exception.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install/0000_50_cluster-update-console-plugin_20_networkpolicy.yaml` around
lines 12 - 16, Update the NetworkPolicy containing podSelector {} and
policyTypes Ingress/Egress to add an ingress rule permitting traffic from the
openshift-console namespace. Preserve the existing default-deny behavior for all
other ingress sources and retain the current egress policy.

28 changes: 28 additions & 0 deletions install/0000_50_cluster-update-console-plugin_30_configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-update-console-plugin
namespace: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: Nginx configuration for the cluster-update console plugin.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
data:
nginx.conf: |
error_log /dev/stderr;
events {}
http {
access_log /dev/stdout;
include /etc/nginx/mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 9001 ssl;
listen [::]:9001 ssl;
ssl_certificate /var/cert/tls.crt;
ssl_certificate_key /var/cert/tls.key;
root /usr/share/nginx/html;
}
}
78 changes: 78 additions & 0 deletions install/0000_50_cluster-update-console-plugin_50_deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-update-console-plugin
namespace: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
spec:
selector:
matchLabels:
app: cluster-update-console-plugin
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 1
type: RollingUpdate
Comment on lines +16 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Prevent rollout downtime and add health probes.

With replicas omitted, this Deployment runs one pod, while maxUnavailable: 1 permits zero available pods during a rollout. It also has no readiness or liveness probes, so traffic can reach a merely-running container and a hung Nginx process will not be restarted.

Set maxUnavailable: 0 with an appropriate surge, and add HTTPS readiness/liveness probes on the named https port. Ensure the NetworkPolicy also permits the required probe traffic.

As per path instructions, Kubernetes/OpenShift manifests must define liveness and readiness probes.

Also applies to: 31-38

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install/0000_50_cluster-update-console-plugin_50_deployment.yaml` around
lines 16 - 20, Update the Deployment rollingUpdate strategy to use
maxUnavailable: 0 with an appropriate maxSurge to keep the single replica
available during rollout. Add HTTPS readiness and liveness probes targeting the
named https port, with suitable probe paths and settings. Update the associated
NetworkPolicy to allow the probe traffic.

Source: Path instructions

template:
metadata:
annotations:
target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
openshift.io/required-scc: restricted-v3
labels:
app: cluster-update-console-plugin
spec:
serviceAccountName: cluster-update-console-plugin
automountServiceAccountToken: false
containers:
- name: plugin
image: '{{index .Images "cluster-update-console-plugin"}}'
imagePullPolicy: IfNotPresent
ports:
- name: https
containerPort: 9001
resources:
requests:
cpu: 20m
memory: 50Mi
Comment on lines +38 to +41

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add CPU and memory limits.

Only resource requests are defined. Without limits, a faulty or unexpectedly busy plugin can consume unbounded node resources. Add bounded CPU and memory limits based on measured workload usage.

As per path instructions, every Kubernetes container must define CPU and memory resource limits.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install/0000_50_cluster-update-console-plugin_50_deployment.yaml` around
lines 38 - 41, Add CPU and memory limits to the container resources block
alongside the existing requests in the deployment manifest. Set bounded limit
values based on the plugin’s measured workload usage, ensuring both cpu and
memory are explicitly defined.

Source: Path instructions

securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Comment on lines +42 to +46

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant deployment file with line numbers
sed -n '1,220p' install/0000_50_cluster-update-console-plugin_50_deployment.yaml | cat -n

# Find any existing readOnlyRootFilesystem settings in the repo
rg -n "readOnlyRootFilesystem|allowPrivilegeEscalation|securityContext|volumeMounts|emptyDir|configMap|secret" install/0000_50_cluster-update-console-plugin_50_deployment.yaml install -g '!**/vendor/**' -g '!**/node_modules/**' || true

# Locate the image/build definition for this workload
rg -n "cluster-update-console-plugin|console-plugin|static content|nginx|httpd|serve" . -g '!**/vendor/**' -g '!**/node_modules/**' || true

Repository: openshift/cluster-version-operator

Length of output: 50390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show only the relevant section if the file is large
wc -l install/0000_50_cluster-update-console-plugin_50_deployment.yaml
sed -n '1,140p' install/0000_50_cluster-update-console-plugin_50_deployment.yaml | cat -n

Repository: openshift/cluster-version-operator

Length of output: 3276


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect any image/package references that might imply writable runtime paths
rg -n "cluster-update-console-plugin|console plugin|nginx|httpd|dist/|/tmp|/var/cache|/var/run|/usr/share" . -g '!**/vendor/**' -g '!**/node_modules/**' || true

Repository: openshift/cluster-version-operator

Length of output: 6593


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map nearby manifests and templates for this component
git ls-files install | rg 'cluster-update-console-plugin|console-plugin' || true

Repository: openshift/cluster-version-operator

Length of output: 632


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=install/0000_50_cluster-update-console-plugin_50_deployment.yaml
wc -l "$file"
sed -n '1,180p' "$file" | cat -n

Repository: openshift/cluster-version-operator

Length of output: 3276


Enable readOnlyRootFilesystem for this container. The existing config and cert mounts are already read-only; if the image needs scratch space, add only the required writable mounts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install/0000_50_cluster-update-console-plugin_50_deployment.yaml` around
lines 42 - 46, Update the container securityContext in the deployment manifest
to set readOnlyRootFilesystem to true. Preserve the existing read-only config
and certificate mounts, and add writable scratch mounts only if required by the
container image.

Source: Path instructions

terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /var/cert
name: cluster-update-console-plugin-cert
readOnly: true
- mountPath: /etc/nginx/nginx.conf
name: nginx-conf
readOnly: true
subPath: nginx.conf
dnsPolicy: ClusterFirst
hostUsers: false
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
operator: Exists
volumes:
- name: cluster-update-console-plugin-cert
secret:
defaultMode: 420
secretName: cluster-update-console-plugin-cert
- name: nginx-conf
configMap:
name: cluster-update-console-plugin
defaultMode: 420
20 changes: 20 additions & 0 deletions install/0000_50_cluster-update-console-plugin_60_service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: openshift-cluster-update-console-plugin
namespace: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
service.beta.openshift.io/serving-cert-secret-name: cluster-update-console-plugin-cert
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
spec:
type: ClusterIP
selector:
app: cluster-update-console-plugin
ports:
- name: https
port: 9001
targetPort: https
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: console.openshift.io/v1
kind: ConsolePlugin
metadata:
name: openshift-cluster-update-console-plugin
annotations:
kubernetes.io/description: The OpenShift cluster-update console plugin provides a web-console interface for managing ClusterVersion updates.
capability.openshift.io/name: Console
release.openshift.io/feature-set: TechPreviewNoUpgrade
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
spec:
displayName: Cluster Updates
i18n:
loadType: Preload
backend:
type: Service
service:
name: openshift-cluster-update-console-plugin
namespace: openshift-cluster-update-console-plugin
port: 9001
basePath: /
8 changes: 8 additions & 0 deletions install/image-references
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
kind: ImageStream
apiVersion: image.openshift.io/v1
spec:
tags:
- name: cluster-update-console-plugin
from:
kind: DockerImage
name: placeholder.url.oc.will.replace.this.example.org:cluster-update-console-plugin
7 changes: 7 additions & 0 deletions pkg/payload/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ func Test_cvoManifests(t *testing.T) {
config := manifestRenderConfig{
ReleaseImage: "quay.io/cvo/release:latest",
ClusterProfile: "some-profile",
Images: map[string]string{
"cluster-update-console-plugin": "quay.io/openshift/cluster-update-console-plugin:latest",
},
}

tests := []struct {
Expand Down Expand Up @@ -409,6 +412,10 @@ func Test_cvoManifests(t *testing.T) {
return nil
}

if _, fileName := filepath.Split(path); fileName == "image-references" {
return nil
}

var manifestsWithoutIncludeAnnotation []manifest.Manifest
data, err := os.ReadFile(path)
if err != nil {
Expand Down