github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/packages/helm/metadata.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package helm 7 8 import ( 9 "archive/tar" 10 "compress/gzip" 11 "errors" 12 "io" 13 "strings" 14 15 "github.com/gitbundle/modules/validation" 16 17 "github.com/hashicorp/go-version" 18 "gopkg.in/yaml.v2" 19 ) 20 21 var ( 22 // ErrMissingChartFile indicates a missing Chart.yaml file 23 ErrMissingChartFile = errors.New("Chart.yaml file is missing") 24 // ErrInvalidName indicates an invalid package name 25 ErrInvalidName = errors.New("package name is invalid") 26 // ErrInvalidVersion indicates an invalid package version 27 ErrInvalidVersion = errors.New("package version is invalid") 28 // ErrInvalidChart indicates an invalid chart 29 ErrInvalidChart = errors.New("chart is invalid") 30 ) 31 32 // Metadata for a Chart file. This models the structure of a Chart.yaml file. 33 type Metadata struct { 34 APIVersion string `json:"api_version" yaml:"apiVersion"` 35 Type string `json:"type,omitempty" yaml:"type,omitempty"` 36 Name string `json:"name" yaml:"name"` 37 Version string `json:"version" yaml:"version"` 38 AppVersion string `json:"app_version,omitempty" yaml:"appVersion,omitempty"` 39 Home string `json:"home,omitempty" yaml:"home,omitempty"` 40 Sources []string `json:"sources,omitempty" yaml:"sources,omitempty"` 41 Description string `json:"description,omitempty" yaml:"description,omitempty"` 42 Keywords []string `json:"keywords,omitempty" yaml:"keywords,omitempty"` 43 Maintainers []*Maintainer `json:"maintainers,omitempty" yaml:"maintainers,omitempty"` 44 Icon string `json:"icon,omitempty" yaml:"icon,omitempty"` 45 Condition string `json:"condition,omitempty" yaml:"condition,omitempty"` 46 Tags string `json:"tags,omitempty" yaml:"tags,omitempty"` 47 Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"` 48 Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` 49 KubeVersion string `json:"kube_version,omitempty" yaml:"kubeVersion,omitempty"` 50 Dependencies []*Dependency `json:"dependencies,omitempty" yaml:"dependencies,omitempty"` 51 } 52 53 type Maintainer struct { 54 Name string `json:"name,omitempty" yaml:"name,omitempty"` 55 Email string `json:"email,omitempty" yaml:"email,omitempty"` 56 URL string `json:"url,omitempty" yaml:"url,omitempty"` 57 } 58 59 type Dependency struct { 60 Name string `json:"name" yaml:"name"` 61 Version string `json:"version,omitempty" yaml:"version,omitempty"` 62 Repository string `json:"repository" yaml:"repository"` 63 Condition string `json:"condition,omitempty" yaml:"condition,omitempty"` 64 Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` 65 Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` 66 ImportValues []interface{} `json:"import_values,omitempty" yaml:"import-values,omitempty"` 67 Alias string `json:"alias,omitempty" yaml:"alias,omitempty"` 68 } 69 70 // ParseChartArchive parses the metadata of a Helm archive 71 func ParseChartArchive(r io.Reader) (*Metadata, error) { 72 gzr, err := gzip.NewReader(r) 73 if err != nil { 74 return nil, err 75 } 76 defer gzr.Close() 77 78 tr := tar.NewReader(gzr) 79 for { 80 hd, err := tr.Next() 81 if err == io.EOF { 82 break 83 } 84 if err != nil { 85 return nil, err 86 } 87 88 if hd.Typeflag != tar.TypeReg { 89 continue 90 } 91 92 if hd.FileInfo().Name() == "Chart.yaml" { 93 if strings.Count(hd.Name, "/") != 1 { 94 continue 95 } 96 97 return ParseChartFile(tr) 98 } 99 } 100 101 return nil, ErrMissingChartFile 102 } 103 104 // ParseChartFile parses a Chart.yaml file to retrieve the metadata of a Helm chart 105 func ParseChartFile(r io.Reader) (*Metadata, error) { 106 var metadata *Metadata 107 if err := yaml.NewDecoder(r).Decode(&metadata); err != nil { 108 return nil, err 109 } 110 111 if metadata.APIVersion == "" { 112 return nil, ErrInvalidChart 113 } 114 115 if metadata.Type != "" && metadata.Type != "application" && metadata.Type != "library" { 116 return nil, ErrInvalidChart 117 } 118 119 if metadata.Name == "" { 120 return nil, ErrInvalidName 121 } 122 123 if _, err := version.NewSemver(metadata.Version); err != nil { 124 return nil, ErrInvalidVersion 125 } 126 127 if !validation.IsValidURL(metadata.Home) { 128 metadata.Home = "" 129 } 130 131 return metadata, nil 132 }