|
|
@@ -48,7 +48,15 @@ type SubdomainCreateOpts struct {
|
|
|
stackName string
|
|
|
}
|
|
|
|
|
|
-func parse(porterYaml []byte, imageInfo types.ImageInfo, config *config.Config, projectID uint, opts SubdomainCreateOpts) (*chart.Chart, map[string]interface{}, error) {
|
|
|
+func parse(
|
|
|
+ porterYaml []byte,
|
|
|
+ imageInfo types.ImageInfo,
|
|
|
+ config *config.Config,
|
|
|
+ projectID uint,
|
|
|
+ existingValues map[string]interface{},
|
|
|
+ existingDependencies []*chart.Dependency,
|
|
|
+ opts SubdomainCreateOpts,
|
|
|
+) (*chart.Chart, map[string]interface{}, error) {
|
|
|
parsed := &PorterStackYAML{}
|
|
|
|
|
|
err := yaml.Unmarshal(porterYaml, parsed)
|
|
|
@@ -56,13 +64,13 @@ func parse(porterYaml []byte, imageInfo types.ImageInfo, config *config.Config,
|
|
|
return nil, nil, fmt.Errorf("%s: %w", "error parsing porter.yaml", err)
|
|
|
}
|
|
|
|
|
|
- values, err := buildStackValues(parsed, imageInfo, opts)
|
|
|
+ values, err := buildStackValues(parsed, imageInfo, existingValues, opts)
|
|
|
if err != nil {
|
|
|
return nil, nil, fmt.Errorf("%s: %w", "error building values from porter.yaml", err)
|
|
|
}
|
|
|
convertedValues := convertMap(values).(map[string]interface{})
|
|
|
|
|
|
- chart, err := buildStackChart(parsed, config, projectID)
|
|
|
+ chart, err := buildStackChart(parsed, config, projectID, existingDependencies)
|
|
|
if err != nil {
|
|
|
return nil, nil, fmt.Errorf("%s: %w", "error building chart from porter.yaml", err)
|
|
|
}
|
|
|
@@ -70,7 +78,7 @@ func parse(porterYaml []byte, imageInfo types.ImageInfo, config *config.Config,
|
|
|
return chart, convertedValues, nil
|
|
|
}
|
|
|
|
|
|
-func buildStackValues(parsed *PorterStackYAML, imageInfo types.ImageInfo, opts SubdomainCreateOpts) (map[string]interface{}, error) {
|
|
|
+func buildStackValues(parsed *PorterStackYAML, imageInfo types.ImageInfo, existingValues map[string]interface{}, opts SubdomainCreateOpts) (map[string]interface{}, error) {
|
|
|
values := make(map[string]interface{})
|
|
|
|
|
|
for name, app := range parsed.Apps {
|
|
|
@@ -82,7 +90,24 @@ func buildStackValues(parsed *PorterStackYAML, imageInfo types.ImageInfo, opts S
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
- values[name] = helm_values
|
|
|
+
|
|
|
+ // required to identify the chart type because of https://github.com/helm/helm/issues/9214
|
|
|
+ helmName := getHelmName(name, appType)
|
|
|
+ if existingValues != nil {
|
|
|
+ if existingValues[helmName] != nil {
|
|
|
+ existingValuesMap := existingValues[helmName].(map[string]interface{})
|
|
|
+ helm_values = utils.DeepCoalesceValues(existingValuesMap, helm_values)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ values[helmName] = helm_values
|
|
|
+ }
|
|
|
+
|
|
|
+ // add back in the existing values that were not overwritten
|
|
|
+ for k, v := range existingValues {
|
|
|
+ if values[k] == nil {
|
|
|
+ values[k] = v
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if imageInfo.Repository != "" && imageInfo.Tag != "" {
|
|
|
@@ -138,24 +163,52 @@ func getDefaultValues(app *App, env map[string]string, appType string) map[strin
|
|
|
return defaultValues
|
|
|
}
|
|
|
|
|
|
-func buildStackChart(parsed *PorterStackYAML, config *config.Config, projectID uint) (*chart.Chart, error) {
|
|
|
+func buildStackChart(parsed *PorterStackYAML, config *config.Config, projectID uint, existingDependencies []*chart.Dependency) (*chart.Chart, error) {
|
|
|
deps := make([]*chart.Dependency, 0)
|
|
|
-
|
|
|
for alias, app := range parsed.Apps {
|
|
|
- appType := getType(alias, app)
|
|
|
+ var appType string
|
|
|
+ if existingDependencies != nil {
|
|
|
+ for _, dep := range existingDependencies {
|
|
|
+ // this condition checks that the dependency is of the form <alias>-web or <alias>-wkr or <alias>-job, meaning it already exists in the chart
|
|
|
+ if strings.HasPrefix(dep.Alias, fmt.Sprintf("%s-", alias)) && (strings.HasSuffix(dep.Alias, "-web") || strings.HasSuffix(dep.Alias, "-wkr") || strings.HasSuffix(dep.Alias, "-job")) {
|
|
|
+ appType = getChartTypeFromHelmName(dep.Alias)
|
|
|
+ if appType == "" {
|
|
|
+ return nil, fmt.Errorf("unable to determine type of existing dependency")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // this is a new app, so we need to get the type from the app name or type
|
|
|
+ if appType == "" {
|
|
|
+ appType = getType(alias, app)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ appType = getType(alias, app)
|
|
|
+ }
|
|
|
selectedRepo := config.ServerConf.DefaultApplicationHelmRepoURL
|
|
|
selectedVersion, err := getLatestTemplateVersion(appType, config, projectID)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
+ helmName := getHelmName(alias, appType)
|
|
|
deps = append(deps, &chart.Dependency{
|
|
|
Name: appType,
|
|
|
- Alias: alias,
|
|
|
+ Alias: helmName,
|
|
|
Version: selectedVersion,
|
|
|
Repository: selectedRepo,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ // add in the existing dependencies that were not overwritten
|
|
|
+ for _, dep := range existingDependencies {
|
|
|
+ if !dependencyExists(deps, dep) {
|
|
|
+ // have to repair the dependency name because of https://github.com/helm/helm/issues/9214
|
|
|
+ if strings.HasSuffix(dep.Name, "-web") || strings.HasSuffix(dep.Name, "-wkr") || strings.HasSuffix(dep.Name, "-job") {
|
|
|
+ dep.Name = getChartTypeFromHelmName(dep.Name)
|
|
|
+ }
|
|
|
+ deps = append(deps, dep)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
chart, err := createChartFromDependencies(deps)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -164,6 +217,15 @@ func buildStackChart(parsed *PorterStackYAML, config *config.Config, projectID u
|
|
|
return chart, nil
|
|
|
}
|
|
|
|
|
|
+func dependencyExists(deps []*chart.Dependency, dep *chart.Dependency) bool {
|
|
|
+ for _, d := range deps {
|
|
|
+ if d.Alias == dep.Alias {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
func createChartFromDependencies(deps []*chart.Dependency) (*chart.Chart, error) {
|
|
|
metadata := &chart.Metadata{
|
|
|
Name: "umbrella",
|
|
|
@@ -354,3 +416,26 @@ func getNestedMap(obj map[string]interface{}, fields ...string) (map[string]inte
|
|
|
|
|
|
return res, nil
|
|
|
}
|
|
|
+
|
|
|
+func getHelmName(alias string, t string) string {
|
|
|
+ var suffix string
|
|
|
+ if t == "web" {
|
|
|
+ suffix = "-web"
|
|
|
+ } else if t == "worker" {
|
|
|
+ suffix = "-wkr"
|
|
|
+ } else if t == "job" {
|
|
|
+ suffix = "-job"
|
|
|
+ }
|
|
|
+ return fmt.Sprintf("%s%s", alias, suffix)
|
|
|
+}
|
|
|
+
|
|
|
+func getChartTypeFromHelmName(name string) string {
|
|
|
+ if strings.HasSuffix(name, "-web") {
|
|
|
+ return "web"
|
|
|
+ } else if strings.HasSuffix(name, "-wkr") {
|
|
|
+ return "worker"
|
|
|
+ } else if strings.HasSuffix(name, "-job") {
|
|
|
+ return "job"
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|