1package manifest 2 3import ( 4 "regexp" 5 "strings" 6 7 bosherr "github.com/cloudfoundry/bosh-utils/errors" 8 boshlog "github.com/cloudfoundry/bosh-utils/logger" 9) 10 11type Validator interface { 12 Validate(Manifest) error 13} 14 15type validator struct { 16 logger boshlog.Logger 17} 18 19func NewValidator(logger boshlog.Logger) Validator { 20 return &validator{logger: logger} 21} 22 23func (v *validator) Validate(manifest Manifest) error { 24 errs := []error{} 25 releaseNames := map[string]struct{}{} 26 if len(manifest.Releases) < 1 { 27 errs = append(errs, bosherr.Errorf("releases must contain at least 1 release")) 28 } 29 30 for releaseIdx, release := range manifest.Releases { 31 if v.isBlank(release.Name) { 32 errs = append(errs, bosherr.Errorf("releases[%d].name must be provided", releaseIdx)) 33 } 34 35 if _, found := releaseNames[release.Name]; found { 36 errs = append(errs, bosherr.Errorf("releases[%d].name '%s' must be unique", releaseIdx, release.Name)) 37 } 38 releaseNames[release.Name] = struct{}{} 39 40 if v.isBlank(release.URL) { 41 errs = append(errs, bosherr.Errorf("releases[%d].url must be provided", releaseIdx)) 42 } 43 44 matched, err := regexp.MatchString("^(file|http|https)://", release.URL) 45 if err != nil || !matched { 46 errs = append(errs, bosherr.Errorf("releases[%d].url must be a valid URL (file:// or http(s)://)", releaseIdx)) 47 } 48 49 if strings.HasPrefix(release.URL, "http") && v.isBlank(release.SHA1) { 50 errs = append(errs, bosherr.Errorf("releases[%d].sha1 must be provided for http URL", releaseIdx)) 51 } 52 } 53 54 if len(errs) > 0 { 55 return bosherr.NewMultiError(errs...) 56 } 57 58 return nil 59} 60 61func (v *validator) isBlank(str string) bool { 62 return str == "" || strings.TrimSpace(str) == "" 63} 64