Skip to content

Commit

Permalink
Feat: clusteradm get klusterlet-info (#143)
Browse files Browse the repository at this point in the history
* add get klusterlet-info command
add common utility PrintComponentsCRD for cluster-manager/klusterlet to print crd

Signed-off-by: ycyaoxdu <[email protected]>

* fix: use common utility printer.PrintComponentsCRD to replace printComponentsCRD, printer.PrintComponentsDeploy to replace printComponentsDelpoyment.

Signed-off-by: ycyaoxdu <[email protected]>
  • Loading branch information
ycyaoxdu authored Mar 15, 2022
1 parent 29969eb commit 1a74a74
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 121 deletions.
2 changes: 2 additions & 0 deletions pkg/cmd/get/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"open-cluster-management.io/clusteradm/pkg/cmd/get/cluster"
"open-cluster-management.io/clusteradm/pkg/cmd/get/clusterset"
"open-cluster-management.io/clusteradm/pkg/cmd/get/hubinfo"
"open-cluster-management.io/clusteradm/pkg/cmd/get/klusterletinfo"
"open-cluster-management.io/clusteradm/pkg/cmd/get/token"
"open-cluster-management.io/clusteradm/pkg/cmd/get/work"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
Expand All @@ -25,6 +26,7 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream
cmd.AddCommand(cluster.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(clusterset.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(hubinfo.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(klusterletinfo.NewCmd(clusteradmFlags, streams))
cmd.AddCommand(work.NewCmd(clusteradmFlags, streams))

return cmd
Expand Down
132 changes: 11 additions & 121 deletions pkg/cmd/get/hubinfo/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ package hubinfo
import (
"context"
"fmt"
"strings"

"github.com/spf13/cobra"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/kubernetes"
operatorclient "open-cluster-management.io/api/client/operator/clientset/versioned"
v1 "open-cluster-management.io/api/operator/v1"
Expand Down Expand Up @@ -52,8 +49,8 @@ func (o *Options) validate(args []string) error {
const (
clusterManagerName = "cluster-manager"
registrationOperatorNamespace = "open-cluster-management"
clusterManagerNameCRD = "clustermanagers.operator.open-cluster-management.io"

componentsNamespace = "open-cluster-management-hub"
componentNameRegistrationController = "cluster-manager-registration-controller"
componentNameRegistrationWebhook = "cluster-manager-registration-webhook"
componentNameWorkWebhook = "cluster-manager-work-webhook"
Expand Down Expand Up @@ -94,16 +91,16 @@ func (o *Options) printRegistrationOperator() error {
crdStatus := make(map[string]string)
cmgrCrd, err := o.crdClient.ApiextensionsV1().
CustomResourceDefinitions().
Get(context.TODO(), "clustermanagers.operator.open-cluster-management.io", metav1.GetOptions{})
Get(context.TODO(), clusterManagerNameCRD, metav1.GetOptions{})
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
}
if cmgrCrd != nil {
crdStatus["clustermanagers.operator.open-cluster-management.io"] = "installed"
crdStatus[clusterManagerNameCRD] = "installed"
} else {
crdStatus["clustermanagers.operator.open-cluster-management.io"] = "absent"
crdStatus[clusterManagerNameCRD] = "absent"
}

o.printer.Write(printer.LEVEL_0, "Registration Operator:\n")
Expand Down Expand Up @@ -144,133 +141,26 @@ func (o *Options) printComponents() error {
}

func (o *Options) printRegistration(cmgr *v1.ClusterManager) error {
registrationController, err := o.kubeClient.AppsV1().
Deployments(componentsNamespace).
Get(context.TODO(), componentNameRegistrationController, metav1.GetOptions{})
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
return nil
}
registrationWebhook, err := o.kubeClient.AppsV1().
Deployments(componentsNamespace).
Get(context.TODO(), componentNameRegistrationWebhook, metav1.GetOptions{})
o.printer.Write(printer.LEVEL_1, "Registration:\n")
err := printer.PrintComponentsDeploy(o.printer, o.kubeClient, cmgr.Status.RelatedResources, componentNameRegistrationController)
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
return nil
return err
}

controllerExpectedRs := int(*registrationController.Spec.Replicas)
controllerAvailableRs := registrationController.Status.AvailableReplicas
webhookExpectedRs := int(*registrationWebhook.Spec.Replicas)
webhookAvailableRs := registrationWebhook.Status.AvailableReplicas
o.printer.Write(printer.LEVEL_1, "Registration:\n")
o.printer.Write(printer.LEVEL_2, "Controller:\t(%d/%d) %s\n", controllerAvailableRs, controllerExpectedRs, getImageName(registrationController))
o.printer.Write(printer.LEVEL_2, "Webhook:\t(%d/%d) %s\n", webhookAvailableRs, webhookExpectedRs, getImageName(registrationWebhook))
return nil
return printer.PrintComponentsDeploy(o.printer, o.kubeClient, cmgr.Status.RelatedResources, componentNameRegistrationWebhook)
}

func (o *Options) printWork(cmgr *v1.ClusterManager) error {
workWebhook, err := o.kubeClient.AppsV1().
Deployments(componentsNamespace).
Get(context.TODO(), componentNameWorkWebhook, metav1.GetOptions{})
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
return nil
}

webhookExpectedRs := int(*workWebhook.Spec.Replicas)
webhookAvailableRs := workWebhook.Status.AvailableReplicas
o.printer.Write(printer.LEVEL_1, "Work:\n")
o.printer.Write(printer.LEVEL_2, "Webhook:\t(%d/%d) %s\n", webhookAvailableRs, webhookExpectedRs, getImageName(workWebhook))
return nil
return printer.PrintComponentsDeploy(o.printer, o.kubeClient, cmgr.Status.RelatedResources, componentNameWorkWebhook)
}

func (o *Options) printPlacement(cmgr *v1.ClusterManager) error {
placementController, err := o.kubeClient.AppsV1().
Deployments(componentsNamespace).
Get(context.TODO(), componentNamePlacementController, metav1.GetOptions{})
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
return nil
}
controllerExpectedRs := int(*placementController.Spec.Replicas)
controllerAvailableRs := placementController.Status.AvailableReplicas
o.printer.Write(printer.LEVEL_1, "Placement:\n")
o.printer.Write(printer.LEVEL_2, "Controller:\t(%d/%d) %s\n", controllerAvailableRs, controllerExpectedRs, getImageName(placementController))
return nil
return printer.PrintComponentsDeploy(o.printer, o.kubeClient, cmgr.Status.RelatedResources, componentNamePlacementController)
}

func (o *Options) printComponentsCRD(cmgr *v1.ClusterManager) error {
testingCRDNames := sets.NewString()
for _, rs := range cmgr.Status.RelatedResources {
if rs.Resource == "customresourcedefinitions" {
testingCRDNames.Insert(rs.Name)
}
}
crdList, err := o.crdClient.ApiextensionsV1().
CustomResourceDefinitions().
List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
statuses := make(map[string]string)
existingCRDNames := sets.NewString()
crdVersions := make(map[string][]string)
crdStorageVersion := make(map[string]string)
for _, existingCRD := range crdList.Items {
existingCRDNames.Insert(existingCRD.Name)
crdVersions[existingCRD.Name] = existingCRD.Status.StoredVersions
servingVersions := sets.NewString()
for _, v := range existingCRD.Spec.Versions {
if v.Served {
servingVersions.Insert(v.Name)
}
if v.Storage {
crdStorageVersion[existingCRD.Name] = v.Name
}
crdVersions[existingCRD.Name] = servingVersions.List()
}
}
for _, name := range testingCRDNames.List() {
st := "absent"
if existingCRDNames.Has(name) {
st = "installed"
}
statuses[name] = st
}
o.printer.Write(printer.LEVEL_1, "CustomResourceDefinition:\n")
for name, st := range statuses {
versionStr := formatCRDVersion(crdVersions, crdStorageVersion, name)
o.printer.Write(printer.LEVEL_2, "(%s) %s [%s]\n", st, name, versionStr)
}
return nil
}

func getImageName(deploy *appsv1.Deployment) string {
imageName := "<none>"
for _, container := range deploy.Spec.Template.Spec.Containers {
imageName = container.Image
}
return imageName
}

func formatCRDVersion(allServingVersions map[string][]string, storageVersion map[string]string, crdName string) string {
servings := allServingVersions[crdName]
storage := storageVersion[crdName]
outputVersions := sets.NewString()
for _, v := range servings {
if v == storage {
v = "*" + v
}
outputVersions.Insert(v)
}
return strings.Join(outputVersions.List(), "|")
return printer.PrintComponentsCRD(o.printer, o.crdClient, cmgr.Status.RelatedResources)
}
47 changes: 47 additions & 0 deletions pkg/cmd/get/klusterletinfo/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright Contributors to the Open Cluster Management project
package klusterletinfo

import (
"fmt"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
clusteradmhelpers "open-cluster-management.io/clusteradm/pkg/helpers"
)

var example = `
# Get klusterlet-info.
%[1]s get klusterlet-info
`

// NewCmd...
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
o := newOptions(clusteradmFlags, streams)

cmd := &cobra.Command{
Use: "klusterlet-info",
Short: "get klusterlet-info",
Example: fmt.Sprintf(example, clusteradmhelpers.GetExampleHeader()),
SilenceUsage: true,
PreRunE: func(c *cobra.Command, args []string) error {
clusteradmhelpers.DryRunMessage(clusteradmFlags.DryRun)
return nil
},
RunE: func(c *cobra.Command, args []string) error {
if err := o.complete(c, args); err != nil {
return err
}
if err := o.validate(args); err != nil {
return err
}
if err := o.run(); err != nil {
return err
}

return nil
},
}

return cmd
}
Loading

0 comments on commit 1a74a74

Please sign in to comment.