diff --git a/.golangci.yaml b/.golangci.yaml index 62434899..fa92db63 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -21,6 +21,7 @@ linters: - ineffassign - misspell - nolintlint + - nonamedreturns - prealloc - revive - sloglint @@ -74,6 +75,10 @@ linters-settings: desc: "The 'github.com/evanphx/json-patch' package is superseded. Use pkg/utils/jsonpatch.go instead." - pkg: "gopkg.in/satori/go.uuid.v1" desc: "Use https://github.com/gofrs/uuid instead. Satori/go.uuid is no longer maintained and has critical vulnerabilities." + nonamedreturns: + # Report named error if it is assigned inside defer. + # Default: false + report-error-in-defer: false issues: exclude: # Using underscores is a common practice, refactor in the future diff --git a/pkg/addon-operator/bootstrap.go b/pkg/addon-operator/bootstrap.go index 1544f88d..e31df581 100644 --- a/pkg/addon-operator/bootstrap.go +++ b/pkg/addon-operator/bootstrap.go @@ -43,7 +43,7 @@ func (op *AddonOperator) bootstrap() error { return nil } -func (op *AddonOperator) Assemble(debugServer *debug.Server) (err error) { +func (op *AddonOperator) Assemble(debugServer *debug.Server) error { op.registerDefaultRoutes() if app.AdmissionServerEnabled { op.AdmissionServer.start(op.ctx) @@ -58,8 +58,7 @@ func (op *AddonOperator) Assemble(debugServer *debug.Server) (err error) { op.RegisterDebugModuleRoutes(debugServer) op.RegisterDiscoveryRoute(debugServer) - err = op.InitModuleManager() - if err != nil { + if err := op.InitModuleManager(); err != nil { return err } diff --git a/pkg/addon-operator/operator.go b/pkg/addon-operator/operator.go index 93b8ff24..63940930 100644 --- a/pkg/addon-operator/operator.go +++ b/pkg/addon-operator/operator.go @@ -738,13 +738,16 @@ func (op *AddonOperator) CreatePurgeTasks(modulesToPurge []string, t sh_task.Tas return newTasks } -// HandleApplyKubeConfigValues ... -func (op *AddonOperator) HandleApplyKubeConfigValues(t sh_task.Task, logLabels map[string]string) (res queue.TaskResult) { - var handleErr error +// ApplyKubeConfigValues +func (op *AddonOperator) HandleApplyKubeConfigValues(t sh_task.Task, logLabels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "HandleApplyKubeConfigValues").End() - logEntry := utils.EnrichLoggerWithLabels(op.Logger, logLabels) - hm := task.HookMetadataAccessor(t) + var ( + handleErr error + res queue.TaskResult + logEntry = utils.EnrichLoggerWithLabels(op.Logger, logLabels) + hm = task.HookMetadataAccessor(t) + ) op.KubeConfigManager.SafeReadConfig(func(config *config.KubeConfig) { handleErr = op.ModuleManager.ApplyNewKubeConfigValues(config, hm.GlobalValuesChanged) @@ -764,12 +767,14 @@ func (op *AddonOperator) HandleApplyKubeConfigValues(t sh_task.Task, logLabels m res.Status = queue.Success logEntry.Debug("HandleApplyKubeConfigValues success") - return + return res } // HandleConvergeModules is a multi-phase task. -func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "ConvergeModules").End() + + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, logLabels) taskEvent, ok := t.GetProp(converge.ConvergeEventProp).(converge.ConvergeEvent) @@ -802,7 +807,7 @@ func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[str res.HeadTasks = tasks res.Status = queue.Keep op.logTaskAdd(logEntry, "head", res.HeadTasks...) - return + return res } } @@ -829,7 +834,7 @@ func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[str res.HeadTasks = tasks res.Status = queue.Keep op.logTaskAdd(logEntry, "head", res.HeadTasks...) - return + return res } } } @@ -844,7 +849,7 @@ func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[str res.HeadTasks = tasks res.Status = queue.Keep op.logTaskAdd(logEntry, "head", res.HeadTasks...) - return + return res } } } @@ -871,6 +876,7 @@ func (op *AddonOperator) HandleConvergeModules(t sh_task.Task, logLabels map[str logEntry.Debug("ConvergeModules success") res.Status = queue.Success + return res } @@ -913,6 +919,7 @@ func (op *AddonOperator) CreateBeforeAllTasks(logLabels map[string]string, event }) tasks = append(tasks, newTask.WithQueuedAt(queuedAt)) } + return tasks } @@ -969,6 +976,7 @@ func (op *AddonOperator) CreateAndStartQueue(queueName string) bool { } op.engine.TaskQueues.NewNamedQueue(queueName, op.TaskHandler) op.engine.TaskQueues.GetByName(queueName).Start() + return true } @@ -1457,9 +1465,10 @@ func (op *AddonOperator) UpdateWaitInQueueMetric(t sh_task.Task) { } // HandleGlobalHookEnableKubernetesBindings add Synchronization tasks. -func (op *AddonOperator) HandleGlobalHookEnableKubernetesBindings(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleGlobalHookEnableKubernetesBindings(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "DiscoverHelmReleases").End() + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) logEntry.Debug("Global hook enable kubernetes bindings") @@ -1532,7 +1541,7 @@ func (op *AddonOperator) HandleGlobalHookEnableKubernetesBindings(t sh_task.Task t.UpdateFailureMessage(err.Error()) t.WithQueuedAt(queuedAt) res.Status = queue.Fail - return + return res } // Substitute current task with Synchronization tasks for the main queue. // Other Synchronization tasks are queued into specified queues. @@ -1571,13 +1580,14 @@ func (op *AddonOperator) HandleGlobalHookEnableKubernetesBindings(t sh_task.Task res.Status = queue.Success - return + return res } // HandleDiscoverHelmReleases runs RefreshStateFromHelmReleases to detect modules state at start. -func (op *AddonOperator) HandleDiscoverHelmReleases(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleDiscoverHelmReleases(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "DiscoverHelmReleases").End() + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) logEntry.Debug("Discover Helm releases state") @@ -1589,20 +1599,21 @@ func (op *AddonOperator) HandleDiscoverHelmReleases(t sh_task.Task, labels map[s log.Err(err)) t.UpdateFailureMessage(err.Error()) t.WithQueuedAt(time.Now()) - return + return res } res.Status = queue.Success tasks := op.CreatePurgeTasks(state.ModulesToPurge, t) res.AfterTasks = tasks op.logTaskAdd(logEntry, "after", res.AfterTasks...) - return + return res } // HandleModulePurge run helm purge for unknown module. -func (op *AddonOperator) HandleModulePurge(t sh_task.Task, labels map[string]string) (status queue.TaskStatus) { +func (op *AddonOperator) HandleModulePurge(t sh_task.Task, labels map[string]string) queue.TaskStatus { defer trace.StartRegion(context.Background(), "ModulePurge").End() + var status queue.TaskStatus logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) logEntry.Debug("Module purge start") @@ -1616,18 +1627,17 @@ func (op *AddonOperator) HandleModulePurge(t sh_task.Task, labels map[string]str } status = queue.Success - return + + return status } // HandleModuleDelete deletes helm release for known module. -func (op *AddonOperator) HandleModuleDelete(t sh_task.Task, labels map[string]string) (status queue.TaskStatus) { +func (op *AddonOperator) HandleModuleDelete(t sh_task.Task, labels map[string]string) queue.TaskStatus { defer trace.StartRegion(context.Background(), "ModuleDelete").End() + var status queue.TaskStatus hm := task.HookMetadataAccessor(t) - status = queue.Success - baseModule := op.ModuleManager.GetModule(hm.ModuleName) - logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) logEntry.Debug("Module delete", slog.String("name", hm.ModuleName)) @@ -1660,18 +1670,18 @@ func (op *AddonOperator) HandleModuleDelete(t sh_task.Task, labels map[string]st status = queue.Success } - return + return status } // HandleModuleEnsureCRDs ensure CRDs for module. -func (op *AddonOperator) HandleModuleEnsureCRDs(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleModuleEnsureCRDs(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "ModuleEnsureCRDs").End() hm := task.HookMetadataAccessor(t) - res.Status = queue.Success - + res := queue.TaskResult{ + Status: queue.Success, + } baseModule := op.ModuleManager.GetModule(hm.ModuleName) - logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) logEntry.Debug("Module ensureCRDs", slog.String("name", hm.ModuleName)) @@ -1689,12 +1699,14 @@ func (op *AddonOperator) HandleModuleEnsureCRDs(t sh_task.Task, labels map[strin op.discoveredGVKsLock.Unlock() } - return + return res } // HandleParallelModuleRun runs multiple HandleModuleRun tasks in parallel and aggregates their results -func (op *AddonOperator) HandleParallelModuleRun(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleParallelModuleRun(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "ParallelModuleRun").End() + + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) hm := task.HookMetadataAccessor(t) @@ -1785,6 +1797,7 @@ L: } op.parallelTaskChannels.Delete(t.GetId()) res.Status = queue.Success + return res } @@ -1794,6 +1807,7 @@ func formatErrorSummary(errors map[string]string) string { for moduleName, moduleErr := range errors { errSummary += fmt.Sprintf("\t- %s: %s", moduleName, moduleErr) } + return errSummary } @@ -1811,17 +1825,18 @@ func formatErrorSummary(errors map[string]string) string { // // ModuleRun is restarted if hook or chart is failed. // After first HandleModuleRun success, no onStartup and kubernetes.Synchronization tasks will run. -func (op *AddonOperator) HandleModuleRun(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleModuleRun(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "ModuleRun").End() - logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) + var res queue.TaskResult + logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) hm := task.HookMetadataAccessor(t) baseModule := op.ModuleManager.GetModule(hm.ModuleName) // Break error loop when module becomes disabled. if !op.ModuleManager.IsModuleEnabled(baseModule.GetName()) { res.Status = queue.Success - return + return res } metricLabels := map[string]string{ @@ -1986,7 +2001,7 @@ func (op *AddonOperator) HandleModuleRun(t sh_task.Task, labels map[string]strin res.HeadTasks = mainSyncTasks res.Status = queue.Keep op.logTaskAdd(logEntry, "head", mainSyncTasks...) - return + return res } } } @@ -2010,7 +2025,7 @@ func (op *AddonOperator) HandleModuleRun(t sh_task.Task, labels map[string]strin logEntry.Debug("Synchronization not completed, keep ModuleRun task in repeat mode") t.WithQueuedAt(time.Now()) res.Status = queue.Repeat - return + return res } } @@ -2059,14 +2074,15 @@ func (op *AddonOperator) HandleModuleRun(t sh_task.Task, labels map[string]strin logEntry.Info("ModuleRun success, module is ready") } } - return + + return res } -func (op *AddonOperator) HandleModuleHookRun(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleModuleHookRun(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "ModuleHookRun").End() + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) - hm := task.HookMetadataAccessor(t) baseModule := op.ModuleManager.GetModule(hm.ModuleName) // TODO: check if module exists @@ -2075,7 +2091,7 @@ func (op *AddonOperator) HandleModuleHookRun(t sh_task.Task, labels map[string]s // Prevent hook running in parallel queue if module is disabled in "main" queue. if !op.ModuleManager.IsModuleEnabled(baseModule.GetName()) { res.Status = queue.Success - return + return res } err := taskHook.RateLimitWait(context.Background()) @@ -2084,7 +2100,7 @@ func (op *AddonOperator) HandleModuleHookRun(t sh_task.Task, labels map[string]s // canceled, or the expected wait time exceeds the Context's Deadline. // The best we can do without proper context usage is to repeat the task. res.Status = queue.Repeat - return + return res } metricLabels := map[string]string{ @@ -2262,11 +2278,11 @@ func (op *AddonOperator) HandleModuleHookRun(t sh_task.Task, labels map[string]s return res } -func (op *AddonOperator) HandleGlobalHookRun(t sh_task.Task, labels map[string]string) (res queue.TaskResult) { +func (op *AddonOperator) HandleGlobalHookRun(t sh_task.Task, labels map[string]string) queue.TaskResult { defer trace.StartRegion(context.Background(), "GlobalHookRun").End() + var res queue.TaskResult logEntry := utils.EnrichLoggerWithLabels(op.Logger, labels) - hm := task.HookMetadataAccessor(t) taskHook := op.ModuleManager.GetGlobalHook(hm.HookName) @@ -2275,9 +2291,8 @@ func (op *AddonOperator) HandleGlobalHookRun(t sh_task.Task, labels map[string]s // This could happen when the Context is // canceled, or the expected wait time exceeds the Context's Deadline. // The best we can do without proper context usage is to repeat the task. - return queue.TaskResult{ - Status: "Repeat", - } + res.Status = "Repeat" + return res } metricLabels := map[string]string{ diff --git a/pkg/helm/helm3/helm3.go b/pkg/helm/helm3/helm3.go index 8ec1a0a8..620b708b 100644 --- a/pkg/helm/helm3/helm3.go +++ b/pkg/helm/helm3/helm3.go @@ -65,19 +65,19 @@ func NewClient(logger *log.Logger, logLabels ...map[string]string) client.HelmCl } // cmd runs Helm binary with specified arguments. -func (h *Helm3Client) cmd(args ...string) (stdout string, stderr string, err error) { - cmd := exec.Command(Helm3Path, args...) - +func (h *Helm3Client) cmd(args ...string) (string /*stdout*/, string /*stderr*/, error) { var stdoutBuf bytes.Buffer - cmd.Stdout = &stdoutBuf var stderrBuf bytes.Buffer + + cmd := exec.Command(Helm3Path, args...) + cmd.Stdout = &stdoutBuf cmd.Stderr = &stderrBuf - err = executor.Run(cmd) - stdout = strings.TrimSpace(stdoutBuf.String()) - stderr = strings.TrimSpace(stderrBuf.String()) + err := executor.Run(cmd) + stdout := strings.TrimSpace(stdoutBuf.String()) + stderr := strings.TrimSpace(stderrBuf.String()) - return + return stdout, stderr, err } // initAndVersion runs helm version command. @@ -98,7 +98,7 @@ func (h *Helm3Client) initAndVersion() error { // Example helm history output: // REVISION UPDATED STATUS CHART DESCRIPTION // 1 Fri Jul 14 18:25:00 2017 SUPERSEDED symfony-demo-0.1.0 Install complete -func (h *Helm3Client) LastReleaseStatus(releaseName string) (revision string, status string, err error) { +func (h *Helm3Client) LastReleaseStatus(releaseName string) (string /*revision*/, string /*status*/, error) { stdout, stderr, err := h.cmd( "history", releaseName, "--namespace", h.Namespace, @@ -109,33 +109,33 @@ func (h *Helm3Client) LastReleaseStatus(releaseName string) (revision string, st errLine := strings.Split(stderr, "\n")[0] if strings.Contains(errLine, "Error:") && strings.Contains(errLine, "not found") { // Bad module name or no releases installed - err = fmt.Errorf("release '%s' not found\n%v %v", releaseName, stdout, stderr) - revision = "0" - return + return "0", "", fmt.Errorf("release '%s' not found\n%s %s", releaseName, stdout, stderr) } - err = fmt.Errorf("cannot get history for release '%s'\n%v %v", releaseName, stdout, stderr) - return + return "", "", fmt.Errorf("cannot get history for release '%s'\n%s %s", releaseName, stdout, stderr) } - var historyInfo []map[string]string - + historyInfo := make([]map[string]string, 0) err = k8syaml.Unmarshal([]byte(stdout), &historyInfo) if err != nil { - return "", "", fmt.Errorf("helm history returns invalid json: %v", err) + return "", "", fmt.Errorf("helm history returns invalid json: %w", err) } + if len(historyInfo) == 0 { return "", "", fmt.Errorf("helm history is empty: '%s'", stdout) } + status, has := historyInfo[0]["status"] if !has { return "", "", fmt.Errorf("helm history has no 'status' field: '%s'", stdout) } - revision, has = historyInfo[0]["revision"] + + revision, has := historyInfo[0]["revision"] if !has { return "", "", fmt.Errorf("helm history has no 'revision' field: '%s'", stdout) } - return + + return revision, status, nil } func (h *Helm3Client) UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, namespace string) error { @@ -199,7 +199,7 @@ func (h *Helm3Client) GetReleaseValues(releaseName string) (utils.Values, error) return values, nil } -func (h *Helm3Client) DeleteRelease(releaseName string) (err error) { +func (h *Helm3Client) DeleteRelease(releaseName string) error { h.Logger.Debug("helm release: execute helm uninstall", slog.String("release", releaseName)) args := []string{ @@ -208,11 +208,12 @@ func (h *Helm3Client) DeleteRelease(releaseName string) (err error) { } stdout, stderr, err := h.cmd(args...) if err != nil { - return fmt.Errorf("helm uninstall %s invocation error: %v\n%v %v", releaseName, err, stdout, stderr) + return fmt.Errorf("helm uninstall %s invocation error: %w\n%v %v", releaseName, err, stdout, stderr) } h.Logger.Debug("helm release deleted", slog.String("release", releaseName)) - return + + return nil } func (h *Helm3Client) IsReleaseExists(releaseName string) (bool, error) { diff --git a/pkg/helm/helm3lib/helm3lib.go b/pkg/helm/helm3lib/helm3lib.go index c01115f8..68952b9a 100644 --- a/pkg/helm/helm3lib/helm3lib.go +++ b/pkg/helm/helm3lib/helm3lib.go @@ -148,7 +148,7 @@ func (h *LibClient) initAndVersion() error { } // LastReleaseStatus returns last known revision for release and its status -func (h *LibClient) LastReleaseStatus(releaseName string) (revision string, status string, err error) { +func (h *LibClient) LastReleaseStatus(releaseName string) (string /*revision*/, string /*status*/, error) { lastRelease, err := actionConfig.Releases.Last(releaseName) if err != nil { // in the Last(x) function we have the condition: diff --git a/pkg/helm/post_renderer/post_renderer.go b/pkg/helm/post_renderer/post_renderer.go index 918536a4..7a7ed8e1 100644 --- a/pkg/helm/post_renderer/post_renderer.go +++ b/pkg/helm/post_renderer/post_renderer.go @@ -11,14 +11,16 @@ type PostRenderer struct { ExtraLabels map[string]string } -func (p *PostRenderer) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) { +func (p *PostRenderer) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) { if len(p.ExtraLabels) == 0 { return renderedManifests, nil } + nodes, err := kio.FromBytes(renderedManifests.Bytes()) if err != nil { - return nil, fmt.Errorf("parse rendered manifests failed: %v", err) + return nil, fmt.Errorf("parse rendered manifests failed: %w", err) } + for _, node := range nodes { labels := node.GetLabels() for k, v := range p.ExtraLabels { @@ -29,7 +31,7 @@ func (p *PostRenderer) Run(renderedManifests *bytes.Buffer) (modifiedManifests * str, err := kio.StringAll(nodes) if err != nil { - return nil, fmt.Errorf("string all nodes failed: %v", err) + return nil, fmt.Errorf("string all nodes failed: %w", err) } return bytes.NewBufferString(str), nil diff --git a/pkg/kube_config_manager/backend/configmap/configmap.go b/pkg/kube_config_manager/backend/configmap/configmap.go index 0c52a3ba..0d22364c 100644 --- a/pkg/kube_config_manager/backend/configmap/configmap.go +++ b/pkg/kube_config_manager/backend/configmap/configmap.go @@ -144,8 +144,10 @@ func (b Backend) getConfigMap(ctx context.Context) (*v1.ConfigMap, error) { return obj, err } -func parseConfigMapData(data map[string]string) (cfg *config.KubeConfig, err error) { - cfg = config.NewConfig() +func parseConfigMapData(data map[string]string) (*config.KubeConfig, error) { + var err error + cfg := config.NewConfig() + // Parse values in global section. cfg.Global, err = getGlobalKubeConfigFromConfigData(data) if err != nil { diff --git a/pkg/module_manager/loader/fs/fs.go b/pkg/module_manager/loader/fs/fs.go index 7fd7bb13..6aaae65e 100644 --- a/pkg/module_manager/loader/fs/fs.go +++ b/pkg/module_manager/loader/fs/fs.go @@ -283,6 +283,6 @@ func parseUintOrDefault(num string, defaultValue uint32) uint32 { // // /modules/XXX-module-name/openapi/config-values.yaml // /modules/XXX-module-name/openapi/values.yaml -func (fl *FileSystemLoader) readOpenAPIFiles(openApiDir string) (configValuesBytes, valuesBytes []byte, err error) { +func (fl *FileSystemLoader) readOpenAPIFiles(openApiDir string) ([]byte /*configValuesBytes*/, []byte /*valuesBytes*/, error) { return utils.ReadOpenAPIFiles(openApiDir) } diff --git a/pkg/module_manager/models/hooks/kind/batch_hook.go b/pkg/module_manager/models/hooks/kind/batch_hook.go index 61aea5c5..8c71c6b7 100644 --- a/pkg/module_manager/models/hooks/kind/batch_hook.go +++ b/pkg/module_manager/models/hooks/kind/batch_hook.go @@ -92,8 +92,8 @@ func (h *BatchHook) GetHookConfigDescription() string { } // Execute runs the hook via the OS interpreter and returns the result of the execution -func (h *BatchHook) Execute(configVersion string, bContext []bindingcontext.BindingContext, moduleSafeName string, configValues, values utils.Values, logLabels map[string]string) (result *HookResult, err error) { - result = &HookResult{ +func (h *BatchHook) Execute(configVersion string, bContext []bindingcontext.BindingContext, moduleSafeName string, configValues, values utils.Values, logLabels map[string]string) (*HookResult, error) { + result := &HookResult{ Patches: make(map[utils.ValuesPatchType]*utils.ValuesPatch), } @@ -153,22 +153,22 @@ func (h *BatchHook) Execute(configVersion string, bContext []bindingcontext.Bind result.Patches[utils.ConfigMapPatch], err = utils.ValuesPatchFromFile(configValuesPatchPath) if err != nil { - return result, fmt.Errorf("got bad json patch for config values: %s", err) + return result, fmt.Errorf("got bad json patch for config values: %w", err) } result.Patches[utils.MemoryValuesPatch], err = utils.ValuesPatchFromFile(valuesPatchPath) if err != nil { - return result, fmt.Errorf("got bad json patch for values: %s", err) + return result, fmt.Errorf("got bad json patch for values: %w", err) } result.Metrics, err = metricoperation.MetricOperationsFromFile(metricsPath) if err != nil { - return result, fmt.Errorf("got bad metrics: %s", err) + return result, fmt.Errorf("got bad metrics: %w", err) } kubernetesPatchBytes, err := os.ReadFile(kubernetesPatchPath) if err != nil { - return result, fmt.Errorf("can't read kubernetes patch file: %s", err) + return result, fmt.Errorf("can't read kubernetes patch file: %w", err) } result.ObjectPatcherOperations, err = objectpatch.ParseOperations(kubernetesPatchBytes) @@ -248,45 +248,46 @@ func (h *BatchHook) GetAfterDeleteHelm() *float64 { } // PrepareTmpFilesForHookRun creates temporary files for hook and returns environment variables with paths -func (h *BatchHook) prepareTmpFilesForHookRun(bindingContext []byte, moduleSafeName string, configValues, values utils.Values) (tmpFiles map[string]string, err error) { - tmpFiles = make(map[string]string) +func (h *BatchHook) prepareTmpFilesForHookRun(bindingContext []byte, moduleSafeName string, configValues, values utils.Values) (map[string]string, error) { + var err error + tmpFiles := make(map[string]string) tmpFiles["CONFIG_VALUES_PATH"], err = h.prepareConfigValuesJsonFile(moduleSafeName, configValues) if err != nil { - return + return tmpFiles, err } tmpFiles["VALUES_PATH"], err = h.prepareValuesJsonFile(moduleSafeName, values) if err != nil { - return + return tmpFiles, err } tmpFiles["BINDING_CONTEXT_PATH"], err = h.prepareBindingContextJsonFile(moduleSafeName, bindingContext) if err != nil { - return + return tmpFiles, err } tmpFiles["CONFIG_VALUES_JSON_PATCH_PATH"], err = h.prepareConfigValuesJsonPatchFile() if err != nil { - return + return tmpFiles, err } tmpFiles["VALUES_JSON_PATCH_PATH"], err = h.prepareValuesJsonPatchFile() if err != nil { - return + return tmpFiles, err } tmpFiles["METRICS_PATH"], err = h.prepareMetricsFile() if err != nil { - return + return tmpFiles, err } tmpFiles["KUBERNETES_PATCH_PATH"], err = h.prepareKubernetesPatchFile() if err != nil { - return + return tmpFiles, err } - return + return tmpFiles, err } // METRICS_PATH diff --git a/pkg/module_manager/models/hooks/kind/gohook.go b/pkg/module_manager/models/hooks/kind/gohook.go index 64dfb9de..c32d6a90 100644 --- a/pkg/module_manager/models/hooks/kind/gohook.go +++ b/pkg/module_manager/models/hooks/kind/gohook.go @@ -101,7 +101,7 @@ func (h *GoHook) GetHookConfigDescription() string { } // Execute runs the hook and return the result of the execution -func (h *GoHook) Execute(_ string, bContext []bindingcontext.BindingContext, _ string, configValues, values utils.Values, logLabels map[string]string) (result *HookResult, err error) { +func (h *GoHook) Execute(_ string, bContext []bindingcontext.BindingContext, _ string, configValues, values utils.Values, logLabels map[string]string) (*HookResult, error) { // Values are patched in-place, so an error can occur. patchableValues, err := gohook.NewPatchableValues(values) if err != nil { @@ -151,7 +151,7 @@ func (h *GoHook) Execute(_ string, bContext []bindingcontext.BindingContext, _ s return nil, err } - result = &HookResult{ + result := &HookResult{ Patches: map[utils.ValuesPatchType]*utils.ValuesPatch{ utils.MemoryValuesPatch: {Operations: patchableValues.GetPatches()}, utils.ConfigMapPatch: {Operations: patchableConfigValues.GetPatches()}, diff --git a/pkg/module_manager/models/hooks/kind/shellhook.go b/pkg/module_manager/models/hooks/kind/shellhook.go index 626a15dc..ff9dd06b 100644 --- a/pkg/module_manager/models/hooks/kind/shellhook.go +++ b/pkg/module_manager/models/hooks/kind/shellhook.go @@ -88,8 +88,8 @@ func (sh *ShellHook) GetHookConfigDescription() string { } // Execute runs the hook via the OS interpreter and returns the result of the execution -func (sh *ShellHook) Execute(configVersion string, bContext []bindingcontext.BindingContext, moduleSafeName string, configValues, values utils.Values, logLabels map[string]string) (result *HookResult, err error) { - result = &HookResult{ +func (sh *ShellHook) Execute(configVersion string, bContext []bindingcontext.BindingContext, moduleSafeName string, configValues, values utils.Values, logLabels map[string]string) (*HookResult, error) { + result := &HookResult{ Patches: make(map[utils.ValuesPatchType]*utils.ValuesPatch), } @@ -146,22 +146,22 @@ func (sh *ShellHook) Execute(configVersion string, bContext []bindingcontext.Bin result.Patches[utils.ConfigMapPatch], err = utils.ValuesPatchFromFile(configValuesPatchPath) if err != nil { - return result, fmt.Errorf("got bad json patch for config values: %s", err) + return result, fmt.Errorf("got bad json patch for config values: %w", err) } result.Patches[utils.MemoryValuesPatch], err = utils.ValuesPatchFromFile(valuesPatchPath) if err != nil { - return result, fmt.Errorf("got bad json patch for values: %s", err) + return result, fmt.Errorf("got bad json patch for values: %w", err) } result.Metrics, err = metricoperation.MetricOperationsFromFile(metricsPath) if err != nil { - return result, fmt.Errorf("got bad metrics: %s", err) + return result, fmt.Errorf("got bad metrics: %w", err) } kubernetesPatchBytes, err := os.ReadFile(kubernetesPatchPath) if err != nil { - return result, fmt.Errorf("can't read kubernetes patch file: %s", err) + return result, fmt.Errorf("can't read kubernetes patch file: %w", err) } result.ObjectPatcherOperations, err = objectpatch.ParseOperations(kubernetesPatchBytes) @@ -172,7 +172,7 @@ func (sh *ShellHook) Execute(configVersion string, bContext []bindingcontext.Bin return result, nil } -func (sh *ShellHook) getConfig() (configOutput []byte, err error) { +func (sh *ShellHook) getConfig() ([]byte, error) { envs := make([]string, 0) envs = append(envs, os.Environ()...) args := []string{"--config"} @@ -397,45 +397,46 @@ func getModuleHookConfigSchema(version string) *spec.Schema { } // PrepareTmpFilesForHookRun creates temporary files for hook and returns environment variables with paths -func (sh *ShellHook) prepareTmpFilesForHookRun(bindingContext []byte, moduleSafeName string, configValues, values utils.Values) (tmpFiles map[string]string, err error) { - tmpFiles = make(map[string]string) +func (sh *ShellHook) prepareTmpFilesForHookRun(bindingContext []byte, moduleSafeName string, configValues, values utils.Values) (map[string]string, error) { + var err error + tmpFiles := make(map[string]string) tmpFiles["CONFIG_VALUES_PATH"], err = sh.prepareConfigValuesJsonFile(moduleSafeName, configValues) if err != nil { - return + return tmpFiles, err } tmpFiles["VALUES_PATH"], err = sh.prepareValuesJsonFile(moduleSafeName, values) if err != nil { - return + return tmpFiles, err } tmpFiles["BINDING_CONTEXT_PATH"], err = sh.prepareBindingContextJsonFile(moduleSafeName, bindingContext) if err != nil { - return + return tmpFiles, err } tmpFiles["CONFIG_VALUES_JSON_PATCH_PATH"], err = sh.prepareConfigValuesJsonPatchFile() if err != nil { - return + return tmpFiles, err } tmpFiles["VALUES_JSON_PATCH_PATH"], err = sh.prepareValuesJsonPatchFile() if err != nil { - return + return tmpFiles, err } tmpFiles["METRICS_PATH"], err = sh.prepareMetricsFile() if err != nil { - return + return tmpFiles, err } tmpFiles["KUBERNETES_PATCH_PATH"], err = sh.prepareKubernetesPatchFile() if err != nil { - return + return tmpFiles, err } - return + return tmpFiles, err } // METRICS_PATH diff --git a/pkg/module_manager/models/modules/basic.go b/pkg/module_manager/models/modules/basic.go index 03a57a18..ac84f531 100644 --- a/pkg/module_manager/models/modules/basic.go +++ b/pkg/module_manager/models/modules/basic.go @@ -248,7 +248,7 @@ func (bm *BasicModule) searchModuleHooks() ([]*hooks.ModuleHook, error) { return mHooks, nil } -func (bm *BasicModule) searchModuleShellHooks() (hks []*kind.ShellHook, err error) { +func (bm *BasicModule) searchModuleShellHooks() ([]*kind.ShellHook, error) { hooksDir := filepath.Join(bm.Path, "hooks") if _, err := os.Stat(hooksDir); os.IsNotExist(err) { return nil, nil @@ -259,7 +259,7 @@ func (bm *BasicModule) searchModuleShellHooks() (hks []*kind.ShellHook, err erro return nil, err } - hks = make([]*kind.ShellHook, 0) + hks := make([]*kind.ShellHook, 0) // sort hooks by path sort.Strings(hooksRelativePaths) @@ -286,10 +286,10 @@ func (bm *BasicModule) searchModuleShellHooks() (hks []*kind.ShellHook, err erro hks = append(hks, shHook) } - return + return hks, nil } -func (bm *BasicModule) searchModuleBatchHooks() (hks []*kind.BatchHook, err error) { +func (bm *BasicModule) searchModuleBatchHooks() ([]*kind.BatchHook, error) { hooksDir := filepath.Join(bm.Path, "hooks") if _, err := os.Stat(hooksDir); os.IsNotExist(err) { return nil, nil @@ -300,7 +300,7 @@ func (bm *BasicModule) searchModuleBatchHooks() (hks []*kind.BatchHook, err erro return nil, err } - hks = make([]*kind.BatchHook, 0) + hks := make([]*kind.BatchHook, 0) // sort hooks by path sort.Strings(hooksRelativePaths) @@ -325,7 +325,7 @@ func (bm *BasicModule) searchModuleBatchHooks() (hks []*kind.BatchHook, err erro } } - return + return hks, nil } func RecursiveGetBatchHookExecutablePaths(dir string, logger *log.Logger) ([]string, error) { @@ -398,7 +398,7 @@ func IsFileBatchHook(path string, f os.FileInfo) error { return ErrFileIsNotBatchHook } -func (bm *BasicModule) searchModuleGoHooks() (hks []*kind.GoHook) { +func (bm *BasicModule) searchModuleGoHooks() []*kind.GoHook { // find module hooks in go hooks registry return sdk.Registry().GetModuleHooks(bm.Name) } diff --git a/pkg/module_manager/models/modules/global.go b/pkg/module_manager/models/modules/global.go index 08676840..17df4f37 100644 --- a/pkg/module_manager/models/modules/global.go +++ b/pkg/module_manager/models/modules/global.go @@ -470,7 +470,7 @@ func (gm *GlobalModule) searchAndRegisterHooks() ([]*hooks.GlobalHook, error) { } // searchGlobalHooks recursively find all executables in hooksDir. Absent hooksDir is not an error. -func (gm *GlobalModule) searchGlobalHooks() (hks []*hooks.GlobalHook, err error) { +func (gm *GlobalModule) searchGlobalHooks() ([]*hooks.GlobalHook, error) { if gm.hooksDir == "" { gm.logger.Warn("Global hooks directory path is empty! No global hooks to load.") return nil, nil @@ -491,7 +491,7 @@ func (gm *GlobalModule) searchGlobalHooks() (hks []*hooks.GlobalHook, err error) return nil, err } - hks = make([]*hooks.GlobalHook, 0, len(shellHooks)+len(goHooks)) + hks := make([]*hooks.GlobalHook, 0, len(shellHooks)+len(goHooks)) for _, sh := range shellHooks { gh := hooks.NewGlobalHook(sh) @@ -514,7 +514,7 @@ func (gm *GlobalModule) searchGlobalHooks() (hks []*hooks.GlobalHook, err error) } // searchGlobalHooks recursively find all executables in hooksDir. Absent hooksDir is not an error. -func (gm *GlobalModule) searchGlobalShellHooks(hooksDir string) (hks []*kind.ShellHook, err error) { +func (gm *GlobalModule) searchGlobalShellHooks(hooksDir string) ([]*kind.ShellHook, error) { if _, err := os.Stat(hooksDir); os.IsNotExist(err) { return nil, nil } @@ -528,7 +528,7 @@ func (gm *GlobalModule) searchGlobalShellHooks(hooksDir string) (hks []*kind.She return nil, err } - hks = make([]*kind.ShellHook, 0) + hks := make([]*kind.ShellHook, 0) // sort hooks by path sort.Strings(hooksRelativePaths) @@ -561,11 +561,11 @@ func (gm *GlobalModule) searchGlobalShellHooks(hooksDir string) (hks []*kind.She slog.String("count", count), slog.String("dir", hooksDir)) - return + return hks, nil } // searchGlobalHooks recursively find all executables in hooksDir. Absent hooksDir is not an error. -func (gm *GlobalModule) searchGlobalBatchHooks(hooksDir string) (hks []*kind.BatchHook, err error) { +func (gm *GlobalModule) searchGlobalBatchHooks(hooksDir string) ([]*kind.BatchHook, error) { if _, err := os.Stat(hooksDir); os.IsNotExist(err) { return nil, nil } @@ -580,7 +580,7 @@ func (gm *GlobalModule) searchGlobalBatchHooks(hooksDir string) (hks []*kind.Bat return nil, err } - hks = make([]*kind.BatchHook, 0) + hks := make([]*kind.BatchHook, 0) // sort hooks by path sort.Strings(hooksRelativePaths) @@ -615,7 +615,7 @@ func (gm *GlobalModule) searchGlobalBatchHooks(hooksDir string) (hks []*kind.Bat slog.String("count", count), slog.String("dir", hooksDir)) - return + return hks, nil } func (gm *GlobalModule) searchGlobalGoHooks() ([]*kind.GoHook, error) { diff --git a/pkg/module_manager/module_manager.go b/pkg/module_manager/module_manager.go index 647cb8c0..4c6e4495 100644 --- a/pkg/module_manager/module_manager.go +++ b/pkg/module_manager/module_manager.go @@ -708,7 +708,7 @@ func (mm *ModuleManager) RunGlobalHook(hookName string, binding BindingType, bin return mm.global.RunHookByName(hookName, binding, bindingContext, logLabels) } -func (mm *ModuleManager) RunModuleHook(moduleName, hookName string, binding BindingType, bindingContext []BindingContext, logLabels map[string]string) (beforeChecksum string, afterChecksum string, err error) { +func (mm *ModuleManager) RunModuleHook(moduleName, hookName string, binding BindingType, bindingContext []BindingContext, logLabels map[string]string) (string /*beforeChecksum*/, string /*afterChecksum*/, error) { ml := mm.GetModule(moduleName) return ml.RunHookByName(hookName, binding, bindingContext, logLabels) diff --git a/pkg/task/hook_metadata.go b/pkg/task/hook_metadata.go index 6d7a1a0b..12194620 100644 --- a/pkg/task/hook_metadata.go +++ b/pkg/task/hook_metadata.go @@ -102,20 +102,22 @@ var ( _ modules.TaskMetadata = HookMetadata{} ) -func HookMetadataAccessor(t task.Task) (meta HookMetadata) { +func HookMetadataAccessor(t task.Task) HookMetadata { taskMeta := t.GetMetadata() if taskMeta == nil { log.Error("Possible Bug! task metadata is nil") - return + return HookMetadata{} } + meta, ok := taskMeta.(HookMetadata) if !ok { log.Error("Possible Bug! task metadata is not of type ModuleHookMetadata", slog.String("type", string(t.GetType())), slog.String("got", fmt.Sprintf("%T", meta))) - return + return HookMetadata{} } - return + + return meta } func (hm HookMetadata) GetDescription() string { diff --git a/pkg/utils/fswalk.go b/pkg/utils/fswalk.go index a5e498d8..205d77ee 100644 --- a/pkg/utils/fswalk.go +++ b/pkg/utils/fswalk.go @@ -34,8 +34,8 @@ import ( */ // FilesFromRoot returns a map with path and array of files under it -func FilesFromRoot(root string, filterFn func(dir string, name string, info os.FileInfo) bool) (files map[string]map[string]string, err error) { - files = make(map[string]map[string]string) +func FilesFromRoot(root string, filterFn func(dir string, name string, info os.FileInfo) bool) (map[string]map[string]string, error) { + files := make(map[string]map[string]string) symlinkedDirs, err := WalkSymlinks(root, "", files, filterFn) if err != nil { @@ -82,7 +82,7 @@ func FilesFromRoot(root string, filterFn func(dir string, name string, info os.F return files, nil } -func SymlinkInfo(path string, info os.FileInfo) (target string, isDir bool, err error) { +func SymlinkInfo(path string, info os.FileInfo) (string, bool, error) { // return empty path if not a symlink if info.Mode()&os.ModeSymlink == 0 { return "", false, nil @@ -90,7 +90,7 @@ func SymlinkInfo(path string, info os.FileInfo) (target string, isDir bool, err // Eval symlink path and get stat of a target path - target, err = filepath.EvalSymlinks(path) + target, err := filepath.EvalSymlinks(path) if err != nil { return "", false, err } @@ -104,10 +104,10 @@ func SymlinkInfo(path string, info os.FileInfo) (target string, isDir bool, err } // WalkSymlinks walks a directory, updates files map and returns symlinked directories -func WalkSymlinks(target string, linkName string, files map[string]map[string]string, filterFn func(dir string, name string, info os.FileInfo) bool) (symlinkedDirectories map[string]string, err error) { - symlinkedDirectories = map[string]string{} +func WalkSymlinks(target string, linkName string, files map[string]map[string]string, filterFn func(dir string, name string, info os.FileInfo) bool) (map[string]string, error) { + symlinkedDirectories := map[string]string{} - err = filepath.Walk(target, func(foundPath string, info os.FileInfo, err error) error { + err := filepath.Walk(target, func(foundPath string, info os.FileInfo, err error) error { if err != nil { return fmt.Errorf("failure accessing a path '%s': %v\n", foundPath, err) } @@ -146,17 +146,16 @@ func WalkSymlinks(target string, linkName string, files map[string]map[string]st return nil }) if err != nil { - return nil, fmt.Errorf("walk symlinks dir %s: %v", target, err) + return nil, fmt.Errorf("walk symlinks dir %s: %w", target, err) } return symlinkedDirectories, nil } // FindExecutableFilesInPath returns a list of executable and a list of non-executable files in path -func FindExecutableFilesInPath(dir string) (executables []string, nonExecutables []string, err error) { - executables = make([]string, 0) - - nonExecutables = make([]string, 0) +func FindExecutableFilesInPath(dir string) ([]string, []string, error) { + executables := make([]string, 0) + nonExecutables := make([]string, 0) // Find only executable files files, err := FilesFromRoot(dir, func(dir string, name string, info os.FileInfo) bool { @@ -167,7 +166,7 @@ func FindExecutableFilesInPath(dir string) (executables []string, nonExecutables return false }) if err != nil { - return + return executables, nonExecutables, err } for dirPath, filePaths := range files { @@ -178,5 +177,5 @@ func FindExecutableFilesInPath(dir string) (executables []string, nonExecutables sort.Strings(executables) - return + return executables, nonExecutables, nil } diff --git a/pkg/utils/loader.go b/pkg/utils/loader.go index 0b4d7854..9fb0fcb6 100644 --- a/pkg/utils/loader.go +++ b/pkg/utils/loader.go @@ -61,7 +61,7 @@ func LoadValuesFileFromDir(dir string, strictModeEnabled bool) (Values, error) { // // /modules/XXX-module-name/openapi/config-values.yaml // /modules/XXX-module-name/openapi/values.yaml -func ReadOpenAPIFiles(openApiDir string) (configValuesBytes, valuesBytes []byte, err error) { +func ReadOpenAPIFiles(openApiDir string) ([]byte /*configValuesBytes*/, []byte /*valuesBytes*/, error) { if openApiDir == "" { return nil, nil, nil } @@ -69,21 +69,23 @@ func ReadOpenAPIFiles(openApiDir string) (configValuesBytes, valuesBytes []byte, return nil, nil, nil } + configValuesBytes := make([]byte, 0) configPath := filepath.Join(openApiDir, ConfigValuesFileName) if _, err := os.Stat(configPath); !os.IsNotExist(err) { configValuesBytes, err = os.ReadFile(configPath) if err != nil { - return nil, nil, fmt.Errorf("read file '%s': %v", configPath, err) + return nil, nil, fmt.Errorf("read file '%s': %w", configPath, err) } } + valuesBytes := make([]byte, 0) valuesPath := filepath.Join(openApiDir, ValuesFileName) if _, err := os.Stat(valuesPath); !os.IsNotExist(err) { valuesBytes, err = os.ReadFile(valuesPath) if err != nil { - return nil, nil, fmt.Errorf("read file '%s': %v", valuesPath, err) + return nil, nil, fmt.Errorf("read file '%s': %w", valuesPath, err) } } - return + return configValuesBytes, valuesBytes, nil } diff --git a/pkg/utils/module_list.go b/pkg/utils/module_list.go index b7428e96..f940495f 100644 --- a/pkg/utils/module_list.go +++ b/pkg/utils/module_list.go @@ -65,7 +65,7 @@ func KeysSortedByReference(m map[string]struct{}, ref []string) []string { // ListSubtract creates a new array from 'src' array with items that are // not present in 'ignored' arrays. -func ListSubtract(src []string, ignored ...[]string) (result []string) { +func ListSubtract(src []string, ignored ...[]string) []string { ignoredMap := make(map[string]bool) for _, arr := range ignored { for _, v := range arr { @@ -73,18 +73,20 @@ func ListSubtract(src []string, ignored ...[]string) (result []string) { } } + result := make([]string, 0, len(src)) for _, v := range src { if _, ok := ignoredMap[v]; !ok { result = append(result, v) } } - return + + return result } // ListIntersection returns an array with items that are present in all 'arrs' arrays. -func ListIntersection(arrs ...[]string) (result []string) { +func ListIntersection(arrs ...[]string) []string { if len(arrs) == 0 { - return + return nil } // Counts each item in arrays. @@ -95,13 +97,14 @@ func ListIntersection(arrs ...[]string) (result []string) { } } + result := make([]string, 0, len(m)) for k, v := range m { if v == len(arrs) { result = append(result, k) } } - return + return result } // ListUnion creates a new array with unique items from all src arrays. diff --git a/pkg/utils/stdliblogtolog/adapter.go b/pkg/utils/stdliblogtolog/adapter.go index aeb4bf13..fa4e1182 100644 --- a/pkg/utils/stdliblogtolog/adapter.go +++ b/pkg/utils/stdliblogtolog/adapter.go @@ -20,7 +20,7 @@ type writer struct { logger *log.Logger } -func (w *writer) Write(msg []byte) (n int, err error) { +func (w *writer) Write(msg []byte) (int, error) { // There is no loglevel for stdlib logger w.logger.Log(logctx.SetCustomKeyContext(context.Background()), log.LevelInfo.Level(), strings.TrimSpace(string(msg))) diff --git a/pkg/values/validation/schemas.go b/pkg/values/validation/schemas.go index fa596f76..52416ee4 100644 --- a/pkg/values/validation/schemas.go +++ b/pkg/values/validation/schemas.go @@ -112,7 +112,7 @@ func (st *SchemaStorage) Validate(valuesType SchemaType, moduleName string, valu // validateObject uses schema to validate data structure in the dataObj. // See https://github.com/kubernetes/apiextensions-apiserver/blob/1bb376f70aa2c6f2dec9a8c7f05384adbfac7fbb/pkg/apiserver/validation/validation.go#L47 -func validateObject(dataObj interface{}, s *spec.Schema, rootName string) (multiErr error) { +func validateObject(dataObj interface{}, s *spec.Schema, rootName string) error { if s == nil { return fmt.Errorf("validate config: schema is not provided") } @@ -143,6 +143,7 @@ func validateObject(dataObj interface{}, s *spec.Schema, rootName string) (multi if allErrs == nil || allErrs.Len() == 0 { allErrs = multierror.Append(allErrs, fmt.Errorf("configuration is not valid")) } + return allErrs.ErrorOrNil() } @@ -220,7 +221,7 @@ func LoadSchemaFromBytes(openApiContent []byte) (*spec.Schema, error) { } // PrepareSchemas loads schemas for config values, values and helm values. -func PrepareSchemas(configBytes, valuesBytes []byte) (schemas map[SchemaType]*spec.Schema, err error) { +func PrepareSchemas(configBytes, valuesBytes []byte) (map[SchemaType]*spec.Schema, error) { res := make(map[SchemaType]*spec.Schema) if len(configBytes) > 0 { schemaObj, err := LoadSchemaFromBytes(configBytes) @@ -238,6 +239,7 @@ func PrepareSchemas(configBytes, valuesBytes []byte) (schemas map[SchemaType]*sp if err != nil { return nil, fmt.Errorf("load '%s' schema: %w", ValuesSchema, err) } + res[ValuesSchema] = schema.TransformSchema( schemaObj, &schema.ExtendTransformer{Parent: res[ConfigValuesSchema]},