diff --git a/cmd/cmd_check.go b/cmd/cmd_check.go index 7d3aced..593879e 100644 --- a/cmd/cmd_check.go +++ b/cmd/cmd_check.go @@ -6,6 +6,7 @@ import ( func init() { checkCmd.AddCommand(checkBoxCmd) + checkCmd.AddCommand(checkAllCmd) rootCmd.AddCommand(checkCmd) } @@ -26,3 +27,12 @@ var checkBoxCmd = &cobra.Command{ return checkAndNotify(args) }, } + +var checkAllCmd = &cobra.Command{ + Use: "all", + Short: "one-off check on all boxes registered on the opensensemap instance", + RunE: func(cmd *cobra.Command, args []string) error { + cmd.SilenceUsage = true + return checkAndNotifyAll() + }, +} diff --git a/cmd/cmd_watch.go b/cmd/cmd_watch.go index 471fba7..63c032d 100644 --- a/cmd/cmd_watch.go +++ b/cmd/cmd_watch.go @@ -18,6 +18,7 @@ func init() { viper.BindPFlags(watchCmd.PersistentFlags()) watchCmd.AddCommand(watchBoxesCmd) + watchCmd.AddCommand(watchAllCmd) rootCmd.AddCommand(watchCmd) } @@ -54,3 +55,27 @@ var watchBoxesCmd = &cobra.Command{ } }, } + +var watchAllCmd = &cobra.Command{ + Use: "all", + Short: "watch all boxes registered on the map", + PreRun: func(cmd *cobra.Command, args []string) { + interval := viper.GetDuration("interval") * time.Minute + ticker = time.NewTicker(interval).C + }, + RunE: func(cmd *cobra.Command, args []string) error { + cmd.SilenceUsage = true + err := checkAndNotifyAll() + if err != nil { + return err + } + for { + <-ticker + err = checkAndNotifyAll() + if err != nil { + // we already did retries, so exiting seems appropriate + return err + } + } + }, +} diff --git a/cmd/shared.go b/cmd/shared.go index 74c169e..ff9a519 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -5,6 +5,7 @@ import ( "regexp" "strings" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -33,6 +34,26 @@ func BoxIdValidator(cmd *cobra.Command, args []string) error { return nil } +func checkAndNotifyAll() error { + log.Info("getting list of boxes...") + + // fetch all boxes first & extract their IDs + osem := core.NewOsemClient(viper.GetString("api")) + boxes, err := osem.GetAllBoxes() + if err != nil { + return err + } + boxIDs := make([]string, len(*boxes)) + for i, box := range *boxes { + boxIDs[i] = box.Id + } + + // then check each box individually. we only pass the ID + // and fetch again, because box metadata is different in + // GetAllBoxes and GetBox.. + return checkAndNotify(boxIDs) +} + func checkAndNotify(boxIds []string) error { boxLocalConfig := map[string]*core.NotifyConfig{} for _, boxID := range boxIds { diff --git a/core/osem_api.go b/core/osem_api.go index 59ed708..7b18d08 100644 --- a/core/osem_api.go +++ b/core/osem_api.go @@ -33,6 +33,16 @@ func (client *OsemClient) GetBox(boxId string) (*Box, error) { return box, nil } +func (client *OsemClient) GetAllBoxes() (*[]Box, error) { + boxes := &[]Box{} + fail := &OsemError{} + client.sling.New().Path("boxes").Receive(boxes, fail) + if fail.Message != "" { + return boxes, errors.New("could not fetch boxes: " + fail.Message) + } + return boxes, nil +} + type NotifyEvent struct { Type string `json:"type"` Target string `json:"target"`