do everything with cli command

This commit is contained in:
kolaente 2018-12-07 23:49:25 +01:00
parent f68ab13e58
commit 2aa93589f2
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
10 changed files with 282 additions and 26 deletions

44
cmd/daemon.go Normal file
View File

@ -0,0 +1,44 @@
// Sofaraum client is the client software which collects statistics about
// wifi devices nearby and then sends them to the Sofaraum Server.
// Copyright (c) 2018.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"git.kolaente.de/sofaraum/client/pkg/processing"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// daemonCmd represents the daemon command
var daemonCmd = &cobra.Command{
Use: "daemon",
Short: "Runs the sofa daemon which constantly parses airodump-ng csv dumps and sends the results to the server.",
Long: `The sofa daemon parses csv dumps produced by airodump-ng and sends the aggregated results to the sofa server.`,
Run: func(cmd *cobra.Command, args []string) {
processing.SummonTheDaemon()
},
}
func init() {
rootCmd.AddCommand(daemonCmd)
// Flags
daemonCmd.Flags().StringP("csvlocation", "c", "/opt/sofadaemon", "The location of the airodump-ng csv dumps")
viper.BindPFlag("daemon.csvlocation", daemonCmd.Flags().Lookup("csvlocation"))
daemonCmd.Flags().StringP("wifidevice", "w", "wlan0", "The wifi interface with which to collect wifi statistics")
viper.BindPFlag("daemon.wifidevice", daemonCmd.Flags().Lookup("wifidevice"))
}

97
cmd/root.go Normal file
View File

@ -0,0 +1,97 @@
// Sofaraum client is the client software which collects statistics about
// wifi devices nearby and then sends them to the Sofaraum Server.
// Copyright (c) 2018.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package cmd
import (
"fmt"
"os"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "sofa",
Short: "The sofaraum client which collects statistics and sends them to a sofaraum server",
Long: `The sofaraum client which collects statistics about nearby wifi devices and sends them to a sofaraum server.
Find more information on sofaraum.de`,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
// Global flag
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.sofad.yaml)")
rootCmd.PersistentFlags().StringP("serverurl", "s", "", "The server url where the client will send the data to")
rootCmd.PersistentFlags().StringP("privatekey", "k", "", "The locaton of the private key which will be used to authenticate against the server")
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Search config in home directory with name ".cliend" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".sofad")
}
viper.AddConfigPath(".")
viper.SetConfigName("sofad.yml")
// Init checking for environment variables
viper.SetEnvPrefix("sofa")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
// Set default configs
// Daemon
viper.SetDefault("daemon.csvlocation", "")
viper.SetDefault("daemon.wifidevice", "wlan0")
// Server
viper.SetDefault("server.url", "")
viper.SetDefault("server.privatekey", "")
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}

5
go.mod
View File

@ -1,10 +1,15 @@
module git.kolaente.de/sofaraum/client module git.kolaente.de/sofaraum/client
require ( require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/client9/misspell v0.3.4 github.com/client9/misspell v0.3.4
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970 github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970
github.com/mitchellh/go-homedir v1.0.0
github.com/spf13/cobra v0.0.3
github.com/spf13/viper v1.3.1
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd // indirect golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd // indirect
) )

49
go.sum
View File

@ -1,12 +1,61 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsWsMCce0vQHz3xiMPjJ9m4c2eeNs= github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsWsMCce0vQHz3xiMPjJ9m4c2eeNs=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8= github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY= github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY=
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970 h1:0+1ZURVRim6FxA/jhWhJklsgoWc69q1sxlIu2Ztnhy0= github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970 h1:0+1ZURVRim6FxA/jhWhJklsgoWc69q1sxlIu2Ztnhy0=
github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970/go.mod h1:iYGcTYIPUvEWhFo6aKUuLchs+AV4ssYdyuBbQJZGcBk= github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970/go.mod h1:iYGcTYIPUvEWhFo6aKUuLchs+AV4ssYdyuBbQJZGcBk=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.1 h1:5+8j8FTpnFV4nEImW/ofkzEt8VoOiLXxdYIDsB73T38=
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd h1:iGtqU5YFAjHfcmM6XLsTOpIm8HrEmDpt+XiZaxrJhyE= golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd h1:iGtqU5YFAjHfcmM6XLsTOpIm8HrEmDpt+XiZaxrJhyE=
golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

25
main.go
View File

@ -18,17 +18,13 @@
package main package main
import ( import (
"fmt" "git.kolaente.de/sofaraum/client/cmd"
"git.kolaente.de/sofaraum/client/pkg/processing"
"os"
) )
// Version sets the version. Will be overwritten by drone or when building with the makefile // Version sets the version. Will be overwritten by drone or when building with the makefile
var Version = "0.1" const Version = `0.1`
func main() { const TheSofa = `
fmt.Println(`
___.--------'´´´´´´:´´´´´´'--------.___ ___.--------'´´´´´´:´´´´´´'--------.___
( | : | ) ( | : | )
\ ,;,,, : | / \ ,;,,, : | /
@ -47,17 +43,8 @@ func main() {
This program comes with ABSOLUTELY NO WARRANTY This program comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome This is free software, and you are welcome
to redistribute it under certain conditions to redistribute it under certain conditions
=================================================`) =================================================`
stop := make(chan bool) func main() {
go processing.RunAirodumpNG(stop) cmd.Execute()
go processing.UpdateActiveClients()
for exit := range stop {
if !exit {
continue
}
os.Exit(1)
}
} }

View File

@ -20,12 +20,8 @@ package config
const ( const (
// TheClientCSVHeader is the header of the csv file where aircrack-ng starts putting infos about the clients // TheClientCSVHeader is the header of the csv file where aircrack-ng starts putting infos about the clients
TheClientCSVHeader = `Station MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs` TheClientCSVHeader = `Station MAC, First time seen, Last time seen, Power, # packets, BSSID, Probed ESSIDs`
// CSVDumps is the folder where aircrack-ng stores the dumps
CSVDumps = `/home/konrad/go/src/git.kolaente.de/sofaraum/client`
// SecondsUntilInactive specifies the seconds until a client is considered inactive // SecondsUntilInactive specifies the seconds until a client is considered inactive
SecondsUntilInactive = 120 SecondsUntilInactive = 120
// UpdateSecondsInterval is how often the currently active clients should be processed and sent to the server // UpdateSecondsInterval is how often the currently active clients should be processed and sent to the server
UpdateSecondsInterval = 2 UpdateSecondsInterval = 2
// WifiInterface the wifi interface aircrack-ng listens on
WifiInterface = `wlp59s0`
) )

View File

@ -0,0 +1,34 @@
// Sofaraum client is the client software which collects statistics about
// wifi devices nearby and then sends them to the Sofaraum Server.
// Copyright (c) 2018.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package processing
import "os"
func SummonTheDaemon() {
stop := make(chan bool)
go RunAirodumpNG(stop)
go UpdateActiveClients()
for exit := range stop {
if !exit {
continue
}
os.Exit(1)
}
}

View File

@ -18,14 +18,14 @@
package processing package processing
import ( import (
"git.kolaente.de/sofaraum/client/pkg/config" "github.com/spf13/viper"
"log" "log"
"os/exec" "os/exec"
) )
// RunAirodumpNG does what it says // RunAirodumpNG does what it says
func RunAirodumpNG(stop chan bool) { func RunAirodumpNG(stop chan bool) {
err := exec.Command("/bin/bash", []string{"-c", "airodump-ng " + config.WifiInterface + " -w " + config.CSVDumps + "/dump --output-format csv"}...).Run() err := exec.Command("/bin/bash", []string{"-c", "airodump-ng " + viper.GetString("daemon.wifidevice") + " -w " + viper.GetString("daemon.csvlocation") + "/dump --output-format csv"}...).Run()
if err != nil { if err != nil {
log.Println("Could not run airodump-ng. Please make sure it is installed and you have sufficient permissions. ", err) log.Println("Could not run airodump-ng. Please make sure it is installed and you have sufficient permissions. ", err)
stop <- true stop <- true

View File

@ -20,6 +20,7 @@ package processing
import ( import (
"fmt" "fmt"
"git.kolaente.de/sofaraum/client/pkg/config" "git.kolaente.de/sofaraum/client/pkg/config"
"github.com/spf13/viper"
"time" "time"
) )
@ -28,7 +29,7 @@ func UpdateActiveClients() {
for { for {
time.Sleep(config.UpdateSecondsInterval * time.Second) time.Sleep(config.UpdateSecondsInterval * time.Second)
clients := ParseCSVDumps(config.CSVDumps) clients := ParseCSVDumps(viper.GetString("daemon.csvlocation"))
var activeClients int64 var activeClients int64
for _, c := range clients { for _, c := range clients {

43
vendor/modules.txt vendored
View File

@ -1,16 +1,59 @@
# github.com/client9/misspell v0.3.4 # github.com/client9/misspell v0.3.4
github.com/client9/misspell/cmd/misspell github.com/client9/misspell/cmd/misspell
github.com/client9/misspell github.com/client9/misspell
# github.com/fsnotify/fsnotify v1.4.7
github.com/fsnotify/fsnotify
# github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 # github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
github.com/fzipp/gocyclo github.com/fzipp/gocyclo
# github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc # github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
github.com/gordonklaus/ineffassign github.com/gordonklaus/ineffassign
# github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/hcl
github.com/hashicorp/hcl/hcl/printer
github.com/hashicorp/hcl/hcl/ast
github.com/hashicorp/hcl/hcl/parser
github.com/hashicorp/hcl/hcl/token
github.com/hashicorp/hcl/json/parser
github.com/hashicorp/hcl/hcl/scanner
github.com/hashicorp/hcl/hcl/strconv
github.com/hashicorp/hcl/json/scanner
github.com/hashicorp/hcl/json/token
# github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap
# github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970 # github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970
github.com/karalabe/xgo github.com/karalabe/xgo
# github.com/magiconair/properties v1.8.0
github.com/magiconair/properties
# github.com/mitchellh/go-homedir v1.0.0
github.com/mitchellh/go-homedir
# github.com/mitchellh/mapstructure v1.1.2
github.com/mitchellh/mapstructure
# github.com/pelletier/go-toml v1.2.0
github.com/pelletier/go-toml
# github.com/spf13/afero v1.1.2
github.com/spf13/afero
github.com/spf13/afero/mem
# github.com/spf13/cast v1.3.0
github.com/spf13/cast
# github.com/spf13/cobra v0.0.3
github.com/spf13/cobra
# github.com/spf13/jwalterweatherman v1.0.0
github.com/spf13/jwalterweatherman
# github.com/spf13/pflag v1.0.3
github.com/spf13/pflag
# github.com/spf13/viper v1.3.1
github.com/spf13/viper
# golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 # golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
golang.org/x/lint/golint golang.org/x/lint/golint
golang.org/x/lint golang.org/x/lint
# golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a
golang.org/x/sys/unix
# golang.org/x/text v0.3.0
golang.org/x/text/transform
golang.org/x/text/unicode/norm
# golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd # golang.org/x/tools v0.0.0-20181128225727-c5b00d9557fd
golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/astutil
golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/internal/gcimporter golang.org/x/tools/go/internal/gcimporter
# gopkg.in/yaml.v2 v2.2.2
gopkg.in/yaml.v2