mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Always create event next 3rd Tuesday (#17799)
Fix to always create events for next 3rd Tuesday #17441
This commit is contained in:
parent
31fe9d17b9
commit
c6e2e8d6c4
2 changed files with 77 additions and 68 deletions
|
|
@ -198,7 +198,6 @@ func processCalendarFailingHosts(
|
|||
hostCalendarEvent, calendarEvent, err := ds.GetHostCalendarEventByEmail(ctx, host.Email)
|
||||
|
||||
expiredEvent := false
|
||||
webhookAlreadyFiredThisMonth := false
|
||||
if err == nil {
|
||||
if hostCalendarEvent.HostID != host.HostID {
|
||||
// This calendar event belongs to another host with this associated email,
|
||||
|
|
@ -217,7 +216,6 @@ func processCalendarFailingHosts(
|
|||
// we give a grace period of one day for the host before we schedule a new event.
|
||||
continue // continue with next host
|
||||
}
|
||||
webhookAlreadyFiredThisMonth = webhookAlreadyFired && sameMonth(now, calendarEvent.StartTime)
|
||||
if calendarEvent.EndTime.Before(now) {
|
||||
expiredEvent = true
|
||||
}
|
||||
|
|
@ -237,7 +235,7 @@ func processCalendarFailingHosts(
|
|||
}
|
||||
case fleet.IsNotFound(err) || expiredEvent:
|
||||
if err := processFailingHostCreateCalendarEvent(
|
||||
ctx, ds, userCalendar, orgName, host, webhookAlreadyFiredThisMonth,
|
||||
ctx, ds, userCalendar, orgName, host,
|
||||
); err != nil {
|
||||
level.Info(logger).Log("msg", "process failing host create calendar event", "err", err)
|
||||
continue // continue with next host
|
||||
|
|
@ -357,21 +355,14 @@ func sameDate(t1 time.Time, t2 time.Time) bool {
|
|||
return y1 == y2 && m1 == m2 && d1 == d2
|
||||
}
|
||||
|
||||
func sameMonth(t1 time.Time, t2 time.Time) bool {
|
||||
y1, m1, _ := t1.Date()
|
||||
y2, m2, _ := t2.Date()
|
||||
return y1 == y2 && m1 == m2
|
||||
}
|
||||
|
||||
func processFailingHostCreateCalendarEvent(
|
||||
ctx context.Context,
|
||||
ds fleet.Datastore,
|
||||
userCalendar fleet.UserCalendar,
|
||||
orgName string,
|
||||
host fleet.HostPolicyMembershipData,
|
||||
webhookAlreadyFiredThisMonth bool,
|
||||
) error {
|
||||
calendarEvent, err := attemptCreatingEventOnUserCalendar(orgName, host, userCalendar, webhookAlreadyFiredThisMonth)
|
||||
calendarEvent, err := attemptCreatingEventOnUserCalendar(orgName, host, userCalendar)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create event on user calendar: %w", err)
|
||||
}
|
||||
|
|
@ -385,10 +376,9 @@ func attemptCreatingEventOnUserCalendar(
|
|||
orgName string,
|
||||
host fleet.HostPolicyMembershipData,
|
||||
userCalendar fleet.UserCalendar,
|
||||
webhookAlreadyFiredThisMonth bool,
|
||||
) (*fleet.CalendarEvent, error) {
|
||||
year, month, today := time.Now().Date()
|
||||
preferredDate := getPreferredCalendarEventDate(year, month, today, webhookAlreadyFiredThisMonth)
|
||||
preferredDate := getPreferredCalendarEventDate(year, month, today)
|
||||
for {
|
||||
calendarEvent, err := userCalendar.CreateEvent(
|
||||
preferredDate, func(conflict bool) string {
|
||||
|
|
@ -408,10 +398,7 @@ func attemptCreatingEventOnUserCalendar(
|
|||
}
|
||||
}
|
||||
|
||||
func getPreferredCalendarEventDate(
|
||||
year int, month time.Month, today int,
|
||||
webhookAlreadyFired bool,
|
||||
) time.Time {
|
||||
func getPreferredCalendarEventDate(year int, month time.Month, today int) time.Time {
|
||||
const (
|
||||
// 3rd Tuesday of Month
|
||||
preferredWeekDay = time.Tuesday
|
||||
|
|
@ -425,12 +412,13 @@ func getPreferredCalendarEventDate(
|
|||
}
|
||||
preferredDate := firstDayOfMonth.AddDate(0, 0, offset+(7*(preferredOrdinal-1)))
|
||||
if today > preferredDate.Day() {
|
||||
today_ := time.Date(year, month, today, 0, 0, 0, 0, time.UTC)
|
||||
if webhookAlreadyFired {
|
||||
nextMonth := today_.AddDate(0, 1, 0) // move to next month
|
||||
return getPreferredCalendarEventDate(nextMonth.Year(), nextMonth.Month(), 1, false)
|
||||
// We are past the preferred date, so we move to next month and calculate again.
|
||||
month := month + 1
|
||||
if month == 13 {
|
||||
month = 1
|
||||
year += 1
|
||||
}
|
||||
preferredDate = addBusinessDay(today_)
|
||||
return getPreferredCalendarEventDate(year, month, 1)
|
||||
}
|
||||
return preferredDate
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,72 +12,93 @@ func TestGetPreferredCalendarEventDate(t *testing.T) {
|
|||
return time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
year int
|
||||
month time.Month
|
||||
daysStart int
|
||||
daysEnd int
|
||||
webhookFiredThisMonth bool
|
||||
name string
|
||||
year int
|
||||
month time.Month
|
||||
daysStart int
|
||||
daysEnd int
|
||||
|
||||
expected time.Time
|
||||
}{
|
||||
{
|
||||
name: "March 2024 (webhook hasn't fired)",
|
||||
year: 2024,
|
||||
month: 3,
|
||||
daysStart: 1,
|
||||
daysEnd: 31,
|
||||
webhookFiredThisMonth: false,
|
||||
name: "March 2024 (before 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 3,
|
||||
daysStart: 1,
|
||||
daysEnd: 19,
|
||||
|
||||
expected: date(2024, 3, 19),
|
||||
},
|
||||
{
|
||||
name: "March 2024 (webhook has fired, days before 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 3,
|
||||
daysStart: 1,
|
||||
daysEnd: 18,
|
||||
webhookFiredThisMonth: true,
|
||||
|
||||
expected: date(2024, 3, 19),
|
||||
},
|
||||
{
|
||||
name: "March 2024 (webhook has fired, days after 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 3,
|
||||
daysStart: 20,
|
||||
daysEnd: 30,
|
||||
webhookFiredThisMonth: true,
|
||||
name: "March 2024 (past 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 3,
|
||||
daysStart: 20,
|
||||
daysEnd: 31,
|
||||
|
||||
expected: date(2024, 4, 16),
|
||||
},
|
||||
{
|
||||
name: "April 2024 (webhook hasn't fired)",
|
||||
year: 2024,
|
||||
month: 4,
|
||||
daysEnd: 30,
|
||||
webhookFiredThisMonth: false,
|
||||
name: "April 2024 (before 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 4,
|
||||
daysStart: 1,
|
||||
daysEnd: 16,
|
||||
|
||||
expected: date(2024, 4, 16),
|
||||
},
|
||||
{
|
||||
name: "April 2024 (after 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 4,
|
||||
daysStart: 17,
|
||||
daysEnd: 30,
|
||||
|
||||
expected: date(2024, 5, 21),
|
||||
},
|
||||
{
|
||||
name: "May 2024 (before 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 5,
|
||||
daysStart: 1,
|
||||
daysEnd: 21,
|
||||
|
||||
expected: date(2024, 5, 21),
|
||||
},
|
||||
{
|
||||
name: "May 2024 (after 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 5,
|
||||
daysStart: 22,
|
||||
daysEnd: 31,
|
||||
|
||||
expected: date(2024, 6, 18),
|
||||
},
|
||||
{
|
||||
name: "Dec 2024 (before 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 12,
|
||||
daysStart: 1,
|
||||
daysEnd: 17,
|
||||
|
||||
expected: date(2024, 12, 17),
|
||||
},
|
||||
{
|
||||
name: "Dec 2024 (after 3rd Tuesday)",
|
||||
year: 2024,
|
||||
month: 12,
|
||||
daysStart: 18,
|
||||
daysEnd: 31,
|
||||
|
||||
expected: date(2025, 1, 21),
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
for day := tc.daysStart; day <= tc.daysEnd; day++ {
|
||||
actual := getPreferredCalendarEventDate(tc.year, tc.month, day, tc.webhookFiredThisMonth)
|
||||
actual := getPreferredCalendarEventDate(tc.year, tc.month, day)
|
||||
require.NotEqual(t, actual.Weekday(), time.Saturday)
|
||||
require.NotEqual(t, actual.Weekday(), time.Sunday)
|
||||
if day <= tc.expected.Day() || tc.webhookFiredThisMonth {
|
||||
require.Equal(t, tc.expected, actual)
|
||||
} else {
|
||||
today := date(tc.year, tc.month, day)
|
||||
if weekday := today.Weekday(); weekday == time.Friday {
|
||||
require.Equal(t, today.AddDate(0, 0, +3), actual)
|
||||
} else if weekday == time.Saturday {
|
||||
require.Equal(t, today.AddDate(0, 0, +2), actual)
|
||||
} else {
|
||||
require.Equal(t, today.AddDate(0, 0, +1), actual)
|
||||
}
|
||||
}
|
||||
require.Equal(t, tc.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue