Skip to content

Commit

Permalink
Merge pull request #253 from manavellamnimble/runImagePullSecret
Browse files Browse the repository at this point in the history
Add or create ImagePullSecret  in a run collector
  • Loading branch information
divolgin authored Sep 8, 2020
2 parents f68e0db + 1f08424 commit e232cc0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 15 deletions.
21 changes: 14 additions & 7 deletions pkg/apis/troubleshoot/v1beta1/collector_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,20 @@ type Data struct {

type Run struct {
CollectorMeta `json:",inline" yaml:",inline"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Image string `json:"image" yaml:"image"`
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Image string `json:"image" yaml:"image"`
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
}

type ImagePullSecrets struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"`
SecretType string `json:"type,omitempty" yaml:"type,omitempty"`
}

type Exec struct {
Expand Down
21 changes: 14 additions & 7 deletions pkg/apis/troubleshoot/v1beta2/collector_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,20 @@ type Data struct {

type Run struct {
CollectorMeta `json:",inline" yaml:",inline"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Image string `json:"image" yaml:"image"`
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace" yaml:"namespace"`
Image string `json:"image" yaml:"image"`
Command []string `json:"command,omitempty" yaml:"command,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"`
ImagePullSecret *ImagePullSecrets `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"`
}

type ImagePullSecrets struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"`
SecretType string `json:"type,omitempty" yaml:"type,omitempty"`
}

type Exec struct {
Expand Down
83 changes: 82 additions & 1 deletion pkg/collect/run.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package collect

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"io/ioutil"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -30,7 +34,15 @@ func Run(c *Collector, runCollector *troubleshootv1beta2.Run) (map[string][]byte
logger.Printf("Failed to delete pod %s: %v\n", pod.Name, err)
}
}()

if runCollector.ImagePullSecret.Data != nil {
defer func() {
for _, k := range pod.Spec.ImagePullSecrets {
if err := client.CoreV1().Secrets(pod.Namespace).Delete(ctx, k.Name, metav1.DeleteOptions{}); err != nil {
logger.Printf("Failed to delete secret %s: %v\n", k.Name, err)
}
}
}()
}
if runCollector.Timeout == "" {
return runWithoutTimeout(ctx, c, pod, runCollector)
}
Expand Down Expand Up @@ -137,10 +149,79 @@ func runPod(ctx context.Context, client *kubernetes.Clientset, runCollector *tro
},
}

if runCollector.ImagePullSecret != nil {
err := createSecret(ctx, client, runCollector.ImagePullSecret, &pod)
if err != nil {
return nil, errors.Wrap(err, "failed to create secret")
}
}
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.Clientset, imagePullSecret *troubleshootv1beta2.ImagePullSecrets, pod *corev1.Pod) error {
//In case a new secret needs to be created
if imagePullSecret.Data != nil {
var out bytes.Buffer
data := make(map[string][]byte)
if imagePullSecret.SecretType == "kubernetes.io/dockerconfigjson" {
//If secret type is dockerconfigjson, check if required field in data exists
v, found := imagePullSecret.Data[".dockerconfigjson"]
if !found {
return errors.Errorf("Secret type kubernetes.io/dockerconfigjson requires argument \".dockerconfigjson\"")
}
if len(imagePullSecret.Data) > 1 {
return errors.Errorf("Secret type kubernetes.io/dockerconfigjson accepts only one argument \".dockerconfigjson\"")
}
//Then, if data is a path to a config file, it is opened
configFile, err := ioutil.ReadFile(v)
if err != nil {
//If data is not a valid path, we assume data is a base64 encoded config.json file
//Client only accepts Json formated files as data, so we decode and indent it (indentation is required)
parsedConfig, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return errors.Wrap(err, "Secret's config file not found or unable to decode data.")
}
err = json.Indent(&out, parsedConfig, "", "\t")
if err != nil {
return errors.Wrap(err, "Unable to parse encoded data.")
}
data[".dockerconfigjson"] = out.Bytes()
} else {
data[".dockerconfigjson"] = configFile
}
} else {
for k, v := range imagePullSecret.Data {
data[k] = []byte(v)
}
}
secret := corev1.Secret{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
},
ObjectMeta: metav1.ObjectMeta{
Name: imagePullSecret.Name,
GenerateName: "troubleshoot",
Namespace: pod.Namespace,
},
Data: data,
Type: corev1.SecretType(imagePullSecret.SecretType),
}
created, err := client.CoreV1().Secrets(pod.Namespace).Create(ctx, &secret, metav1.CreateOptions{})
if err != nil {
return errors.Wrap(err, "failed to create secret")
}
pod.Spec.ImagePullSecrets = append(pod.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: created.Name})
return nil
}
//In case secret must only be added to the specs.
if imagePullSecret.Name != "" {
pod.Spec.ImagePullSecrets = append(pod.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: imagePullSecret.Name})
return nil
}
return errors.Errorf("Secret must at least have a Name")
}

0 comments on commit e232cc0

Please sign in to comment.