add or create ImagePullSecret

This commit is contained in:
Matias Manavella
2020-09-04 12:41:47 -03:00
parent 2289e00558
commit 4b2e7e153e
3 changed files with 110 additions and 15 deletions

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -1,7 +1,11 @@
package collect
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"io/ioutil"
"time"
"github.com/pkg/errors"
@@ -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)
}
@@ -137,6 +149,12 @@ 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, err
}
}
created, err := client.CoreV1().Pods(namespace).Create(ctx, &pod, metav1.CreateOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to create pod")
@@ -144,3 +162,66 @@ func runPod(ctx context.Context, client *kubernetes.Clientset, runCollector *tro
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 err
}
err = json.Indent(&out, parsedConfig, "", "\t")
if err != nil {
return errors.Errorf("Secret's config file not found or 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: "tmpsecret",
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 err
}
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")
}