Skip to content
Snippets Groups Projects
Select Git revision
  • 6c43e710b11dffe1022fcc2aa7f0cea58ee0f368
  • main default protected
  • development
  • integration
  • v1.1.5
  • v1.1.4
  • v1.1.3
  • v1.1.2
  • v1.1.1
  • v1.1.0
  • v1.0.0
11 results

GetVersion.swift

Blame
  • root.go 7.41 KiB
    ////////////////////////////////////////////////////////////////////////////////
    // Copyright © 2020 Privategrity Corporation                                   /
    //                                                                             /
    // All rights reserved.                                                        /
    ////////////////////////////////////////////////////////////////////////////////
    
    // Package cmd initializes the CLI and config parsers as well as the logger
    
    package cmd
    
    import (
    	"fmt"
    	"github.com/mitchellh/go-homedir"
    	"github.com/pkg/errors"
    	"github.com/spf13/cobra"
    	jww "github.com/spf13/jwalterweatherman"
    	"github.com/spf13/viper"
    	"gitlab.com/elixxir/comms/mixmessages"
    	"gitlab.com/elixxir/notifications-bot/notifications"
    	"gitlab.com/elixxir/notifications-bot/storage"
    	"gitlab.com/elixxir/primitives/id"
    	"gitlab.com/elixxir/primitives/ndf"
    	"gitlab.com/elixxir/primitives/utils"
    	"os"
    	"path"
    	"strings"
    )
    
    var (
    	cfgFile            string
    	verbose            bool
    	noTLS              bool
    	NotificationParams notifications.Params
    	loopDelay          int
    )
    
    // rootCmd represents the base command when called without any subcommands
    var rootCmd = &cobra.Command{
    	Use:   "registration",
    	Short: "Runs a registration server for cMix",
    	Long:  `This server provides registration functions on cMix`,
    	Args:  cobra.NoArgs,
    	Run: func(cmd *cobra.Command, args []string) {
    		if verbose {
    			err := os.Setenv("GRPC_GO_LOG_SEVERITY_LEVEL", "info")
    			if err != nil {
    				jww.ERROR.Printf("Could not set GRPC_GO_LOG_SEVERITY_LEVEL: %+v", err)
    			}
    
    			err = os.Setenv("GRPC_GO_LOG_VERBOSITY_LEVEL", "2")
    			if err != nil {
    				jww.ERROR.Printf("Could not set GRPC_GO_LOG_VERBOSITY_LEVEL: %+v", err)
    			}
    		}
    
    		// Parse config file options
    		certPath := viper.GetString("certPath")
    		keyPath := viper.GetString("keyPath")
    		localAddress := fmt.Sprintf("0.0.0.0:%d", viper.GetInt("port"))
    		fbCreds := viper.GetString("firebaseCredentialsPath")
    
    		// Populate params
    		NotificationParams = notifications.Params{
    			Address:  localAddress,
    			CertPath: certPath,
    			KeyPath:  keyPath,
    			FBCreds:  fbCreds,
    		}
    		jww.INFO.Println("Starting Notifications...")
    
    		impl, err := notifications.StartNotifications(NotificationParams, noTLS, false)
    		if err != nil {
    			jww.FATAL.Panicf("Failed to start notifications server: %+v", err)
    		}
    
    		impl.Storage = storage.NewDatabase(
    			viper.GetString("dbUsername"),
    			viper.GetString("dbPassword"),
    			viper.GetString("dbName"),
    			viper.GetString("dbAddress"),
    		)
    
    		err = setupConnection(impl, viper.GetString("permissioningCertPath"), viper.GetString("permissioningAddress"))
    		if err != nil {
    			jww.FATAL.Panicf("Failed to set up connections: %+v", err)
    		}
    
    		// Start notification loop
    		killChan := make(chan struct{})
    		errChan := make(chan error)
    		go impl.RunNotificationLoop(loopDelay, killChan, errChan)
    
    		// Wait forever to prevent process from ending
    		err = <-errChan
    		panic(err)
    	},
    }
    
    // setupConnection handles connecting to permissioning and polling for the NDF once connected
    func setupConnection(impl *notifications.Impl, permissioningCertPath, permissioningAddr string) error {
    	// Read in permissioning certificate
    	cert, err := utils.ReadFile(permissioningCertPath)
    	if err != nil {
    		return errors.Wrap(err, "Could not read permissioning cert")
    	}
    
    	// Add host for permissioning server
    	_, err = impl.Comms.AddHost(id.PERMISSIONING, permissioningAddr, cert, true, true)
    	if err != nil {
    		return errors.Wrap(err, "Failed to Create permissioning host")
    	}
    
    	// Loop until an NDF is received
    	var def *ndf.NetworkDefinition
    	for def == nil {
    		def, err = notifications.PollNdf(nil, impl.Comms)
    		// Don't stop if error is expected
    		if err != nil && !strings.Contains(err.Error(), ndf.NO_NDF) {
    			return errors.Wrap(err, "Failed to get NDF")
    		}
    	}
    
    	// Update NDF & gateway host
    	err = impl.UpdateNdf(def)
    	if err != nil {
    		return errors.Wrap(err, "Failed to update impl's NDF")
    	}
    	return nil
    }
    
    // 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 {
    		jww.ERROR.Println(err)
    		os.Exit(1)
    	}
    }
    
    // init is the initialization function for Cobra which defines commands
    // and flags.
    func init() {
    	// NOTE: The point of init() is to be declarative.
    	// There is one init in each sub command. Do not put variable declarations
    	// here, and ensure all the Flags are of the *P variety, unless there's a
    	// very good reason not to have them as local params to sub command."
    	cobra.OnInitialize(initConfig, initLog)
    
    	// Here you will define your flags and configuration settings.
    	// Cobra supports persistent flags, which, if defined here,
    	// will be global for your application.
    	rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false,
    		"Show verbose logs for debugging")
    
    	rootCmd.Flags().StringVarP(&cfgFile, "config", "c",
    		"", "Sets a custom config file path")
    
    	rootCmd.Flags().BoolVar(&noTLS, "noTLS", false,
    		"Runs without TLS enabled")
    
    	rootCmd.Flags().IntVarP(&loopDelay, "loopDelay", "", 500,
    		"Set the delay between notification loops (in milliseconds)")
    
    	// Bind config and command line flags of the same name
    	err := viper.BindPFlag("verbose", rootCmd.Flags().Lookup("verbose"))
    	handleBindingError(err, "verbose")
    }
    
    // Handle flag binding errors
    func handleBindingError(err error, flag string) {
    	if err != nil {
    		jww.FATAL.Panicf("Error on binding flag \"%s\":%+v", flag, err)
    	}
    }
    
    // initConfig reads in config file and ENV variables if set.
    func initConfig() {
    	//Use default config location if none is passed
    	if cfgFile == "" {
    		// Find home directory.
    		home, err := homedir.Dir()
    		if err != nil {
    			jww.ERROR.Println(err)
    			os.Exit(1)
    		}
    
    		cfgFile = home + "/.elixxir/notifications.yaml"
    
    	}
    
    	validConfig := true
    	f, err := os.Open(cfgFile)
    	if err != nil {
    		jww.ERROR.Printf("Unable to open config file (%s): %+v", cfgFile, err)
    		validConfig = false
    	}
    	_, err = f.Stat()
    	if err != nil {
    		jww.ERROR.Printf("Invalid config file (%s): %+v", cfgFile, err)
    		validConfig = false
    	}
    	err = f.Close()
    	if err != nil {
    		jww.ERROR.Printf("Unable to close config file (%s): %+v", cfgFile, err)
    		validConfig = false
    	}
    
    	// Set the config file if it is valid
    	if validConfig {
    		// Set the config path to the directory containing the config file
    		// This may increase the reliability of the config watching, somewhat
    		cfgDir, _ := path.Split(cfgFile)
    		viper.AddConfigPath(cfgDir)
    
    		viper.SetConfigFile(cfgFile)
    		viper.AutomaticEnv() // read in environment variables that match
    
    		// If a config file is found, read it in.
    		if err := viper.ReadInConfig(); err != nil {
    			jww.ERROR.Printf("Unable to parse config file (%s): %+v", cfgFile, err)
    			validConfig = false
    		}
    		viper.WatchConfig()
    	}
    }
    
    // initLog initializes logging thresholds and the log path.
    func initLog() {
    	if viper.Get("logPath") != nil {
    		// If verbose flag set then log more info for debugging
    		if verbose || viper.GetBool("verbose") {
    			jww.SetLogThreshold(jww.LevelDebug)
    			jww.SetStdoutThreshold(jww.LevelDebug)
    			mixmessages.DebugMode()
    		} else {
    			jww.SetLogThreshold(jww.LevelInfo)
    			jww.SetStdoutThreshold(jww.LevelInfo)
    		}
    		// Create log file, overwrites if existing
    		logPath := viper.GetString("logPath")
    		logFile, err := os.Create(logPath)
    		if err != nil {
    			jww.WARN.Println("Invalid or missing log path, default path used.")
    		} else {
    			jww.SetLogOutput(logFile)
    		}
    	}
    }