diff --git a/CHANGELOG.md b/CHANGELOG.md index 81866a1..866f5c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2020-09-26 + +## Added + - Enable prompt for password feature if interactive setting is true + - Better validation of required/optional profile settings + - Configure defaults for namespace and format settings + +## Changed + - Rename server var to profile, to clarify code + - Updated documentation + +## [0.2.1] - 2020-09-22 + +## Added +- Merge PR #4 (add trusted-ca-file capability) +- Set default timeout to 15s + ## [0.2.0] - 2020-09-21 ### Fixed diff --git a/README.md b/README.md index 887abba..bdcce60 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Multiple profiles can be setup for a single backend, in case you need a differen OSC could also be used in a CI/CD pipeline to perform actions on multiple clusters. An `osc.config.yaml` can also be read from the current working directory. -## Configuration +# Configuration ```yaml --- @@ -20,7 +20,8 @@ OSC could also be used in a CI/CD pipeline to perform actions on multiple cluste localhost: env: dev username: admin - password: P@ssw0rd! + password: "" + interactive: true api: http://localhost:8080 trusted-ca-file: "/path/to/trust-ca.pem" namespace: default @@ -36,9 +37,32 @@ localhost-ssl: namespace: foo format: json insecure-skip-tls-verify: true + +localhost-min: + username: admin + password: P@ssw0rd! + api: https://localhost:8080 ``` -## Commands +## Required profile parameters * +A minimum config profile requires 3 settings: + +- "api" +- "username" +- "password" *** (If "interactive" is set to true on the profile, this setting is optional) *** + +## Optional profile parameters +A profile in the OSC config contains a number of optional parameters. If a parameter is not present, the default value will be used. + +- "timeout". (Default: 15s) +- "env" (Default: no value) +- "trusted-ca-file" (Default: no value) +- "namespace" (Default: "default") +- "format" (Default: "tabular") +- "insecure-skip-tls-verify" (Default: false) +- "interactive" (Default: false) + +# Commands Once your configuration file is in place, switching between Sensu backend clusters is a breeze. @@ -62,7 +86,7 @@ Flags: Use "osc [command] --help" for more information about a command. ``` -### List +## List List will show you the currentl sensuctl cluster/profile settings, along with the list of available profiles in your OSC config. @@ -81,12 +105,21 @@ localhost dev admin default tabular localhost-ssl dev admin foo json https://localhost:8080 ``` -### Connect +## Connect Connect takes 1 argument, the profile `name` in the config. It creates a new sensuctl configuration for you. No need to type in the API, username/password, namespace, format preferences anymore. Woo Hoo! -`> osc connect localhost` - ```bash +osc connect localhost Connected to Sensu backend: localhost (http://localhost:8080) ``` + +## Connect (interactive) + +If a profile has interactive set to true, OSC will prompt the user for the password associated with that profile username. + +```bash +osc connect localhost-auth +? Password for admin: ********* +Connected to Sensu backend: localhost-auth (http://localhost:8080) +``` diff --git a/go.mod b/go.mod index 2b12cda..3d47c4c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module osc go 1.14 require ( + github.com/AlecAivazis/survey/v2 v2.1.1 github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.4.0 + golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect ) diff --git a/go.sum b/go.sum index acef08e..664519a 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI= +github.com/AlecAivazis/survey/v2 v2.1.1/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -41,10 +45,14 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 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/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -52,11 +60,19 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ= +github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= @@ -96,6 +112,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -107,13 +124,18 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -125,6 +147,11 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1 h1:R4dVlxdmKenVdMRS/tTspEpSTRWINYrHD8ySIU9yCIU= +golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/config/config.go b/pkg/config/config.go index 6b71791..f1cc967 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -11,9 +11,11 @@ import ( ) const ( - sensuctlClusterFile = "~/.config/sensu/sensuctl/cluster" - sensuctlProfileFile = "~/.config/sensu/sensuctl/profile" - sensuctlDefaultTimeout time.Duration = 15 * time.Second + sensuctlClusterFile = "~/.config/sensu/sensuctl/cluster" + sensuctlProfileFile = "~/.config/sensu/sensuctl/profile" + sensuctlDefaultFormat = "tabular" + sensuctlDefaultNamespace = "default" + sensuctlDefaultTimeout time.Duration = 15 * time.Second ) // Cluster sensuctl format @@ -40,46 +42,76 @@ type Backend struct { } // Create generates new sensuctl cluster/profile configs -func Create(c Cluster, server string) error { +func Create(c Cluster, profile string) error { - c.APIUrl = viper.GetString(server + ".api") + newCluster, err := newClusterConfig(c, profile) + if err != nil { + return err + } + err = WriteSensuClusterConfig(newCluster) + if err != nil { + return err + } + + newProfile, err := newProfileConfig(profile) + if err != nil { + return err + } + err = WriteSensuProfileConfig(newProfile) + if err != nil { + return err + } + + return nil +} + +func newClusterConfig(c Cluster, profile string) ([]byte, error) { + c.APIUrl = viper.GetString(profile + ".api") // run through optional parameters - if viper.IsSet(server + ".trusted-ca-file") { - c.TrustedCAFile = viper.GetString(server + ".trusted-ca-file") + if viper.IsSet(profile + ".trusted-ca-file") { + c.TrustedCAFile = viper.GetString(profile + ".trusted-ca-file") } - if viper.IsSet(server + ".timeout") { - c.Timeout = viper.GetDuration(server + ".timeout") + if viper.IsSet(profile + ".timeout") { + c.Timeout = viper.GetDuration(profile + ".timeout") } else { c.Timeout = sensuctlDefaultTimeout } - if viper.IsSet(server + ".insecure-skip-tls-verify") { - c.InsecureSkipTLSVerify = viper.GetBool(server + ".insecure-skip-tls-verify") + if viper.IsSet(profile + ".insecure-skip-tls-verify") { + c.InsecureSkipTLSVerify = viper.GetBool(profile + ".insecure-skip-tls-verify") } newCluster, err := json.MarshalIndent(c, "", " ") if err != nil { - return err + return nil, err } - err = WriteSensuClusterConfig(newCluster) - if err != nil { - return err + + return newCluster, nil +} + +func newProfileConfig(profile string) ([]byte, error) { + + format := viper.GetString(profile + ".format") + namespace := viper.GetString(profile + ".namespace") + + // apply default if not present in config + if format == "" { + format = sensuctlDefaultFormat + } + if namespace == "" { + namespace = sensuctlDefaultNamespace } tmpProfile := Profile{ - Format: viper.GetString(server + ".format"), - Namespace: viper.GetString(server + ".namespace"), + Format: format, + Namespace: namespace, } + newProfile, err := json.MarshalIndent(tmpProfile, "", " ") if err != nil { - return err + return nil, err } - err = WriteSensuProfileConfig(newProfile) - if err != nil { - return err - } - - return nil + return newProfile, nil } // ReadSensuConfig loads the current sensuctl config and returns a config.Backend{} diff --git a/pkg/osc/osc.go b/pkg/osc/osc.go index 06a6d5d..22f4f83 100644 --- a/pkg/osc/osc.go +++ b/pkg/osc/osc.go @@ -14,15 +14,17 @@ import ( "text/tabwriter" "time" + "github.com/AlecAivazis/survey/v2" "github.com/spf13/viper" ) var ( - server string + profile string api string username string password string insecure bool + interactive bool trustedcafile string ) @@ -74,18 +76,20 @@ func List() { // Connect establishes a new sensuctl config for the chosen backend profile func Connect(args []string) { - server = args[0] - api = viper.GetString(server + ".api") - username = viper.GetString(server + ".username") - password = viper.GetString(server + ".password") - insecure = viper.GetBool(server + ".insecure-skip-tls-verify") - trustedcafile = viper.GetString(server + ".trusted-ca-file") + profile := args[0] + interactive = viper.GetBool(profile + ".interactive") - if viper.GetString(server+".api") == "" { - fmt.Printf("Config profile (%s) does not exist.\n", server) + validProfile := validateProfile(profile) + + if !validProfile { + fmt.Printf("Config profile (%s) is missing required parameters.", profile) os.Exit(1) } + if interactive { + passwordPrompt() + } + // create the http client var client = http.Client{ Timeout: 10 * time.Second, @@ -148,12 +152,12 @@ func Connect(args []string) { fmt.Println(err) return } - err = config.Create(newConfig, server) + err = config.Create(newConfig, profile) if err != nil { fmt.Printf("Error connecting: %s\n", err) return } - fmt.Printf("Connected to Sensu backend: %s (%s)\n", server, api) + fmt.Printf("Connected to Sensu backend: %s (%s)\n", profile, api) } else { fmt.Println("Auth failed! Check profile credentials.") os.Exit(1) @@ -206,6 +210,38 @@ func backendToken(c http.Client) (config.Cluster, error) { return respConfig, nil } +// passwordPrompt asks for a password +func passwordPrompt() { + prompt := &survey.Password{ + Message: "Password for " + username + ":", + } + survey.AskOne(prompt, &password) +} + +// validateProfile ensures a minimum set of profile config settings are set +func validateProfile(profile string) bool { + api = viper.GetString(profile + ".api") + username = viper.GetString(profile + ".username") + password = viper.GetString(profile + ".password") + insecure = viper.GetBool(profile + ".insecure-skip-tls-verify") + trustedcafile = viper.GetString(profile + ".trusted-ca-file") + + if api == "" { + fmt.Println("api is required") + return false + } + if username == "" { + fmt.Println("username is required") + return false + } + if !interactive && password == "" { + fmt.Println("password is required") + return false + } + + return true +} + // frmt returns a unicode separator the length of the provided string // to make the CLI output formatted a bit better. func frmt(s string) string {