github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/initializer/deploy/kustomize.go (about)

     1  /*
     2  Copyright 2020 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 deploy
    18  
    19  import (
    20  	"context"
    21  	"path/filepath"
    22  
    23  	pkgkustomize "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/kustomize"
    24  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer/errors"
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes"
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    28  )
    29  
    30  // kustomize implements deploymentInitializer for the kustomize deployer.
    31  type kustomize struct {
    32  	defaultKustomization string
    33  	kustomizations       []string
    34  	bases                []string
    35  	images               []string
    36  }
    37  
    38  // newKustomizeInitializer returns a kustomize config generator.
    39  func newKustomizeInitializer(defaultKustomization string, bases, kustomizations, potentialConfigs []string) *kustomize {
    40  	var images []string
    41  	for _, file := range potentialConfigs {
    42  		imgs, err := kubernetes.ParseImagesFromKubernetesYaml(file)
    43  		if err == nil {
    44  			images = append(images, imgs...)
    45  		}
    46  	}
    47  	return &kustomize{
    48  		defaultKustomization: defaultKustomization,
    49  		images:               images,
    50  		bases:                bases,
    51  		kustomizations:       kustomizations,
    52  	}
    53  }
    54  
    55  // deployConfig implements the Initializer interface and generates
    56  // a kustomize deployment config.
    57  func (k *kustomize) DeployConfig() (latest.DeployConfig, []latest.Profile) {
    58  	var kustomizeConfig *latest.KustomizeDeploy
    59  	var profiles []latest.Profile
    60  
    61  	// if there's only one kustomize path, either leave it blank (if it's the default path),
    62  	// or generate a config with that single path and return it
    63  	if len(k.kustomizations) == 1 {
    64  		if k.kustomizations[0] == pkgkustomize.DefaultKustomizePath {
    65  			kustomizeConfig = &latest.KustomizeDeploy{}
    66  		} else {
    67  			kustomizeConfig = &latest.KustomizeDeploy{
    68  				KustomizePaths: k.kustomizations,
    69  			}
    70  		}
    71  		return latest.DeployConfig{
    72  			DeployType: latest.DeployType{
    73  				KustomizeDeploy: kustomizeConfig,
    74  			},
    75  		}, nil
    76  	}
    77  
    78  	// if there are multiple paths, generate a config that chooses a default
    79  	// kustomization based on our heuristic, and creates separate profiles
    80  	// for all other overlays in the project
    81  	defaultKustomization := k.defaultKustomization
    82  	if defaultKustomization == "" {
    83  		// either choose one that's called "dev", or else the first one that isn't called "prod"
    84  		dev, prod := -1, -1
    85  		for i, kustomization := range k.kustomizations {
    86  			switch filepath.Base(kustomization) {
    87  			case "dev":
    88  				dev = i
    89  			case "prod":
    90  				prod = i
    91  			default:
    92  			}
    93  		}
    94  
    95  		switch {
    96  		case dev != -1:
    97  			defaultKustomization = k.kustomizations[dev]
    98  		case prod == 0:
    99  			defaultKustomization = k.kustomizations[1]
   100  		default:
   101  			defaultKustomization = k.kustomizations[0]
   102  		}
   103  		log.Entry(context.TODO()).Warnf("multiple kustomizations found but no default provided - defaulting to %s", defaultKustomization)
   104  	}
   105  
   106  	for _, kustomization := range k.kustomizations {
   107  		if kustomization == defaultKustomization {
   108  			kustomizeConfig = &latest.KustomizeDeploy{
   109  				KustomizePaths: []string{defaultKustomization},
   110  			}
   111  		} else {
   112  			profiles = append(profiles, latest.Profile{
   113  				Name: filepath.Base(kustomization),
   114  				Pipeline: latest.Pipeline{
   115  					Deploy: latest.DeployConfig{
   116  						DeployType: latest.DeployType{
   117  							KustomizeDeploy: &latest.KustomizeDeploy{
   118  								KustomizePaths: []string{kustomization},
   119  							},
   120  						},
   121  					},
   122  				},
   123  			})
   124  		}
   125  	}
   126  
   127  	return latest.DeployConfig{
   128  		DeployType: latest.DeployType{
   129  			KustomizeDeploy: kustomizeConfig,
   130  		},
   131  	}, profiles
   132  }
   133  
   134  // GetImages implements the Initializer interface and lists all the
   135  // images present in the k8s manifest files.
   136  func (k *kustomize) GetImages() []string {
   137  	return k.images
   138  }
   139  
   140  // Validate implements the Initializer interface and ensures
   141  // we have at least one manifest before generating a config
   142  func (k *kustomize) Validate() error {
   143  	if len(k.images) == 0 {
   144  		return errors.NoManifestErr{}
   145  	}
   146  	return nil
   147  }
   148  
   149  // we don't generate k8s manifests for a kustomize deploy
   150  func (k *kustomize) AddManifestForImage(string, string) {}