Skip to content

Configuration Structure For Certificate Renewal (Part 1 of the certificate renewal command feature) #9780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 6, 2025

Conversation

howard-junec
Copy link
Contributor

@howard-junec howard-junec commented Jun 3, 2025

Issue #, if available:

Description of changes:
This PR includes add core configuration structures and validation for the certificate renewal command. This includes:

  • RenewalConfig structure for cluster and node configuration
  • Config file parsing and validation logic
  • Basic command framework for certificate renewal

This is part 1 of the certificate renewal feature, focusing on configuration handling. The actual certificate renewal implementation will follow in a separate PR.

The command now supports input config file
Example:

  1. Using config file: eksctl anywhere renew certificates [--config <file-path>] [--component <etcd|control-plane>]:
    user can renew certificates by:
  • eksctl anywhere renew certificates --config config.yaml (renew by the config file)
  • eksctl anywhere renew certificates --config config.yaml --component etcd (only renew etcd)
  • eksctl anywhere renew certificates --config config.yaml --component control-plane (only renew control-plane)

Example Config file:

clusterName: my-cluster

controlPlane:

  nodes:

  - 100.000.0.11

  - 100.000.0.12

  - 100.000.0.13

  os: ubuntu # rhel or bottlerocket

  sshKey: /path/to/ssh/private-key

  sshUser: ec2-user

etcd:

  nodes:

  - 100.000.0.14

  - 100.000.0.15

  - 100.000.0.16

  os: ubuntu # rhels or bottlerocket

  sshKey: /path/to/ssh/private-key

  sshUser: ec2-user

Testing (if applicable):

Documentation added/planned (if applicable):

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@eks-distro-bot
Copy link
Collaborator

Hi @howard-junec. Thanks for your PR.

I'm waiting for a aws member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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/test-infra repository.

@eks-distro-bot eks-distro-bot added needs-ok-to-test size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 3, 2025
@eks-distro-bot eks-distro-bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 5, 2025
Copy link
Member

@panktishah26 panktishah26 left a comment

Choose a reason for hiding this comment

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

Thank you for this PR. Great work!!

var renewCmd = &cobra.Command{
Use: "renew",
Short: "renew resources",
Long: "Use eksctl anywhere renew to renew resources, such as clusters",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Long: "Use eksctl anywhere renew to renew resources, such as clusters",
Long: "Use eksctl anywhere renew to renew cluster resources",

var renewCertificatesCmd = &cobra.Command{
Use: "certificates",
Short: "Renew certificates for cluster components",
Long: `Renew certificates for etcd and control plane nodes in EKS Anywhere cluster.
Copy link
Member

Choose a reason for hiding this comment

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

Let's not add these details in the command description. We should add it in our docs.

Suggested change
Long: `Renew certificates for etcd and control plane nodes in EKS Anywhere cluster.
Long: `Renew external ETCD and control plane certificates.


var renewCertificatesCmd = &cobra.Command{
Use: "certificates",
Short: "Renew certificates for cluster components",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Short: "Renew certificates for cluster components",
Short: "Renew certificates",

renewCmd.AddCommand(renewCertificatesCmd)

renewCertificatesCmd.Flags().StringVarP(&rc.configFile, "config", "f", "", "Config file containing node and SSH information")
renewCertificatesCmd.Flags().StringVarP(&rc.clusterName, "cluster-name", "n", "", "Name of the cluster to renew certificates for")
Copy link
Member

Choose a reason for hiding this comment

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

For now, can we focus on a scenario where certificates are already expired? The reason is we would have to take ssh-key for control plane and external etcd both. In this case, I would want to see if we can use the same config file as an input to avoid confusion.

renewCertificatesCmd.Flags().StringVarP(&rc.configFile, "config", "f", "", "Config file containing node and SSH information")
renewCertificatesCmd.Flags().StringVarP(&rc.clusterName, "cluster-name", "n", "", "Name of the cluster to renew certificates for")
renewCertificatesCmd.Flags().StringVarP(&rc.component, "component", "c", "", "Component to renew certificates for (etcd or control-plane). If not specified, renews both.")
renewCertificatesCmd.Flags().StringVar(&rc.sshKey, "ssh-key", "", "SSH private key file (required when using --cluster-name)")
Copy link
Member

Choose a reason for hiding this comment

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

Can we remove this to focus on already expired certificates?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For renewing already expired certificates, do we still want to keep the --component flag, or should we just rely on the config file approach and remove the options for --component etcd and --component control-plane.

Copy link
Member

Choose a reason for hiding this comment

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

let's have component flag.

return nil
}

func (rc *renewCertificatesOptions) renewCertificates(cmd *cobra.Command) error {
Copy link
Member

Choose a reason for hiding this comment

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

We would have to change below validations based on taking just a config file as an input.

cluster.Name = config.ClusterName
}

renewer, err := certificates.NewRenewer()
Copy link
Member

Choose a reason for hiding this comment

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

since these are in a different PR, can we return nil for the scope of this PR?

}

if err := validateNodeConfig(&config.ControlPlane, "control plane"); err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return err
return fmt.Errorf("validating control plane %v, err")

return fmt.Errorf("at least one control plane node is required")
}

if err := validateNodeConfig(&config.ControlPlane, "control plane"); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Let's not pass "control plane" or "etcd" as another param for error message. We can do something like below.

Copy link
Member

Choose a reason for hiding this comment

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

let's have this file when we add feature for valid certificates.

@eks-distro-bot eks-distro-bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jun 5, 2025

config, err := certificates.ParseConfig(rc.configFile)
if err != nil {
return fmt.Errorf("failed to parse config file: %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return fmt.Errorf("failed to parse config file: %v", err)
return fmt.Errorf("parsing config file: %v", err)

@panktishah26
Copy link
Member

/lgtm

if config.OS == "" {
return fmt.Errorf("OS is required")
}
if config.OS != "ubuntu" && config.OS != "rhel" && config.OS != "redhat" && config.OS != "bottlerocket" {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if we need "rhel", and can we use the OSFamily variables in our code
https://github.com/aws/eks-anywhere/blob/main/pkg/api/v1alpha1/machine_types.go#L8

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I delete the "rhel", and use the OSFamily variables.

}

if _, err := os.Stat(config.SSHKey); err != nil {
return fmt.Errorf("SSH key file: %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return fmt.Errorf("SSH key file: %v", err)
return fmt.Errorf("retrieving SSH key file information: %v", err)

renewCmd.AddCommand(renewCertificatesCmd)
renewCertificatesCmd.Flags().StringVarP(&rc.configFile, "config", "f", "", "Config file containing node and SSH information")
renewCertificatesCmd.Flags().StringVarP(&rc.component, "component", "c", "", "Component to renew certificates for (etcd or control-plane). If not specified, renews both.")
}
Copy link
Member

@2ez4szliu 2ez4szliu Jun 6, 2025

Choose a reason for hiding this comment

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

Suggested change
}
if err := renewCertificatesCmd.MarkFlagRequired("config"); err != nil {
log.Fatalf("marking config as required: %s", err)
}
}

so that we don't need to manually check if config is empty

return err
}

if rc.configFile == "" {
Copy link
Member

Choose a reason for hiding this comment

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

can be removed after we mark "config" as required

@2ez4szliu
Copy link
Member

/lgtm

@2ez4szliu
Copy link
Member

/ok-to-test

@eks-distro-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

Approval requirements bypassed by manually added approval.

This pull-request has been approved by:

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

The pull request process is described here

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

@eks-distro-bot eks-distro-bot merged commit 0fd1e05 into aws:main Jun 6, 2025
9 of 10 checks passed
Copy link

codecov bot commented Jun 6, 2025

Codecov Report

Attention: Patch coverage is 8.10811% with 68 lines in your changes missing coverage. Please review.

Project coverage is 69.76%. Comparing base (75d66e7) to head (c4233de).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
pkg/certificates/config.go 0.00% 48 Missing ⚠️
cmd/eksctl-anywhere/cmd/renewcertificates.go 16.66% 19 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (8.10%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9780      +/-   ##
==========================================
- Coverage   69.85%   69.76%   -0.10%     
==========================================
  Files         672      675       +3     
  Lines       50165    50239      +74     
==========================================
+ Hits        35045    35051       +6     
- Misses      13329    13396      +67     
- Partials     1791     1792       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm ok-to-test size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants