Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions docs/user/reference/cli/azldev_advanced_ct-tools.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions docs/user/reference/cli/azldev_advanced_ct-tools_config-dump.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/app/azldev/cmds/advanced/advanced.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ output but fully supported.`,
}

app.AddTopLevelCommand(cmd)
ctToolsOnAppInit(app, cmd)
mcpOnAppInit(app, cmd)
mockOnAppInit(app, cmd)
wgetOnAppInit(app, cmd)
Expand Down
94 changes: 94 additions & 0 deletions internal/app/azldev/cmds/advanced/cttools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package advanced

import (
"fmt"

"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev"
"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/cttools"
"github.com/spf13/cobra"
)

func ctToolsOnAppInit(_ *azldev.App, parentCmd *cobra.Command) {
parentCmd.AddCommand(NewCTToolsCmd())
}

// Constructs a [cobra.Command] for the "ct-tools" subcommand hierarchy.
func NewCTToolsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "ct-tools",
Short: "Control Tower tools",
Long: `Control Tower tools for working with distro configuration.

Provides utilities for parsing, resolving, and dumping the fully merged
distro configuration used by Control Tower environments.`,
}

cmd.AddCommand(NewConfigDumpCmd())

return cmd
}

// Options controlling the config-dump command.
type ConfigDumpOptions struct {
// Path to the top-level TOML configuration file.
ConfigPath string
// The Control Tower environment to filter for (e.g. "ct-dev").
Environment string
}

// Constructs a [cobra.Command] for the "ct-tools config-dump" subcommand.
func NewConfigDumpCmd() *cobra.Command {
options := &ConfigDumpOptions{}

cmd := &cobra.Command{
Use: "config-dump",
Short: "Dump fully resolved distro config",
Long: `Parse and resolve all distro configuration TOML files starting from a
top-level file, merge includes, expand all templates (koji-targets,
build-roots, mock-options), and output the fully resolved configuration
filtered to a specific Control Tower environment.`,
Comment thread
sameluch marked this conversation as resolved.
Example: ` # Dump config for ct-dev as JSON
azldev advanced ct-tools config-dump \
--ct-config /path/to/azurelinux.toml \
--environment ct-dev -O json`,
RunE: azldev.RunFuncWithoutRequiredConfig(func(env *azldev.Env) (results interface{}, err error) {
return RunConfigDump(env, options)
}),
}
Comment thread
sameluch marked this conversation as resolved.

cmd.Flags().StringVar(
&options.ConfigPath, "ct-config", "",
"Path to the top-level CT distro TOML configuration file",
)

envHelp := "Control Tower environment name " +
"(e.g. ct-dev, ct-staging, ct-prod)"
cmd.Flags().StringVar(&options.Environment, "environment", "", envHelp)

_ = cmd.MarkFlagRequired("ct-config")
_ = cmd.MarkFlagRequired("environment")
_ = cmd.MarkFlagFilename("ct-config", "toml")

return cmd
Comment thread
sameluch marked this conversation as resolved.
}

// RunConfigDump loads, resolves, filters, and returns the distro configuration.
func RunConfigDump(env *azldev.Env, options *ConfigDumpOptions) (*cttools.DistroConfig, error) {
config, err := cttools.LoadConfig(env.FS(), options.ConfigPath)
if err != nil {
return nil, fmt.Errorf("failed to load config from %#q:\n%w", options.ConfigPath, err)
}

if err := cttools.ResolveTemplates(config); err != nil {
return nil, fmt.Errorf("failed to resolve templates:\n%w", err)
}

if err := cttools.FilterEnvironment(config, options.Environment); err != nil {
return nil, fmt.Errorf("failed to filter environment:\n%w", err)
}

return config, nil
}
41 changes: 41 additions & 0 deletions internal/app/azldev/cmds/advanced/cttools_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package advanced_test

import (
"testing"

"github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/cmds/advanced"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewCTToolsCmd(t *testing.T) {
cmd := advanced.NewCTToolsCmd()
require.NotNil(t, cmd)
assert.Equal(t, "ct-tools", cmd.Use)
}

func TestNewConfigDumpCmd(t *testing.T) {
cmd := advanced.NewConfigDumpCmd()
require.NotNil(t, cmd)
assert.Equal(t, "config-dump", cmd.Use)
}

func TestCTToolsCmd_HasConfigDumpSubcommand(t *testing.T) {
cmd := advanced.NewCTToolsCmd()

subCmds := cmd.Commands()
found := false

for _, sub := range subCmds {
if sub.Use == "config-dump" {
found = true

break
}
}

assert.True(t, found, "ct-tools should have config-dump subcommand")
}
Loading
Loading