Skip to content

Commit

Permalink
chore: doc generator for webmesh-node
Browse files Browse the repository at this point in the history
  • Loading branch information
tinyzimmer committed Jul 29, 2023
1 parent 77cfff4 commit b8cb267
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 69 deletions.
2 changes: 1 addition & 1 deletion cmd/gendocs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func main() {
}
return
}
err = nodecmd.GenMarkdownTree(*out)
err = nodecmd.GenMarkdownDoc("Configuration", -10, *out)
if err != nil {
fatal(err)
}
Expand Down
61 changes: 0 additions & 61 deletions pkg/cmd/nodecmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,64 +214,3 @@ func Execute() error {

return nil
}

func usage() {
fmt.Fprintf(os.Stderr, "Webmesh Node (Version: %s)\n\n", version.Version)
fmt.Fprintf(os.Stderr, "Usage: %s [flags]\n", os.Args[0])

fmt.Fprint(os.Stderr, `
The webmesh node is a single node in a webmesh cluster. It is responsible for
tracking the cluster state, managing network configurations, and providing a
gRPC API for other nodes to interact with the cluster. The API is also used by
the webmesh CLI to interact with the cluster.
The node can be configured to bootstrap a new cluster or join an existing
cluster. When bootstrapping a new cluster, the node will become the leader of
the cluster. When joining an existing cluster, the node will attempt to join
the cluster by contacting the leader. Optionally, the node can be configured to
bootstrap with a set of initial nodes. When bootstrapping with initial nodes,
the node will become the leader of the cluster if the initial nodes are not
already part of a cluster. If the initial nodes are already part of a cluster,
the node will join the cluster by contacting the leader of the cluster.
Configuration is available via command line flags, environment variables, and
configuration files. The configuration is parsed in the following order:
- Environment Variables
- Command Line Flags
- Configuration File
Environment variables match the command line flags where all characters are
uppercased and dashes and dots are replaced with underscores. For example, the
command line flag "mesh.node-id" would be set via the environment variable
"MESH_NODE_ID".
Configuration files can be in YAML, JSON, or TOML. The configuration file is
specified via the "--config" flag. The configuration file matches the structure
of the command line flags. For example, the following YAML configuration would
be equivalent to the shown command line flag:
# config.yaml
mesh:
node-id: "node-1" # --mesh.node-id="node-1"
`)

util.FlagsUsage(fs, "Global Configurations:", "global", "")
util.FlagsUsage(fs, "Mesh Configurations:", "mesh", "")
util.FlagsUsage(fs, "Authentication Configurations:", "auth", "")
util.FlagsUsage(fs, "Bootstrap Configurations:", "bootstrap", "")
util.FlagsUsage(fs, "Raft Configurations:", "raft", "")
util.FlagsUsage(fs, "TLS Configurations:", "tls", "")
util.FlagsUsage(fs, "WireGuard Configurations:", "wireguard", "")
util.FlagsUsage(fs, "Service Configurations:", "services", "")
util.FlagsUsage(fs, "Plugin Configurations:", "plugins", "")

fmt.Fprint(os.Stderr, "General Flags\n\n")
fmt.Fprint(os.Stderr, " --config Load flags from the given configuration file\n")
fmt.Fprint(os.Stderr, " --print-config Print the configuration and exit\n")
fmt.Fprint(os.Stderr, "\n")
fmt.Fprint(os.Stderr, " --help Show this help message\n")
fmt.Fprint(os.Stderr, " --version Show version information and exit\n")
fmt.Fprint(os.Stderr, "\n")
}
111 changes: 110 additions & 1 deletion pkg/cmd/nodecmd/gendocs.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,113 @@ limitations under the License.

package nodecmd

func GenMarkdownTree(outfile string) error { return nil }
import (
"flag"
"fmt"
"os"
"strings"
)

func GenMarkdownDoc(title string, weight int, outfile string) error {
var sb strings.Builder
// Doc header
sb.WriteString(fmt.Sprintf(`---
title: %s
weight: %d
---
`, title, weight))
// Prelude
prelude := `
Each node can be configured to bootstrap a new cluster or join an existing cluster.
When bootstrapping a new cluster, the node will become the leader of the cluster.
When joining an existing cluster, the node will attempt to join the cluster by contacting the leader.
Optionally, the node can be configured to bootstrap with a set of initial nodes.
When bootstrapping with initial nodes, the nodes will perform an election to determine which node should write the initial network configuration.
If the initial nodes are already part of a cluster, the node will join the cluster by contacting the leader of the cluster.
Configuration is available via command line flags, environment variables, and configuration files.
The configuration is parsed in the following order:
- Environment Variables
- Command Line Flags
- Configuration File
Environment variables match the command line flags where all characters are uppercased and dashes and dots are replaced with underscores.
For example, the command line flag BACKTICKmesh.node-idBACKTICK would be set via the environment variable BACKTICKMESH_NODE_IDBACKTICK.
Configuration files can be in YAML, JSON, or TOML.
The configuration file is specified via the "--config" flag.
The configuration file matches the structure of the command line flags.
For example, the following YAML configuration would be equivalent to the shown command line flag:
FENCEyaml
# config.yaml
mesh:
node-id: "node-1" # --mesh.node-id="node-1"
FENCE
The below tables show all of the available configuration options and their default values.
{{< toc >}}
FENCE
General Flags
--config Load flags from the given configuration file
--print-config Print the configuration and exit
--help Show this help message
--version Show version information and exit
FENCE
`
prelude = strings.ReplaceAll(prelude, "BACKTICK", "`")
prelude = strings.ReplaceAll(prelude, "FENCE", "```")
sb.WriteString(prelude)
appendFlagSection("Global Configurations", "global", &sb)
appendFlagSection("Mesh Configurations", "mesh", &sb)
appendFlagSection("Auth Configurations", "auth", &sb)
// Auth disclaimer about needing more flags
sb.WriteString("_TODO: Generic flags need to be provided for external plugin auth providers_\n\n")
appendFlagSection("Bootstrap Configurations", "bootstrap", &sb)
appendFlagSection("Raft Configurations", "raft", &sb)
appendFlagSection("TLS Configurations", "tls", &sb)
appendFlagSection("WireGuard Configurations", "wireguard", &sb)
appendFlagSection("Services Configurations", "services", &sb)
appendFlagSection("Plugin Configurations", "plugins", &sb)
extraPluginInfo := `
Local executable plugins can be configured with the BACKTICK--plugins.localBACKTICK flag or configuration entry.
These are provided as a list of paths and configurations in the format of BACKTICKpath=/path/to/executable,config1=val1,config2=val2,...BACKTICK.
External server plugins are configured with the BACKTICK--plugins.serverBACKTICK flag or configuration entry.
Configurations are the same as the local plugin, but with the addition of server configurations in the format of BACKTICKserver=rpcserver.com:8443[,insecure=true][,tls-ca-file=ca.crt][,tls-key-file=tls.key][,tls-cert-file=tls.crt]BACKTICK.
`
extraPluginInfo = strings.ReplaceAll(extraPluginInfo, "BACKTICK", "`")
sb.WriteString(extraPluginInfo)
return os.WriteFile(outfile, []byte(sb.String()), 0644)
}

func appendFlagSection(title string, flagPrefix string, sb *strings.Builder) {
sb.WriteString(fmt.Sprintf("## %s\n\n", title))
sb.WriteString("| CLI Flag | Env Var | Config File | Default | Description |\n")
sb.WriteString("| -------- | ------- | ----------- | ------- | ----------- |\n")
fs.VisitAll(func(f *flag.Flag) {
if !strings.HasPrefix(f.Name, flagPrefix) {
return
}
usage := strings.Replace(f.Usage, "\n", " ", -1)
sb.WriteString(fmt.Sprintf("| `--%s` | `%s` | `%s` | %s | %s |\n",
f.Name,
strings.ToUpper(strings.ReplaceAll(strings.ReplaceAll(f.Name, "-", "_"), ".", "_")),
f.Name,
func() string {
if f.DefValue == "" {
return ""
}
return fmt.Sprintf("`%s`", f.DefValue)
}(),
usage))
})
sb.WriteString("\n")
}
64 changes: 64 additions & 0 deletions pkg/cmd/nodecmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import (
"flag"
"fmt"
"io"
"os"

"gopkg.in/yaml.v3"

"github.com/webmeshproj/webmesh/pkg/cmd/nodecmd/global"
"github.com/webmeshproj/webmesh/pkg/mesh"
"github.com/webmeshproj/webmesh/pkg/services"
"github.com/webmeshproj/webmesh/pkg/util"
"github.com/webmeshproj/webmesh/pkg/version"
)

// Options are the node options.
Expand Down Expand Up @@ -75,3 +78,64 @@ func (o *Options) MarshalTo(w io.Writer) error {
}
return nil
}

func usage() {
fmt.Fprintf(os.Stderr, "Webmesh Node (Version: %s)\n\n", version.Version)
fmt.Fprintf(os.Stderr, "Usage: %s [flags]\n", os.Args[0])

fmt.Fprint(os.Stderr, `
The webmesh node is a single node in a webmesh cluster. It is responsible for
tracking the cluster state, managing network configurations, and providing a
gRPC API for other nodes to interact with the cluster. The API is also used by
the webmesh CLI to interact with the cluster.
The node can be configured to bootstrap a new cluster or join an existing
cluster. When bootstrapping a new cluster, the node will become the leader of
the cluster. When joining an existing cluster, the node will attempt to join
the cluster by contacting the leader. Optionally, the node can be configured to
bootstrap with a set of initial nodes. When bootstrapping with initial nodes,
the node will become the leader of the cluster if the initial nodes are not
already part of a cluster. If the initial nodes are already part of a cluster,
the node will join the cluster by contacting the leader of the cluster.
Configuration is available via command line flags, environment variables, and
configuration files. The configuration is parsed in the following order:
- Environment Variables
- Command Line Flags
- Configuration File
Environment variables match the command line flags where all characters are
uppercased and dashes and dots are replaced with underscores. For example, the
command line flag "mesh.node-id" would be set via the environment variable
"MESH_NODE_ID".
Configuration files can be in YAML, JSON, or TOML. The configuration file is
specified via the "--config" flag. The configuration file matches the structure
of the command line flags. For example, the following YAML configuration would
be equivalent to the shown command line flag:
# config.yaml
mesh:
node-id: "node-1" # --mesh.node-id="node-1"
`)

util.FlagsUsage(fs, "Global Configurations:", "global")
util.FlagsUsage(fs, "Mesh Configurations:", "mesh")
util.FlagsUsage(fs, "Authentication Configurations:", "auth")
util.FlagsUsage(fs, "Bootstrap Configurations:", "bootstrap")
util.FlagsUsage(fs, "Raft Configurations:", "raft")
util.FlagsUsage(fs, "TLS Configurations:", "tls")
util.FlagsUsage(fs, "WireGuard Configurations:", "wireguard")
util.FlagsUsage(fs, "Service Configurations:", "services")
util.FlagsUsage(fs, "Plugin Configurations:", "plugins")

fmt.Fprint(os.Stderr, "General Flags\n\n")
fmt.Fprint(os.Stderr, " --config Load flags from the given configuration file\n")
fmt.Fprint(os.Stderr, " --print-config Print the configuration and exit\n")
fmt.Fprint(os.Stderr, "\n")
fmt.Fprint(os.Stderr, " --help Show this help message\n")
fmt.Fprint(os.Stderr, " --version Show version information and exit\n")
fmt.Fprint(os.Stderr, "\n")
}
7 changes: 1 addition & 6 deletions pkg/util/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,14 @@ import (
)

// FlagsUsage prints the usage of all flags with the given prefix.
func FlagsUsage(fs *flag.FlagSet, title, prefix, notPrefix string) {
func FlagsUsage(fs *flag.FlagSet, title, prefix string) {
t := tabwriter.NewWriter(os.Stderr, 1, 4, 4, ' ', 0)
defer t.Flush()
fmt.Fprintf(t, "%s\n\n", title)
fs.VisitAll(func(f *flag.Flag) {
if !strings.HasPrefix(f.Name, prefix) {
return
}
if notPrefix != "" {
if strings.HasPrefix(f.Name, notPrefix) {
return
}
}
usageLines := strings.Split(f.Usage, "\n")
if len(usageLines) > 1 {
fmt.Fprintln(t)
Expand Down

0 comments on commit b8cb267

Please sign in to comment.