Path: blob/main/install/installer/pkg/config/loader.go
2499 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package config56import (7"fmt"89"github.com/gitpod-io/gitpod/installer/pkg/cluster"10"github.com/gitpod-io/gitpod/installer/pkg/yq"11"github.com/go-playground/validator/v10"1213"sigs.k8s.io/yaml"14)1516// CurrentVersion points to the latest config version17const CurrentVersion = "v1"1819// NewDefaultConfig returns a new instance of the current config struct,20// with all defaults filled in.21func NewDefaultConfig() (interface{}, error) {22v, ok := versions[CurrentVersion]23if !ok {24return nil, fmt.Errorf("current config version is invalid - this should never happen")25}2627cfg := v.Factory()28err := v.Defaults(cfg)29if err != nil {30return nil, err31}3233return cfg, nil34}3536type ConfigVersion interface {37// Factory provides a new instance of the config struct38Factory() interface{}3940// Defaults fills in the defaults for this version.41// obj is expected to be the return value of Factory()42Defaults(obj interface{}) error4344// LoadValidationFuncs loads the custom validation functions45LoadValidationFuncs(*validator.Validate) error4647// ClusterValidation introduces configuration specific cluster validation checks48ClusterValidation(cfg interface{}) cluster.ValidationChecks4950// CheckDeprecated checks for deprecated config params.51// Returns key/value pair of deprecated params/values and any error messages (used for conflicting params)52CheckDeprecated(cfg interface{}) (map[string]interface{}, []string)53}5455// AddVersion adds a new version.56// Expected to be called from the init package of a config package.57func AddVersion(version string, v ConfigVersion) {58if versions == nil {59versions = make(map[string]ConfigVersion)60}61versions[version] = v62}6364var (65ErrInvalidType = fmt.Errorf("invalid type")66)6768var versions map[string]ConfigVersion6970func LoadConfigVersion(version string) (ConfigVersion, error) {71v, ok := versions[version]72if !ok {73return nil, fmt.Errorf("unsupprted API version: %s", version)74}7576return v, nil77}7879// Load takes a config string and overrides that onto the default80// config for that version (passed in the config). If no config version81// is passed, It overrides it onto the default CurrentVersion of the binary82func Load(overrideConfig string, strict bool) (cfg interface{}, version string, err error) {83var overrideVS struct {84APIVersion string `json:"apiVersion"`85}86err = yaml.Unmarshal([]byte(overrideConfig), &overrideVS)87if err != nil {88return89}9091apiVersion := overrideVS.APIVersion92// fall-back to default CurrentVersion if no apiVersion was passed93if version == "" {94apiVersion = CurrentVersion95}9697v, err := LoadConfigVersion(apiVersion)98if err != nil {99return100}101102// Load default configuration103cfg = v.Factory()104err = v.Defaults(cfg)105if err != nil {106return107}108109// Remove the apiVersion from the config as this has already been parsed110// Use yq to make processing reliable111output, err := yq.Process(overrideConfig, "del(.apiVersion)")112if err != nil {113return114}115116// Override passed configuration onto the default117if strict {118err = yaml.UnmarshalStrict([]byte(*output), cfg)119} else {120err = yaml.Unmarshal([]byte(*output), cfg)121}122if err != nil {123return124}125126return cfg, apiVersion, nil127}128129func Marshal(version string, cfg interface{}) ([]byte, error) {130if _, ok := versions[version]; !ok {131return nil, fmt.Errorf("unsupported API version: %s", version)132}133134b, err := yaml.Marshal(cfg)135if err != nil {136return nil, err137}138139return []byte(fmt.Sprintf("apiVersion: %s\n%s", version, string(b))), nil140}141142143