mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 00:49:03 +00:00
parent
1c311b73be
commit
be0e89142f
5 changed files with 152 additions and 2 deletions
|
|
@ -502,6 +502,7 @@ var hostRefs = []string{
|
|||
"query_results",
|
||||
"host_activities",
|
||||
"host_mdm_actions",
|
||||
"host_calendar_events",
|
||||
}
|
||||
|
||||
// NOTE: The following tables are explicity excluded from hostRefs list and accordingly are not
|
||||
|
|
|
|||
|
|
@ -2554,7 +2554,6 @@ func testHostLiteByIdentifierAndID(t *testing.T, ds *Datastore) {
|
|||
h, err = ds.HostLiteByID(context.Background(), 0)
|
||||
assert.ErrorIs(t, err, sql.ErrNoRows)
|
||||
assert.Nil(t, h)
|
||||
|
||||
}
|
||||
|
||||
func testHostsAddToTeam(t *testing.T, ds *Datastore) {
|
||||
|
|
@ -2795,7 +2794,6 @@ func testHostsTotalAndUnseenSince(t *testing.T, ds *Datastore) {
|
|||
assert.Equal(t, 2, total)
|
||||
require.Len(t, unseen, 1)
|
||||
assert.Equal(t, host3.ID, unseen[0])
|
||||
|
||||
}
|
||||
|
||||
func testHostsListByPolicy(t *testing.T, ds *Datastore) {
|
||||
|
|
@ -6577,6 +6575,23 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
|||
`, host.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a calendar event for the host.
|
||||
_, err = ds.writer(context.Background()).Exec(`
|
||||
INSERT INTO calendar_events (email, start_time, end_time, event)
|
||||
VALUES ('foobar@example.com', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '{}');
|
||||
`)
|
||||
require.NoError(t, err)
|
||||
var calendarEventID int
|
||||
err = ds.writer(context.Background()).Get(&calendarEventID, `
|
||||
SELECT id FROM calendar_events WHERE email = 'foobar@example.com';
|
||||
`)
|
||||
require.NoError(t, err)
|
||||
_, err = ds.writer(context.Background()).Exec(`
|
||||
INSERT INTO host_calendar_events (host_id, calendar_event_id, webhook_status)
|
||||
VALUES (?, ?, 1);
|
||||
`, host.ID, calendarEventID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check there's an entry for the host in all the associated tables.
|
||||
for _, hostRef := range hostRefs {
|
||||
var ok bool
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package tables
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func init() {
|
||||
MigrationClient.AddMigration(Up_20240313085226, Down_20240313085226)
|
||||
}
|
||||
|
||||
func Up_20240313085226(tx *sql.Tx) error {
|
||||
// TODO(lucas): Check if we need more indexes.
|
||||
|
||||
if _, err := tx.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS calendar_events (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
end_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
event JSON NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
`); err != nil {
|
||||
return fmt.Errorf("create calendar_events table: %w", err)
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS host_calendar_events (
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
host_id INT(10) UNSIGNED NOT NULL,
|
||||
calendar_event_id INT(10) UNSIGNED NOT NULL,
|
||||
webhook_status TINYINT NOT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE KEY idx_one_calendar_event_per_host (host_id),
|
||||
FOREIGN KEY (calendar_event_id) REFERENCES calendar_events(id) ON DELETE CASCADE
|
||||
);
|
||||
`); err != nil {
|
||||
return fmt.Errorf("create host_calendar_events table: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Down_20240313085226(tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package tables
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUp_20240313085226(t *testing.T) {
|
||||
db := applyUpToPrev(t)
|
||||
applyNext(t, db)
|
||||
|
||||
sampleEvent := fleet.CalendarEvent{
|
||||
Email: "foo@example.com",
|
||||
StartTime: time.Now().UTC(),
|
||||
EndTime: time.Now().UTC().Add(30 * time.Minute),
|
||||
Data: []byte("{\"foo\": \"bar\"}"),
|
||||
}
|
||||
sampleEvent.ID = uint(execNoErrLastID(t, db,
|
||||
`INSERT INTO calendar_events (email, start_time, end_time, event) VALUES (?, ?, ?, ?);`,
|
||||
sampleEvent.Email, sampleEvent.StartTime, sampleEvent.EndTime, sampleEvent.Data,
|
||||
))
|
||||
|
||||
sampleHostEvent := fleet.HostCalendarEvent{
|
||||
HostID: 1,
|
||||
CalendarEventID: sampleEvent.ID,
|
||||
WebhookStatus: fleet.CalendarWebhookStatusPending,
|
||||
}
|
||||
sampleHostEvent.ID = uint(execNoErrLastID(t, db,
|
||||
`INSERT INTO host_calendar_events (host_id, calendar_event_id, webhook_status) VALUES (?, ?, ?);`,
|
||||
sampleHostEvent.HostID, sampleHostEvent.CalendarEventID, sampleHostEvent.WebhookStatus,
|
||||
))
|
||||
|
||||
var event fleet.CalendarEvent
|
||||
err := db.Get(&event, `SELECT * FROM calendar_events WHERE id = ?;`, sampleEvent.ID)
|
||||
require.NoError(t, err)
|
||||
sampleEvent.CreatedAt = event.CreatedAt // sampleEvent doesn't have this set.
|
||||
sampleEvent.UpdatedAt = event.UpdatedAt // sampleEvent doesn't have this set.
|
||||
sampleEvent.StartTime = sampleEvent.StartTime.Round(time.Second)
|
||||
sampleEvent.EndTime = sampleEvent.EndTime.Round(time.Second)
|
||||
event.StartTime = event.StartTime.Round(time.Second)
|
||||
event.EndTime = event.EndTime.Round(time.Second)
|
||||
require.Equal(t, sampleEvent, event)
|
||||
|
||||
var hostEvent fleet.HostCalendarEvent
|
||||
err = db.Get(&hostEvent, `SELECT * FROM host_calendar_events WHERE id = ?;`, sampleHostEvent.ID)
|
||||
require.NoError(t, err)
|
||||
sampleHostEvent.CreatedAt = hostEvent.CreatedAt // sampleHostEvent doesn't have this set.
|
||||
sampleHostEvent.UpdatedAt = hostEvent.UpdatedAt // sampleHostEvent doesn't have this set.
|
||||
require.Equal(t, sampleHostEvent, hostEvent)
|
||||
}
|
||||
29
server/fleet/calendar_events.go
Normal file
29
server/fleet/calendar_events.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package fleet
|
||||
|
||||
import "time"
|
||||
|
||||
type CalendarEvent struct {
|
||||
ID uint `db:"id"`
|
||||
Email string `db:"email"`
|
||||
StartTime time.Time `db:"start_time"`
|
||||
EndTime time.Time `db:"end_time"`
|
||||
Data []byte `db:"event"`
|
||||
|
||||
UpdateCreateTimestamps
|
||||
}
|
||||
|
||||
type CalendarWebhookStatus int
|
||||
|
||||
const (
|
||||
CalendarWebhookStatusPending CalendarWebhookStatus = iota
|
||||
CalendarWebhookStatusSent
|
||||
)
|
||||
|
||||
type HostCalendarEvent struct {
|
||||
ID uint `db:"id"`
|
||||
HostID uint `db:"host_id"`
|
||||
CalendarEventID uint `db:"calendar_event_id"`
|
||||
WebhookStatus CalendarWebhookStatus `db:"webhook_status"`
|
||||
|
||||
UpdateCreateTimestamps
|
||||
}
|
||||
Loading…
Reference in a new issue