Not another markup language. Framework for replacing Kubernetes YAML with Go.

Overview

Go Reference

Not another markup language.

Replace Kubernetes YAML with raw Go!

Say so long πŸ‘‹ to YAML and start using the Go πŸŽ‰ programming language to represent and deploy applications.

Take advantage of all the lovely features of Go.

Test your code directly in local Kubernetes using kind.

Get your application directly into Go instead of YAML and use it in controllers, operators, CRs/CRDs easily. Use the Go compiler to your advantage.

Quickstart

Check out the examples GitHub organization.

  • simple basic CLI example.
  • full CLI example with custom commands and flags.

Implement Deployable

As long as there is a Go system that implements this interface it can be used with naml. See examples for how to include an implementation in your project.

// Deployable is used to deploy applications.
type Deployable interface {

	// Install will attempt to install in Kubernetes
	Install(client *kubernetes.Clientset) error

	// Uninstall will attempt to uninstall in Kubernetes
	Uninstall(client *kubernetes.Clientset) error

	// Meta returns the Kubernetes native ObjectMeta which is used to manage applications with naml.
	Meta() *v1.ObjectMeta
}

About

This is a framework for infrastructure teams who need more than just conditional manifests.

This allows teams to start encapsulating, managing, and testing their applications in raw Go.

Teams can now buid controllers, operators, and custom toolchains using reliable, testable, and scalable Go.

The philosophy

The bet here is that any person confident in managing YAML for Kubernetes can also be equally as confident managing Go for Kubernetes.

The feature add is that no matter how good our YAML management tools get, they will never be as good as just plain Go when it comes to things like syntax checking, testing, shipping, and flexibility.

Nothing fancy

Feel free to fork this repository and begin using it for your team. There isn't anything special here. πŸ€·β€β™€ We use the same client the rest of Kubernetes does.

❎ No new tools.

❎ No charts.

❎ No templating at runtime.

❎ No vague error messages.

❎ No more YAML guessing/checking.

βœ… Just Go. πŸŽ‰

Features

✨ There is not a single .yaml file in this entire repository. ✨

  • Express applications in πŸŽ‰ Go instead of YAML.
  • Use the Go compiler to check your syntax.
  • Write real tests πŸ€“ using Go to check and validate your deployments.
  • Test your applications in Kubernetes using kind.
  • Define custom installation logic. What happens if it fails?
  • Define custom application registries. Multiple apps of the same flavor? No problem.
  • Use the latest client (the same client the rest of Kubernetes uses).

Getting Started

Check out the examples GitHub organization.

  • simple basic CLI example.
  • full CLI example with custom commands and flags.
Comments
  • Valast fails at runtime with type pointers

    Valast fails at runtime with type pointers

    Write now the type pointer generation is failing (at runtime!)

    panic: interface conversion: interface {} is *int, not *int32
    
    goroutine 1 [running]:
    github.com/naml-examples/simple.(*App).Install(0xc000391200, 0xc000508000, 0x0, 0xa)
            /home/nova/src/tests/app.go:86 +0xed9
    github.com/kris-nova/naml.Install(0x1afcaf0, 0xc000391200, 0xc0004a3bd0, 0x0)
            /home/nova/go/pkg/mod/github.com/kris-nova/[email protected]/cmd.go:386 +0xc7
    github.com/kris-nova/naml.RunCommandLineWithOptions.func2(0xc0004d2000, 0x1, 0x1)
            /home/nova/go/pkg/mod/github.com/kris-nova/[email protected]/cmd.go:160 +0x39f
    github.com/urfave/cli/v2.(*Command).Run(0xc000391440, 0xc0003fdf40, 0x0, 0x0)
            /home/nova/go/pkg/mod/github.com/urfave/cli/[email protected]/command.go:163 +0x4dd
    github.com/urfave/cli/v2.(*App).RunContext(0xc00025bd40, 0x1afc930, 0xc00019a010, 0xc0001a4000, 0x2, 0x2, 0x0, 0x0)
            /home/nova/go/pkg/mod/github.com/urfave/cli/[email protected]/app.go:313 +0x810
    github.com/urfave/cli/v2.(*App).Run(...)
            /home/nova/go/pkg/mod/github.com/urfave/cli/[email protected]/app.go:224
    github.com/kris-nova/naml.RunCommandLineWithOptions(0x1afcaf0, 0xc000391200)
            /home/nova/go/pkg/mod/github.com/kris-nova/[email protected]/cmd.go:316 +0xf2b
    github.com/kris-nova/naml.RunCommandLine(...)
            /home/nova/go/pkg/mod/github.com/kris-nova/[email protected]/cmd.go:51
    main.main()
            /home/nova/src/tests/cmd/main.go:42 +0xa5
    

    Looks like this is the culprit

    			Replicas: valast.Addr(1).(*int32),
    

    We should fix Valast to do something like this

    			Replicas: valast.Addr(int32(1)).(*int32),
    
    opened by krisnova 16
  • TGIK: spotlight on naml

    TGIK: spotlight on naml

    Just wanted to say that I really like the project, writing (or templating) YAML is just painful!

    Also if anyone is interested, TGIK will be doing an episode showcasing naml on their Youtube channel in 2 days, it will be fun to watch :)

    https://youtu.be/ubJ4n_QHs98

    opened by Piotr1215 6
  • Codify fails when the input yaml object names have a dash in it.

    Codify fails when the input yaml object names have a dash in it.

    Took the example stateless app from https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/ and ran it against naml.

    [...]
    kind: Deployment
    metadata:
      name: nginx-deployment
    [...]
    

    Ran this through naml:

    kubectl get deployments -oyaml | naml c
    Error during codify: unable to auto format code: 88:2: expected identifier on left side of :=2021-08-01T18:41:03-07:00 [Critical  ]  unable to auto format code: 88:2: expected identifier on left side of :=
    

    I disabled gofmt to see the actual error and found this:

    nginx-deploymentDeployment := &appsv1.Deployment{
    

    We should probably trim illegal characters, though this may in rare circumstances cause a duplicate name. e.g. two deployments on the same system with names nginx-deployment vs nginxdeplolyment

    opened by fkautz 6
  • Make this a GitHub template repo?

    Make this a GitHub template repo?

    If I understand properly, you're supposed to fork this repo and then modify it to fit your app. GH templates would make it a little bit easier for folks to do that.

    opened by arschles 5
  • Codify doesn't deal well with unknown resource types

    Codify doesn't deal well with unknown resource types

    I tried running naml codify on an ObjectBucketClaim resource:

    apiVersion: objectbucket.io/v1alpha1
    kind: ObjectBucketClaim
    metadata:
      name: example-obc
    spec:
      generateBucketName: example-obc
      storageClassName: openshift-storage.noobaa.io
    

    I was expecting it to fail due to an unknown resource type, but to my surprise it didn't emit any errors. The resulting main.go has no resources (and does not compile).

    It would be nice if naml codify would emit an error (and fail) when it is unable to successfully convert the input.

    opened by larsks 4
  • Support MutatingWebhookConfiguration and HorizontalPodAutoscaler

    Support MutatingWebhookConfiguration and HorizontalPodAutoscaler

    This PR is largely motivated by the contents of https://github.com/knative/serving/releases/download/knative-v1.1.0/serving-core.yaml

    There are two issues that still require more work:

    1. Template delimiters inside configmap data causes parsing errors with go fmt. Not sure how to handle this at the moment so temporarily replaced double curly braces with quotes to get working output.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: test
    data: 
      a: |
        # {{ .Name }}
    
    1. Handling multiple versions for a Horizontal Pod Autoscaler. v2beta2 was not replaced with autoscalingv2beta2 for some reason after the alias. Tried to follow policyv1beta1 but might've missed something. https://github.com/GuessWhoSamFoo/naml/blob/4194c5e2352317bfdd1709adf6a47140a0b503f2/codify/codify.go#L40
    opened by GuessWhoSamFoo 3
  • Compile Issue

    Compile Issue

    Saul Nachman12:17 PM
    # command-line-arguments
    ./test.go:31:2: imported and not used: "k8s.io/api/apps/v1" as appsv1
    ./test.go:32:2: imported and not used: "k8s.io/api/core/v1" as corev1
    ./test.go:33:2: imported and not used: "k8s.io/api/networking/v1" as networkingv1
    ./test.go:35:2: imported and not used: "k8s.io/apimachinery/pkg/util/intstr"
    ./test.go:73:25: undefined: Ingress
    ./test.go:108:33: client.NetworkingV1().Ingresss undefined (type "k8s.io/client-go/kubernetes/typed/networking/v1".NetworkingV1Interface has
    
    opened by krisnova 3
  • use goname pattern in clusterrole

    use goname pattern in clusterrole

    ClusterRole now follows goname pattern that was set in Deployments.

    Also extracts goName into its own method for simplifcation.

    Signed-off-by: Frederick F. Kautz IV [email protected]

    opened by fkautz 3
  • not installing with different kubeconfig file

    not installing with different kubeconfig file

    Hi, really fun project, enjoying it so far :). One little thing I noticed; when I merge 2 kubeconfig files in the KUBECONFIG variable, there is hardcoded path searching for config file in .kube dir in this function in client.go

    // Client is used to authenticate with Kubernetes and build the Kube client
    // for the rest of the program.
    func Client() (*kubernetes.Clientset, error) {
    	kubeConfigPath := path.Join(homedir.HomeDir(), ".kube", "config")
    	return ClientFromPath(kubeConfigPath)
    }
    

    giving this error when context is in other file than config:

    unable to find local kube config [/home/decoder/.kube/config]: invalid configuration: [context was not found for specified context: default, cluster has no server defined]

    Swapping to another cluster (with context present in config) works as expected.

    Maybe reading KUBECONFIG variable on a retry when this error occurs would be a good idea?

    opened by Piotr1215 3
  • naml codify makefile

    naml codify makefile

    lets auto generate a makefile as well for our friends

    maybe syntax like this

    kubectl get deploy -oyaml | naml codify --name=beeps > main.go
    naml codify makefile --name=beeps > Makefile
    make
    ./beeps
    sudo make install
    beeps --help
    
    opened by krisnova 2
  • Promote @fkautz to maintainer

    Promote @fkautz to maintainer

    This project seems to have seen decent traction - perhaps it's worth considering another maintainer?

    Anyway @fkautz you seem to be the most active here. Would you be interested in a low-commitment maintainer spot on the project to serve as another place to get things done / merge PRs / review my code / etc?

    opened by krisnova 2
  • Unable to translate HorizontalPodAutoscaler yaml

    Unable to translate HorizontalPodAutoscaler yaml

    Hello! Thanks for this wonderful library. I am trying to convert a YAML file that contains a "kind: HorizontalPodAutoscaler" and "kind: CustomResourceDefinition". These are ignored by NAML. Is this expected?

    opened by srinathnarayanan 0
  • Build failed

    Build failed

    trying to make a basic test

    kubectl get job beeps -o yaml | naml codify > main.go

    naml build

    2022-10-04T16:44:09+02:00 [Warning   ]  ⚠ naml build alpha feature ⚠
    2022-10-04T16:44:09+02:00 [Warning   ]  if this is a feature you plan on using please make your use case known in the issue tracker
    2022-10-04T16:44:09+02:00 [Warning   ]  ⚠ naml build alpha feature ⚠
    2022-10-04T16:44:09+02:00 [Critical  ]  unable to build NAML binary from source:
    
    +-------------------------+---------------------------------
    | Codify Compile Failure  |
    +-------------------------+
    |
    |
    | # github.com/kris-nova/naml/codify
    ../../go/pkg/mod/github.com/kris-nova/[email protected]/codify/codify.go:138:3: unknown field 'ClusterName' in struct literal of type "k8s.io/apimachinery/pkg/apis/meta/v1".ObjectMeta
    ../../go/pkg/mod/github.com/kris-nova/[email protected]/codify/codify.go:138:33: m.ClusterName undefined (type "k8s.io/apimachinery/pkg/apis/meta/v1".ObjectMeta has no field or method ClusterName)
    +----------------------------------------------------------
    
    opened by tuxtof 0
  • Errors when building generated main.go

    Errors when building generated main.go

    Dislaimer: I come from JavaLand. Applolgies if I am reporting something that would be easy to solve for people living in GoLand.

    I am trying out NAML to cofify an existing deployment

    1. I exported our deployment to yaml first via kubectl get all -n <my_namespace> -o yaml | tee out/all.yaml which resulted in a yaml file with 24031 lines
    2. Then I switched to the out folder and converted it to go via cat all.yaml | naml codify > main.go which resulted in a go file with 26986 lines
    3. Now that I tried go build main.go I am getting following errors
    > naml build -o app
    2022-04-25T11:14:16+02:00 [Warning   ]  ⚠ naml build alpha feature ⚠
    2022-04-25T11:14:16+02:00 [Warning   ]  if this is a feature you plan on using please make your use case known in the issue tracker
    2022-04-25T11:14:16+02:00 [Warning   ]  ⚠ naml build alpha feature ⚠
    2022-04-25T11:14:17+02:00 [Critical  ]  unable to build NAML binary from source: 
    
    +-------------------------+---------------------------------
    | Codify Compile Failure  |
    +-------------------------+
    | 
    | 
    | # command-line-arguments
    /tmp/3648555560.go:171:9: unknown field 'i' in struct literal of type resource.Quantity
    /tmp/3648555560.go:171:21: int64Amount not exported by package resource
    /tmp/3648555560.go:172:10: unknown field 'value' in struct literal of type resource.int64Amount
    /tmp/3648555560.go:173:10: unknown field 'scale' in struct literal of type resource.int64Amount
    /tmp/3648555560.go:175:9: unknown field 's' in struct literal of type resource.Quantity
    /tmp/3648555560.go:179:9: unknown field 'i' in struct literal of type resource.Quantity
    /tmp/3648555560.go:179:26: int64Amount not exported by package resource
    /tmp/3648555560.go:179:38: unknown field 'value' in struct literal of type resource.int64Amount
    /tmp/3648555560.go:180:9: unknown field 's' in struct literal of type resource.Quantity
    /tmp/3648555560.go:186:21: int64Amount not exported by package resource
    /tmp/3648555560.go:186:21: too many errors
    +----------------------------------------------------------
    

    Another thing that was quite strange to me was that NAML generated properties like NodeName: with the node a certain pod is currently running on. Haven't looked further but my gut feeling tells me that it generates code for pods resulting from staeful/daemon/replica-sets which doesn't feel right.

    opened by amalic 0
  • Use reflection and harden package names

    Use reflection and harden package names

    Relevant to #61 we can harden our package management

    We can (and should) use reflection to snoop the Kubernetes libraries as needed. We need to get rid of the string lists at the top of codify.go

    https://github.com/kris-nova/naml/blob/main/codify/codify.go#L37

    opened by krisnova 0
  • naml build to solve for makefile and go.mod

    naml build to solve for makefile and go.mod

    Right now we have a problem with vendoring and capturing the compile commands with naml

    We can use naml build as a way to vet the code and ensure everything is working as expected

    opened by krisnova 0
Releases(v1.0.3)
Owner
Kris NΓ³va
professional grown up business adult does important internet business
Kris NΓ³va
How you can use Go to replace YAML files with Kubernetes.

YamYams A small project that is free to use. ?? I wanted to offer a starting point for anyone interested in replacing YAML with Go. You can read more

Kris NΓ³va 1.2k Jan 6, 2023
kubectl plugin for signing Kubernetes manifest YAML files with sigstore

k8s-manifest-sigstore kubectl plugin for signing Kubernetes manifest YAML files with sigstore ⚠️ Still under developement, not ready for production us

sigstore 70 Nov 28, 2022
YAML and Golang implementations of common Kubernetes patterns.

Kubernetes Patterns Types Patterns Foundational Patterns Behavioral Patterns Structural Patterns Configuration Patterns Usage To run, simply do go run

Sharad Bhat 71 Aug 8, 2022
Creates Helm chart from Kubernetes yaml

Helmify CLI that creates Helm charts from kubernetes yamls. Helmify reads a list of supported k8s objects from stdin and converts it to a helm chart.

Artem 363 Dec 28, 2022
Just a dummy Kubernetes Operator, playing with another dummy service

My first operator Just playing/learning to create a K8S operator in go. I will create a dummy operator that creates pods to open a shell inside It is

Jose Gato Luis 0 Dec 16, 2021
Kubernetes OS Server - Kubernetes Extension API server exposing OS configuration like sysctl via Kubernetes API

KOSS is a Extension API Server which exposes OS properties and functionality using Kubernetes API, so it can be accessed using e.g. kubectl. At the moment this is highly experimental and only managing sysctl is supported. To make things actually usable, you must run KOSS binary as root on the machine you will be managing.

Mateusz Gozdek 3 May 19, 2021
An Easy to use Go framework for Kubernetes based on kubernetes/client-go

k8devel An Easy to use Go framework for Kubernetes based on kubernetes/client-go, see examples dir for a quick start. How to test it ? Download the mo

null 10 Mar 25, 2022
General Pod Autoscaler(GPA) is a extension for K8s HPA, which can be used not only for serving, also for game.

Introduction General Pod Autoscaler(GPA) is a extension for K8s HPA, which can be used not only for serving, also for game. Features Compatible with a

Open Cloud-native Game-application Initiative 15 Aug 19, 2022
Write controller-runtime based k8s controllers that read/write to git, not k8s

Git Backed Controller The basic idea is to write a k8s controller that runs against git and not k8s apiserver. So the controller is reading and writin

Darren Shepherd 50 Dec 10, 2021
Pulumi provider for Vultr (based on the Terraform one), not official

Vultr Resource Provider The Vultr Resource Provider lets you manage Vultr resources. Installing This package is currently not available for most langu

Vincent Bernat 2 Apr 23, 2022
Demo of skaffold's port-forwarding with ko builder (does not work)

skaffold port-forwarding : Ko builder vs docker builder When using ko builder (see folder ko/), port forwarding does not work (skaffold debug or skaff

null 0 Jan 6, 2022
An operator which complements grafana-operator for custom features which are not feasible to be merged into core operator

Grafana Complementary Operator A grafana which complements grafana-operator for custom features which are not feasible to be merged into core operator

Snapp Cab Incubators 6 Aug 16, 2022
This is for managing Slack App Manifests, it is no use if you are not developing an App for Slack.

Terraform Provider Slack App This is for managing Slack App Manifests, it is no use if you are not developing an App for Slack. Requirements Terraform

ChangeEngine 2 May 23, 2022
Β΅Task is an automation engine that models and executes business processes declared in yaml. βœοΈπŸ“‹

Β΅Task, the Lightweight Automation Engine Β΅Task is an automation engine built for the cloud. It is: simple to operate: only a postgres DB is required s

OVHcloud 802 Dec 29, 2022
Converts your k8s YAML to a cdk8s Api Object.

kube2cdk8s Converts your k8s YAML to a cdk8s Api Object. Uses Pulumi's kube2pulumi as a base. Dependencies 1. pulumi cli 2. pulumi kubernetes provider

smallcase 16 Oct 18, 2022
No YAML deployments to K8s

no-yaml No YAML deployments to K8s with following approaches: Pulumi NAML cdk8s We will deploy the ?? ?? CNCF App Delivery SIG Demo podtato-head and u

Engin Diri 10 Dec 27, 2022
A handy utility to generate configmap and values.yaml of your application for helmifying them

Helmfig Are you tired of writing values.yaml for configmap of your project when you are helmifying them? Helmfig is a handy tool that can generate the

Snapp Cab Incubators 25 Dec 14, 2022
go-opa-validate is an open-source lib that evaluates OPA (open policy agent) policy against JSON or YAML data.

go-opa-validate go-opa-validate is an open-source lib that evaluates OPA (open policy agent) policy against JSON or YAML data. Installation Usage Cont

chenk 6 Nov 17, 2022
Prestic - Lets you define and run restic commands from a YAML file

Pete's Restic Lets you define and run restic commands from a YAML file. Features

Pete Taylor 0 Jan 10, 2022