github.com/crowdsecurity/crowdsec@v1.6.1/cmd/crowdsec/api.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "runtime" 7 "time" 8 9 log "github.com/sirupsen/logrus" 10 11 "github.com/crowdsecurity/go-cs-lib/trace" 12 13 "github.com/crowdsecurity/crowdsec/pkg/apiserver" 14 "github.com/crowdsecurity/crowdsec/pkg/csconfig" 15 ) 16 17 func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) { 18 if cConfig.API.Server.OnlineClient == nil || cConfig.API.Server.OnlineClient.Credentials == nil { 19 log.Info("push and pull to Central API disabled") 20 } 21 22 apiServer, err := apiserver.NewServer(cConfig.API.Server) 23 if err != nil { 24 return nil, fmt.Errorf("unable to run local API: %w", err) 25 } 26 27 if hasPlugins(cConfig.API.Server.Profiles) { 28 log.Info("initiating plugin broker") 29 // On windows, the plugins are always run as medium-integrity processes, so we don't care about plugin_config 30 if cConfig.PluginConfig == nil && runtime.GOOS != "windows" { 31 return nil, errors.New("plugins are enabled, but the plugin_config section is missing in the configuration") 32 } 33 34 if cConfig.ConfigPaths.NotificationDir == "" { 35 return nil, errors.New("plugins are enabled, but config_paths.notification_dir is not defined") 36 } 37 38 if cConfig.ConfigPaths.PluginDir == "" { 39 return nil, errors.New("plugins are enabled, but config_paths.plugin_dir is not defined") 40 } 41 42 err = pluginBroker.Init(cConfig.PluginConfig, cConfig.API.Server.Profiles, cConfig.ConfigPaths) 43 if err != nil { 44 return nil, fmt.Errorf("unable to run plugin broker: %w", err) 45 } 46 47 log.Info("initiated plugin broker") 48 apiServer.AttachPluginBroker(&pluginBroker) 49 } 50 51 err = apiServer.InitController() 52 if err != nil { 53 return nil, fmt.Errorf("unable to run local API: %w", err) 54 } 55 56 return apiServer, nil 57 } 58 59 func serveAPIServer(apiServer *apiserver.APIServer) { 60 apiReady := make(chan bool, 1) 61 apiTomb.Go(func() error { 62 defer trace.CatchPanic("crowdsec/serveAPIServer") 63 go func() { 64 defer trace.CatchPanic("crowdsec/runAPIServer") 65 log.Debugf("serving API after %s ms", time.Since(crowdsecT0)) 66 if err := apiServer.Run(apiReady); err != nil { 67 log.Fatal(err) 68 } 69 }() 70 71 pluginTomb.Go(func() error { 72 pluginBroker.Run(&pluginTomb) 73 return nil 74 }) 75 76 <-apiTomb.Dying() // lock until go routine is dying 77 pluginTomb.Kill(nil) 78 log.Infof("serve: shutting down api server") 79 if err := apiServer.Shutdown(); err != nil { 80 return err 81 } 82 return nil 83 }) 84 <-apiReady 85 } 86 87 func hasPlugins(profiles []*csconfig.ProfileCfg) bool { 88 for _, profile := range profiles { 89 if len(profile.Notifications) != 0 { 90 return true 91 } 92 } 93 return false 94 }