package main
import (
templatev1 "github.com/openshift/api/template/v1"
templatev1client "github.com/openshift/client-go/template/clientset/versioned/typed/template/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// Instantiate loader for kubeconfig file.
kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{},
)
// Determine the Namespace referenced by the current context in the
// kubeconfig file.
namespace, _, err := kubeconfig.Namespace()
if err != nil {
panic(err)
}
// Get a rest.Config from the kubeconfig file. This will be passed into all
// the client objects we create.
restconfig, err := kubeconfig.ClientConfig()
if err != nil {
panic(err)
}
// Create a Kubernetes core/v1 client.
coreclient, err := corev1client.NewForConfig(restconfig)
if err != nil {
panic(err)
}
// Create an OpenShift template/v1 client.
templateclient, err := templatev1client.NewForConfig(restconfig)
if err != nil {
panic(err)
}
// Get the "jenkins-ephemeral" Template from the "openshift" Namespace.
template, err := templateclient.Templates("openshift").Get(
"jenkins-ephemeral", metav1.GetOptions{})
if err != nil {
panic(err)
}
// INSTANTIATE THE TEMPLATE.
// To set Template parameters, create a Secret holding overridden parameters
// and their values.
secret, err := coreclient.Secrets(namespace).Create(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "parameters",
},
StringData: map[string]string{
"MEMORY_LIMIT": "1024Mi",
},
})
if err != nil {
panic(err)
}
// Create a TemplateInstance object, linking the Template and a reference to
// the Secret object created above.
ti, err := templateclient.TemplateInstances(namespace).Create(
&templatev1.TemplateInstance{
ObjectMeta: metav1.ObjectMeta{
Name: "templateinstance",
},
Spec: templatev1.TemplateInstanceSpec{
Template: *template,
Secret: &corev1.LocalObjectReference{
Name: secret.Name,
},
},
})
if err != nil {
panic(err)
}
// Watch the TemplateInstance object until it indicates the Ready or
// InstantiateFailure status condition.
watcher, err := templateclient.TemplateInstances(namespace).Watch(
metav1.SingleObject(ti.ObjectMeta),
)
if err != nil {
panic(err)
}
for event := range watcher.ResultChan() {
switch event.Type {
case watch.Modified:
ti = event.Object.(*templatev1.TemplateInstance)
for _, cond := range ti.Status.Conditions {
// If the TemplateInstance contains a status condition
// Ready == True, stop watching.
if cond.Type == templatev1.TemplateInstanceReady &&
cond.Status == corev1.ConditionTrue {
watcher.Stop()
}
// If the TemplateInstance contains a status condition
// InstantiateFailure == True, indicate failure.
if cond.Type ==
templatev1.TemplateInstanceInstantiateFailure &&
cond.Status == corev1.ConditionTrue {
panic("templateinstance instantiation failed")
}
}
default:
panic("unexpected event type " + event.Type)
}
}
// DELETE THE INSTANTIATED TEMPLATE.
// We use the foreground propagation policy to ensure that the garbage
// collector removes all instantiated objects before the TemplateInstance
// itself disappears.
foreground := metav1.DeletePropagationForeground
deleteOptions := metav1.DeleteOptions{PropagationPolicy: &foreground}
err = templateclient.TemplateInstances(namespace).Delete(ti.Name,
&deleteOptions)
if err != nil {
panic(err)
}
// Watch the TemplateInstance object until it disappears.
watcher, err = templateclient.TemplateInstances(namespace).Watch(
metav1.SingleObject(ti.ObjectMeta),
)
if err != nil {
panic(err)
}
for event := range watcher.ResultChan() {
switch event.Type {
case watch.Modified:
// do nothing
case watch.Deleted:
watcher.Stop()
default:
panic("unexpected event type " + event.Type)
}
}
// Finally delete the "parameters" Secret.
err = coreclient.Secrets(namespace).Delete(secret.Name,
&metav1.DeleteOptions{})
if err != nil {
panic(err)
}
}