teleport/dronegen/types.go
a-palchikov 32ac67db06
darwin fips builds (#5866)
* Switch to go1.16. Use embed package to embed webassets instead of ad-hoc attaching to binary
* Fix pipeline duplicate step error
* Resolve duplicate pipeline step name error. Explicitly define platform for 'exec' pipelines. Remove the uid/gid environment from 'exec' pipelines as redundant.
* Set proper dependencies when building darwin package fips pipelines. Use enterprise build directory for tsh
* Address review comments
2021-03-29 19:20:01 +02:00

203 lines
5.3 KiB
Go

package main
import (
"errors"
"fmt"
"path/filepath"
"runtime"
"strings"
)
// Types to mirror the YAML fields of the drone config.
// See https://docs.drone.io/pipeline/kubernetes/syntax/ and https://docs.drone.io/pipeline/exec/syntax/.
type pipeline struct {
comment string
Kind string `yaml:"kind"`
Type string `yaml:"type"`
Name string `yaml:"name"`
Environment map[string]value `yaml:"environment,omitempty"`
Trigger trigger `yaml:"trigger"`
Workspace workspace `yaml:"workspace,omitempty"`
Platform platform `yaml:"platform,omitempty"`
Clone clone `yaml:"clone,omitempty"`
DependsOn []string `yaml:"depends_on,omitempty"`
Concurrency concurrency `yaml:"concurrency,omitempty"`
Steps []step `yaml:"steps"`
Services []service `yaml:"services,omitempty"`
Volumes []volume `yaml:"volumes,omitempty"`
}
func newKubePipeline(name string) pipeline {
return pipeline{
comment: generatedComment(),
Kind: "pipeline",
Type: "kubernetes",
Name: name,
Clone: clone{Disable: true},
}
}
//nolint:deadcode,unused
func newExecPipeline(name string) pipeline {
return pipeline{
comment: generatedComment(),
Kind: "pipeline",
Type: "exec",
Name: name,
Clone: clone{Disable: true},
}
}
func generatedComment() string {
c := `################################################
# Generated using dronegen, do not edit by hand!
# Use 'make dronegen' to update.
`
_, file, line, ok := runtime.Caller(2)
if ok {
// Trim off the local path to the repo.
i := strings.LastIndex(file, "dronegen")
if i > 0 {
file = file[i:]
}
c += fmt.Sprintf("# Generated at %s:%d\n", file, line)
}
c += "################################################\n\n"
return c
}
type trigger struct {
Event triggerRef `yaml:"event,omitempty"`
Cron triggerRef `yaml:"cron,omitempty"`
Target triggerRef `yaml:"target,omitempty"`
Ref triggerRef `yaml:"ref,omitempty"`
Repo triggerRef `yaml:"repo"`
Branch triggerRef `yaml:"branch,omitempty"`
}
type triggerRef struct {
Include []string `yaml:"include,omitempty"`
Exclude []string `yaml:"exclude,omitempty"`
}
// UnmarshalYAML parses trigger references as either a list of strings, or as
// include/exclude lists. Both are allowed by drone.
func (v *triggerRef) UnmarshalYAML(unmarshal func(interface{}) error) error {
var rawItems []string
if err := unmarshal(&rawItems); err == nil {
v.Include = rawItems
return nil
}
var regular struct {
Include []string `yaml:"include,omitempty"`
Exclude []string `yaml:"exclude,omitempty"`
}
if err := unmarshal(&regular); err == nil {
v.Include = regular.Include
v.Exclude = regular.Exclude
return nil
}
return errors.New("can't unmarshal the value as either string or from_secret reference")
}
func (r workspace) join(elems ...string) (path string) {
return filepath.Join(append([]string{r.Path}, elems...)...)
}
type workspace struct {
Path string `yaml:"path"`
}
type clone struct {
Disable bool `yaml:"disable"`
}
type platform struct {
OS string `yaml:"os"`
Arch string `yaml:"arch"`
}
type concurrency struct {
Limit int `yaml:"limit"`
}
type volume struct {
Name string `yaml:"name"`
Temp *volumeTemp `yaml:"temp,omitempty"`
Claim *volumeClaim `yaml:"claim,omitempty"`
}
type volumeTemp struct {
Medium string `yaml:"medium,omitempty"`
}
type volumeClaim struct {
Name string `yaml:"name"`
}
type service struct {
Name string `yaml:"name"`
Image string `yaml:"image"`
Volumes []volumeRef `yaml:"volumes"`
}
type volumeRef struct {
Name string `yaml:"name"`
Path string `yaml:"path"`
}
type step struct {
Name string `yaml:"name"`
Image string `yaml:"image,omitempty"`
Commands []string `yaml:"commands,omitempty"`
Environment map[string]value `yaml:"environment,omitempty"`
Volumes []volumeRef `yaml:"volumes,omitempty"`
Settings map[string]value `yaml:"settings,omitempty"`
Template []string `yaml:"template,omitempty"`
When *condition `yaml:"when,omitempty"`
Failure string `yaml:"failure,omitempty"`
}
type condition struct {
Status []string `yaml:"status,omitempty"`
}
// value is a string value for key:value pairs like "environment" or
// "settings". Values can be either inline strings (raw) or references to
// secrets stored in Drone (fromSecret).
type value struct {
raw string
fromSecret string
}
type valueFromSecret struct {
FromSecret string `yaml:"from_secret"`
}
func (v value) MarshalYAML() (interface{}, error) {
if v.raw != "" && v.fromSecret != "" {
return nil, fmt.Errorf("value %+v has both raw and fromSecret set, can only have one", v)
}
if v.raw != "" {
return v.raw, nil
}
if v.fromSecret != "" {
return valueFromSecret{FromSecret: v.fromSecret}, nil
}
return nil, fmt.Errorf("value has neither raw nor fromSecret set, need one")
}
func (v *value) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := unmarshal(&v.raw); err == nil {
return nil
}
var fs valueFromSecret
if err := unmarshal(&fs); err == nil {
v.fromSecret = fs.FromSecret
return nil
}
return errors.New("can't unmarshal the value as either string or from_secret reference")
}