database/elasticsearch/elasticsearch.go
func (db *Database) StorePluginResults(results database.PluginResults) error {

	// Test connection to ElasticSearch
	err := db.TestConnection()
	if err != nil {
		return errors.Wrap(err, "failed to connect to database")
	}

	client, err := elastic.NewSimpleClient(
		elastic.SetURL(db.URL),
		elastic.SetBasicAuth(
			utils.Getopts(db.Username, "MALICE_ELASTICSEARCH_USERNAME", ""),
			utils.Getopts(db.Password, "MALICE_ELASTICSEARCH_PASSWORD", ""),
		),
	)
	if err != nil {
		return errors.Wrap(err, "failed to create elasticsearch simple client")
	}

	// get sample db record
	getSample, err := client.Get().
		Index(db.Index).
		Type(db.Type).
		Id(results.ID).
		Do(context.Background())
	// ignore 404 not found error
	if err != nil && !elastic.IsNotFound(err) {
		return errors.Wrapf(err, "failed to get sample with id: %s", results.ID)
	}

	if getSample != nil && getSample.Found {
		log.Debugf("got document %s in version %d from index %s, type %s\n", getSample.Id, getSample.Version, getSample.Index, getSample.Type)
		updateScan := map[string]interface{}{
			"scan_date": time.Now().Format(time.RFC3339Nano),
			"plugins": map[string]interface{}{
				results.Category: map[string]interface{}{
					results.Name: results.Data,
				},
			},
		}
		update, err := client.Update().Index(db.Index).Type(db.Type).Id(getSample.Id).
			Doc(updateScan).
			Do(context.Background())
		if err != nil {
			return errors.Wrapf(err, "failed to update sample with id: %s", results.ID)
		}

		log.Debugf("updated version of sample %q is now %d\n", update.Id, update.Version)

	} else {
		// ID not found so create new document with `index` command
		scan := map[string]interface{}{
			"plugins": map[string]interface{}{
				results.Category: map[string]interface{}{
					results.Name: results.Data,
				},
			},
			"scan_date": time.Now().Format(time.RFC3339Nano),
		}

		newScan, err := client.Index().
			Index(db.Index).
			Type(db.Type).
			OpType("index").
			// Id("1").
			BodyJson(scan).
			Do(context.Background())
		if err != nil {
			return errors.Wrapf(err, "failed to create new sample plugin doc with id: %s", results.ID)
		}

		log.WithFields(log.Fields{
			"id":    newScan.Id,
			"index": newScan.Index,
			"type":  newScan.Type,
		}).Debug("indexed sample")
	}

	return nil
}
func (db *Database) StorePluginResults(results database.PluginResults) error {

	// Test connection to ElasticSearch
	err := db.TestConnection()
	if err != nil {
		return errors.Wrap(err, "failed to connect to database")
	}

	client, err := elastic.NewSimpleClient(
		elastic.SetURL(db.URL),
		elastic.SetBasicAuth(
			utils.Getopts(db.Username, "MALICE_ELASTICSEARCH_USERNAME", ""),
			utils.Getopts(db.Password, "MALICE_ELASTICSEARCH_PASSWORD", ""),
		),
	)
	if err != nil {
		return errors.Wrap(err, "failed to create elasticsearch simple client")
	}

	// get sample db record
	getSample, err := client.Get().
		Index(db.Index).
		Type(db.Type).
		Id(results.ID).
		Do(context.Background())
	// ignore 404 not found error
	if err != nil && !elastic.IsNotFound(err) {
		return errors.Wrapf(err, "failed to get sample with id: %s", results.ID)
	}

	if getSample != nil && getSample.Found {
		log.Debugf("got document %s in version %d from index %s, type %s\n", getSample.Id, getSample.Version, getSample.Index, getSample.Type)
		updateScan := map[string]interface{}{
			"scan_date": time.Now().Format(time.RFC3339Nano),
			"plugins": map[string]interface{}{
				results.Category: map[string]interface{}{
					results.Name: results.Data,
				},
			},
		}
		update, err := client.Update().Index(db.Index).Type(db.Type).Id(getSample.Id).
			Doc(updateScan).
			Do(context.Background())
		if err != nil {
			return errors.Wrapf(err, "failed to update sample with id: %s", results.ID)
		}

		log.Debugf("updated version of sample %q is now %d\n", update.Id, update.Version)

	} else {
		// ID not found so create new document with `index` command
		scan := map[string]interface{}{
			"plugins": map[string]interface{}{
				results.Category: map[string]interface{}{
					results.Name: results.Data,
				},
			},
			"scan_date": time.Now().Format(time.RFC3339Nano),
		}

		newScan, err := client.Index().
			Index(db.Index).
			Type(db.Type).
			OpType("index").
			// Id("1").
			BodyJson(scan).
			Do(context.Background())
		if err != nil {
			return errors.Wrapf(err, "failed to create new sample plugin doc with id: %s", results.ID)
		}

		log.WithFields(log.Fields{
			"id":    newScan.Id,
			"index": newScan.Index,
			"type":  newScan.Type,
		}).Debug("indexed sample")
	}

	return nil
}
// StorePluginResults stores a plugin's results in the database by updating
// the placeholder created by the call to StoreFileInfo