Skip to content

Commit

Permalink
feat: add support for v1alpha1 resources
Browse files Browse the repository at this point in the history
Signed-off-by: maanugh <[email protected]>
  • Loading branch information
maanugh committed Nov 21, 2024
1 parent 631fde0 commit 22ed067
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 42 deletions.
225 changes: 191 additions & 34 deletions pkg/cmd/describe/describe_rollout.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ import (

kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
rolloutsv1beta1 "github.com/openkruise/kruise-rollout-api/client/clientset/versioned"
rolloutsapi "github.com/openkruise/kruise-rollout-api/client/clientset/versioned"
rolloutv1alpha1types "github.com/openkruise/kruise-rollout-api/client/clientset/versioned/typed/rollouts/v1alpha1"
rolloutsv1beta1types "github.com/openkruise/kruise-rollout-api/client/clientset/versioned/typed/rollouts/v1beta1"
rolloutsapi "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
rolloutsapiv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
rolloutsapiv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
internalapi "github.com/openkruise/kruise-tools/pkg/api"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -66,15 +68,16 @@ var (

type DescribeRolloutOptions struct {
genericclioptions.IOStreams
Builder func() *resource.Builder
Namespace string
EnforceNamespace bool
Resources []string
RolloutViewerFn func(runtime.Object) (*rolloutsapi.Rollout, error)
Watch bool
NoColor bool
TimeoutSeconds int
RolloutsClient rolloutsv1beta1types.RolloutInterface
Builder func() *resource.Builder
Namespace string
EnforceNamespace bool
Resources []string
RolloutViewerFn func(runtime.Object) (interface{}, error)
Watch bool
NoColor bool
TimeoutSeconds int
RolloutsV1beta1Client rolloutsv1beta1types.RolloutInterface
RolloutsV1alpha1Client rolloutv1alpha1types.RolloutInterface
}

type WorkloadInfo struct {
Expand Down Expand Up @@ -151,11 +154,13 @@ func (o *DescribeRolloutOptions) Complete(f cmdutil.Factory, args []string) erro
return err
}

rolloutsClientset, err := rolloutsv1beta1.NewForConfig(config)
rolloutsClientset, err := rolloutsapi.NewForConfig(config)
if err != nil {
return err
}
o.RolloutsClient = rolloutsClientset.RolloutsV1beta1().Rollouts(o.Namespace)
o.RolloutsV1beta1Client = rolloutsClientset.RolloutsV1beta1().Rollouts(o.Namespace)

o.RolloutsV1alpha1Client = rolloutsClientset.RolloutsV1alpha1().Rollouts(o.Namespace)

return nil
}
Expand Down Expand Up @@ -207,9 +212,20 @@ func (o *DescribeRolloutOptions) watchRollout(r *resource.Result) error {
}
info := infos[0]

watcher, err := o.RolloutsClient.Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + info.Name,
})
var watcher watch.Interface

switch info.Object.(type) {
case *rolloutsapiv1beta1.Rollout:
watcher, err = o.RolloutsV1beta1Client.Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + info.Name,
})
case *rolloutsapiv1alpha1.Rollout:
watcher, err = o.RolloutsV1alpha1Client.Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + info.Name,
})
default:
return fmt.Errorf("unsupported rollout type %T", info.Object)
}

if err != nil {
return err
Expand All @@ -235,23 +251,49 @@ func (o *DescribeRolloutOptions) watchRolloutUpdates(ctx context.Context, watche
return nil
}
if event.Type == watch.Added || event.Type == watch.Modified {
if rollout, ok := event.Object.(*rolloutsapi.Rollout); ok {
o.clearScreen()
o.printRolloutInfo(rollout)
var rollout interface{}
switch obj := event.Object.(type) {
case *rolloutsapiv1beta1.Rollout:
rollout = obj
case *rolloutsapiv1alpha1.Rollout:
rollout = obj
default:
continue
}
o.clearScreen()
o.printRolloutInfo(rollout)
}
case <-ctx.Done():
return ctx.Err()
}
}
}

func (o *DescribeRolloutOptions) printRolloutInfo(rollout interface{}) {
switch r := rollout.(type) {
case *rolloutsapiv1beta1.Rollout:
o.printRolloutV1BetaInfo(r)
case *rolloutsapiv1alpha1.Rollout:
o.printRolloutV1AlphaInfo(r)
default:
fmt.Fprintf(o.Out, "Unsupported rollout type: %T\n", rollout)
}
}

func (o *DescribeRolloutOptions) clearScreen() {
fmt.Fprint(o.Out, "\033[2J\033[H")
}

func (o *DescribeRolloutOptions) GetResources(rollout *rolloutsapi.Rollout) (*WorkloadInfo, error) {
resources := []string{rollout.Spec.WorkloadRef.Kind + "/" + rollout.Spec.WorkloadRef.Name}
type RolloutWorkloadRef struct {
Kind string
Name string
StableRevision string
CanaryRevision string
PodTemplateHash string
}

func (o *DescribeRolloutOptions) GetResources(rollout RolloutWorkloadRef) (*WorkloadInfo, error) {
resources := []string{rollout.Kind + "/" + rollout.Name}
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
Expand Down Expand Up @@ -319,8 +361,8 @@ func (o *DescribeRolloutOptions) GetResources(rollout *rolloutsapi.Rollout) (*Wo
return nil, fmt.Errorf("unsupported workload kind %T", obj)
}

workloadInfo.CurrentRevision = rollout.Status.CanaryStatus.StableRevision
workloadInfo.UpdateRevision = rollout.Status.CanaryStatus.CanaryRevision
workloadInfo.CurrentRevision = rollout.StableRevision
workloadInfo.UpdateRevision = rollout.CanaryRevision

var labelSelectorParam string
switch obj.(type) {
Expand All @@ -330,9 +372,9 @@ func (o *DescribeRolloutOptions) GetResources(rollout *rolloutsapi.Rollout) (*Wo
labelSelectorParam = "controller-revision-hash"
}

SelectorParam := rollout.Status.CanaryStatus.PodTemplateHash
SelectorParam := rollout.PodTemplateHash
if SelectorParam == "" {
SelectorParam = rollout.Status.CanaryStatus.StableRevision
SelectorParam = rollout.StableRevision
}

// Fetch pods
Expand Down Expand Up @@ -435,20 +477,20 @@ func (o *DescribeRolloutOptions) colorizeIcon(phase string) string {
return ""
}
switch phase {
case string(rolloutsapi.RolloutPhaseHealthy), string(corev1.PodRunning):
case string(rolloutsapiv1beta1.RolloutPhaseHealthy), string(corev1.PodRunning):
return "\033[32m✔\033[0m"
case string(rolloutsapi.RolloutPhaseProgressing), string(corev1.PodPending):
case string(rolloutsapiv1beta1.RolloutPhaseProgressing), string(corev1.PodPending):
return "\033[33m⚠\033[0m"
case string(rolloutsapi.RolloutPhaseDisabled), string(corev1.PodUnknown), string(rolloutsapi.RolloutPhaseTerminating), string(rolloutsapi.RolloutPhaseDisabling), string(corev1.PodFailed):
case string(rolloutsapiv1beta1.RolloutPhaseDisabled), string(corev1.PodUnknown), string(rolloutsapiv1beta1.RolloutPhaseTerminating), string(rolloutsapiv1beta1.RolloutPhaseDisabling), string(corev1.PodFailed):
return "\033[31m✘\033[0m"
case string(rolloutsapi.RolloutPhaseInitial):
case string(rolloutsapiv1beta1.RolloutPhaseInitial):
return "\033[33m⚠\033[0m"
default:
return ""
}
}

func (o *DescribeRolloutOptions) printTrafficRouting(trafficRouting []rolloutsapi.TrafficRoutingRef) {
func (o *DescribeRolloutOptions) printTrafficRouting(trafficRouting []rolloutsapiv1beta1.TrafficRoutingRef) {
fmt.Fprint(o.Out, "Traffic Routings:\n")
for _, trafficRouting := range trafficRouting {
fmt.Fprintf(o.Out, tableFormat, " - Service: ", trafficRouting.Service)
Expand All @@ -472,8 +514,116 @@ func (o *DescribeRolloutOptions) printTrafficRouting(trafficRouting []rolloutsap
}
}

func (o *DescribeRolloutOptions) printRolloutInfo(rollout *rolloutsapi.Rollout) {
// Name, Namespace, Status, Message
func (o *DescribeRolloutOptions) printRolloutV1AlphaInfo(rollout *rolloutsapiv1alpha1.Rollout) {
fmt.Fprintf(o.Out, tableFormat, "Name:", rollout.Name)
fmt.Fprintf(o.Out, tableFormat, "Namespace:", rollout.Namespace)
if rollout.Status.ObservedGeneration == rollout.GetObjectMeta().GetGeneration() {
fmt.Fprintf(o.Out, tableFormat, "Status:", o.colorizeIcon(string(rollout.Status.Phase))+" "+string(rollout.Status.Phase))

if rollout.Status.Message != "" {
fmt.Fprintf(o.Out, tableFormat, "Message:", rollout.Status.Message)
}
}

// Strategy
fmt.Fprintf(o.Out, tableFormat, "Strategy:", "Canary")

if canary := rollout.Spec.Strategy.Canary; canary != nil {
fmt.Fprintf(o.Out, tableFormat, " Step:", strconv.Itoa(int(rollout.Status.CanaryStatus.CurrentStepIndex))+"/"+strconv.Itoa(len(canary.Steps)))
fmt.Fprint(o.Out, " Steps:\n")
currentStepIndex := int(rollout.Status.CanaryStatus.CurrentStepIndex)
for i, step := range canary.Steps {
isCurrentStep := (i + 1) == currentStepIndex
if isCurrentStep {
fmt.Fprint(o.Out, "\033[32m")
}

if step.Replicas != nil {
fmt.Fprintf(o.Out, tableFormat, " - Replicas: ", step.Replicas)
}
if step.TrafficRoutingStrategy.Weight != nil {
fmt.Fprintf(o.Out, tableFormat, " Weight: ", *step.TrafficRoutingStrategy.Weight)
}

if step.Matches != nil {
fmt.Fprintln(o.Out, " Matches: ")
for _, match := range step.Matches {
fmt.Fprintln(o.Out, " - Headers: ")
for _, path := range match.Headers {
fmt.Fprintf(o.Out, tableFormat, " - Name:", path.Name)
fmt.Fprintf(o.Out, tableFormat, " Value:", path.Value)
fmt.Fprintf(o.Out, tableFormat, " Type:", *path.Type)
}
}
}

if isCurrentStep {
fmt.Fprintf(o.Out, tableFormat, " State:", rollout.Status.CanaryStatus.CurrentStepState)
fmt.Fprint(o.Out, "\033[0m") // Reset color
}
}
}

rolloutWorkload := RolloutWorkloadRef{
Kind: rollout.Spec.ObjectRef.WorkloadRef.Kind,
Name: rollout.Spec.ObjectRef.WorkloadRef.Name,
StableRevision: rollout.Status.CanaryStatus.StableRevision,
CanaryRevision: rollout.Status.CanaryStatus.CanaryRevision,
PodTemplateHash: rollout.Status.CanaryStatus.PodTemplateHash,
}

// Workload
info, err := o.GetResources(rolloutWorkload)
if err != nil {
fmt.Fprintf(o.Out, "Error getting resources: %v\n", err)
return
}

// Images
for i, image := range info.Images {
if i == 0 {
fmt.Fprintf(o.Out, tableFormat, "Images:", image)
} else {
fmt.Fprintf(o.Out, tableFormat, "", image)
}
}

// Revisions
fmt.Fprintf(o.Out, tableFormat, "Current Revision:", info.CurrentRevision)
fmt.Fprintf(o.Out, tableFormat, "Update Revision:", info.UpdateRevision)

// Replicas
if rollout.Status.ObservedGeneration == rollout.GetObjectMeta().GetGeneration() {
fmt.Fprint(o.Out, "Replicas:\n")
fmt.Fprintf(o.Out, tableFormat, " Desired:", info.Replicas.Desired)
fmt.Fprintf(o.Out, tableFormat, " Updated:", info.Replicas.Updated)
fmt.Fprintf(o.Out, tableFormat, " Current:", info.Replicas.Current)
fmt.Fprintf(o.Out, tableFormat, " Ready:", info.Replicas.Ready)
fmt.Fprintf(o.Out, tableFormat, " Available:", info.Replicas.Available)
}

if len(info.Pod) > 0 {
w := tabwriter.NewWriter(o.Out, 0, 0, 2, ' ', 0)
fmt.Fprintln(w, "NAME\tREADY\tBATCH ID\tREVISION\tAGE\tRESTARTS\tSTATUS")

for _, pod := range info.Pod {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s %s\n",
pod.Name,
pod.Ready,
pod.BatchID,
pod.Revision,
pod.Age,
pod.Restarts,
o.colorizeIcon(pod.Status),
pod.Status,
)
}
w.Flush()
}

}

func (o *DescribeRolloutOptions) printRolloutV1BetaInfo(rollout *rolloutsapiv1beta1.Rollout) {
fmt.Fprintf(o.Out, tableFormat, "Name:", rollout.Name)
fmt.Fprintf(o.Out, tableFormat, "Namespace:", rollout.Namespace)
if rollout.Status.ObservedGeneration == rollout.GetObjectMeta().GetGeneration() {
Expand Down Expand Up @@ -546,7 +696,15 @@ func (o *DescribeRolloutOptions) printRolloutInfo(rollout *rolloutsapi.Rollout)
}

// Workload
info, err := o.GetResources(rollout)
rolloutWorkload := RolloutWorkloadRef{
Kind: rollout.Spec.WorkloadRef.Kind,
Name: rollout.Spec.WorkloadRef.Name,
StableRevision: rollout.Status.CanaryStatus.StableRevision,
CanaryRevision: rollout.Status.CanaryStatus.CanaryRevision,
PodTemplateHash: rollout.Status.CanaryStatus.PodTemplateHash,
}

info, err := o.GetResources(rolloutWorkload)
if err != nil {
fmt.Fprintf(o.Out, "Error getting resources: %v\n", err)
return
Expand Down Expand Up @@ -593,5 +751,4 @@ func (o *DescribeRolloutOptions) printRolloutInfo(rollout *rolloutsapi.Rollout)
}
w.Flush()
}

}
3 changes: 1 addition & 2 deletions pkg/internal/polymorphichelpers/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package polymorphichelpers
import (
"time"

rolloutsapi "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -52,7 +51,7 @@ type StatusViewerFunc func(mapping *meta.RESTMapping) (StatusViewer, error)
// StatusViewerFn gives a way to easily override the function for unit testing if needed
var StatusViewerFn StatusViewerFunc = statusViewer

type RolloutViewerFunc func(obj runtime.Object) (*rolloutsapi.Rollout, error)
type RolloutViewerFunc func(obj runtime.Object) (interface{}, error)

var RolloutViewerFn RolloutViewerFunc = rolloutViewer

Expand Down
16 changes: 10 additions & 6 deletions pkg/internal/polymorphichelpers/rolloutviewer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ import (

"k8s.io/apimachinery/pkg/runtime"

rolloutschema "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
rolloutv1alpha1 "github.com/openkruise/kruise-rollout-api/rollouts/v1alpha1"
rolloutv1beta1 "github.com/openkruise/kruise-rollout-api/rollouts/v1beta1"
)

// statusViewer returns a StatusViewer for printing rollout status.
func rolloutViewer(obj runtime.Object) (*rolloutschema.Rollout, error) {
rollout, ok := obj.(*rolloutschema.Rollout)
if !ok {
return nil, fmt.Errorf("Object is not a rollout")
func rolloutViewer(obj runtime.Object) (interface{}, error) {
if rollout, ok := obj.(*rolloutv1beta1.Rollout); ok {
return rollout, nil
}
return rollout, nil
if rollout, ok := obj.(*rolloutv1alpha1.Rollout); ok {
return rollout, nil
}

return nil, fmt.Errorf("unknown rollout type: %T", obj)
}

0 comments on commit 22ed067

Please sign in to comment.