Path: blob/main/components/content-service-api/go/initializer.go
2498 views
// Copyright (c) 2022 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 api56import (7"fmt"8"strconv"9"strings"1011"golang.org/x/xerrors"12)1314// GetCheckoutLocationsFromInitializer returns a list of all checkout locations from the initializer15func GetCheckoutLocationsFromInitializer(init *WorkspaceInitializer) []string {16var res []string17_ = WalkInitializer(nil, init, func(path []string, init *WorkspaceInitializer) error {18switch spec := init.Spec.(type) {19case *WorkspaceInitializer_Git:20res = append(res, spec.Git.CheckoutLocation)21case *WorkspaceInitializer_Backup:22res = append(res, spec.Backup.CheckoutLocation)2324case *WorkspaceInitializer_Prebuild:25// walkInitializer will visit the Git initializer26}2728return nil29})30return res31}3233const extractedSecretPrefix = "extracted-secret/"3435// GatherSecretsFromInitializer collects all from an initializer. This function does not36// alter the initializer in any way.37func GatherSecretsFromInitializer(init *WorkspaceInitializer) map[string]string {38return extractSecretsFromInitializer(init, false)39}4041// ExtractAndReplaceSecretsFromInitializer removes secrets to the initializer.42// This function alters the initializer, which only becomes useful calling InjectSecretsToInitializer.43// This is the counterpart of InjectSecretsToInitializer.44func ExtractAndReplaceSecretsFromInitializer(init *WorkspaceInitializer) map[string]string {45return extractSecretsFromInitializer(init, true)46}4748func extractSecretsFromInitializer(init *WorkspaceInitializer, replaceValue bool) map[string]string {49res := make(map[string]string)5051_ = WalkInitializer([]string{"initializer"}, init, func(path []string, init *WorkspaceInitializer) error {52git, ok := init.Spec.(*WorkspaceInitializer_Git)53if !ok {54return nil55}5657pwd := git.Git.Config.AuthPassword58if pwd == "" || strings.HasPrefix(pwd, extractedSecretPrefix) {59return nil60}6162name := strings.Join(path, ".")63res[name] = pwd6465if replaceValue {66git.Git.Config.AuthPassword = extractedSecretPrefix + name67}6869return nil70})7172return res73}7475// InjectSecretsToInitializer injects secrets to the initializer. This is the counterpart of ExtractSecretsFromInitializer.76func InjectSecretsToInitializer(init *WorkspaceInitializer, secrets map[string][]byte) error {77return WalkInitializer([]string{"initializer"}, init, func(path []string, init *WorkspaceInitializer) error {78git, ok := init.Spec.(*WorkspaceInitializer_Git)79if !ok {80return nil81}8283pwd := git.Git.Config.AuthPassword84if !strings.HasPrefix(pwd, extractedSecretPrefix) {85return nil86}8788name := strings.TrimPrefix(pwd, extractedSecretPrefix)89val, ok := secrets[name]90if !ok {91return xerrors.Errorf("secret %s not found", name)92}9394git.Git.Config.AuthPassword = string(val)9596return nil97})98}99100// WalkInitializer walks the initializer structure101func WalkInitializer(path []string, init *WorkspaceInitializer, visitor func(path []string, init *WorkspaceInitializer) error) error {102if init == nil {103return nil104}105106switch spec := init.Spec.(type) {107case *WorkspaceInitializer_Empty:108return visitor(append(path, "empty"), init)109case *WorkspaceInitializer_Git:110return visitor(append(path, "git"), init)111case *WorkspaceInitializer_Snapshot:112return visitor(append(path, "snapshot"), init)113case *WorkspaceInitializer_Prebuild:114child := append(path, "prebuild")115err := visitor(child, init)116if err != nil {117return err118}119for i, g := range spec.Prebuild.Git {120err = WalkInitializer(append(child, strconv.Itoa(i)), &WorkspaceInitializer{Spec: &WorkspaceInitializer_Git{Git: g}}, visitor)121if err != nil {122return err123}124}125return nil126case *WorkspaceInitializer_Composite:127path = append(path, "composite")128err := visitor(path, init)129if err != nil {130return err131}132for i, p := range spec.Composite.Initializer {133err := WalkInitializer(append(path, strconv.Itoa(i)), p, visitor)134if err != nil {135return err136}137}138return nil139case *WorkspaceInitializer_Download:140return visitor(append(path, "download"), init)141case *WorkspaceInitializer_Backup:142return visitor(append(path, "backup"), init)143144default:145return fmt.Errorf("unsupported workspace initializer in walkInitializer - this is a bug in Gitpod")146}147}148149150