Skip to content

Commit

Permalink
OCM-7265 | feat: Added the ability to edit KubeletConfigs for HCP clu…
Browse files Browse the repository at this point in the history
…sters
  • Loading branch information
robpblake committed May 13, 2024
1 parent f41b67d commit 3eccd47
Show file tree
Hide file tree
Showing 12 changed files with 403 additions and 84 deletions.
5 changes: 2 additions & 3 deletions cmd/create/kubeletconfig/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func CreateKubeletConfigRunner(options *KubeletConfigOptions) rosa.CommandRunner

if !cluster.Hypershift().Enabled() {
// Classic clusters can only have a single KubeletConfig
kubeletConfig, err := r.OCMClient.GetClusterKubeletConfig(cluster.ID())
kubeletConfig, _, err := r.OCMClient.GetClusterKubeletConfig(cluster.ID())
if err != nil {
return fmt.Errorf("Failed getting KubeletConfig for cluster '%s': %s",
r.ClusterKey, err)
Expand All @@ -84,7 +84,7 @@ func CreateKubeletConfigRunner(options *KubeletConfigOptions) rosa.CommandRunner
}
}

name, err := ValidateOrPromptForName(options.Name)
name, err := PromptForName(options.Name)
if err != nil {
return nil
}
Expand Down Expand Up @@ -115,7 +115,6 @@ func CreateKubeletConfigRunner(options *KubeletConfigOptions) rosa.CommandRunner
clusterKey, err)
}
r.Reporter.Infof("Successfully created KubeletConfig for cluster '%s'", clusterKey)

return nil
}
}
4 changes: 2 additions & 2 deletions cmd/describe/kubeletconfig/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ func run(_ *cobra.Command, _ []string) {
cluster := r.FetchCluster()

r.Reporter.Debugf("Loading KubeletConfig for cluster '%s'", clusterKey)
kubeletConfig, err := r.OCMClient.GetClusterKubeletConfig(cluster.ID())
kubeletConfig, exists, err := r.OCMClient.GetClusterKubeletConfig(cluster.ID())
if err != nil {
r.Reporter.Errorf("%v", err)
os.Exit(1)
}

if kubeletConfig == nil {
if !exists {
r.Reporter.Infof("No custom KubeletConfig exists for cluster '%s'", clusterKey)
os.Exit(0)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/edit/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func init() {
Cmd.AddCommand(service.Cmd)
Cmd.AddCommand(tuningconfigs.Cmd)
Cmd.AddCommand(autoscaler.Cmd)
Cmd.AddCommand(kubeletconfig.Cmd)
kubeletConfig := kubeletconfig.NewEditKubeletConfigCommand()
Cmd.AddCommand(kubeletConfig)

flags := Cmd.PersistentFlags()
arguments.AddProfileFlag(flags)
Expand All @@ -59,7 +60,7 @@ func init() {
globallyAvailableCommands := []*cobra.Command{
autoscaler.Cmd, addon.Cmd,
service.Cmd, cluster.Cmd,
ingress.Cmd, kubeletconfig.Cmd,
ingress.Cmd, kubeletConfig,
machinepool.Cmd, tuningconfigs.Cmd,
}
arguments.MarkRegionDeprecated(Cmd, globallyAvailableCommands)
Expand Down
143 changes: 79 additions & 64 deletions cmd/edit/kubeletconfig/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ limitations under the License.
package kubeletconfig

import (
"context"
"fmt"
"os"

cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/spf13/cobra"
Expand All @@ -30,89 +30,104 @@ import (
"github.com/openshift/rosa/pkg/rosa"
)

var Cmd = &cobra.Command{
Use: "kubeletconfig",
Aliases: []string{"kubelet-config"},
Short: "Edit the custom kubeletconfig for a cluster",
Long: "Edit the custom kubeletconfig for a cluster.",
Example: ` # Edit a custom kubeletconfig to have a pod-pids-limit of 10000
const (
use = "kubeletconfig"
short = "Edit a kubeletconfig for a cluster"
long = short
example = ` # Edit a KubeletConfig to have a pod-pids-limit of 10000
rosa edit kubeletconfig --cluster=mycluster --pod-pids-limit=10000
`,
Run: run,
Args: cobra.NoArgs,
}
# Edit a KubeletConfig named 'bar' to have a pod-pids-limit of 10000
rosa edit kubeletconfig --cluster=mycluster --name=bar --pod-pids-limit=10000
`
kubeletNotExistingMessage = "The specified KubeletConfig does not exist for cluster '%s'." +
" You should first create it via 'rosa create kubeletconfig'"
)

var args struct {
podPidsLimit int
}
var aliases = []string{"kubelet-config"}

func NewEditKubeletConfigCommand() *cobra.Command {

options := NewKubeletConfigOptions()
cmd := &cobra.Command{
Use: use,
Aliases: aliases,
Short: short,
Long: long,
Example: example,
Run: rosa.DefaultRunner(rosa.RuntimeWithOCM(), EditKubeletConfigRunner(options)),
Args: cobra.NoArgs,
}

func init() {
flags := Cmd.Flags()
flags := cmd.Flags()
flags.SortFlags = false

ocm.AddClusterFlag(Cmd)
ocm.AddClusterFlag(cmd)
interactive.AddFlag(flags)
options.AddFlagsToCommand(cmd)
return cmd
}

flags.IntVar(
&args.podPidsLimit,
PodPidsLimitOption,
PodPidsLimitOptionDefaultValue,
PodPidsLimitOptionUsage)
func EditKubeletConfigRunner(options *KubeletConfigOptions) rosa.CommandRunner {
return func(ctx context.Context, r *rosa.Runtime, command *cobra.Command, args []string) error {
cluster, err := r.OCMClient.GetCluster(r.GetClusterKey(), r.Creator)
if err != nil {
return err
}

}
if cluster.State() != cmv1.ClusterStateReady {
return fmt.Errorf("Cluster '%s' is not yet ready. Current state is '%s'", r.GetClusterKey(), cluster.State())
}

func run(_ *cobra.Command, _ []string) {
r := rosa.NewRuntime().WithOCM()
defer r.Cleanup()
var kubeletconfig *cmv1.KubeletConfig
var exists bool

clusterKey := r.GetClusterKey()
cluster := r.FetchCluster()
if cluster.Hypershift().Enabled() {
options.Name, err = PromptForName(options.Name)
if err != nil {
return err
}

if cluster.Hypershift().Enabled() {
r.Reporter.Errorf("Hosted Control Plane clusters do not support KubeletConfig configuration")
os.Exit(1)
}
options.ValidateForHypershift()
kubeletconfig, exists, err = r.OCMClient.FindKubeletConfigByName(ctx, cluster.ID(), options.Name)
} else {
kubeletconfig, exists, err = r.OCMClient.GetClusterKubeletConfig(cluster.ID())
}

if cluster.State() != cmv1.ClusterStateReady {
r.Reporter.Errorf("Cluster '%s' is not yet ready. Current state is '%s'", clusterKey, cluster.State())
os.Exit(1)
}
if err != nil {
return fmt.Errorf("Failed to fetch KubeletConfig configuration for cluster '%s': %s",
r.GetClusterKey(), err)
}

kubeletconfig, err := r.OCMClient.GetClusterKubeletConfig(cluster.ID())
if err != nil {
r.Reporter.Errorf("Failed to fetch existing KubeletConfig configuration for cluster '%s': %s",
clusterKey, err)
os.Exit(1)
}
if !exists {
return fmt.Errorf(kubeletNotExistingMessage, r.GetClusterKey())
}

if kubeletconfig == nil {
r.Reporter.Errorf("No KubeletConfig for cluster '%s' has been found. "+
"You should first create it via 'rosa create kubeletconfig'", clusterKey)
os.Exit(1)
}
requestedPids, err := ValidateOrPromptForRequestedPidsLimit(options.PodPidsLimit, r.GetClusterKey(), kubeletconfig, r)
if err != nil {
return err
}

r.Reporter.Debugf("Updating KubeletConfig for cluster '%s'", clusterKey)
if !cluster.Hypershift().Enabled() {
// Classic clusters must prompt the user as edit will cause all worker nodes to reboot
prompt := fmt.Sprintf("Updating the custom KubeletConfig for cluster '%s' will cause all non-Control Plane "+
"nodes to reboot. This may cause outages to your applications. Do you wish to continue?", r.GetClusterKey())

requestedPids, err := ValidateOrPromptForRequestedPidsLimit(args.podPidsLimit, clusterKey, kubeletconfig, r)
if err != nil {
os.Exit(1)
}
if !confirm.ConfirmRaw(prompt) {
r.Reporter.Infof("Update of custom KubeletConfig for cluster '%s' aborted.", r.GetClusterKey())
return nil
}
}

prompt := fmt.Sprintf("Updating the custom KubeletConfig for cluster '%s' will cause all non-Control Plane "+
"nodes to reboot. This may cause outages to your applications. Do you wish to continue?", clusterKey)
r.Reporter.Debugf("Updating KubeletConfig '%s' for cluster '%s'", kubeletconfig.ID(), r.GetClusterKey())
_, err = r.OCMClient.UpdateKubeletConfig(
ctx, cluster.ID(), kubeletconfig.ID(), ocm.KubeletConfigArgs{PodPidsLimit: requestedPids, Name: options.Name})

if confirm.ConfirmRaw(prompt) {
r.Reporter.Debugf("Updating KubeletConfig for cluster '%s'", clusterKey)
_, err = r.OCMClient.UpdateKubeletConfig(cluster.ID(), ocm.KubeletConfigArgs{PodPidsLimit: requestedPids})
if err != nil {
r.Reporter.Errorf("Failed creating custom KubeletConfig for cluster '%s': %s",
cluster.ID(), err)
os.Exit(1)
return fmt.Errorf("Failed to update KubeletConfig for cluster '%s': %s",
r.GetClusterKey(), err)
}

r.Reporter.Infof("Successfully updated custom KubeletConfig for cluster '%s'", clusterKey)
os.Exit(0)
r.Reporter.Infof("Successfully updated KubeletConfig for cluster '%s'", r.GetClusterKey())
return nil
}

r.Reporter.Infof("Update of custom KubeletConfig for cluster '%s' aborted.", clusterKey)
}
Loading

0 comments on commit 3eccd47

Please sign in to comment.