Render executes the rendering of templates based on the provided options. nolint:funlen,gocritic // funlen: 75-line linear dispatch over (Full ? FullConfigProcess : ApplyPatches) with per-branch cluster-meta hydration and per-mode serialisation; splitting either branch would scatter the shared Fail
(ctx context.Context, c *client.Client, opts Options)
| 1578 | // |
| 1579 | //nolint:funlen,gocritic // funlen: 75-line linear dispatch over (Full ? FullConfigProcess : ApplyPatches) with per-branch cluster-meta hydration and per-mode serialisation; splitting either branch would scatter the shared FailIfMultiNodes/loadValues/SerializeConfiguration steps across helpers without simplifying control flow. hugeParam: Options is the package's public configuration carrier; passing by pointer would propagate across pkg/commands and external consumers. |
| 1580 | func Render(ctx context.Context, c *client.Client, opts Options) ([]byte, error) { |
| 1581 | // Validate TalosVersion early so malformed values surface a user-friendly |
| 1582 | // error instead of an opaque "semverCompare: invalid semantic version" from |
| 1583 | // inside template rendering. |
| 1584 | if opts.TalosVersion != "" { |
| 1585 | _, err := config.ParseContractFromVersion(opts.TalosVersion) |
| 1586 | if err != nil { |
| 1587 | return nil, errors.Wrap(err, "invalid talos-version") |
| 1588 | } |
| 1589 | } |
| 1590 | |
| 1591 | // Gather facts and enable lookup options |
| 1592 | if !opts.Offline { |
| 1593 | cmdName := opts.CommandName |
| 1594 | if cmdName == "" { |
| 1595 | cmdName = cmdNameTalm |
| 1596 | } |
| 1597 | |
| 1598 | err := helpers.FailIfMultiNodes(ctx, cmdName) |
| 1599 | if err != nil { |
| 1600 | return nil, errors.Wrap(err, "checking node selector") |
| 1601 | } |
| 1602 | |
| 1603 | helmEngine.LookupFunc = newLookupFunction(ctx, c, cmdName, opts.TalosEndpoints) |
| 1604 | } |
| 1605 | |
| 1606 | // Require at least one template before loading and rendering the chart. |
| 1607 | // Rendering it first would be wasted (the output is discarded when no |
| 1608 | // template is selected) and, worse, the render fires live lookups whose |
| 1609 | // "connection refused" then masks the real problem: the operator forgot |
| 1610 | // --file / --template. Fail fast with the actionable error instead. This |
| 1611 | // runs after the online multi-node guard, which is a cheaper precondition |
| 1612 | // with no network I/O. |
| 1613 | if len(opts.TemplateFiles) == 0 { |
| 1614 | return nil, errors.New("templates are not set for the command: please use `--file` or `--template` flag") |
| 1615 | } |
| 1616 | |
| 1617 | chartPath, err := os.Getwd() |
| 1618 | if err != nil { |
| 1619 | return nil, errors.Wrap(err, "resolving working directory") |
| 1620 | } |
| 1621 | |
| 1622 | if opts.Root != "" { |
| 1623 | chartPath = opts.Root |
| 1624 | } |
| 1625 | |
| 1626 | chrt, err := loader.LoadDir(chartPath) |
| 1627 | if err != nil { |
| 1628 | return nil, errors.Wrapf(err, "loading chart from %q", chartPath) |
| 1629 | } |
| 1630 | |
| 1631 | values, err := loadValues(opts) |
| 1632 | if err != nil { |
| 1633 | return nil, err |
| 1634 | } |
| 1635 | |
| 1636 | rootValues := map[string]any{ |
| 1637 | helmKeyValues: mergeMaps(chrt.Values, values), |