crowdsec/pkg/cwhub/dataset.go

107 lines
2 KiB
Go
Raw Normal View History

package cwhub
2020-05-27 14:31:08 +00:00
import (
"errors"
2020-05-27 14:31:08 +00:00
"fmt"
"io"
2020-05-27 14:31:08 +00:00
"net/http"
"os"
"path/filepath"
2020-05-27 14:31:08 +00:00
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
2020-05-27 14:31:08 +00:00
"github.com/crowdsecurity/crowdsec/pkg/types"
)
2020-05-27 14:31:08 +00:00
type DataSet struct {
Data []types.DataSource `yaml:"data,omitempty"`
2020-05-27 14:31:08 +00:00
}
func downloadFile(url string, destPath string) error {
log.Debugf("downloading %s in %s", url, destPath)
req, err := http.NewRequest(http.MethodGet, url, nil)
2020-05-27 14:31:08 +00:00
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("got HTTP status '%s' from %s", resp.Status, url)
}
body, err := io.ReadAll(resp.Body)
2020-05-27 14:31:08 +00:00
if err != nil {
return err
}
file, err := os.OpenFile(destPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644)
2020-05-27 14:31:08 +00:00
if err != nil {
return err
}
defer file.Close()
2020-05-27 14:31:08 +00:00
_, err = file.Write(body)
2020-05-27 14:31:08 +00:00
if err != nil {
return err
}
if err = file.Sync(); err != nil {
2020-05-27 14:31:08 +00:00
return err
}
return nil
}
func GetData(data []types.DataSource, dataDir string) error {
2020-05-27 14:31:08 +00:00
for _, dataS := range data {
destPath := filepath.Join(dataDir, dataS.DestPath)
2020-05-27 14:31:08 +00:00
log.Infof("downloading data '%s' in '%s'", dataS.SourceURL, destPath)
if err := downloadFile(dataS.SourceURL, destPath); err != nil {
2020-05-27 14:31:08 +00:00
return err
}
}
return nil
}
// downloadData downloads the data files for an item
func downloadData(dataFolder string, force bool, reader io.Reader) error {
dec := yaml.NewDecoder(reader)
for {
data := &DataSet{}
if err := dec.Decode(data); err != nil {
if errors.Is(err, io.EOF) {
break
}
return fmt.Errorf("while reading file: %w", err)
}
download := false
for _, dataS := range data.Data {
if _, err := os.Stat(filepath.Join(dataFolder, dataS.DestPath)); os.IsNotExist(err) {
download = true
}
}
if download || force {
if err := GetData(data.Data, dataFolder); err != nil {
return fmt.Errorf("while getting data: %w", err)
}
}
}
return nil
}