diff --git a/cmd/uncloud/caddy/config.go b/cmd/uncloud/caddy/config.go new file mode 100644 index 00000000..ffe16832 --- /dev/null +++ b/cmd/uncloud/caddy/config.go @@ -0,0 +1,76 @@ +package caddy + +import ( + "context" + "fmt" + "os" + + "github.com/alecthomas/chroma/v2/quick" + "github.com/psviderski/uncloud/internal/cli" + "github.com/psviderski/uncloud/pkg/api" + "github.com/spf13/cobra" +) + +type configOptions struct { + machine string + noColor bool + context string +} + +func NewConfigCommand() *cobra.Command { + opts := configOptions{} + + cmd := &cobra.Command{ + Use: "config", + Short: "Show the current Caddy configuration (Caddyfile).", + Long: "Display the current Caddy configuration (Caddyfile) from the connected machine or a specified one.", + RunE: func(cmd *cobra.Command, args []string) error { + uncli := cmd.Context().Value("cli").(*cli.CLI) + return runConfig(cmd.Context(), uncli, opts) + }, + } + + cmd.Flags().StringVarP(&opts.machine, "machine", "m", "", + "Name or ID of the machine to get the configuration from. (default is connected machine)") + cmd.Flags().BoolVar(&opts.noColor, "no-color", false, + "Disable syntax highlighting for the output.") + cmd.Flags().StringVarP( + &opts.context, "context", "c", "", + "Name of the cluster context. (default is the current context)", + ) + + return cmd +} + +func runConfig(ctx context.Context, uncli *cli.CLI, opts configOptions) error { + clusterClient, err := uncli.ConnectCluster(ctx, opts.context) + if err != nil { + return fmt.Errorf("connect to cluster: %w", err) + } + defer clusterClient.Close() + + if opts.machine != "" { + // If a specific machine is requested, use it to get the Caddy configuration. + ctx, _, err = api.ProxyMachinesContext(ctx, clusterClient, []string{opts.machine}) + if err != nil { + return err + } + } + + config, err := clusterClient.Caddy.GetConfig(ctx, nil) + if err != nil { + return fmt.Errorf("get Caddy config: %w", err) + } + + // Print the Caddyfile with syntax highlighting. + if opts.noColor { + fmt.Print(config.Caddyfile) + } else { + if err = quick.Highlight(os.Stdout, config.Caddyfile, "caddy", "terminal256", "monokai"); err != nil { + // If highlighting fails, fall back to plain output. + fmt.Print(config.Caddyfile) + } + } + + return nil +} diff --git a/cmd/uncloud/caddy/root.go b/cmd/uncloud/caddy/root.go index a20fe9e2..1f71475f 100644 --- a/cmd/uncloud/caddy/root.go +++ b/cmd/uncloud/caddy/root.go @@ -10,6 +10,7 @@ func NewRootCommand() *cobra.Command { Short: "Manage Caddy reverse proxy service.", } cmd.AddCommand( + NewConfigCommand(), NewDeployCommand(), ) return cmd diff --git a/go.mod b/go.mod index f7ae1f86..0b447ede 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/BurntSushi/toml v1.4.0 github.com/Masterminds/semver v1.5.0 github.com/Masterminds/squirrel v1.5.4 + github.com/alecthomas/chroma/v2 v2.20.0 github.com/caddyserver/caddy/v2 v2.8.4 github.com/cenkalti/backoff/v4 v4.3.0 github.com/charmbracelet/huh v0.6.0 @@ -108,6 +109,7 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dlclark/regexp2 v1.11.5 // indirect github.com/docker/buildx v0.18.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect diff --git a/go.sum b/go.sum index 32bee10a..f3851ef2 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,12 @@ github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdII github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= +github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= +github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= +github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= +github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -259,6 +265,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/buildx v0.18.0 h1:rSauXHeJt90NvtXrLK5J992Eb0UPJZs2vV3u1zTf1nE= github.com/docker/buildx v0.18.0/go.mod h1:JGNSshOhHs5FhG3u51jXUf4lLOeD2QBIlJ2vaRB67p4= github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM= @@ -487,6 +495,8 @@ github.com/hashicorp/memberlist v0.5.1 h1:mk5dRuzeDNis2bi6LLoQIXfMH7JQvAzt3mQD0v github.com/hashicorp/memberlist v0.5.1/go.mod h1:zGDXV6AqbDTKTM6yxW0I4+JtFzZAJVoIPvss4hV8F24= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=