Skip to content

Commit

Permalink
add ytt invocation
Browse files Browse the repository at this point in the history
  • Loading branch information
katmutua committed Dec 2, 2022
1 parent 8bd396f commit bcf0126
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 16 deletions.
27 changes: 27 additions & 0 deletions cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
set -euo pipefail

# make sure to regenerate manifests and run tests
make all

# delete any existing convention and deployment
kubectl delete -f samples/ytt-based-conventions/ytt-example.yaml
kapp delete -a conventions -n cartographer-system

# create a new deployment
kapp deploy -n cartographer-system -a conventions -f <( \
ko resolve -f <( \
ytt \
-f dist/cartographer-conventions.yaml
) \
)

# create the ytt based convention
kubectl apply -f samples/ytt-based-conventions/ytt-example.yaml
#kubectl delete -f samples/ytt-based-conventions/ytt-example.yaml

# inspect the ytt based convention
kubectl get clusterpodconvention.conventions.carto.run/spring-ytt-sample -o yaml

# create a workload
kubectl apply -f samples/ytt-based-conventions/workload.yaml
#kubectl delete -f samples/ytt-based-conventions/workload.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ func (s *ClusterPodConventionSpec) Validate() validation.FieldErrors {
errs = errs.Also(s.Webhook.Validate().ViaField("webhook"))
}
// only invoke ytt validations if the webhook configuration is not being used
if s.Webhook == nil && s.Ytt != nil {
errs = errs.Also(s.Webhook.Validate().ViaField("ytt"))
}
// if s.Webhook == nil && s.Ytt != nil {
// errs = errs.Also(s.Ytt.Validate().ViaField("ytt"))
// }
}

if s.SelectorTarget != PodTemplateSpecLabels && s.SelectorTarget != PodIntentLabels {
Expand Down
74 changes: 61 additions & 13 deletions pkg/controllers/podintent_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,23 @@ import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"path"
"runtime"
"sort"
"strings"
"time"

"github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/authn/k8schain"
"github.com/vmware-labs/reconciler-runtime/apis"
"github.com/vmware-labs/reconciler-runtime/reconcilers"
"github.com/vmware-labs/reconciler-runtime/tracker"
"gopkg.in/yaml.v2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -132,19 +139,15 @@ func ResolveConventions() reconcilers.SubReconciler {
convention.ClientConfig = *clientConfig
} else if source.Spec.Ytt != nil {
log.Info("handling a ytt based convention")
// read template spec and convenert to a sptream of bytes
// template
template := &parent.Spec.Template
// convert template as a stream of bytes
// templatesAsBytes = bytes.NewBuffer([]byte(template(string)))

// convert template to a stream of bytes
// kubectl = "kubectl"
// ytt = "ytt"
// args
log.Info("your template spec", template.GetObjectMeta())

return nil

// read template spec and convert to string

log.Info("retrieved pod template spec from the workload", parent)
stampedObj, err := ApplyYtt(ctx, *parent)
if err != nil {
return nil
}
log.Info("stamped out object", stampedObj)
}
conventions = append(conventions, convention)
}
Expand All @@ -162,6 +165,51 @@ func ResolveConventions() reconcilers.SubReconciler {
}
}

func ApplyYtt(ctx context.Context, workload conventionsv1alpha1.PodIntent) (interface{}, error) {
template := workload.Spec.Template.AsPodTemplateSpec()
log := logr.FromContextOrDiscard(ctx)

ctx, cancel := context.WithTimeout(ctx, 4*time.Second)
defer cancel()

ytt := "ytt"
if kodata, ok := os.LookupEnv("KO_DATA_PATH"); ok {
ytt = path.Join(kodata, fmt.Sprintf("ytt-%s-%s", runtime.GOOS, runtime.GOARCH))
}

args := []string{"--", "version"}
stdin := bytes.NewReader([]byte(template.Spec.String()))
stdout := bytes.NewBuffer([]byte{})
stderr := bytes.NewBuffer([]byte{})

cmd := exec.CommandContext(ctx, ytt, args...)
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr

log.Info("ytt call args", args)
log.Info("ytt call input", template)

if err := cmd.Run(); err != nil {
msg := stderr.String()
if msg == "" {
log.Error(err, "failed handle ytt")
return nil, err
}
return nil, err
}
output := stdout.String()
log.Info("ytt result", "output", output)

stampedObject := &unstructured.Unstructured{}
log.Info("your stamped object", stampedObject)
if err := yaml.Unmarshal([]byte(output), stampedObject); err != nil {
// ytt should never return invalid yaml
return nil, err
}
return stampedObject, nil
}

// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch
// +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;list;watch

Expand Down
11 changes: 11 additions & 0 deletions samples/ytt-based-conventions/workload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: conventions.carto.run/v1alpha1
kind: PodIntent
metadata:
name: spring-sample
spec:
template:
spec:
containers:
- name: workload
image: scothis/petclinic:sbom-20211210@sha256:8b517f21f283229e855e316e2753396239884eb9c4009ab6c797bdf2a041140f

0 comments on commit bcf0126

Please sign in to comment.