github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/render/transform/transform.go (about)

     1  /*
     2  Copyright 2021 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package transform
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	sErrors "github.com/GoogleContainerTools/skaffold/pkg/skaffold/errors"
    24  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/render/kptfile"
    25  	latestV2 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v2"
    26  	"github.com/GoogleContainerTools/skaffold/proto/v1"
    27  )
    28  
    29  var (
    30  	allowListedTransformer = []string{"set-labels"}
    31  	transformerAllowlist   = map[string]kptfile.Function{
    32  		"set-labels": {
    33  			Image:     "gcr.io/kpt-fn/set-labels:v0.1",
    34  			ConfigMap: map[string]string{},
    35  		},
    36  	}
    37  )
    38  
    39  // NewTransformer instantiates a Transformer object.
    40  func NewTransformer(config []latestV2.Transformer) (*Transformer, error) {
    41  	newFuncs, err := validateTransformers(config)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	return &Transformer{kptFn: newFuncs, needRefresh: true, config: config}, nil
    46  }
    47  
    48  type Transformer struct {
    49  	needRefresh bool
    50  	kptFn       []kptfile.Function
    51  	config      []latestV2.Transformer
    52  }
    53  
    54  // GetDeclarativeValidators transforms and returns the skaffold validators defined in skaffold.yaml
    55  func (v *Transformer) GetDeclarativeTransformers() ([]kptfile.Function, error) {
    56  	// TODO: guarantee the v.kptFn is updated once users changed skaffold.yaml file.
    57  	if v.needRefresh {
    58  		newFuncs, err := validateTransformers(v.config)
    59  		if err != nil {
    60  			return nil, err
    61  		}
    62  		v.kptFn = newFuncs
    63  		v.needRefresh = false
    64  	}
    65  	return v.kptFn, nil
    66  }
    67  
    68  func validateTransformers(config []latestV2.Transformer) ([]kptfile.Function, error) {
    69  	var newFuncs []kptfile.Function
    70  	for _, c := range config {
    71  		newFunc, ok := transformerAllowlist[c.Name]
    72  		if !ok {
    73  			// TODO: Add links to explain "skaffold-managed mode" and "kpt-managed mode".
    74  			return nil, sErrors.NewErrorWithStatusCode(
    75  				&proto.ActionableErr{
    76  					Message: fmt.Sprintf("unsupported transformer %q", c.Name),
    77  					ErrCode: proto.StatusCode_CONFIG_UNKNOWN_TRANSFORMER,
    78  					Suggestions: []*proto.Suggestion{
    79  						{
    80  							SuggestionCode: proto.SuggestionCode_CONFIG_ALLOWLIST_transformers,
    81  							Action: fmt.Sprintf(
    82  								"please only use the following transformers in skaffold-managed mode: %v. "+
    83  									"to use custom transformers, please use kpt-managed mode.", allowListedTransformer),
    84  						},
    85  					},
    86  				})
    87  		}
    88  		if c.ConfigMap != nil {
    89  			for _, stringifiedData := range c.ConfigMap {
    90  				items := strings.Split(stringifiedData, ":")
    91  				if len(items) != 2 {
    92  					return nil, sErrors.NewErrorWithStatusCode(
    93  						&proto.ActionableErr{
    94  							Message: fmt.Sprintf("unknown arguments for transformer %v", c.Name),
    95  							ErrCode: proto.StatusCode_CONFIG_UNKNOWN_TRANSFORMER,
    96  							Suggestions: []*proto.Suggestion{
    97  								{
    98  									SuggestionCode: proto.SuggestionCode_CONFIG_ALLOWLIST_transformers,
    99  									Action: fmt.Sprintf("please check if the .transformer field and " +
   100  										"make sure `configMapData` is a list of data in the form of `${KEY}=${VALUE}`"),
   101  								},
   102  							},
   103  						})
   104  				}
   105  				newFunc.ConfigMap[items[0]] = items[1]
   106  			}
   107  		}
   108  		newFuncs = append(newFuncs, newFunc)
   109  	}
   110  	return newFuncs, nil
   111  }