Add Display to the Access List Member and Owner API Surface #67636 (#67790)

* add UserDisplay message for user display values

* add tests for access list display API and remove unused conversion helper

* simplify comments in access list API and related types

* use status field for ACL member and owner displays

* Clarify UserDisplay documentation to explain message states and user presence

* Remove JSON serialization for OwnerDisplays and Status fields in access list types

* Clarify comments in AccessListMember and Status structs to indicate that certain fields are ignored during marshaling to prevent user confusion.
This commit is contained in:
Lion Chen
2026-06-29 15:42:15 -07:00
committed by GitHub
parent 466e2a1889
commit bba95ff6fc
17 changed files with 1169 additions and 196 deletions
+34 -20
View File
@@ -38,6 +38,22 @@ func NewClient(grpcClient accesslistv1.AccessListServiceClient) *Client {
}
}
func fromAccessListProto(accessList *accesslistv1.AccessList) (*accesslist.AccessList, error) {
return conv.FromProto(
accessList,
conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()),
conv.WithOwnerDisplaysField(accessList.GetStatus()),
)
}
func fromMemberProto(member *accesslistv1.Member) (*accesslist.AccessListMember, error) {
return conv.FromMemberProto(
member,
conv.WithMemberIneligibleStatusField(member),
conv.WithMemberStatusField(member),
)
}
// GetAccessLists returns a list of all access lists.
func (c *Client) GetAccessLists(ctx context.Context) ([]*accesslist.AccessList, error) {
resp, err := c.grpcClient.GetAccessLists(ctx, &accesslistv1.GetAccessListsRequest{})
@@ -48,9 +64,7 @@ func (c *Client) GetAccessLists(ctx context.Context) ([]*accesslist.AccessList,
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
var err error
accessLists[i], err = conv.FromProto(
accessList,
conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()))
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -76,7 +90,7 @@ func (c *Client) ListAccessLists(ctx context.Context, pageSize int, nextToken st
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
var err error
accessLists[i], err = conv.FromProto(accessList, conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()))
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -94,7 +108,7 @@ func (c *Client) ListAccessListsV2(ctx context.Context, req *accesslistv1.ListAc
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
accessLists[i], err = conv.FromProto(accessList, conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()))
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -112,7 +126,7 @@ func (c *Client) GetAccessList(ctx context.Context, name string) (*accesslist.Ac
return nil, trace.Wrap(err)
}
accessList, err := conv.FromProto(resp, conv.WithOwnersIneligibleStatusField(resp.GetSpec().GetOwners()))
accessList, err := fromAccessListProto(resp)
return accessList, trace.Wrap(err)
}
@@ -126,7 +140,7 @@ func (c *Client) GetAccessListsToReview(ctx context.Context) ([]*accesslist.Acce
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
var err error
accessLists[i], err = conv.FromProto(accessList, conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()))
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -156,7 +170,7 @@ func (c *Client) UpsertAccessList(ctx context.Context, accessList *accesslist.Ac
if err != nil {
return nil, trace.Wrap(err)
}
responseAccessList, err := conv.FromProto(resp, conv.WithOwnersIneligibleStatusField(resp.GetSpec().GetOwners()))
responseAccessList, err := fromAccessListProto(resp)
return responseAccessList, trace.Wrap(err)
}
@@ -168,7 +182,7 @@ func (c *Client) UpdateAccessList(ctx context.Context, accessList *accesslist.Ac
if err != nil {
return nil, trace.Wrap(err)
}
responseAccessList, err := conv.FromProto(resp, conv.WithOwnersIneligibleStatusField(resp.GetSpec().GetOwners()))
responseAccessList, err := fromAccessListProto(resp)
return responseAccessList, trace.Wrap(err)
}
@@ -206,7 +220,7 @@ func (c *Client) ListAccessListMembers(ctx context.Context, accessList string, p
members = make([]*accesslist.AccessListMember, len(resp.Members))
for i, member := range resp.Members {
var err error
members[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
members[i], err = fromMemberProto(member)
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -228,7 +242,7 @@ func (c *Client) ListAllAccessListMembers(ctx context.Context, pageSize int, pag
members = make([]*accesslist.AccessListMember, len(resp.Members))
for i, member := range resp.Members {
var err error
members[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
members[i], err = fromMemberProto(member)
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -247,7 +261,7 @@ func (c *Client) GetAccessListMember(ctx context.Context, accessList, memberName
return nil, trace.Wrap(err)
}
member, err := conv.FromMemberProto(resp, conv.WithMemberIneligibleStatusField(resp))
member, err := fromMemberProto(resp)
return member, trace.Wrap(err)
}
@@ -262,7 +276,7 @@ func (c *Client) GetStaticAccessListMember(ctx context.Context, accessList, memb
return nil, trace.Wrap(err)
}
member, err := conv.FromMemberProto(resp.Member, conv.WithMemberIneligibleStatusField(resp.Member))
member, err := fromMemberProto(resp.Member)
return member, trace.Wrap(err)
}
@@ -294,7 +308,7 @@ func (c *Client) UpsertAccessListMember(ctx context.Context, member *accesslist.
if err != nil {
return nil, trace.Wrap(err)
}
responseMember, err := conv.FromMemberProto(resp, conv.WithMemberIneligibleStatusField(resp))
responseMember, err := fromMemberProto(resp)
return responseMember, trace.Wrap(err)
}
@@ -307,7 +321,7 @@ func (c *Client) UpsertStaticAccessListMember(ctx context.Context, member *acces
if err != nil {
return nil, trace.Wrap(err)
}
m, err := conv.FromMemberProto(resp.Member, conv.WithMemberIneligibleStatusField(resp.Member))
m, err := fromMemberProto(resp.Member)
return m, trace.Wrap(err)
}
@@ -319,7 +333,7 @@ func (c *Client) UpdateAccessListMember(ctx context.Context, member *accesslist.
if err != nil {
return nil, trace.Wrap(err)
}
responseMember, err := conv.FromMemberProto(resp, conv.WithMemberIneligibleStatusField(resp))
responseMember, err := fromMemberProto(resp)
return responseMember, trace.Wrap(err)
}
@@ -360,7 +374,7 @@ func (c *Client) UpsertAccessListWithMembers(ctx context.Context, list *accessli
return nil, nil, trace.Wrap(err)
}
accessList, err := conv.FromProto(resp.AccessList, conv.WithOwnersIneligibleStatusField(resp.AccessList.GetSpec().GetOwners()))
accessList, err := fromAccessListProto(resp.AccessList)
if err != nil {
return nil, nil, trace.Wrap(err)
}
@@ -368,7 +382,7 @@ func (c *Client) UpsertAccessListWithMembers(ctx context.Context, list *accessli
updatedMembers := make([]*accesslist.AccessListMember, len(resp.Members))
for i, member := range resp.Members {
var err error
updatedMembers[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
updatedMembers[i], err = fromMemberProto(member)
if err != nil {
return nil, nil, trace.Wrap(err)
}
@@ -464,7 +478,7 @@ func (c *Client) GetSuggestedAccessLists(ctx context.Context, accessRequestID st
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
var err error
accessLists[i], err = conv.FromProto(accessList)
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -483,7 +497,7 @@ func (c *Client) ListUserAccessLists(ctx context.Context, req *accesslistv1.List
accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
for i, accessList := range resp.AccessLists {
accessLists[i], err = conv.FromProto(accessList, conv.WithOwnersIneligibleStatusField(accessList.GetSpec().GetOwners()))
accessLists[i], err = fromAccessListProto(accessList)
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -1354,6 +1354,84 @@ func (b0 ScopedRoleGrant_builder) Build() *ScopedRoleGrant {
return m0
}
// UserDisplay contains display values derived from a user. An empty message
// means the user has no primary/secondary distinct from the username; the
// absence of this message means the user was not found.
type UserDisplay struct {
state protoimpl.MessageState `protogen:"hybrid.v1"`
// primary is a human-readable display name when distinct from username.
Primary string `protobuf:"bytes,1,opt,name=primary,proto3" json:"primary,omitempty"`
// secondary is supporting display context when distinct from username.
Secondary string `protobuf:"bytes,2,opt,name=secondary,proto3" json:"secondary,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UserDisplay) Reset() {
*x = UserDisplay{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UserDisplay) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserDisplay) ProtoMessage() {}
func (x *UserDisplay) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
func (x *UserDisplay) GetPrimary() string {
if x != nil {
return x.Primary
}
return ""
}
func (x *UserDisplay) GetSecondary() string {
if x != nil {
return x.Secondary
}
return ""
}
func (x *UserDisplay) SetPrimary(v string) {
x.Primary = v
}
func (x *UserDisplay) SetSecondary(v string) {
x.Secondary = v
}
type UserDisplay_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
// primary is a human-readable display name when distinct from username.
Primary string
// secondary is supporting display context when distinct from username.
Secondary string
}
func (b0 UserDisplay_builder) Build() *UserDisplay {
m0 := &UserDisplay{}
b, x := &b0, m0
_, _ = b, x
x.Primary = b.Primary
x.Secondary = b.Secondary
return m0
}
// Member describes a member of an Access List.
type Member struct {
state protoimpl.MessageState `protogen:"hybrid.v1"`
@@ -1363,14 +1441,16 @@ type Member struct {
Spec *MemberSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"`
// scope is the scope of the Access List member, it must be equal to the
// scope of the parent Access List.
Scope string `protobuf:"bytes,3,opt,name=scope,proto3" json:"scope,omitempty"`
Scope string `protobuf:"bytes,3,opt,name=scope,proto3" json:"scope,omitempty"`
// status contains dynamically calculated fields.
Status *MemberStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Member) Reset() {
*x = Member{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1382,7 +1462,7 @@ func (x *Member) String() string {
func (*Member) ProtoMessage() {}
func (x *Member) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1414,6 +1494,13 @@ func (x *Member) GetScope() string {
return ""
}
func (x *Member) GetStatus() *MemberStatus {
if x != nil {
return x.Status
}
return nil
}
func (x *Member) SetHeader(v *v1.ResourceHeader) {
x.Header = v
}
@@ -1426,6 +1513,10 @@ func (x *Member) SetScope(v string) {
x.Scope = v
}
func (x *Member) SetStatus(v *MemberStatus) {
x.Status = v
}
func (x *Member) HasHeader() bool {
if x == nil {
return false
@@ -1440,6 +1531,13 @@ func (x *Member) HasSpec() bool {
return x.Spec != nil
}
func (x *Member) HasStatus() bool {
if x == nil {
return false
}
return x.Status != nil
}
func (x *Member) ClearHeader() {
x.Header = nil
}
@@ -1448,6 +1546,10 @@ func (x *Member) ClearSpec() {
x.Spec = nil
}
func (x *Member) ClearStatus() {
x.Status = nil
}
type Member_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
@@ -1458,6 +1560,8 @@ type Member_builder struct {
// scope is the scope of the Access List member, it must be equal to the
// scope of the parent Access List.
Scope string
// status contains dynamically calculated fields.
Status *MemberStatus
}
func (b0 Member_builder) Build() *Member {
@@ -1467,6 +1571,105 @@ func (b0 Member_builder) Build() *Member {
x.Header = b.Header
x.Spec = b.Spec
x.Scope = b.Scope
x.Status = b.Status
return m0
}
// MemberStatus contains dynamic fields calculated during retrieval.
type MemberStatus struct {
state protoimpl.MessageState `protogen:"hybrid.v1"`
// display contains display values for the member user.
Display *UserDisplay `protobuf:"bytes,1,opt,name=display,proto3" json:"display,omitempty"`
// added_by_display contains display values for the user that added the member.
AddedByDisplay *UserDisplay `protobuf:"bytes,2,opt,name=added_by_display,json=addedByDisplay,proto3" json:"added_by_display,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *MemberStatus) Reset() {
*x = MemberStatus{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MemberStatus) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MemberStatus) ProtoMessage() {}
func (x *MemberStatus) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
func (x *MemberStatus) GetDisplay() *UserDisplay {
if x != nil {
return x.Display
}
return nil
}
func (x *MemberStatus) GetAddedByDisplay() *UserDisplay {
if x != nil {
return x.AddedByDisplay
}
return nil
}
func (x *MemberStatus) SetDisplay(v *UserDisplay) {
x.Display = v
}
func (x *MemberStatus) SetAddedByDisplay(v *UserDisplay) {
x.AddedByDisplay = v
}
func (x *MemberStatus) HasDisplay() bool {
if x == nil {
return false
}
return x.Display != nil
}
func (x *MemberStatus) HasAddedByDisplay() bool {
if x == nil {
return false
}
return x.AddedByDisplay != nil
}
func (x *MemberStatus) ClearDisplay() {
x.Display = nil
}
func (x *MemberStatus) ClearAddedByDisplay() {
x.AddedByDisplay = nil
}
type MemberStatus_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
// display contains display values for the member user.
Display *UserDisplay
// added_by_display contains display values for the user that added the member.
AddedByDisplay *UserDisplay
}
func (b0 MemberStatus_builder) Build() *MemberStatus {
m0 := &MemberStatus{}
b, x := &b0, m0
_, _ = b, x
x.Display = b.Display
x.AddedByDisplay = b.AddedByDisplay
return m0
}
@@ -1500,7 +1703,7 @@ type MemberSpec struct {
func (x *MemberSpec) Reset() {
*x = MemberSpec{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1512,7 +1715,7 @@ func (x *MemberSpec) String() string {
func (*MemberSpec) ProtoMessage() {}
func (x *MemberSpec) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1690,7 +1893,7 @@ type Review struct {
func (x *Review) Reset() {
*x = Review{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1702,7 +1905,7 @@ func (x *Review) String() string {
func (*Review) ProtoMessage() {}
func (x *Review) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1812,7 +2015,7 @@ type ReviewSpec struct {
func (x *ReviewSpec) Reset() {
*x = ReviewSpec{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1824,7 +2027,7 @@ func (x *ReviewSpec) String() string {
func (*ReviewSpec) ProtoMessage() {}
func (x *ReviewSpec) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1965,7 +2168,7 @@ type ReviewChanges struct {
func (x *ReviewChanges) Reset() {
*x = ReviewChanges{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1977,7 +2180,7 @@ func (x *ReviewChanges) String() string {
func (*ReviewChanges) ProtoMessage() {}
func (x *ReviewChanges) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2098,7 +2301,7 @@ type CurrentUserAssignments struct {
func (x *CurrentUserAssignments) Reset() {
*x = CurrentUserAssignments{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2110,7 +2313,7 @@ func (x *CurrentUserAssignments) String() string {
func (*CurrentUserAssignments) ProtoMessage() {}
func (x *CurrentUserAssignments) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2174,7 +2377,7 @@ type UserAssignments struct {
func (x *UserAssignments) Reset() {
*x = UserAssignments{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2186,7 +2389,7 @@ func (x *UserAssignments) String() string {
func (*UserAssignments) ProtoMessage() {}
func (x *UserAssignments) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2258,13 +2461,15 @@ type AccessListStatus struct {
// scoped_member_of describes scoped Access Lists where this Access List is an explicit member.
// Each item is the scope-qualified name of the parent scoped Access List.
ScopedMemberOf []string `protobuf:"bytes,8,rep,name=scoped_member_of,json=scopedMemberOf,proto3" json:"scoped_member_of,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
// owner_displays contains display values for owners, keyed by owner username.
OwnerDisplays map[string]*UserDisplay `protobuf:"bytes,9,rep,name=owner_displays,json=ownerDisplays,proto3" json:"owner_displays,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AccessListStatus) Reset() {
*x = AccessListStatus{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2276,7 +2481,7 @@ func (x *AccessListStatus) String() string {
func (*AccessListStatus) ProtoMessage() {}
func (x *AccessListStatus) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2343,6 +2548,13 @@ func (x *AccessListStatus) GetScopedMemberOf() []string {
return nil
}
func (x *AccessListStatus) GetOwnerDisplays() map[string]*UserDisplay {
if x != nil {
return x.OwnerDisplays
}
return nil
}
func (x *AccessListStatus) SetMemberCount(v uint32) {
x.MemberCount = &v
}
@@ -2375,6 +2587,10 @@ func (x *AccessListStatus) SetScopedMemberOf(v []string) {
x.ScopedMemberOf = v
}
func (x *AccessListStatus) SetOwnerDisplays(v map[string]*UserDisplay) {
x.OwnerDisplays = v
}
func (x *AccessListStatus) HasMemberCount() bool {
if x == nil {
return false
@@ -2440,6 +2656,8 @@ type AccessListStatus_builder struct {
// scoped_member_of describes scoped Access Lists where this Access List is an explicit member.
// Each item is the scope-qualified name of the parent scoped Access List.
ScopedMemberOf []string
// owner_displays contains display values for owners, keyed by owner username.
OwnerDisplays map[string]*UserDisplay
}
func (b0 AccessListStatus_builder) Build() *AccessListStatus {
@@ -2454,6 +2672,7 @@ func (b0 AccessListStatus_builder) Build() *AccessListStatus {
x.UserAssignments = b.UserAssignments
x.ScopedOwnerOf = b.ScopedOwnerOf
x.ScopedMemberOf = b.ScopedMemberOf
x.OwnerDisplays = b.OwnerDisplays
return m0
}
@@ -2508,11 +2727,18 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\fscoped_roles\x18\x03 \x03(\v2'.teleport.accesslist.v1.ScopedRoleGrantR\vscopedRoles\";\n" +
"\x0fScopedRoleGrant\x12\x12\n" +
"\x04role\x18\x01 \x01(\tR\x04role\x12\x14\n" +
"\x05scope\x18\x02 \x01(\tR\x05scope\"\x92\x01\n" +
"\x05scope\x18\x02 \x01(\tR\x05scope\"E\n" +
"\vUserDisplay\x12\x18\n" +
"\aprimary\x18\x01 \x01(\tR\aprimary\x12\x1c\n" +
"\tsecondary\x18\x02 \x01(\tR\tsecondary\"\xd0\x01\n" +
"\x06Member\x12:\n" +
"\x06header\x18\x01 \x01(\v2\".teleport.header.v1.ResourceHeaderR\x06header\x126\n" +
"\x04spec\x18\x02 \x01(\v2\".teleport.accesslist.v1.MemberSpecR\x04spec\x12\x14\n" +
"\x05scope\x18\x03 \x01(\tR\x05scope\"\x98\x03\n" +
"\x05scope\x18\x03 \x01(\tR\x05scope\x12<\n" +
"\x06status\x18\x04 \x01(\v2$.teleport.accesslist.v1.MemberStatusR\x06status\"\x9c\x01\n" +
"\fMemberStatus\x12=\n" +
"\adisplay\x18\x01 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\adisplay\x12M\n" +
"\x10added_by_display\x18\x02 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\x0eaddedByDisplay\"\x98\x03\n" +
"\n" +
"MemberSpec\x12\x1f\n" +
"\vaccess_list\x18\x01 \x01(\tR\n" +
@@ -2549,7 +2775,7 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xcd\x01\n" +
"\x0fUserAssignments\x12[\n" +
"\x0eownership_type\x18\x01 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\rownershipType\x12]\n" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xda\x03\n" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xa5\x05\n" +
"\x10AccessListStatus\x12&\n" +
"\fmember_count\x18\x01 \x01(\rH\x00R\vmemberCount\x88\x01\x01\x12/\n" +
"\x11member_list_count\x18\x02 \x01(\rH\x01R\x0fmemberListCount\x88\x01\x01\x12\x19\n" +
@@ -2558,7 +2784,11 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\x18current_user_assignments\x18\x05 \x01(\v2..teleport.accesslist.v1.CurrentUserAssignmentsR\x16currentUserAssignments\x12R\n" +
"\x10user_assignments\x18\x06 \x01(\v2'.teleport.accesslist.v1.UserAssignmentsR\x0fuserAssignments\x12&\n" +
"\x0fscoped_owner_of\x18\a \x03(\tR\rscopedOwnerOf\x12(\n" +
"\x10scoped_member_of\x18\b \x03(\tR\x0escopedMemberOfB\x0f\n" +
"\x10scoped_member_of\x18\b \x03(\tR\x0escopedMemberOf\x12b\n" +
"\x0eowner_displays\x18\t \x03(\v2;.teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntryR\rownerDisplays\x1ae\n" +
"\x12OwnerDisplaysEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x129\n" +
"\x05value\x18\x02 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\x05value:\x028\x01B\x0f\n" +
"\r_member_countB\x14\n" +
"\x12_member_list_count*\xb6\x01\n" +
"\x0fReviewFrequency\x12 \n" +
@@ -2589,7 +2819,7 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"*ACCESS_LIST_USER_ASSIGNMENT_TYPE_INHERITED\x10\x02BXZVgithub.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1;accesslistv1b\x06proto3"
var file_teleport_accesslist_v1_accesslist_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_teleport_accesslist_v1_accesslist_proto_goTypes = []any{
(ReviewFrequency)(0), // 0: teleport.accesslist.v1.ReviewFrequency
(ReviewDayOfMonth)(0), // 1: teleport.accesslist.v1.ReviewDayOfMonth
@@ -2605,23 +2835,26 @@ var file_teleport_accesslist_v1_accesslist_proto_goTypes = []any{
(*AccessListRequires)(nil), // 11: teleport.accesslist.v1.AccessListRequires
(*AccessListGrants)(nil), // 12: teleport.accesslist.v1.AccessListGrants
(*ScopedRoleGrant)(nil), // 13: teleport.accesslist.v1.ScopedRoleGrant
(*Member)(nil), // 14: teleport.accesslist.v1.Member
(*MemberSpec)(nil), // 15: teleport.accesslist.v1.MemberSpec
(*Review)(nil), // 16: teleport.accesslist.v1.Review
(*ReviewSpec)(nil), // 17: teleport.accesslist.v1.ReviewSpec
(*ReviewChanges)(nil), // 18: teleport.accesslist.v1.ReviewChanges
(*CurrentUserAssignments)(nil), // 19: teleport.accesslist.v1.CurrentUserAssignments
(*UserAssignments)(nil), // 20: teleport.accesslist.v1.UserAssignments
(*AccessListStatus)(nil), // 21: teleport.accesslist.v1.AccessListStatus
(*v1.ResourceHeader)(nil), // 22: teleport.header.v1.ResourceHeader
(*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 24: google.protobuf.Duration
(*v11.Trait)(nil), // 25: teleport.trait.v1.Trait
(*UserDisplay)(nil), // 14: teleport.accesslist.v1.UserDisplay
(*Member)(nil), // 15: teleport.accesslist.v1.Member
(*MemberStatus)(nil), // 16: teleport.accesslist.v1.MemberStatus
(*MemberSpec)(nil), // 17: teleport.accesslist.v1.MemberSpec
(*Review)(nil), // 18: teleport.accesslist.v1.Review
(*ReviewSpec)(nil), // 19: teleport.accesslist.v1.ReviewSpec
(*ReviewChanges)(nil), // 20: teleport.accesslist.v1.ReviewChanges
(*CurrentUserAssignments)(nil), // 21: teleport.accesslist.v1.CurrentUserAssignments
(*UserAssignments)(nil), // 22: teleport.accesslist.v1.UserAssignments
(*AccessListStatus)(nil), // 23: teleport.accesslist.v1.AccessListStatus
nil, // 24: teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry
(*v1.ResourceHeader)(nil), // 25: teleport.header.v1.ResourceHeader
(*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 27: google.protobuf.Duration
(*v11.Trait)(nil), // 28: teleport.trait.v1.Trait
}
var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{
22, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader
25, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader
6, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec
21, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus
23, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus
7, // 3: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner
8, // 4: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit
11, // 5: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires
@@ -2630,39 +2863,44 @@ var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{
12, // 8: teleport.accesslist.v1.AccessListSpec.owner_grants:type_name -> teleport.accesslist.v1.AccessListGrants
3, // 9: teleport.accesslist.v1.AccessListOwner.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 10: teleport.accesslist.v1.AccessListOwner.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
23, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp
26, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp
9, // 12: teleport.accesslist.v1.AccessListAudit.recurrence:type_name -> teleport.accesslist.v1.Recurrence
10, // 13: teleport.accesslist.v1.AccessListAudit.notifications:type_name -> teleport.accesslist.v1.Notifications
0, // 14: teleport.accesslist.v1.Recurrence.frequency:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 15: teleport.accesslist.v1.Recurrence.day_of_month:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
24, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration
25, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait
25, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait
27, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration
28, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait
28, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait
13, // 19: teleport.accesslist.v1.AccessListGrants.scoped_roles:type_name -> teleport.accesslist.v1.ScopedRoleGrant
22, // 20: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader
15, // 21: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec
23, // 22: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp
23, // 23: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp
3, // 24: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 25: teleport.accesslist.v1.MemberSpec.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
22, // 26: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader
17, // 27: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec
23, // 28: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp
18, // 29: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges
11, // 30: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires
0, // 31: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 32: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
4, // 33: teleport.accesslist.v1.CurrentUserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 34: teleport.accesslist.v1.CurrentUserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 35: teleport.accesslist.v1.UserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 36: teleport.accesslist.v1.UserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
19, // 37: teleport.accesslist.v1.AccessListStatus.current_user_assignments:type_name -> teleport.accesslist.v1.CurrentUserAssignments
20, // 38: teleport.accesslist.v1.AccessListStatus.user_assignments:type_name -> teleport.accesslist.v1.UserAssignments
39, // [39:39] is the sub-list for method output_type
39, // [39:39] is the sub-list for method input_type
39, // [39:39] is the sub-list for extension type_name
39, // [39:39] is the sub-list for extension extendee
0, // [0:39] is the sub-list for field type_name
25, // 20: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader
17, // 21: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec
16, // 22: teleport.accesslist.v1.Member.status:type_name -> teleport.accesslist.v1.MemberStatus
14, // 23: teleport.accesslist.v1.MemberStatus.display:type_name -> teleport.accesslist.v1.UserDisplay
14, // 24: teleport.accesslist.v1.MemberStatus.added_by_display:type_name -> teleport.accesslist.v1.UserDisplay
26, // 25: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp
26, // 26: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp
3, // 27: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 28: teleport.accesslist.v1.MemberSpec.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
25, // 29: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader
19, // 30: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec
26, // 31: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp
20, // 32: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges
11, // 33: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires
0, // 34: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 35: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
4, // 36: teleport.accesslist.v1.CurrentUserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 37: teleport.accesslist.v1.CurrentUserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 38: teleport.accesslist.v1.UserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 39: teleport.accesslist.v1.UserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
21, // 40: teleport.accesslist.v1.AccessListStatus.current_user_assignments:type_name -> teleport.accesslist.v1.CurrentUserAssignments
22, // 41: teleport.accesslist.v1.AccessListStatus.user_assignments:type_name -> teleport.accesslist.v1.UserAssignments
24, // 42: teleport.accesslist.v1.AccessListStatus.owner_displays:type_name -> teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry
14, // 43: teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry.value:type_name -> teleport.accesslist.v1.UserDisplay
44, // [44:44] is the sub-list for method output_type
44, // [44:44] is the sub-list for method input_type
44, // [44:44] is the sub-list for extension type_name
44, // [44:44] is the sub-list for extension extendee
0, // [0:44] is the sub-list for field type_name
}
func init() { file_teleport_accesslist_v1_accesslist_proto_init() }
@@ -2670,14 +2908,14 @@ func file_teleport_accesslist_v1_accesslist_proto_init() {
if File_teleport_accesslist_v1_accesslist_proto != nil {
return
}
file_teleport_accesslist_v1_accesslist_proto_msgTypes[16].OneofWrappers = []any{}
file_teleport_accesslist_v1_accesslist_proto_msgTypes[18].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_accesslist_v1_accesslist_proto_rawDesc), len(file_teleport_accesslist_v1_accesslist_proto_rawDesc)),
NumEnums: 5,
NumMessages: 17,
NumMessages: 20,
NumExtensions: 0,
NumServices: 0,
},
@@ -1312,19 +1312,96 @@ func (b0 ScopedRoleGrant_builder) Build() *ScopedRoleGrant {
return m0
}
// UserDisplay contains display values derived from a user. An empty message
// means the user has no primary/secondary distinct from the username; the
// absence of this message means the user was not found.
type UserDisplay struct {
state protoimpl.MessageState `protogen:"opaque.v1"`
xxx_hidden_Primary string `protobuf:"bytes,1,opt,name=primary,proto3"`
xxx_hidden_Secondary string `protobuf:"bytes,2,opt,name=secondary,proto3"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UserDisplay) Reset() {
*x = UserDisplay{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UserDisplay) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserDisplay) ProtoMessage() {}
func (x *UserDisplay) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
func (x *UserDisplay) GetPrimary() string {
if x != nil {
return x.xxx_hidden_Primary
}
return ""
}
func (x *UserDisplay) GetSecondary() string {
if x != nil {
return x.xxx_hidden_Secondary
}
return ""
}
func (x *UserDisplay) SetPrimary(v string) {
x.xxx_hidden_Primary = v
}
func (x *UserDisplay) SetSecondary(v string) {
x.xxx_hidden_Secondary = v
}
type UserDisplay_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
// primary is a human-readable display name when distinct from username.
Primary string
// secondary is supporting display context when distinct from username.
Secondary string
}
func (b0 UserDisplay_builder) Build() *UserDisplay {
m0 := &UserDisplay{}
b, x := &b0, m0
_, _ = b, x
x.xxx_hidden_Primary = b.Primary
x.xxx_hidden_Secondary = b.Secondary
return m0
}
// Member describes a member of an Access List.
type Member struct {
state protoimpl.MessageState `protogen:"opaque.v1"`
xxx_hidden_Header *v1.ResourceHeader `protobuf:"bytes,1,opt,name=header,proto3"`
xxx_hidden_Spec *MemberSpec `protobuf:"bytes,2,opt,name=spec,proto3"`
xxx_hidden_Scope string `protobuf:"bytes,3,opt,name=scope,proto3"`
xxx_hidden_Status *MemberStatus `protobuf:"bytes,4,opt,name=status,proto3"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Member) Reset() {
*x = Member{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1336,7 +1413,7 @@ func (x *Member) String() string {
func (*Member) ProtoMessage() {}
func (x *Member) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1368,6 +1445,13 @@ func (x *Member) GetScope() string {
return ""
}
func (x *Member) GetStatus() *MemberStatus {
if x != nil {
return x.xxx_hidden_Status
}
return nil
}
func (x *Member) SetHeader(v *v1.ResourceHeader) {
x.xxx_hidden_Header = v
}
@@ -1380,6 +1464,10 @@ func (x *Member) SetScope(v string) {
x.xxx_hidden_Scope = v
}
func (x *Member) SetStatus(v *MemberStatus) {
x.xxx_hidden_Status = v
}
func (x *Member) HasHeader() bool {
if x == nil {
return false
@@ -1394,6 +1482,13 @@ func (x *Member) HasSpec() bool {
return x.xxx_hidden_Spec != nil
}
func (x *Member) HasStatus() bool {
if x == nil {
return false
}
return x.xxx_hidden_Status != nil
}
func (x *Member) ClearHeader() {
x.xxx_hidden_Header = nil
}
@@ -1402,6 +1497,10 @@ func (x *Member) ClearSpec() {
x.xxx_hidden_Spec = nil
}
func (x *Member) ClearStatus() {
x.xxx_hidden_Status = nil
}
type Member_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
@@ -1412,6 +1511,8 @@ type Member_builder struct {
// scope is the scope of the Access List member, it must be equal to the
// scope of the parent Access List.
Scope string
// status contains dynamically calculated fields.
Status *MemberStatus
}
func (b0 Member_builder) Build() *Member {
@@ -1421,6 +1522,103 @@ func (b0 Member_builder) Build() *Member {
x.xxx_hidden_Header = b.Header
x.xxx_hidden_Spec = b.Spec
x.xxx_hidden_Scope = b.Scope
x.xxx_hidden_Status = b.Status
return m0
}
// MemberStatus contains dynamic fields calculated during retrieval.
type MemberStatus struct {
state protoimpl.MessageState `protogen:"opaque.v1"`
xxx_hidden_Display *UserDisplay `protobuf:"bytes,1,opt,name=display,proto3"`
xxx_hidden_AddedByDisplay *UserDisplay `protobuf:"bytes,2,opt,name=added_by_display,json=addedByDisplay,proto3"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *MemberStatus) Reset() {
*x = MemberStatus{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MemberStatus) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MemberStatus) ProtoMessage() {}
func (x *MemberStatus) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
func (x *MemberStatus) GetDisplay() *UserDisplay {
if x != nil {
return x.xxx_hidden_Display
}
return nil
}
func (x *MemberStatus) GetAddedByDisplay() *UserDisplay {
if x != nil {
return x.xxx_hidden_AddedByDisplay
}
return nil
}
func (x *MemberStatus) SetDisplay(v *UserDisplay) {
x.xxx_hidden_Display = v
}
func (x *MemberStatus) SetAddedByDisplay(v *UserDisplay) {
x.xxx_hidden_AddedByDisplay = v
}
func (x *MemberStatus) HasDisplay() bool {
if x == nil {
return false
}
return x.xxx_hidden_Display != nil
}
func (x *MemberStatus) HasAddedByDisplay() bool {
if x == nil {
return false
}
return x.xxx_hidden_AddedByDisplay != nil
}
func (x *MemberStatus) ClearDisplay() {
x.xxx_hidden_Display = nil
}
func (x *MemberStatus) ClearAddedByDisplay() {
x.xxx_hidden_AddedByDisplay = nil
}
type MemberStatus_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
// display contains display values for the member user.
Display *UserDisplay
// added_by_display contains display values for the user that added the member.
AddedByDisplay *UserDisplay
}
func (b0 MemberStatus_builder) Build() *MemberStatus {
m0 := &MemberStatus{}
b, x := &b0, m0
_, _ = b, x
x.xxx_hidden_Display = b.Display
x.xxx_hidden_AddedByDisplay = b.AddedByDisplay
return m0
}
@@ -1441,7 +1639,7 @@ type MemberSpec struct {
func (x *MemberSpec) Reset() {
*x = MemberSpec{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1453,7 +1651,7 @@ func (x *MemberSpec) String() string {
func (*MemberSpec) ProtoMessage() {}
func (x *MemberSpec) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1627,7 +1825,7 @@ type Review struct {
func (x *Review) Reset() {
*x = Review{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1639,7 +1837,7 @@ func (x *Review) String() string {
func (*Review) ProtoMessage() {}
func (x *Review) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1741,7 +1939,7 @@ type ReviewSpec struct {
func (x *ReviewSpec) Reset() {
*x = ReviewSpec{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1753,7 +1951,7 @@ func (x *ReviewSpec) String() string {
func (*ReviewSpec) ProtoMessage() {}
func (x *ReviewSpec) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1885,7 +2083,7 @@ type ReviewChanges struct {
func (x *ReviewChanges) Reset() {
*x = ReviewChanges{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1897,7 +2095,7 @@ func (x *ReviewChanges) String() string {
func (*ReviewChanges) ProtoMessage() {}
func (x *ReviewChanges) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2016,7 +2214,7 @@ type CurrentUserAssignments struct {
func (x *CurrentUserAssignments) Reset() {
*x = CurrentUserAssignments{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2028,7 +2226,7 @@ func (x *CurrentUserAssignments) String() string {
func (*CurrentUserAssignments) ProtoMessage() {}
func (x *CurrentUserAssignments) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[14]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2090,7 +2288,7 @@ type UserAssignments struct {
func (x *UserAssignments) Reset() {
*x = UserAssignments{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2102,7 +2300,7 @@ func (x *UserAssignments) String() string {
func (*UserAssignments) ProtoMessage() {}
func (x *UserAssignments) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[15]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2164,6 +2362,7 @@ type AccessListStatus struct {
xxx_hidden_UserAssignments *UserAssignments `protobuf:"bytes,6,opt,name=user_assignments,json=userAssignments,proto3"`
xxx_hidden_ScopedOwnerOf []string `protobuf:"bytes,7,rep,name=scoped_owner_of,json=scopedOwnerOf,proto3"`
xxx_hidden_ScopedMemberOf []string `protobuf:"bytes,8,rep,name=scoped_member_of,json=scopedMemberOf,proto3"`
xxx_hidden_OwnerDisplays map[string]*UserDisplay `protobuf:"bytes,9,rep,name=owner_displays,json=ownerDisplays,proto3" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
XXX_raceDetectHookData protoimpl.RaceDetectHookData
XXX_presence [1]uint32
unknownFields protoimpl.UnknownFields
@@ -2172,7 +2371,7 @@ type AccessListStatus struct {
func (x *AccessListStatus) Reset() {
*x = AccessListStatus{}
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2184,7 +2383,7 @@ func (x *AccessListStatus) String() string {
func (*AccessListStatus) ProtoMessage() {}
func (x *AccessListStatus) ProtoReflect() protoreflect.Message {
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[16]
mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2251,14 +2450,21 @@ func (x *AccessListStatus) GetScopedMemberOf() []string {
return nil
}
func (x *AccessListStatus) GetOwnerDisplays() map[string]*UserDisplay {
if x != nil {
return x.xxx_hidden_OwnerDisplays
}
return nil
}
func (x *AccessListStatus) SetMemberCount(v uint32) {
x.xxx_hidden_MemberCount = v
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 8)
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 9)
}
func (x *AccessListStatus) SetMemberListCount(v uint32) {
x.xxx_hidden_MemberListCount = v
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 8)
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 9)
}
func (x *AccessListStatus) SetOwnerOf(v []string) {
@@ -2285,6 +2491,10 @@ func (x *AccessListStatus) SetScopedMemberOf(v []string) {
x.xxx_hidden_ScopedMemberOf = v
}
func (x *AccessListStatus) SetOwnerDisplays(v map[string]*UserDisplay) {
x.xxx_hidden_OwnerDisplays = v
}
func (x *AccessListStatus) HasMemberCount() bool {
if x == nil {
return false
@@ -2352,6 +2562,8 @@ type AccessListStatus_builder struct {
// scoped_member_of describes scoped Access Lists where this Access List is an explicit member.
// Each item is the scope-qualified name of the parent scoped Access List.
ScopedMemberOf []string
// owner_displays contains display values for owners, keyed by owner username.
OwnerDisplays map[string]*UserDisplay
}
func (b0 AccessListStatus_builder) Build() *AccessListStatus {
@@ -2359,11 +2571,11 @@ func (b0 AccessListStatus_builder) Build() *AccessListStatus {
b, x := &b0, m0
_, _ = b, x
if b.MemberCount != nil {
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 8)
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 9)
x.xxx_hidden_MemberCount = *b.MemberCount
}
if b.MemberListCount != nil {
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 8)
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 9)
x.xxx_hidden_MemberListCount = *b.MemberListCount
}
x.xxx_hidden_OwnerOf = b.OwnerOf
@@ -2372,6 +2584,7 @@ func (b0 AccessListStatus_builder) Build() *AccessListStatus {
x.xxx_hidden_UserAssignments = b.UserAssignments
x.xxx_hidden_ScopedOwnerOf = b.ScopedOwnerOf
x.xxx_hidden_ScopedMemberOf = b.ScopedMemberOf
x.xxx_hidden_OwnerDisplays = b.OwnerDisplays
return m0
}
@@ -2426,11 +2639,18 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\fscoped_roles\x18\x03 \x03(\v2'.teleport.accesslist.v1.ScopedRoleGrantR\vscopedRoles\";\n" +
"\x0fScopedRoleGrant\x12\x12\n" +
"\x04role\x18\x01 \x01(\tR\x04role\x12\x14\n" +
"\x05scope\x18\x02 \x01(\tR\x05scope\"\x92\x01\n" +
"\x05scope\x18\x02 \x01(\tR\x05scope\"E\n" +
"\vUserDisplay\x12\x18\n" +
"\aprimary\x18\x01 \x01(\tR\aprimary\x12\x1c\n" +
"\tsecondary\x18\x02 \x01(\tR\tsecondary\"\xd0\x01\n" +
"\x06Member\x12:\n" +
"\x06header\x18\x01 \x01(\v2\".teleport.header.v1.ResourceHeaderR\x06header\x126\n" +
"\x04spec\x18\x02 \x01(\v2\".teleport.accesslist.v1.MemberSpecR\x04spec\x12\x14\n" +
"\x05scope\x18\x03 \x01(\tR\x05scope\"\x98\x03\n" +
"\x05scope\x18\x03 \x01(\tR\x05scope\x12<\n" +
"\x06status\x18\x04 \x01(\v2$.teleport.accesslist.v1.MemberStatusR\x06status\"\x9c\x01\n" +
"\fMemberStatus\x12=\n" +
"\adisplay\x18\x01 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\adisplay\x12M\n" +
"\x10added_by_display\x18\x02 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\x0eaddedByDisplay\"\x98\x03\n" +
"\n" +
"MemberSpec\x12\x1f\n" +
"\vaccess_list\x18\x01 \x01(\tR\n" +
@@ -2467,7 +2687,7 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xcd\x01\n" +
"\x0fUserAssignments\x12[\n" +
"\x0eownership_type\x18\x01 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\rownershipType\x12]\n" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xda\x03\n" +
"\x0fmembership_type\x18\x02 \x01(\x0e24.teleport.accesslist.v1.AccessListUserAssignmentTypeR\x0emembershipType\"\xa5\x05\n" +
"\x10AccessListStatus\x12&\n" +
"\fmember_count\x18\x01 \x01(\rH\x00R\vmemberCount\x88\x01\x01\x12/\n" +
"\x11member_list_count\x18\x02 \x01(\rH\x01R\x0fmemberListCount\x88\x01\x01\x12\x19\n" +
@@ -2476,7 +2696,11 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"\x18current_user_assignments\x18\x05 \x01(\v2..teleport.accesslist.v1.CurrentUserAssignmentsR\x16currentUserAssignments\x12R\n" +
"\x10user_assignments\x18\x06 \x01(\v2'.teleport.accesslist.v1.UserAssignmentsR\x0fuserAssignments\x12&\n" +
"\x0fscoped_owner_of\x18\a \x03(\tR\rscopedOwnerOf\x12(\n" +
"\x10scoped_member_of\x18\b \x03(\tR\x0escopedMemberOfB\x0f\n" +
"\x10scoped_member_of\x18\b \x03(\tR\x0escopedMemberOf\x12b\n" +
"\x0eowner_displays\x18\t \x03(\v2;.teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntryR\rownerDisplays\x1ae\n" +
"\x12OwnerDisplaysEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x129\n" +
"\x05value\x18\x02 \x01(\v2#.teleport.accesslist.v1.UserDisplayR\x05value:\x028\x01B\x0f\n" +
"\r_member_countB\x14\n" +
"\x12_member_list_count*\xb6\x01\n" +
"\x0fReviewFrequency\x12 \n" +
@@ -2507,7 +2731,7 @@ const file_teleport_accesslist_v1_accesslist_proto_rawDesc = "" +
"*ACCESS_LIST_USER_ASSIGNMENT_TYPE_INHERITED\x10\x02BXZVgithub.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1;accesslistv1b\x06proto3"
var file_teleport_accesslist_v1_accesslist_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_teleport_accesslist_v1_accesslist_proto_goTypes = []any{
(ReviewFrequency)(0), // 0: teleport.accesslist.v1.ReviewFrequency
(ReviewDayOfMonth)(0), // 1: teleport.accesslist.v1.ReviewDayOfMonth
@@ -2523,23 +2747,26 @@ var file_teleport_accesslist_v1_accesslist_proto_goTypes = []any{
(*AccessListRequires)(nil), // 11: teleport.accesslist.v1.AccessListRequires
(*AccessListGrants)(nil), // 12: teleport.accesslist.v1.AccessListGrants
(*ScopedRoleGrant)(nil), // 13: teleport.accesslist.v1.ScopedRoleGrant
(*Member)(nil), // 14: teleport.accesslist.v1.Member
(*MemberSpec)(nil), // 15: teleport.accesslist.v1.MemberSpec
(*Review)(nil), // 16: teleport.accesslist.v1.Review
(*ReviewSpec)(nil), // 17: teleport.accesslist.v1.ReviewSpec
(*ReviewChanges)(nil), // 18: teleport.accesslist.v1.ReviewChanges
(*CurrentUserAssignments)(nil), // 19: teleport.accesslist.v1.CurrentUserAssignments
(*UserAssignments)(nil), // 20: teleport.accesslist.v1.UserAssignments
(*AccessListStatus)(nil), // 21: teleport.accesslist.v1.AccessListStatus
(*v1.ResourceHeader)(nil), // 22: teleport.header.v1.ResourceHeader
(*timestamppb.Timestamp)(nil), // 23: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 24: google.protobuf.Duration
(*v11.Trait)(nil), // 25: teleport.trait.v1.Trait
(*UserDisplay)(nil), // 14: teleport.accesslist.v1.UserDisplay
(*Member)(nil), // 15: teleport.accesslist.v1.Member
(*MemberStatus)(nil), // 16: teleport.accesslist.v1.MemberStatus
(*MemberSpec)(nil), // 17: teleport.accesslist.v1.MemberSpec
(*Review)(nil), // 18: teleport.accesslist.v1.Review
(*ReviewSpec)(nil), // 19: teleport.accesslist.v1.ReviewSpec
(*ReviewChanges)(nil), // 20: teleport.accesslist.v1.ReviewChanges
(*CurrentUserAssignments)(nil), // 21: teleport.accesslist.v1.CurrentUserAssignments
(*UserAssignments)(nil), // 22: teleport.accesslist.v1.UserAssignments
(*AccessListStatus)(nil), // 23: teleport.accesslist.v1.AccessListStatus
nil, // 24: teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry
(*v1.ResourceHeader)(nil), // 25: teleport.header.v1.ResourceHeader
(*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp
(*durationpb.Duration)(nil), // 27: google.protobuf.Duration
(*v11.Trait)(nil), // 28: teleport.trait.v1.Trait
}
var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{
22, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader
25, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader
6, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec
21, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus
23, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus
7, // 3: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner
8, // 4: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit
11, // 5: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires
@@ -2548,39 +2775,44 @@ var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{
12, // 8: teleport.accesslist.v1.AccessListSpec.owner_grants:type_name -> teleport.accesslist.v1.AccessListGrants
3, // 9: teleport.accesslist.v1.AccessListOwner.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 10: teleport.accesslist.v1.AccessListOwner.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
23, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp
26, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp
9, // 12: teleport.accesslist.v1.AccessListAudit.recurrence:type_name -> teleport.accesslist.v1.Recurrence
10, // 13: teleport.accesslist.v1.AccessListAudit.notifications:type_name -> teleport.accesslist.v1.Notifications
0, // 14: teleport.accesslist.v1.Recurrence.frequency:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 15: teleport.accesslist.v1.Recurrence.day_of_month:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
24, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration
25, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait
25, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait
27, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration
28, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait
28, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait
13, // 19: teleport.accesslist.v1.AccessListGrants.scoped_roles:type_name -> teleport.accesslist.v1.ScopedRoleGrant
22, // 20: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader
15, // 21: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec
23, // 22: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp
23, // 23: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp
3, // 24: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 25: teleport.accesslist.v1.MemberSpec.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
22, // 26: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader
17, // 27: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec
23, // 28: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp
18, // 29: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges
11, // 30: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires
0, // 31: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 32: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
4, // 33: teleport.accesslist.v1.CurrentUserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 34: teleport.accesslist.v1.CurrentUserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 35: teleport.accesslist.v1.UserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 36: teleport.accesslist.v1.UserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
19, // 37: teleport.accesslist.v1.AccessListStatus.current_user_assignments:type_name -> teleport.accesslist.v1.CurrentUserAssignments
20, // 38: teleport.accesslist.v1.AccessListStatus.user_assignments:type_name -> teleport.accesslist.v1.UserAssignments
39, // [39:39] is the sub-list for method output_type
39, // [39:39] is the sub-list for method input_type
39, // [39:39] is the sub-list for extension type_name
39, // [39:39] is the sub-list for extension extendee
0, // [0:39] is the sub-list for field type_name
25, // 20: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader
17, // 21: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec
16, // 22: teleport.accesslist.v1.Member.status:type_name -> teleport.accesslist.v1.MemberStatus
14, // 23: teleport.accesslist.v1.MemberStatus.display:type_name -> teleport.accesslist.v1.UserDisplay
14, // 24: teleport.accesslist.v1.MemberStatus.added_by_display:type_name -> teleport.accesslist.v1.UserDisplay
26, // 25: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp
26, // 26: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp
3, // 27: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus
2, // 28: teleport.accesslist.v1.MemberSpec.membership_kind:type_name -> teleport.accesslist.v1.MembershipKind
25, // 29: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader
19, // 30: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec
26, // 31: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp
20, // 32: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges
11, // 33: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires
0, // 34: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency
1, // 35: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth
4, // 36: teleport.accesslist.v1.CurrentUserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 37: teleport.accesslist.v1.CurrentUserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 38: teleport.accesslist.v1.UserAssignments.ownership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
4, // 39: teleport.accesslist.v1.UserAssignments.membership_type:type_name -> teleport.accesslist.v1.AccessListUserAssignmentType
21, // 40: teleport.accesslist.v1.AccessListStatus.current_user_assignments:type_name -> teleport.accesslist.v1.CurrentUserAssignments
22, // 41: teleport.accesslist.v1.AccessListStatus.user_assignments:type_name -> teleport.accesslist.v1.UserAssignments
24, // 42: teleport.accesslist.v1.AccessListStatus.owner_displays:type_name -> teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry
14, // 43: teleport.accesslist.v1.AccessListStatus.OwnerDisplaysEntry.value:type_name -> teleport.accesslist.v1.UserDisplay
44, // [44:44] is the sub-list for method output_type
44, // [44:44] is the sub-list for method input_type
44, // [44:44] is the sub-list for extension type_name
44, // [44:44] is the sub-list for extension extendee
0, // [0:44] is the sub-list for field type_name
}
func init() { file_teleport_accesslist_v1_accesslist_proto_init() }
@@ -2588,14 +2820,14 @@ func file_teleport_accesslist_v1_accesslist_proto_init() {
if File_teleport_accesslist_v1_accesslist_proto != nil {
return
}
file_teleport_accesslist_v1_accesslist_proto_msgTypes[16].OneofWrappers = []any{}
file_teleport_accesslist_v1_accesslist_proto_msgTypes[18].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_accesslist_v1_accesslist_proto_rawDesc), len(file_teleport_accesslist_v1_accesslist_proto_rawDesc)),
NumEnums: 5,
NumMessages: 17,
NumMessages: 20,
NumExtensions: 0,
NumServices: 0,
},
@@ -187,6 +187,16 @@ message ScopedRoleGrant {
string scope = 2;
}
// UserDisplay contains display values derived from a user. An empty message
// means the user has no primary/secondary distinct from the username; the
// absence of this message means the user was not found.
message UserDisplay {
// primary is a human-readable display name when distinct from username.
string primary = 1;
// secondary is supporting display context when distinct from username.
string secondary = 2;
}
// Member describes a member of an Access List.
message Member {
// header is the header for the resource.
@@ -198,6 +208,17 @@ message Member {
// scope is the scope of the Access List member, it must be equal to the
// scope of the parent Access List.
string scope = 3;
// status contains dynamically calculated fields.
MemberStatus status = 4;
}
// MemberStatus contains dynamic fields calculated during retrieval.
message MemberStatus {
// display contains display values for the member user.
UserDisplay display = 1;
// added_by_display contains display values for the user that added the member.
UserDisplay added_by_display = 2;
}
// MemberSpec is the specification for an Access List member.
@@ -372,4 +393,6 @@ message AccessListStatus {
// scoped_member_of describes scoped Access Lists where this Access List is an explicit member.
// Each item is the scope-qualified name of the parent scoped Access List.
repeated string scoped_member_of = 8;
// owner_displays contains display values for owners, keyed by owner username.
map<string, UserDisplay> owner_displays = 9;
}
+4
View File
@@ -357,6 +357,10 @@ type Status struct {
// MemberOf is a list of Access List UUIDs where this access list is an explicit member.
MemberOf []string `json:"member_of" yaml:"member_of"`
// OwnerDisplays contains display values for owners, keyed by owner username.
// It is ignored when marshaling so tctl users do not mistake these read-time
// values for fields they could update with resource YAML.
OwnerDisplays map[string]types.UserDisplay `json:"-" yaml:"-"`
// ScopedOwnerOf is a list of scope-qualified names of scoped access lists
// where this access list is an explicit owner.
ScopedOwnerOf []string `json:"scoped_owner_of" yaml:"scoped_owner_of"`
+4
View File
@@ -26,6 +26,7 @@ import (
"github.com/jonboulle/clockwork"
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/header"
"github.com/gravitational/teleport/api/utils/testutils/structfill"
)
@@ -524,6 +525,9 @@ func TestEqualIgnoreEphemeralFields(t *testing.T) {
al2 := createAccessList("test1")
al2.Status.OwnerOf = []string{"different", "lists"}
al2.Status.MemberOf = []string{"other", "lists"}
al2.Status.OwnerDisplays = map[string]types.UserDisplay{
"owner1": {Primary: "Owner Name", Secondary: "owner@example.com"},
}
result := EqualAccessLists(al1, al2, WithIgnoreEphemeralFields())
require.True(t, result)
@@ -24,6 +24,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
headerv1 "github.com/gravitational/teleport/api/types/header/convert/v1"
traitv1 "github.com/gravitational/teleport/api/types/trait/convert/v1"
@@ -151,6 +152,51 @@ func ConvertGrantsFromProto(protoGrants *accesslistv1.AccessListGrants) accessli
}
}
// ToUserDisplayProto converts display values into the access list proto shape.
func ToUserDisplayProto(display types.UserDisplay) *accesslistv1.UserDisplay {
return &accesslistv1.UserDisplay{
Primary: display.Primary,
Secondary: display.Secondary,
}
}
// FromUserDisplayProto converts access list proto display values into the shared type.
func FromUserDisplayProto(display *accesslistv1.UserDisplay) types.UserDisplay {
if display == nil {
return types.UserDisplay{}
}
return types.UserDisplay{
Primary: display.GetPrimary(),
Secondary: display.GetSecondary(),
}
}
// ToUserDisplaysProto converts display values keyed by username into proto display values.
func ToUserDisplaysProto(displays map[string]types.UserDisplay) map[string]*accesslistv1.UserDisplay {
if displays == nil {
return nil
}
out := make(map[string]*accesslistv1.UserDisplay, len(displays))
for username, display := range displays {
out[username] = ToUserDisplayProto(display)
}
return out
}
// FromUserDisplaysProto converts proto display values keyed by username into the shared type.
func FromUserDisplaysProto(displays map[string]*accesslistv1.UserDisplay) map[string]types.UserDisplay {
if displays == nil {
return nil
}
out := make(map[string]types.UserDisplay, len(displays))
for username, display := range displays {
out[username] = FromUserDisplayProto(display)
}
return out
}
func convertScopedRoleGrantsFromProto(scopedRoleGrants []*accesslistv1.ScopedRoleGrant) []accesslist.ScopedRoleGrant {
if scopedRoleGrants == nil {
return nil
@@ -240,6 +286,7 @@ func convertStatusToProto(status *accesslist.Status) *accesslistv1.AccessListSta
MemberOf: status.MemberOf,
CurrentUserAssignments: toCurrentUserAssignmentsProto(status.CurrentUserAssignments),
UserAssignments: toUserAssignmentsProto(status.UserAssignments),
OwnerDisplays: ToUserDisplaysProto(status.OwnerDisplays),
ScopedOwnerOf: status.ScopedOwnerOf,
ScopedMemberOf: status.ScopedMemberOf,
}
@@ -263,6 +310,13 @@ func fromStatusProto(msg *accesslistv1.AccessList) *accesslist.Status {
}
}
// WithOwnerDisplaysField sets the "status.owner_displays" field to the provided proto value.
func WithOwnerDisplaysField(protoStatus *accesslistv1.AccessListStatus) AccessListOption {
return func(a *accesslist.AccessList) {
a.Status.OwnerDisplays = FromUserDisplaysProto(protoStatus.GetOwnerDisplays())
}
}
func copyPointer[T any](val *T) *T {
if val == nil {
return nil
@@ -91,6 +91,55 @@ func TestWithOwnersIneligibleStatusField(t *testing.T) {
}))
}
func TestUserDisplayProtoConversion(t *testing.T) {
t.Parallel()
require.Equal(t, &accesslistv1.UserDisplay{}, ToUserDisplayProto(types.UserDisplay{}))
require.Equal(t, types.UserDisplay{}, FromUserDisplayProto(nil))
require.Equal(t, types.UserDisplay{}, FromUserDisplayProto(&accesslistv1.UserDisplay{}))
display := types.UserDisplay{Primary: "Display Name", Secondary: "display@example.com"}
require.Equal(t, display, FromUserDisplayProto(ToUserDisplayProto(display)))
}
func TestUserDisplaysProtoConversion(t *testing.T) {
t.Parallel()
require.Nil(t, FromUserDisplaysProto(nil))
displays := map[string]*accesslistv1.UserDisplay{
"empty": {},
"populated": {Primary: "Display Name", Secondary: "display@example.com"},
"missing": nil,
}
require.Equal(t, map[string]types.UserDisplay{
"empty": {},
"populated": {Primary: "Display Name", Secondary: "display@example.com"},
"missing": {},
}, FromUserDisplaysProto(displays))
}
func TestWithOwnerDisplaysField(t *testing.T) {
t.Parallel()
accessList := newAccessList(t, "access-list")
accessList.Status.OwnerDisplays = map[string]types.UserDisplay{
"test-user1": {Primary: "Test User", Secondary: "test@example.com"},
"test-user2": {},
}
protoAccessList := ToProto(accessList)
converted, err := FromProto(protoAccessList)
require.NoError(t, err)
require.Empty(t, converted.Status.OwnerDisplays)
require.Equal(t, accessList.Status.MemberCount, converted.Status.MemberCount)
converted, err = FromProto(protoAccessList, WithOwnerDisplaysField(protoAccessList.GetStatus()))
require.NoError(t, err)
require.Empty(t, cmp.Diff(accessList.Status.OwnerDisplays, converted.Status.OwnerDisplays))
}
func TestRoundtrip(t *testing.T) {
t.Parallel()
+45 -1
View File
@@ -20,6 +20,7 @@ import (
"github.com/gravitational/trace"
accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
headerv1 "github.com/gravitational/teleport/api/types/header/convert/v1"
"github.com/gravitational/teleport/api/utils"
@@ -65,7 +66,7 @@ func FromMembersProto(msgs []*accesslistv1.Member) ([]*accesslist.AccessListMemb
members := make([]*accesslist.AccessListMember, len(msgs))
for i, msg := range msgs {
var err error
members[i], err = FromMemberProto(msg, WithMemberIneligibleStatusField(msg))
members[i], err = FromMemberProto(msg, WithMemberIneligibleStatusField(msg), WithMemberStatusField(msg))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -98,9 +99,45 @@ func ToMemberProto(member *accesslist.AccessListMember) *accesslistv1.Member {
IneligibleStatus: ineligibleStatus,
MembershipKind: membershipKind,
},
Status: toMemberStatusProto(member.Status),
}
}
func toMemberStatusProto(status *accesslist.AccessListMemberStatus) *accesslistv1.MemberStatus {
if status == nil {
return nil
}
return &accesslistv1.MemberStatus{
Display: toUserDisplayProtoOrNil(status.Display),
AddedByDisplay: toUserDisplayProtoOrNil(status.AddedByDisplay),
}
}
func fromMemberStatusProto(status *accesslistv1.MemberStatus) *accesslist.AccessListMemberStatus {
if status == nil {
return nil
}
return &accesslist.AccessListMemberStatus{
Display: fromUserDisplayProtoOrNil(status.GetDisplay()),
AddedByDisplay: fromUserDisplayProtoOrNil(status.GetAddedByDisplay()),
}
}
func toUserDisplayProtoOrNil(display *types.UserDisplay) *accesslistv1.UserDisplay {
if display == nil {
return nil
}
return ToUserDisplayProto(*display)
}
func fromUserDisplayProtoOrNil(display *accesslistv1.UserDisplay) *types.UserDisplay {
if display == nil {
return nil
}
out := FromUserDisplayProto(display)
return &out
}
// ToMembersProto converts a list of internal access list members into a list of v1 access list members.
func ToMembersProto(members []*accesslist.AccessListMember) []*accesslistv1.Member {
out := make([]*accesslistv1.Member, len(members))
@@ -121,3 +158,10 @@ func WithMemberIneligibleStatusField(protoMember *accesslistv1.Member) MemberOpt
m.Spec.IneligibleStatus = ineligibleStatus
}
}
// WithMemberStatusField sets the "status" field to the provided proto value.
func WithMemberStatusField(protoMember *accesslistv1.Member) MemberOption {
return func(m *accesslist.AccessListMember) {
m.Status = fromMemberStatusProto(protoMember.GetStatus())
}
}
@@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/require"
accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/accesslist"
"github.com/gravitational/teleport/api/types/header"
)
@@ -55,6 +56,49 @@ func TestWithMemberIneligibleStatusField(t *testing.T) {
require.Equal(t, accesslistv1.IneligibleStatus_INELIGIBLE_STATUS_EXPIRED.Enum().String(), alMember.Spec.IneligibleStatus)
}
func TestMemberStatusIgnoredByDefault(t *testing.T) {
member := newAccessListMember(t, "access-list-member")
member.Status = &accesslist.AccessListMemberStatus{
Display: &types.UserDisplay{Primary: "Member Name", Secondary: "member@example.com"},
AddedByDisplay: &types.UserDisplay{Primary: "Adder Name", Secondary: "adder@example.com"},
}
converted, err := FromMemberProto(ToMemberProto(member))
require.NoError(t, err)
require.Nil(t, converted.Status)
}
func TestWithMemberStatusField(t *testing.T) {
member := newAccessListMember(t, "access-list-member")
member.Status = &accesslist.AccessListMemberStatus{
Display: &types.UserDisplay{Primary: "Member Name", Secondary: "member@example.com"},
AddedByDisplay: &types.UserDisplay{Primary: "Adder Name", Secondary: "adder@example.com"},
}
protoMember := ToMemberProto(member)
converted, err := FromMemberProto(protoMember, WithMemberStatusField(protoMember))
require.NoError(t, err)
require.Empty(t, cmp.Diff(member, converted))
}
func TestWithMemberStatusFieldPreservesEmptyDisplay(t *testing.T) {
protoMember := ToMemberProto(newAccessListMember(t, "access-list-member"))
protoMember.Status = &accesslistv1.MemberStatus{
Display: &accesslistv1.UserDisplay{},
AddedByDisplay: &accesslistv1.UserDisplay{Primary: "Adder Name"},
}
member, err := FromMemberProto(protoMember, WithMemberStatusField(protoMember))
require.NoError(t, err)
require.NotNil(t, member.Status)
require.NotNil(t, member.Status.Display)
require.Empty(t, *member.Status.Display)
require.Equal(t, &types.UserDisplay{Primary: "Adder Name"}, member.Status.AddedByDisplay)
}
// Make sure that we don't panic if any of the message fields are missing.
func TestMemberFromProtoNils(t *testing.T) {
testCases := []struct {
+70 -34
View File
@@ -3,6 +3,7 @@
package accesslist
import (
types "github.com/gravitational/teleport/api/types"
header "github.com/gravitational/teleport/api/types/header"
"time"
)
@@ -57,6 +58,12 @@ func deriveDeepCopyAccessListMember(dst, src *AccessListMember) {
deriveDeepCopy_2(field, &src.Spec)
dst.Spec = *field
}()
if src.Status == nil {
dst.Status = nil
} else {
dst.Status = new(AccessListMemberStatus)
deriveDeepCopy_3(dst.Status, src.Status)
}
dst.Scope = src.Scope
}
@@ -69,7 +76,7 @@ func deriveDeepCopyReview(dst, src *Review) {
}()
func() {
field := new(ReviewSpec)
deriveDeepCopy_3(field, &src.Spec)
deriveDeepCopy_4(field, &src.Spec)
dst.Spec = *field
}()
dst.Scope = src.Scope
@@ -122,7 +129,7 @@ func deriveDeepCopy(dst, src *header.ResourceHeader) {
dst.Version = src.Version
func() {
field := new(header.Metadata)
deriveDeepCopy_4(field, &src.Metadata)
deriveDeepCopy_5(field, &src.Metadata)
dst.Metadata = *field
}()
}
@@ -152,27 +159,27 @@ func deriveDeepCopy_(dst, src *Spec) {
}
func() {
field := new(Audit)
deriveDeepCopy_5(field, &src.Audit)
deriveDeepCopy_6(field, &src.Audit)
dst.Audit = *field
}()
func() {
field := new(Requires)
deriveDeepCopy_6(field, &src.MembershipRequires)
deriveDeepCopy_7(field, &src.MembershipRequires)
dst.MembershipRequires = *field
}()
func() {
field := new(Requires)
deriveDeepCopy_6(field, &src.OwnershipRequires)
deriveDeepCopy_7(field, &src.OwnershipRequires)
dst.OwnershipRequires = *field
}()
func() {
field := new(Grants)
deriveDeepCopy_7(field, &src.Grants)
deriveDeepCopy_8(field, &src.Grants)
dst.Grants = *field
}()
func() {
field := new(Grants)
deriveDeepCopy_7(field, &src.OwnerGrants)
deriveDeepCopy_8(field, &src.OwnerGrants)
dst.OwnerGrants = *field
}()
}
@@ -227,6 +234,12 @@ func deriveDeepCopy_1(dst, src *Status) {
}
copy(dst.MemberOf, src.MemberOf)
}
if src.OwnerDisplays != nil {
dst.OwnerDisplays = make(map[string]types.UserDisplay, len(src.OwnerDisplays))
deriveDeepCopy_9(dst.OwnerDisplays, src.OwnerDisplays)
} else {
dst.OwnerDisplays = nil
}
if src.ScopedOwnerOf == nil {
dst.ScopedOwnerOf = nil
} else {
@@ -284,12 +297,12 @@ func deriveDeepCopy_2(dst, src *AccessListMemberSpec) {
dst.Title = src.Title
func() {
field := new(time.Time)
deriveDeepCopy_8(field, &src.Joined)
deriveDeepCopy_10(field, &src.Joined)
dst.Joined = *field
}()
func() {
field := new(time.Time)
deriveDeepCopy_8(field, &src.Expires)
deriveDeepCopy_10(field, &src.Expires)
dst.Expires = *field
}()
dst.Reason = src.Reason
@@ -299,7 +312,23 @@ func deriveDeepCopy_2(dst, src *AccessListMemberSpec) {
}
// deriveDeepCopy_3 recursively copies the contents of src into dst.
func deriveDeepCopy_3(dst, src *ReviewSpec) {
func deriveDeepCopy_3(dst, src *AccessListMemberStatus) {
if src.Display == nil {
dst.Display = nil
} else {
dst.Display = new(types.UserDisplay)
*dst.Display = *src.Display
}
if src.AddedByDisplay == nil {
dst.AddedByDisplay = nil
} else {
dst.AddedByDisplay = new(types.UserDisplay)
*dst.AddedByDisplay = *src.AddedByDisplay
}
}
// deriveDeepCopy_4 recursively copies the contents of src into dst.
func deriveDeepCopy_4(dst, src *ReviewSpec) {
dst.AccessList = src.AccessList
if src.Reviewers == nil {
dst.Reviewers = nil
@@ -321,13 +350,13 @@ func deriveDeepCopy_3(dst, src *ReviewSpec) {
}
func() {
field := new(time.Time)
deriveDeepCopy_8(field, &src.ReviewDate)
deriveDeepCopy_10(field, &src.ReviewDate)
dst.ReviewDate = *field
}()
dst.Notes = src.Notes
func() {
field := new(ReviewChanges)
deriveDeepCopy_9(field, &src.Changes)
deriveDeepCopy_11(field, &src.Changes)
dst.Changes = *field
}()
}
@@ -384,37 +413,37 @@ func deriveTeleportEqual_6(this, that *Grants) bool {
deriveTeleportEqual_10(this.ScopedRoles, that.ScopedRoles)
}
// deriveDeepCopy_4 recursively copies the contents of src into dst.
func deriveDeepCopy_4(dst, src *header.Metadata) {
// deriveDeepCopy_5 recursively copies the contents of src into dst.
func deriveDeepCopy_5(dst, src *header.Metadata) {
dst.Name = src.Name
dst.Description = src.Description
if src.Labels != nil {
dst.Labels = make(map[string]string, len(src.Labels))
deriveDeepCopy_10(dst.Labels, src.Labels)
deriveDeepCopy_12(dst.Labels, src.Labels)
} else {
dst.Labels = nil
}
func() {
field := new(time.Time)
deriveDeepCopy_8(field, &src.Expires)
deriveDeepCopy_10(field, &src.Expires)
dst.Expires = *field
}()
dst.Revision = src.Revision
}
// deriveDeepCopy_5 recursively copies the contents of src into dst.
func deriveDeepCopy_5(dst, src *Audit) {
// deriveDeepCopy_6 recursively copies the contents of src into dst.
func deriveDeepCopy_6(dst, src *Audit) {
func() {
field := new(time.Time)
deriveDeepCopy_8(field, &src.NextAuditDate)
deriveDeepCopy_10(field, &src.NextAuditDate)
dst.NextAuditDate = *field
}()
dst.Recurrence = src.Recurrence
dst.Notifications = src.Notifications
}
// deriveDeepCopy_6 recursively copies the contents of src into dst.
func deriveDeepCopy_6(dst, src *Requires) {
// deriveDeepCopy_7 recursively copies the contents of src into dst.
func deriveDeepCopy_7(dst, src *Requires) {
if src.Roles == nil {
dst.Roles = nil
} else {
@@ -435,14 +464,14 @@ func deriveDeepCopy_6(dst, src *Requires) {
}
if src.Traits != nil {
dst.Traits = make(map[string][]string, len(src.Traits))
deriveDeepCopy_11(dst.Traits, src.Traits)
deriveDeepCopy_13(dst.Traits, src.Traits)
} else {
dst.Traits = nil
}
}
// deriveDeepCopy_7 recursively copies the contents of src into dst.
func deriveDeepCopy_7(dst, src *Grants) {
// deriveDeepCopy_8 recursively copies the contents of src into dst.
func deriveDeepCopy_8(dst, src *Grants) {
if src.Roles == nil {
dst.Roles = nil
} else {
@@ -463,7 +492,7 @@ func deriveDeepCopy_7(dst, src *Grants) {
}
if src.Traits != nil {
dst.Traits = make(map[string][]string, len(src.Traits))
deriveDeepCopy_11(dst.Traits, src.Traits)
deriveDeepCopy_13(dst.Traits, src.Traits)
} else {
dst.Traits = nil
}
@@ -487,18 +516,25 @@ func deriveDeepCopy_7(dst, src *Grants) {
}
}
// deriveDeepCopy_8 recursively copies the contents of src into dst.
func deriveDeepCopy_8(dst, src *time.Time) {
// deriveDeepCopy_9 recursively copies the contents of src into dst.
func deriveDeepCopy_9(dst, src map[string]types.UserDisplay) {
for src_key, src_value := range src {
dst[src_key] = src_value
}
}
// deriveDeepCopy_10 recursively copies the contents of src into dst.
func deriveDeepCopy_10(dst, src *time.Time) {
*dst = *src
}
// deriveDeepCopy_9 recursively copies the contents of src into dst.
func deriveDeepCopy_9(dst, src *ReviewChanges) {
// deriveDeepCopy_11 recursively copies the contents of src into dst.
func deriveDeepCopy_11(dst, src *ReviewChanges) {
if src.MembershipRequirementsChanged == nil {
dst.MembershipRequirementsChanged = nil
} else {
dst.MembershipRequirementsChanged = new(Requires)
deriveDeepCopy_6(dst.MembershipRequirementsChanged, src.MembershipRequirementsChanged)
deriveDeepCopy_7(dst.MembershipRequirementsChanged, src.MembershipRequirementsChanged)
}
if src.RemovedMembers == nil {
dst.RemovedMembers = nil
@@ -612,15 +648,15 @@ func deriveTeleportEqual_10(this, that []ScopedRoleGrant) bool {
return true
}
// deriveDeepCopy_10 recursively copies the contents of src into dst.
func deriveDeepCopy_10(dst, src map[string]string) {
// deriveDeepCopy_12 recursively copies the contents of src into dst.
func deriveDeepCopy_12(dst, src map[string]string) {
for src_key, src_value := range src {
dst[src_key] = src_value
}
}
// deriveDeepCopy_11 recursively copies the contents of src into dst.
func deriveDeepCopy_11(dst, src map[string][]string) {
// deriveDeepCopy_13 recursively copies the contents of src into dst.
func deriveDeepCopy_13(dst, src map[string][]string) {
for src_key, src_value := range src {
if src_value == nil {
dst[src_key] = nil
+15
View File
@@ -35,11 +35,26 @@ type AccessListMember struct {
// Spec is the specification for the access list member.
Spec AccessListMemberSpec `json:"spec" yaml:"spec"`
// Status contains dynamically calculated fields. It is ignored when
// marshaling so tctl users do not mistake these read-time values for fields
// they could update with resource YAML.
Status *AccessListMemberStatus `json:"-" yaml:"-"`
// Scope is the scope of the access list member, it must be equal to the
// scope of the parent access list.
Scope string `json:"scope" yaml:"scope"`
}
// AccessListMemberStatus contains dynamic fields calculated during retrieval.
// Its fields are ignored when marshaling for the same reason as AccessListMember.Status
type AccessListMemberStatus struct {
// Display contains display values for the member user.
Display *types.UserDisplay `json:"-" yaml:"-"`
// AddedByDisplay contains display values for the user that added the member.
AddedByDisplay *types.UserDisplay `json:"-" yaml:"-"`
}
// AccessListMemberSpec describes the specification of a member of an access list.
type AccessListMemberSpec struct {
// AccessList is the name of the associated access list.
+12
View File
@@ -70,3 +70,15 @@ func TestAccessListMemberClone(t *testing.T) {
require.Empty(t, cmp.Diff(item, cpy))
require.NotSame(t, item, cpy)
}
func TestAccessListMemberEqualIgnoresStatus(t *testing.T) {
status := AccessListMemberStatus{
Display: &types.UserDisplay{Primary: "Member Name", Secondary: "member@example.com"},
AddedByDisplay: &types.UserDisplay{Primary: "Adder Name", Secondary: "adder@example.com"},
}
item := &AccessListMember{}
other := item.Clone()
other.Status = &status
require.True(t, item.IsEqual(other))
}
+2 -2
View File
@@ -57,9 +57,9 @@ const (
// UserDisplay contains display values derived from the user.
type UserDisplay struct {
// Primary is a human-readable display name when distinct from username.
Primary string
Primary string `json:"primary,omitempty"`
// Secondary is supporting display context when distinct from username.
Secondary string
Secondary string `json:"secondary,omitempty"`
}
// GetDisplay returns display values derived from the user.
+199 -2
View File
@@ -299,6 +299,27 @@ export interface ScopedRoleGrant {
*/
scope: string;
}
/**
* UserDisplay contains display values derived from a user. An empty message
* means the user has no primary/secondary distinct from the username; the
* absence of this message means the user was not found.
*
* @generated from protobuf message teleport.accesslist.v1.UserDisplay
*/
export interface UserDisplay {
/**
* primary is a human-readable display name when distinct from username.
*
* @generated from protobuf field: string primary = 1;
*/
primary: string;
/**
* secondary is supporting display context when distinct from username.
*
* @generated from protobuf field: string secondary = 2;
*/
secondary: string;
}
/**
* Member describes a member of an Access List.
*
@@ -324,6 +345,31 @@ export interface Member {
* @generated from protobuf field: string scope = 3;
*/
scope: string;
/**
* status contains dynamically calculated fields.
*
* @generated from protobuf field: teleport.accesslist.v1.MemberStatus status = 4;
*/
status?: MemberStatus;
}
/**
* MemberStatus contains dynamic fields calculated during retrieval.
*
* @generated from protobuf message teleport.accesslist.v1.MemberStatus
*/
export interface MemberStatus {
/**
* display contains display values for the member user.
*
* @generated from protobuf field: teleport.accesslist.v1.UserDisplay display = 1;
*/
display?: UserDisplay;
/**
* added_by_display contains display values for the user that added the member.
*
* @generated from protobuf field: teleport.accesslist.v1.UserDisplay added_by_display = 2;
*/
addedByDisplay?: UserDisplay;
}
/**
* MemberSpec is the specification for an Access List member.
@@ -586,6 +632,14 @@ export interface AccessListStatus {
* @generated from protobuf field: repeated string scoped_member_of = 8;
*/
scopedMemberOf: string[];
/**
* owner_displays contains display values for owners, keyed by owner username.
*
* @generated from protobuf field: map<string, teleport.accesslist.v1.UserDisplay> owner_displays = 9;
*/
ownerDisplays: {
[key: string]: UserDisplay;
};
}
/**
* ReviewFrequency is the frequency of reviews.
@@ -1316,12 +1370,68 @@ class ScopedRoleGrant$Type extends MessageType<ScopedRoleGrant> {
*/
export const ScopedRoleGrant = new ScopedRoleGrant$Type();
// @generated message type with reflection information, may provide speed optimized methods
class UserDisplay$Type extends MessageType<UserDisplay> {
constructor() {
super("teleport.accesslist.v1.UserDisplay", [
{ no: 1, name: "primary", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
{ no: 2, name: "secondary", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
]);
}
create(value?: PartialMessage<UserDisplay>): UserDisplay {
const message = globalThis.Object.create((this.messagePrototype!));
message.primary = "";
message.secondary = "";
if (value !== undefined)
reflectionMergePartial<UserDisplay>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: UserDisplay): UserDisplay {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
case /* string primary */ 1:
message.primary = reader.string();
break;
case /* string secondary */ 2:
message.secondary = reader.string();
break;
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: UserDisplay, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
/* string primary = 1; */
if (message.primary !== "")
writer.tag(1, WireType.LengthDelimited).string(message.primary);
/* string secondary = 2; */
if (message.secondary !== "")
writer.tag(2, WireType.LengthDelimited).string(message.secondary);
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message teleport.accesslist.v1.UserDisplay
*/
export const UserDisplay = new UserDisplay$Type();
// @generated message type with reflection information, may provide speed optimized methods
class Member$Type extends MessageType<Member> {
constructor() {
super("teleport.accesslist.v1.Member", [
{ no: 1, name: "header", kind: "message", T: () => ResourceHeader },
{ no: 2, name: "spec", kind: "message", T: () => MemberSpec },
{ no: 3, name: "scope", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
{ no: 3, name: "scope", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
{ no: 4, name: "status", kind: "message", T: () => MemberStatus }
]);
}
create(value?: PartialMessage<Member>): Member {
@@ -1345,6 +1455,9 @@ class Member$Type extends MessageType<Member> {
case /* string scope */ 3:
message.scope = reader.string();
break;
case /* teleport.accesslist.v1.MemberStatus status */ 4:
message.status = MemberStatus.internalBinaryRead(reader, reader.uint32(), options, message.status);
break;
default:
let u = options.readUnknownField;
if (u === "throw")
@@ -1366,6 +1479,9 @@ class Member$Type extends MessageType<Member> {
/* string scope = 3; */
if (message.scope !== "")
writer.tag(3, WireType.LengthDelimited).string(message.scope);
/* teleport.accesslist.v1.MemberStatus status = 4; */
if (message.status)
MemberStatus.internalBinaryWrite(message.status, writer.tag(4, WireType.LengthDelimited).fork(), options).join();
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -1377,6 +1493,59 @@ class Member$Type extends MessageType<Member> {
*/
export const Member = new Member$Type();
// @generated message type with reflection information, may provide speed optimized methods
class MemberStatus$Type extends MessageType<MemberStatus> {
constructor() {
super("teleport.accesslist.v1.MemberStatus", [
{ no: 1, name: "display", kind: "message", T: () => UserDisplay },
{ no: 2, name: "added_by_display", kind: "message", T: () => UserDisplay }
]);
}
create(value?: PartialMessage<MemberStatus>): MemberStatus {
const message = globalThis.Object.create((this.messagePrototype!));
if (value !== undefined)
reflectionMergePartial<MemberStatus>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: MemberStatus): MemberStatus {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
case /* teleport.accesslist.v1.UserDisplay display */ 1:
message.display = UserDisplay.internalBinaryRead(reader, reader.uint32(), options, message.display);
break;
case /* teleport.accesslist.v1.UserDisplay added_by_display */ 2:
message.addedByDisplay = UserDisplay.internalBinaryRead(reader, reader.uint32(), options, message.addedByDisplay);
break;
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: MemberStatus, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
/* teleport.accesslist.v1.UserDisplay display = 1; */
if (message.display)
UserDisplay.internalBinaryWrite(message.display, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
/* teleport.accesslist.v1.UserDisplay added_by_display = 2; */
if (message.addedByDisplay)
UserDisplay.internalBinaryWrite(message.addedByDisplay, writer.tag(2, WireType.LengthDelimited).fork(), options).join();
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message teleport.accesslist.v1.MemberStatus
*/
export const MemberStatus = new MemberStatus$Type();
// @generated message type with reflection information, may provide speed optimized methods
class MemberSpec$Type extends MessageType<MemberSpec> {
constructor() {
super("teleport.accesslist.v1.MemberSpec", [
@@ -1814,7 +1983,8 @@ class AccessListStatus$Type extends MessageType<AccessListStatus> {
{ no: 5, name: "current_user_assignments", kind: "message", T: () => CurrentUserAssignments },
{ no: 6, name: "user_assignments", kind: "message", T: () => UserAssignments },
{ no: 7, name: "scoped_owner_of", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ },
{ no: 8, name: "scoped_member_of", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }
{ no: 8, name: "scoped_member_of", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ },
{ no: 9, name: "owner_displays", kind: "map", K: 9 /*ScalarType.STRING*/, V: { kind: "message", T: () => UserDisplay } }
]);
}
create(value?: PartialMessage<AccessListStatus>): AccessListStatus {
@@ -1823,6 +1993,7 @@ class AccessListStatus$Type extends MessageType<AccessListStatus> {
message.memberOf = [];
message.scopedOwnerOf = [];
message.scopedMemberOf = [];
message.ownerDisplays = {};
if (value !== undefined)
reflectionMergePartial<AccessListStatus>(this, message, value);
return message;
@@ -1856,6 +2027,9 @@ class AccessListStatus$Type extends MessageType<AccessListStatus> {
case /* repeated string scoped_member_of */ 8:
message.scopedMemberOf.push(reader.string());
break;
case /* map<string, teleport.accesslist.v1.UserDisplay> owner_displays */ 9:
this.binaryReadMap9(message.ownerDisplays, reader, options);
break;
default:
let u = options.readUnknownField;
if (u === "throw")
@@ -1867,6 +2041,22 @@ class AccessListStatus$Type extends MessageType<AccessListStatus> {
}
return message;
}
private binaryReadMap9(map: AccessListStatus["ownerDisplays"], reader: IBinaryReader, options: BinaryReadOptions): void {
let len = reader.uint32(), end = reader.pos + len, key: keyof AccessListStatus["ownerDisplays"] | undefined, val: AccessListStatus["ownerDisplays"][any] | undefined;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
case 1:
key = reader.string();
break;
case 2:
val = UserDisplay.internalBinaryRead(reader, reader.uint32(), options);
break;
default: throw new globalThis.Error("unknown map entry field for field teleport.accesslist.v1.AccessListStatus.owner_displays");
}
}
map[key ?? ""] = val ?? UserDisplay.create();
}
internalBinaryWrite(message: AccessListStatus, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
/* optional uint32 member_count = 1; */
if (message.memberCount !== undefined)
@@ -1892,6 +2082,13 @@ class AccessListStatus$Type extends MessageType<AccessListStatus> {
/* repeated string scoped_member_of = 8; */
for (let i = 0; i < message.scopedMemberOf.length; i++)
writer.tag(8, WireType.LengthDelimited).string(message.scopedMemberOf[i]);
/* map<string, teleport.accesslist.v1.UserDisplay> owner_displays = 9; */
for (let k of globalThis.Object.keys(message.ownerDisplays)) {
writer.tag(9, WireType.LengthDelimited).fork().tag(1, WireType.LengthDelimited).string(k);
writer.tag(2, WireType.LengthDelimited).fork();
UserDisplay.internalBinaryWrite(message.ownerDisplays[k], writer, options);
writer.join().join();
}
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
+6
View File
@@ -39,6 +39,12 @@ var ignoredFields = map[string]stringSet{
"GithubConnectorSpecV3": {
"TeamsToLogins": struct{}{}, // Deprecated field, removed since v11
},
"Member": {
"Status": struct{}{},
},
"AccessListStatus": {
"OwnerDisplays": struct{}{},
},
"ServerSpecV2": {
// Useless field for agentless servers, and potentially dangerous as it
// allows remote exec on agentful nodes.
@@ -49,6 +49,7 @@ exclude_fields:
- "Member.header.metadata.id"
# Read only field
- "Member.spec.ineligible_status"
- "Member.status"
# These fields will be marked as Computed: true
computed_fields: