lasso/cmd/lassoctl/cmd/root.go

123 lines
3.4 KiB
Go

/*
Copyright © 2021 Arsen Musayelyan
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 <http://www.gnu.org/licenses/>.
*/
package cmd
import (
"net"
"net/http"
"strings"
"github.com/abiosoft/ishell"
"github.com/mitchellh/mapstructure"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/vmihailenco/msgpack/v5"
"go.arsenm.dev/lasso/internal/types"
"github.com/spf13/viper"
)
var cfgFile string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "lassoctl",
Short: "Manage devices using IPs retrieved from a lasso server",
}
// 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() {
cobra.CheckErr(rootCmd.Execute())
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file to use")
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath("/etc")
viper.SetConfigType("toml")
viper.SetConfigName("lassoctl")
}
viper.SetEnvPrefix("lassoctl")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
viper.ReadInConfig()
}
// getNodeList gets a list of nodes from the lasso server
func getNodeList() map[string]types.Node {
// Get server address
addr := net.JoinHostPort(viper.GetString("server.addr"), viper.GetString("server.port"))
// Create base url for HTTPS server
baseURL := "https://" + addr
// Get node list
res, err := http.Get(baseURL + "/node/list")
if err != nil {
log.Fatal().Err(err).Msg("Error getting node list from server")
}
var resp types.Response
// Decode server response
err = msgpack.NewDecoder(res.Body).Decode(&resp)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding server response")
}
// If server response is an error
if resp.Error {
log.Fatal().Str("error", resp.Message).Msg("Server returned error")
}
var nodes map[string]types.Node
// Decode response data as node map
err = mapstructure.Decode(resp.Data, &nodes)
if err != nil {
log.Fatal().Err(err).Msg("Error decoding nodes map")
}
// Return node map
return nodes
}
// cmdError prints an error while running mssh
func cmdError(shell *ishell.Shell, node string, err error) {
shell.Printf("%s [error]: %v\n", node, err)
}
// cmdOut prints output from a command while running mssh
func cmdOut(shell *ishell.Shell, node, out string) {
shell.Printf("%s [out]: %s\n", node, out)
}
// cmdSucces prints a success message while running mssh
func cmdSuccess(shell *ishell.Shell, node, msg string) {
shell.Printf("%s [success]: %s\n", node, msg)
}