adding new runpod collector and refactoring old run collector to use new code

This commit is contained in:
diamonwiggins
2022-05-02 02:44:02 +00:00
parent 2516924a92
commit 42902405cd
4 changed files with 159 additions and 83 deletions

View File

@@ -76,7 +76,15 @@ type Run struct {
ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"`
PodSpec corev1.PodSpec `json:"podSpec,omitempty" yaml:"podSpec,omitempty"`
}
type RunPod struct {
CollectorMeta `json:",inline" yaml:",inline"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
PodSpec corev1.PodSpec `json:"podSpec,omitempty" yaml:"podSpec,omitempty"`
}
type ImagePullSecrets struct {
@@ -197,6 +205,7 @@ type Collect struct {
ConfigMap *ConfigMap `json:"configMap,omitempty" yaml:"configMap,omitempty"`
Logs *Logs `json:"logs,omitempty" yaml:"logs,omitempty"`
Run *Run `json:"run,omitempty" yaml:"run,omitempty"`
RunPod *RunPod `json:"runPod,omitempty" yaml:"runPod,omitempty"`
Exec *Exec `json:"exec,omitempty" yaml:"exec,omitempty"`
Data *Data `json:"data,omitempty" yaml:"data,omitempty"`
Copy *Copy `json:"copy,omitempty" yaml:"copy,omitempty"`
@@ -330,6 +339,19 @@ func (c *Collect) AccessReviewSpecs(overrideNS string) []authorizationv1.SelfSub
},
NonResourceAttributes: nil,
})
} else if c.RunPod != nil {
result = append(result, authorizationv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
Namespace: pickNamespaceOrDefault(c.RunPod.Namespace, overrideNS),
Verb: "create",
Group: "",
Version: "",
Resource: "pods",
Subresource: "",
Name: "",
},
NonResourceAttributes: nil,
})
} else if c.Exec != nil {
result = append(result, authorizationv1.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
@@ -435,6 +457,10 @@ func (c *Collect) GetName() string {
collector = "run"
name = c.Run.CollectorName
}
if c.RunPod != nil {
collector = "run-pod"
name = c.RunPod.CollectorName
}
if c.Exec != nil {
collector = "exec"
name = c.Exec.CollectorName

View File

@@ -641,6 +641,11 @@ func (in *Collect) DeepCopyInto(out *Collect) {
*out = new(Run)
(*in).DeepCopyInto(*out)
}
if in.RunPod != nil {
in, out := &in.RunPod, &out.RunPod
*out = new(RunPod)
(*in).DeepCopyInto(*out)
}
if in.Exec != nil {
in, out := &in.Exec, &out.Exec
*out = new(Exec)
@@ -3482,7 +3487,6 @@ func (in *Run) DeepCopyInto(out *Run) {
*out = new(ImagePullSecrets)
(*in).DeepCopyInto(*out)
}
in.PodSpec.DeepCopyInto(&out.PodSpec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Run.
@@ -3495,6 +3499,28 @@ func (in *Run) DeepCopy() *Run {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RunPod) DeepCopyInto(out *RunPod) {
*out = *in
out.CollectorMeta = in.CollectorMeta
if in.ImagePullSecret != nil {
in, out := &in.ImagePullSecret, &out.ImagePullSecret
*out = new(ImagePullSecrets)
(*in).DeepCopyInto(*out)
}
in.PodSpec.DeepCopyInto(&out.PodSpec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunPod.
func (in *RunPod) DeepCopy() *RunPod {
if in == nil {
return nil
}
out := new(RunPod)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Secret) DeepCopyInto(out *Secret) {
*out = *in

View File

@@ -93,6 +93,14 @@ func (c *Collector) IsExcluded() bool {
if isExcludedResult {
return true
}
} else if c.Collect.RunPod != nil {
isExcludedResult, err := isExcluded(c.Collect.RunPod.Exclude)
if err != nil {
return true
}
if isExcludedResult {
return true
}
} else if c.Collect.Exec != nil {
isExcludedResult, err := isExcluded(c.Collect.Exec.Exclude)
if err != nil {
@@ -221,6 +229,8 @@ func (c *Collector) RunCollectorSync(clientConfig *rest.Config, client kubernete
result, err = Logs(c, c.Collect.Logs)
} else if c.Collect.Run != nil {
result, err = Run(c, c.Collect.Run)
} else if c.Collect.RunPod != nil {
result, err = RunPod(c, c.Collect.RunPod)
} else if c.Collect.Exec != nil {
result, err = Exec(c, c.Collect.Exec)
} else if c.Collect.Data != nil {

View File

@@ -16,6 +16,48 @@ import (
)
func Run(c *Collector, runCollector *troubleshootv1beta2.Run) (CollectorResult, error) {
podLabels := make(map[string]string)
podLabels["troubleshoot-role"] = "run-collector"
pullPolicy := corev1.PullIfNotPresent
if runCollector.ImagePullPolicy != "" {
pullPolicy = corev1.PullPolicy(runCollector.ImagePullPolicy)
}
namespace := "default"
if runCollector.Namespace != "" {
namespace = runCollector.Namespace
}
serviceAccountName := "default"
if runCollector.ServiceAccountName != "" {
serviceAccountName = runCollector.ServiceAccountName
}
runPodCollector := &troubleshootv1beta2.RunPod{
Name: runCollector.CollectorName,
Namespace: namespace,
Timeout: runCollector.Timeout,
ImagePullSecret: runCollector.ImagePullSecret,
PodSpec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
ServiceAccountName: serviceAccountName,
Containers: []corev1.Container{
{
Image: runCollector.Image,
ImagePullPolicy: pullPolicy,
Name: "collector",
Command: runCollector.Command,
Args: runCollector.Args,
},
},
},
}
return RunPod(c, runPodCollector)
}
func RunPod(c *Collector, runCollector *troubleshootv1beta2.RunPod) (CollectorResult, error) {
ctx := context.Background()
client, err := kubernetes.NewForConfig(c.ClientConfig)
@@ -23,7 +65,7 @@ func Run(c *Collector, runCollector *troubleshootv1beta2.Run) (CollectorResult,
return nil, errors.Wrap(err, "failed to create client from config")
}
pod, err := runPod(ctx, client, runCollector, c.Namespace)
pod, err := runPodWithSpec(ctx, client, runCollector)
if err != nil {
return nil, errors.Wrap(err, "failed to run pod")
}
@@ -76,7 +118,52 @@ func Run(c *Collector, runCollector *troubleshootv1beta2.Run) (CollectorResult,
}
}
func runWithoutTimeout(ctx context.Context, c *Collector, pod *corev1.Pod, runCollector *troubleshootv1beta2.Run) (CollectorResult, error) {
func runPodWithSpec(ctx context.Context, client *kubernetes.Clientset, runCollector *troubleshootv1beta2.RunPod) (*corev1.Pod, error) {
podLabels := make(map[string]string)
podLabels["troubleshoot-role"] = "run-collector"
namespace := "default"
if runCollector.Namespace != "" {
namespace = runCollector.Namespace
}
podName := "run-pod"
if runCollector.CollectorName != "" {
podName = runCollector.CollectorName
} else if runCollector.Name != "" {
podName = runCollector.Name
}
pod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: podName,
Namespace: namespace,
Labels: podLabels,
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
Spec: runCollector.PodSpec,
}
if runCollector.ImagePullSecret != nil && runCollector.ImagePullSecret.Data != nil {
secretName, err := createSecret(ctx, client, pod.Namespace, runCollector.ImagePullSecret)
if err != nil {
return nil, errors.Wrap(err, "failed to create secret")
}
pod.Spec.ImagePullSecrets = append(pod.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: secretName})
}
created, err := client.CoreV1().Pods(namespace).Create(ctx, &pod, metav1.CreateOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to create pod")
}
return created, nil
}
func runWithoutTimeout(ctx context.Context, c *Collector, pod *corev1.Pod, runCollector *troubleshootv1beta2.RunPod) (CollectorResult, error) {
client, err := kubernetes.NewForConfig(c.ClientConfig)
if err != nil {
return nil, errors.Wrap(err, "failed create client from config")
@@ -104,10 +191,15 @@ func runWithoutTimeout(ctx context.Context, c *Collector, pod *corev1.Pod, runCo
output := NewResult()
collectorName := runCollector.Name
if collectorName == "" {
collectorName = runCollector.CollectorName
}
limits := troubleshootv1beta2.LogLimits{
MaxLines: 10000,
}
podLogs, err := savePodLogs(ctx, c.BundlePath, client, *pod, runCollector.Name, "", &limits, true)
podLogs, err := savePodLogs(ctx, c.BundlePath, client, *pod, collectorName, "", &limits, true)
if err != nil {
return nil, errors.Wrap(err, "failed to get pod logs")
}
@@ -119,84 +211,6 @@ func runWithoutTimeout(ctx context.Context, c *Collector, pod *corev1.Pod, runCo
return output, nil
}
func runPod(ctx context.Context, client *kubernetes.Clientset, runCollector *troubleshootv1beta2.Run, namespace string) (*corev1.Pod, error) {
podLabels := make(map[string]string)
podLabels["troubleshoot-role"] = "run-collector"
pullPolicy := corev1.PullIfNotPresent
if runCollector.ImagePullPolicy != "" {
pullPolicy = corev1.PullPolicy(runCollector.ImagePullPolicy)
}
if namespace == "" {
namespace = runCollector.Namespace
}
if namespace == "" {
namespace = "default"
}
serviceAccountName := "default"
if runCollector.ServiceAccountName != "" {
serviceAccountName = runCollector.ServiceAccountName
}
pod := corev1.Pod{}
if runCollector.PodSpec.Containers != nil {
pod = corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: runCollector.CollectorName,
Namespace: namespace,
Labels: podLabels,
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
Spec: runCollector.PodSpec,
}
} else {
pod = corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: runCollector.CollectorName,
Namespace: namespace,
Labels: podLabels,
},
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
ServiceAccountName: serviceAccountName,
Containers: []corev1.Container{
{
Image: runCollector.Image,
ImagePullPolicy: pullPolicy,
Name: "collector",
Command: runCollector.Command,
Args: runCollector.Args,
},
},
},
}
if runCollector.ImagePullSecret != nil && runCollector.ImagePullSecret.Data != nil {
secretName, err := createSecret(ctx, client, pod.Namespace, runCollector.ImagePullSecret)
if err != nil {
return nil, errors.Wrap(err, "failed to create secret")
}
pod.Spec.ImagePullSecrets = append(pod.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: secretName})
}
}
created, err := client.CoreV1().Pods(namespace).Create(ctx, &pod, metav1.CreateOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to create pod")
}
return created, nil
}
func createSecret(ctx context.Context, client kubernetes.Interface, namespace string, imagePullSecret *troubleshootv1beta2.ImagePullSecrets) (string, error) {
if imagePullSecret.Data == nil {
return "", nil