Skip to content

Commit

Permalink
[kubectl plugin] Add validate and find commands (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmed-mez committed Apr 7, 2020
1 parent 02ad133 commit c9305e2
Show file tree
Hide file tree
Showing 12 changed files with 794 additions and 18 deletions.
2 changes: 2 additions & 0 deletions cmd/kubectl-datadog/agent/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package agent

import (
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/agent/check"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/agent/find"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/agent/upgrade"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -35,6 +36,7 @@ func New(streams genericclioptions.IOStreams) *cobra.Command {

cmd.AddCommand(upgrade.New(streams))
cmd.AddCommand(check.New(streams))
cmd.AddCommand(find.New(streams))

o := newOptions(streams)
o.configFlags.AddFlags(cmd.Flags())
Expand Down
19 changes: 5 additions & 14 deletions cmd/kubectl-datadog/agent/check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,7 @@ import (
)

const (
maxParallel = 10
componentLabelKey = "agent.datadoghq.com/component"
agentLabelValue = "agent"
clcRunnerLabelValue = "cluster-checks-runner"
)

var (
agentLabel = fmt.Sprintf("%s=%s", componentLabelKey, agentLabelValue)
clcRunnerLabel = fmt.Sprintf("%s=%s", componentLabelKey, clcRunnerLabelValue)
maxParallel = 10
)

var (
Expand Down Expand Up @@ -104,7 +96,6 @@ func (o *options) complete(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("unable to instantiate restConfig: %v", err)
}
cmd.Println()
return o.Init(cmd)
}

Expand Down Expand Up @@ -135,7 +126,7 @@ func (o *options) run(cmd *cobra.Command) error {
var err error
pods, err = o.getPodsByOptions(metav1.ListOptions{
FieldSelector: fmt.Sprintf("spec.nodeName=%s", node),
LabelSelector: agentLabel,
LabelSelector: common.AgentLabel,
})
if err != nil {
return fmt.Errorf("unable to get Agent pods: %v", err)
Expand All @@ -145,13 +136,13 @@ func (o *options) run(cmd *cobra.Command) error {
default:
var err error
pods, err = o.getPodsByOptions(metav1.ListOptions{
LabelSelector: agentLabel,
LabelSelector: common.AgentLabel,
})
if err != nil {
return fmt.Errorf("unable to get Agent pods: %v", err)
}
clcPods, err := o.getPodsByOptions(metav1.ListOptions{
LabelSelector: clcRunnerLabel,
LabelSelector: common.ClcRunnerLabel,
})
if err != nil {
return fmt.Errorf("unable to get Agent pods: %v", err)
Expand Down Expand Up @@ -304,7 +295,7 @@ func findErrors(statusJSON string) ([]string, bool, error) {
}

func isCLCRunner(pod corev1.Pod) bool {
if value, found := pod.GetLabels()[componentLabelKey]; found && value == clcRunnerLabelValue {
if value, found := pod.GetLabels()[common.ComponentLabelKey]; found && value == common.ClcRunnerLabelValue {
return true
}
return false
Expand Down
115 changes: 115 additions & 0 deletions cmd/kubectl-datadog/agent/find/find.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-2020 Datadog, Inc.

package find

import (
"errors"
"fmt"

"github.com/DataDog/datadog-operator/pkg/plugin/common"

"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

var (
findExample = `
# find the datadog agent pod monitoring a pod named foo
%[1]s find foo
`
)

// options provides information required by Datadog find command
type options struct {
genericclioptions.IOStreams
common.Options
args []string
podName string
}

// newOptions provides an instance of getOptions with default values
func newOptions(streams genericclioptions.IOStreams) *options {
o := &options{
IOStreams: streams,
}
o.SetConfigFlags()
return o
}

// New provides a cobra command wrapping options for "find" sub command
func New(streams genericclioptions.IOStreams) *cobra.Command {
o := newOptions(streams)
cmd := &cobra.Command{
Use: "find [pod name] [flags]",
Short: "Find datadog agent pod monitoring a given pod",
Example: fmt.Sprintf(findExample, "kubectl datadog"),
SilenceUsage: true,
RunE: func(c *cobra.Command, args []string) error {
if err := o.complete(c, args); err != nil {
return err
}
if err := o.validate(); err != nil {
return err
}
return o.run(c)
},
}

o.ConfigFlags.AddFlags(cmd.Flags())

return cmd
}

// complete sets all information required for processing the command
func (o *options) complete(cmd *cobra.Command, args []string) error {
o.args = args
if len(args) > 0 {
o.podName = args[0]
}
return o.Init(cmd)
}

// validate ensures that all required arguments and flag values are provided
func (o *options) validate() error {
if o.podName == "" {
return errors.New("pod name argument is missing")
}
argsCount := len(o.args)
if argsCount > 1 {
return fmt.Errorf("one argument is allowed, got %d", argsCount)
}
return nil
}

// run runs the find command
func (o *options) run(cmd *cobra.Command) error {
pod, err := o.Clientset.CoreV1().Pods(o.UserNamespace).Get(o.podName, metav1.GetOptions{})
if err != nil {
return err
}
agentName, err := o.getAgentByNode(pod.Spec.NodeName)
if err != nil {
return err
}
cmd.Println(fmt.Sprintf("Agent %s is monitoring %s", agentName, o.podName))
return nil
}

// getAgentByNode returns the pod of the datadog agent running on a given node
func (o *options) getAgentByNode(nodeName string) (string, error) {
podList, err := o.Clientset.CoreV1().Pods("").List(metav1.ListOptions{
FieldSelector: fmt.Sprintf("spec.nodeName=%s", nodeName),
LabelSelector: common.AgentLabel,
})
if err != nil {
return "", err
}
if len(podList.Items) == 0 {
return "", fmt.Errorf("no agent pod found. Label selector used: %s", common.AgentLabel)
}
return podList.Items[0].Name, nil
}
2 changes: 2 additions & 0 deletions cmd/kubectl-datadog/datadog/datadog.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/clusteragent/clusteragent"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/flare"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/get"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/validate/validate"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -38,6 +39,7 @@ func NewCmd(streams genericclioptions.IOStreams) *cobra.Command {
// Operator commands
cmd.AddCommand(get.New(streams))
cmd.AddCommand(flare.New(streams))
cmd.AddCommand(validate.New(streams))

// Agent commands
cmd.AddCommand(agent.New(streams))
Expand Down
7 changes: 4 additions & 3 deletions cmd/kubectl-datadog/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package get

import (
"context"
"errors"
"fmt"
"io"

Expand All @@ -15,7 +16,7 @@ import (

"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/cli-runtime/pkg/genericclioptions"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -83,7 +84,7 @@ func (o *options) complete(cmd *cobra.Command, args []string) error {
// validate ensures that all required arguments and flag values are provided
func (o *options) validate() error {
if len(o.args) > 1 {
return fmt.Errorf("either one or no arguments are allowed")
return errors.New("either one or no arguments are allowed")
}
return nil
}
Expand All @@ -98,7 +99,7 @@ func (o *options) run() error {
} else {
dd := &v1alpha1.DatadogAgent{}
err := o.Client.Get(context.TODO(), client.ObjectKey{Namespace: o.UserNamespace, Name: o.userDatadogAgentName}, dd)
if err != nil && errors.IsNotFound(err) {
if err != nil && apierrors.IsNotFound(err) {
return fmt.Errorf("DatadogAgent %s/%s not found", o.UserNamespace, o.userDatadogAgentName)
} else if err != nil {
return fmt.Errorf("unable to get DatadogAgent: %v", err)
Expand Down
43 changes: 43 additions & 0 deletions cmd/kubectl-datadog/validate/ad/ad/ad.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-2020 Datadog, Inc.

package ad

import (
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/validate/ad/pod"
"github.com/DataDog/datadog-operator/cmd/kubectl-datadog/validate/ad/service"

"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

// options provides information required by ad command
type options struct {
genericclioptions.IOStreams
configFlags *genericclioptions.ConfigFlags
}

// newOptions provides an instance of options with default values
func newOptions(streams genericclioptions.IOStreams) *options {
return &options{
configFlags: genericclioptions.NewConfigFlags(false),
IOStreams: streams,
}
}

// New provides a cobra command wrapping options for "ad" sub command
func New(streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "ad [subcommand] [flags]",
}

cmd.AddCommand(pod.New(streams))
cmd.AddCommand(service.New(streams))

o := newOptions(streams)
o.configFlags.AddFlags(cmd.Flags())

return cmd
}

0 comments on commit c9305e2

Please sign in to comment.