Golang – Writing a command line program with urfave/cli package

The code recipe is modified from this video made by tutorialedge.net, this recipe does these:

Help interface.
Resolve FQDN to IPv4 addresses.
  • To find out cname from given host: cli –host google.com cname
Get the cname from given host.
  • To find out mx records from given host: cli –host http://www.google.com mx, this command lists out a list of mx hostnames and no preferences are shown.
Mail exchange servers record.
Find the nameservers from given host.

This recipe gives example on how to use urfave/cli to do something useful, thank you tutorialedge.net for making the youtube video on how to use cli, before watching the video I was using the flag module.

package main

import (
	"fmt"
	"log"
	"net"
	"os"
	"sort"

	"github.com/urfave/cli"
)

/*
The below uses cli v2, see manual for usage example: https://github.com/urfave/cli/blob/master/docs/v2/manual.md
Thanks to the makers of urfave cli it makes command line flags lesser code to write.
The code is modified from the tutorial from this video: https://www.youtube.com/watch?v=i2p0Snwk4gc
The code helps to find ip, name server, mx record and cname from given host.
To find ip from fqdn: cli --host www.google.com ip
To find ns from fqdn: cli --host www.google.com ns
To find cname from host: cli --host www.google.com cname
To find mx records from host: cli --host google.com host (no mx preference is shown only the hostname.)
*/
func main() {
	myFlags := []cli.Flag{
		&cli.StringFlag{
			Name:  "host", // this is the flag --host
			Value: "",     // no default value for --host value.
			Usage: "Value is a FQDN for example www.google.com.",
		},
	}
	app := &cli.App{
		Name:  "NSlookup clone.",
		Usage: "Example: cli --host www.google.com [COMMAND]",
		Flags: myFlags,
		Commands: []*cli.Command{
			{
				Name:  "ip",
				Usage: "Resolve FQDN to IPv4 address.",
				Action: func(c *cli.Context) error {
					ns, nsErr := net.LookupIP(c.String("host"))
					if nsErr != nil {
						return nsErr
					}
					for _, v := range ns {
						fmt.Println(v)
					}
					return nil
				},
			},
			{
				Name:  "cname",
				Usage: "Obtain cname from host.",
				Action: func(c *cli.Context) error {
					cname, cnameErr := net.LookupCNAME(c.String("host"))
					if cnameErr != nil {
						return cnameErr
					}
					fmt.Println(cname)
					return nil
				},
			},
			{
				Name:  "mx",
				Usage: "Obtain mail exchange record from host.",
				Action: func(c *cli.Context) error {
					mx, mxErr := net.LookupMX(c.String("host"))
					if mxErr != nil {
						return mxErr
					}
					for _, v := range mx {
						fmt.Println(v.Host)
					}
					return nil
				},
			},
			{
				Name:  "ns",
				Usage: "Get nameservers from given host",
				Action: func(c *cli.Context) error {
					ns, nsErr := net.LookupNS(c.String("host"))
					if nsErr != nil {
						return nsErr
					}
					for _, v := range ns {
						fmt.Println(v.Host)
					}
					return nil
				},
			},
		},
	}

	sort.Sort(cli.FlagsByName(app.Flags))
	sort.Sort(cli.CommandsByName(app.Commands))

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s