// Start method fetches and builds Sensu data from each datacenter every Refresh seconds func (d *Daemon) Start(interval int, data chan *structs.Data) { // immediately fetch the first set of data and send it over the data channel d.fetchData() d.buildData() select { case data <- d.Data: logger.Debug("Sending initial results on the 'data' channel") default: logger.Debug("Could not send initial results on the 'data' channel") } // fetch new data every interval duration := time.Duration(interval) * time.Second for _ = range time.Tick(duration) { d.resetData() d.fetchData() d.buildData() // send the result over the data channel select { case data <- d.Data: logger.Debug("Sending results on the 'data' channel") default: logger.Debug("Could not send results on the 'data' channel") } } }
func initUchiwa(global GlobalConfig) GlobalConfig { // Set the proper authentication driver if global.Github.Server != "" { global.Auth.Driver = "github" } else if global.Gitlab.Server != "" { global.Auth.Driver = "gitlab" } else if global.Ldap.Server != "" { global.Auth.Driver = "ldap" if global.Ldap.GroupBaseDN == "" { global.Ldap.GroupBaseDN = global.Ldap.BaseDN } if global.Ldap.UserBaseDN == "" { global.Ldap.UserBaseDN = global.Ldap.BaseDN } } else if global.Db.Driver != "" && global.Db.Scheme != "" { global.Auth.Driver = "sql" } else if len(global.Users) != 0 { logger.Debug("Loading multiple users from the config") global.Auth.Driver = "simple" } else if global.User != "" && global.Pass != "" { logger.Debug("Loading single user from the config") global.Auth.Driver = "simple" // Support multiple users global.Users = append(global.Users, auth.User{Username: global.User, Password: global.Pass, FullName: global.User}) } // Set the logger level logger.SetLogLevel(global.LogLevel) return global }
// loadToken loads a private and public RSA keys from the filesystem // in order to be used for the JWT signature func loadToken(a structs.Auth) (*rsa.PrivateKey, *rsa.PublicKey, error) { logger.Debug("Attempting to load the RSA keys from the filesystem") if a.PrivateKey == "" || a.PublicKey == "" { return nil, nil, errors.New("The paths to the private and public RSA keys were not provided") } // Read the files from the filesystem prv, err := ioutil.ReadFile(a.PrivateKey) if err != nil { logger.Fatalf("Unable to open the private key file: %v", err) } pub, err := ioutil.ReadFile(a.PublicKey) if err != nil { logger.Fatalf("Unable to open the public key file: %v", err) } // Parse the RSA keys privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(prv) if err != nil { logger.Fatalf("Unable to parse the private key: %v", err) } publicKey, err := jwt.ParseRSAPublicKeyFromPEM(pub) if err != nil { logger.Fatalf("Unable to parse the public key: %v", err) } logger.Info("Provided RSA keys successfully loaded") return privateKey, publicKey, nil }
// initToken initializes the token by weither loading the keys from the // filesystem with the loadToken() function or by generating temporarily // ones with the generateToken() function func initToken(a structs.Auth) { var err error privateKey, publicKey, err = loadToken(a) if err != nil { // At this point we need to generate temporary RSA keys logger.Debug(err) privateKey, publicKey = generateToken() } }
// generateToken generates a private and public RSA keys // in order to be used for the JWT signature func generateToken() (*rsa.PrivateKey, *rsa.PublicKey) { logger.Debug("Generating new temporary RSA keys") privateKey := generateKeyPair() // Precompute some calculations privateKey.Precompute() publicKey := &privateKey.PublicKey return privateKey, publicKey }
func (s *Sensu) postPayload(endpoint string, payload string) (map[string]interface{}, error) { apis := shuffle(s.APIs) for i := 0; i < len(apis); i++ { m, err := apis[i].postPayload(endpoint, payload) if err == nil { return m, err } logger.Debug(err) } return nil, errors.New("") }
func (s *Sensu) getSlice(endpoint string, limit int) ([]interface{}, error) { apis := shuffle(s.APIs) for i := 0; i < len(apis); i++ { slice, err := apis[i].getSlice(endpoint, limit) if err == nil { return slice, err } logger.Debug(err) } return nil, errors.New("") }
func (s *Sensu) getBytes(endpoint string) ([]byte, *http.Response, error) { apis := shuffle(s.APIs) for i := 0; i < len(apis); i++ { bytes, res, err := apis[i].getBytes(endpoint) if err == nil { return bytes, res, err } logger.Debug(err) } return nil, nil, errors.New("") }
// GetBoolFromInterface ... func GetBoolFromInterface(i interface{}) (bool, error) { if i == nil { logger.Debug("The interface is nil") return false, errors.New("The interface is nil") } b, ok := i.(bool) if !ok { logger.Debugf("Could not assert to a boolean the interface: %+v", i) return false, errors.New("Could not assert to a boolean the interface") } return b, nil }
// BuildSubscriptions builds a slice of every client subscriptions func (d *Daemon) BuildSubscriptions() { for _, client := range d.Data.Clients { var generic structs.GenericClient err := mapstructure.Decode(client, &generic) if err != nil { logger.Debug("%s", err) continue } for _, subscription := range generic.Subscriptions { if !StringInArray(subscription, d.Data.Subscriptions) { d.Data.Subscriptions = append(d.Data.Subscriptions, subscription) } } } }
// listener method listens on the data channel for messages from the daemon // and updates the Data structure with results from the Sensu APIs func (u *Uchiwa) listener(interval int, data chan *structs.Data) { for { select { case result := <-data: logger.Debug("Received results on the 'data' channel") u.Mu.Lock() u.Data = result u.Mu.Unlock() // sleep during the interval timer := time.NewTimer(time.Second * time.Duration(interval)) <-timer.C default: // sleep during 1 second timer := time.NewTimer(time.Second * 1) <-timer.C } } }
func main() { configFile := flag.String("c", "./config.json", "Full or relative path to the configuration file") publicPath := flag.String("p", "public", "Full or relative path to the public directory") flag.Parse() config, err := config.Load(*configFile) if err != nil { logger.Fatal(err) } logger.Debug("Debug mode enabled") u := uchiwa.Init(config) authentication := auth.New(config.Uchiwa.Auth) if config.Uchiwa.Auth.Driver == "simple" { authentication.Simple(config.Uchiwa.Users) } else { authentication.None() } // Audit audit.Log = audit.LogMock // filters uchiwa.FilterAggregates = filters.FilterAggregates uchiwa.FilterChecks = filters.FilterChecks uchiwa.FilterClients = filters.FilterClients uchiwa.FilterDatacenters = filters.FilterDatacenters uchiwa.FilterEvents = filters.FilterEvents uchiwa.FilterStashes = filters.FilterStashes uchiwa.FilterSubscriptions = filters.FilterSubscriptions uchiwa.FilterGetRequest = filters.GetRequest uchiwa.FilterPostRequest = filters.PostRequest uchiwa.FilterSensuData = filters.SensuData u.WebServer(publicPath, authentication) }
func (c *Config) initUchiwa() { if c.Dashboard != nil { c.Uchiwa = *c.Dashboard } if c.Uchiwa.Host == "" { c.Uchiwa.Host = "0.0.0.0" } if c.Uchiwa.Port == 0 { c.Uchiwa.Port = 3000 } if c.Uchiwa.Refresh == 0 { c.Uchiwa.Refresh = 10 } else if c.Uchiwa.Refresh >= 1000 { // backward compatibility with < 0.3.0 version c.Uchiwa.Refresh = c.Uchiwa.Refresh / 1000 } // authentication if c.Uchiwa.Github.Server != "" { c.Uchiwa.Auth = "github" } else if c.Uchiwa.Ldap.Server != "" { c.Uchiwa.Auth = "ldap" if c.Uchiwa.Ldap.Port == 0 { c.Uchiwa.Ldap.Port = 389 } if c.Uchiwa.Ldap.Security == "" { c.Uchiwa.Ldap.Security = "none" } if c.Uchiwa.Ldap.UserAttribute == "" { c.Uchiwa.Ldap.UserAttribute = "sAMAccountName" } if c.Uchiwa.Ldap.UserObjectClass == "" { c.Uchiwa.Ldap.UserObjectClass = "person" } if c.Uchiwa.Ldap.GroupMemberAttribute == "" { c.Uchiwa.Ldap.GroupMemberAttribute = "member" } if c.Uchiwa.Ldap.GroupObjectClass == "" { c.Uchiwa.Ldap.GroupObjectClass = "groupOfNames" } if c.Uchiwa.Ldap.GroupBaseDN == "" { c.Uchiwa.Ldap.GroupBaseDN = c.Uchiwa.Ldap.BaseDN } if c.Uchiwa.Ldap.UserBaseDN == "" { c.Uchiwa.Ldap.UserBaseDN = c.Uchiwa.Ldap.BaseDN } } else if c.Uchiwa.Db.Driver != "" && c.Uchiwa.Db.Scheme != "" { c.Uchiwa.Auth = "sql" } else if len(c.Uchiwa.Users) != 0 { logger.Debug("Loading multiple users from the config") c.Uchiwa.Auth = "simple" } else if c.Uchiwa.User != "" && c.Uchiwa.Pass != "" { logger.Debug("Loading single user from the config") c.Uchiwa.Auth = "simple" c.Uchiwa.Users = append(c.Uchiwa.Users, auth.User{Username: c.Uchiwa.User, Password: c.Uchiwa.Pass, FullName: c.Uchiwa.User}) } // audit if c.Uchiwa.Audit.Level != "verbose" && c.Uchiwa.Audit.Level != "disabled" { c.Uchiwa.Audit.Level = "default" } if c.Uchiwa.Audit.Logfile == "" { c.Uchiwa.Audit.Logfile = "/var/log/sensu/sensu-enterprise-dashboard-audit.log" } }