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