mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-24 16:17:11 +08:00
access_monitoring_rules: Add timezone to schedules spec (#60067)
* Add timezone to AMR schedules * Update documentation with accepted timezone values * Address feedback - Allow empty timezone value - Reference IANA in error message - Add additional timeonze test cases * Fix test case
This commit is contained in:
@@ -394,8 +394,14 @@ func (x *Schedule) GetTime() *TimeSchedule {
|
||||
type TimeSchedule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Shifts contains a set of shifts that make up the schedule.
|
||||
// Shifts are configured in UTC.
|
||||
Shifts []*TimeSchedule_Shift `protobuf:"bytes,1,rep,name=shifts,proto3" json:"shifts,omitempty"`
|
||||
Shifts []*TimeSchedule_Shift `protobuf:"bytes,1,rep,name=shifts,proto3" json:"shifts,omitempty"`
|
||||
// Timezone specifies the schedule timezone. This field is optional and defaults
|
||||
// to "UTC". Accepted values use timezone locations as defined in the IANA
|
||||
// Time Zone Database, such as "America/Los_Angeles", "Europe/Lisbon", or
|
||||
// "Asia/Singapore".
|
||||
//
|
||||
// See https://data.iana.org/time-zones/tzdb/zone1970.tab for a list of supported values.
|
||||
Timezone string `protobuf:"bytes,2,opt,name=timezone,proto3" json:"timezone,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -437,6 +443,13 @@ func (x *TimeSchedule) GetShifts() []*TimeSchedule_Shift {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TimeSchedule) GetTimezone() string {
|
||||
if x != nil {
|
||||
return x.Timezone
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// CreateAccessMonitoringRuleRequest is the request for CreateAccessMonitoringRule.
|
||||
type CreateAccessMonitoringRuleRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@@ -1014,9 +1027,10 @@ const file_teleport_accessmonitoringrules_v1_access_monitoring_rules_proto_rawDe
|
||||
"\vintegration\x18\x01 \x01(\tR\vintegration\x12\x1a\n" +
|
||||
"\bdecision\x18\x02 \x01(\tR\bdecision\"O\n" +
|
||||
"\bSchedule\x12C\n" +
|
||||
"\x04time\x18\x01 \x01(\v2/.teleport.accessmonitoringrules.v1.TimeScheduleR\x04time\"\xa8\x01\n" +
|
||||
"\x04time\x18\x01 \x01(\v2/.teleport.accessmonitoringrules.v1.TimeScheduleR\x04time\"\xc4\x01\n" +
|
||||
"\fTimeSchedule\x12M\n" +
|
||||
"\x06shifts\x18\x01 \x03(\v25.teleport.accessmonitoringrules.v1.TimeSchedule.ShiftR\x06shifts\x1aI\n" +
|
||||
"\x06shifts\x18\x01 \x03(\v25.teleport.accessmonitoringrules.v1.TimeSchedule.ShiftR\x06shifts\x12\x1a\n" +
|
||||
"\btimezone\x18\x02 \x01(\tR\btimezone\x1aI\n" +
|
||||
"\x05Shift\x12\x18\n" +
|
||||
"\aweekday\x18\x01 \x01(\tR\aweekday\x12\x14\n" +
|
||||
"\x05start\x18\x02 \x01(\tR\x05start\x12\x10\n" +
|
||||
|
||||
@@ -100,9 +100,16 @@ message Schedule {
|
||||
// TimeSchedule specifies an in-line schedule.
|
||||
message TimeSchedule {
|
||||
// Shifts contains a set of shifts that make up the schedule.
|
||||
// Shifts are configured in UTC.
|
||||
repeated Shift shifts = 1;
|
||||
|
||||
// Timezone specifies the schedule timezone. This field is optional and defaults
|
||||
// to "UTC". Accepted values use timezone locations as defined in the IANA
|
||||
// Time Zone Database, such as "America/Los_Angeles", "Europe/Lisbon", or
|
||||
// "Asia/Singapore".
|
||||
//
|
||||
// See https://data.iana.org/time-zones/tzdb/zone1970.tab for a list of supported values.
|
||||
string timezone = 2;
|
||||
|
||||
// Shift contains the weekday, start time, and end time of a shift.
|
||||
message Shift {
|
||||
// Weekday specifies the day of the week, e.g., "Sunday", "Monday", "Tuesday".
|
||||
|
||||
+2
-1
@@ -76,7 +76,8 @@ Optional:
|
||||
|
||||
Optional:
|
||||
|
||||
- `shifts` (Attributes List) Shifts contains a set of shifts that make up the schedule. Shifts are configured in UTC. (see [below for nested schema](#nested-schema-for-specschedulestimeshifts))
|
||||
- `shifts` (Attributes List) Shifts contains a set of shifts that make up the schedule. (see [below for nested schema](#nested-schema-for-specschedulestimeshifts))
|
||||
- `timezone` (String) Timezone specifies the schedule timezone. This field is optional and defaults to "UTC". Accepted values use timezone locations as defined in the IANA Time Zone Database, such as "America/Los_Angeles", "Europe/Lisbon", or "Asia/Singapore". See https://data.iana.org/time-zones/tzdb/zone1970.tab for a list of supported values.
|
||||
|
||||
### Nested Schema for `spec.schedules.time.shifts`
|
||||
|
||||
|
||||
+2
-1
@@ -98,7 +98,8 @@ Optional:
|
||||
|
||||
Optional:
|
||||
|
||||
- `shifts` (Attributes List) Shifts contains a set of shifts that make up the schedule. Shifts are configured in UTC. (see [below for nested schema](#nested-schema-for-specschedulestimeshifts))
|
||||
- `shifts` (Attributes List) Shifts contains a set of shifts that make up the schedule. (see [below for nested schema](#nested-schema-for-specschedulestimeshifts))
|
||||
- `timezone` (String) Timezone specifies the schedule timezone. This field is optional and defaults to "UTC". Accepted values use timezone locations as defined in the IANA Time Zone Database, such as "America/Los_Angeles", "Europe/Lisbon", or "Asia/Singapore". See https://data.iana.org/time-zones/tzdb/zone1970.tab for a list of supported values.
|
||||
|
||||
### Nested Schema for `spec.schedules.time.shifts`
|
||||
|
||||
|
||||
+67
-21
@@ -142,27 +142,34 @@ func GenSchemaAccessMonitoringRule(ctx context.Context) (github_com_hashicorp_te
|
||||
},
|
||||
"schedules": {
|
||||
Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.MapNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"time": {
|
||||
Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"shifts": {
|
||||
Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{
|
||||
"end": {
|
||||
Description: "End specifies the end time in the format HH:MM, e.g., \"12:30\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
"start": {
|
||||
Description: "Start specifies the start time in the format HH:MM, e.g., \"12:30\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
"weekday": {
|
||||
Description: "Weekday specifies the day of the week, e.g., \"Sunday\", \"Monday\", \"Tuesday\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
}),
|
||||
Description: "Shifts contains a set of shifts that make up the schedule. Shifts are configured in UTC.",
|
||||
Optional: true,
|
||||
}}),
|
||||
Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{
|
||||
"shifts": {
|
||||
Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{
|
||||
"end": {
|
||||
Description: "End specifies the end time in the format HH:MM, e.g., \"12:30\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
"start": {
|
||||
Description: "Start specifies the start time in the format HH:MM, e.g., \"12:30\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
"weekday": {
|
||||
Description: "Weekday specifies the day of the week, e.g., \"Sunday\", \"Monday\", \"Tuesday\".",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
}),
|
||||
Description: "Shifts contains a set of shifts that make up the schedule.",
|
||||
Optional: true,
|
||||
},
|
||||
"timezone": {
|
||||
Description: "Timezone specifies the schedule timezone. This field is optional and defaults to \"UTC\". Accepted values use timezone locations as defined in the IANA Time Zone Database, such as \"America/Los_Angeles\", \"Europe/Lisbon\", or \"Asia/Singapore\". See https://data.iana.org/time-zones/tzdb/zone1970.tab for a list of supported values.",
|
||||
Optional: true,
|
||||
Type: github_com_hashicorp_terraform_plugin_framework_types.StringType,
|
||||
},
|
||||
}),
|
||||
Description: "TimeSchedule specifies an in-line schedule.",
|
||||
Optional: true,
|
||||
}}),
|
||||
@@ -701,6 +708,23 @@ func CopyAccessMonitoringRuleFromTerraform(_ context.Context, tf github_com_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
a, ok := tf.Attrs["timezone"]
|
||||
if !ok {
|
||||
diags.Append(attrReadMissingDiag{"AccessMonitoringRule.spec.schedules.time.timezone"})
|
||||
} else {
|
||||
v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String)
|
||||
if !ok {
|
||||
diags.Append(attrReadConversionFailureDiag{"AccessMonitoringRule.spec.schedules.time.timezone", "github.com/hashicorp/terraform-plugin-framework/types.String"})
|
||||
} else {
|
||||
var t string
|
||||
if !v.Null && !v.Unknown {
|
||||
t = string(v.Value)
|
||||
}
|
||||
obj.Timezone = t
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1524,6 +1548,28 @@ func CopyAccessMonitoringRuleToTerraform(ctx context.Context, obj *github_com_gr
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
t, ok := tf.AttrTypes["timezone"]
|
||||
if !ok {
|
||||
diags.Append(attrWriteMissingDiag{"AccessMonitoringRule.spec.schedules.time.timezone"})
|
||||
} else {
|
||||
v, ok := tf.Attrs["timezone"].(github_com_hashicorp_terraform_plugin_framework_types.String)
|
||||
if !ok {
|
||||
i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil))
|
||||
if err != nil {
|
||||
diags.Append(attrWriteGeneralError{"AccessMonitoringRule.spec.schedules.time.timezone", err})
|
||||
}
|
||||
v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String)
|
||||
if !ok {
|
||||
diags.Append(attrWriteConversionFailureDiag{"AccessMonitoringRule.spec.schedules.time.timezone", "github.com/hashicorp/terraform-plugin-framework/types.String"})
|
||||
}
|
||||
v.Null = string(obj.Timezone) == ""
|
||||
}
|
||||
v.Value = string(obj.Timezone)
|
||||
v.Unknown = false
|
||||
tf.Attrs["timezone"] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
v.Unknown = false
|
||||
tf.Attrs["time"] = v
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
"time"
|
||||
_ "time/tzdata"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
@@ -156,6 +157,10 @@ func validateSchedules(schedules map[string]*accessmonitoringrulesv1.Schedule) e
|
||||
}
|
||||
|
||||
func validateTimeSchedule(schedule *accessmonitoringrulesv1.TimeSchedule) error {
|
||||
if _, err := time.LoadLocation(schedule.GetTimezone()); err != nil {
|
||||
return trace.Wrap(err, "invalid timezone: refer to the IANA Time Zone Database for valid options")
|
||||
}
|
||||
|
||||
if len(schedule.GetShifts()) == 0 {
|
||||
return trace.BadParameter("at least one shift is required")
|
||||
}
|
||||
|
||||
@@ -249,6 +249,98 @@ func TestValidateSchedules(t *testing.T) {
|
||||
require.ErrorContains(t, err, "at least one shift is require")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "valid timezone (UTC)",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
"default": {
|
||||
Time: &accessmonitoringrulesv1.TimeSchedule{
|
||||
Timezone: "UTC",
|
||||
Shifts: []*accessmonitoringrulesv1.TimeSchedule_Shift{
|
||||
{
|
||||
Weekday: time.Monday.String(),
|
||||
Start: "00:00",
|
||||
End: "23:59",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
assertErr: require.NoError,
|
||||
},
|
||||
{
|
||||
description: "valid timezone (America/Los_Angeles)",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
"default": {
|
||||
Time: &accessmonitoringrulesv1.TimeSchedule{
|
||||
Timezone: "America/Los_Angeles",
|
||||
Shifts: []*accessmonitoringrulesv1.TimeSchedule_Shift{
|
||||
{
|
||||
Weekday: time.Monday.String(),
|
||||
Start: "00:00",
|
||||
End: "23:59",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
assertErr: require.NoError,
|
||||
},
|
||||
{
|
||||
description: "valid timezone (Europe/Lisbon)",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
"default": {
|
||||
Time: &accessmonitoringrulesv1.TimeSchedule{
|
||||
Timezone: "Europe/Lisbon",
|
||||
Shifts: []*accessmonitoringrulesv1.TimeSchedule_Shift{
|
||||
{
|
||||
Weekday: time.Monday.String(),
|
||||
Start: "00:00",
|
||||
End: "23:59",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
assertErr: require.NoError,
|
||||
},
|
||||
{
|
||||
description: "valid timezone (Asia/Singapore)",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
"default": {
|
||||
Time: &accessmonitoringrulesv1.TimeSchedule{
|
||||
Timezone: "Asia/Singapore",
|
||||
Shifts: []*accessmonitoringrulesv1.TimeSchedule_Shift{
|
||||
{
|
||||
Weekday: time.Monday.String(),
|
||||
Start: "00:00",
|
||||
End: "23:59",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
assertErr: require.NoError,
|
||||
},
|
||||
{
|
||||
description: "invalid timezone",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
"default": {
|
||||
Time: &accessmonitoringrulesv1.TimeSchedule{
|
||||
Timezone: "invalid",
|
||||
Shifts: []*accessmonitoringrulesv1.TimeSchedule_Shift{
|
||||
{
|
||||
Weekday: time.Monday.String(),
|
||||
Start: "00:00",
|
||||
End: "23:59",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
assertErr: func(t require.TestingT, err error, _ ...interface{}) {
|
||||
require.ErrorContains(t, err, "invalid timezone")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "start time is not before end time",
|
||||
schedules: map[string]*accessmonitoringrulesv1.Schedule{
|
||||
|
||||
Reference in New Issue
Block a user