diff --git a/krm-functions/templater/Dockerfile.sample b/krm-functions/templater/Dockerfile.sample new file mode 100644 index 000000000..5cf4c1604 --- /dev/null +++ b/krm-functions/templater/Dockerfile.sample @@ -0,0 +1,11 @@ +FROM golang:1.13-stretch as builder +ENV CGO_ENABLED=0 +WORKDIR /go/src/ +COPY image/go.mod . +RUN go mod download +COPY main.go . +RUN go build -v -o /usr/local/bin/config-function ./ + +FROM alpine:latest +COPY --from=builder /usr/local/bin/config-function /usr/local/bin/config-function +CMD ["/usr/local/bin/config-function"] diff --git a/krm-functions/templater/Makefile b/krm-functions/templater/Makefile new file mode 100644 index 000000000..04dcf0acf --- /dev/null +++ b/krm-functions/templater/Makefile @@ -0,0 +1,78 @@ +.PHONY: generate license fix vet fmt test build tidy image + +SHELL := /bin/bash +GOBIN := $(shell go env GOPATH)/bin + +# docker image options +DOCKER_REGISTRY ?= quay.io +DOCKER_IMAGE_NAME ?= templater +DOCKER_IMAGE_PREFIX ?= airshipit +DOCKER_IMAGE_TAG ?= dev +DOCKER_IMAGE ?= $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_PREFIX)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) +PUBLISH ?= false +DOCKER_FORCE_CLEAN ?= true + +# proxy options +PROXY ?= http://proxy.foo.com:8000 +NO_PROXY ?= localhost,127.0.0.1,.svc.cluster.local +USE_PROXY ?= false + +.PHONY: build +build: + (cd image && go build -v -o $(GOBIN)/config-function .) + +.PHONY: all +all: generate license build fix vet fmt test lint tidy + +.PHONY: fix +fix: + (cd image && go fix ./...) + +.PHONY: fmt +fmt: + (cd image && go fmt ./...) + +.PHONY: generate +generate: + (which $(GOBIN)/mdtogo || go get sigs.k8s.io/kustomize/cmd/mdtogo) + (cd image && GOBIN=$(GOBIN) go generate ./...) + +.PHONY: tidy +tidy: + (cd image && go mod tidy) + +.PHONY: fix +lint: + (which $(GOBIN)/golangci-lint || go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.19.1) + (cd image && $(GOBIN)/golangci-lint run ./...) + +.PHONY: test +test: + (cd image && go test -cover ./...) + +.PHONY: vet +vet: + (cd image && go vet ./...) + +.PHONY: image +image: +ifeq ($(USE_PROXY), true) + cd image && \ + docker build . --network=host \ + --build-arg http_proxy=$(PROXY) \ + --build-arg https_proxy=$(PROXY) \ + --build-arg HTTP_PROXY=$(PROXY) \ + --build-arg HTTPS_PROXY=$(PROXY) \ + --build-arg no_proxy=$(NO_PROXY) \ + --build-arg NO_PROXY=$(NO_PROXY) \ + --tag $(DOCKER_IMAGE) \ + --force-rm=$(DOCKER_FORCE_CLEAN) +else + cd image && \ + docker build . --network=host \ + --tag $(DOCKER_IMAGE) \ + --force-rm=$(DOCKER_FORCE_CLEAN) +endif +ifeq ($(PUBLISH), true) + @docker push $(DOCKER_IMAGE) +endif diff --git a/krm-functions/templater/README.md b/krm-functions/templater/README.md new file mode 100644 index 000000000..3805922c7 --- /dev/null +++ b/krm-functions/templater/README.md @@ -0,0 +1,71 @@ +# Templater function + +This plugin is an implementation of a templater function written using `go` and uses the `kyaml` +and `airshipctl` libraries for parsing the input and writing the output. + +## Function implementation + +The function is implemented as an [image](image), and built using `make image`. + +## Function invocation + +The function is invoked by authoring a [Local Resource](local-resource) +with `metadata.annotations.[config.kubernetes.io/function]` and running: + + kustomize fn run local-resource/ + +This exits non-zero if there is an error. + +## Running the Example + +Run the function with: + + kustomize fn run local-resource/ + +The generated resources will appear in local-resource/ + +``` +$ cat local-resource/* + +apiVersion: metal3.io/v1alpha1 +kind: BareMetalHost +metadata: + name: node-1 +spec: + bootMACAddress: 00:aa:bb:cc:dd + +apiVersion: metal3.io/v1alpha1 +kind: BareMetalHost +metadata: + name: node-2 +spec: + bootMACAddress: 00:aa:bb:cc:ee +... +``` +### Configuration file format + +`Templater` configuration resource is represented as a standard +k8s resource with Group, Version, Kind and Metadata header. Templater +configuration is defined using `template` and `values` fields with +following structure. + + values: + hosts: + - macAddress: 00:aa:bb:cc:dd + name: node-1 + - macAddress: 00:aa:bb:cc:ee + name: node-2 + template: | + {{ range .hosts -}} + --- + apiVersion: metal3.io/v1alpha1 + kind: BareMetalHost + metadata: + name: {{ .name }} + spec: + bootMACAddress: {{ .macAddress }} + {{ end -}} + +`values` defines the substituion value as Map. +`template` defines the template with placeholders to substitue the value from the + values Map diff --git a/krm-functions/templater/image/go.mod b/krm-functions/templater/image/go.mod new file mode 100644 index 000000000..ece315d17 --- /dev/null +++ b/krm-functions/templater/image/go.mod @@ -0,0 +1,8 @@ +module opendev.org/airship/airshipctl/functions/templater/image + +go 1.14 + +require ( + opendev.org/airship/airshipctl v0.0.0-20201007215749-76e4d3f48c5a + sigs.k8s.io/kustomize/kyaml v0.7.1 +) diff --git a/krm-functions/templater/local-resource/example-use.yaml b/krm-functions/templater/local-resource/example-use.yaml new file mode 100644 index 000000000..530dfc7b0 --- /dev/null +++ b/krm-functions/templater/local-resource/example-use.yaml @@ -0,0 +1,34 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# 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 "AS IS" 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. +apiVersion: airshipit.org/v1alpha1 +kind: Templater +metadata: + annotations: + config.kubernetes.io/function: | + container: + image: quay.io/airshipit/templater:dev +values: + hosts: + - macAddress: 00:aa:bb:cc:dd + name: node-1 + - macAddress: 00:aa:bb:cc:ee + name: node-2 +template: | + {{ range .hosts -}} + --- + apiVersion: metal3.io/v1alpha1 + kind: BareMetalHost + metadata: + name: {{ .name }} + spec: + bootMACAddress: {{ .macAddress }} + {{ end -}} diff --git a/krm-functions/templater/main.go b/krm-functions/templater/main.go new file mode 100644 index 000000000..b213a2f26 --- /dev/null +++ b/krm-functions/templater/main.go @@ -0,0 +1,32 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +// Package main implements an injection function for resource reservations and +// is run with `kustomize config run -- DIR/`. +package main + +import ( + "fmt" + "os" + + "sigs.k8s.io/kustomize/kyaml/fn/framework" + + "opendev.org/airship/airshipctl/pkg/document/plugin/templater" +) + +func main() { + cfg := make(map[string]interface{}) + resourceList := &framework.ResourceList{FunctionConfig: &cfg} + cmd := framework.Command(resourceList, func() error { + plugin, err := templater.New(cfg) + if err != nil { + return err + } + resourceList.Items, err = plugin.Filter(resourceList.Items) + return err + }) + if err := cmd.Execute(); err != nil { + fmt.Fprint(os.Stderr, err) + os.Exit(1) + } +} diff --git a/manifests/function/airshipctl-base-catalogues/env-vars-template.yaml b/manifests/function/airshipctl-base-catalogues/env-vars-template.yaml index 2a8bdf1ba..d9f08d3c7 100644 --- a/manifests/function/airshipctl-base-catalogues/env-vars-template.yaml +++ b/manifests/function/airshipctl-base-catalogues/env-vars-template.yaml @@ -4,6 +4,10 @@ metadata: name: env-vars-template labels: airshipit.org/deploy-k8s: "false" + annotations: + config.kubernetes.io/function: |- + container: + image: quay.io/airshipit/templater:dev template: | --- apiVersion: airshipit.org/v1alpha1 diff --git a/manifests/function/hostgenerator-m3/hosttemplate.yaml b/manifests/function/hostgenerator-m3/hosttemplate.yaml index 0c9804ec9..766e319a2 100644 --- a/manifests/function/hostgenerator-m3/hosttemplate.yaml +++ b/manifests/function/hostgenerator-m3/hosttemplate.yaml @@ -2,6 +2,10 @@ apiVersion: airshipit.org/v1alpha1 kind: Templater metadata: name: m3-host-template + annotations: + config.kubernetes.io/function: |- + container: + image: quay.io/airshipit/templater:dev values: # hosts: