...

Source file src/github.com/redhat-developer/odo/pkg/devfile/devfile.go

Documentation: github.com/redhat-developer/odo/pkg/devfile

     1  package devfile
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/devfile/api/v2/pkg/validation/variables"
    10  	"github.com/devfile/library/v2/pkg/devfile"
    11  	"github.com/devfile/library/v2/pkg/devfile/parser"
    12  	"k8s.io/utils/pointer"
    13  
    14  	"github.com/redhat-developer/odo/pkg/devfile/validate"
    15  	"github.com/redhat-developer/odo/pkg/log"
    16  )
    17  
    18  func parseRawDevfile(args parser.ParserArgs) (parser.DevfileObj, error) {
    19  	args.FlattenedDevfile = pointer.Bool(false)
    20  	args.ConvertKubernetesContentInUri = pointer.Bool(false)
    21  	args.ImageNamesAsSelector = nil
    22  	args.SetBooleanDefaults = pointer.Bool(false)
    23  
    24  	devfileObj, varWarnings, err := devfile.ParseDevfileAndValidate(args)
    25  	if err != nil {
    26  		return parser.DevfileObj{}, err
    27  	}
    28  
    29  	// display warnings related to variable substitution
    30  	displayVariableWarnings(varWarnings)
    31  
    32  	return devfileObj, nil
    33  }
    34  
    35  func parseEffectiveDevfile(args parser.ParserArgs) (parser.DevfileObj, error) {
    36  	// Effective Devfile with everything resolved (e.g., parent flattened, K8s URIs inlined, ...)
    37  	args.SetBooleanDefaults = pointer.Bool(false)
    38  	args.FlattenedDevfile = pointer.Bool(true)
    39  	args.ConvertKubernetesContentInUri = pointer.Bool(true)
    40  	if args.ImageNamesAsSelector != nil && args.ImageNamesAsSelector.Registry != "" {
    41  		// Tag should be a unique build identifier
    42  		args.ImageNamesAsSelector.Tag = strconv.Itoa(os.Getpid())
    43  	} else {
    44  		args.ImageNamesAsSelector = nil
    45  	}
    46  
    47  	var varWarnings variables.VariableWarning
    48  	devfileObj, varWarnings, err := devfile.ParseDevfileAndValidate(args)
    49  	if err != nil {
    50  		return parser.DevfileObj{}, err
    51  	}
    52  
    53  	// odo specific validations
    54  	err = validate.ValidateDevfileData(devfileObj.Data)
    55  	if err != nil {
    56  		return parser.DevfileObj{}, err
    57  	}
    58  
    59  	// display warnings related to variable substitution
    60  	displayVariableWarnings(varWarnings)
    61  
    62  	return devfileObj, nil
    63  }
    64  
    65  // ParseAndValidateFromFile reads, parses and validates  devfile from a file
    66  // if there are warning it logs them on stdout
    67  func ParseAndValidateFromFile(devfilePath string, imageRegistry string, wantEffective bool) (parser.DevfileObj, error) {
    68  	parserArgs := parser.ParserArgs{
    69  		Path: devfilePath,
    70  		ImageNamesAsSelector: &parser.ImageSelectorArgs{
    71  			Registry: imageRegistry,
    72  		},
    73  	}
    74  	if wantEffective {
    75  		return parseEffectiveDevfile(parserArgs)
    76  	}
    77  	return parseRawDevfile(parserArgs)
    78  }
    79  
    80  // ParseAndValidateFromFileWithVariables reads, parses and validates  devfile from a file
    81  // variables are used to override devfile variables.
    82  // If wantEffective is true, it returns a complete view of the Devfile, where everything is resolved.
    83  // For example, parent will be flattened in the child, and Kubernetes manifests referenced by URI will be inlined in the related components.
    84  // If there are warnings, it logs them on stdout.
    85  func ParseAndValidateFromFileWithVariables(devfilePath string, variables map[string]string, imageRegistry string, wantEffective bool) (parser.DevfileObj, error) {
    86  	parserArgs := parser.ParserArgs{
    87  		Path:              devfilePath,
    88  		ExternalVariables: variables,
    89  		ImageNamesAsSelector: &parser.ImageSelectorArgs{
    90  			Registry: imageRegistry,
    91  		},
    92  	}
    93  	if wantEffective {
    94  		return parseEffectiveDevfile(parserArgs)
    95  	}
    96  	return parseRawDevfile(parserArgs)
    97  }
    98  
    99  func displayVariableWarnings(varWarnings variables.VariableWarning) {
   100  	variableWarning := func(section string, variable string, messages []string) string {
   101  		var quotedVars []string
   102  		for _, v := range messages {
   103  			quotedVars = append(quotedVars, fmt.Sprintf("%q", v))
   104  		}
   105  		return fmt.Sprintf("Invalid variable(s) %s in %q section with name %q. ", strings.Join(quotedVars, ","), section, variable)
   106  	}
   107  
   108  	for variable, messages := range varWarnings.Commands {
   109  		log.Warningf(variableWarning("commands", variable, messages))
   110  	}
   111  	for variable, messages := range varWarnings.Components {
   112  		log.Warningf(variableWarning("components", variable, messages))
   113  	}
   114  	for variable, messages := range varWarnings.Projects {
   115  		log.Warningf(variableWarning("projects", variable, messages))
   116  	}
   117  	for variable, messages := range varWarnings.StarterProjects {
   118  		log.Warningf(variableWarning("starterProjects", variable, messages))
   119  	}
   120  
   121  }
   122  

View as plain text