Skip to content

CNTRLPLANE-2678: Add fetch-etcd-certs CPO subcommand for HCPEtcdBackup - #8010

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
jparrill:CNTRLPLANE-2678
Mar 25, 2026
Merged

CNTRLPLANE-2678: Add fetch-etcd-certs CPO subcommand for HCPEtcdBackup#8010
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
jparrill:CNTRLPLANE-2678

Conversation

@jparrill

@jparrill jparrill commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a new fetch-etcd-certs subcommand to the CPO binary that fetches etcd-client-tls Secret and etcd-ca ConfigMap from an HCP namespace and writes TLS certificates to disk
  • Registers the command in CPO commandFor() (symlink dispatch) and defaultCommand() (subcommand dispatch)
  • Adds symlink in Dockerfile.dev for dev image builds
  • This subcommand will run as InitContainer 1 in the HCPEtcdBackup backup Job

This is the OCP payload component of CNTRLPLANE-2678 (HCPEtcdBackup Controller). The full controller implementation (reconciler, Job construction, NetworkPolicy, retention) will follow in subsequent PRs. This is shipped first as it affects the CPO binary in the OCP release payload.

Related PRs

Jira

  • CNTRLPLANE-2678 - HCPEtcdBackup Controller: Reconciler, Job Construction, NetworkPolicy, and Retention
  • Parent epic: CNTRLPLANE-2676 - HCPEtcdBackup CRD for OADP Integration

Test plan

  • Unit tests: 7 table-driven test cases covering happy path, missing resources, missing keys, directory creation, file permissions (0600)
  • Command structure test: validates flag registration and required flag enforcement
  • Manual test: verified against a live dev cluster — fetched real etcd TLS certs and validated with openssl
  • Build verification: go build ./etcd-backup/... ./control-plane-operator/... passes

How to test manually

# 1. Build the CPO binary
make control-plane-operator

# 2. Run against a cluster with a HostedCluster deployed
KUBECONFIG=<path-to-mgmt-kubeconfig> ./bin/control-plane-operator fetch-etcd-certs \
  --hcp-namespace=<hcp-namespace> \
  --output-dir=/tmp/etcd-certs-test

# 3. Verify the certs were written and are valid
openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout

# 4. Run unit tests
go test ./etcd-backup/... -v

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added fetch-etcd-certs CLI command (runnable from the control-plane-operator) to retrieve etcd TLS artifacts from a HostedControlPlane namespace and write them to disk with secure (0600) permissions; flags for HCP namespace, output directory, and credential resource names.
  • Tests

    • Added tests covering successful retrieval/persistence, file permissions, nested output directories, and failure cases for missing resources or required data keys.

@openshift-ci-robot

Copy link
Copy Markdown

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Mar 19, 2026
@openshift-ci-robot

openshift-ci-robot commented Mar 19, 2026

Copy link
Copy Markdown

@jparrill: This pull request references CNTRLPLANE-2678 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds a new fetch-etcd-certs subcommand to the CPO binary that fetches etcd-client-tls Secret and etcd-ca ConfigMap from an HCP namespace and writes TLS certificates to disk
  • Registers the command in CPO commandFor() (symlink dispatch) and defaultCommand() (subcommand dispatch)
  • Adds symlink in Dockerfile.dev for dev image builds
  • This subcommand will run as InitContainer 1 in the HCPEtcdBackup backup Job

This is the OCP payload component of CNTRLPLANE-2678 (HCPEtcdBackup Controller). The full controller implementation (reconciler, Job construction, NetworkPolicy, retention) will follow in subsequent PRs. This is shipped first as it affects the CPO binary in the OCP release payload.

Jira

  • CNTRLPLANE-2678 - HCPEtcdBackup Controller: Reconciler, Job Construction, NetworkPolicy, and Retention
  • Parent epic: CNTRLPLANE-2676 - HCPEtcdBackup CRD for OADP Integration

Test plan

  • Unit tests: 7 table-driven test cases covering happy path, missing resources, missing keys, directory creation, file permissions (0600)
  • Command structure test: validates flag registration and required flag enforcement
  • Manual test: verified against a live dev cluster — fetched real etcd TLS certs and validated with openssl
  • Build verification: go build ./etcd-backup/... ./control-plane-operator/... passes

How to test manually

# 1. Build the CPO binary
make control-plane-operator

# 2. Run against a cluster with a HostedCluster deployed
KUBECONFIG=<path-to-mgmt-kubeconfig> ./bin/control-plane-operator fetch-etcd-certs \
 --hcp-namespace=<hcp-namespace> \
 --output-dir=/tmp/etcd-certs-test

# 3. Verify the certs were written and are valid
openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout

# 4. Run unit tests
go test ./etcd-backup/... -v

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 19, 2026
@openshift-ci

openshift-ci Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot

openshift-ci-robot commented Mar 19, 2026

Copy link
Copy Markdown

@jparrill: This pull request references CNTRLPLANE-2678 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds a new fetch-etcd-certs subcommand to the CPO binary that fetches etcd-client-tls Secret and etcd-ca ConfigMap from an HCP namespace and writes TLS certificates to disk
  • Registers the command in CPO commandFor() (symlink dispatch) and defaultCommand() (subcommand dispatch)
  • Adds symlink in Dockerfile.dev for dev image builds
  • This subcommand will run as InitContainer 1 in the HCPEtcdBackup backup Job

This is the OCP payload component of CNTRLPLANE-2678 (HCPEtcdBackup Controller). The full controller implementation (reconciler, Job construction, NetworkPolicy, retention) will follow in subsequent PRs. This is shipped first as it affects the CPO binary in the OCP release payload.

Jira

  • CNTRLPLANE-2678 - HCPEtcdBackup Controller: Reconciler, Job Construction, NetworkPolicy, and Retention
  • Parent epic: CNTRLPLANE-2676 - HCPEtcdBackup CRD for OADP Integration

Test plan

  • Unit tests: 7 table-driven test cases covering happy path, missing resources, missing keys, directory creation, file permissions (0600)
  • Command structure test: validates flag registration and required flag enforcement
  • Manual test: verified against a live dev cluster — fetched real etcd TLS certs and validated with openssl
  • Build verification: go build ./etcd-backup/... ./control-plane-operator/... passes

How to test manually

# 1. Build the CPO binary
make control-plane-operator

# 2. Run against a cluster with a HostedCluster deployed
KUBECONFIG=<path-to-mgmt-kubeconfig> ./bin/control-plane-operator fetch-etcd-certs \
 --hcp-namespace=<hcp-namespace> \
 --output-dir=/tmp/etcd-certs-test

# 3. Verify the certs were written and are valid
openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout

# 4. Run unit tests
go test ./etcd-backup/... -v

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added do-not-merge/needs-area area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/needs-area labels Mar 19, 2026
@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This pull request adds a new fetch-etcd-certs CLI subcommand to control-plane-operator. The command builds a controller-runtime Kubernetes client, retrieves the etcd client TLS Secret and etcd CA ConfigMap from a specified HostedControlPlane namespace, validates required data keys, and writes the client certificate, client key, and CA certificate to an output directory with 0600 permissions. The Dockerfile and main command registration were updated to expose the new subcommand.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as fetch-etcd-certs CLI
    participant K8s as Kubernetes API
    participant FS as File System

    User->>CLI: Invoke with hcp-namespace, output-dir flags
    CLI->>CLI: Parse and validate flags
    CLI->>CLI: Create controller-runtime client (kubeconfig)
    CLI->>K8s: Get etcd-client Secret from namespace
    K8s-->>CLI: Return Secret with cert/key data
    CLI->>K8s: Get etcd CA ConfigMap from namespace
    K8s-->>CLI: Return ConfigMap with CA cert data
    CLI->>CLI: Validate required data keys exist
    CLI->>FS: Create output directory if needed
    FS-->>CLI: Directory created/exists
    CLI->>FS: Write client cert file (0600)
    FS-->>CLI: Cert file written
    CLI->>FS: Write client key file (0600)
    FS-->>CLI: Key file written
    CLI->>FS: Write CA cert file (0600)
    FS-->>CLI: CA cert file written
    CLI-->>User: Success logged with file paths and byte counts
Loading
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@mgencur

mgencur commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

/lgtm
/hold

Hold for other reviewers

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 19, 2026
@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Mar 19, 2026
@openshift-ci-robot

Copy link
Copy Markdown

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

@cwbotbot

cwbotbot commented Mar 19, 2026

Copy link
Copy Markdown

Test Results

e2e-aws

Failed Tests

Total failed tests: 3

  • TestNodePool
  • TestNodePool/HostedCluster2
  • TestNodePool/HostedCluster2/Teardown

e2e-aks

@openshift-ci-robot

openshift-ci-robot commented Mar 19, 2026

Copy link
Copy Markdown

@jparrill: This pull request references CNTRLPLANE-2678 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds a new fetch-etcd-certs subcommand to the CPO binary that fetches etcd-client-tls Secret and etcd-ca ConfigMap from an HCP namespace and writes TLS certificates to disk
  • Registers the command in CPO commandFor() (symlink dispatch) and defaultCommand() (subcommand dispatch)
  • Adds symlink in Dockerfile.dev for dev image builds
  • This subcommand will run as InitContainer 1 in the HCPEtcdBackup backup Job

This is the OCP payload component of CNTRLPLANE-2678 (HCPEtcdBackup Controller). The full controller implementation (reconciler, Job construction, NetworkPolicy, retention) will follow in subsequent PRs. This is shipped first as it affects the CPO binary in the OCP release payload.

Related PRs

Jira

  • CNTRLPLANE-2678 - HCPEtcdBackup Controller: Reconciler, Job Construction, NetworkPolicy, and Retention
  • Parent epic: CNTRLPLANE-2676 - HCPEtcdBackup CRD for OADP Integration

Test plan

  • Unit tests: 7 table-driven test cases covering happy path, missing resources, missing keys, directory creation, file permissions (0600)
  • Command structure test: validates flag registration and required flag enforcement
  • Manual test: verified against a live dev cluster — fetched real etcd TLS certs and validated with openssl
  • Build verification: go build ./etcd-backup/... ./control-plane-operator/... passes

How to test manually

# 1. Build the CPO binary
make control-plane-operator

# 2. Run against a cluster with a HostedCluster deployed
KUBECONFIG=<path-to-mgmt-kubeconfig> ./bin/control-plane-operator fetch-etcd-certs \
 --hcp-namespace=<hcp-namespace> \
 --output-dir=/tmp/etcd-certs-test

# 3. Verify the certs were written and are valid
openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout

# 4. Run unit tests
go test ./etcd-backup/... -v

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@jparrill

Copy link
Copy Markdown
Contributor Author

/test e2e-aws

jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 23, 2026
Adapt the etcd-backup command to work when the backup Job runs from
the HyperShift Operator namespace. Update default cert paths to
/etc/etcd-certs/ to align with the fetch-etcd-certs init container
output introduced in openshift#8010. The command focuses on executing etcdctl
snapshot save and writing the snapshot to disk.

Add new manifest functions for running etcd backup Jobs from the
HO namespace:
- EtcdBackupJob: Job manifest with HCP labels
- EtcdBackupJobServiceAccount: SA for the HO namespace
- EtcdBackupJobRole: Role in HCP namespace for etcd TLS access
- EtcdBackupJobRoleBinding: cross-namespace RoleBinding
- EtcdBackupNetworkPolicy: temporary NetworkPolicy for etcd access

Existing EtcdBackupCronJob and EtcdBackupServiceAccount are preserved
for backward compatibility.

JIRA: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 23, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 23, 2026
Adapt the etcd-backup subcommand to work when the backup Job runs from
the HO namespace, aligning default cert paths with the fetch-etcd-certs
subcommand (PR openshift#8010). Remove S3 upload logic (upload responsibility
moves to a separate etcd-upload step). Add new manifest functions for
HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount. Update vendor to remove unused AWS S3
transfermanager dependency.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 23, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
@jparrill
jparrill marked this pull request as ready for review March 23, 2026 16:46
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 23, 2026
@openshift-ci
openshift-ci Bot requested review from csrwng and enxebre March 23, 2026 16:48
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 23, 2026
… manifests

Update the etcd-backup subcommand default cert paths to align with the
fetch-etcd-certs output directory (PR openshift#8010). Add new manifest functions
for HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Comment thread etcd-backup/fetchcerts.go
type certFile struct {
name string
data []byte
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

great

Comment thread etcd-backup/fetchcerts.go
Short: "Fetch etcd TLS certificates from an HCP namespace and write them to disk",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yep!

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Mar 25, 2026
@openshift-ci-robot

Copy link
Copy Markdown

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws

@openshift-ci

openshift-ci Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jparrill, sdminonne

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot

openshift-ci-robot commented Mar 25, 2026

Copy link
Copy Markdown

@jparrill: This pull request references CNTRLPLANE-2678 which is a valid jira issue.

Details

In response to this:

Summary

  • Adds a new fetch-etcd-certs subcommand to the CPO binary that fetches etcd-client-tls Secret and etcd-ca ConfigMap from an HCP namespace and writes TLS certificates to disk
  • Registers the command in CPO commandFor() (symlink dispatch) and defaultCommand() (subcommand dispatch)
  • Adds symlink in Dockerfile.dev for dev image builds
  • This subcommand will run as InitContainer 1 in the HCPEtcdBackup backup Job

This is the OCP payload component of CNTRLPLANE-2678 (HCPEtcdBackup Controller). The full controller implementation (reconciler, Job construction, NetworkPolicy, retention) will follow in subsequent PRs. This is shipped first as it affects the CPO binary in the OCP release payload.

Related PRs

Jira

  • CNTRLPLANE-2678 - HCPEtcdBackup Controller: Reconciler, Job Construction, NetworkPolicy, and Retention
  • Parent epic: CNTRLPLANE-2676 - HCPEtcdBackup CRD for OADP Integration

Test plan

  • Unit tests: 7 table-driven test cases covering happy path, missing resources, missing keys, directory creation, file permissions (0600)
  • Command structure test: validates flag registration and required flag enforcement
  • Manual test: verified against a live dev cluster — fetched real etcd TLS certs and validated with openssl
  • Build verification: go build ./etcd-backup/... ./control-plane-operator/... passes

How to test manually

# 1. Build the CPO binary
make control-plane-operator

# 2. Run against a cluster with a HostedCluster deployed
KUBECONFIG=<path-to-mgmt-kubeconfig> ./bin/control-plane-operator fetch-etcd-certs \
 --hcp-namespace=<hcp-namespace> \
 --output-dir=/tmp/etcd-certs-test

# 3. Verify the certs were written and are valid
openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout

# 4. Run unit tests
go test ./etcd-backup/... -v

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

  • Added fetch-etcd-certs CLI command (runnable from the control-plane-operator) to retrieve etcd TLS artifacts from a HostedControlPlane namespace and write them to disk with secure (0600) permissions; flags for HCP namespace, output directory, and credential resource names.

  • Tests

  • Added tests covering successful retrieval/persistence, file permissions, nested output directories, and failure cases for missing resources or required data keys.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
etcd-backup/fetchcerts.go (1)

111-113: Use a tighter directory mode for cert/key storage

Line 111 creates the cert directory as 0755. Since this directory stores private key material, prefer 0700 unless broader traversal is explicitly required.

Proposed fix
-	if err := os.MkdirAll(opts.outputDir, 0755); err != nil {
+	if err := os.MkdirAll(opts.outputDir, 0700); err != nil {
 		return fmt.Errorf("failed to create output directory %s: %w", opts.outputDir, err)
 	}

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@etcd-backup/fetchcerts.go` around lines 111 - 113, The directory creation for
certificate storage uses os.MkdirAll(opts.outputDir, 0755), which is too
permissive for private keys; change the mode to 0700 to restrict access (update
the os.MkdirAll call that references opts.outputDir in fetchcerts.go to use
0700) so only the owner can traverse/read the cert/key directory.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@etcd-backup/fetchcerts.go`:
- Around line 43-47: The current signal.NotifyContext yields a cancel-only
context that can allow API Get calls in runFetchCerts to hang indefinitely;
update the flow to apply a deadline (context.WithTimeout) so API operations time
out: either wrap the NotifyContext result with a reasonable timeout before
calling runFetchCerts (e.g., ctx, cancel := context.WithTimeout(ctx,
<duration>)) or, inside runFetchCerts, create per-API-call contexts with
timeouts when performing the client Get calls (the methods invoking Get) so each
network/API call uses a context with deadline and is properly cancelled;
reference runFetchCerts, signal.NotifyContext, and the API Get calls to locate
where to add context.WithTimeout and ensure all derived contexts are cancelled
via defer cancel().

---

Nitpick comments:
In `@etcd-backup/fetchcerts.go`:
- Around line 111-113: The directory creation for certificate storage uses
os.MkdirAll(opts.outputDir, 0755), which is too permissive for private keys;
change the mode to 0700 to restrict access (update the os.MkdirAll call that
references opts.outputDir in fetchcerts.go to use 0700) so only the owner can
traverse/read the cert/key directory.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e0deb307-ace2-46d8-87a0-5acd7463257c

📥 Commits

Reviewing files that changed from the base of the PR and between ea9836a and 0acaf88.

📒 Files selected for processing (4)
  • Dockerfile.dev
  • control-plane-operator/main.go
  • etcd-backup/fetchcerts.go
  • etcd-backup/fetchcerts_test.go
✅ Files skipped from review due to trivial changes (3)
  • Dockerfile.dev
  • control-plane-operator/main.go
  • etcd-backup/fetchcerts_test.go

Comment thread etcd-backup/fetchcerts.go
Comment on lines +43 to +47
ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
defer cancel()

return runFetchCerts(ctx, opts)
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add a deadline to API operations to avoid hanging the init container

Line 43 creates a cancel-only context. If the API server/network stalls, the Get calls at Line 86 and Line 92 can block indefinitely and hold the backup Job.

Proposed fix
 import (
 	"context"
 	"fmt"
 	"log"
 	"os"
 	"os/signal"
 	"path/filepath"
 	"syscall"
+	"time"
@@
 		RunE: func(cmd *cobra.Command, args []string) error {
 			ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
 			defer cancel()
+			ctx, timeoutCancel := context.WithTimeout(ctx, 30*time.Second)
+			defer timeoutCancel()

 			return runFetchCerts(ctx, opts)
 		},
 	}

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

Also applies to: 86-94

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@etcd-backup/fetchcerts.go` around lines 43 - 47, The current
signal.NotifyContext yields a cancel-only context that can allow API Get calls
in runFetchCerts to hang indefinitely; update the flow to apply a deadline
(context.WithTimeout) so API operations time out: either wrap the NotifyContext
result with a reasonable timeout before calling runFetchCerts (e.g., ctx, cancel
:= context.WithTimeout(ctx, <duration>)) or, inside runFetchCerts, create
per-API-call contexts with timeouts when performing the client Get calls (the
methods invoking Get) so each network/API call uses a context with deadline and
is properly cancelled; reference runFetchCerts, signal.NotifyContext, and the
API Get calls to locate where to add context.WithTimeout and ensure all derived
contexts are cancelled via defer cancel().

@jparrill

Copy link
Copy Markdown
Contributor Author

/retest-required

@jparrill

Copy link
Copy Markdown
Contributor Author

/retest

@mgencur

mgencur commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

I just did a simple verification against the running cluster:

ᐅ make control-plane-operator

ᐅ KUBECONFIG=$KUBECONFIG control-plane-operator fetch-etcd-certs \ 
  --hcp-namespace=clusters-mgencur-hc1 \
  --output-dir=/tmp/etcd-certs-test
2026/03/25 15:11:10 wrote /tmp/etcd-certs-test/etcd-client.crt (1326 bytes)
2026/03/25 15:11:10 wrote /tmp/etcd-certs-test/etcd-client.key (1679 bytes)
2026/03/25 15:11:10 wrote /tmp/etcd-certs-test/ca.crt (1192 bytes)

ᐅ openssl x509 -in /tmp/etcd-certs-test/etcd-client.crt -noout -subject -issuer
subject=O=kubernetes, CN=etcd-client
issuer=OU=openshift, CN=etcd-signer
ᐅ openssl x509 -in /tmp/etcd-certs-test/ca.crt -noout -subject -issuer
subject=OU=openshift, CN=etcd-signer
issuer=OU=openshift, CN=etcd-signer
ᐅ openssl rsa -in /tmp/etcd-certs-test/etcd-client.key -check -noout
RSA key ok

Everything looks ok. This will be part of the bigger feature which will be verified later.

@mgencur

mgencur commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

/verified by @mgencur

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Mar 25, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@mgencur: This PR has been marked as verified by @mgencur.

Details

In response to this:

/verified by @mgencur

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@jparrill

Copy link
Copy Markdown
Contributor Author

/retest-required

@openshift-ci

openshift-ci Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

@jparrill: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 031dada into openshift:main Mar 25, 2026
29 checks passed
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 26, 2026
… manifests

Update the etcd-backup subcommand default cert paths to align with the
fetch-etcd-certs output directory (PR openshift#8010). Add new manifest functions
for HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 26, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 26, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Mar 26, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
bryan-cox pushed a commit to bryan-cox/hypershift that referenced this pull request Mar 27, 2026
… manifests

Update the etcd-backup subcommand default cert paths to align with the
fetch-etcd-certs output directory (PR openshift#8010). Add new manifest functions
for HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
bryan-cox pushed a commit to bryan-cox/hypershift that referenced this pull request Mar 27, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
mehabhalodiya pushed a commit to mehabhalodiya/hypershift that referenced this pull request Apr 13, 2026
… manifests

Update the etcd-backup subcommand default cert paths to align with the
fetch-etcd-certs output directory (PR openshift#8010). Add new manifest functions
for HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
mehabhalodiya pushed a commit to mehabhalodiya/hypershift that referenced this pull request Apr 13, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
@jparrill

jparrill commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

/jira backport release-4.21,release-4.20

@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: Missing required branches for backport chain:

  • release-4.22 OR openshift-4.22,
Details

In response to this:

/jira backport release-4.21,release-4.20

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

jparrill added a commit to jparrill/hypershift that referenced this pull request Jul 13, 2026
… manifests

Update the etcd-backup subcommand default cert paths to align with the
fetch-etcd-certs output directory (PR openshift#8010). Add new manifest functions
for HO namespace deployment: EtcdBackupJob, EtcdBackupJobServiceAccount,
EtcdBackupJobRole, EtcdBackupJobRoleBinding, EtcdBackupNetworkPolicy.
Preserve backward compatibility with existing EtcdBackupCronJob and
EtcdBackupServiceAccount.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Jul 13, 2026
…lows

Add integration tests that validate the etcd backup process against a
live management cluster. Two test scenarios are covered:

- HO namespace flow: creates cross-namespace RBAC, NetworkPolicy, and a
  Job using fetch-etcd-certs (PR openshift#8010) + etcdctl snapshot + etcdutl
  verify as a mock of the future HCPEtcdBackup controller.
- HCP namespace flow (legacy): creates a Job directly in the HCP
  namespace mounting etcd-client-tls and etcd-ca as volumes.

Both tests verify snapshot integrity via etcdutl snapshot status.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
jparrill added a commit to jparrill/hypershift that referenced this pull request Jul 13, 2026
Adjust code from PRs openshift#8010, openshift#8017, openshift#8040 to compile on release-4.21:

- etcd-upload: migrate S3TransferAPI from transfermanager v0.1 API
  (PutObject/PutObjectInput) to v0.2 API (UploadObject/UploadObjectInput)
  resolved by go mod tidy on this branch. Regenerate mock accordingly.
- etcd-backup: fix mapToTags to use url.Values for proper URL-encoding
  of S3 object tag keys/values (bug exposed by backported tests).
- go.mod/vendor: add aws-sdk-go-v2 direct dependencies (config, s3,
  transfermanager) and Azure azblob SDK required by etcd-upload, then
  run go mod tidy + go mod vendor.

Ref: CNTRLPLANE-2678

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants