github.com/jenkins-x/jx/v2@v2.1.155/pkg/config/install_applications.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/ghodss/yaml"
    10  	"github.com/jenkins-x/jx/v2/pkg/util"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  const (
    15  	// ApplicationsConfigFileName is the name of the applications configuration file
    16  	ApplicationsConfigFileName = "jx-apps.yml"
    17  	// PhaseSystem is installed before the apps phase
    18  	PhaseSystem Phase = "system"
    19  	// PhaseApps is installed after the system phase
    20  	PhaseApps Phase = "apps"
    21  )
    22  
    23  // PhaseValues the string values for Phases
    24  var PhaseValues = []string{"system", "apps"}
    25  
    26  // ApplicationConfig contains applications to install during boot
    27  type ApplicationConfig struct {
    28  	// Applications of applications
    29  	Applications []Application `json:"applications"`
    30  	// DefaultNamespace the default namespace to install applications into
    31  	DefaultNamespace string `json:"defaultNamespace"`
    32  }
    33  
    34  // Application is an application to install during boot
    35  type Application struct {
    36  	// Name of the application / helm chart
    37  	Name string `json:"name"`
    38  	// Repository the helm repository
    39  	Repository string `json:"repository"`
    40  	// Namespace to install the application into
    41  	Namespace string `json:"namespace,omitempty"`
    42  	// Phase of the pipeline to install application
    43  	Phase Phase `json:"phase,omitempty"`
    44  }
    45  
    46  // Phase of the pipeline to install application
    47  type Phase string
    48  
    49  // LoadApplicationsConfig loads the boot applications configuration file
    50  // if there is not a file called `jx-apps.yml` in the given dir we will scan up the parent
    51  // directories looking for the requirements file as we often run 'jx' steps in sub directories.
    52  func LoadApplicationsConfig(dir string) (*ApplicationConfig, error) {
    53  	fileName := ApplicationsConfigFileName
    54  	if dir != "" {
    55  		fileName = filepath.Join(dir, fileName)
    56  	}
    57  
    58  	exists, err := util.FileExists(fileName)
    59  	if err != nil || !exists {
    60  		return nil, errors.Errorf("no %s found in directory %s", fileName, dir)
    61  	}
    62  
    63  	config := &ApplicationConfig{}
    64  
    65  	data, err := ioutil.ReadFile(fileName)
    66  	if err != nil {
    67  		return config, fmt.Errorf("Failed to load file %s due to %s", fileName, err)
    68  	}
    69  	validationErrors, err := util.ValidateYaml(config, data)
    70  	if err != nil {
    71  		return config, fmt.Errorf("failed to validate YAML file %s due to %s", fileName, err)
    72  	}
    73  	if len(validationErrors) > 0 {
    74  		return config, fmt.Errorf("Validation failures in YAML file %s:\n%s", fileName, strings.Join(validationErrors, "\n"))
    75  	}
    76  	err = yaml.Unmarshal(data, config)
    77  	if err != nil {
    78  		return config, fmt.Errorf("Failed to unmarshal YAML file %s due to %s", fileName, err)
    79  	}
    80  
    81  	// validate all phases are known types, default to apps if not specified
    82  	for _, app := range config.Applications {
    83  		if app.Phase != "" {
    84  			if app.Phase != PhaseSystem && app.Phase != PhaseApps {
    85  				return config, fmt.Errorf("failed to validate YAML file, invalid phase '%s', needed on of %v",
    86  					string(app.Phase), PhaseValues)
    87  			}
    88  		}
    89  	}
    90  
    91  	return config, err
    92  }