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  }