Always create event next 3rd Tuesday (#17799)

Fix to always create events for next 3rd Tuesday #17441
This commit is contained in:
Lucas Manuel Rodriguez 2024-03-22 14:16:08 -03:00 committed by Victor Lyuboslavsky
parent 31fe9d17b9
commit c6e2e8d6c4
No known key found for this signature in database
2 changed files with 77 additions and 68 deletions

View file

@ -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
}

View file

@ -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)
}
})
}