mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-12 09:24:24 -05:00
9d25372e10
This tool can generate Go source files and lockfiles for container images.
131 lines
3.7 KiB
Go
131 lines
3.7 KiB
Go
/*
|
|
Copyright (c) Edgeless Systems GmbH
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
// inject renders Go source files with injected pinning values.
|
|
package inject
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"regexp"
|
|
"text/template"
|
|
)
|
|
|
|
// Render renders the source code to inject the pinned values.
|
|
func Render(out io.Writer, vals PinningValues) error {
|
|
if err := validate(vals); err != nil {
|
|
return err
|
|
}
|
|
return sourceTpl.Execute(out, vals)
|
|
}
|
|
|
|
// validate validates the values to inject.
|
|
func validate(vals PinningValues) error {
|
|
if vals.Package == "" {
|
|
return errors.New("package is empty")
|
|
}
|
|
if vals.Ident == "" {
|
|
return errors.New("identifier is empty")
|
|
}
|
|
if vals.Registry == "" {
|
|
return errors.New("registry is empty")
|
|
}
|
|
if vals.Name == "" {
|
|
return errors.New("name is empty")
|
|
}
|
|
if vals.Digest == "" {
|
|
return errors.New("digest is empty")
|
|
}
|
|
|
|
if matched := packageNameRegexp.MatchString(vals.Package); !matched {
|
|
return errors.New("package is not valid")
|
|
}
|
|
if matched := identRegexp.MatchString(vals.Ident); !matched {
|
|
return errors.New("identifier is not valid")
|
|
}
|
|
if matched := registryRegexp.MatchString(vals.Registry); !matched {
|
|
return errors.New("registry is not valid")
|
|
}
|
|
if matched := prefixRegexp.MatchString(vals.Prefix); !matched {
|
|
return errors.New("prefix is not valid")
|
|
}
|
|
if matched := nameRegexp.MatchString(vals.Name); !matched {
|
|
return errors.New("name is not valid")
|
|
}
|
|
if matched := tagRegexp.MatchString(vals.Tag); vals.Tag != "" && !matched {
|
|
return errors.New("tag is not valid")
|
|
}
|
|
if matched := digestRegexp.MatchString(vals.Digest); !matched {
|
|
return errors.New("digest is not valid")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// PinningValues contains the values to inject into the generated source code.
|
|
type PinningValues struct {
|
|
// Package is the name of the package to generate.
|
|
Package string
|
|
// Ident is the base identifier of the generated constants.
|
|
Ident string
|
|
// Registry string
|
|
Registry string
|
|
// Prefix is the prefix of the container image name.
|
|
Prefix string
|
|
// Name is the name of the container image.
|
|
Name string
|
|
// Tag is the (optional) tag of the container image.
|
|
Tag string
|
|
// Digest is the digest of the container image.
|
|
Digest string
|
|
}
|
|
|
|
var (
|
|
sourceTpl = template.Must(template.New("goSource").Parse(goSourceTpl))
|
|
|
|
// packageNameRegexp is the regular expression for a valid package name.
|
|
packageNameRegexp = regexp.MustCompile(`^[a-z][a-z0-9_]*$`)
|
|
|
|
// identRegexp is the regular expression for a valid identifier.
|
|
identRegexp = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
|
|
|
|
// registryRegexp is the regular expression for a valid registry.
|
|
registryRegexp = regexp.MustCompile(`^[^\s/"]+$`)
|
|
|
|
// prefixRegexp is the regular expression for a valid prefix.
|
|
prefixRegexp = regexp.MustCompile(`^([a-zA-Z0-9][a-zA-Z0-9-_/]*)?$`)
|
|
|
|
// nameRegexp is the regular expression for a valid name.
|
|
nameRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9-_]*$`)
|
|
|
|
// tagRegexp is the regular expression for a valid tag.
|
|
tagRegexp = regexp.MustCompile(`[\w][\w.-]{0,127}`)
|
|
|
|
// digestRegexp is the regular expression for a valid digest.
|
|
digestRegexp = regexp.MustCompile(`^sha256:[a-f0-9]{64}$`)
|
|
)
|
|
|
|
const goSourceTpl = `package {{.Package}}
|
|
|
|
// Code generated by oci-pin. DO NOT EDIT.
|
|
|
|
const (
|
|
// {{.Ident}}Registry is the {{.Name}} container image registry.
|
|
{{.Ident}}Registry = "{{.Registry}}"
|
|
|
|
{{if .Prefix }} // {{.Ident}}Prefix is the {{.Name}} container image prefix.
|
|
{{.Ident}}Prefix = "{{.Prefix}}"
|
|
|
|
{{end}} // {{.Ident}}Name is the {{.Name}} container image short name part.
|
|
{{.Ident}}Name = "{{.Name}}"
|
|
|
|
{{if .Tag }} // {{.Ident}}Tag is the tag for the {{.Name}} container image.
|
|
{{.Ident}}Tag = "{{.Tag}}"
|
|
|
|
{{end}} // {{.Ident}}Digest is the digest for the {{.Name}} container image.
|
|
{{.Ident}}Digest = "{{.Digest}}"
|
|
)
|
|
`
|