Skip to content

Commit

Permalink
Remove use of templates for plugin Jobs and DaemonSets
Browse files Browse the repository at this point in the history
This change removes the use of templates for creating resources when
running plugins and instead creates the objects directly to use with the
Kubernetes API. This change should introduce no change in behaviour. It
is just refactoring in preparation for adding support to customise pod
options.

Signed-off-by: Bridget McErlean <[email protected]>
  • Loading branch information
zubron committed Aug 13, 2019
1 parent f68cb44 commit a9efcae
Show file tree
Hide file tree
Showing 13 changed files with 387 additions and 342 deletions.
4 changes: 2 additions & 2 deletions cmd/sonobuoy/app/gen_plugin_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os"

"github.com/heptio/sonobuoy/pkg/errlog"
"github.com/heptio/sonobuoy/pkg/plugin"
"github.com/heptio/sonobuoy/pkg/plugin/manifest"
"github.com/pkg/errors"
"github.com/spf13/cobra"
Expand All @@ -32,7 +33,6 @@ import (
const (
defaultPluginName = "plugin"
defaultPluginDriver = "Job"
defaultMountPath = "/tmp/results"
defaultMountName = "results"
defaultMountReadOnly = false
)
Expand Down Expand Up @@ -107,7 +107,7 @@ func defaultManifest() manifest.Manifest {
m.SonobuoyConfig.Driver = defaultPluginDriver
m.Spec.VolumeMounts = []v1.VolumeMount{
v1.VolumeMount{
MountPath: defaultMountPath,
MountPath: plugin.ResultsDir,
Name: defaultMountName,
ReadOnly: defaultMountReadOnly,
},
Expand Down
11 changes: 5 additions & 6 deletions pkg/client/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ import (
)

const (
e2ePluginName = "e2e"
systemdLogsName = "systemd-logs"
pluginResultsDir = "/tmp/results"
e2ePluginName = "e2e"
systemdLogsName = "systemd-logs"
)

// templateValues are used for direct template substitution for manifest generation.
Expand Down Expand Up @@ -257,7 +256,7 @@ func systemdLogsManifest(cfg *GenConfig) *manifest.Manifest {
ImagePullPolicy: corev1.PullPolicy(cfg.ImagePullPolicy),
Env: []corev1.EnvVar{
{Name: "CHROOT_DIR", Value: "/node"},
{Name: "RESULTS_DIR", Value: pluginResultsDir},
{Name: "RESULTS_DIR", Value: plugin.ResultsDir},
{Name: "NODE_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{FieldPath: "spec.nodeName"},
Expand All @@ -271,7 +270,7 @@ func systemdLogsManifest(cfg *GenConfig) *manifest.Manifest {
{
ReadOnly: false,
Name: "results",
MountPath: pluginResultsDir,
MountPath: plugin.ResultsDir,
}, {
ReadOnly: false,
Name: "root",
Expand Down Expand Up @@ -306,7 +305,7 @@ func e2eManifest(cfg *GenConfig) *manifest.Manifest {
{
ReadOnly: false,
Name: "results",
MountPath: pluginResultsDir,
MountPath: plugin.ResultsDir,
},
},
},
Expand Down
3 changes: 3 additions & 0 deletions pkg/plugin/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ package plugin
const (
// GracefulShutdownPeriod is how long plugins have to cleanly finish before they are terminated.
GracefulShutdownPeriod = 60

// ResultsDir is the directory where results will be available in Sonobuoy plugin containers.
ResultsDir = "/tmp/results"
)
127 changes: 73 additions & 54 deletions pkg/plugin/driver/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import (
"encoding/pem"
"fmt"

"github.com/heptio/sonobuoy/pkg/plugin"
"github.com/heptio/sonobuoy/pkg/plugin/manifest"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kuberuntime "k8s.io/apimachinery/pkg/runtime"
)

// Base is the struct that stores state for plugin drivers and contains helper methods.
Expand All @@ -42,23 +42,6 @@ type Base struct {
CustomAnnotations map[string]string
}

// TemplateData is all the fields available to plugin driver templates.
type TemplateData struct {
PluginName string
ResultType string
SessionID string
Namespace string
SonobuoyImage string
ImagePullPolicy string
ImagePullSecrets string
CustomAnnotations map[string]string
ProducerContainer string
MasterAddress string
CACert string
SecretName string
ExtraVolumes []string
}

// GetSessionID returns the session id associated with the plugin.
func (b *Base) GetSessionID() string {
return b.SessionID
Expand Down Expand Up @@ -94,42 +77,6 @@ func (b *Base) GetResultFiles() []string {
return b.Definition.SonobuoyConfig.ResultFiles
}

//GetTemplateData fills a TemplateData struct with the passed in and state variables.
func (b *Base) GetTemplateData(masterAddress string, cert *tls.Certificate) (*TemplateData, error) {

container, err := kuberuntime.Encode(manifest.Encoder, &b.Definition.Spec)
if err != nil {
return nil, errors.Wrapf(err, "couldn't reserialize container for job %q", b.Definition.SonobuoyConfig.PluginName)
}

volumes := make([]string, len(b.Definition.ExtraVolumes))
for i, volume := range b.Definition.ExtraVolumes {
enc, err := kuberuntime.Encode(manifest.Encoder, &volume)
if err != nil {
return nil, errors.Wrap(err, "couldn't serialize extra volume")
}
volumes[i] = string(enc)
}

cacert := getCACertPEM(cert)

return &TemplateData{
PluginName: b.Definition.SonobuoyConfig.PluginName,
ResultType: b.Definition.SonobuoyConfig.ResultType,
SessionID: b.SessionID,
Namespace: b.Namespace,
SonobuoyImage: b.SonobuoyImage,
ImagePullPolicy: b.ImagePullPolicy,
ImagePullSecrets: b.ImagePullSecrets,
CustomAnnotations: b.CustomAnnotations,
ProducerContainer: string(container),
MasterAddress: masterAddress,
CACert: cacert,
SecretName: b.GetSecretName(),
ExtraVolumes: volumes,
}, nil
}

// MakeTLSSecret makes a Kubernetes secret object for the given TLS certificate.
func (b *Base) MakeTLSSecret(cert *tls.Certificate) (*v1.Secret, error) {
rsaKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
Expand Down Expand Up @@ -192,3 +139,75 @@ func getKeyPEM(key *ecdsa.PrivateKey) ([]byte, error) {
Bytes: derKEY,
}), nil
}

func (b *Base) workerEnvironment(hostname string, cert *tls.Certificate) []v1.EnvVar {
envVars := []v1.EnvVar{
{
Name: "NODE_NAME",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "spec.nodeName",
},
},
},
{
Name: "RESULTS_DIR",
Value: plugin.ResultsDir,
},
{
Name: "RESULT_TYPE",
Value: b.GetResultType(),
},
{
Name: "MASTER_URL",
Value: hostname,
},
{
Name: "CA_CERT",
Value: getCACertPEM(cert),
},
{
Name: "CLIENT_CERT",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: b.GetSecretName(),
},
Key: "tls.crt",
},
},
},
{
Name: "CLIENT_KEY",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: b.GetSecretName(),
},
Key: "tls.key",
},
},
},
}
return envVars
}

// CreateWorkerContainerDefintion creates the container definition to run the Sonobuoy worker for a plugin.
func (b *Base) CreateWorkerContainerDefintion(hostname string, cert *tls.Certificate, command, args []string) v1.Container {
container := v1.Container{
Name: "sonobuoy-worker",
Image: b.SonobuoyImage,
Command: command,
Args: args,
Env: b.workerEnvironment(hostname, cert),
ImagePullPolicy: v1.PullPolicy(b.ImagePullPolicy),
VolumeMounts: []v1.VolumeMount{
{
Name: "results",
ReadOnly: false,
MountPath: plugin.ResultsDir,
},
},
}
return container
}
Loading

0 comments on commit a9efcae

Please sign in to comment.