Skip to content

Commit

Permalink
Merge pull request #107 from Kuadrant/106-topology-command-open-defau…
Browse files Browse the repository at this point in the history
…lt-all-to-visualize-svg

Topology command:  open svg graph in the user’s preferred application
  • Loading branch information
trepel authored Dec 20, 2024
2 parents fd21d07 + fc06185 commit 0018dfc
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 21 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ kuadrantctl [command] [subcommand] [flags]
| ------------ | ---------------------------------------------------------- |
| `completion` | Generate autocompletion scripts for the specified shell |
| `generate` | Commands related to Kubernetes Gateway API and Kuadrant resource generation from OpenAPI 3.x specifications |
| `topology` | Command related to Kuadrant topology |
| `help` | Help about any command |
| `version` | Print the version number of `kuadrantctl` |
| `version` | Print the version number of `kuadrantctl` |

### Flags

Expand Down Expand Up @@ -81,6 +82,29 @@ Generate Gateway API resources from an OpenAPI 3.x specification
| ---------- | ------------------------------------------------ | --------------------------------- |
| `httproute`| Generate Gateway API HTTPRoute from OpenAPI 3.0.X| `--oas string` Path to OpenAPI spec file (in JSON or YAML format), URL, or '-' to read from standard input (required). `-o` Output format: 'yaml' or 'json'. (default "yaml") |

#### `topology`

Export and visualize kuadrant topology

### Usage

```shell
$ kuadrantctl topology -h
Export and visualize kuadrant topology

Usage:
kuadrantctl topology [flags]

Flags:
-d, --dot string Graphviz DOT output file
-h, --help help for topology
-n, --namespace string Topology's namespace (default "kuadrant-system")
-o, --output string SVG image output file
Global Flags:
-v, --verbose verbose output
```
##### `generate kuadrant`
Generate Kuadrant resources from an OpenAPI 3.x specification
Expand Down
63 changes: 43 additions & 20 deletions cmd/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package cmd

import (
"bytes"
"fmt"
"errors"
"os"
"os/exec"
"strings"

"github.com/goccy/go-graphviz"
"github.com/spf13/cobra"
Expand All @@ -15,20 +17,22 @@ import (
)

var (
topologyNS string
topologyOutputFile string
topologyNS string
topologySVGOutputFile string
topologyDOTOutputFile string
)

func topologyCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "topology",
Short: "Read kuadrant topology",
Long: "Read kuadrant topology",
Short: "Export and visualize kuadrant topology",
Long: "Export and visualize kuadrant topology",
RunE: runTopology,
}

cmd.Flags().StringVarP(&topologyNS, "namespace", "n", "kuadrant-system", "Topology's namespace")
cmd.Flags().StringVarP(&topologyOutputFile, "output", "o", "(required)", "Output file")
cmd.Flags().StringVarP(&topologySVGOutputFile, "output", "o", "", "SVG image output file")
cmd.Flags().StringVarP(&topologyDOTOutputFile, "dot", "d", "", "Graphviz DOT output file")
err := cmd.MarkFlagRequired("output")
if err != nil {
panic(err)
Expand All @@ -37,6 +41,9 @@ func topologyCommand() *cobra.Command {
}

func runTopology(cmd *cobra.Command, args []string) error {
if !strings.HasSuffix(topologySVGOutputFile, ".svg") {
return errors.New("output file must have .svg extension")
}
ctx := cmd.Context()
configuration, err := config.GetConfig()
if err != nil {
Expand All @@ -56,18 +63,18 @@ func runTopology(cmd *cobra.Command, args []string) error {
return err
}

topologyOutputFileInDotFormat := fmt.Sprintf("%s.dot", topologyOutputFile)

fDot, err := os.Create(topologyOutputFileInDotFormat)
if err != nil {
return err
}
defer fDot.Close()

_, err = fDot.WriteString(topologyConfigMap.Data["topology"])
logf.Log.V(1).Info("write topology in DOT format to file", "file", topologyOutputFileInDotFormat, "error", err)
if err != nil {
return err
if topologyDOTOutputFile != "" {
fDot, err := os.Create(topologyDOTOutputFile)
if err != nil {
return err
}
defer fDot.Close()

_, err = fDot.WriteString(topologyConfigMap.Data["topology"])
logf.Log.V(1).Info("write topology in DOT format to file", "file", topologyDOTOutputFile, "error", err)
if err != nil {
return err
}
}

g, err := graphviz.New(ctx)
Expand Down Expand Up @@ -96,17 +103,33 @@ func runTopology(cmd *cobra.Command, args []string) error {
}

// write to file
fSvg, err := os.Create(topologyOutputFile)
fSvg, err := os.Create(topologySVGOutputFile)
if err != nil {
return err
}
defer fSvg.Close()

_, err = fSvg.Write(buf.Bytes())
logf.Log.V(1).Info("write topology in SVG format to file", "file", topologyOutputFile, "error", err)
logf.Log.V(1).Info("write topology in SVG format to file", "file", topologySVGOutputFile, "error", err)
if err != nil {
return err
}

externalCommand := "xdg-open"
if _, err := exec.LookPath("open"); err == nil {
externalCommand = "open"
}

openCmd := exec.Command(externalCommand, topologySVGOutputFile)
// pipe the commands output to the applications
// standard output
openCmd.Stdout = os.Stdout

// Run still runs the command and waits for completion
// but the output is instantly piped to Stdout
if err := openCmd.Run(); err != nil {
return err
}

return nil
}

0 comments on commit 0018dfc

Please sign in to comment.