<p>Is there documentation on building <strong>k8s jobs</strong> in go-client somewhere? In particular I'm trying to convert a job yaml to go code and for the life of me cannot find reference docs that say how the fields convert</p>

Saloni Goel
<p>Converting YAML to Golang can be difficult, and often times the documentation with examples is missing.</p>
<p>I wrote a tool called <a href="https://github.com/kris-nova/naml" rel="nofollow noreferrer">naml</a> that is able to convert any Kubernetes YAML to raw Go. It is handy because it works using the version of Kubernetes you are running it against, and is compiled with the latest version of the Kubernetes code base.</p>
<p>If you wanted to create a Job, and see valid Go for the job it would look like this. Creating a Job <code>beeps</code> with container image <code>boops</code></p>
<pre><code>[nova@emma ~]$ kubectl create job beeps --image boops
job.batch/beeps created
[nova@emma ~]$ 
</code></pre>
<p>Naml will out a working program by design, but you will also get the output you are looking for.</p>
<pre><code>[nova@emma naml]$ kubectl get job beeps -o yaml | naml codify
// Copyright © 2021 Kris Nóva &lt;kris@nivenly.com&gt;
//
// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//   ███╗   ██╗ █████╗ ███╗   ███╗██╗
//   ████╗  ██║██╔══██╗████╗ ████║██║
//   ██╔██╗ ██║███████║██╔████╔██║██║
//   ██║╚██╗██║██╔══██║██║╚██╔╝██║██║
//   ██║ ╚████║██║  ██║██║ ╚═╝ ██║███████╗
//   ╚═╝  ╚═══╝╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝
//

package main

import (
        &quot;context&quot;
        &quot;fmt&quot;
        &quot;os&quot;

        &quot;github.com/hexops/valast&quot;
        batchv1 &quot;k8s.io/api/batch/v1&quot;
        corev1 &quot;k8s.io/api/core/v1&quot;
        metav1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
        &quot;k8s.io/apimachinery/pkg/types&quot;

        &quot;github.com/kris-nova/naml&quot;
        &quot;k8s.io/apimachinery/pkg/runtime&quot;
        &quot;k8s.io/client-go/kubernetes&quot;
)

// Version is the current release of your application.
var Version string = &quot;0.0.1&quot;

func main() {
        // Load the application into the NAML registery
        // Note: naml.Register() can be used multiple times.
        naml.Register(NewApp(&quot;App&quot;, &quot;Application autogenerated from NAML v0.3.1&quot;))

        // Run the generic naml command line program with
        // the application loaded.
        err := naml.RunCommandLine()
        if err != nil {
                fmt.Println(err.Error())
                os.Exit(1)
        }
}

// App is a very important grown up business application.
type App struct {
        metav1.ObjectMeta
        description string
        objects     []runtime.Object
        // ----------------------------------
        // Add your configuration fields here
        // ----------------------------------
}

// NewApp will create a new instance of App.
//
// See https://github.com/naml-examples for more examples.
//
// This is where you pass in fields to your application (similar to Values.yaml)
// Example: func NewApp(name string, example string, something int) *App
func NewApp(name, description string) *App {
        return &amp;App{
                description: description,
                ObjectMeta: metav1.ObjectMeta{
                        Name:            name,
                        ResourceVersion: Version,
                },
                // ----------------------------------
                // Add your configuration fields here
                // ----------------------------------
        }
}

func (a *App) Install(client *kubernetes.Clientset) error {
        var err error

        beepsJob := &amp;batchv1.Job{
                TypeMeta: metav1.TypeMeta{
                        Kind:       &quot;Job&quot;,
                        APIVersion: &quot;batch/batchv1&quot;,
                },
                ObjectMeta: metav1.ObjectMeta{
                        Name:            &quot;beeps&quot;,
                        Namespace:       &quot;default&quot;,
                        UID:             types.UID(&quot;650e4f36-3316-4506-bbe0-1e34c13742cf&quot;),
                        ResourceVersion: &quot;3231200&quot;,
                        Generation:      1,
                        Labels: map[string]string{
                                &quot;controller-uid&quot;: &quot;650e4f36-3316-4506-bbe0-1e34c13742cf&quot;,
                                &quot;job-name&quot;:       &quot;beeps&quot;,
                        },
                },
                Spec: batchv1.JobSpec{
                        Parallelism:  valast.Addr(int32(1)).(*int32),
                        Completions:  valast.Addr(int32(1)).(*int32),
                        BackoffLimit: valast.Addr(int32(6)).(*int32),
                        Selector: &amp;metav1.LabelSelector{MatchLabels: map[string]string{
                                &quot;controller-uid&quot;: &quot;650e4f36-3316-4506-bbe0-1e34c13742cf&quot;,
                        }},
                        Template: corev1.PodTemplateSpec{
                                ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{
                                        &quot;controller-uid&quot;: &quot;650e4f36-3316-4506-bbe0-1e34c13742cf&quot;,
                                        &quot;job-name&quot;:       &quot;beeps&quot;,
                                }},
                                Spec: corev1.PodSpec{
                                        Containers: []corev1.Container{corev1.Container{
                                                Name:                     &quot;beeps&quot;,
                                                Image:                    &quot;boops&quot;,
                                                TerminationMessagePath:   &quot;/dev/termination-log&quot;,
                                                TerminationMessagePolicy: corev1.TerminationMessagePolicy(&quot;File&quot;),
                                                ImagePullPolicy:          corev1.PullPolicy(&quot;Always&quot;),
                                        }},
                                        RestartPolicy:                 corev1.RestartPolicy(&quot;Never&quot;),
                                        TerminationGracePeriodSeconds: valast.Addr(int64(30)).(*int64),
                                        DNSPolicy:                     corev1.DNSPolicy(&quot;ClusterFirst&quot;),
                                        SecurityContext:               &amp;corev1.PodSecurityContext{},
                                        SchedulerName:                 &quot;default-scheduler&quot;,
                                },
                        },
                        CompletionMode: valast.Addr(batchv1.CompletionMode(&quot;NonIndexed&quot;)).(*batchv1.CompletionMode),
                        Suspend:        valast.Addr(false).(*bool),
                },
        }
        a.objects = append(a.objects, beepsJob)

        if client != nil {
                _, err = client.BatchV1().Jobs(&quot;default&quot;).Create(context.TODO(), beepsJob, metav1.CreateOptions{})
                if err != nil {
                        return err
                }
        }

        return err
}

func (a *App) Uninstall(client *kubernetes.Clientset) error {
        var err error

        if client != nil {
                err = client.BatchV1().Jobs(&quot;default&quot;).Delete(context.TODO(), &quot;beeps&quot;, metav1.DeleteOptions{})
                if err != nil {
                        return err
                }
        }

        return err
}

func (a *App) Description() string {
        return a.description
}

func (a *App) Meta() *metav1.ObjectMeta {
        return &amp;a.ObjectMeta
}

func (a *App) Objects() []runtime.Object {
        return a.objects
}
</code></pre>
