Skip to content

Commit

Permalink
fix: 新增验证 pod container 状态功能
Browse files Browse the repository at this point in the history
  • Loading branch information
googs1025 committed Dec 2, 2023
1 parent 424a95b commit 20aa2a1
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
11 changes: 11 additions & 0 deletions example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package main
import (
"fmt"
"github.com/practice/shell_extender/pkg/command"
"github.com/practice/shell_extender/pkg/pod_exec_command"
"github.com/practice/shell_extender/pkg/remote_command"
"log"
)

func main() {
Expand Down Expand Up @@ -73,4 +75,13 @@ func main() {
fmt.Println(err)
}
fmt.Println("===============================")

fmt.Println("==============ExecPodContainerCmd=================")
cmd := pod_exec_command.NewExecPodContainerCmd("./pkg/pod_exec_command/config1", "test-pod",
"my-container", "default", true)
err = cmd.Run([]string{"sh", "-c", "ls -a"})
if err != nil {
log.Fatal(err)
}
fmt.Println("===============================")
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ go 1.18
require (
github.com/go-ping/ping v1.1.0
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.7.0
golang.org/x/crypto v0.11.0
k8s.io/api v0.27.4
k8s.io/apimachinery v0.27.4
k8s.io/client-go v0.27.4
)

Expand Down Expand Up @@ -46,7 +48,6 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.27.4 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand Down
63 changes: 49 additions & 14 deletions pkg/pod_exec_command/pod_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package pod_exec_command

import (
"context"
"errors"
v1 "k8s.io/api/core/v1"
"fmt"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
Expand All @@ -12,20 +15,15 @@ import (
"os"
)

var (
ErrParseKubeConfig = errors.New("parse kube config file error")
ErrPrepareClient = errors.New("prepare kube client error")
ErrSPDYExecutor = errors.New("SPDY Exec error")
)

type ExecPodContainerCmd struct {
// kubeConfig kubeconfig目录地址,默认集群内.kube/config
kubeConfig string
kubeConfig string
// insecure 是否跳过tls鉴权
insecure bool
podName string
containerName string
namespace string
k8sClient kubernetes.Interface
}

func NewExecPodContainerCmd(kubeConfig string, podName string, containerName string, namespace string, insecure bool) *ExecPodContainerCmd {
Expand All @@ -35,22 +33,53 @@ func NewExecPodContainerCmd(kubeConfig string, podName string, containerName str
}

// prepare 准备登入材料
func (epc *ExecPodContainerCmd) prepare() (*rest.Config, *kubernetes.Clientset, error) {
func (epc *ExecPodContainerCmd) prepare() (*rest.Config, kubernetes.Interface, error) {
config, err := clientcmd.BuildConfigFromFlags("", epc.kubeConfig)
if err != nil {
return nil, nil, ErrParseKubeConfig
return nil, nil, errors.Wrapf(err, "parse kube config file error: %s", err)
}
config.Insecure = epc.insecure
client, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, nil, ErrPrepareClient
return nil, nil, errors.Wrapf(err, "prepare kube client error: %s", err)
}
epc.k8sClient = client
return config, client, nil
}

// validatePod 验证 pod container
func (epc *ExecPodContainerCmd) validatePod(ctx context.Context, podName, containerName, namespace string) error {
pod, err := epc.k8sClient.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})
if err != nil && k8serrors.IsNotFound(err) {
return fmt.Errorf("pod %s/%s not found", namespace, podName)
}

if err != nil {
return err
}

if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodFailed {
return fmt.Errorf("cannot exec into container in a completed pod, current phase %s", pod.Status.Phase)
}

for _, cc := range pod.Spec.InitContainers {
if containerName == cc.Name {
return fmt.Errorf("can't exec init container %s in pod %s/%s ", containerName, namespace, podName)
}
}

for _, cs := range pod.Status.ContainerStatuses {
if containerName == cs.Name {
return nil
}
}

return fmt.Errorf("pod has no container %s", containerName)
}

// Run 执行远程命令
func (epc *ExecPodContainerCmd) Run(command []string) error {
option := &v1.PodExecOptions{
option := &corev1.PodExecOptions{
Container: epc.containerName,
Command: command,
Stdin: true,
Expand All @@ -63,6 +92,12 @@ func (epc *ExecPodContainerCmd) Run(command []string) error {
return err
}

// 校验 pod container 是否存在
err = epc.validatePod(context.Background(), epc.podName, epc.containerName, epc.namespace)
if err != nil {
return errors.Wrapf(err, "validate Pod error: %s", err)
}

// 执行pods中 特定container容器的命令
req := client.CoreV1().RESTClient().Post().Resource("pods").
Namespace(epc.namespace).
Expand All @@ -76,7 +111,7 @@ func (epc *ExecPodContainerCmd) Run(command []string) error {

exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return ErrSPDYExecutor
return errors.Wrapf(err, "SPDY Exec error: %s", err)
}

return exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{
Expand Down
7 changes: 4 additions & 3 deletions pkg/pod_exec_command/pod_exec_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package pod_exec_command

import (
"log"
"testing"
)

func TestHandleCommand(t *testing.T) {

cmd := NewExecPodContainerCmd("./config", "myinspect-controller-69748dc6bf-84wdp",
"myinspect-controller", "default", true)
cmd := NewExecPodContainerCmd("./config1", "test-pod",
"my-container", "default", true)
err := cmd.Run([]string{"sh", "-c", "ls -a"})
if err != nil {
return
log.Fatal(err)
}
}

0 comments on commit 20aa2a1

Please sign in to comment.