Skip to content

Commit

Permalink
Initial implementation of deployment health
Browse files Browse the repository at this point in the history
  • Loading branch information
Alena Varkockova committed Nov 20, 2020
1 parent bfdb8e4 commit 5d55379
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 35 deletions.
23 changes: 12 additions & 11 deletions pkg/cmd/verify/verify.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package verify

import (
"context"
"fmt"
"os"

"github.com/alenkacz/cert-manager-verifier/pkg/verify"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/kubernetes"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubectl/pkg/polymorphichelpers"
"os"
)

type Options struct {
ConfigFlags *genericclioptions.ConfigFlags
Streams *genericclioptions.IOStreams
ConfigFlags *genericclioptions.ConfigFlags
Streams *genericclioptions.IOStreams
}

func NewOptions() *Options {
Expand All @@ -38,7 +35,7 @@ func NewCmd() *cobra.Command {
Long: `Cert Manager is used widely in kubernetes clusters and many things depend on it.
Unfortunately it's not so easy to know that cert-manager is installed and readiness probes are not
enough here.`,
Args: cobra.NoArgs,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return options.Execute()
},
Expand Down Expand Up @@ -66,5 +63,9 @@ func (o *Options) Execute() error {
return fmt.Errorf("unable to get kubernetes client: %v", err)
}

fmt.Printf("aaa")
}
result := verify.DeploymentReady(kubeClient, verify.DeploymentDefinitionDefault())
for _, r := range result {
fmt.Printf("%s\t%t\n", r.Name, r.Ready)
}
return nil
}
61 changes: 37 additions & 24 deletions pkg/verify/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,62 @@ package verify
import (
"context"
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/kubectl/pkg/polymorphichelpers"
)

func DeploymentReady(kubeClient *kubernetes.Clientset) error {
// TODO handle non-default namespace
// TODO make sure these names work also with helm chart installation
type DeploymentDefinition struct {
Namespace string
Names []string
}

func DeploymentDefinitionDefault() DeploymentDefinition {
// TODO make sure these Names work also with helm chart installation
// TODO make sure we support cert-manager that does not have all these deployments
deploymentReady(kubeClient, "cert-manager", "cert-manager")
caInjectorDeployment, err :=kubeClient.AppsV1().Deployments("cert-manager").Get(context.TODO(), "cert-manager-cainjector", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("error when retrieving cert-manager deployments: %v", err)
}
webhookDeployment, err :=kubeClient.AppsV1().Deployments("cert-manager").Get(context.TODO(), "cert-manager-webhook", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("error when retrieving cert-manager deployments: %v", err)
return DeploymentDefinition{
Namespace: "cert-manager",
Names: []string{"cert-manager", "cert-manager-cainjector", "cert-manager-webhook"},
}
}

type UnhealthyError struct {

type DeploymentResult struct {
Name string
Ready bool
Message string
Error error
}

func DeploymentReady(kubeClient *kubernetes.Clientset, deployments DeploymentDefinition) []DeploymentResult {
result := []DeploymentResult{}
for _, d := range deployments.Names {
// TODO add wait time and timeout
result = append(result, deploymentReady(kubeClient, d, deployments.Namespace))
}
return result
}

func deploymentReady(kubeClient *kubernetes.Clientset, name, namespace string) error {
func deploymentReady(kubeClient *kubernetes.Clientset, name, namespace string) DeploymentResult {
statusViewer := &polymorphichelpers.DeploymentStatusViewer{}
result := DeploymentResult{
Name: name,
Ready: false,
}
cmDeployment, err := kubeClient.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("error when retrieving cert-manager deployments: %v", err)
result.Error = fmt.Errorf("error when retrieving cert-manager deployments: %v", err)
return result
}
unst, err := toUnstructured(cmDeployment)
if err != nil {
return fmt.Errorf("error when converting deployment to unstructured: %v", err)
}
msg, healthy, err := statusViewer.Status(unst, 0)
if err != nil {
return fmt.Errorf("error when evaluating health of deployment: %v", err)
}
if !healthy {
return fmt.Errorf("deployment %v is marked healthy", objUnstructured.GetName()), nil
result.Error = fmt.Errorf("error when converting deployment to unstructured: %v", err)
return result
}
result.Message, result.Ready, result.Error = statusViewer.Status(unst, 0)
return result
}

func toUnstructured(obj runtime.Object) (*unstructured.Unstructured, error) {
Expand All @@ -54,4 +67,4 @@ func toUnstructured(obj runtime.Object) (*unstructured.Unstructured, error) {
return nil, err
}
return &unstructured.Unstructured{Object: unstructMap}, nil
}
}

0 comments on commit 5d55379

Please sign in to comment.