Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/types/accesslist/accesslist.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,9 @@ func (a *Audit) UnmarshalJSON(data []byte) error {
return trace.Wrap(err)
}

if audit.NextAuditDate == "" {
return nil
}
var err error
a.NextAuditDate, err = time.Parse(time.RFC3339Nano, audit.NextAuditDate)
if err != nil {
Expand Down
68 changes: 53 additions & 15 deletions api/types/accesslist/accesslist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,27 +182,65 @@ func TestAuditMarshaling(t *testing.T) {
}

func TestAuditUnmarshaling(t *testing.T) {
raw := map[string]interface{}{
"next_audit_date": "2023-02-02T00:00:00Z",
"recurrence": map[string]interface{}{
"frequency": "3 months",
"day_of_month": "1",
tests := []struct {
name string
input map[string]interface{}
expectedNextAudit time.Time
expectedRecurrence Recurrence
expectedNotificationStart time.Duration
}{
{
name: "with next_audit_date",
input: map[string]interface{}{
"next_audit_date": "2023-02-02T00:00:00Z",
"recurrence": map[string]interface{}{
"frequency": "3 months",
"day_of_month": "1",
},
"notifications": map[string]interface{}{
"start": twoWeeks.String(),
},
},
expectedNextAudit: time.Date(2023, 02, 02, 0, 0, 0, 0, time.UTC),
expectedRecurrence: Recurrence{
Frequency: ThreeMonths,
DayOfMonth: FirstDayOfMonth,
},
expectedNotificationStart: twoWeeks,
},
"notifications": map[string]interface{}{
"start": twoWeeks.String(),
{
name: "without next_audit_date",
input: map[string]interface{}{
"recurrence": map[string]interface{}{
"frequency": "3 months",
"day_of_month": "1",
},
"notifications": map[string]interface{}{
"start": twoWeeks.String(),
},
},
expectedNextAudit: time.Time{},
expectedRecurrence: Recurrence{
Frequency: ThreeMonths,
DayOfMonth: FirstDayOfMonth,
},
expectedNotificationStart: twoWeeks,
},
}

data, err := json.Marshal(&raw)
require.NoError(t, err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := json.Marshal(&tt.input)
require.NoError(t, err)

var audit Audit
require.NoError(t, json.Unmarshal(data, &audit))
var audit Audit
require.NoError(t, json.Unmarshal(data, &audit))

require.Equal(t, time.Date(2023, 02, 02, 0, 0, 0, 0, time.UTC), audit.NextAuditDate)
require.Equal(t, ThreeMonths, audit.Recurrence.Frequency)
require.Equal(t, FirstDayOfMonth, audit.Recurrence.DayOfMonth)
require.Equal(t, twoWeeks, audit.Notifications.Start)
require.Equal(t, tt.expectedNextAudit, audit.NextAuditDate)
require.Equal(t, tt.expectedRecurrence, audit.Recurrence)
require.Equal(t, tt.expectedNotificationStart, audit.Notifications.Start)
})
}
}

func TestAccessListDefaults(t *testing.T) {
Expand Down
23 changes: 18 additions & 5 deletions docs/pages/access-controls/access-lists/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,24 @@ spec:
# audit defines how frequently an Access List and its membership must be audited, along
# with the next audit date.
audit:
# Audit frequency defaults to 6 months. Format to golang's time.ParseDuration function:
# https://pkg.go.dev/time#ParseDuration
frequency: 4380h
recurrence:
# Frequency is the frequency between access list reviews.
# Defaults to 6months.
# Possible values are: 1month, 3months, 6months, 1year
frequency: 6months
# DayOfMonth is the day of month subsequent reviews will be scheduled on.
# Defaults to 1.
# Possible values are: 1, 15, last
day_of_month: "1"
# The next time this Access List must be audited by.
next_audit_date: "2024-01-01T00:00:00Z"
# If not set, the next audit date will be picked up automatically.
notifications:
# When the access-request plugins will start to notify before the audit
# deadline. Format to golang's time.ParseDuration function:
# https://pkg.go.dev/time#ParseDuration
# Defaults to two weeks.
start: 336h # two weeks
next_audit_date: "2025-01-01T00:00:00Z"
description: "A description of the Access List and its purpose"
# owners are a list of Teleport users who own the Access List. Provided the owners
# meet the ownership requirements, these users can control membership requirements
Expand Down Expand Up @@ -126,4 +139,4 @@ above) and run `tctl create <filename>`. Access Lists can be updated by using `t
`tctl` also supports a subset of Access List focused commands under the `tctl acl` subcommand.
Through these you can list Access Lists, get information about a particular Access Lists, and manage
Access List users. To see more details, run `tctl acl --help`. More detail can be seen in the
[CLI Reference](../../reference/cli.mdx).
[CLI Reference](../../reference/cli.mdx).
27 changes: 27 additions & 0 deletions tool/tctl/common/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1"
loginrulepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/loginrule/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
"github.com/gravitational/teleport/api/types/discoveryconfig"
"github.com/gravitational/teleport/api/types/externalauditstorage"
"github.com/gravitational/teleport/api/types/secreports"
Expand Down Expand Up @@ -1320,3 +1321,29 @@ func (c *serverInfoCollection) writeText(w io.Writer, verbose bool) error {
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}

type accessListCollection struct {
accessLists []*accesslist.AccessList
}

func (c *accessListCollection) resources() []types.Resource {
r := make([]types.Resource, len(c.accessLists))
for i, resource := range c.accessLists {
r[i] = resource
}
return r
}

func (c *accessListCollection) writeText(w io.Writer, verbose bool) error {
t := asciitable.MakeTable([]string{"Name", "Title", "Review Frequency", "Next Audit Date"})
for _, al := range c.accessLists {
t.AddRow([]string{
al.GetName(),
al.Spec.Title,
al.Spec.Audit.Recurrence.Frequency.String(),
al.Spec.Audit.NextAuditDate.Format(time.RFC822),
})
}
_, err := t.AsBuffer().WriteTo(w)
return trace.Wrap(err)
}
11 changes: 11 additions & 0 deletions tool/tctl/common/resource_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
loginrulepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/loginrule/v1"
"github.com/gravitational/teleport/api/internalutils/stream"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
"github.com/gravitational/teleport/api/types/discoveryconfig"
"github.com/gravitational/teleport/api/types/externalauditstorage"
"github.com/gravitational/teleport/api/types/installers"
Expand Down Expand Up @@ -2270,6 +2271,16 @@ func (rc *ResourceCommand) getCollection(ctx context.Context, client auth.Client
return nil, trace.Wrap(err)
}
return &serverInfoCollection{serverInfos: serverInfos}, nil
case types.KindAccessList:
if rc.ref.Name != "" {
resource, err := client.AccessListClient().GetAccessList(ctx, rc.ref.Name)
if err != nil {
return nil, trace.Wrap(err)
}
return &accessListCollection{accessLists: []*accesslist.AccessList{resource}}, nil
}
accessLists, err := client.AccessListClient().GetAccessLists(ctx)
return &accessListCollection{accessLists: accessLists}, trace.Wrap(err)
}
return nil, trace.BadParameter("getting %q is not supported", rc.ref.String())
}
Expand Down