| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- // Package cmd holds the cobra command tree.
- package cmd
- import (
- "fmt"
- "os"
- "github.com/spf13/cobra"
- "schlundtech-dns/internal/api"
- )
- // global flags shared by every command.
- var (
- flagOutput string
- flagEndpoint string
- flagDryRun bool
- )
- var rootCmd = &cobra.Command{
- Use: "schlundtech-dns",
- Short: "Manage Schlundtech DNS zones and records",
- Long: `schlundtech-dns talks to the Schlundtech DNS gateway and lets you list your
- zones, read their records and change them.
- Credentials are read from a .env file in the working directory, falling back to
- the environment. Real environment variables win over .env, so a one-off
- override needs no edit:
- SCHLUNDTECH_CONTEXT=1 ./schlundtech-dns zones
- Copy .env.example to .env and fill it in:
- SCHLUNDTECH_USER the gateway user
- SCHLUNDTECH_PASSWORD the gateway password
- SCHLUNDTECH_CONTEXT the project the records belong to (Schlundtech uses 10)
- SCHLUNDTECH_TOKEN six-digit 2FA code, if two-factor authentication is on
- SCHLUNDTECH_ENDPOINT override the gateway URL, e.g. the demo system
- Keep .env out of git and readable only by you: chmod 600 .env
- DNS changes are public and propagate within seconds, so every command that
- writes has a --dry-run flag. Use it first.`,
- Example: ` cp .env.example .env && chmod 600 .env
- ./schlundtech-dns zones
- ./schlundtech-dns records list example.com
- ./schlundtech-dns records set example.com --name @ --type TXT --value 'v=spf1 -all' --dry-run`,
- SilenceUsage: true,
- SilenceErrors: true,
- }
- func init() {
- rootCmd.PersistentFlags().StringVar(&flagOutput, "output", "table", "output format: table or json")
- rootCmd.PersistentFlags().StringVar(&flagEndpoint, "endpoint", "", "override the gateway URL (default "+api.DefaultEndpoint+")")
- rootCmd.PersistentFlags().BoolVar(&flagDryRun, "dry-run", false, "show what would change without sending it")
- }
- // Execute runs the command tree. Errors go to stderr so that stdout stays
- // pipeable.
- func Execute() {
- if err := rootCmd.Execute(); err != nil {
- fmt.Fprintln(os.Stderr, "error:", err)
- os.Exit(1)
- }
- }
- // client builds an API client from the environment. Commands that do not talk
- // to the gateway never call it, so --help works without credentials.
- func client() (*api.Client, error) {
- creds, warning, err := loadCredentials()
- if warning != "" {
- // A warning, not an error: the credentials are still usable.
- fmt.Fprintln(os.Stderr, "warning:", warning)
- }
- if err != nil {
- return nil, err
- }
- endpoint := flagEndpoint
- if endpoint == "" {
- endpoint = creds.Endpoint
- }
- opts := []api.Option{}
- if endpoint != "" {
- opts = append(opts, api.WithEndpoint(endpoint))
- }
- return api.New(creds, opts...), nil
- }
|