mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Update golangci-lint version (1.49.0 -> 1.50.1) and enable linters: dupword and testableexamples
170 lines
3.7 KiB
Go
170 lines
3.7 KiB
Go
// Copyright 2022 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package krmfunction
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/rakyll/statik/fs"
|
|
// load embedded func wrapper
|
|
_ "sigs.k8s.io/kustomize/cmd/pluginator/v2/internal/krmfunction/funcwrapper"
|
|
)
|
|
|
|
// Converter is a converter to convert the
|
|
// plugin file to KRM function
|
|
type Converter struct {
|
|
// Path to the output directory
|
|
outputDir string
|
|
// Path to the input file
|
|
inputFile string
|
|
wrapperFileName string
|
|
pluginFileName string
|
|
goModFileName string
|
|
dockerFileName string
|
|
}
|
|
|
|
// NewConverter return a pointer to a new converter
|
|
func NewConverter(outputDir, inputFile string) *Converter {
|
|
return &Converter{
|
|
outputDir: outputDir,
|
|
inputFile: inputFile,
|
|
wrapperFileName: "main.go",
|
|
pluginFileName: "plugin.go",
|
|
goModFileName: "go.mod",
|
|
dockerFileName: "Dockerfile",
|
|
}
|
|
}
|
|
|
|
// Convert converts the input file to a executable
|
|
// KRM function and writes to destination directory
|
|
func (c *Converter) Convert() error {
|
|
// read and process executable wrapper
|
|
wrapper, err := c.readEmbeddedFile(c.wrapperFileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
wrapper = c.prepareWrapper(wrapper)
|
|
|
|
if !strings.HasSuffix(c.inputFile, ".go") {
|
|
return fmt.Errorf("input file %s is not a Go file", c.inputFile)
|
|
}
|
|
|
|
// read and process plugin code
|
|
pluginCode, err := c.readDiskFile(c.inputFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, c.pluginFileName = filepath.Split(c.inputFile)
|
|
|
|
// go.mod file
|
|
goMod, err := c.readEmbeddedFile(c.goModFileName + ".src")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// prepare destination directory
|
|
err = c.mkDstDir()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// write
|
|
return c.write(map[string]string{
|
|
c.wrapperFileName: wrapper,
|
|
c.pluginFileName: pluginCode,
|
|
c.goModFileName: goMod,
|
|
c.dockerFileName: c.getDockerfile(),
|
|
})
|
|
}
|
|
|
|
func (c *Converter) getDockerfile() string {
|
|
return `FROM golang:1.19-bullseye
|
|
ENV CGO_ENABLED=0
|
|
WORKDIR /go/src/
|
|
COPY . .
|
|
RUN go build -v -o /usr/local/bin/function ./
|
|
FROM alpine:latest
|
|
COPY --from=0 /usr/local/bin/function /usr/local/bin/function
|
|
CMD ["function"]
|
|
`
|
|
}
|
|
|
|
func (c *Converter) prepareWrapper(content string) string {
|
|
b := bytes.NewBufferString(content)
|
|
o := &bytes.Buffer{}
|
|
scanner := bufio.NewScanner(b)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
// Set the package name to main
|
|
if strings.TrimSpace(line) == "package funcwrappersrc" {
|
|
line = "package main"
|
|
}
|
|
// assign to plugin variable
|
|
if strings.TrimSpace(line) == "var plugin resmap.Configurable" {
|
|
//nolint:dupword
|
|
line += `
|
|
// KustomizePlugin is a global variable defined in every plugin
|
|
plugin = &KustomizePlugin
|
|
`
|
|
}
|
|
o.WriteString(line + "\n")
|
|
}
|
|
return o.String()
|
|
}
|
|
|
|
// readEmbeddedFile read the file from embedded files with filename
|
|
// name. Return the file content if it's successful.
|
|
func (c *Converter) readEmbeddedFile(name string) (string, error) {
|
|
statikFS, err := fs.New()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
r, err := statikFS.Open("/" + name)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer r.Close()
|
|
contents, err := io.ReadAll(r)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return string(contents), nil
|
|
}
|
|
|
|
func (c *Converter) readDiskFile(path string) (string, error) {
|
|
f, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(f), nil
|
|
}
|
|
|
|
func (c *Converter) mkDstDir() error {
|
|
p := c.outputDir
|
|
f, err := os.Open(p)
|
|
if err == nil || f != nil {
|
|
return fmt.Errorf("directory %s has already existed", p)
|
|
}
|
|
|
|
return os.MkdirAll(p, 0755)
|
|
}
|
|
|
|
func (c *Converter) write(m map[string]string) error {
|
|
for k, v := range m {
|
|
p := filepath.Join(c.outputDir, k)
|
|
err := os.WriteFile(p, []byte(v), 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|