From 18832308b2c5400a0bdc07cac94507026edea7fc Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 7 Nov 2024 14:16:51 -0600 Subject: [PATCH 01/36] Adding Azure integration gRPC messages and RPC methods --- api/proto/teleport/legacy/types/types.proto | 10 + api/types/types.pb.go | 351 +++++++++++++++++++ gen/proto/go/accessgraph/v1alpha/azure.pb.go | 221 ++---------- proto/accessgraph/v1alpha/azure.proto | 2 +- 4 files changed, 394 insertions(+), 190 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 42b6852923223..39fac0a85908a 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8025,6 +8025,8 @@ message OktaOptions { message AccessGraphSync { // AWS is a configuration for AWS Access Graph service poll service. repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; + // Azure is a configuration for the Azure Access Graph service poll service. + repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "azure,omitempty"]; // PollInterval is the frequency at which to poll for AWS resources google.protobuf.Duration PollInterval = 2 [ (gogoproto.jsontag) = "poll_interval,omitempty", @@ -8042,3 +8044,11 @@ message AccessGraphAWSSync { // Integration is the integration name used to generate credentials to interact with AWS APIs. string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; } + +// AccessGraphAzureSync is a configuration for Azure Access Graph service poll service. +message AccessGraphAzureSync { + repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; + string SubscriptionID = 2 [(gogoproto.jsontag) = "regions,omitempty"]; + string UmiClientId = 3 [(gogoproto.jsontag) = "regions,omitempty"]; + string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 5a5743a778c11..4b10f78f6a5fc 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -21463,6 +21463,50 @@ func (m *AccessGraphAWSSync) XXX_DiscardUnknown() { var xxx_messageInfo_AccessGraphAWSSync proto.InternalMessageInfo +// AccessGraphAzureSync is a configuration for Azure Access Graph service poll service. +type AccessGraphAzureSync struct { + Regions []string `protobuf:"bytes,1,rep,name=Regions,proto3" json:"regions,omitempty"` + SubscriptionID string `protobuf:"bytes,2,opt,name=SubscriptionID,proto3" json:"regions,omitempty"` + UmiClientId string `protobuf:"bytes,3,opt,name=UmiClientId,proto3" json:"regions,omitempty"` + Integration string `protobuf:"bytes,4,opt,name=Integration,proto3" json:"integration,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessGraphAzureSync) Reset() { *m = AccessGraphAzureSync{} } +func (m *AccessGraphAzureSync) String() string { return proto.CompactTextString(m) } +func (*AccessGraphAzureSync) ProtoMessage() {} +func (*AccessGraphAzureSync) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{359} +} +func (m *AccessGraphAzureSync) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessGraphAzureSync) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessGraphAzureSync.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AccessGraphAzureSync) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessGraphAzureSync.Merge(m, src) +} +func (m *AccessGraphAzureSync) XXX_Size() int { + return m.Size() +} +func (m *AccessGraphAzureSync) XXX_DiscardUnknown() { + xxx_messageInfo_AccessGraphAzureSync.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessGraphAzureSync proto.InternalMessageInfo + func init() { proto.RegisterEnum("types.IAMPolicyStatus", IAMPolicyStatus_name, IAMPolicyStatus_value) proto.RegisterEnum("types.DatabaseTLSMode", DatabaseTLSMode_name, DatabaseTLSMode_value) @@ -21900,6 +21944,7 @@ func init() { proto.RegisterType((*OktaOptions)(nil), "types.OktaOptions") proto.RegisterType((*AccessGraphSync)(nil), "types.AccessGraphSync") proto.RegisterType((*AccessGraphAWSSync)(nil), "types.AccessGraphAWSSync") + proto.RegisterType((*AccessGraphAzureSync)(nil), "types.AccessGraphAzureSync") } func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } @@ -50442,6 +50487,63 @@ func (m *AccessGraphAWSSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AccessGraphAzureSync) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccessGraphAzureSync) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Integration) > 0 { + i -= len(m.Integration) + copy(dAtA[i:], m.Integration) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Integration))) + i-- + dAtA[i] = 0x22 + } + if len(m.UmiClientId) > 0 { + i -= len(m.UmiClientId) + copy(dAtA[i:], m.UmiClientId) + i = encodeVarintTypes(dAtA, i, uint64(len(m.UmiClientId))) + i-- + dAtA[i] = 0x1a + } + if len(m.SubscriptionID) > 0 { + i -= len(m.SubscriptionID) + copy(dAtA[i:], m.SubscriptionID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.SubscriptionID))) + i-- + dAtA[i] = 0x12 + } + if len(m.Regions) > 0 { + for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Regions[iNdEx]) + copy(dAtA[i:], m.Regions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { offset -= sovTypes(v) base := offset @@ -61805,6 +61907,12 @@ func (m *AccessGraphSync) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } + if len(m.Azure) > 0 { + for _, e := range m.Azure { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval) n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { @@ -61839,6 +61947,36 @@ func (m *AccessGraphAWSSync) Size() (n int) { return n } +func (m *AccessGraphAzureSync) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Regions) > 0 { + for _, s := range m.Regions { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + l = len(m.SubscriptionID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.UmiClientId) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Integration) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovTypes(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -134180,6 +134318,40 @@ func (m *AccessGraphSync) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Azure", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Azure = append(m.Azure, &AccessGraphAzureSync{}) + if err := m.Azure[len(m.Azure)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -134353,6 +134525,185 @@ func (m *AccessGraphAWSSync) Unmarshal(dAtA []byte) error { } return nil } +func (m *AccessGraphAzureSync) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccessGraphAzureSync: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccessGraphAzureSync: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Regions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Regions = append(m.Regions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubscriptionID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubscriptionID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UmiClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UmiClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Integration", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Integration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTypes(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 308847e258ba9..3b83614b514ae 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -164,6 +164,20 @@ func (x *AzureResource) GetVirtualMachine() *AzureVirtualMachine { return nil } +func (x *AzureResource) GetManagedDatabase() *AzureManagedDatabase { + if x, ok := x.GetResource().(*AzureResource_ManagedDatabase); ok { + return x.ManagedDatabase + } + return nil +} + +func (x *AzureResource) GetAksCluster() *AzureAKSCluster { + if x, ok := x.GetResource().(*AzureResource_AksCluster); ok { + return x.AksCluster + } + return nil +} + type isAzureResource_Resource interface { isAzureResource_Resource() } @@ -188,6 +202,14 @@ type AzureResource_VirtualMachine struct { VirtualMachine *AzureVirtualMachine `protobuf:"bytes,4,opt,name=virtual_machine,json=virtualMachine,proto3,oneof"` } +type AzureResource_ManagedDatabase struct { + ManagedDatabase *AzureManagedDatabase `protobuf:"bytes,5,opt,name=managed_database,json=managedDatabase,proto3,oneof"` +} + +type AzureResource_AksCluster struct { + AksCluster *AzureAKSCluster `protobuf:"bytes,6,opt,name=aks_cluster,json=aksCluster,proto3,oneof"` +} + func (*AzureResource_Principal) isAzureResource_Resource() {} func (*AzureResource_RoleDefinition) isAzureResource_Resource() {} @@ -196,6 +218,10 @@ func (*AzureResource_RoleAssignment) isAzureResource_Resource() {} func (*AzureResource_VirtualMachine) isAzureResource_Resource() {} +func (*AzureResource_ManagedDatabase) isAzureResource_Resource() {} + +func (*AzureResource_AksCluster) isAzureResource_Resource() {} + // AzureVirtualMachine is an Azure virtual machine type AzureVirtualMachine struct { state protoimpl.MessageState @@ -512,7 +538,6 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzureRoleAssignment) GetId() string { @@ -570,29 +595,14 @@ type AzureRoleDefinition struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // id is the ID of the role definition - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // subscription_id is the ID of the subscription to which the role definition belongs - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - // last_sync_time is when the role definition was last fetched from Azure - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - // name is the given name for the role definition - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - // description provides additional detail about the role definition - Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` - // assignable_scopes limits the scopes defined in corresponding role assignments - AssignableScopes []string `protobuf:"bytes,6,rep,name=assignable_scopes,json=assignableScopes,proto3" json:"assignable_scopes,omitempty"` - // permissions define the actions and not (disallowed) actions - Permissions []*AzureRBACPermission `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` - // role_name is the given name for the role itself - RoleName string `protobuf:"bytes,8,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"` - // type defines the type of role - Type string `protobuf:"bytes,9,opt,name=type,proto3" json:"type,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -604,7 +614,6 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -617,7 +626,6 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleDefinition) GetId() string { @@ -648,21 +656,6 @@ func (x *AzureRoleDefinition) GetName() string { return "" } -func (x *AzureRoleDefinition) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *AzureRoleDefinition) GetAssignableScopes() []string { - if x != nil { - return x.AssignableScopes - } - return nil -} - -func (x *AzureRoleDefinition) GetPermissions() []*AzureRBACPermission { if x != nil { return x.Permissions } @@ -684,36 +677,20 @@ func (x *AzureRoleDefinition) GetType() string { } // AzurePermission defines the actions and not (disallowed) actions for a role definition -type AzureRBACPermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // actions define the resources and verbs allowed on the resources - Actions []string `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"` - // not_actions define the resources and verbs disallowed on the resources - NotActions []string `protobuf:"bytes,2,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` - // data_actions define fine-grained resources and verbs allowed within the resource - DataActions []string `protobuf:"bytes,3,rep,name=data_actions,json=dataActions,proto3" json:"data_actions,omitempty"` - // not_data_actions define fine-grained resources and verbs disallowed within the resource - NotDataActions []string `protobuf:"bytes,4,rep,name=not_data_actions,json=notDataActions,proto3" json:"not_data_actions,omitempty"` } -func (x *AzureRBACPermission) Reset() { - *x = AzureRBACPermission{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzureRBACPermission) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzureRBACPermission) ProtoMessage() {} -func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -724,19 +701,14 @@ func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzureRBACPermission.ProtoReflect.Descriptor instead. -func (*AzureRBACPermission) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } -func (x *AzureRBACPermission) GetActions() []string { if x != nil { return x.Actions } return nil } -func (x *AzureRBACPermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -770,8 +742,6 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xdf, - 0x02, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -792,114 +762,6 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0xe8, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, - 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, - 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x77, 0x0a, 0x0d, 0x41, - 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0c, - 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, - 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x49, 0x64, 0x22, 0xb0, 0x02, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, - 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, - 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x4f, 0x66, 0x12, 0x42, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x95, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, - 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, - 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, - 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, - 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, - 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, - 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xf0, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x61, 0x74, - 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x74, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, } var ( @@ -919,32 +781,11 @@ var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine - (*AzureIdentity)(nil), // 3: accessgraph.v1alpha.AzureIdentity - (*AzurePrincipal)(nil), // 4: accessgraph.v1alpha.AzurePrincipal - (*AzureRoleAssignment)(nil), // 5: accessgraph.v1alpha.AzureRoleAssignment - (*AzureRoleDefinition)(nil), // 6: accessgraph.v1alpha.AzureRoleDefinition - (*AzureRBACPermission)(nil), // 7: accessgraph.v1alpha.AzureRBACPermission - nil, // 8: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource - 4, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal - 6, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition - 5, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine - 9, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry - 9, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp - 3, // 8: accessgraph.v1alpha.AzurePrincipal.identities:type_name -> accessgraph.v1alpha.AzureIdentity - 9, // 9: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 10: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp - 7, // 11: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -957,6 +798,8 @@ func file_accessgraph_v1alpha_azure_proto_init() { (*AzureResource_RoleDefinition)(nil), (*AzureResource_RoleAssignment)(nil), (*AzureResource_VirtualMachine)(nil), + (*AzureResource_ManagedDatabase)(nil), + (*AzureResource_AksCluster)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/accessgraph/v1alpha/azure.proto b/proto/accessgraph/v1alpha/azure.proto index 1050c3c98f75e..58bef9b36e97b 100644 --- a/proto/accessgraph/v1alpha/azure.proto +++ b/proto/accessgraph/v1alpha/azure.proto @@ -127,7 +127,7 @@ message AzureRoleDefinition { string type = 9; } -// AzurePermission defines the actions and not (disallowed) actions for a role definition +// AzureRBACPermission defines the actions and not (disallowed) actions for a role definition message AzureRBACPermission { // actions define the resources and verbs allowed on the resources repeated string actions = 1; From b113b78bd04042a31905dfdb4e7da930bed74400 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 7 Nov 2024 18:23:45 -0600 Subject: [PATCH 02/36] Make derive --- api/types/discoveryconfig/derived.gen.go | 106 ++++++++++++++--------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index 9053fdd312473..c10fbf8b83f1c 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -144,12 +144,12 @@ func deriveTeleportEqual_7(this, that map[string]string) bool { func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_17(this.SSM, that.SSM) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_18(this.SSM, that.SSM) && this.Integration == that.Integration && this.KubeAppDiscovery == that.KubeAppDiscovery && this.SetupAccessForARN == that.SetupAccessForARN @@ -159,34 +159,34 @@ func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { func deriveTeleportEqual_9(this, that *types.AzureMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Subscriptions, that.Subscriptions) && - deriveTeleportEqual_13(this.ResourceGroups, that.ResourceGroups) && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.ResourceTags, that.ResourceTags) && - deriveTeleportEqual_16(this.Params, that.Params) + deriveTeleportEqual_14(this.Subscriptions, that.Subscriptions) && + deriveTeleportEqual_14(this.ResourceGroups, that.ResourceGroups) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_16(this.ResourceTags, that.ResourceTags) && + deriveTeleportEqual_17(this.Params, that.Params) } // deriveTeleportEqual_10 returns whether this and that are equal. func deriveTeleportEqual_10(this, that *types.GCPMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Locations, that.Locations) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_13(this.ProjectIDs, that.ProjectIDs) && - deriveTeleportEqual_13(this.ServiceAccounts, that.ServiceAccounts) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Locations, that.Locations) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_14(this.ProjectIDs, that.ProjectIDs) && + deriveTeleportEqual_14(this.ServiceAccounts, that.ServiceAccounts) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_11 returns whether this and that are equal. func deriveTeleportEqual_11(this, that *types.KubernetesMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Namespaces, that.Namespaces) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Namespaces, that.Namespaces) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_12 returns whether this and that are equal. @@ -198,7 +198,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { return false } for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_18(this[i], that[i])) { + if !(deriveTeleportEqual_19(this[i], that[i])) { return false } } @@ -206,7 +206,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { } // deriveTeleportEqual_13 returns whether this and that are equal. -func deriveTeleportEqual_13(this, that []string) bool { +func deriveTeleportEqual_13(this, that []*types.AccessGraphAzureSync) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -214,7 +214,7 @@ func deriveTeleportEqual_13(this, that []string) bool { return false } for i := 0; i < len(this); i++ { - if !(this[i] == that[i]) { + if !(deriveTeleportEqual_20(this[i], that[i])) { return false } } @@ -222,15 +222,31 @@ func deriveTeleportEqual_13(this, that []string) bool { } // deriveTeleportEqual_14 returns whether this and that are equal. -func deriveTeleportEqual_14(this, that *types.AssumeRole) bool { +func deriveTeleportEqual_14(this, that []string) bool { + if this == nil || that == nil { + return this == nil && that == nil + } + if len(this) != len(that) { + return false + } + for i := 0; i < len(this); i++ { + if !(this[i] == that[i]) { + return false + } + } + return true +} + +// deriveTeleportEqual_15 returns whether this and that are equal. +func deriveTeleportEqual_15(this, that *types.AssumeRole) bool { return (this == nil && that == nil) || this != nil && that != nil && this.RoleARN == that.RoleARN && this.ExternalID == that.ExternalID } -// deriveTeleportEqual_15 returns whether this and that are equal. -func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { +// deriveTeleportEqual_16 returns whether this and that are equal. +func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -242,15 +258,15 @@ func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { if !ok { return false } - if !(deriveTeleportEqual_13(v, thatv)) { + if !(deriveTeleportEqual_14(v, thatv)) { return false } } return true } -// deriveTeleportEqual_16 returns whether this and that are equal. -func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { +// deriveTeleportEqual_17 returns whether this and that are equal. +func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.JoinMethod == that.JoinMethod && @@ -259,28 +275,38 @@ func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { this.InstallTeleport == that.InstallTeleport && this.SSHDConfig == that.SSHDConfig && this.PublicProxyAddr == that.PublicProxyAddr && - deriveTeleportEqual_19(this.Azure, that.Azure) && + deriveTeleportEqual_21(this.Azure, that.Azure) && this.EnrollMode == that.EnrollMode } -// deriveTeleportEqual_17 returns whether this and that are equal. -func deriveTeleportEqual_17(this, that *types.AWSSSM) bool { +// deriveTeleportEqual_18 returns whether this and that are equal. +func deriveTeleportEqual_18(this, that *types.AWSSSM) bool { return (this == nil && that == nil) || this != nil && that != nil && this.DocumentName == that.DocumentName } -// deriveTeleportEqual_18 returns whether this and that are equal. -func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { +// deriveTeleportEqual_19 returns whether this and that are equal. +func deriveTeleportEqual_19(this, that *types.AccessGraphAWSSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && this.Integration == that.Integration } -// deriveTeleportEqual_19 returns whether this and that are equal. -func deriveTeleportEqual_19(this, that *types.AzureInstallerParams) bool { +// deriveTeleportEqual_20 returns whether this and that are equal. +func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { + return (this == nil && that == nil) || + this != nil && that != nil && + deriveTeleportEqual_14(this.Regions, that.Regions) && + this.SubscriptionID == that.SubscriptionID && + this.UmiClientId == that.UmiClientId && + this.Integration == that.Integration +} + +// deriveTeleportEqual_21 returns whether this and that are equal. +func deriveTeleportEqual_21(this, that *types.AzureInstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ClientID == that.ClientID From 92c19795e2e34610d5172d2d741b8e3f8a33d1ae Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Fri, 8 Nov 2024 10:23:31 -0600 Subject: [PATCH 03/36] More PR feedback and generating protobuf code --- api/proto/teleport/legacy/types/types.proto | 4 +- api/types/types.pb.go | 67 +---- gen/proto/go/accessgraph/v1alpha/azure.pb.go | 260 +++++++++++++------ 3 files changed, 199 insertions(+), 132 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 39fac0a85908a..6c9fee7c0ac01 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8048,7 +8048,7 @@ message AccessGraphAWSSync { // AccessGraphAzureSync is a configuration for Azure Access Graph service poll service. message AccessGraphAzureSync { repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; - string SubscriptionID = 2 [(gogoproto.jsontag) = "regions,omitempty"]; - string UmiClientId = 3 [(gogoproto.jsontag) = "regions,omitempty"]; + string SubscriptionID = 2 [(gogoproto.jsontag) = "subscription_id,omitempty"]; + string UMIClientID = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; } diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 4b10f78f6a5fc..cb2411d3ca520 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -21376,12 +21376,10 @@ var xxx_messageInfo_OktaOptions proto.InternalMessageInfo // AccessGraphSync is a configuration for Access Graph service. type AccessGraphSync struct { // AWS is a configuration for AWS Access Graph service poll service. - AWS []*AccessGraphAWSSync `protobuf:"bytes,1,rep,name=AWS,proto3" json:"aws,omitempty"` - // PollInterval is the frequency at which to poll for AWS resources - PollInterval time.Duration `protobuf:"bytes,2,opt,name=PollInterval,proto3,stdduration" json:"poll_interval,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AWS []*AccessGraphAWSSync `protobuf:"bytes,1,rep,name=AWS,proto3" json:"aws,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessGraphSync) Reset() { *m = AccessGraphSync{} } @@ -21466,8 +21464,8 @@ var xxx_messageInfo_AccessGraphAWSSync proto.InternalMessageInfo // AccessGraphAzureSync is a configuration for Azure Access Graph service poll service. type AccessGraphAzureSync struct { Regions []string `protobuf:"bytes,1,rep,name=Regions,proto3" json:"regions,omitempty"` - SubscriptionID string `protobuf:"bytes,2,opt,name=SubscriptionID,proto3" json:"regions,omitempty"` - UmiClientId string `protobuf:"bytes,3,opt,name=UmiClientId,proto3" json:"regions,omitempty"` + SubscriptionID string `protobuf:"bytes,2,opt,name=SubscriptionID,proto3" json:"subscription_id,omitempty"` + UMIClientID string `protobuf:"bytes,3,opt,name=UMIClientID,proto3" json:"umi_client_id,omitempty"` Integration string `protobuf:"bytes,4,opt,name=Integration,proto3" json:"integration,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -50518,10 +50516,10 @@ func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if len(m.UmiClientId) > 0 { - i -= len(m.UmiClientId) - copy(dAtA[i:], m.UmiClientId) - i = encodeVarintTypes(dAtA, i, uint64(len(m.UmiClientId))) + if len(m.UMIClientID) > 0 { + i -= len(m.UMIClientID) + copy(dAtA[i:], m.UMIClientID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.UMIClientID))) i-- dAtA[i] = 0x1a } @@ -61907,12 +61905,6 @@ func (m *AccessGraphSync) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } - if len(m.Azure) > 0 { - for _, e := range m.Azure { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval) n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { @@ -61963,7 +61955,7 @@ func (m *AccessGraphAzureSync) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - l = len(m.UmiClientId) + l = len(m.UMIClientID) if l > 0 { n += 1 + l + sovTypes(uint64(l)) } @@ -134285,39 +134277,6 @@ func (m *AccessGraphSync) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PollInterval", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.PollInterval, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Azure", wireType) @@ -134620,7 +134579,7 @@ func (m *AccessGraphAzureSync) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UmiClientId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UMIClientID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -134648,7 +134607,7 @@ func (m *AccessGraphAzureSync) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.UmiClientId = string(dAtA[iNdEx:postIndex]) + m.UMIClientID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 3b83614b514ae..53868ae3a4ff5 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -164,20 +164,6 @@ func (x *AzureResource) GetVirtualMachine() *AzureVirtualMachine { return nil } -func (x *AzureResource) GetManagedDatabase() *AzureManagedDatabase { - if x, ok := x.GetResource().(*AzureResource_ManagedDatabase); ok { - return x.ManagedDatabase - } - return nil -} - -func (x *AzureResource) GetAksCluster() *AzureAKSCluster { - if x, ok := x.GetResource().(*AzureResource_AksCluster); ok { - return x.AksCluster - } - return nil -} - type isAzureResource_Resource interface { isAzureResource_Resource() } @@ -202,14 +188,6 @@ type AzureResource_VirtualMachine struct { VirtualMachine *AzureVirtualMachine `protobuf:"bytes,4,opt,name=virtual_machine,json=virtualMachine,proto3,oneof"` } -type AzureResource_ManagedDatabase struct { - ManagedDatabase *AzureManagedDatabase `protobuf:"bytes,5,opt,name=managed_database,json=managedDatabase,proto3,oneof"` -} - -type AzureResource_AksCluster struct { - AksCluster *AzureAKSCluster `protobuf:"bytes,6,opt,name=aks_cluster,json=aksCluster,proto3,oneof"` -} - func (*AzureResource_Principal) isAzureResource_Resource() {} func (*AzureResource_RoleDefinition) isAzureResource_Resource() {} @@ -218,30 +196,16 @@ func (*AzureResource_RoleAssignment) isAzureResource_Resource() {} func (*AzureResource_VirtualMachine) isAzureResource_Resource() {} -func (*AzureResource_ManagedDatabase) isAzureResource_Resource() {} - -func (*AzureResource_AksCluster) isAzureResource_Resource() {} - // AzureVirtualMachine is an Azure virtual machine type AzureVirtualMachine struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // id is the ID of the virtual machine - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // subscription_id is the ID of the subscription to which the virtual machine belongs - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - // last_sync_time is when the virtual machine was last fetched from Azure - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - // name is the given name of the virtual machine - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - // resource_group is the name of the resource group to which the virtual machine belongs - ResourceGroup string `protobuf:"bytes,5,opt,name=resource_group,json=resourceGroup,proto3" json:"resource_group,omitempty"` - // tags are a collection of arbitrary key-values applied to the virtual machine - Tags map[string]string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // location is the geographical location of the Virtual Machine - Location string `protobuf:"bytes,7,opt,name=location,proto3" json:"location,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } func (x *AzureVirtualMachine) Reset() { @@ -316,42 +280,40 @@ func (x *AzureVirtualMachine) GetTags() map[string]string { return nil } -func (x *AzureVirtualMachine) GetLocation() string { +func (x *AzureManagedDatabase) GetName() string { if x != nil { - return x.Location + return x.Name } return "" } -// AzureIdentity is a Graph API object identity -type AzureIdentity struct { +// AzureAKSCluster is an AKS cluster +type AzureAKSCluster struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // sign_in_type is the type of identity used when signing in, e.g. "emailAddress" or "userName" - SignInType string `protobuf:"bytes,1,opt,name=sign_in_type,json=signInType,proto3" json:"sign_in_type,omitempty"` - // issuer is the issuer of the identity, such as a domain name like "goteleport.com" - Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` - // issuer_assigned_id unique identifier assigned to the user by the issuer - IssuerAssignedId string `protobuf:"bytes,3,opt,name=issuer_assigned_id,json=issuerAssignedId,proto3" json:"issuer_assigned_id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } -func (x *AzureIdentity) Reset() { - *x = AzureIdentity{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] +func (x *AzureAKSCluster) Reset() { + *x = AzureAKSCluster{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzureIdentity) String() string { +func (x *AzureAKSCluster) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzureIdentity) ProtoMessage() {} +func (*AzureAKSCluster) ProtoMessage() {} -func (x *AzureIdentity) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] +func (x *AzureAKSCluster) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -362,33 +324,40 @@ func (x *AzureIdentity) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzureIdentity.ProtoReflect.Descriptor instead. -func (*AzureIdentity) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} +// Deprecated: Use AzureAKSCluster.ProtoReflect.Descriptor instead. +func (*AzureAKSCluster) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } -func (x *AzureIdentity) GetSignInType() string { +func (x *AzureAKSCluster) GetId() string { if x != nil { - return x.SignInType + return x.Id } return "" } -func (x *AzureIdentity) GetIssuer() string { +func (x *AzureAKSCluster) GetSubscriptionId() string { if x != nil { - return x.Issuer + return x.SubscriptionId } return "" } -func (x *AzureIdentity) GetIssuerAssignedId() string { +func (x *AzureAKSCluster) GetLastSyncTime() *timestamppb.Timestamp { if x != nil { - return x.IssuerAssignedId + return x.LastSyncTime + } + return nil +} + +func (x *AzureAKSCluster) GetName() string { + if x != nil { + return x.Name } return "" } -// AzurePrincipal is a Graph API principal (user, group, service principal) +// AzurePrincipal is an Azure principal (user, group, service principal) type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -412,7 +381,7 @@ type AzurePrincipal struct { func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -424,7 +393,7 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -437,7 +406,7 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzurePrincipal) GetId() string { @@ -513,7 +482,7 @@ type AzureRoleAssignment struct { func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -525,7 +494,7 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -538,6 +507,7 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleAssignment) GetId() string { @@ -599,10 +569,12 @@ type AzureRoleDefinition struct { SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Permissions []*AzurePermission `protobuf:"bytes,5,rep,name=permissions,proto3" json:"permissions,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -614,6 +586,7 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -626,6 +599,7 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } func (x *AzureRoleDefinition) GetId() string { @@ -656,6 +630,7 @@ func (x *AzureRoleDefinition) GetName() string { return "" } +func (x *AzureRoleDefinition) GetPermissions() []*AzurePermission { if x != nil { return x.Permissions } @@ -677,20 +652,28 @@ func (x *AzureRoleDefinition) GetType() string { } // AzurePermission defines the actions and not (disallowed) actions for a role definition +type AzurePermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } +func (x *AzurePermission) Reset() { + *x = AzurePermission{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } +func (x *AzurePermission) String() string { return protoimpl.X.MessageStringOf(x) } +func (*AzurePermission) ProtoMessage() {} +func (x *AzurePermission) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -701,14 +684,19 @@ func (x *AzureRoleDefinition) GetType() string { return mi.MessageOf(x) } +// Deprecated: Use AzurePermission.ProtoReflect.Descriptor instead. +func (*AzurePermission) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{8} } +func (x *AzurePermission) GetActions() []string { if x != nil { return x.Actions } return nil } +func (x *AzurePermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -742,6 +730,8 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x80, + 0x04, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -762,6 +752,103 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x12, 0x56, 0x0a, 0x10, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, + 0x61, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6b, 0x73, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, + 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, + 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0xa0, 0x01, 0x0a, 0x0f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, + 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, + 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, + 0x66, 0x22, 0xf7, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xec, 0x01, 0x0a, 0x13, + 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x0f, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, + 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -776,16 +863,39 @@ func file_accessgraph_v1alpha_azure_proto_rawDescGZIP() []byte { return file_accessgraph_v1alpha_azure_proto_rawDescData } -var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine + (*AzureManagedDatabase)(nil), // 3: accessgraph.v1alpha.AzureManagedDatabase + (*AzureAKSCluster)(nil), // 4: accessgraph.v1alpha.AzureAKSCluster + (*AzurePrincipal)(nil), // 5: accessgraph.v1alpha.AzurePrincipal + (*AzureRoleAssignment)(nil), // 6: accessgraph.v1alpha.AzureRoleAssignment + (*AzureRoleDefinition)(nil), // 7: accessgraph.v1alpha.AzureRoleDefinition + (*AzurePermission)(nil), // 8: accessgraph.v1alpha.AzurePermission (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource + 5, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal + 7, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition + 6, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine + 3, // 5: accessgraph.v1alpha.AzureResource.managed_database:type_name -> accessgraph.v1alpha.AzureManagedDatabase + 4, // 6: accessgraph.v1alpha.AzureResource.aks_cluster:type_name -> accessgraph.v1alpha.AzureAKSCluster + 9, // 7: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 8: accessgraph.v1alpha.AzureManagedDatabase.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 9: accessgraph.v1alpha.AzureAKSCluster.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 10: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 11: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 12: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 13: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzurePermission + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -798,8 +908,6 @@ func file_accessgraph_v1alpha_azure_proto_init() { (*AzureResource_RoleDefinition)(nil), (*AzureResource_RoleAssignment)(nil), (*AzureResource_VirtualMachine)(nil), - (*AzureResource_ManagedDatabase)(nil), - (*AzureResource_AksCluster)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -807,7 +915,7 @@ func file_accessgraph_v1alpha_azure_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accessgraph_v1alpha_azure_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, From abaeebb3255c23ea46b8177cd00f885e754deb60 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Fri, 8 Nov 2024 15:36:59 -0600 Subject: [PATCH 04/36] Make derive --- api/types/discoveryconfig/derived.gen.go | 109 +++++++++-------------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index c10fbf8b83f1c..f92f2f40ba9c9 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -116,8 +116,7 @@ func deriveTeleportEqual_5(this, that []types.KubernetesMatcher) bool { func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_12(this.AWS, that.AWS) && - this.PollInterval == that.PollInterval + deriveTeleportEqual_12(this.AWS, that.AWS) } // deriveTeleportEqual_7 returns whether this and that are equal. @@ -144,12 +143,12 @@ func deriveTeleportEqual_7(this, that map[string]string) bool { func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && - deriveTeleportEqual_16(this.Tags, that.Tags) && - deriveTeleportEqual_17(this.Params, that.Params) && - deriveTeleportEqual_18(this.SSM, that.SSM) && + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_15(this.Tags, that.Tags) && + deriveTeleportEqual_16(this.Params, that.Params) && + deriveTeleportEqual_17(this.SSM, that.SSM) && this.Integration == that.Integration && this.KubeAppDiscovery == that.KubeAppDiscovery && this.SetupAccessForARN == that.SetupAccessForARN @@ -159,34 +158,34 @@ func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { func deriveTeleportEqual_9(this, that *types.AzureMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Subscriptions, that.Subscriptions) && - deriveTeleportEqual_14(this.ResourceGroups, that.ResourceGroups) && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_16(this.ResourceTags, that.ResourceTags) && - deriveTeleportEqual_17(this.Params, that.Params) + deriveTeleportEqual_13(this.Subscriptions, that.Subscriptions) && + deriveTeleportEqual_13(this.ResourceGroups, that.ResourceGroups) && + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.ResourceTags, that.ResourceTags) && + deriveTeleportEqual_16(this.Params, that.Params) } // deriveTeleportEqual_10 returns whether this and that are equal. func deriveTeleportEqual_10(this, that *types.GCPMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Locations, that.Locations) && - deriveTeleportEqual_16(this.Tags, that.Tags) && - deriveTeleportEqual_14(this.ProjectIDs, that.ProjectIDs) && - deriveTeleportEqual_14(this.ServiceAccounts, that.ServiceAccounts) && - deriveTeleportEqual_17(this.Params, that.Params) && - deriveTeleportEqual_16(this.Labels, that.Labels) + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Locations, that.Locations) && + deriveTeleportEqual_15(this.Tags, that.Tags) && + deriveTeleportEqual_13(this.ProjectIDs, that.ProjectIDs) && + deriveTeleportEqual_13(this.ServiceAccounts, that.ServiceAccounts) && + deriveTeleportEqual_16(this.Params, that.Params) && + deriveTeleportEqual_15(this.Labels, that.Labels) } // deriveTeleportEqual_11 returns whether this and that are equal. func deriveTeleportEqual_11(this, that *types.KubernetesMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Namespaces, that.Namespaces) && - deriveTeleportEqual_16(this.Labels, that.Labels) + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Namespaces, that.Namespaces) && + deriveTeleportEqual_15(this.Labels, that.Labels) } // deriveTeleportEqual_12 returns whether this and that are equal. @@ -198,7 +197,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { return false } for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_19(this[i], that[i])) { + if !(deriveTeleportEqual_18(this[i], that[i])) { return false } } @@ -206,23 +205,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { } // deriveTeleportEqual_13 returns whether this and that are equal. -func deriveTeleportEqual_13(this, that []*types.AccessGraphAzureSync) bool { - if this == nil || that == nil { - return this == nil && that == nil - } - if len(this) != len(that) { - return false - } - for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_20(this[i], that[i])) { - return false - } - } - return true -} - -// deriveTeleportEqual_14 returns whether this and that are equal. -func deriveTeleportEqual_14(this, that []string) bool { +func deriveTeleportEqual_13(this, that []string) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -237,16 +220,16 @@ func deriveTeleportEqual_14(this, that []string) bool { return true } -// deriveTeleportEqual_15 returns whether this and that are equal. -func deriveTeleportEqual_15(this, that *types.AssumeRole) bool { +// deriveTeleportEqual_14 returns whether this and that are equal. +func deriveTeleportEqual_14(this, that *types.AssumeRole) bool { return (this == nil && that == nil) || this != nil && that != nil && this.RoleARN == that.RoleARN && this.ExternalID == that.ExternalID } -// deriveTeleportEqual_16 returns whether this and that are equal. -func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { +// deriveTeleportEqual_15 returns whether this and that are equal. +func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -258,15 +241,15 @@ func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { if !ok { return false } - if !(deriveTeleportEqual_14(v, thatv)) { + if !(deriveTeleportEqual_13(v, thatv)) { return false } } return true } -// deriveTeleportEqual_17 returns whether this and that are equal. -func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { +// deriveTeleportEqual_16 returns whether this and that are equal. +func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.JoinMethod == that.JoinMethod && @@ -275,38 +258,28 @@ func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { this.InstallTeleport == that.InstallTeleport && this.SSHDConfig == that.SSHDConfig && this.PublicProxyAddr == that.PublicProxyAddr && - deriveTeleportEqual_21(this.Azure, that.Azure) && + deriveTeleportEqual_19(this.Azure, that.Azure) && this.EnrollMode == that.EnrollMode } -// deriveTeleportEqual_18 returns whether this and that are equal. -func deriveTeleportEqual_18(this, that *types.AWSSSM) bool { +// deriveTeleportEqual_17 returns whether this and that are equal. +func deriveTeleportEqual_17(this, that *types.AWSSSM) bool { return (this == nil && that == nil) || this != nil && that != nil && this.DocumentName == that.DocumentName } -// deriveTeleportEqual_19 returns whether this and that are equal. -func deriveTeleportEqual_19(this, that *types.AccessGraphAWSSync) bool { - return (this == nil && that == nil) || - this != nil && that != nil && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && - this.Integration == that.Integration -} - -// deriveTeleportEqual_20 returns whether this and that are equal. -func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { +// deriveTeleportEqual_18 returns whether this and that are equal. +func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Regions, that.Regions) && - this.SubscriptionID == that.SubscriptionID && - this.UmiClientId == that.UmiClientId && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && this.Integration == that.Integration } -// deriveTeleportEqual_21 returns whether this and that are equal. -func deriveTeleportEqual_21(this, that *types.AzureInstallerParams) bool { +// deriveTeleportEqual_19 returns whether this and that are equal. +func deriveTeleportEqual_19(this, that *types.AzureInstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ClientID == that.ClientID From 9e66e46ce9e8832acee485ecf2af4cfd04fa2a35 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 14:21:33 -0600 Subject: [PATCH 05/36] Adding identities field to principals, condition to role assignments, and role name to role definitions --- gen/proto/go/accessgraph/v1alpha/azure.pb.go | 417 ++++++++----------- 1 file changed, 168 insertions(+), 249 deletions(-) diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 53868ae3a4ff5..9f15efe5fe416 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -280,15 +280,8 @@ func (x *AzureVirtualMachine) GetTags() map[string]string { return nil } -func (x *AzureManagedDatabase) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -// AzureAKSCluster is an AKS cluster -type AzureAKSCluster struct { +// AzurePrincipal is an Azure principal (user, group, service principal) +type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -296,92 +289,13 @@ type AzureAKSCluster struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *AzureAKSCluster) Reset() { - *x = AzureAKSCluster{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AzureAKSCluster) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AzureAKSCluster) ProtoMessage() {} - -func (x *AzureAKSCluster) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AzureAKSCluster.ProtoReflect.Descriptor instead. -func (*AzureAKSCluster) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} -} - -func (x *AzureAKSCluster) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *AzureAKSCluster) GetSubscriptionId() string { - if x != nil { - return x.SubscriptionId - } - return "" -} - -func (x *AzureAKSCluster) GetLastSyncTime() *timestamppb.Timestamp { - if x != nil { - return x.LastSyncTime - } - return nil -} - -func (x *AzureAKSCluster) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -// AzurePrincipal is an Azure principal (user, group, service principal) -type AzurePrincipal struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // id is the ID of the principal - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // subscription_id is the ID of the subscription to which the principal belongs - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - // last_sync_time is when the principal was last fetched from Azure - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - // display_name is the given name for the principal, e.g. a user's first+last name - DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - // member_of lists the groups and directories the principal is assigned to - MemberOf []string `protobuf:"bytes,5,rep,name=member_of,json=memberOf,proto3" json:"member_of,omitempty"` - // identities lists the identities that can be used to sign in to the account - Identities []*AzureIdentity `protobuf:"bytes,6,rep,name=identities,proto3" json:"identities,omitempty"` - // object_type defines the type of principal, e.g. "user" or "group" - ObjectType string `protobuf:"bytes,7,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` + DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + MemberOf []string `protobuf:"bytes,5,rep,name=member_of,json=memberOf,proto3" json:"member_of,omitempty"` } func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -393,7 +307,7 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -406,7 +320,7 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} } func (x *AzurePrincipal) GetId() string { @@ -451,6 +365,13 @@ func (x *AzurePrincipal) GetIdentities() []*AzureIdentity { return nil } +func (x *AzurePrincipal) GetIdentities() []*AzureIdentity { + if x != nil { + return x.Identities + } + return nil +} + func (x *AzurePrincipal) GetObjectType() string { if x != nil { return x.ObjectType @@ -464,25 +385,17 @@ type AzureRoleAssignment struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // id is the ID of the role assignment - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // subscription_id is the ID of the subscription to which the role assignment belongs - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - // last_sync_time is when the role assignment was last fetched from Azure - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - // principal_id is the ID of the principal being assigned a role - PrincipalId string `protobuf:"bytes,4,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` - // role_definition_id is the ID of the role definition assigned to the principal - RoleDefinitionId string `protobuf:"bytes,5,opt,name=role_definition_id,json=roleDefinitionId,proto3" json:"role_definition_id,omitempty"` - // scope constrains which resources the assignment applies to - Scope string `protobuf:"bytes,6,opt,name=scope,proto3" json:"scope,omitempty"` - // condition further which resources the assignment applies to - Condition string `protobuf:"bytes,7,opt,name=condition,proto3" json:"condition,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + PrincipalId string `protobuf:"bytes,4,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` + RoleDefinitionId string `protobuf:"bytes,5,opt,name=role_definition_id,json=roleDefinitionId,proto3" json:"role_definition_id,omitempty"` + Scope string `protobuf:"bytes,6,opt,name=scope,proto3" json:"scope,omitempty"` } func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -494,7 +407,7 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -507,7 +420,7 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } func (x *AzureRoleAssignment) GetId() string { @@ -565,16 +478,18 @@ type AzureRoleDefinition struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Permissions []*AzurePermission `protobuf:"bytes,5,rep,name=permissions,proto3" json:"permissions,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + AssignableScopes []string `protobuf:"bytes,6,rep,name=assignable_scopes,json=assignableScopes,proto3" json:"assignable_scopes,omitempty"` + Permissions []*AzureRBACPermission `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -586,7 +501,7 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -599,7 +514,7 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzureRoleDefinition) GetId() string { @@ -651,17 +566,26 @@ func (x *AzureRoleDefinition) GetType() string { return "" } +func (x *AzureRoleDefinition) GetRoleName() string { + if x != nil { + return x.RoleName + } + return "" +} + // AzurePermission defines the actions and not (disallowed) actions for a role definition type AzurePermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + Actions []string `protobuf:"bytes,4,rep,name=actions,proto3" json:"actions,omitempty"` + NotActions []string `protobuf:"bytes,5,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` } -func (x *AzurePermission) Reset() { - *x = AzurePermission{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] +func (x *AzureRBACPermission) Reset() { + *x = AzureRBACPermission{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -672,8 +596,8 @@ func (x *AzurePermission) String() string { func (*AzurePermission) ProtoMessage() {} -func (x *AzurePermission) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] +func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -684,9 +608,9 @@ func (x *AzurePermission) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzurePermission.ProtoReflect.Descriptor instead. -func (*AzurePermission) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{8} +// Deprecated: Use AzureRBACPermission.ProtoReflect.Descriptor instead. +func (*AzureRBACPermission) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzurePermission) GetActions() []string { @@ -717,6 +641,20 @@ func (x *AzureRBACPermission) GetNotDataActions() []string { return nil } +func (x *AzureRBACPermission) GetDataActions() []string { + if x != nil { + return x.DataActions + } + return nil +} + +func (x *AzureRBACPermission) GetNotDataActions() []string { + if x != nil { + return x.NotDataActions + } + return nil +} + var File_accessgraph_v1alpha_azure_proto protoreflect.FileDescriptor var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ @@ -752,103 +690,88 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x12, 0x56, 0x0a, 0x10, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, - 0x61, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6b, 0x73, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, - 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, - 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0xa0, 0x01, 0x0a, 0x0f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, - 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, - 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, - 0x66, 0x22, 0xf7, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, - 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, - 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xec, 0x01, 0x0a, 0x13, - 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x0f, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, - 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x69, 0x6e, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x22, 0xcc, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, + 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x22, 0xf7, 0x01, + 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, + 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xbf, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, + 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, + 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, + 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x13, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, + 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -863,39 +786,35 @@ func file_accessgraph_v1alpha_azure_proto_rawDescGZIP() []byte { return file_accessgraph_v1alpha_azure_proto_rawDescData } -var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine - (*AzureManagedDatabase)(nil), // 3: accessgraph.v1alpha.AzureManagedDatabase - (*AzureAKSCluster)(nil), // 4: accessgraph.v1alpha.AzureAKSCluster - (*AzurePrincipal)(nil), // 5: accessgraph.v1alpha.AzurePrincipal - (*AzureRoleAssignment)(nil), // 6: accessgraph.v1alpha.AzureRoleAssignment - (*AzureRoleDefinition)(nil), // 7: accessgraph.v1alpha.AzureRoleDefinition - (*AzurePermission)(nil), // 8: accessgraph.v1alpha.AzurePermission - (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp + (*AzurePrincipal)(nil), // 3: accessgraph.v1alpha.AzurePrincipal + (*AzureRoleAssignment)(nil), // 4: accessgraph.v1alpha.AzureRoleAssignment + (*AzureRoleDefinition)(nil), // 5: accessgraph.v1alpha.AzureRoleDefinition + (*AzureRBACPermission)(nil), // 6: accessgraph.v1alpha.AzureRBACPermission + nil, // 7: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry + (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource - 5, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal - 7, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition - 6, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment + 3, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal + 5, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition + 4, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine - 3, // 5: accessgraph.v1alpha.AzureResource.managed_database:type_name -> accessgraph.v1alpha.AzureManagedDatabase - 4, // 6: accessgraph.v1alpha.AzureResource.aks_cluster:type_name -> accessgraph.v1alpha.AzureAKSCluster - 9, // 7: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 8: accessgraph.v1alpha.AzureManagedDatabase.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 9: accessgraph.v1alpha.AzureAKSCluster.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 10: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 11: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 12: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 13: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzurePermission - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 8, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp + 7, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry + 8, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 8: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 9: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp + 6, // 10: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -915,7 +834,7 @@ func file_accessgraph_v1alpha_azure_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accessgraph_v1alpha_azure_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, From 6cf5e402b744eb3173240df15a24dca8769ccc22 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 14:30:44 -0600 Subject: [PATCH 06/36] Rebase conflicts --- api/proto/teleport/legacy/types/types.proto | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 6c9fee7c0ac01..fcde215c22213 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -6708,11 +6708,6 @@ message PluginEntraIDSyncSettings { // This field is populated on a best-effort basis for legacy plugins but mandatory for plugins created after its introduction. // For existing plugins, it is filled in using the Entra integration when utilized. string tenant_id = 4; - - // entra_app_id refers to the Entra Application ID that supports the SSO for "sso_connector_id". - // This field is populated on a best-effort basis for legacy plugins but mandatory for plugins created after its introduction. - // For existing plugins, it is filled in using the entity descriptor url when utilized. - string entra_app_id = 5; } // EntraIDCredentialsSource defines the credentials source for Entra ID. @@ -8027,12 +8022,6 @@ message AccessGraphSync { repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; // Azure is a configuration for the Azure Access Graph service poll service. repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "azure,omitempty"]; - // PollInterval is the frequency at which to poll for AWS resources - google.protobuf.Duration PollInterval = 2 [ - (gogoproto.jsontag) = "poll_interval,omitempty", - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true - ]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. @@ -8049,6 +8038,6 @@ message AccessGraphAWSSync { message AccessGraphAzureSync { repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; string SubscriptionID = 2 [(gogoproto.jsontag) = "subscription_id,omitempty"]; - string UMIClientID = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; + string UmiClientId = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; } From 081a526355712975924cabf64eb57f13e48941fd Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 14:34:54 -0600 Subject: [PATCH 07/36] Did not fully fetch from origin/master when rebasing --- api/proto/teleport/legacy/types/types.proto | 11 ++ api/types/discoveryconfig/derived.gen.go | 110 ++++++++++++-------- 2 files changed, 80 insertions(+), 41 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index fcde215c22213..5a89900001243 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -6708,6 +6708,11 @@ message PluginEntraIDSyncSettings { // This field is populated on a best-effort basis for legacy plugins but mandatory for plugins created after its introduction. // For existing plugins, it is filled in using the Entra integration when utilized. string tenant_id = 4; + + // entra_app_id refers to the Entra Application ID that supports the SSO for "sso_connector_id". + // This field is populated on a best-effort basis for legacy plugins but mandatory for plugins created after its introduction. + // For existing plugins, it is filled in using the entity descriptor url when utilized. + string entra_app_id = 5; } // EntraIDCredentialsSource defines the credentials source for Entra ID. @@ -8022,6 +8027,12 @@ message AccessGraphSync { repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; // Azure is a configuration for the Azure Access Graph service poll service. repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "azure,omitempty"]; + // PollInterval is the frequency at which to poll for AWS resources + google.protobuf.Duration PollInterval = 3 [ + (gogoproto.jsontag) = "poll_interval,omitempty", + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index f92f2f40ba9c9..77bd2004e34ca 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -116,7 +116,9 @@ func deriveTeleportEqual_5(this, that []types.KubernetesMatcher) bool { func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_12(this.AWS, that.AWS) + deriveTeleportEqual_12(this.AWS, that.AWS) && + deriveTeleportEqual_13(this.Azure, that.Azure) && + this.PollInterval == that.PollInterval } // deriveTeleportEqual_7 returns whether this and that are equal. @@ -143,12 +145,12 @@ func deriveTeleportEqual_7(this, that map[string]string) bool { func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_17(this.SSM, that.SSM) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_18(this.SSM, that.SSM) && this.Integration == that.Integration && this.KubeAppDiscovery == that.KubeAppDiscovery && this.SetupAccessForARN == that.SetupAccessForARN @@ -158,34 +160,34 @@ func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { func deriveTeleportEqual_9(this, that *types.AzureMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Subscriptions, that.Subscriptions) && - deriveTeleportEqual_13(this.ResourceGroups, that.ResourceGroups) && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.ResourceTags, that.ResourceTags) && - deriveTeleportEqual_16(this.Params, that.Params) + deriveTeleportEqual_14(this.Subscriptions, that.Subscriptions) && + deriveTeleportEqual_14(this.ResourceGroups, that.ResourceGroups) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_16(this.ResourceTags, that.ResourceTags) && + deriveTeleportEqual_17(this.Params, that.Params) } // deriveTeleportEqual_10 returns whether this and that are equal. func deriveTeleportEqual_10(this, that *types.GCPMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Locations, that.Locations) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_13(this.ProjectIDs, that.ProjectIDs) && - deriveTeleportEqual_13(this.ServiceAccounts, that.ServiceAccounts) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Locations, that.Locations) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_14(this.ProjectIDs, that.ProjectIDs) && + deriveTeleportEqual_14(this.ServiceAccounts, that.ServiceAccounts) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_11 returns whether this and that are equal. func deriveTeleportEqual_11(this, that *types.KubernetesMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Namespaces, that.Namespaces) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Namespaces, that.Namespaces) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_12 returns whether this and that are equal. @@ -197,7 +199,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { return false } for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_18(this[i], that[i])) { + if !(deriveTeleportEqual_19(this[i], that[i])) { return false } } @@ -205,7 +207,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { } // deriveTeleportEqual_13 returns whether this and that are equal. -func deriveTeleportEqual_13(this, that []string) bool { +func deriveTeleportEqual_13(this, that []*types.AccessGraphAzureSync) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -213,7 +215,7 @@ func deriveTeleportEqual_13(this, that []string) bool { return false } for i := 0; i < len(this); i++ { - if !(this[i] == that[i]) { + if !(deriveTeleportEqual_20(this[i], that[i])) { return false } } @@ -221,15 +223,31 @@ func deriveTeleportEqual_13(this, that []string) bool { } // deriveTeleportEqual_14 returns whether this and that are equal. -func deriveTeleportEqual_14(this, that *types.AssumeRole) bool { +func deriveTeleportEqual_14(this, that []string) bool { + if this == nil || that == nil { + return this == nil && that == nil + } + if len(this) != len(that) { + return false + } + for i := 0; i < len(this); i++ { + if !(this[i] == that[i]) { + return false + } + } + return true +} + +// deriveTeleportEqual_15 returns whether this and that are equal. +func deriveTeleportEqual_15(this, that *types.AssumeRole) bool { return (this == nil && that == nil) || this != nil && that != nil && this.RoleARN == that.RoleARN && this.ExternalID == that.ExternalID } -// deriveTeleportEqual_15 returns whether this and that are equal. -func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { +// deriveTeleportEqual_16 returns whether this and that are equal. +func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -241,15 +259,15 @@ func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { if !ok { return false } - if !(deriveTeleportEqual_13(v, thatv)) { + if !(deriveTeleportEqual_14(v, thatv)) { return false } } return true } -// deriveTeleportEqual_16 returns whether this and that are equal. -func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { +// deriveTeleportEqual_17 returns whether this and that are equal. +func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.JoinMethod == that.JoinMethod && @@ -258,28 +276,38 @@ func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { this.InstallTeleport == that.InstallTeleport && this.SSHDConfig == that.SSHDConfig && this.PublicProxyAddr == that.PublicProxyAddr && - deriveTeleportEqual_19(this.Azure, that.Azure) && + deriveTeleportEqual_21(this.Azure, that.Azure) && this.EnrollMode == that.EnrollMode } -// deriveTeleportEqual_17 returns whether this and that are equal. -func deriveTeleportEqual_17(this, that *types.AWSSSM) bool { +// deriveTeleportEqual_18 returns whether this and that are equal. +func deriveTeleportEqual_18(this, that *types.AWSSSM) bool { return (this == nil && that == nil) || this != nil && that != nil && this.DocumentName == that.DocumentName } -// deriveTeleportEqual_18 returns whether this and that are equal. -func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { +// deriveTeleportEqual_19 returns whether this and that are equal. +func deriveTeleportEqual_19(this, that *types.AccessGraphAWSSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && this.Integration == that.Integration } -// deriveTeleportEqual_19 returns whether this and that are equal. -func deriveTeleportEqual_19(this, that *types.AzureInstallerParams) bool { +// deriveTeleportEqual_20 returns whether this and that are equal. +func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { + return (this == nil && that == nil) || + this != nil && that != nil && + deriveTeleportEqual_14(this.Regions, that.Regions) && + this.SubscriptionID == that.SubscriptionID && + this.UmiClientId == that.UmiClientId && + this.Integration == that.Integration +} + +// deriveTeleportEqual_21 returns whether this and that are equal. +func deriveTeleportEqual_21(this, that *types.AzureInstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ClientID == that.ClientID From c51afd18c164a28238830e217a1509da644929d7 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 14:36:51 -0600 Subject: [PATCH 08/36] Removing azure config field and keeping poll_interval as-is --- api/proto/teleport/legacy/types/types.proto | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 5a89900001243..4d0544d59eacf 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8025,10 +8025,8 @@ message OktaOptions { message AccessGraphSync { // AWS is a configuration for AWS Access Graph service poll service. repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; - // Azure is a configuration for the Azure Access Graph service poll service. - repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "azure,omitempty"]; // PollInterval is the frequency at which to poll for AWS resources - google.protobuf.Duration PollInterval = 3 [ + google.protobuf.Duration PollInterval = 2 [ (gogoproto.jsontag) = "poll_interval,omitempty", (gogoproto.nullable) = false, (gogoproto.stdduration) = true From 3faf1f133c36a00e0ec1cd3ad77be527aad31ddb Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 17:33:26 -0600 Subject: [PATCH 09/36] Correct from parent branch --- api/proto/teleport/legacy/types/types.proto | 2 +- api/types/discoveryconfig/derived.gen.go | 107 ++++++++------------ 2 files changed, 41 insertions(+), 68 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 4d0544d59eacf..12cf67c474972 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8047,6 +8047,6 @@ message AccessGraphAWSSync { message AccessGraphAzureSync { repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; string SubscriptionID = 2 [(gogoproto.jsontag) = "subscription_id,omitempty"]; - string UmiClientId = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; + string UMIClientID = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; } diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index 77bd2004e34ca..9053fdd312473 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -117,7 +117,6 @@ func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && deriveTeleportEqual_12(this.AWS, that.AWS) && - deriveTeleportEqual_13(this.Azure, that.Azure) && this.PollInterval == that.PollInterval } @@ -145,12 +144,12 @@ func deriveTeleportEqual_7(this, that map[string]string) bool { func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && - deriveTeleportEqual_16(this.Tags, that.Tags) && - deriveTeleportEqual_17(this.Params, that.Params) && - deriveTeleportEqual_18(this.SSM, that.SSM) && + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_15(this.Tags, that.Tags) && + deriveTeleportEqual_16(this.Params, that.Params) && + deriveTeleportEqual_17(this.SSM, that.SSM) && this.Integration == that.Integration && this.KubeAppDiscovery == that.KubeAppDiscovery && this.SetupAccessForARN == that.SetupAccessForARN @@ -160,34 +159,34 @@ func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { func deriveTeleportEqual_9(this, that *types.AzureMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Subscriptions, that.Subscriptions) && - deriveTeleportEqual_14(this.ResourceGroups, that.ResourceGroups) && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_16(this.ResourceTags, that.ResourceTags) && - deriveTeleportEqual_17(this.Params, that.Params) + deriveTeleportEqual_13(this.Subscriptions, that.Subscriptions) && + deriveTeleportEqual_13(this.ResourceGroups, that.ResourceGroups) && + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.ResourceTags, that.ResourceTags) && + deriveTeleportEqual_16(this.Params, that.Params) } // deriveTeleportEqual_10 returns whether this and that are equal. func deriveTeleportEqual_10(this, that *types.GCPMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Locations, that.Locations) && - deriveTeleportEqual_16(this.Tags, that.Tags) && - deriveTeleportEqual_14(this.ProjectIDs, that.ProjectIDs) && - deriveTeleportEqual_14(this.ServiceAccounts, that.ServiceAccounts) && - deriveTeleportEqual_17(this.Params, that.Params) && - deriveTeleportEqual_16(this.Labels, that.Labels) + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Locations, that.Locations) && + deriveTeleportEqual_15(this.Tags, that.Tags) && + deriveTeleportEqual_13(this.ProjectIDs, that.ProjectIDs) && + deriveTeleportEqual_13(this.ServiceAccounts, that.ServiceAccounts) && + deriveTeleportEqual_16(this.Params, that.Params) && + deriveTeleportEqual_15(this.Labels, that.Labels) } // deriveTeleportEqual_11 returns whether this and that are equal. func deriveTeleportEqual_11(this, that *types.KubernetesMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Types, that.Types) && - deriveTeleportEqual_14(this.Namespaces, that.Namespaces) && - deriveTeleportEqual_16(this.Labels, that.Labels) + deriveTeleportEqual_13(this.Types, that.Types) && + deriveTeleportEqual_13(this.Namespaces, that.Namespaces) && + deriveTeleportEqual_15(this.Labels, that.Labels) } // deriveTeleportEqual_12 returns whether this and that are equal. @@ -199,7 +198,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { return false } for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_19(this[i], that[i])) { + if !(deriveTeleportEqual_18(this[i], that[i])) { return false } } @@ -207,23 +206,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { } // deriveTeleportEqual_13 returns whether this and that are equal. -func deriveTeleportEqual_13(this, that []*types.AccessGraphAzureSync) bool { - if this == nil || that == nil { - return this == nil && that == nil - } - if len(this) != len(that) { - return false - } - for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_20(this[i], that[i])) { - return false - } - } - return true -} - -// deriveTeleportEqual_14 returns whether this and that are equal. -func deriveTeleportEqual_14(this, that []string) bool { +func deriveTeleportEqual_13(this, that []string) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -238,16 +221,16 @@ func deriveTeleportEqual_14(this, that []string) bool { return true } -// deriveTeleportEqual_15 returns whether this and that are equal. -func deriveTeleportEqual_15(this, that *types.AssumeRole) bool { +// deriveTeleportEqual_14 returns whether this and that are equal. +func deriveTeleportEqual_14(this, that *types.AssumeRole) bool { return (this == nil && that == nil) || this != nil && that != nil && this.RoleARN == that.RoleARN && this.ExternalID == that.ExternalID } -// deriveTeleportEqual_16 returns whether this and that are equal. -func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { +// deriveTeleportEqual_15 returns whether this and that are equal. +func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -259,15 +242,15 @@ func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { if !ok { return false } - if !(deriveTeleportEqual_14(v, thatv)) { + if !(deriveTeleportEqual_13(v, thatv)) { return false } } return true } -// deriveTeleportEqual_17 returns whether this and that are equal. -func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { +// deriveTeleportEqual_16 returns whether this and that are equal. +func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.JoinMethod == that.JoinMethod && @@ -276,38 +259,28 @@ func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { this.InstallTeleport == that.InstallTeleport && this.SSHDConfig == that.SSHDConfig && this.PublicProxyAddr == that.PublicProxyAddr && - deriveTeleportEqual_21(this.Azure, that.Azure) && + deriveTeleportEqual_19(this.Azure, that.Azure) && this.EnrollMode == that.EnrollMode } -// deriveTeleportEqual_18 returns whether this and that are equal. -func deriveTeleportEqual_18(this, that *types.AWSSSM) bool { +// deriveTeleportEqual_17 returns whether this and that are equal. +func deriveTeleportEqual_17(this, that *types.AWSSSM) bool { return (this == nil && that == nil) || this != nil && that != nil && this.DocumentName == that.DocumentName } -// deriveTeleportEqual_19 returns whether this and that are equal. -func deriveTeleportEqual_19(this, that *types.AccessGraphAWSSync) bool { - return (this == nil && that == nil) || - this != nil && that != nil && - deriveTeleportEqual_14(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && - this.Integration == that.Integration -} - -// deriveTeleportEqual_20 returns whether this and that are equal. -func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { +// deriveTeleportEqual_18 returns whether this and that are equal. +func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_14(this.Regions, that.Regions) && - this.SubscriptionID == that.SubscriptionID && - this.UmiClientId == that.UmiClientId && + deriveTeleportEqual_13(this.Regions, that.Regions) && + deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && this.Integration == that.Integration } -// deriveTeleportEqual_21 returns whether this and that are equal. -func deriveTeleportEqual_21(this, that *types.AzureInstallerParams) bool { +// deriveTeleportEqual_19 returns whether this and that are equal. +func deriveTeleportEqual_19(this, that *types.AzureInstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ClientID == that.ClientID From 61f3335eab9172d59e982eb1573c673ba809e68b Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 7 Nov 2024 14:16:51 -0600 Subject: [PATCH 10/36] Adding Azure integration gRPC messages and RPC methods --- api/proto/teleport/legacy/types/types.proto | 2 + api/types/types.pb.go | 97 ++++++ gen/proto/go/accessgraph/v1alpha/azure.pb.go | 328 +++++++++++++------ proto/accessgraph/v1alpha/azure.proto | 2 +- 4 files changed, 320 insertions(+), 109 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 12cf67c474972..cda07aa429c6a 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8031,6 +8031,8 @@ message AccessGraphSync { (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Azure is a configuration for the Azure Access Graph service poll service. + repeated AccessGraphAzureSync Azure = 3 [(gogoproto.jsontag) = "azure,omitempty"]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. diff --git a/api/types/types.pb.go b/api/types/types.pb.go index cb2411d3ca520..694edf00ace6c 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -50500,6 +50500,63 @@ func (m *AccessGraphAzureSync) MarshalTo(dAtA []byte) (int, error) { return m.MarshalToSizedBuffer(dAtA[:size]) } +func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Integration) > 0 { + i -= len(m.Integration) + copy(dAtA[i:], m.Integration) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Integration))) + i-- + dAtA[i] = 0x22 + } + if len(m.UmiClientId) > 0 { + i -= len(m.UmiClientId) + copy(dAtA[i:], m.UmiClientId) + i = encodeVarintTypes(dAtA, i, uint64(len(m.UmiClientId))) + i-- + dAtA[i] = 0x1a + } + if len(m.SubscriptionID) > 0 { + i -= len(m.SubscriptionID) + copy(dAtA[i:], m.SubscriptionID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.SubscriptionID))) + i-- + dAtA[i] = 0x12 + } + if len(m.Regions) > 0 { + for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Regions[iNdEx]) + copy(dAtA[i:], m.Regions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AccessGraphAzureSync) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccessGraphAzureSync) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i @@ -61905,6 +61962,12 @@ func (m *AccessGraphSync) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } + if len(m.Azure) > 0 { + for _, e := range m.Azure { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval) n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { @@ -134311,6 +134374,40 @@ func (m *AccessGraphSync) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Azure", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Azure = append(m.Azure, &AccessGraphAzureSync{}) + if err := m.Azure[len(m.Azure)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 9f15efe5fe416..65bc24ab991b2 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -164,6 +164,20 @@ func (x *AzureResource) GetVirtualMachine() *AzureVirtualMachine { return nil } +func (x *AzureResource) GetManagedDatabase() *AzureManagedDatabase { + if x, ok := x.GetResource().(*AzureResource_ManagedDatabase); ok { + return x.ManagedDatabase + } + return nil +} + +func (x *AzureResource) GetAksCluster() *AzureAKSCluster { + if x, ok := x.GetResource().(*AzureResource_AksCluster); ok { + return x.AksCluster + } + return nil +} + type isAzureResource_Resource interface { isAzureResource_Resource() } @@ -188,6 +202,14 @@ type AzureResource_VirtualMachine struct { VirtualMachine *AzureVirtualMachine `protobuf:"bytes,4,opt,name=virtual_machine,json=virtualMachine,proto3,oneof"` } +type AzureResource_ManagedDatabase struct { + ManagedDatabase *AzureManagedDatabase `protobuf:"bytes,5,opt,name=managed_database,json=managedDatabase,proto3,oneof"` +} + +type AzureResource_AksCluster struct { + AksCluster *AzureAKSCluster `protobuf:"bytes,6,opt,name=aks_cluster,json=aksCluster,proto3,oneof"` +} + func (*AzureResource_Principal) isAzureResource_Resource() {} func (*AzureResource_RoleDefinition) isAzureResource_Resource() {} @@ -196,6 +218,10 @@ func (*AzureResource_RoleAssignment) isAzureResource_Resource() {} func (*AzureResource_VirtualMachine) isAzureResource_Resource() {} +func (*AzureResource_ManagedDatabase) isAzureResource_Resource() {} + +func (*AzureResource_AksCluster) isAzureResource_Resource() {} + // AzureVirtualMachine is an Azure virtual machine type AzureVirtualMachine struct { state protoimpl.MessageState @@ -266,21 +292,79 @@ func (x *AzureVirtualMachine) GetName() string { return "" } -func (x *AzureVirtualMachine) GetResourceGroup() string { if x != nil { - return x.ResourceGroup } return "" } -func (x *AzureVirtualMachine) GetTags() map[string]string { if x != nil { - return x.Tags } return nil } -// AzurePrincipal is an Azure principal (user, group, service principal) +// AzureIdentity is a Graph API object identity +type AzureIdentity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SignInType string `protobuf:"bytes,1,opt,name=sign_in_type,json=signInType,proto3" json:"sign_in_type,omitempty"` + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + IssuerAssignedId string `protobuf:"bytes,3,opt,name=issuer_assigned_id,json=issuerAssignedId,proto3" json:"issuer_assigned_id,omitempty"` +} + +func (x *AzureIdentity) Reset() { + *x = AzureIdentity{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AzureIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AzureIdentity) ProtoMessage() {} + +func (x *AzureIdentity) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AzureIdentity.ProtoReflect.Descriptor instead. +func (*AzureIdentity) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} +} + +func (x *AzureIdentity) GetSignInType() string { + if x != nil { + return x.SignInType + } + return "" +} + +func (x *AzureIdentity) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +func (x *AzureIdentity) GetIssuerAssignedId() string { + if x != nil { + return x.IssuerAssignedId + } + return "" +} + +// AzurePrincipal is a Graph API principal (user, group, service principal) type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -295,7 +379,7 @@ type AzurePrincipal struct { func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -307,7 +391,7 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -320,7 +404,7 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } func (x *AzurePrincipal) GetId() string { @@ -395,7 +479,7 @@ type AzureRoleAssignment struct { func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -407,7 +491,7 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -420,7 +504,7 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzureRoleAssignment) GetId() string { @@ -485,11 +569,12 @@ type AzureRoleDefinition struct { Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` AssignableScopes []string `protobuf:"bytes,6,rep,name=assignable_scopes,json=assignableScopes,proto3" json:"assignable_scopes,omitempty"` Permissions []*AzureRBACPermission `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` + RoleName string `protobuf:"bytes,8,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -501,7 +586,7 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -514,7 +599,7 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleDefinition) GetId() string { @@ -545,25 +630,25 @@ func (x *AzureRoleDefinition) GetName() string { return "" } -func (x *AzureRoleDefinition) GetPermissions() []*AzurePermission { +func (x *AzureRoleDefinition) GetDescription() string { if x != nil { - return x.Permissions + return x.Description } - return nil + return "" } -func (x *AzureRoleDefinition) GetRoleName() string { +func (x *AzureRoleDefinition) GetAssignableScopes() []string { if x != nil { - return x.RoleName + return x.AssignableScopes } - return "" + return nil } -func (x *AzureRoleDefinition) GetType() string { +func (x *AzureRoleDefinition) GetPermissions() []*AzureRBACPermission { if x != nil { - return x.Type + return x.Permissions } - return "" + return nil } func (x *AzureRoleDefinition) GetRoleName() string { @@ -574,30 +659,32 @@ func (x *AzureRoleDefinition) GetRoleName() string { } // AzurePermission defines the actions and not (disallowed) actions for a role definition -type AzurePermission struct { +type AzureRBACPermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Actions []string `protobuf:"bytes,4,rep,name=actions,proto3" json:"actions,omitempty"` - NotActions []string `protobuf:"bytes,5,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` + Actions []string `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"` + NotActions []string `protobuf:"bytes,2,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` + DataActions []string `protobuf:"bytes,3,rep,name=data_actions,json=dataActions,proto3" json:"data_actions,omitempty"` + NotDataActions []string `protobuf:"bytes,4,rep,name=not_data_actions,json=notDataActions,proto3" json:"not_data_actions,omitempty"` } func (x *AzureRBACPermission) Reset() { *x = AzureRBACPermission{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzurePermission) String() string { +func (x *AzureRBACPermission) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzurePermission) ProtoMessage() {} +func (*AzureRBACPermission) ProtoMessage() {} func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -610,17 +697,17 @@ func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRBACPermission.ProtoReflect.Descriptor instead. func (*AzureRBACPermission) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } -func (x *AzurePermission) GetActions() []string { +func (x *AzureRBACPermission) GetActions() []string { if x != nil { return x.Actions } return nil } -func (x *AzurePermission) GetNotActions() []string { +func (x *AzureRBACPermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -668,8 +755,8 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x80, - 0x04, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xdf, + 0x02, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -712,8 +799,33 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, - 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x77, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, + 0x73, 0x75, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x41, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x49, 0x64, 0x22, 0x8f, 0x02, 0x0a, 0x0e, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, + 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, + 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x12, 0x42, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0a, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x95, 0x02, 0x0a, 0x13, 0x41, + 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, @@ -721,57 +833,53 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x22, 0xf7, 0x01, - 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, - 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, - 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xbf, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, - 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, - 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, - 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, - 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, - 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, - 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x13, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, - 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, + 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, + 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0xdc, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, + 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x74, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -791,30 +899,32 @@ var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine - (*AzurePrincipal)(nil), // 3: accessgraph.v1alpha.AzurePrincipal - (*AzureRoleAssignment)(nil), // 4: accessgraph.v1alpha.AzureRoleAssignment - (*AzureRoleDefinition)(nil), // 5: accessgraph.v1alpha.AzureRoleDefinition - (*AzureRBACPermission)(nil), // 6: accessgraph.v1alpha.AzureRBACPermission - nil, // 7: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*AzureIdentity)(nil), // 3: accessgraph.v1alpha.AzureIdentity + (*AzurePrincipal)(nil), // 4: accessgraph.v1alpha.AzurePrincipal + (*AzureRoleAssignment)(nil), // 5: accessgraph.v1alpha.AzureRoleAssignment + (*AzureRoleDefinition)(nil), // 6: accessgraph.v1alpha.AzureRoleDefinition + (*AzureRBACPermission)(nil), // 7: accessgraph.v1alpha.AzureRBACPermission + nil, // 8: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource - 3, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal - 5, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition - 4, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment + 4, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal + 6, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition + 5, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine - 8, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp - 7, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry - 8, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 8: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 9: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp - 6, // 10: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 9, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry + 9, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp + 3, // 8: accessgraph.v1alpha.AzurePrincipal.identities:type_name -> accessgraph.v1alpha.AzureIdentity + 9, // 9: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 10: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp + 7, // 11: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -827,6 +937,8 @@ func file_accessgraph_v1alpha_azure_proto_init() { (*AzureResource_RoleDefinition)(nil), (*AzureResource_RoleAssignment)(nil), (*AzureResource_VirtualMachine)(nil), + (*AzureResource_ManagedDatabase)(nil), + (*AzureResource_AksCluster)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/accessgraph/v1alpha/azure.proto b/proto/accessgraph/v1alpha/azure.proto index 58bef9b36e97b..7b31e5623106a 100644 --- a/proto/accessgraph/v1alpha/azure.proto +++ b/proto/accessgraph/v1alpha/azure.proto @@ -27,7 +27,7 @@ message AzureResourceList { repeated AzureResource resources = 1; } -// AzureResource is a list of Azure resources supported by the access graph. +// AWSResource is a list of AWS resources supported by the access graph. message AzureResource { oneof resource { // principal is an Azure principal From 34d6b4f8114684730e0ce8f0da962300fe5c303f Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Fri, 8 Nov 2024 10:23:31 -0600 Subject: [PATCH 11/36] More PR feedback and generating protobuf code --- gen/proto/go/accessgraph/v1alpha/azure.pb.go | 282 ++++--------------- proto/accessgraph/v1alpha/azure.proto | 2 +- 2 files changed, 60 insertions(+), 224 deletions(-) diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 65bc24ab991b2..66186e8d12916 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -164,20 +164,6 @@ func (x *AzureResource) GetVirtualMachine() *AzureVirtualMachine { return nil } -func (x *AzureResource) GetManagedDatabase() *AzureManagedDatabase { - if x, ok := x.GetResource().(*AzureResource_ManagedDatabase); ok { - return x.ManagedDatabase - } - return nil -} - -func (x *AzureResource) GetAksCluster() *AzureAKSCluster { - if x, ok := x.GetResource().(*AzureResource_AksCluster); ok { - return x.AksCluster - } - return nil -} - type isAzureResource_Resource interface { isAzureResource_Resource() } @@ -202,14 +188,6 @@ type AzureResource_VirtualMachine struct { VirtualMachine *AzureVirtualMachine `protobuf:"bytes,4,opt,name=virtual_machine,json=virtualMachine,proto3,oneof"` } -type AzureResource_ManagedDatabase struct { - ManagedDatabase *AzureManagedDatabase `protobuf:"bytes,5,opt,name=managed_database,json=managedDatabase,proto3,oneof"` -} - -type AzureResource_AksCluster struct { - AksCluster *AzureAKSCluster `protobuf:"bytes,6,opt,name=aks_cluster,json=aksCluster,proto3,oneof"` -} - func (*AzureResource_Principal) isAzureResource_Resource() {} func (*AzureResource_RoleDefinition) isAzureResource_Resource() {} @@ -218,10 +196,6 @@ func (*AzureResource_RoleAssignment) isAzureResource_Resource() {} func (*AzureResource_VirtualMachine) isAzureResource_Resource() {} -func (*AzureResource_ManagedDatabase) isAzureResource_Resource() {} - -func (*AzureResource_AksCluster) isAzureResource_Resource() {} - // AzureVirtualMachine is an Azure virtual machine type AzureVirtualMachine struct { state protoimpl.MessageState @@ -292,42 +266,83 @@ func (x *AzureVirtualMachine) GetName() string { return "" } +// AzureManagedDatabase is an Azure-managed Postgres or MySQL database +type AzureManagedDatabase struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *AzureManagedDatabase) Reset() { + *x = AzureManagedDatabase{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AzureManagedDatabase) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AzureManagedDatabase) ProtoMessage() {} + +func (x *AzureManagedDatabase) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AzureManagedDatabase.ProtoReflect.Descriptor instead. +func (*AzureManagedDatabase) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} +} + +func (x *AzureManagedDatabase) GetId() string { + if x != nil { + return x.Id } return "" } +func (x *AzureManagedDatabase) GetSubscriptionId() string { if x != nil { + return x.SubscriptionId + } + return "" +} + +func (x *AzureManagedDatabase) GetLastSyncTime() *timestamppb.Timestamp { + if x != nil { + return x.LastSyncTime } return nil } -// AzureIdentity is a Graph API object identity -type AzureIdentity struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SignInType string `protobuf:"bytes,1,opt,name=sign_in_type,json=signInType,proto3" json:"sign_in_type,omitempty"` - Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` - IssuerAssignedId string `protobuf:"bytes,3,opt,name=issuer_assigned_id,json=issuerAssignedId,proto3" json:"issuer_assigned_id,omitempty"` } -func (x *AzureIdentity) Reset() { - *x = AzureIdentity{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzureIdentity) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzureIdentity) ProtoMessage() {} -func (x *AzureIdentity) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -338,33 +353,23 @@ func (x *AzureIdentity) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzureIdentity.ProtoReflect.Descriptor instead. -func (*AzureIdentity) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} } -func (x *AzureIdentity) GetSignInType() string { if x != nil { - return x.SignInType } return "" } -func (x *AzureIdentity) GetIssuer() string { if x != nil { - return x.Issuer } return "" } -func (x *AzureIdentity) GetIssuerAssignedId() string { if x != nil { - return x.IssuerAssignedId } return "" } -// AzurePrincipal is a Graph API principal (user, group, service principal) type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -379,7 +384,6 @@ type AzurePrincipal struct { func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -391,7 +395,6 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -404,7 +407,6 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } func (x *AzurePrincipal) GetId() string { @@ -479,7 +481,6 @@ type AzureRoleAssignment struct { func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -491,7 +492,6 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -504,7 +504,6 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzureRoleAssignment) GetId() string { @@ -562,19 +561,14 @@ type AzureRoleDefinition struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` - AssignableScopes []string `protobuf:"bytes,6,rep,name=assignable_scopes,json=assignableScopes,proto3" json:"assignable_scopes,omitempty"` - Permissions []*AzureRBACPermission `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` - RoleName string `protobuf:"bytes,8,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -586,7 +580,6 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -599,7 +592,6 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleDefinition) GetId() string { @@ -630,21 +622,6 @@ func (x *AzureRoleDefinition) GetName() string { return "" } -func (x *AzureRoleDefinition) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *AzureRoleDefinition) GetAssignableScopes() []string { - if x != nil { - return x.AssignableScopes - } - return nil -} - -func (x *AzureRoleDefinition) GetPermissions() []*AzureRBACPermission { if x != nil { return x.Permissions } @@ -659,7 +636,6 @@ func (x *AzureRoleDefinition) GetRoleName() string { } // AzurePermission defines the actions and not (disallowed) actions for a role definition -type AzureRBACPermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -670,21 +646,14 @@ type AzureRBACPermission struct { NotDataActions []string `protobuf:"bytes,4,rep,name=not_data_actions,json=notDataActions,proto3" json:"not_data_actions,omitempty"` } -func (x *AzureRBACPermission) Reset() { - *x = AzureRBACPermission{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzureRBACPermission) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzureRBACPermission) ProtoMessage() {} -func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -695,19 +664,14 @@ func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzureRBACPermission.ProtoReflect.Descriptor instead. -func (*AzureRBACPermission) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } -func (x *AzureRBACPermission) GetActions() []string { if x != nil { return x.Actions } return nil } -func (x *AzureRBACPermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -755,8 +719,6 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xdf, - 0x02, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -777,109 +739,6 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0xcc, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, - 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, - 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x77, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, - 0x73, 0x75, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x49, 0x64, 0x22, 0x8f, 0x02, 0x0a, 0x0e, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, - 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, - 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, - 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x12, 0x42, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0a, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x95, 0x02, 0x0a, 0x13, 0x41, - 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, - 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, - 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0xdc, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, - 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, - 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x74, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, } var ( @@ -894,37 +753,16 @@ func file_accessgraph_v1alpha_azure_proto_rawDescGZIP() []byte { return file_accessgraph_v1alpha_azure_proto_rawDescData } -var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine - (*AzureIdentity)(nil), // 3: accessgraph.v1alpha.AzureIdentity - (*AzurePrincipal)(nil), // 4: accessgraph.v1alpha.AzurePrincipal - (*AzureRoleAssignment)(nil), // 5: accessgraph.v1alpha.AzureRoleAssignment - (*AzureRoleDefinition)(nil), // 6: accessgraph.v1alpha.AzureRoleDefinition - (*AzureRBACPermission)(nil), // 7: accessgraph.v1alpha.AzureRBACPermission - nil, // 8: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource - 4, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal - 6, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition - 5, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine - 9, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry - 9, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp - 3, // 8: accessgraph.v1alpha.AzurePrincipal.identities:type_name -> accessgraph.v1alpha.AzureIdentity - 9, // 9: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 10: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp - 7, // 11: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -937,8 +775,6 @@ func file_accessgraph_v1alpha_azure_proto_init() { (*AzureResource_RoleDefinition)(nil), (*AzureResource_RoleAssignment)(nil), (*AzureResource_VirtualMachine)(nil), - (*AzureResource_ManagedDatabase)(nil), - (*AzureResource_AksCluster)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -946,7 +782,7 @@ func file_accessgraph_v1alpha_azure_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accessgraph_v1alpha_azure_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/accessgraph/v1alpha/azure.proto b/proto/accessgraph/v1alpha/azure.proto index 7b31e5623106a..58bef9b36e97b 100644 --- a/proto/accessgraph/v1alpha/azure.proto +++ b/proto/accessgraph/v1alpha/azure.proto @@ -27,7 +27,7 @@ message AzureResourceList { repeated AzureResource resources = 1; } -// AWSResource is a list of AWS resources supported by the access graph. +// AzureResource is a list of Azure resources supported by the access graph. message AzureResource { oneof resource { // principal is an Azure principal From e76cc029d5c598b3998f3c81a1b120b96ba24860 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Fri, 8 Nov 2024 15:27:42 -0600 Subject: [PATCH 12/36] Adding partial implementation --- lib/srv/discovery/access_graph_azure.go | 382 ++++++++++++++++++ .../fetchers/azure-sync/azure-sync.go | 246 +++++++++++ .../fetchers/azure-sync/msggraphclient.go | 239 +++++++++++ .../fetchers/azure-sync/reconcile.go | 153 +++++++ .../fetchers/azure-sync/roleassignments.go | 56 +++ .../fetchers/azure-sync/roledefinitions.go | 19 + 6 files changed, 1095 insertions(+) create mode 100644 lib/srv/discovery/access_graph_azure.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/azure-sync.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/msggraphclient.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/reconcile.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/roleassignments.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/roledefinitions.go diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go new file mode 100644 index 0000000000000..b04ac5fe9bddd --- /dev/null +++ b/lib/srv/discovery/access_graph_azure.go @@ -0,0 +1,382 @@ +package discovery + +import ( + "context" + "errors" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/retryutils" + "github.com/gravitational/teleport/entitlements" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/teleport/lib/modules" + "github.com/gravitational/teleport/lib/services" + azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" + "github.com/gravitational/trace" + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + "io" + "sync" + "time" +) + +func (s *Server) reconcileAccessGraphAzure( + ctx context.Context, + currentTAGResources *azure_sync.Resources, + stream accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, + features azure_sync.Features, +) error { + type fetcherResult struct { + result *azure_sync.Resources + err error + } + + allFetchers := s.getAllTAGSyncAzureFetchers() + if len(allFetchers) == 0 { + // If there are no fetchers, we don't need to continue. + // We will send a delete request for all resources and return. + upsert, toDel := azure_sync.ReconcileResults(currentTAGResources, &azure_sync.Resources{}) + + if err := azurePush(stream, upsert, toDel); err != nil { + s.Log.ErrorContext(ctx, "Error pushing empty resources to TAGs", "error", err) + } + return trace.Wrap(errNoAccessGraphFetchers) + } + + // TODO (mbrock): Update discovery config status + /* + s.awsSyncStatus.iterationStarted(allFetchers, s.clock.Now()) + for _, discoveryConfigName := range s.awsSyncStatus.discoveryConfigs() { + s.updateDiscoveryConfigStatus(discoveryConfigName) + } + */ + + resultsC := make(chan fetcherResult, len(allFetchers)) + // Use a channel to limit the number of concurrent fetchers. + tokens := make(chan struct{}, 3) + accountIds := map[string]struct{}{} + for _, fetcher := range allFetchers { + fetcher := fetcher + accountIds[fetcher.GetSubscriptionID()] = struct{}{} + tokens <- struct{}{} + go func() { + defer func() { + <-tokens + }() + result, err := fetcher.Poll(ctx, features) + resultsC <- fetcherResult{result, trace.Wrap(err)} + }() + } + + results := make([]*azure_sync.Resources, 0, len(allFetchers)) + errs := make([]error, 0, len(allFetchers)) + // Collect the results from all fetchers. + // Each fetcher can return an error and a result. + for i := 0; i < len(allFetchers); i++ { + fetcherResult := <-resultsC + if fetcherResult.err != nil { + errs = append(errs, fetcherResult.err) + } + if fetcherResult.result != nil { + results = append(results, fetcherResult.result) + } + } + // Aggregate all errors into a single error. + err := trace.NewAggregate(errs...) + if err != nil { + s.Log.ErrorContext(ctx, "Error polling TAGs", "error", err) + } + result := azure_sync.MergeResources(results...) + // Merge all results into a single result + upsert, toDel := azure_sync.ReconcileResults(currentTAGResources, result) + pushErr := azurePush(stream, upsert, toDel) + + // TODO (mbrock): Update discovery config status + /* + s.awsSyncStatus.iterationFinished(allFetchers, pushErr, s.clock.Now()) + for _, discoveryConfigName := range s.awsSyncStatus.discoveryConfigs() { + s.updateDiscoveryConfigStatus(discoveryConfigName) + } + */ + + if pushErr != nil { + s.Log.ErrorContext(ctx, "Error pushing TAGs", "error", pushErr) + return nil + } + // Update the currentTAGResources with the result of the reconciliation. + *currentTAGResources = *result + return nil +} + +func azurePushUpsertInBatches( + client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, + upsert *accessgraphv1alpha.AzureResourceList, +) error { + for i := 0; i < len(upsert.Resources); i += batchSize { + end := i + batchSize + if end > len(upsert.Resources) { + end = len(upsert.Resources) + } + err := client.Send( + &accessgraphv1alpha.AzureEventsStreamRequest{ + Operation: &accessgraphv1alpha.AzureEventsStreamRequest_Upsert{ + Upsert: &accessgraphv1alpha.AzureResourceList{ + Resources: upsert.Resources[i:end], + }, + }, + }, + ) + if err != nil { + return trace.Wrap(err) + } + } + return nil +} + +func azurePushDeleteInBatches( + client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, + toDel *accessgraphv1alpha.AzureResourceList, +) error { + for i := 0; i < len(toDel.Resources); i += batchSize { + end := i + batchSize + if end > len(toDel.Resources) { + end = len(toDel.Resources) + } + err := client.Send( + &accessgraphv1alpha.AzureEventsStreamRequest{ + Operation: &accessgraphv1alpha.AzureEventsStreamRequest_Delete{ + Delete: &accessgraphv1alpha.AzureResourceList{ + Resources: toDel.Resources[i:end], + }, + }, + }, + ) + if err != nil { + return trace.Wrap(err) + } + } + return nil +} + +func azurePush( + client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, + upsert *accessgraphv1alpha.AzureResourceList, + toDel *accessgraphv1alpha.AzureResourceList, +) error { + err := azurePushUpsertInBatches(client, upsert) + if err != nil { + return trace.Wrap(err) + } + err = azurePushDeleteInBatches(client, toDel) + if err != nil { + return trace.Wrap(err) + } + err = client.Send( + &accessgraphv1alpha.AzureEventsStreamRequest{ + Operation: &accessgraphv1alpha.AzureEventsStreamRequest_Sync{}, + }, + ) + return trace.Wrap(err) +} + +// getAllTAGSyncAzureFetchers returns both static and dynamic TAG Azure fetchers +func (s *Server) getAllTAGSyncAzureFetchers() []azure_sync.Fetcher { + allFetchers := make([]azure_sync.Fetcher, 0, len(s.dynamicTAGSyncFetchers)) + + s.muDynamicTAGSyncAzureFetchers.RLock() + for _, fetcherSet := range s.dynamicTAGSyncAzureFetchers { + allFetchers = append(allFetchers, fetcherSet...) + } + s.muDynamicTAGSyncAzureFetchers.RUnlock() + + allFetchers = append(allFetchers, s.staticTAGSyncAzureFetchers...) + return allFetchers +} + +// initializeAndWatchAzureAccessGraph initializes and watches the TAG Azure stream +func (s *Server) initializeAndWatchAzureAccessGraph(ctx context.Context, reloadCh chan struct{}) error { + // Check if the access graph is enabled + clusterFeatures := s.Config.ClusterFeatures() + policy := modules.GetProtoEntitlement(&clusterFeatures, entitlements.Policy) + if !clusterFeatures.AccessGraph && !policy.Enabled { + return trace.Wrap(errTAGFeatureNotEnabled) + } + + // Configure the access graph semaphore for constraining multiple discovery servers + const ( + semaphoreExpiration = time.Minute + semaphoreName = "access_graph_azure_sync" + serviceConfig = `{ + "loadBalancingPolicy": "round_robin", + "healthCheckConfig": { + "serviceName": "" + } + }` + ) + lease, err := services.AcquireSemaphoreLockWithRetry( + ctx, + services.SemaphoreLockConfigWithRetry{ + SemaphoreLockConfig: services.SemaphoreLockConfig{ + Service: s.AccessPoint, + Params: types.AcquireSemaphoreRequest{ + SemaphoreKind: types.KindAccessGraph, + SemaphoreName: semaphoreName, + MaxLeases: 1, + Holder: s.Config.ServerID, + }, + Expiry: semaphoreExpiration, + Clock: s.clock, + }, + Retry: retryutils.LinearConfig{ + Clock: s.clock, + First: time.Second, + Step: semaphoreExpiration / 2, + Max: semaphoreExpiration, + Jitter: retryutils.NewJitter(), + }, + }, + ) + if err != nil { + return trace.Wrap(err) + } + ctx, cancel := context.WithCancel(lease) + defer cancel() + defer func() { + lease.Stop() + if err := lease.Wait(); err != nil { + s.Log.WarnContext(ctx, "error cleaning up semaphore", "error", err) + } + }() + + // Create the access graph client + accessGraphConn, err := newAccessGraphClient( + ctx, + s.GetClientCert, + s.Config.AccessGraphConfig, + grpc.WithDefaultServiceConfig(serviceConfig), + ) + if err != nil { + return trace.Wrap(err) + } + // Close the connection when the function returns. + defer accessGraphConn.Close() + client := accessgraphv1alpha.NewAccessGraphServiceClient(accessGraphConn) + + // Create the event stream + stream, err := client.AzureEventsStream(ctx) + if err != nil { + s.Log.ErrorContext(ctx, "Failed to get TAG Azure service stream", "error", err) + return trace.Wrap(err) + } + header, err := stream.Header() + if err != nil { + s.Log.ErrorContext(ctx, "Failed to get TAG Azure service stream header", "error", err) + return trace.Wrap(err) + } + const ( + supportedResourcesKey = "supported-kinds" + ) + supportedKinds := header.Get(supportedResourcesKey) + if len(supportedKinds) == 0 { + return trace.BadParameter("TAG Azure service did not return supported kinds") + } + features := azure_sync.BuildFeatures(supportedKinds...) + + // Cancels the context to stop the event watcher if the access graph connection fails + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + go func() { + defer wg.Done() + defer cancel() + if !accessGraphConn.WaitForStateChange(ctx, connectivity.Ready) { + s.Log.Info("access graph service connection was closed") + } + }() + + // Reconciles the resources as they're imported from Azure + azureResources := &azure_sync.Resources{} + ticker := time.NewTicker(15 * time.Minute) + defer ticker.Stop() + for { + err := s.reconcileAccessGraphAzure(ctx, azureResources, stream, features) + if errors.Is(err, errNoAccessGraphFetchers) { + _, err := stream.CloseAndRecv() + if errors.Is(err, io.EOF) { + err = nil + } + return trace.Wrap(err) + } + select { + case <-ctx.Done(): + return trace.Wrap(ctx.Err()) + case <-ticker.C: + case <-reloadCh: + } + } +} + +// initTAGAzureWatchers initializes the TAG Azure watchers +func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { + staticFetchers, err := s.accessGraphAzureFetchersFromMatchers(cfg.Matchers, "" /* discoveryConfigName */) + if err != nil { + s.Log.ErrorContext(ctx, "Error initializing access graph fetchers", "error", err) + } + s.staticTAGSyncAzureFetchers = staticFetchers + if cfg.AccessGraphConfig.Enabled { + go func() { + reloadCh := s.newDiscoveryConfigChangedSub() + for { + fetchers := s.getAllTAGSyncAzureFetchers() + // Wait for the config to change and re-evaluate the fetchers before starting the sync. + if len(fetchers) == 0 { + s.Log.Debug("No Azure sync fetchers configured. Access graph sync will not be enabled.") + select { + case <-ctx.Done(): + return + case <-reloadCh: + // if the config changes, we need to get the updated list of fetchers + } + continue + } + // Reset the Azure resources to force a full sync + if err := s.initializeAndWatchAzureAccessGraph(ctx, reloadCh); errors.Is(err, errTAGFeatureNotEnabled) { + s.Log.Warn("Access Graph specified in config, but the license does not include Teleport Policy. Access graph sync will not be enabled.") + break + } else if err != nil { + s.Log.Warn("Error initializing and watching access graph", "error", err) + } + + select { + case <-ctx.Done(): + return + case <-time.After(time.Minute): + } + } + }() + } + return nil +} + +func (s *Server) accessGraphAzureFetchersFromMatchers(matchers Matchers, discoveryConfigName string) ([]azure_sync.Fetcher, error) { + var fetchers []azure_sync.Fetcher + var errs []error + if matchers.AccessGraph == nil { + return fetchers, nil + } + for _, matcher := range matchers.AccessGraph.Azure { + fetcher, err := azure_sync.NewFetcher( + azure_sync.Config{ + CloudClients: s.CloudClients, + SubscriptionID: matcher.SubscriptionID, + Regions: matcher.Regions, + Integration: matcher.Integration, + DiscoveryConfigName: discoveryConfigName, + }, + ) + if err != nil { + errs = append(errs, err) + continue + } + fetchers = append(fetchers, fetcher) + } + return fetchers, trace.NewAggregate(errs...) +} diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go new file mode 100644 index 0000000000000..ac69560c0ea70 --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -0,0 +1,246 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/teleport/lib/cloud" + "github.com/gravitational/trace" + "golang.org/x/sync/errgroup" + "sync" +) + +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( +"context" +accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" +"github.com/gravitational/teleport/lib/cloud" +"github.com/gravitational/teleport/lib/srv/discovery/common" +"github.com/gravitational/trace" +"golang.org/x/sync/errgroup" +"sync" +) + +const ( + featNamePrincipals = "azure/principals" + featNameRoleDefinitions = "azure/roledefinitions" + featNameRoleAssignments = "azure/roleassignments" + featNameVms = "azure/virtualmachines" + featNameManagedDatabases = "azure/databases" + featNameAKSClusters = "azure/aksclusters" +) + +const FetcherConcurrency = 5 + +type Config struct { + CloudClients cloud.Clients + SubscriptionID string + Regions []string + Integration string + DiscoveryConfigName string +} + +type Resources struct { + Principals []*accessgraphv1alpha.AzurePrincipal + RoleDefinitions []*accessgraphv1alpha.AzureRoleDefinition + RoleAssignments []*accessgraphv1alpha.AzureRoleAssignment + VirtualMachines []*accessgraphv1alpha.AzureVirtualMachine +} + +type Features struct { + Principals bool + RoleDefinitions bool + RoleAssignments bool + VirtualMachines bool + ManagedDatabases bool + AKSClusters bool +} + +type Fetcher interface { + Poll(context.Context, Features) (*Resources, error) + Status() (uint64, error) + DiscoveryConfigName() string + IsFromDiscoveryConfig() bool + GetSubscriptionID() string +} + +type azureFetcher struct { + Config + lastError error + lastDiscoveredResources uint64 + lastResult *Resources +} + +func NewFetcher(cfg Config) (Fetcher, error) { + return &azureFetcher{ + Config: cfg, + lastResult: &Resources{}, + }, nil +} + +// BuildFeatures builds the feature flags based on supported types returned by Access Graph +// Azure endpoints. +func BuildFeatures(values ...string) Features { + features := Features{} + for _, value := range values { + switch value { + case featNameVms: + features.VirtualMachines = true + case featNamePrincipals: + features.Principals = true + case featNameRoleDefinitions: + features.RoleDefinitions = true + case featNameRoleAssignments: + features.RoleAssignments = true + case featNameManagedDatabases: + features.ManagedDatabases = true + case featNameAKSClusters: + features.AKSClusters = true + } + } + return features +} + +func (a *azureFetcher) Poll(ctx context.Context, feats Features) (*Resources, error) { + res, err := a.fetch(ctx, feats) + if res == nil { + return nil, err + } + res.VirtualMachines = common.DeduplicateSlice(res.VirtualMachines, azureVmKey) + res.Principals = common.DeduplicateSlice(res.Principals, azureUserKey) + res.RoleDefinitions = common.DeduplicateSlice(res.RoleDefinitions, azureRoleDefKey) + res.RoleAssignments = common.DeduplicateSlice(res.RoleAssignments, azureRoleAssignKey) + return res, trace.Wrap(err) +} + +func (a *azureFetcher) fetch(ctx context.Context, feats Features) (*Resources, error) { + // Accumulate Azure resources + eg, ctx := errgroup.WithContext(ctx) + eg.SetLimit(FetcherConcurrency) + var result = &Resources{} + var errs []error + errsCh := make(chan error) + if feats.Principals { + eg.Go(func() error { + principals, err := a.fetchPrincipals(ctx) + if err != nil { + errsCh <- err + return err + } + result.Principals = principals + return nil + }) + } + if feats.RoleDefinitions { + eg.Go(func() error { + roleDefs, err := a.fetchRoleDefinitions(ctx) + if err != nil { + errsCh <- err + return err + } + result.RoleDefinitions = roleDefs + return nil + }) + } + if feats.RoleAssignments { + eg.Go(func() error { + roleAssigns, err := a.fetchRoleAssignments(ctx) + if err != nil { + errsCh <- err + return err + } + result.RoleAssignments = roleAssigns + return nil + }) + } + if feats.VirtualMachines { + eg.Go(func() error { + vms, err := a.fetchVirtualMachines(ctx) + if err != nil { + errsCh <- err + return err + } + result.VirtualMachines = vms + return nil + }) + } + + // Collect the error messages from the error channel + var wg sync.WaitGroup + go func() { + wg.Add(1) + defer wg.Done() + for { + err, ok := <-errsCh + if !ok { + return + } + errs = append(errs, err) + } + }() + _ = eg.Wait() + close(errsCh) + wg.Wait() + if len(errs) > 0 { + return result, trace.NewAggregate(errs...) + } + + // Return the resources + return result, nil +} + +func (a *azureFetcher) Status() (uint64, error) { + return a.lastDiscoveredResources, a.lastError +} +func (a *azureFetcher) DiscoveryConfigName() string { + return a.Config.DiscoveryConfigName +} +func (a *azureFetcher) IsFromDiscoveryConfig() bool { + return a.Config.DiscoveryConfigName != "" +} +func (a *azureFetcher) GetSubscriptionID() string { + return a.Config.SubscriptionID +} + +func ptrsToList(ptrs []*string) []string { + strList := make([]string, len(ptrs)) + for _, ptr := range ptrs { + strList = append(strList, *ptr) + } + return strList +} diff --git a/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go new file mode 100644 index 0000000000000..bb46b7464f94e --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go @@ -0,0 +1,239 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +// GraphClient represents generic MS API client +type GraphClient struct { + token azcore.AccessToken +} + +const ( + usersSuffix = "users" + groupsSuffix = "groups" + servicePrincipalsSuffix = "servicePrincipals" + graphBaseURL = "https://graph.microsoft.com/v1.0" + httpTimeout = time.Second * 30 +) + +// graphError represents MS Graph error +type graphError struct { + E struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"error"` +} + +// genericGraphResponse represents the utility struct for parsing MS Graph API response +type genericGraphResponse struct { + Context string `json:"@odata.context"` + Count int `json:"@odata.count"` + NextLink string `json:"@odata.nextLink"` + Value json.RawMessage `json:"value"` +} + +// User represents user resource +type User struct { + ID string `json:"id"` + Name string `json:"displayName"` + MemberOf []Membership `json:"memberOf"` +} + +type Membership struct { + Type string `json:"@odata.type"` + ID string `json:"id"` +} + +// request represents generic request structure +type request struct { + // Method HTTP method + Method string + // URL which overrides URL construction + URL *string + // Path to a resource + Path string + // Expand $expand value + Expand []string + // Filter $filter value + Filter string + // Body request body + Body string + // Response represents template structure for a response + Response interface{} + // Err represents template structure for an error + Err error + // SuccessCode http code representing success + SuccessCode int +} + +// GetURL builds the request URL +func (r *request) GetURL() (string, error) { + if r.URL != nil { + return *r.URL, nil + } + u, err := url.Parse(graphBaseURL) + if err != nil { + return "", err + } + + data := url.Values{} + if len(r.Expand) > 0 { + data.Set("$expand", strings.Join(r.Expand, ",")) + } + if r.Filter != "" { + data.Set("$filter", r.Filter) + } + + u.Path = u.Path + "/" + r.Path + u.RawQuery = data.Encode() + + return u.String(), nil +} + +// NewGraphClient creates MS Graph API client +func NewGraphClient(token azcore.AccessToken) *GraphClient { + return &GraphClient{ + token: token, + } +} + +// Error returns error string +func (e graphError) Error() string { + return e.E.Code + " " + e.E.Message +} + +func (c *GraphClient) ListUsers(ctx context.Context) ([]User, error) { + return c.listIdentities(ctx, usersSuffix, []string{"memberOf"}) +} + +func (c *GraphClient) ListGroups(ctx context.Context) ([]User, error) { + return c.listIdentities(ctx, groupsSuffix, []string{"memberOf"}) +} + +func (c *GraphClient) ListServicePrincipals(ctx context.Context) ([]User, error) { + return c.listIdentities(ctx, servicePrincipalsSuffix, []string{"memberOf"}) +} + +func (c *GraphClient) listIdentities(ctx context.Context, idType string, expand []string) ([]User, error) { + var users []User + var nextLink *string + for { + g := &genericGraphResponse{} + req := request{ + Method: http.MethodGet, + Path: idType, + Expand: expand, + Response: &g, + Err: &graphError{}, + URL: nextLink, + } + err := c.request(ctx, req) + if err != nil { + return nil, err + } + var newUsers []User + err = json.NewDecoder(bytes.NewReader(g.Value)).Decode(&newUsers) + if err != nil { + return nil, err + } + users = append(users, newUsers...) + if g.NextLink == "" { + break + } + nextLink = &g.NextLink + } + + return users, nil +} + +// request sends the request to the graph/bot service and returns response body as bytes slice +func (c *GraphClient) request(ctx context.Context, req request) error { + reqUrl, err := req.GetURL() + if err != nil { + return err + } + + r, err := http.NewRequestWithContext(ctx, req.Method, reqUrl, strings.NewReader(req.Body)) + if err != nil { + return err + } + + r.Header.Set("Authorization", "Bearer "+c.token.Token) + r.Header.Set("Content-Type", "application/json") + + client := http.Client{Timeout: httpTimeout} + resp, err := client.Do(r) + if err != nil { + return err + } + + defer func(Body io.ReadCloser) { + _ = Body.Close() + }(resp.Body) + + b, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + expectedCode := req.SuccessCode + if expectedCode == 0 { + expectedCode = http.StatusOK + } + + if expectedCode == resp.StatusCode { + if req.Response == nil { + return nil + } + + err := json.NewDecoder(bytes.NewReader(b)).Decode(req.Response) + if err != nil { + return err + } + } else { + if req.Err == nil { + return fmt.Errorf("Error requesting MS Graph API: %v", string(b)) + } + + err := json.NewDecoder(bytes.NewReader(b)).Decode(req.Err) + if err != nil { + return err + } + + if req.Err.Error() == "" { + return fmt.Errorf("Error requesting MS Graph API. Expected response code was %v, but is %v", expectedCode, resp.StatusCode) + } + + return req.Err + } + + return nil +} diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile.go b/lib/srv/discovery/fetchers/azure-sync/reconcile.go new file mode 100644 index 0000000000000..60169d877b488 --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile.go @@ -0,0 +1,153 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( + "fmt" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/teleport/lib/srv/discovery/common" + "google.golang.org/protobuf/proto" +) + +func MergeResources(results ...*Resources) *Resources { + if len(results) == 0 { + return &Resources{} + } + if len(results) == 1 { + return results[0] + } + result := &Resources{} + for _, r := range results { + result.Principals = append(result.Principals, r.Principals...) + result.VirtualMachines = append(result.VirtualMachines, r.VirtualMachines...) + } + result.Principals = common.DeduplicateSlice(result.Principals, azureUserKey) + result.VirtualMachines = common.DeduplicateSlice(result.VirtualMachines, azureVmKey) + return result +} + +func newResourceList() *accessgraphv1alpha.AzureResourceList { + return &accessgraphv1alpha.AzureResourceList{ + Resources: make([]*accessgraphv1alpha.AzureResource, 0), + } +} + +func ReconcileResults(old *Resources, new *Resources) (upsert, delete *accessgraphv1alpha.AzureResourceList) { + upsert, delete = newResourceList(), newResourceList() + reconciledResources := []*reconcilePair{ + reconcile(old.VirtualMachines, new.VirtualMachines, azureVmKey, azureVmWrap), + reconcile(old.Principals, new.Principals, azureUserKey, azureUsersWrap), + reconcile(old.RoleDefinitions, new.RoleDefinitions, azureRoleDefKey, azureRoleDefWrap), + reconcile(old.RoleAssignments, new.RoleAssignments, azureRoleAssignKey, azureRoleAssignWrap), + } + for _, res := range reconciledResources { + upsert.Resources = append(upsert.Resources, res.upsert.Resources...) + delete.Resources = append(delete.Resources, res.delete.Resources...) + } + return upsert, delete +} + +type reconcilePair struct { + upsert, delete *accessgraphv1alpha.AzureResourceList +} + +func reconcile[T proto.Message]( + oldItems []T, + newItems []T, + keyFn func(T) string, + wrapFn func(T) *accessgraphv1alpha.AzureResource, +) *reconcilePair { + // Remove duplicates from the new items + newItems = common.DeduplicateSlice(newItems, keyFn) + upsertRes := newResourceList() + deleteRes := newResourceList() + + // Delete all old items if there are no new items + if len(newItems) == 0 { + for _, item := range oldItems { + deleteRes.Resources = append(deleteRes.Resources, wrapFn(item)) + } + return &reconcilePair{upsertRes, deleteRes} + } + + // Create all new items if there are no old items + if len(oldItems) == 0 { + for _, item := range newItems { + upsertRes.Resources = append(upsertRes.Resources, wrapFn(item)) + } + return &reconcilePair{upsertRes, deleteRes} + } + + // Map old and new items by their key + oldMap := make(map[string]T, len(oldItems)) + for _, item := range oldItems { + oldMap[keyFn(item)] = item + } + newMap := make(map[string]T, len(newItems)) + for _, item := range newItems { + newMap[keyFn(item)] = item + } + + // Append new or modified items to the upsert list + for _, item := range newItems { + if oldItem, ok := oldMap[keyFn(item)]; !ok || !proto.Equal(oldItem, item) { + upsertRes.Resources = append(upsertRes.Resources, wrapFn(item)) + } + } + + // Append removed items to the delete list + for _, item := range oldItems { + if _, ok := newMap[keyFn(item)]; !ok { + deleteRes.Resources = append(deleteRes.Resources, wrapFn(item)) + } + } + return &reconcilePair{upsertRes, deleteRes} +} + +func azureVmKey(vm *accessgraphv1alpha.AzureVirtualMachine) string { + return fmt.Sprintf("%s:%s", vm.SubscriptionId, vm.Id) +} + +func azureVmWrap(vm *accessgraphv1alpha.AzureVirtualMachine) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_VirtualMachine{VirtualMachine: vm}} +} + +func azureUserKey(user *accessgraphv1alpha.AzurePrincipal) string { + return fmt.Sprintf("%s:%s", user.SubscriptionId, user.Id) +} + +func azureUsersWrap(principal *accessgraphv1alpha.AzurePrincipal) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_Principal{Principal: principal}} +} + +func azureRoleDefKey(roleDef *accessgraphv1alpha.AzureRoleDefinition) string { + return fmt.Sprintf("%s:%s", roleDef.SubscriptionId, roleDef.Id) +} + +func azureRoleDefWrap(roleDef *accessgraphv1alpha.AzureRoleDefinition) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_RoleDefinition{RoleDefinition: roleDef}} +} + +func azureRoleAssignKey(roleAssign *accessgraphv1alpha.AzureRoleAssignment) string { + return fmt.Sprintf("%s:%s", roleAssign.SubscriptionId, roleAssign.Id) +} + +func azureRoleAssignWrap(roleAssign *accessgraphv1alpha.AzureRoleAssignment) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_RoleAssignment{RoleAssignment: roleAssign}} +} diff --git a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go new file mode 100644 index 0000000000000..93c2690c7b19b --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go @@ -0,0 +1,56 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( + "context" + "fmt" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (a *azureFetcher) fetchRoleAssignments(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleAssignment, error) { + // Get the Role Assignments client + cli, err := a.CloudClients.GetAzureRoleAssignmentsClient(a.GetSubscriptionID()) + if err != nil { + return nil, trace.Wrap(err) + } + + // List the role definitions + roleAssigns, err := cli.ListRoleAssignments(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) + if err != nil { + return nil, trace.Wrap(err) + } + + // Convert to protobuf format + pbRoleAssigns := make([]*accessgraphv1alpha.AzureRoleAssignment, 0, len(roleAssigns)) + for _, roleAssign := range roleAssigns { + pbRoleAssign := &accessgraphv1alpha.AzureRoleAssignment{ + Id: *roleAssign.ID, + SubscriptionId: a.SubscriptionID, + LastSyncTime: timestamppb.Now(), + PrincipalId: *roleAssign.Properties.PrincipalID, + RoleDefinitionId: *roleAssign.Properties.RoleDefinitionID, + Scope: *roleAssign.Properties.Scope, + } + pbRoleAssigns = append(pbRoleAssigns, pbRoleAssign) + } + return pbRoleAssigns, nil +} diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go new file mode 100644 index 0000000000000..89813980d729c --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -0,0 +1,19 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync From 577cee6ddf6f58bf15773a91e993350db70a550c Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 11 Nov 2024 18:52:12 -0600 Subject: [PATCH 13/36] Adding more fetching --- lib/srv/discovery/access_graph.go | 12 +- lib/srv/discovery/access_graph_azure.go | 35 +++--- lib/srv/discovery/common/reconcile.go | 32 +++++ lib/srv/discovery/discovery.go | 29 +++-- .../fetchers/azure-sync/azure-sync.go | 117 ++++++++---------- .../fetchers/azure-sync/principals.go | 63 ++++++++++ .../fetchers/azure-sync/roleassignments.go | 2 +- .../fetchers/azure-sync/roledefinitions.go | 43 +++++++ .../fetchers/azure-sync/virtualmachines.go | 53 ++++++++ 9 files changed, 288 insertions(+), 98 deletions(-) create mode 100644 lib/srv/discovery/common/reconcile.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/principals.go create mode 100644 lib/srv/discovery/fetchers/azure-sync/virtualmachines.go diff --git a/lib/srv/discovery/access_graph.go b/lib/srv/discovery/access_graph.go index 4bc207b21df01..b05e85d72bc32 100644 --- a/lib/srv/discovery/access_graph.go +++ b/lib/srv/discovery/access_graph.go @@ -145,15 +145,15 @@ func (s *Server) reconcileAccessGraph(ctx context.Context, currentTAGResources * // getAllAWSSyncFetchers returns all AWS sync fetchers. func (s *Server) getAllAWSSyncFetchers() []aws_sync.AWSSync { - allFetchers := make([]aws_sync.AWSSync, 0, len(s.dynamicTAGSyncFetchers)) + allFetchers := make([]aws_sync.AWSSync, 0, len(s.dynamicTAGAWSFetchers)) - s.muDynamicTAGSyncFetchers.RLock() - for _, fetcherSet := range s.dynamicTAGSyncFetchers { + s.muDynamicTAGAWSFetchers.RLock() + for _, fetcherSet := range s.dynamicTAGAWSFetchers { allFetchers = append(allFetchers, fetcherSet...) } - s.muDynamicTAGSyncFetchers.RUnlock() + s.muDynamicTAGAWSFetchers.RUnlock() - allFetchers = append(allFetchers, s.staticTAGSyncFetchers...) + allFetchers = append(allFetchers, s.staticTAGAWSFetchers...) // TODO(tigrato): submit fetchers event return allFetchers } @@ -443,7 +443,7 @@ func (s *Server) initAccessGraphWatchers(ctx context.Context, cfg *Config) error if err != nil { s.Log.ErrorContext(ctx, "Error initializing access graph fetchers", "error", err) } - s.staticTAGSyncFetchers = fetchers + s.staticTAGAWSFetchers = fetchers if cfg.AccessGraphConfig.Enabled { go func() { diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index b04ac5fe9bddd..8b0ec38cacc0c 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -178,16 +178,16 @@ func azurePush( } // getAllTAGSyncAzureFetchers returns both static and dynamic TAG Azure fetchers -func (s *Server) getAllTAGSyncAzureFetchers() []azure_sync.Fetcher { - allFetchers := make([]azure_sync.Fetcher, 0, len(s.dynamicTAGSyncFetchers)) +func (s *Server) getAllTAGSyncAzureFetchers() []*azure_sync.Fetcher { + allFetchers := make([]*azure_sync.Fetcher, 0, len(s.dynamicTAGAWSFetchers)) - s.muDynamicTAGSyncAzureFetchers.RLock() - for _, fetcherSet := range s.dynamicTAGSyncAzureFetchers { + s.muDynamicTAGAzureFetchers.RLock() + for _, fetcherSet := range s.dynamicTAGAzureFetchers { allFetchers = append(allFetchers, fetcherSet...) } - s.muDynamicTAGSyncAzureFetchers.RUnlock() + s.muDynamicTAGAzureFetchers.RUnlock() - allFetchers = append(allFetchers, s.staticTAGSyncAzureFetchers...) + allFetchers = append(allFetchers, s.staticTAGAzureFetchers...) return allFetchers } @@ -320,7 +320,7 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { if err != nil { s.Log.ErrorContext(ctx, "Error initializing access graph fetchers", "error", err) } - s.staticTAGSyncAzureFetchers = staticFetchers + s.staticTAGAzureFetchers = staticFetchers if cfg.AccessGraphConfig.Enabled { go func() { reloadCh := s.newDiscoveryConfigChangedSub() @@ -356,22 +356,21 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { return nil } -func (s *Server) accessGraphAzureFetchersFromMatchers(matchers Matchers, discoveryConfigName string) ([]azure_sync.Fetcher, error) { - var fetchers []azure_sync.Fetcher +func (s *Server) accessGraphAzureFetchersFromMatchers(matchers Matchers, discoveryConfigName string) ([]*azure_sync.Fetcher, error) { + var fetchers []*azure_sync.Fetcher var errs []error if matchers.AccessGraph == nil { return fetchers, nil } for _, matcher := range matchers.AccessGraph.Azure { - fetcher, err := azure_sync.NewFetcher( - azure_sync.Config{ - CloudClients: s.CloudClients, - SubscriptionID: matcher.SubscriptionID, - Regions: matcher.Regions, - Integration: matcher.Integration, - DiscoveryConfigName: discoveryConfigName, - }, - ) + fetcherCfg := azure_sync.Config{ + CloudClients: s.CloudClients, + SubscriptionID: matcher.SubscriptionID, + Regions: matcher.Regions, + Integration: matcher.Integration, + DiscoveryConfigName: discoveryConfigName, + } + fetcher, err := azure_sync.NewFetcher(fetcherCfg, s.ctx) if err != nil { errs = append(errs, err) continue diff --git a/lib/srv/discovery/common/reconcile.go b/lib/srv/discovery/common/reconcile.go new file mode 100644 index 0000000000000..9161ae69b95b1 --- /dev/null +++ b/lib/srv/discovery/common/reconcile.go @@ -0,0 +1,32 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +func DeduplicateSlice[T any](s []T, key func(T) string) []T { + out := make([]T, 0, len(s)) + seen := make(map[string]struct{}) + for _, v := range s { + if _, ok := seen[key(v)]; ok { + continue + } + seen[key(v)] = struct{}{} + out = append(out, v) + } + return out +} diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index 141e2cd6d613a..d752e1415e5cf 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -23,6 +23,7 @@ import ( "crypto/tls" "errors" "fmt" + azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" "log/slog" "slices" "strings" @@ -376,11 +377,17 @@ type Server struct { muDynamicServerGCPFetchers sync.RWMutex staticServerGCPFetchers []server.Fetcher - // dynamicTAGSyncFetchers holds the current TAG Fetchers for the Dynamic Matchers (those coming from DiscoveryConfig resource). + // dynamicTAGAWSFetchers holds the current TAG Fetchers for the Dynamic Matchers (those coming from DiscoveryConfig resource). // The key is the DiscoveryConfig name. - dynamicTAGSyncFetchers map[string][]aws_sync.AWSSync - muDynamicTAGSyncFetchers sync.RWMutex - staticTAGSyncFetchers []aws_sync.AWSSync + dynamicTAGAWSFetchers map[string][]aws_sync.AWSSync + muDynamicTAGAWSFetchers sync.RWMutex + staticTAGAWSFetchers []aws_sync.AWSSync + + // dynamicTAGAzureFetchers holds the current TAG Fetchers for the Dynamic Matchers (those coming from DiscoveryConfig resource). + // The key is the DiscoveryConfig name. + dynamicTAGAzureFetchers map[string][]*azure_sync.Fetcher + muDynamicTAGAzureFetchers sync.RWMutex + staticTAGAzureFetchers []*azure_sync.Fetcher // dynamicKubeFetchers holds the current kube fetchers that use integration as a source of credentials, // for the Dynamic Matchers (those coming from DiscoveryConfig resource). @@ -426,7 +433,7 @@ func New(ctx context.Context, cfg *Config) (*Server, error) { dynamicServerAWSFetchers: make(map[string][]server.Fetcher), dynamicServerAzureFetchers: make(map[string][]server.Fetcher), dynamicServerGCPFetchers: make(map[string][]server.Fetcher), - dynamicTAGSyncFetchers: make(map[string][]aws_sync.AWSSync), + dynamicTAGAWSFetchers: make(map[string][]aws_sync.AWSSync), dynamicDiscoveryConfig: make(map[string]*discoveryconfig.DiscoveryConfig), awsSyncStatus: awsSyncStatus{}, awsEC2ResourcesStatus: newAWSResourceStatusCollector(types.AWSMatcherEC2), @@ -1669,9 +1676,9 @@ func (s *Server) deleteDynamicFetchers(name string) { delete(s.dynamicServerGCPFetchers, name) s.muDynamicServerGCPFetchers.Unlock() - s.muDynamicTAGSyncFetchers.Lock() - delete(s.dynamicTAGSyncFetchers, name) - s.muDynamicTAGSyncFetchers.Unlock() + s.muDynamicTAGAWSFetchers.Lock() + delete(s.dynamicTAGAWSFetchers, name) + s.muDynamicTAGAWSFetchers.Unlock() s.muDynamicKubeFetchers.Lock() delete(s.dynamicKubeFetchers, name) @@ -1725,9 +1732,9 @@ func (s *Server) upsertDynamicMatchers(ctx context.Context, dc *discoveryconfig. if err != nil { return trace.Wrap(err) } - s.muDynamicTAGSyncFetchers.Lock() - s.dynamicTAGSyncFetchers[dc.GetName()] = awsSyncMatchers - s.muDynamicTAGSyncFetchers.Unlock() + s.muDynamicTAGAWSFetchers.Lock() + s.dynamicTAGAWSFetchers[dc.GetName()] = awsSyncMatchers + s.muDynamicTAGAWSFetchers.Unlock() kubeFetchers, err := s.kubeFetchersFromMatchers(matchers, dc.GetName()) if err != nil { diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index ac69560c0ea70..f84860d7d54ed 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -19,50 +19,24 @@ package azure_sync import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" "github.com/gravitational/teleport/lib/cloud" + "github.com/gravitational/teleport/lib/cloud/azure" + "github.com/gravitational/teleport/lib/srv/discovery/common" "github.com/gravitational/trace" "golang.org/x/sync/errgroup" "sync" ) -/* - * Teleport - * Copyright (C) 2024 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package azure_sync - -import ( -"context" -accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" -"github.com/gravitational/teleport/lib/cloud" -"github.com/gravitational/teleport/lib/srv/discovery/common" -"github.com/gravitational/trace" -"golang.org/x/sync/errgroup" -"sync" -) - const ( - featNamePrincipals = "azure/principals" - featNameRoleDefinitions = "azure/roledefinitions" - featNameRoleAssignments = "azure/roleassignments" - featNameVms = "azure/virtualmachines" - featNameManagedDatabases = "azure/databases" - featNameAKSClusters = "azure/aksclusters" + featNamePrincipals = "azure/principals" + featNameRoleDefinitions = "azure/roledefinitions" + featNameRoleAssignments = "azure/roleassignments" + featNameVms = "azure/virtualmachines" ) const FetcherConcurrency = 5 @@ -82,37 +56,59 @@ type Resources struct { VirtualMachines []*accessgraphv1alpha.AzureVirtualMachine } -type Features struct { - Principals bool - RoleDefinitions bool - RoleAssignments bool - VirtualMachines bool - ManagedDatabases bool - AKSClusters bool -} +type RoleDefinitionsClient interface{} + +type RoleAssignmentsClient interface{} -type Fetcher interface { - Poll(context.Context, Features) (*Resources, error) - Status() (uint64, error) - DiscoveryConfigName() string - IsFromDiscoveryConfig() bool - GetSubscriptionID() string +type VirtualMachinesClient interface { + ListVirtualMachines(ctx context.Context, resourceGroup string) ([]*armcompute.VirtualMachine, error) } -type azureFetcher struct { +type Fetcher struct { Config lastError error lastDiscoveredResources uint64 lastResult *Resources + + graphClient *GraphClient + vmClient VirtualMachinesClient + roleDefClient RoleDefinitionsClient + roleAssignClient RoleAssignmentsClient } -func NewFetcher(cfg Config) (Fetcher, error) { - return &azureFetcher{ +func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { + cred, err := azidentity.NewManagedIdentityCredential(nil) + if err != nil { + return nil, trace.Wrap(err) + } + token, err := cred.GetToken(ctx, policy.TokenRequestOptions{}) + if err != nil { + return nil, trace.Wrap(err) + } + staticCred := azure.NewStaticCredential(token) + + // Create the clients + vmClient, err := azure.NewVirtualMachinesClient(cfg.SubscriptionID, staticCred, nil) + if err != nil { + return nil, trace.Wrap(err) + } + + return &Fetcher{ Config: cfg, lastResult: &Resources{}, + vmClient: vmClient, }, nil } +type Features struct { + Principals bool + RoleDefinitions bool + RoleAssignments bool + VirtualMachines bool + ManagedDatabases bool + AKSClusters bool +} + // BuildFeatures builds the feature flags based on supported types returned by Access Graph // Azure endpoints. func BuildFeatures(values ...string) Features { @@ -127,16 +123,13 @@ func BuildFeatures(values ...string) Features { features.RoleDefinitions = true case featNameRoleAssignments: features.RoleAssignments = true - case featNameManagedDatabases: - features.ManagedDatabases = true - case featNameAKSClusters: features.AKSClusters = true } } return features } -func (a *azureFetcher) Poll(ctx context.Context, feats Features) (*Resources, error) { +func (a *Fetcher) Poll(ctx context.Context, feats Features) (*Resources, error) { res, err := a.fetch(ctx, feats) if res == nil { return nil, err @@ -148,7 +141,7 @@ func (a *azureFetcher) Poll(ctx context.Context, feats Features) (*Resources, er return res, trace.Wrap(err) } -func (a *azureFetcher) fetch(ctx context.Context, feats Features) (*Resources, error) { +func (a *Fetcher) fetch(ctx context.Context, feats Features) (*Resources, error) { // Accumulate Azure resources eg, ctx := errgroup.WithContext(ctx) eg.SetLimit(FetcherConcurrency) @@ -224,16 +217,16 @@ func (a *azureFetcher) fetch(ctx context.Context, feats Features) (*Resources, e return result, nil } -func (a *azureFetcher) Status() (uint64, error) { +func (a *Fetcher) Status() (uint64, error) { return a.lastDiscoveredResources, a.lastError } -func (a *azureFetcher) DiscoveryConfigName() string { +func (a *Fetcher) DiscoveryConfigName() string { return a.Config.DiscoveryConfigName } -func (a *azureFetcher) IsFromDiscoveryConfig() bool { +func (a *Fetcher) IsFromDiscoveryConfig() bool { return a.Config.DiscoveryConfigName != "" } -func (a *azureFetcher) GetSubscriptionID() string { +func (a *Fetcher) GetSubscriptionID() string { return a.Config.SubscriptionID } diff --git a/lib/srv/discovery/fetchers/azure-sync/principals.go b/lib/srv/discovery/fetchers/azure-sync/principals.go new file mode 100644 index 0000000000000..be01af350bb76 --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/principals.go @@ -0,0 +1,63 @@ +package azure_sync + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" + "slices" +) + +const groupType = "#microsoft.graph.group" + +func (a *Fetcher) fetchPrincipals(ctx context.Context) ([]*accessgraphv1alpha.AzurePrincipal, error) { + // Get the VM client + cred, err := a.CloudClients.GetAzureCredential() + if err != nil { + return nil, trace.Wrap(err) + } + scopes := []string{"https://graph.microsoft.com/.default"} + token, err := cred.GetToken(ctx, policy.TokenRequestOptions{Scopes: scopes}) + if err != nil { + return nil, trace.Wrap(err) + } + cli := NewGraphClient(token) + + // Fetch the users, groups, and managed identities + users, err := cli.ListUsers(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + groups, err := cli.ListGroups(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + svcPrincipals, err := cli.ListServicePrincipals(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + principals := slices.Concat(users, groups, svcPrincipals) + + // Return the users as protobuf messages + pbPrincipals := make([]*accessgraphv1alpha.AzurePrincipal, 0, len(principals)) + for _, principal := range principals { + // Extract group membership + memberOf := make([]string, 0) + for _, member := range principal.MemberOf { + if member.Type == groupType { + memberOf = append(memberOf, member.ID) + } + } + // Create the protobuf principal and append it to the list + pbPrincipal := &accessgraphv1alpha.AzurePrincipal{ + Id: principal.ID, + SubscriptionId: a.GetSubscriptionID(), + LastSyncTime: timestamppb.Now(), + DisplayName: principal.Name, + MemberOf: memberOf, + } + pbPrincipals = append(pbPrincipals, pbPrincipal) + } + return pbPrincipals, nil +} diff --git a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go index 93c2690c7b19b..8b9d235cad9b2 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go +++ b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go @@ -26,7 +26,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -func (a *azureFetcher) fetchRoleAssignments(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleAssignment, error) { +func (a *Fetcher) fetchRoleAssignments(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleAssignment, error) { // Get the Role Assignments client cli, err := a.CloudClients.GetAzureRoleAssignmentsClient(a.GetSubscriptionID()) if err != nil { diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go index 89813980d729c..fac5a7015556e 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -17,3 +17,46 @@ */ package azure_sync + +import ( + "context" + "fmt" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleDefinition, error) { + // Get the Role Definitions client + cli, err := a.CloudClients.GetAzureRoleDefinitionsClient(a.GetSubscriptionID()) + if err != nil { + return nil, trace.Wrap(err) + } + + // List the role definitions + roleDefs, err := cli.ListRoleDefinitions(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) + if err != nil { + return nil, trace.Wrap(err) + } + + // Convert to protobuf format + pbRoleDefs := make([]*accessgraphv1alpha.AzureRoleDefinition, 0, len(roleDefs)) + for _, roleDef := range roleDefs { + pbPerms := make([]*accessgraphv1alpha.AzureRBACPermission, len(roleDef.Properties.Permissions)) + for _, perm := range roleDef.Properties.Permissions { + pbPerm := accessgraphv1alpha.AzureRBACPermission{ + Actions: ptrsToList(perm.Actions), + } + pbPerms = append(pbPerms, &pbPerm) + } + pbRoleDef := &accessgraphv1alpha.AzureRoleDefinition{ + Id: *roleDef.ID, + Name: *roleDef.Properties.RoleName, + SubscriptionId: a.SubscriptionID, + LastSyncTime: timestamppb.Now(), + Permissions: pbPerms, + } + pbRoleDefs = append(pbRoleDefs, pbRoleDef) + } + return pbRoleDefs, nil +} diff --git a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go new file mode 100644 index 0000000000000..76b8e65317ed7 --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go @@ -0,0 +1,53 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package azure_sync + +import ( + "context" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (a *Fetcher) fetchVirtualMachines(ctx context.Context) ([]*accessgraphv1alpha.AzureVirtualMachine, error) { + // Get the VM client + cli, err := a.CloudClients.GetAzureVirtualMachinesClient(a.GetSubscriptionID()) + if err != nil { + return nil, trace.Wrap(err) + } + + // Fetch the VMs + vms, err := cli.ListVirtualMachines(ctx, "*") + if err != nil { + return nil, trace.Wrap(err) + } + + // Return the VMs as protobuf messages + pbVms := make([]*accessgraphv1alpha.AzureVirtualMachine, 0, len(vms)) + for _, vm := range vms { + pbVm := accessgraphv1alpha.AzureVirtualMachine{ + Id: *vm.ID, + SubscriptionId: a.GetSubscriptionID(), + LastSyncTime: timestamppb.Now(), + Name: *vm.Name, + } + pbVms = append(pbVms, &pbVm) + } + return pbVms, nil +} From 37799987df7ce195ea1fb71cc57d140909c5db7e Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 7 Nov 2024 14:53:10 -0600 Subject: [PATCH 14/36] Adding Azure role definitions and assignments clients --- go.mod | 1 + lib/cloud/azure/roleassignments.go | 39 +++++++++++++++++++++++++++++ lib/cloud/azure/roledefinitions.go | 39 +++++++++++++++++++++++++++++ lib/cloud/clients.go | 40 +++++++++++++++++++++++++++++- 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 lib/cloud/azure/roleassignments.go create mode 100644 lib/cloud/azure/roledefinitions.go diff --git a/go.mod b/go.mod index fa63fe6eb8695..4b7a13bd836e9 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( connectrpc.com/connect v1.17.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go new file mode 100644 index 0000000000000..aca82fe34a309 --- /dev/null +++ b/lib/cloud/azure/roleassignments.go @@ -0,0 +1,39 @@ +package azure + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" + "github.com/gravitational/trace" +) + +type RoleAssignmentsClient interface { + ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) +} + +type roleAssignmentsClient struct { + cli *armauthorization.RoleAssignmentsClient +} + +func (c *roleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { + pager := c.cli.NewListForScopePager(scope, nil) + roleDefs := make([]*armauthorization.RoleAssignment, 0, 128) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefs = append(roleDefs, page.Value...) + } + return roleDefs, nil +} + +func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (RoleAssignmentsClient, error) { + clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefCli := clientFactory.NewRoleAssignmentsClient() + return &roleAssignmentsClient{cli: roleDefCli}, nil +} diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go new file mode 100644 index 0000000000000..aebf1345b75dd --- /dev/null +++ b/lib/cloud/azure/roledefinitions.go @@ -0,0 +1,39 @@ +package azure + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" + "github.com/gravitational/trace" +) + +type RoleDefinitionsClient interface { + ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) +} + +type roleDefinitionsClient struct { + cli *armauthorization.RoleDefinitionsClient +} + +func (c *roleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { + pager := c.cli.NewListPager(scope, nil) + roleDefs := make([]*armauthorization.RoleDefinition, 0, 128) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefs = append(roleDefs, page.Value...) + } + return roleDefs, nil +} + +func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (RoleDefinitionsClient, error) { + clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefCli := clientFactory.NewRoleDefinitionsClient() + return &roleDefinitionsClient{cli: roleDefCli}, nil +} diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index 93bb27f90b246..c61b0e60d8cf3 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -171,6 +171,10 @@ type AzureClients interface { GetAzurePostgresFlexServersClient(subscription string) (azure.PostgresFlexServersClient, error) // GetAzureRunCommandClient returns an Azure Run Command client for the given subscription. GetAzureRunCommandClient(subscription string) (azure.RunCommandClient, error) + // GetAzureRoleDefinitionsClient returns an Azure Role Definitions client for the given subscription. + GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) + // GetAzureRoleAssignmentsClient returns an Azure Role Assignment client for the given subscription. + GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) } type clientConstructor[T any] func(context.Context) (T, error) @@ -236,6 +240,14 @@ func newAzureClients() (*azureClients, error) { if err != nil { return nil, trace.Wrap(err) } + azClients.azureRoleDefinitionsClients, err = azure.NewClientMap(azure.NewRoleDefinitionsClient) + if err != nil { + return nil, trace.Wrap(err) + } + azClients.azureRoleAssignmentsClients, err = azure.NewClientMap(azure.NewRoleAssignmentsClient) + if err != nil { + return nil, trace.Wrap(err) + } return azClients, nil } @@ -356,6 +368,10 @@ type azureClients struct { azurePostgresFlexServersClients azure.ClientMap[azure.PostgresFlexServersClient] // azureRunCommandClients contains the cached Azure Run Command clients. azureRunCommandClients azure.ClientMap[azure.RunCommandClient] + // azureRoleDefinitionsClients contains the cached Azure Role Definitions clients. + azureRoleDefinitionsClients azure.ClientMap[azure.RoleDefinitionsClient] + // azureRoleAssignmentsClients contains the cached Azure Role Assignments clients. + azureRoleAssignmentsClients azure.ClientMap[azure.RoleAssignmentsClient] } // credentialsSource defines where the credentials must come from. @@ -756,6 +772,16 @@ func (c *cloudClients) GetAzureRunCommandClient(subscription string) (azure.RunC return c.azureRunCommandClients.Get(subscription, c.GetAzureCredential) } +// GetAzureRoleDefinitionsClient returns an Azure Role Definitions client +func (c *cloudClients) GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) { + return c.azureRoleDefinitionsClients.Get(subscription, c.GetAzureCredential) +} + +// GetAzureRoleAssignmentsClient returns an Azure Role Assignments client +func (c *cloudClients) GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) { + return c.azureRoleAssignmentsClients.Get(subscription, c.GetAzureCredential) +} + // Close closes all initialized clients. func (c *cloudClients) Close() (err error) { c.mtx.Lock() @@ -1066,6 +1092,8 @@ type TestCloudClients struct { AzureMySQLFlex azure.MySQLFlexServersClient AzurePostgresFlex azure.PostgresFlexServersClient AzureRunCommand azure.RunCommandClient + AzureRoleDefinitions azure.RoleDefinitionsClient + AzureRoleAssignments azure.RoleAssignmentsClient } // GetAWSSession returns AWS session for the specified region, optionally @@ -1319,11 +1347,21 @@ func (c *TestCloudClients) GetAzurePostgresFlexServersClient(subscription string return c.AzurePostgresFlex, nil } -// GetAzureRunCommand returns an Azure Run Command client for the given subscription. +// GetAzureRunCommandClient returns an Azure Run Command client for the given subscription. func (c *TestCloudClients) GetAzureRunCommandClient(subscription string) (azure.RunCommandClient, error) { return c.AzureRunCommand, nil } +// GetAzureRoleDefinitionsClient returns an Azure Role Definitions client for the given subscription. +func (c *TestCloudClients) GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) { + return c.AzureRoleDefinitions, nil +} + +// GetAzureRoleAssignmentsClient returns an Azure Role Assignments client for the given subscription. +func (c *TestCloudClients) GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) { + return c.AzureRoleAssignments, nil +} + // Close closes all initialized clients. func (c *TestCloudClients) Close() error { return nil From 974617be5231bf5d11e6ff6d431bc6827833d668 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 11 Nov 2024 19:13:42 -0600 Subject: [PATCH 15/36] Creating local consumer interface for Azure clients in the sync package --- api/types/discoveryconfig/derived.gen.go | 14 ++++++++-- lib/cloud/azure/roleassignments.go | 24 +++++++---------- lib/cloud/azure/roledefinitions.go | 24 +++++++---------- lib/cloud/clients.go | 12 --------- .../fetchers/azure-sync/azure-sync.go | 27 +++++++++++++++---- .../fetchers/azure-sync/roleassignments.go | 8 +----- .../fetchers/azure-sync/roledefinitions.go | 8 +----- 7 files changed, 56 insertions(+), 61 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index 9053fdd312473..b95a3a3e8ffbe 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -279,8 +279,18 @@ func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { this.Integration == that.Integration } -// deriveTeleportEqual_19 returns whether this and that are equal. -func deriveTeleportEqual_19(this, that *types.AzureInstallerParams) bool { +// deriveTeleportEqual_20 returns whether this and that are equal. +func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { + return (this == nil && that == nil) || + this != nil && that != nil && + deriveTeleportEqual_14(this.Regions, that.Regions) && + this.SubscriptionID == that.SubscriptionID && + this.UmiClientId == that.UmiClientId && + this.Integration == that.Integration +} + +// deriveTeleportEqual_21 returns whether this and that are equal. +func deriveTeleportEqual_21(this, that *types.AzureInstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.ClientID == that.ClientID diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go index aca82fe34a309..94af4dbbbd4d4 100644 --- a/lib/cloud/azure/roleassignments.go +++ b/lib/cloud/azure/roleassignments.go @@ -8,15 +8,20 @@ import ( "github.com/gravitational/trace" ) -type RoleAssignmentsClient interface { - ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) +type RoleAssignmentsClient struct { + cli *armauthorization.RoleAssignmentsClient } -type roleAssignmentsClient struct { - cli *armauthorization.RoleAssignmentsClient +func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentsClient, error) { + clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefCli := clientFactory.NewRoleAssignmentsClient() + return &RoleAssignmentsClient{cli: roleDefCli}, nil } -func (c *roleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { +func (c *RoleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { pager := c.cli.NewListForScopePager(scope, nil) roleDefs := make([]*armauthorization.RoleAssignment, 0, 128) for pager.More() { @@ -28,12 +33,3 @@ func (c *roleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope s } return roleDefs, nil } - -func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (RoleAssignmentsClient, error) { - clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) - if err != nil { - return nil, trace.Wrap(err) - } - roleDefCli := clientFactory.NewRoleAssignmentsClient() - return &roleAssignmentsClient{cli: roleDefCli}, nil -} diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go index aebf1345b75dd..45b90a06dc688 100644 --- a/lib/cloud/azure/roledefinitions.go +++ b/lib/cloud/azure/roledefinitions.go @@ -8,15 +8,20 @@ import ( "github.com/gravitational/trace" ) -type RoleDefinitionsClient interface { - ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) +type RoleDefinitionsClient struct { + cli *armauthorization.RoleDefinitionsClient } -type roleDefinitionsClient struct { - cli *armauthorization.RoleDefinitionsClient +func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleDefinitionsClient, error) { + clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) + if err != nil { + return nil, trace.Wrap(err) + } + roleDefCli := clientFactory.NewRoleDefinitionsClient() + return &RoleDefinitionsClient{cli: roleDefCli}, nil } -func (c *roleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { +func (c *RoleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { pager := c.cli.NewListPager(scope, nil) roleDefs := make([]*armauthorization.RoleDefinition, 0, 128) for pager.More() { @@ -28,12 +33,3 @@ func (c *roleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope s } return roleDefs, nil } - -func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (RoleDefinitionsClient, error) { - clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) - if err != nil { - return nil, trace.Wrap(err) - } - roleDefCli := clientFactory.NewRoleDefinitionsClient() - return &roleDefinitionsClient{cli: roleDefCli}, nil -} diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index c61b0e60d8cf3..66a2fe9a5c71b 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -171,10 +171,6 @@ type AzureClients interface { GetAzurePostgresFlexServersClient(subscription string) (azure.PostgresFlexServersClient, error) // GetAzureRunCommandClient returns an Azure Run Command client for the given subscription. GetAzureRunCommandClient(subscription string) (azure.RunCommandClient, error) - // GetAzureRoleDefinitionsClient returns an Azure Role Definitions client for the given subscription. - GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) - // GetAzureRoleAssignmentsClient returns an Azure Role Assignment client for the given subscription. - GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) } type clientConstructor[T any] func(context.Context) (T, error) @@ -240,14 +236,6 @@ func newAzureClients() (*azureClients, error) { if err != nil { return nil, trace.Wrap(err) } - azClients.azureRoleDefinitionsClients, err = azure.NewClientMap(azure.NewRoleDefinitionsClient) - if err != nil { - return nil, trace.Wrap(err) - } - azClients.azureRoleAssignmentsClients, err = azure.NewClientMap(azure.NewRoleAssignmentsClient) - if err != nil { - return nil, trace.Wrap(err) - } return azClients, nil } diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index f84860d7d54ed..19a3ce8d0b9ac 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -22,6 +22,7 @@ import ( "context" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" "github.com/gravitational/teleport/lib/cloud" @@ -56,9 +57,13 @@ type Resources struct { VirtualMachines []*accessgraphv1alpha.AzureVirtualMachine } -type RoleDefinitionsClient interface{} +type RoleDefinitionsClient interface { + ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) +} -type RoleAssignmentsClient interface{} +type RoleAssignmentsClient interface { + ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) +} type VirtualMachinesClient interface { ListVirtualMachines(ctx context.Context, resourceGroup string) ([]*armcompute.VirtualMachine, error) @@ -77,6 +82,7 @@ type Fetcher struct { } func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { + // Establish the credential from the managed identity cred, err := azidentity.NewManagedIdentityCredential(nil) if err != nil { return nil, trace.Wrap(err) @@ -92,11 +98,22 @@ func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { if err != nil { return nil, trace.Wrap(err) } + roleDefClient, err := azure.NewRoleDefinitionsClient(cfg.SubscriptionID, staticCred, nil) + if err != nil { + return nil, trace.Wrap(err) + } + roleAssignClient, err := azure.NewRoleAssignmentsClient(cfg.SubscriptionID, staticCred, nil) + if err != nil { + return nil, trace.Wrap(err) + } + // Create and return the fetcher return &Fetcher{ - Config: cfg, - lastResult: &Resources{}, - vmClient: vmClient, + Config: cfg, + lastResult: &Resources{}, + vmClient: vmClient, + roleDefClient: roleDefClient, + roleAssignClient: roleAssignClient, }, nil } diff --git a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go index 8b9d235cad9b2..c497ca8baabdd 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go +++ b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go @@ -27,14 +27,8 @@ import ( ) func (a *Fetcher) fetchRoleAssignments(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleAssignment, error) { - // Get the Role Assignments client - cli, err := a.CloudClients.GetAzureRoleAssignmentsClient(a.GetSubscriptionID()) - if err != nil { - return nil, trace.Wrap(err) - } - // List the role definitions - roleAssigns, err := cli.ListRoleAssignments(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) + roleAssigns, err := a.roleAssignClient.ListRoleAssignments(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go index fac5a7015556e..e24f65804d253 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -27,14 +27,8 @@ import ( ) func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleDefinition, error) { - // Get the Role Definitions client - cli, err := a.CloudClients.GetAzureRoleDefinitionsClient(a.GetSubscriptionID()) - if err != nil { - return nil, trace.Wrap(err) - } - // List the role definitions - roleDefs, err := cli.ListRoleDefinitions(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) + roleDefs, err := a.roleDefClient.ListRoleDefinitions(ctx, fmt.Sprintf("/subscriptions/%s", a.SubscriptionID)) if err != nil { return nil, trace.Wrap(err) } From 2f2c6efcba7b8c0a43e33e7506eeed215c763e7f Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 17:26:39 -0600 Subject: [PATCH 16/36] Using the common deduplication function, and unit testing azure reconciliation --- lib/srv/discovery/fetchers/aws-sync/merge.go | 42 ++-- .../discovery/fetchers/aws-sync/merge_test.go | 7 +- .../discovery/fetchers/aws-sync/reconcile.go | 16 +- .../fetchers/azure-sync/azure-sync.go | 2 +- .../fetchers/azure-sync/reconcile.go | 8 +- .../fetchers/azure-sync/reconcile_test.go | 189 ++++++++++++++++++ 6 files changed, 222 insertions(+), 42 deletions(-) create mode 100644 lib/srv/discovery/fetchers/azure-sync/reconcile_test.go diff --git a/lib/srv/discovery/fetchers/aws-sync/merge.go b/lib/srv/discovery/fetchers/aws-sync/merge.go index 6847243e13782..1249cf00120e3 100644 --- a/lib/srv/discovery/fetchers/aws-sync/merge.go +++ b/lib/srv/discovery/fetchers/aws-sync/merge.go @@ -18,6 +18,8 @@ package aws_sync +import "github.com/gravitational/teleport/lib/srv/discovery/common" + // MergeResources merges multiple resources into a single Resources object. // This is used to merge resources from multiple accounts and regions // into a single object. @@ -58,24 +60,24 @@ func MergeResources(results ...*Resources) *Resources { } func deduplicateResources(result *Resources) { - result.Users = deduplicateSlice(result.Users, usersKey) - result.UserInlinePolicies = deduplicateSlice(result.UserInlinePolicies, userInlinePolKey) - result.UserAttachedPolicies = deduplicateSlice(result.UserAttachedPolicies, userAttchPolKey) - result.UserGroups = deduplicateSlice(result.UserGroups, userGroupKey) - result.Groups = deduplicateSlice(result.Groups, groupKey) - result.GroupInlinePolicies = deduplicateSlice(result.GroupInlinePolicies, grpInlinePolKey) - result.GroupAttachedPolicies = deduplicateSlice(result.GroupAttachedPolicies, grpAttchPolKey) - result.Instances = deduplicateSlice(result.Instances, instanceKey) - result.Policies = deduplicateSlice(result.Policies, policyKey) - result.S3Buckets = deduplicateSlice(result.S3Buckets, s3bucketKey) - result.Roles = deduplicateSlice(result.Roles, roleKey) - result.RoleInlinePolicies = deduplicateSlice(result.RoleInlinePolicies, roleInlinePolKey) - result.RoleAttachedPolicies = deduplicateSlice(result.RoleAttachedPolicies, roleAttchPolKey) - result.InstanceProfiles = deduplicateSlice(result.InstanceProfiles, instanceProfKey) - result.AssociatedAccessPolicies = deduplicateSlice(result.AssociatedAccessPolicies, assocAccPolKey) - result.EKSClusters = deduplicateSlice(result.EKSClusters, eksClusterKey) - result.AccessEntries = deduplicateSlice(result.AccessEntries, accessEntryKey) - result.RDSDatabases = deduplicateSlice(result.RDSDatabases, rdsDbKey) - result.SAMLProviders = deduplicateSlice(result.SAMLProviders, samlProvKey) - result.OIDCProviders = deduplicateSlice(result.OIDCProviders, oidcProvKey) + result.Users = common.DeduplicateSlice(result.Users, usersKey) + result.UserInlinePolicies = common.DeduplicateSlice(result.UserInlinePolicies, userInlinePolKey) + result.UserAttachedPolicies = common.DeduplicateSlice(result.UserAttachedPolicies, userAttchPolKey) + result.UserGroups = common.DeduplicateSlice(result.UserGroups, userGroupKey) + result.Groups = common.DeduplicateSlice(result.Groups, groupKey) + result.GroupInlinePolicies = common.DeduplicateSlice(result.GroupInlinePolicies, grpInlinePolKey) + result.GroupAttachedPolicies = common.DeduplicateSlice(result.GroupAttachedPolicies, grpAttchPolKey) + result.Instances = common.DeduplicateSlice(result.Instances, instanceKey) + result.Policies = common.DeduplicateSlice(result.Policies, policyKey) + result.S3Buckets = common.DeduplicateSlice(result.S3Buckets, s3bucketKey) + result.Roles = common.DeduplicateSlice(result.Roles, roleKey) + result.RoleInlinePolicies = common.DeduplicateSlice(result.RoleInlinePolicies, roleInlinePolKey) + result.RoleAttachedPolicies = common.DeduplicateSlice(result.RoleAttachedPolicies, roleAttchPolKey) + result.InstanceProfiles = common.DeduplicateSlice(result.InstanceProfiles, instanceProfKey) + result.AssociatedAccessPolicies = common.DeduplicateSlice(result.AssociatedAccessPolicies, assocAccPolKey) + result.EKSClusters = common.DeduplicateSlice(result.EKSClusters, eksClusterKey) + result.AccessEntries = common.DeduplicateSlice(result.AccessEntries, accessEntryKey) + result.RDSDatabases = common.DeduplicateSlice(result.RDSDatabases, rdsDbKey) + result.SAMLProviders = common.DeduplicateSlice(result.SAMLProviders, samlProvKey) + result.OIDCProviders = common.DeduplicateSlice(result.OIDCProviders, oidcProvKey) } diff --git a/lib/srv/discovery/fetchers/aws-sync/merge_test.go b/lib/srv/discovery/fetchers/aws-sync/merge_test.go index b109782ed1333..be19486e567c8 100644 --- a/lib/srv/discovery/fetchers/aws-sync/merge_test.go +++ b/lib/srv/discovery/fetchers/aws-sync/merge_test.go @@ -19,6 +19,7 @@ package aws_sync import ( + "github.com/gravitational/teleport/lib/srv/discovery/common" "testing" "github.com/google/go-cmp/cmp" @@ -45,9 +46,9 @@ func TestMergeResources(t *testing.T) { result := MergeResources(&oldResults, &newResults) expected := Resources{ - Users: deduplicateSlice(append(oldUsers, newUsers...), usersKey), - Roles: deduplicateSlice(append(oldRoles, newRoles...), roleKey), - Instances: deduplicateSlice(append(oldEC2, newEC2...), instanceKey), + Users: common.DeduplicateSlice(append(oldUsers, newUsers...), usersKey), + Roles: common.DeduplicateSlice(append(oldRoles, newRoles...), roleKey), + Instances: common.DeduplicateSlice(append(oldEC2, newEC2...), instanceKey), } require.Empty(t, cmp.Diff(&expected, result, protocmp.Transform(), cmpopts.EquateEmpty())) } diff --git a/lib/srv/discovery/fetchers/aws-sync/reconcile.go b/lib/srv/discovery/fetchers/aws-sync/reconcile.go index d9bfc3330ce69..753f1d1ca3bc3 100644 --- a/lib/srv/discovery/fetchers/aws-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/aws-sync/reconcile.go @@ -20,6 +20,7 @@ package aws_sync import ( "fmt" + "github.com/gravitational/teleport/lib/srv/discovery/common" "google.golang.org/protobuf/proto" @@ -71,19 +72,6 @@ type reconcilePair struct { upsert, delete *accessgraphv1alpha.AWSResourceList } -func deduplicateSlice[T any](s []T, key func(T) string) []T { - out := make([]T, 0, len(s)) - seen := make(map[string]struct{}) - for _, v := range s { - if _, ok := seen[key(v)]; ok { - continue - } - seen[key(v)] = struct{}{} - out = append(out, v) - } - return out -} - func reconcile[T proto.Message]( oldItems []T, newItems []T, @@ -91,7 +79,7 @@ func reconcile[T proto.Message]( wrapFn func(T) *accessgraphv1alpha.AWSResource, ) *reconcilePair { // Remove duplicates from the new items - newItems = deduplicateSlice(newItems, keyFn) + newItems = common.DeduplicateSlice(newItems, keyFn) upsertRes := newResourceList() deleteRes := newResourceList() diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index 19a3ce8d0b9ac..b6bfc60fa18ac 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -152,7 +152,7 @@ func (a *Fetcher) Poll(ctx context.Context, feats Features) (*Resources, error) return nil, err } res.VirtualMachines = common.DeduplicateSlice(res.VirtualMachines, azureVmKey) - res.Principals = common.DeduplicateSlice(res.Principals, azureUserKey) + res.Principals = common.DeduplicateSlice(res.Principals, azurePrincipalsKey) res.RoleDefinitions = common.DeduplicateSlice(res.RoleDefinitions, azureRoleDefKey) res.RoleAssignments = common.DeduplicateSlice(res.RoleAssignments, azureRoleAssignKey) return res, trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile.go b/lib/srv/discovery/fetchers/azure-sync/reconcile.go index 60169d877b488..5d80878504eb3 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile.go @@ -37,7 +37,7 @@ func MergeResources(results ...*Resources) *Resources { result.Principals = append(result.Principals, r.Principals...) result.VirtualMachines = append(result.VirtualMachines, r.VirtualMachines...) } - result.Principals = common.DeduplicateSlice(result.Principals, azureUserKey) + result.Principals = common.DeduplicateSlice(result.Principals, azurePrincipalsKey) result.VirtualMachines = common.DeduplicateSlice(result.VirtualMachines, azureVmKey) return result } @@ -52,7 +52,7 @@ func ReconcileResults(old *Resources, new *Resources) (upsert, delete *accessgra upsert, delete = newResourceList(), newResourceList() reconciledResources := []*reconcilePair{ reconcile(old.VirtualMachines, new.VirtualMachines, azureVmKey, azureVmWrap), - reconcile(old.Principals, new.Principals, azureUserKey, azureUsersWrap), + reconcile(old.Principals, new.Principals, azurePrincipalsKey, azurePrincipalsWrap), reconcile(old.RoleDefinitions, new.RoleDefinitions, azureRoleDefKey, azureRoleDefWrap), reconcile(old.RoleAssignments, new.RoleAssignments, azureRoleAssignKey, azureRoleAssignWrap), } @@ -128,11 +128,11 @@ func azureVmWrap(vm *accessgraphv1alpha.AzureVirtualMachine) *accessgraphv1alpha return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_VirtualMachine{VirtualMachine: vm}} } -func azureUserKey(user *accessgraphv1alpha.AzurePrincipal) string { +func azurePrincipalsKey(user *accessgraphv1alpha.AzurePrincipal) string { return fmt.Sprintf("%s:%s", user.SubscriptionId, user.Id) } -func azureUsersWrap(principal *accessgraphv1alpha.AzurePrincipal) *accessgraphv1alpha.AzureResource { +func azurePrincipalsWrap(principal *accessgraphv1alpha.AzurePrincipal) *accessgraphv1alpha.AzureResource { return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_Principal{Principal: principal}} } diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go new file mode 100644 index 0000000000000..e9d298a9ec5fb --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go @@ -0,0 +1,189 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package azure_sync + +import ( + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/stretchr/testify/require" + "testing" +) + +func TestReconcileResults(t *testing.T) { + principals := generatePrincipals() + roleDefs := generateRoleDefs() + roleAssigns := generateRoleAssigns() + vms := generateVms() + + tests := []struct { + oldResults *Resources + newResults *Resources + expectedUpserts *accessgraphv1alpha.AzureResourceList + expectedDeletes *accessgraphv1alpha.AzureResourceList + }{ + // Overlapping old and new results + { + oldResults: &Resources{ + Principals: principals[0:2], + RoleDefinitions: roleDefs[0:2], + RoleAssignments: roleAssigns[0:2], + VirtualMachines: vms[0:2], + }, + newResults: &Resources{ + Principals: principals[1:3], + RoleDefinitions: roleDefs[1:3], + RoleAssignments: roleAssigns[1:3], + VirtualMachines: vms[1:3], + }, + expectedUpserts: generateExpected(principals[2:3], roleDefs[2:3], roleAssigns[2:3], vms[2:3]), + expectedDeletes: generateExpected(principals[0:1], roleDefs[0:1], roleAssigns[0:1], vms[0:1]), + }, + // Completely new results + { + oldResults: &Resources{ + Principals: nil, + RoleDefinitions: nil, + RoleAssignments: nil, + VirtualMachines: nil, + }, + newResults: &Resources{ + Principals: principals[1:3], + RoleDefinitions: roleDefs[1:3], + RoleAssignments: roleAssigns[1:3], + VirtualMachines: vms[1:3], + }, + expectedUpserts: generateExpected(principals[1:3], roleDefs[1:3], roleAssigns[1:3], vms[1:3]), + expectedDeletes: generateExpected(nil, nil, nil, nil), + }, + // No new results + { + oldResults: &Resources{ + Principals: principals[1:3], + RoleDefinitions: roleDefs[1:3], + RoleAssignments: roleAssigns[1:3], + VirtualMachines: vms[1:3], + }, + newResults: &Resources{ + Principals: nil, + RoleDefinitions: nil, + RoleAssignments: nil, + VirtualMachines: nil, + }, + expectedUpserts: generateExpected(nil, nil, nil, nil), + expectedDeletes: generateExpected(principals[1:3], roleDefs[1:3], roleAssigns[1:3], vms[1:3]), + }, + } + + for _, test := range tests { + upserts, deletes := ReconcileResults(test.oldResults, test.newResults) + require.ElementsMatch(t, upserts.Resources, test.expectedUpserts.Resources) + require.ElementsMatch(t, deletes.Resources, test.expectedDeletes.Resources) + } + +} + +func generateExpected( + principals []*accessgraphv1alpha.AzurePrincipal, + roleDefs []*accessgraphv1alpha.AzureRoleDefinition, + roleAssigns []*accessgraphv1alpha.AzureRoleAssignment, + vms []*accessgraphv1alpha.AzureVirtualMachine, +) *accessgraphv1alpha.AzureResourceList { + resList := &accessgraphv1alpha.AzureResourceList{ + Resources: make([]*accessgraphv1alpha.AzureResource, 0), + } + for _, principal := range principals { + resList.Resources = append(resList.Resources, azurePrincipalsWrap(principal)) + } + for _, roleDef := range roleDefs { + resList.Resources = append(resList.Resources, azureRoleDefWrap(roleDef)) + } + for _, roleAssign := range roleAssigns { + resList.Resources = append(resList.Resources, azureRoleAssignWrap(roleAssign)) + } + for _, vm := range vms { + resList.Resources = append(resList.Resources, azureVmWrap(vm)) + } + return resList +} + +func generatePrincipals() []*accessgraphv1alpha.AzurePrincipal { + return []*accessgraphv1alpha.AzurePrincipal{ + { + Id: "/principals/foo", + DisplayName: "userFoo", + }, + { + Id: "/principals/bar", + DisplayName: "userBar", + }, + { + Id: "/principals/charles", + DisplayName: "userCharles", + }, + } +} + +func generateRoleDefs() []*accessgraphv1alpha.AzureRoleDefinition { + return []*accessgraphv1alpha.AzureRoleDefinition{ + { + Id: "/roledefinitions/foo", + Name: "roleFoo", + }, + { + Id: "/roledefinitions/bar", + Name: "roleBar", + }, + { + Id: "/roledefinitions/charles", + Name: "roleCharles", + }, + } +} + +func generateRoleAssigns() []*accessgraphv1alpha.AzureRoleAssignment { + return []*accessgraphv1alpha.AzureRoleAssignment{ + { + Id: "/roleassignments/foo", + PrincipalId: "userFoo", + }, + { + Id: "/roleassignments/bar", + PrincipalId: "userBar", + }, + { + Id: "/roleassignments/charles", + PrincipalId: "userCharles", + }, + } +} + +func generateVms() []*accessgraphv1alpha.AzureVirtualMachine { + return []*accessgraphv1alpha.AzureVirtualMachine{ + { + Id: "/vms/foo", + Name: "userFoo", + }, + { + Id: "/vms/bar", + Name: "userBar", + }, + { + Id: "/vms/charles", + Name: "userCharles", + }, + } +} From 0c3301774495eae1aff54360ad9dd2ea336468d6 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Wed, 13 Nov 2024 22:54:37 -0600 Subject: [PATCH 17/36] Adding unit test for azure sync --- .../fetchers/azure-sync/azure-sync_test.go | 184 ++++++++++++++++++ .../fetchers/azure-sync/reconcile_test.go | 8 +- .../fetchers/azure-sync/virtualmachines.go | 8 +- 3 files changed, 189 insertions(+), 11 deletions(-) create mode 100644 lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go new file mode 100644 index 0000000000000..ce8edb7f4588e --- /dev/null +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -0,0 +1,184 @@ +package azure_sync + +import ( + "context" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" + "github.com/stretchr/testify/require" + "testing" +) + +type testRoleDefCli struct { + returnErr bool + roleDefs []*armauthorization.RoleDefinition +} + +func (t testRoleDefCli) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { + if t.returnErr { + return nil, fmt.Errorf("error") + } + return t.roleDefs, nil +} + +type testRoleAssignCli struct { + returnErr bool + roleAssigns []*armauthorization.RoleAssignment +} + +func (t testRoleAssignCli) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { + if t.returnErr { + return nil, fmt.Errorf("error") + } + return t.roleAssigns, nil +} + +type testVmCli struct { + returnErr bool + vms []*armcompute.VirtualMachine +} + +func (t testVmCli) ListVirtualMachines(ctx context.Context, scope string) ([]*armcompute.VirtualMachine, error) { + if t.returnErr { + return nil, fmt.Errorf("error") + } + fmt.Printf("CLIENT VMS: %v\n", t.vms) + return t.vms, nil +} + +func newRoleDef(id string, name string) *armauthorization.RoleDefinition { + role_name := "test_role_name" + return &armauthorization.RoleDefinition{ + ID: &id, + Name: &name, + Properties: &armauthorization.RoleDefinitionProperties{ + Permissions: []*armauthorization.Permission{}, + RoleName: &role_name, + }, + } +} + +func newRoleAssign(id string, name string) *armauthorization.RoleAssignment { + scope := "test_scope" + principalId := "test_principal_id" + roleDefId := "test_role_def_id" + return &armauthorization.RoleAssignment{ + ID: &id, + Name: &name, + Properties: &armauthorization.RoleAssignmentProperties{ + PrincipalID: &principalId, + RoleDefinitionID: &roleDefId, + Scope: &scope, + }, + } +} + +func newVm(id string, name string) *armcompute.VirtualMachine { + return &armcompute.VirtualMachine{ + ID: &id, + Name: &name, + } +} + +func TestPoll(t *testing.T) { + roleDefs := []*armauthorization.RoleDefinition{ + newRoleDef("id1", "name1"), + } + roleAssigns := []*armauthorization.RoleAssignment{ + newRoleAssign("id1", "name1"), + } + vms := []*armcompute.VirtualMachine{ + newVm("id1", "name2"), + } + roleDefClient := testRoleDefCli{} + roleAssignClient := testRoleAssignCli{} + vmClient := testVmCli{} + fetcher := Fetcher{ + Config: Config{}, + lastResult: &Resources{}, + roleDefClient: &roleDefClient, + roleAssignClient: &roleAssignClient, + vmClient: &vmClient, + } + ctx := context.Background() + allFeats := Features{ + RoleDefinitions: true, + RoleAssignments: true, + VirtualMachines: true, + } + noVmsFeats := allFeats + noVmsFeats.VirtualMachines = false + + tests := []struct { + returnErr bool + roleDefs []*armauthorization.RoleDefinition + roleAssigns []*armauthorization.RoleAssignment + vms []*armcompute.VirtualMachine + feats Features + }{ + // Process no results from clients + { + returnErr: false, + roleDefs: []*armauthorization.RoleDefinition{}, + roleAssigns: []*armauthorization.RoleAssignment{}, + vms: []*armcompute.VirtualMachine{}, + feats: allFeats, + }, + // Process test results from clients + { + returnErr: false, + roleDefs: roleDefs, + roleAssigns: roleAssigns, + vms: vms, + feats: allFeats, + }, + // Handle errors from clients + { + returnErr: true, + roleDefs: roleDefs, + roleAssigns: roleAssigns, + vms: vms, + feats: allFeats, + }, + // Handle VM features being disabled + { + returnErr: false, + roleDefs: roleDefs, + roleAssigns: roleAssigns, + vms: vms, + feats: noVmsFeats, + }, + } + + for _, tt := range tests { + // Set the test data + roleDefClient.returnErr = tt.returnErr + roleDefClient.roleDefs = tt.roleDefs + roleAssignClient.returnErr = tt.returnErr + roleAssignClient.roleAssigns = tt.roleAssigns + vmClient.returnErr = tt.returnErr + vmClient.vms = tt.vms + + // Poll for resources + resources, err := fetcher.Poll(ctx, tt.feats) + + // Require no error unless otherwise specified + if tt.returnErr { + require.Error(t, err) + continue + } + require.NoError(t, err) + + // Verify the results, based on the features set + require.NotNil(t, resources) + if tt.feats.RoleDefinitions { + require.Len(t, resources.RoleDefinitions, len(tt.roleDefs)) + } + if tt.feats.RoleAssignments { + require.Len(t, resources.RoleAssignments, len(tt.roleAssigns)) + } + if tt.feats.VirtualMachines { + require.Len(t, resources.VirtualMachines, len(tt.vms)) + } + } +} diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go index e9d298a9ec5fb..d337a0fcaaa92 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go @@ -88,10 +88,10 @@ func TestReconcileResults(t *testing.T) { }, } - for _, test := range tests { - upserts, deletes := ReconcileResults(test.oldResults, test.newResults) - require.ElementsMatch(t, upserts.Resources, test.expectedUpserts.Resources) - require.ElementsMatch(t, deletes.Resources, test.expectedDeletes.Resources) + for _, tt := range tests { + upserts, deletes := ReconcileResults(tt.oldResults, tt.newResults) + require.ElementsMatch(t, upserts.Resources, tt.expectedUpserts.Resources) + require.ElementsMatch(t, deletes.Resources, tt.expectedDeletes.Resources) } } diff --git a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go index 76b8e65317ed7..c9c02c948881e 100644 --- a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go +++ b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go @@ -26,14 +26,8 @@ import ( ) func (a *Fetcher) fetchVirtualMachines(ctx context.Context) ([]*accessgraphv1alpha.AzureVirtualMachine, error) { - // Get the VM client - cli, err := a.CloudClients.GetAzureVirtualMachinesClient(a.GetSubscriptionID()) - if err != nil { - return nil, trace.Wrap(err) - } - // Fetch the VMs - vms, err := cli.ListVirtualMachines(ctx, "*") + vms, err := a.vmClient.ListVirtualMachines(ctx, "*") if err != nil { return nil, trace.Wrap(err) } From 61844868d9cc49eab79fa19d00b5ae2c48b52682 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Sat, 16 Nov 2024 11:21:08 -0600 Subject: [PATCH 18/36] Add proper config parsing --- api/proto/teleport/legacy/types/types.proto | 10 ++-------- lib/config/configuration.go | 15 +++++++++++++++ lib/config/fileconf.go | 9 +++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index cda07aa429c6a..eb9fcb2cef64d 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8025,14 +8025,8 @@ message OktaOptions { message AccessGraphSync { // AWS is a configuration for AWS Access Graph service poll service. repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; - // PollInterval is the frequency at which to poll for AWS resources - google.protobuf.Duration PollInterval = 2 [ - (gogoproto.jsontag) = "poll_interval,omitempty", - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true - ]; - // Azure is a configuration for the Azure Access Graph service poll service. - repeated AccessGraphAzureSync Azure = 3 [(gogoproto.jsontag) = "azure,omitempty"]; + // Azure is a configuration for Azure Access Graph service poll service. + repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "aws,omitempty"]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. diff --git a/lib/config/configuration.go b/lib/config/configuration.go index 54dc6a2c82820..1cb3f975ea4bd 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -1754,6 +1754,21 @@ kubernetes matchers are present`) AssumeRole: assumeRole, }) } + for _, azureMatcher := range fc.Discovery.AccessGraph.Azure { + regions := azureMatcher.Regions + if len(regions) == 0 { + return trace.BadParameter("missing regions in access_graph.azure") + } + subscriptionID := azureMatcher.SubscriptionID + umiClientID := azureMatcher.UMIClientID + integration := azureMatcher.Integration + tMatcher.Azure = append(tMatcher.Azure, &types.AccessGraphAzureSync{ + Regions: regions, + SubscriptionID: subscriptionID, + UMIClientID: umiClientID, + Integration: integration, + }) + } if fc.Discovery.AccessGraph.PollInterval > 0 { tMatcher.PollInterval = fc.Discovery.AccessGraph.PollInterval } diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index a4bc53787ce9f..7530388cc414d 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -1523,6 +1523,8 @@ type GCPMatcher struct { type AccessGraphSync struct { // AWS is the AWS configuration for the AccessGraph Sync service. AWS []AccessGraphAWSSync `yaml:"aws,omitempty"` + // Azure is the Azure configuration for the AccessGraph Sync service. + Azure []AccessGraphAzureSync `yaml:"azure,omitempty"` // PollInterval is the frequency at which to poll for AWS resources PollInterval time.Duration `yaml:"poll_interval,omitempty"` } @@ -1538,6 +1540,13 @@ type AccessGraphAWSSync struct { ExternalID string `yaml:"external_id,omitempty"` } +type AccessGraphAzureSync struct { + Regions []string `yaml:"regions,omitempty"` + SubscriptionID string `yaml:"subscription_id,omitempty"` + UMIClientID string `yaml:"umi_client_id,omitempty"` + Integration string `yaml:"integration,omitempty"` +} + // CommandLabel is `command` section of `ssh_service` in the config file type CommandLabel struct { Name string `yaml:"name"` From edf5ac913f8a4554e9c02c5756004858d105fbab Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 14:23:47 -0600 Subject: [PATCH 19/36] Initializing Azure watcher and fixing Azure creds --- lib/srv/discovery/access_graph_azure.go | 81 ++++++++----------- lib/srv/discovery/discovery.go | 5 ++ .../fetchers/azure-sync/azure-sync.go | 14 +--- 3 files changed, 44 insertions(+), 56 deletions(-) diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 8b0ec38cacc0c..5916e6f79dc54 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -29,6 +29,7 @@ func (s *Server) reconcileAccessGraphAzure( err error } + // Get all the fetchers allFetchers := s.getAllTAGSyncAzureFetchers() if len(allFetchers) == 0 { // If there are no fetchers, we don't need to continue. @@ -41,16 +42,8 @@ func (s *Server) reconcileAccessGraphAzure( return trace.Wrap(errNoAccessGraphFetchers) } - // TODO (mbrock): Update discovery config status - /* - s.awsSyncStatus.iterationStarted(allFetchers, s.clock.Now()) - for _, discoveryConfigName := range s.awsSyncStatus.discoveryConfigs() { - s.updateDiscoveryConfigStatus(discoveryConfigName) - } - */ - + // Fetch results concurrently resultsC := make(chan fetcherResult, len(allFetchers)) - // Use a channel to limit the number of concurrent fetchers. tokens := make(chan struct{}, 3) accountIds := map[string]struct{}{} for _, fetcher := range allFetchers { @@ -66,11 +59,11 @@ func (s *Server) reconcileAccessGraphAzure( }() } + // Collect the results from all fetchers. results := make([]*azure_sync.Resources, 0, len(allFetchers)) errs := make([]error, 0, len(allFetchers)) - // Collect the results from all fetchers. - // Each fetcher can return an error and a result. for i := 0; i < len(allFetchers); i++ { + // Each fetcher can return an error and a result. fetcherResult := <-resultsC if fetcherResult.err != nil { errs = append(errs, fetcherResult.err) @@ -79,28 +72,23 @@ func (s *Server) reconcileAccessGraphAzure( results = append(results, fetcherResult.result) } } + // Aggregate all errors into a single error. err := trace.NewAggregate(errs...) if err != nil { s.Log.ErrorContext(ctx, "Error polling TAGs", "error", err) } result := azure_sync.MergeResources(results...) + // Merge all results into a single result upsert, toDel := azure_sync.ReconcileResults(currentTAGResources, result) pushErr := azurePush(stream, upsert, toDel) - // TODO (mbrock): Update discovery config status - /* - s.awsSyncStatus.iterationFinished(allFetchers, pushErr, s.clock.Now()) - for _, discoveryConfigName := range s.awsSyncStatus.discoveryConfigs() { - s.updateDiscoveryConfigStatus(discoveryConfigName) - } - */ - if pushErr != nil { s.Log.ErrorContext(ctx, "Error pushing TAGs", "error", pushErr) return nil } + // Update the currentTAGResources with the result of the reconciliation. *currentTAGResources = *result return nil @@ -321,38 +309,39 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { s.Log.ErrorContext(ctx, "Error initializing access graph fetchers", "error", err) } s.staticTAGAzureFetchers = staticFetchers - if cfg.AccessGraphConfig.Enabled { - go func() { - reloadCh := s.newDiscoveryConfigChangedSub() - for { - fetchers := s.getAllTAGSyncAzureFetchers() - // Wait for the config to change and re-evaluate the fetchers before starting the sync. - if len(fetchers) == 0 { - s.Log.Debug("No Azure sync fetchers configured. Access graph sync will not be enabled.") - select { - case <-ctx.Done(): - return - case <-reloadCh: - // if the config changes, we need to get the updated list of fetchers - } - continue - } - // Reset the Azure resources to force a full sync - if err := s.initializeAndWatchAzureAccessGraph(ctx, reloadCh); errors.Is(err, errTAGFeatureNotEnabled) { - s.Log.Warn("Access Graph specified in config, but the license does not include Teleport Policy. Access graph sync will not be enabled.") - break - } else if err != nil { - s.Log.Warn("Error initializing and watching access graph", "error", err) - } - + if !cfg.AccessGraphConfig.Enabled { + return nil + } + go func() { + reloadCh := s.newDiscoveryConfigChangedSub() + for { + fetchers := s.getAllTAGSyncAzureFetchers() + // Wait for the config to change and re-evaluate the fetchers before starting the sync. + if len(fetchers) == 0 { + s.Log.Debug("No Azure sync fetchers configured. Access graph sync will not be enabled.") select { case <-ctx.Done(): return - case <-time.After(time.Minute): + case <-reloadCh: + // if the config changes, we need to get the updated list of fetchers } + continue } - }() - } + // Reset the Azure resources to force a full sync + if err := s.initializeAndWatchAzureAccessGraph(ctx, reloadCh); errors.Is(err, errTAGFeatureNotEnabled) { + s.Log.Warn("Access Graph specified in config, but the license does not include Teleport Policy. Access graph sync will not be enabled.") + break + } else if err != nil { + s.Log.Warn("Error initializing and watching access graph", "error", err) + } + + select { + case <-ctx.Done(): + return + case <-time.After(time.Minute): + } + } + }() return nil } diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index d752e1415e5cf..a0a381ffa7c2e 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -434,6 +434,7 @@ func New(ctx context.Context, cfg *Config) (*Server, error) { dynamicServerAzureFetchers: make(map[string][]server.Fetcher), dynamicServerGCPFetchers: make(map[string][]server.Fetcher), dynamicTAGAWSFetchers: make(map[string][]aws_sync.AWSSync), + dynamicTAGAzureFetchers: make(map[string][]*azure_sync.Fetcher), dynamicDiscoveryConfig: make(map[string]*discoveryconfig.DiscoveryConfig), awsSyncStatus: awsSyncStatus{}, awsEC2ResourcesStatus: newAWSResourceStatusCollector(types.AWSMatcherEC2), @@ -478,6 +479,10 @@ func New(ctx context.Context, cfg *Config) (*Server, error) { return nil, trace.Wrap(err) } + if err := s.initTAGAzureWatchers(s.ctx, cfg); err != nil { + return nil, trace.Wrap(err) + } + return s, nil } diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index b6bfc60fa18ac..bc62e439ff248 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -20,7 +20,6 @@ package azure_sync import ( "context" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" @@ -83,26 +82,21 @@ type Fetcher struct { func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { // Establish the credential from the managed identity - cred, err := azidentity.NewManagedIdentityCredential(nil) + cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { return nil, trace.Wrap(err) } - token, err := cred.GetToken(ctx, policy.TokenRequestOptions{}) - if err != nil { - return nil, trace.Wrap(err) - } - staticCred := azure.NewStaticCredential(token) // Create the clients - vmClient, err := azure.NewVirtualMachinesClient(cfg.SubscriptionID, staticCred, nil) + vmClient, err := azure.NewVirtualMachinesClient(cfg.SubscriptionID, cred, nil) if err != nil { return nil, trace.Wrap(err) } - roleDefClient, err := azure.NewRoleDefinitionsClient(cfg.SubscriptionID, staticCred, nil) + roleDefClient, err := azure.NewRoleDefinitionsClient(cfg.SubscriptionID, cred, nil) if err != nil { return nil, trace.Wrap(err) } - roleAssignClient, err := azure.NewRoleAssignmentsClient(cfg.SubscriptionID, staticCred, nil) + roleAssignClient, err := azure.NewRoleAssignmentsClient(cfg.SubscriptionID, cred, nil) if err != nil { return nil, trace.Wrap(err) } From 0d54f2aebd590a250ca30ca7953a4b12062d0f91 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 14:37:22 -0600 Subject: [PATCH 20/36] Post-rebase grpc and derived --- api/types/discoveryconfig/derived.gen.go | 93 +++++--- gen/proto/go/accessgraph/v1alpha/azure.pb.go | 238 +++++++++++++++---- 2 files changed, 241 insertions(+), 90 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index b95a3a3e8ffbe..77bd2004e34ca 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -117,6 +117,7 @@ func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && deriveTeleportEqual_12(this.AWS, that.AWS) && + deriveTeleportEqual_13(this.Azure, that.Azure) && this.PollInterval == that.PollInterval } @@ -144,12 +145,12 @@ func deriveTeleportEqual_7(this, that map[string]string) bool { func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_17(this.SSM, that.SSM) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_18(this.SSM, that.SSM) && this.Integration == that.Integration && this.KubeAppDiscovery == that.KubeAppDiscovery && this.SetupAccessForARN == that.SetupAccessForARN @@ -159,34 +160,34 @@ func deriveTeleportEqual_8(this, that *types.AWSMatcher) bool { func deriveTeleportEqual_9(this, that *types.AzureMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Subscriptions, that.Subscriptions) && - deriveTeleportEqual_13(this.ResourceGroups, that.ResourceGroups) && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_15(this.ResourceTags, that.ResourceTags) && - deriveTeleportEqual_16(this.Params, that.Params) + deriveTeleportEqual_14(this.Subscriptions, that.Subscriptions) && + deriveTeleportEqual_14(this.ResourceGroups, that.ResourceGroups) && + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_16(this.ResourceTags, that.ResourceTags) && + deriveTeleportEqual_17(this.Params, that.Params) } // deriveTeleportEqual_10 returns whether this and that are equal. func deriveTeleportEqual_10(this, that *types.GCPMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Locations, that.Locations) && - deriveTeleportEqual_15(this.Tags, that.Tags) && - deriveTeleportEqual_13(this.ProjectIDs, that.ProjectIDs) && - deriveTeleportEqual_13(this.ServiceAccounts, that.ServiceAccounts) && - deriveTeleportEqual_16(this.Params, that.Params) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Locations, that.Locations) && + deriveTeleportEqual_16(this.Tags, that.Tags) && + deriveTeleportEqual_14(this.ProjectIDs, that.ProjectIDs) && + deriveTeleportEqual_14(this.ServiceAccounts, that.ServiceAccounts) && + deriveTeleportEqual_17(this.Params, that.Params) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_11 returns whether this and that are equal. func deriveTeleportEqual_11(this, that *types.KubernetesMatcher) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Types, that.Types) && - deriveTeleportEqual_13(this.Namespaces, that.Namespaces) && - deriveTeleportEqual_15(this.Labels, that.Labels) + deriveTeleportEqual_14(this.Types, that.Types) && + deriveTeleportEqual_14(this.Namespaces, that.Namespaces) && + deriveTeleportEqual_16(this.Labels, that.Labels) } // deriveTeleportEqual_12 returns whether this and that are equal. @@ -198,7 +199,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { return false } for i := 0; i < len(this); i++ { - if !(deriveTeleportEqual_18(this[i], that[i])) { + if !(deriveTeleportEqual_19(this[i], that[i])) { return false } } @@ -206,7 +207,7 @@ func deriveTeleportEqual_12(this, that []*types.AccessGraphAWSSync) bool { } // deriveTeleportEqual_13 returns whether this and that are equal. -func deriveTeleportEqual_13(this, that []string) bool { +func deriveTeleportEqual_13(this, that []*types.AccessGraphAzureSync) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -214,7 +215,7 @@ func deriveTeleportEqual_13(this, that []string) bool { return false } for i := 0; i < len(this); i++ { - if !(this[i] == that[i]) { + if !(deriveTeleportEqual_20(this[i], that[i])) { return false } } @@ -222,15 +223,31 @@ func deriveTeleportEqual_13(this, that []string) bool { } // deriveTeleportEqual_14 returns whether this and that are equal. -func deriveTeleportEqual_14(this, that *types.AssumeRole) bool { +func deriveTeleportEqual_14(this, that []string) bool { + if this == nil || that == nil { + return this == nil && that == nil + } + if len(this) != len(that) { + return false + } + for i := 0; i < len(this); i++ { + if !(this[i] == that[i]) { + return false + } + } + return true +} + +// deriveTeleportEqual_15 returns whether this and that are equal. +func deriveTeleportEqual_15(this, that *types.AssumeRole) bool { return (this == nil && that == nil) || this != nil && that != nil && this.RoleARN == that.RoleARN && this.ExternalID == that.ExternalID } -// deriveTeleportEqual_15 returns whether this and that are equal. -func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { +// deriveTeleportEqual_16 returns whether this and that are equal. +func deriveTeleportEqual_16(this, that map[string]utils.Strings) bool { if this == nil || that == nil { return this == nil && that == nil } @@ -242,15 +259,15 @@ func deriveTeleportEqual_15(this, that map[string]utils.Strings) bool { if !ok { return false } - if !(deriveTeleportEqual_13(v, thatv)) { + if !(deriveTeleportEqual_14(v, thatv)) { return false } } return true } -// deriveTeleportEqual_16 returns whether this and that are equal. -func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { +// deriveTeleportEqual_17 returns whether this and that are equal. +func deriveTeleportEqual_17(this, that *types.InstallerParams) bool { return (this == nil && that == nil) || this != nil && that != nil && this.JoinMethod == that.JoinMethod && @@ -259,23 +276,23 @@ func deriveTeleportEqual_16(this, that *types.InstallerParams) bool { this.InstallTeleport == that.InstallTeleport && this.SSHDConfig == that.SSHDConfig && this.PublicProxyAddr == that.PublicProxyAddr && - deriveTeleportEqual_19(this.Azure, that.Azure) && + deriveTeleportEqual_21(this.Azure, that.Azure) && this.EnrollMode == that.EnrollMode } -// deriveTeleportEqual_17 returns whether this and that are equal. -func deriveTeleportEqual_17(this, that *types.AWSSSM) bool { +// deriveTeleportEqual_18 returns whether this and that are equal. +func deriveTeleportEqual_18(this, that *types.AWSSSM) bool { return (this == nil && that == nil) || this != nil && that != nil && this.DocumentName == that.DocumentName } -// deriveTeleportEqual_18 returns whether this and that are equal. -func deriveTeleportEqual_18(this, that *types.AccessGraphAWSSync) bool { +// deriveTeleportEqual_19 returns whether this and that are equal. +func deriveTeleportEqual_19(this, that *types.AccessGraphAWSSync) bool { return (this == nil && that == nil) || this != nil && that != nil && - deriveTeleportEqual_13(this.Regions, that.Regions) && - deriveTeleportEqual_14(this.AssumeRole, that.AssumeRole) && + deriveTeleportEqual_14(this.Regions, that.Regions) && + deriveTeleportEqual_15(this.AssumeRole, that.AssumeRole) && this.Integration == that.Integration } diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index 66186e8d12916..dccfd5f9b54e7 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -266,83 +266,54 @@ func (x *AzureVirtualMachine) GetName() string { return "" } -// AzureManagedDatabase is an Azure-managed Postgres or MySQL database -type AzureManagedDatabase struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *AzureManagedDatabase) Reset() { - *x = AzureManagedDatabase{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AzureManagedDatabase) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AzureManagedDatabase) ProtoMessage() {} - -func (x *AzureManagedDatabase) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AzureManagedDatabase.ProtoReflect.Descriptor instead. -func (*AzureManagedDatabase) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} -} - -func (x *AzureManagedDatabase) GetId() string { +func (x *AzureVirtualMachine) GetResourceGroup() string { if x != nil { - return x.Id + return x.ResourceGroup } return "" } -func (x *AzureManagedDatabase) GetSubscriptionId() string { +func (x *AzureVirtualMachine) GetTags() map[string]string { if x != nil { - return x.SubscriptionId + return x.Tags } - return "" + return nil } -func (x *AzureManagedDatabase) GetLastSyncTime() *timestamppb.Timestamp { +func (x *AzureManagedDatabase) GetName() string { if x != nil { - return x.LastSyncTime + return x.Name } - return nil + return "" } +// AzureAKSCluster is an AKS cluster +type AzureAKSCluster struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` } +func (x *AzureAKSCluster) Reset() { + *x = AzureAKSCluster{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } +func (x *AzureAKSCluster) String() string { return protoimpl.X.MessageStringOf(x) } +func (*AzureAKSCluster) ProtoMessage() {} +func (x *AzureAKSCluster) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -353,23 +324,40 @@ func (x *AzureManagedDatabase) GetLastSyncTime() *timestamppb.Timestamp { return mi.MessageOf(x) } +// Deprecated: Use AzureAKSCluster.ProtoReflect.Descriptor instead. +func (*AzureAKSCluster) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } +func (x *AzureAKSCluster) GetId() string { if x != nil { + return x.Id } return "" } +func (x *AzureAKSCluster) GetSubscriptionId() string { if x != nil { + return x.SubscriptionId } return "" } +func (x *AzureAKSCluster) GetLastSyncTime() *timestamppb.Timestamp { if x != nil { + return x.LastSyncTime + } + return nil +} + +func (x *AzureAKSCluster) GetName() string { + if x != nil { + return x.Name } return "" } +// AzurePrincipal is an Azure principal (user, group, service principal) type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -384,6 +372,7 @@ type AzurePrincipal struct { func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -395,6 +384,7 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -407,6 +397,7 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzurePrincipal) GetId() string { @@ -481,6 +472,7 @@ type AzureRoleAssignment struct { func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -492,6 +484,7 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -504,6 +497,7 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleAssignment) GetId() string { @@ -565,10 +559,12 @@ type AzureRoleDefinition struct { SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Permissions []*AzurePermission `protobuf:"bytes,5,rep,name=permissions,proto3" json:"permissions,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -580,6 +576,7 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -592,6 +589,7 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } func (x *AzureRoleDefinition) GetId() string { @@ -622,6 +620,7 @@ func (x *AzureRoleDefinition) GetName() string { return "" } +func (x *AzureRoleDefinition) GetPermissions() []*AzurePermission { if x != nil { return x.Permissions } @@ -636,6 +635,7 @@ func (x *AzureRoleDefinition) GetRoleName() string { } // AzurePermission defines the actions and not (disallowed) actions for a role definition +type AzurePermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -646,14 +646,21 @@ func (x *AzureRoleDefinition) GetRoleName() string { NotDataActions []string `protobuf:"bytes,4,rep,name=not_data_actions,json=notDataActions,proto3" json:"not_data_actions,omitempty"` } +func (x *AzurePermission) Reset() { + *x = AzurePermission{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } +func (x *AzurePermission) String() string { return protoimpl.X.MessageStringOf(x) } +func (*AzurePermission) ProtoMessage() {} +func (x *AzurePermission) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -664,14 +671,19 @@ func (x *AzureRoleDefinition) GetRoleName() string { return mi.MessageOf(x) } +// Deprecated: Use AzurePermission.ProtoReflect.Descriptor instead. +func (*AzurePermission) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{8} } +func (x *AzurePermission) GetActions() []string { if x != nil { return x.Actions } return nil } +func (x *AzurePermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -719,6 +731,8 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x80, + 0x04, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -739,6 +753,103 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x12, 0x56, 0x0a, 0x10, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, + 0x61, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6b, 0x73, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, + 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, + 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0xa0, 0x01, 0x0a, 0x0f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, + 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, + 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, + 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, + 0x66, 0x22, 0xf7, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xec, 0x01, 0x0a, 0x13, + 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x0f, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, + 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -753,16 +864,39 @@ func file_accessgraph_v1alpha_azure_proto_rawDescGZIP() []byte { return file_accessgraph_v1alpha_azure_proto_rawDescData } -var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_accessgraph_v1alpha_azure_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine + (*AzureManagedDatabase)(nil), // 3: accessgraph.v1alpha.AzureManagedDatabase + (*AzureAKSCluster)(nil), // 4: accessgraph.v1alpha.AzureAKSCluster + (*AzurePrincipal)(nil), // 5: accessgraph.v1alpha.AzurePrincipal + (*AzureRoleAssignment)(nil), // 6: accessgraph.v1alpha.AzureRoleAssignment + (*AzureRoleDefinition)(nil), // 7: accessgraph.v1alpha.AzureRoleDefinition + (*AzurePermission)(nil), // 8: accessgraph.v1alpha.AzurePermission (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource + 5, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal + 7, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition + 6, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine + 3, // 5: accessgraph.v1alpha.AzureResource.managed_database:type_name -> accessgraph.v1alpha.AzureManagedDatabase + 4, // 6: accessgraph.v1alpha.AzureResource.aks_cluster:type_name -> accessgraph.v1alpha.AzureAKSCluster + 9, // 7: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 8: accessgraph.v1alpha.AzureManagedDatabase.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 9: accessgraph.v1alpha.AzureAKSCluster.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 10: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 11: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 12: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 13: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzurePermission + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } @@ -782,7 +916,7 @@ func file_accessgraph_v1alpha_azure_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_accessgraph_v1alpha_azure_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, From e2b2e2304bb652dd4317a3a935e2cf100354f05d Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 14:41:14 -0600 Subject: [PATCH 21/36] Fixing rebase --- api/proto/teleport/legacy/types/types.proto | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index eb9fcb2cef64d..20e25eb673aba 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8025,8 +8025,14 @@ message OktaOptions { message AccessGraphSync { // AWS is a configuration for AWS Access Graph service poll service. repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; + // PollInterval is the frequency at which to poll for AWS resources + google.protobuf.Duration PollInterval = 2 [ + (gogoproto.jsontag) = "poll_interval,omitempty", + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // Azure is a configuration for Azure Access Graph service poll service. - repeated AccessGraphAzureSync Azure = 2 [(gogoproto.jsontag) = "aws,omitempty"]; + repeated AccessGraphAzureSync Azure = 3 [(gogoproto.jsontag) = "aws,omitempty"]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. From 8194d1d8a12bd68d01342f1d17e623f148d264d8 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 14:48:52 -0600 Subject: [PATCH 22/36] Make derived --- api/types/discoveryconfig/derived.gen.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index 77bd2004e34ca..cd6bb42352c43 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -117,8 +117,7 @@ func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && deriveTeleportEqual_12(this.AWS, that.AWS) && - deriveTeleportEqual_13(this.Azure, that.Azure) && - this.PollInterval == that.PollInterval + deriveTeleportEqual_13(this.Azure, that.Azure) } // deriveTeleportEqual_7 returns whether this and that are equal. From bbfc3b8d02f615f4ec5edbc7b4918d2d77b8509d Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 15:26:28 -0600 Subject: [PATCH 23/36] Fix imports --- lib/cloud/azure/roleassignments.go | 1 + lib/cloud/azure/roledefinitions.go | 1 + lib/srv/discovery/access_graph_azure.go | 14 ++++++++------ lib/srv/discovery/discovery.go | 2 +- lib/srv/discovery/fetchers/aws-sync/merge_test.go | 3 ++- lib/srv/discovery/fetchers/aws-sync/reconcile.go | 2 +- .../discovery/fetchers/azure-sync/azure-sync.go | 8 +++++--- .../fetchers/azure-sync/azure-sync_test.go | 3 ++- .../fetchers/azure-sync/msggraphclient.go | 3 ++- .../discovery/fetchers/azure-sync/principals.go | 6 ++++-- lib/srv/discovery/fetchers/azure-sync/reconcile.go | 4 +++- .../fetchers/azure-sync/reconcile_test.go | 6 ++++-- .../fetchers/azure-sync/roleassignments.go | 4 +++- .../fetchers/azure-sync/roledefinitions.go | 4 +++- .../fetchers/azure-sync/virtualmachines.go | 4 +++- 15 files changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go index 94af4dbbbd4d4..c381e11d47aeb 100644 --- a/lib/cloud/azure/roleassignments.go +++ b/lib/cloud/azure/roleassignments.go @@ -2,6 +2,7 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go index 45b90a06dc688..668f3d4456d3c 100644 --- a/lib/cloud/azure/roledefinitions.go +++ b/lib/cloud/azure/roledefinitions.go @@ -2,6 +2,7 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 5916e6f79dc54..d504f49a2f904 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -3,6 +3,14 @@ package discovery import ( "context" "errors" + "io" + "sync" + "time" + + "github.com/gravitational/trace" + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/retryutils" "github.com/gravitational/teleport/entitlements" @@ -10,12 +18,6 @@ import ( "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/services" azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" - "github.com/gravitational/trace" - "google.golang.org/grpc" - "google.golang.org/grpc/connectivity" - "io" - "sync" - "time" ) func (s *Server) reconcileAccessGraphAzure( diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index a0a381ffa7c2e..c39b934b1e15d 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -23,7 +23,6 @@ import ( "crypto/tls" "errors" "fmt" - azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" "log/slog" "slices" "strings" @@ -63,6 +62,7 @@ import ( "github.com/gravitational/teleport/lib/srv/discovery/common" "github.com/gravitational/teleport/lib/srv/discovery/fetchers" aws_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/aws-sync" + azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" "github.com/gravitational/teleport/lib/srv/discovery/fetchers/db" "github.com/gravitational/teleport/lib/srv/server" logutils "github.com/gravitational/teleport/lib/utils/log" diff --git a/lib/srv/discovery/fetchers/aws-sync/merge_test.go b/lib/srv/discovery/fetchers/aws-sync/merge_test.go index be19486e567c8..614828aae61b6 100644 --- a/lib/srv/discovery/fetchers/aws-sync/merge_test.go +++ b/lib/srv/discovery/fetchers/aws-sync/merge_test.go @@ -19,13 +19,14 @@ package aws_sync import ( - "github.com/gravitational/teleport/lib/srv/discovery/common" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/require" "google.golang.org/protobuf/testing/protocmp" + + "github.com/gravitational/teleport/lib/srv/discovery/common" ) func TestMergeResources(t *testing.T) { diff --git a/lib/srv/discovery/fetchers/aws-sync/reconcile.go b/lib/srv/discovery/fetchers/aws-sync/reconcile.go index 753f1d1ca3bc3..553a1edcd129a 100644 --- a/lib/srv/discovery/fetchers/aws-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/aws-sync/reconcile.go @@ -20,11 +20,11 @@ package aws_sync import ( "fmt" - "github.com/gravitational/teleport/lib/srv/discovery/common" "google.golang.org/protobuf/proto" accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/teleport/lib/srv/discovery/common" ) func newResourceList() *accessgraphv1alpha.AWSResourceList { diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index bc62e439ff248..98c431282f323 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -20,16 +20,18 @@ package azure_sync import ( "context" + "sync" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" + "github.com/gravitational/trace" + "golang.org/x/sync/errgroup" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/azure" "github.com/gravitational/teleport/lib/srv/discovery/common" - "github.com/gravitational/trace" - "golang.org/x/sync/errgroup" - "sync" ) const ( diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go index ce8edb7f4588e..2c4c47bfb2f3a 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -3,10 +3,11 @@ package azure_sync import ( "context" "fmt" + "testing" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" "github.com/stretchr/testify/require" - "testing" ) type testRoleDefCli struct { diff --git a/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go index bb46b7464f94e..2785ebf17658d 100644 --- a/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go +++ b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go @@ -23,12 +23,13 @@ import ( "context" "encoding/json" "fmt" - "github.com/Azure/azure-sdk-for-go/sdk/azcore" "io" "net/http" "net/url" "strings" "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" ) // GraphClient represents generic MS API client diff --git a/lib/srv/discovery/fetchers/azure-sync/principals.go b/lib/srv/discovery/fetchers/azure-sync/principals.go index be01af350bb76..59ebac5f55284 100644 --- a/lib/srv/discovery/fetchers/azure-sync/principals.go +++ b/lib/srv/discovery/fetchers/azure-sync/principals.go @@ -2,11 +2,13 @@ package azure_sync import ( "context" + "slices" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" - accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/timestamppb" - "slices" + + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) const groupType = "#microsoft.graph.group" diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile.go b/lib/srv/discovery/fetchers/azure-sync/reconcile.go index 5d80878504eb3..a184c34972e57 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile.go @@ -20,9 +20,11 @@ package azure_sync import ( "fmt" + + "google.golang.org/protobuf/proto" + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" "github.com/gravitational/teleport/lib/srv/discovery/common" - "google.golang.org/protobuf/proto" ) func MergeResources(results ...*Resources) *Resources { diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go index d337a0fcaaa92..28b293bcf1f8d 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile_test.go @@ -18,9 +18,11 @@ package azure_sync import ( - accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" - "github.com/stretchr/testify/require" "testing" + + "github.com/stretchr/testify/require" + + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) func TestReconcileResults(t *testing.T) { diff --git a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go index c497ca8baabdd..f45275368debe 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roleassignments.go +++ b/lib/srv/discovery/fetchers/azure-sync/roleassignments.go @@ -21,9 +21,11 @@ package azure_sync import ( "context" "fmt" - accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/timestamppb" + + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) func (a *Fetcher) fetchRoleAssignments(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleAssignment, error) { diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go index e24f65804d253..b598587ff74d8 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -21,9 +21,11 @@ package azure_sync import ( "context" "fmt" - accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/timestamppb" + + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alpha.AzureRoleDefinition, error) { diff --git a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go index c9c02c948881e..bc1c279a8b416 100644 --- a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go +++ b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go @@ -20,9 +20,11 @@ package azure_sync import ( "context" - accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" + "github.com/gravitational/trace" "google.golang.org/protobuf/types/known/timestamppb" + + accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) func (a *Fetcher) fetchVirtualMachines(ctx context.Context) ([]*accessgraphv1alpha.AzureVirtualMachine, error) { From 8a47506d403fbd767db21288539405cdeb03315c Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 18 Nov 2024 17:38:51 -0600 Subject: [PATCH 24/36] Fix grpc/derived after rebase --- api/types/discoveryconfig/derived.gen.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index cd6bb42352c43..9279ab6d4d824 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -117,6 +117,7 @@ func deriveTeleportEqual_6(this, that *types.AccessGraphSync) bool { return (this == nil && that == nil) || this != nil && that != nil && deriveTeleportEqual_12(this.AWS, that.AWS) && + this.PollInterval == that.PollInterval && deriveTeleportEqual_13(this.Azure, that.Azure) } @@ -301,7 +302,7 @@ func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { this != nil && that != nil && deriveTeleportEqual_14(this.Regions, that.Regions) && this.SubscriptionID == that.SubscriptionID && - this.UmiClientId == that.UmiClientId && + this.UMIClientID == that.UMIClientID && this.Integration == that.Integration } From e1b7ab286287aacf197a73fffe400aae915ea6c6 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 12:39:45 -0600 Subject: [PATCH 25/36] Make grpc --- gen/proto/go/accessgraph/v1alpha/azure.pb.go | 492 ++++++++++--------- 1 file changed, 270 insertions(+), 222 deletions(-) diff --git a/gen/proto/go/accessgraph/v1alpha/azure.pb.go b/gen/proto/go/accessgraph/v1alpha/azure.pb.go index dccfd5f9b54e7..c839731eb60bb 100644 --- a/gen/proto/go/accessgraph/v1alpha/azure.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/azure.pb.go @@ -202,10 +202,20 @@ type AzureVirtualMachine struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // id is the ID of the virtual machine + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // subscription_id is the ID of the subscription to which the virtual machine belongs + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + // last_sync_time is when the virtual machine was last fetched from Azure + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + // name is the given name of the virtual machine + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // resource_group is the name of the resource group to which the virtual machine belongs + ResourceGroup string `protobuf:"bytes,5,opt,name=resource_group,json=resourceGroup,proto3" json:"resource_group,omitempty"` + // tags are a collection of arbitrary key-values applied to the virtual machine + Tags map[string]string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // location is the geographical location of the Virtual Machine + Location string `protobuf:"bytes,7,opt,name=location,proto3" json:"location,omitempty"` } func (x *AzureVirtualMachine) Reset() { @@ -280,40 +290,42 @@ func (x *AzureVirtualMachine) GetTags() map[string]string { return nil } -func (x *AzureManagedDatabase) GetName() string { +func (x *AzureVirtualMachine) GetLocation() string { if x != nil { - return x.Name + return x.Location } return "" } -// AzureAKSCluster is an AKS cluster -type AzureAKSCluster struct { +// AzureIdentity is a Graph API object identity +type AzureIdentity struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // sign_in_type is the type of identity used when signing in, e.g. "emailAddress" or "userName" + SignInType string `protobuf:"bytes,1,opt,name=sign_in_type,json=signInType,proto3" json:"sign_in_type,omitempty"` + // issuer is the issuer of the identity, such as a domain name like "goteleport.com" + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + // issuer_assigned_id unique identifier assigned to the user by the issuer + IssuerAssignedId string `protobuf:"bytes,3,opt,name=issuer_assigned_id,json=issuerAssignedId,proto3" json:"issuer_assigned_id,omitempty"` } -func (x *AzureAKSCluster) Reset() { - *x = AzureAKSCluster{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] +func (x *AzureIdentity) Reset() { + *x = AzureIdentity{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzureAKSCluster) String() string { +func (x *AzureIdentity) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzureAKSCluster) ProtoMessage() {} +func (*AzureIdentity) ProtoMessage() {} -func (x *AzureAKSCluster) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] +func (x *AzureIdentity) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -324,55 +336,57 @@ func (x *AzureAKSCluster) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzureAKSCluster.ProtoReflect.Descriptor instead. -func (*AzureAKSCluster) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} +// Deprecated: Use AzureIdentity.ProtoReflect.Descriptor instead. +func (*AzureIdentity) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{3} } -func (x *AzureAKSCluster) GetId() string { +func (x *AzureIdentity) GetSignInType() string { if x != nil { - return x.Id + return x.SignInType } return "" } -func (x *AzureAKSCluster) GetSubscriptionId() string { +func (x *AzureIdentity) GetIssuer() string { if x != nil { - return x.SubscriptionId + return x.Issuer } return "" } -func (x *AzureAKSCluster) GetLastSyncTime() *timestamppb.Timestamp { - if x != nil { - return x.LastSyncTime - } - return nil -} - -func (x *AzureAKSCluster) GetName() string { +func (x *AzureIdentity) GetIssuerAssignedId() string { if x != nil { - return x.Name + return x.IssuerAssignedId } return "" } -// AzurePrincipal is an Azure principal (user, group, service principal) +// AzurePrincipal is a Graph API principal (user, group, service principal) type AzurePrincipal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - MemberOf []string `protobuf:"bytes,5,rep,name=member_of,json=memberOf,proto3" json:"member_of,omitempty"` + // id is the ID of the principal + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // subscription_id is the ID of the subscription to which the principal belongs + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + // last_sync_time is when the principal was last fetched from Azure + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + // display_name is the given name for the principal, e.g. a user's first+last name + DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + // member_of lists the groups and directories the principal is assigned to + MemberOf []string `protobuf:"bytes,5,rep,name=member_of,json=memberOf,proto3" json:"member_of,omitempty"` + // identities lists the identities that can be used to sign in to the account + Identities []*AzureIdentity `protobuf:"bytes,6,rep,name=identities,proto3" json:"identities,omitempty"` + // object_type defines the type of principal, e.g. "user" or "group" + ObjectType string `protobuf:"bytes,7,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` } func (x *AzurePrincipal) Reset() { *x = AzurePrincipal{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -384,7 +398,7 @@ func (x *AzurePrincipal) String() string { func (*AzurePrincipal) ProtoMessage() {} func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -397,7 +411,7 @@ func (x *AzurePrincipal) ProtoReflect() protoreflect.Message { // Deprecated: Use AzurePrincipal.ProtoReflect.Descriptor instead. func (*AzurePrincipal) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{4} } func (x *AzurePrincipal) GetId() string { @@ -442,13 +456,6 @@ func (x *AzurePrincipal) GetIdentities() []*AzureIdentity { return nil } -func (x *AzurePrincipal) GetIdentities() []*AzureIdentity { - if x != nil { - return x.Identities - } - return nil -} - func (x *AzurePrincipal) GetObjectType() string { if x != nil { return x.ObjectType @@ -462,17 +469,25 @@ type AzureRoleAssignment struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - PrincipalId string `protobuf:"bytes,4,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` - RoleDefinitionId string `protobuf:"bytes,5,opt,name=role_definition_id,json=roleDefinitionId,proto3" json:"role_definition_id,omitempty"` - Scope string `protobuf:"bytes,6,opt,name=scope,proto3" json:"scope,omitempty"` + // id is the ID of the role assignment + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // subscription_id is the ID of the subscription to which the role assignment belongs + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + // last_sync_time is when the role assignment was last fetched from Azure + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + // principal_id is the ID of the principal being assigned a role + PrincipalId string `protobuf:"bytes,4,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` + // role_definition_id is the ID of the role definition assigned to the principal + RoleDefinitionId string `protobuf:"bytes,5,opt,name=role_definition_id,json=roleDefinitionId,proto3" json:"role_definition_id,omitempty"` + // scope constrains which resources the assignment applies to + Scope string `protobuf:"bytes,6,opt,name=scope,proto3" json:"scope,omitempty"` + // condition further which resources the assignment applies to + Condition string `protobuf:"bytes,7,opt,name=condition,proto3" json:"condition,omitempty"` } func (x *AzureRoleAssignment) Reset() { *x = AzureRoleAssignment{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -484,7 +499,7 @@ func (x *AzureRoleAssignment) String() string { func (*AzureRoleAssignment) ProtoMessage() {} func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -497,7 +512,7 @@ func (x *AzureRoleAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleAssignment.ProtoReflect.Descriptor instead. func (*AzureRoleAssignment) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{5} } func (x *AzureRoleAssignment) GetId() string { @@ -555,16 +570,29 @@ type AzureRoleDefinition struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` - LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - Permissions []*AzurePermission `protobuf:"bytes,5,rep,name=permissions,proto3" json:"permissions,omitempty"` + // id is the ID of the role definition + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // subscription_id is the ID of the subscription to which the role definition belongs + SubscriptionId string `protobuf:"bytes,2,opt,name=subscription_id,json=subscriptionId,proto3" json:"subscription_id,omitempty"` + // last_sync_time is when the role definition was last fetched from Azure + LastSyncTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_sync_time,json=lastSyncTime,proto3" json:"last_sync_time,omitempty"` + // name is the given name for the role definition + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // description provides additional detail about the role definition + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // assignable_scopes limits the scopes defined in corresponding role assignments + AssignableScopes []string `protobuf:"bytes,6,rep,name=assignable_scopes,json=assignableScopes,proto3" json:"assignable_scopes,omitempty"` + // permissions define the actions and not (disallowed) actions + Permissions []*AzureRBACPermission `protobuf:"bytes,7,rep,name=permissions,proto3" json:"permissions,omitempty"` + // role_name is the given name for the role itself + RoleName string `protobuf:"bytes,8,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"` + // type defines the type of role + Type string `protobuf:"bytes,9,opt,name=type,proto3" json:"type,omitempty"` } func (x *AzureRoleDefinition) Reset() { *x = AzureRoleDefinition{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +604,7 @@ func (x *AzureRoleDefinition) String() string { func (*AzureRoleDefinition) ProtoMessage() {} func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +617,7 @@ func (x *AzureRoleDefinition) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureRoleDefinition.ProtoReflect.Descriptor instead. func (*AzureRoleDefinition) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{6} } func (x *AzureRoleDefinition) GetId() string { @@ -620,7 +648,21 @@ func (x *AzureRoleDefinition) GetName() string { return "" } -func (x *AzureRoleDefinition) GetPermissions() []*AzurePermission { +func (x *AzureRoleDefinition) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *AzureRoleDefinition) GetAssignableScopes() []string { + if x != nil { + return x.AssignableScopes + } + return nil +} + +func (x *AzureRoleDefinition) GetPermissions() []*AzureRBACPermission { if x != nil { return x.Permissions } @@ -634,33 +676,44 @@ func (x *AzureRoleDefinition) GetRoleName() string { return "" } -// AzurePermission defines the actions and not (disallowed) actions for a role definition -type AzurePermission struct { +func (x *AzureRoleDefinition) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +// AzureRBACPermission defines the actions and not (disallowed) actions for a role definition +type AzureRBACPermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Actions []string `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"` - NotActions []string `protobuf:"bytes,2,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` - DataActions []string `protobuf:"bytes,3,rep,name=data_actions,json=dataActions,proto3" json:"data_actions,omitempty"` + // actions define the resources and verbs allowed on the resources + Actions []string `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"` + // not_actions define the resources and verbs disallowed on the resources + NotActions []string `protobuf:"bytes,2,rep,name=not_actions,json=notActions,proto3" json:"not_actions,omitempty"` + // data_actions define fine-grained resources and verbs allowed within the resource + DataActions []string `protobuf:"bytes,3,rep,name=data_actions,json=dataActions,proto3" json:"data_actions,omitempty"` + // not_data_actions define fine-grained resources and verbs disallowed within the resource NotDataActions []string `protobuf:"bytes,4,rep,name=not_data_actions,json=notDataActions,proto3" json:"not_data_actions,omitempty"` } -func (x *AzurePermission) Reset() { - *x = AzurePermission{} - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] +func (x *AzureRBACPermission) Reset() { + *x = AzureRBACPermission{} + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AzurePermission) String() string { +func (x *AzureRBACPermission) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AzurePermission) ProtoMessage() {} +func (*AzureRBACPermission) ProtoMessage() {} -func (x *AzurePermission) ProtoReflect() protoreflect.Message { - mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[8] +func (x *AzureRBACPermission) ProtoReflect() protoreflect.Message { + mi := &file_accessgraph_v1alpha_azure_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -671,19 +724,19 @@ func (x *AzurePermission) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AzurePermission.ProtoReflect.Descriptor instead. -func (*AzurePermission) Descriptor() ([]byte, []int) { - return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{8} +// Deprecated: Use AzureRBACPermission.ProtoReflect.Descriptor instead. +func (*AzureRBACPermission) Descriptor() ([]byte, []int) { + return file_accessgraph_v1alpha_azure_proto_rawDescGZIP(), []int{7} } -func (x *AzurePermission) GetActions() []string { +func (x *AzureRBACPermission) GetActions() []string { if x != nil { return x.Actions } return nil } -func (x *AzurePermission) GetNotActions() []string { +func (x *AzureRBACPermission) GetNotActions() []string { if x != nil { return x.NotActions } @@ -704,20 +757,6 @@ func (x *AzureRBACPermission) GetNotDataActions() []string { return nil } -func (x *AzureRBACPermission) GetDataActions() []string { - if x != nil { - return x.DataActions - } - return nil -} - -func (x *AzureRBACPermission) GetNotDataActions() []string { - if x != nil { - return x.NotDataActions - } - return nil -} - var File_accessgraph_v1alpha_azure_proto protoreflect.FileDescriptor var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ @@ -731,8 +770,8 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x80, - 0x04, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xdf, + 0x02, 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, @@ -753,103 +792,114 @@ var file_accessgraph_v1alpha_azure_proto_rawDesc = []byte{ 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x12, 0x56, 0x0a, 0x10, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0b, - 0x61, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x6b, 0x73, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, - 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, - 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0xa0, 0x01, 0x0a, 0x0f, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x4b, 0x53, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, - 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, - 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4f, - 0x66, 0x22, 0xf7, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, - 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, - 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0xec, 0x01, 0x0a, 0x13, - 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x0f, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, - 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x69, 0x6e, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x22, 0xe8, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, + 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x77, 0x0a, 0x0d, 0x41, + 0x7a, 0x75, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0c, + 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, + 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x49, 0x64, 0x22, 0xb0, 0x02, 0x0a, 0x0e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x50, 0x72, + 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x6f, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x4f, 0x66, 0x12, 0x42, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x95, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, + 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, + 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, + 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x2c, 0x0a, + 0x12, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x65, 0x44, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xf0, 0x02, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x44, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x40, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x42, 0x41, 0x43, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x6f, 0x74, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x61, 0x74, + 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x6f, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -869,34 +919,32 @@ var file_accessgraph_v1alpha_azure_proto_goTypes = []any{ (*AzureResourceList)(nil), // 0: accessgraph.v1alpha.AzureResourceList (*AzureResource)(nil), // 1: accessgraph.v1alpha.AzureResource (*AzureVirtualMachine)(nil), // 2: accessgraph.v1alpha.AzureVirtualMachine - (*AzureManagedDatabase)(nil), // 3: accessgraph.v1alpha.AzureManagedDatabase - (*AzureAKSCluster)(nil), // 4: accessgraph.v1alpha.AzureAKSCluster - (*AzurePrincipal)(nil), // 5: accessgraph.v1alpha.AzurePrincipal - (*AzureRoleAssignment)(nil), // 6: accessgraph.v1alpha.AzureRoleAssignment - (*AzureRoleDefinition)(nil), // 7: accessgraph.v1alpha.AzureRoleDefinition - (*AzurePermission)(nil), // 8: accessgraph.v1alpha.AzurePermission + (*AzureIdentity)(nil), // 3: accessgraph.v1alpha.AzureIdentity + (*AzurePrincipal)(nil), // 4: accessgraph.v1alpha.AzurePrincipal + (*AzureRoleAssignment)(nil), // 5: accessgraph.v1alpha.AzureRoleAssignment + (*AzureRoleDefinition)(nil), // 6: accessgraph.v1alpha.AzureRoleDefinition + (*AzureRBACPermission)(nil), // 7: accessgraph.v1alpha.AzureRBACPermission + nil, // 8: accessgraph.v1alpha.AzureVirtualMachine.TagsEntry (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } var file_accessgraph_v1alpha_azure_proto_depIdxs = []int32{ 1, // 0: accessgraph.v1alpha.AzureResourceList.resources:type_name -> accessgraph.v1alpha.AzureResource - 5, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal - 7, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition - 6, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment + 4, // 1: accessgraph.v1alpha.AzureResource.principal:type_name -> accessgraph.v1alpha.AzurePrincipal + 6, // 2: accessgraph.v1alpha.AzureResource.role_definition:type_name -> accessgraph.v1alpha.AzureRoleDefinition + 5, // 3: accessgraph.v1alpha.AzureResource.role_assignment:type_name -> accessgraph.v1alpha.AzureRoleAssignment 2, // 4: accessgraph.v1alpha.AzureResource.virtual_machine:type_name -> accessgraph.v1alpha.AzureVirtualMachine - 3, // 5: accessgraph.v1alpha.AzureResource.managed_database:type_name -> accessgraph.v1alpha.AzureManagedDatabase - 4, // 6: accessgraph.v1alpha.AzureResource.aks_cluster:type_name -> accessgraph.v1alpha.AzureAKSCluster - 9, // 7: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 8: accessgraph.v1alpha.AzureManagedDatabase.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 9: accessgraph.v1alpha.AzureAKSCluster.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 10: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 11: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp - 9, // 12: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp - 8, // 13: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzurePermission - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 9, // 5: accessgraph.v1alpha.AzureVirtualMachine.last_sync_time:type_name -> google.protobuf.Timestamp + 8, // 6: accessgraph.v1alpha.AzureVirtualMachine.tags:type_name -> accessgraph.v1alpha.AzureVirtualMachine.TagsEntry + 9, // 7: accessgraph.v1alpha.AzurePrincipal.last_sync_time:type_name -> google.protobuf.Timestamp + 3, // 8: accessgraph.v1alpha.AzurePrincipal.identities:type_name -> accessgraph.v1alpha.AzureIdentity + 9, // 9: accessgraph.v1alpha.AzureRoleAssignment.last_sync_time:type_name -> google.protobuf.Timestamp + 9, // 10: accessgraph.v1alpha.AzureRoleDefinition.last_sync_time:type_name -> google.protobuf.Timestamp + 7, // 11: accessgraph.v1alpha.AzureRoleDefinition.permissions:type_name -> accessgraph.v1alpha.AzureRBACPermission + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_azure_proto_init() } From bf049cc616830e6d8ae2d333f805221f50f88bf8 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 13:10:03 -0600 Subject: [PATCH 26/36] Fix error handling for bidi client --- lib/srv/discovery/{access_graph.go => access_graph_aws.go} | 0 lib/srv/discovery/access_graph_azure.go | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/srv/discovery/{access_graph.go => access_graph_aws.go} (100%) diff --git a/lib/srv/discovery/access_graph.go b/lib/srv/discovery/access_graph_aws.go similarity index 100% rename from lib/srv/discovery/access_graph.go rename to lib/srv/discovery/access_graph_aws.go diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index d504f49a2f904..55201239b61d6 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -289,7 +289,7 @@ func (s *Server) initializeAndWatchAzureAccessGraph(ctx context.Context, reloadC for { err := s.reconcileAccessGraphAzure(ctx, azureResources, stream, features) if errors.Is(err, errNoAccessGraphFetchers) { - _, err := stream.CloseAndRecv() + err := stream.CloseSend() if errors.Is(err, io.EOF) { err = nil } From 0eb22d22da5588431d4ebb994fc13596be4132f0 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 13:45:00 -0600 Subject: [PATCH 27/36] Go mod tidy on integrations --- integrations/event-handler/go.mod | 1 + integrations/terraform/go.mod | 1 + 2 files changed, 2 insertions(+) diff --git a/integrations/event-handler/go.mod b/integrations/event-handler/go.mod index a1faea1d48034..f716fd71ffb2a 100644 --- a/integrations/event-handler/go.mod +++ b/integrations/event-handler/go.mod @@ -37,6 +37,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 // indirect diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index 7240aa79dc715..786539368f8da 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -44,6 +44,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 // indirect From e1d6ecf18cc0e4f893d3cdf0cf34388beaf4d243 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 14:53:35 -0600 Subject: [PATCH 28/36] Fixing race condition in error collection --- lib/srv/discovery/fetchers/azure-sync/azure-sync.go | 2 +- lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index 98c431282f323..c74f5597d528c 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -208,8 +208,8 @@ func (a *Fetcher) fetch(ctx context.Context, feats Features) (*Resources, error) // Collect the error messages from the error channel var wg sync.WaitGroup + wg.Add(1) go func() { - wg.Add(1) defer wg.Done() for { err, ok := <-errsCh diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go index 2c4c47bfb2f3a..9a078f9353f2e 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -43,7 +43,6 @@ func (t testVmCli) ListVirtualMachines(ctx context.Context, scope string) ([]*ar if t.returnErr { return nil, fmt.Errorf("error") } - fmt.Printf("CLIENT VMS: %v\n", t.vms) return t.vms, nil } From fad9a527c20e7ed1958514510a4d83745bf48e82 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 16:35:26 -0600 Subject: [PATCH 29/36] Fixing json mistake in grpc --- api/proto/teleport/legacy/types/types.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 20e25eb673aba..6c2a80850bd71 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8032,7 +8032,7 @@ message AccessGraphSync { (gogoproto.stdduration) = true ]; // Azure is a configuration for Azure Access Graph service poll service. - repeated AccessGraphAzureSync Azure = 3 [(gogoproto.jsontag) = "aws,omitempty"]; + repeated AccessGraphAzureSync Azure = 3 [(gogoproto.jsontag) = "azure,omitempty"]; } // AccessGraphAWSSync is a configuration for AWS Access Graph service poll service. From f32703892fce3752422617a40e3847a730fb14d7 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 17:34:32 -0600 Subject: [PATCH 30/36] Linting --- lib/srv/discovery/access_graph_azure.go | 10 +++++----- lib/srv/discovery/fetchers/azure-sync/azure-sync.go | 1 - .../discovery/fetchers/azure-sync/msggraphclient.go | 6 +++--- lib/srv/discovery/fetchers/azure-sync/principals.go | 3 ++- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 55201239b61d6..d5458e548e833 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -220,7 +220,7 @@ func (s *Server) initializeAndWatchAzureAccessGraph(ctx context.Context, reloadC First: time.Second, Step: semaphoreExpiration / 2, Max: semaphoreExpiration, - Jitter: retryutils.NewJitter(), + Jitter: retryutils.DefaultJitter, }, }, ) @@ -278,7 +278,7 @@ func (s *Server) initializeAndWatchAzureAccessGraph(ctx context.Context, reloadC defer wg.Done() defer cancel() if !accessGraphConn.WaitForStateChange(ctx, connectivity.Ready) { - s.Log.Info("access graph service connection was closed") + s.Log.InfoContext(ctx, "access graph service connection was closed") } }() @@ -320,7 +320,7 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { fetchers := s.getAllTAGSyncAzureFetchers() // Wait for the config to change and re-evaluate the fetchers before starting the sync. if len(fetchers) == 0 { - s.Log.Debug("No Azure sync fetchers configured. Access graph sync will not be enabled.") + s.Log.DebugContext(ctx, "No Azure sync fetchers configured. Access graph sync will not be enabled.") select { case <-ctx.Done(): return @@ -331,10 +331,10 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { } // Reset the Azure resources to force a full sync if err := s.initializeAndWatchAzureAccessGraph(ctx, reloadCh); errors.Is(err, errTAGFeatureNotEnabled) { - s.Log.Warn("Access Graph specified in config, but the license does not include Teleport Policy. Access graph sync will not be enabled.") + s.Log.WarnContext(ctx, "Access Graph specified in config, but the license does not include Teleport Policy. Access graph sync will not be enabled.") break } else if err != nil { - s.Log.Warn("Error initializing and watching access graph", "error", err) + s.Log.WarnContext(ctx, "Error initializing and watching access graph", "error", err) } select { diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index c74f5597d528c..5fa7fd0e0a55e 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -76,7 +76,6 @@ type Fetcher struct { lastDiscoveredResources uint64 lastResult *Resources - graphClient *GraphClient vmClient VirtualMachinesClient roleDefClient RoleDefinitionsClient roleAssignClient RoleAssignmentsClient diff --git a/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go index 2785ebf17658d..75d2960d7fa55 100644 --- a/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go +++ b/lib/srv/discovery/fetchers/azure-sync/msggraphclient.go @@ -196,9 +196,9 @@ func (c *GraphClient) request(ctx context.Context, req request) error { return err } - defer func(Body io.ReadCloser) { - _ = Body.Close() - }(resp.Body) + defer func(r *http.Response) { + _ = r.Body.Close() + }(resp) b, err := io.ReadAll(resp.Body) if err != nil { diff --git a/lib/srv/discovery/fetchers/azure-sync/principals.go b/lib/srv/discovery/fetchers/azure-sync/principals.go index 59ebac5f55284..74aad7f8abceb 100644 --- a/lib/srv/discovery/fetchers/azure-sync/principals.go +++ b/lib/srv/discovery/fetchers/azure-sync/principals.go @@ -12,6 +12,7 @@ import ( ) const groupType = "#microsoft.graph.group" +const defaultGraphScope = "https://graph.microsoft.com/.default" func (a *Fetcher) fetchPrincipals(ctx context.Context) ([]*accessgraphv1alpha.AzurePrincipal, error) { // Get the VM client @@ -19,7 +20,7 @@ func (a *Fetcher) fetchPrincipals(ctx context.Context) ([]*accessgraphv1alpha.Az if err != nil { return nil, trace.Wrap(err) } - scopes := []string{"https://graph.microsoft.com/.default"} + scopes := []string{defaultGraphScope} token, err := cred.GetToken(ctx, policy.TokenRequestOptions{Scopes: scopes}) if err != nil { return nil, trace.Wrap(err) From c900515955ce4c33baacc5bc47c96f0ade655347 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 2 Dec 2024 17:51:00 -0600 Subject: [PATCH 31/36] Adding license --- lib/cloud/azure/roleassignments.go | 18 ++++++++++++++++++ lib/cloud/azure/roledefinitions.go | 18 ++++++++++++++++++ lib/srv/discovery/access_graph_azure.go | 18 ++++++++++++++++++ .../fetchers/azure-sync/azure-sync_test.go | 18 ++++++++++++++++++ .../fetchers/azure-sync/principals.go | 18 ++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go index c381e11d47aeb..e32cf830921bf 100644 --- a/lib/cloud/azure/roleassignments.go +++ b/lib/cloud/azure/roleassignments.go @@ -1,3 +1,21 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package azure import ( diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go index 668f3d4456d3c..8fccf2ad588a3 100644 --- a/lib/cloud/azure/roledefinitions.go +++ b/lib/cloud/azure/roledefinitions.go @@ -1,3 +1,21 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package azure import ( diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index d5458e548e833..1f990fb401ff5 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -1,3 +1,21 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package discovery import ( diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go index 9a078f9353f2e..013e7dba1b51a 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -1,3 +1,21 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package azure_sync import ( diff --git a/lib/srv/discovery/fetchers/azure-sync/principals.go b/lib/srv/discovery/fetchers/azure-sync/principals.go index 74aad7f8abceb..1584989d81cd4 100644 --- a/lib/srv/discovery/fetchers/azure-sync/principals.go +++ b/lib/srv/discovery/fetchers/azure-sync/principals.go @@ -1,3 +1,21 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + package azure_sync import ( From dde6053ce1c8a423c6c56ce2d0593b9fdcb30791 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 5 Dec 2024 17:10:41 -0600 Subject: [PATCH 32/36] Godoc --- lib/cloud/azure/roleassignments.go | 3 +++ lib/cloud/azure/roledefinitions.go | 3 +++ lib/srv/discovery/access_graph_azure.go | 9 ++++++- .../fetchers/azure-sync/azure-sync.go | 27 ++++++++++++------- .../fetchers/azure-sync/reconcile.go | 10 +++++++ .../fetchers/azure-sync/roledefinitions.go | 8 ++++++ 6 files changed, 49 insertions(+), 11 deletions(-) diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go index e32cf830921bf..815ce0af67e13 100644 --- a/lib/cloud/azure/roleassignments.go +++ b/lib/cloud/azure/roleassignments.go @@ -27,10 +27,12 @@ import ( "github.com/gravitational/trace" ) +// RoleAssignmentsClient wraps the Azure API to provide a high level subset of functionality type RoleAssignmentsClient struct { cli *armauthorization.RoleAssignmentsClient } +// NewRoleAssignmentsClient creates a new client for a given subscription and credentials func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentsClient, error) { clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) if err != nil { @@ -40,6 +42,7 @@ func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, return &RoleAssignmentsClient{cli: roleDefCli}, nil } +// ListRoleAssignments returns role assignments for a given scope func (c *RoleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { pager := c.cli.NewListForScopePager(scope, nil) roleDefs := make([]*armauthorization.RoleAssignment, 0, 128) diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go index 8fccf2ad588a3..5c56b1a38e51b 100644 --- a/lib/cloud/azure/roledefinitions.go +++ b/lib/cloud/azure/roledefinitions.go @@ -27,10 +27,12 @@ import ( "github.com/gravitational/trace" ) +// RoleDefinitionsClient wraps the Azure API to provide a high level subset of functionality type RoleDefinitionsClient struct { cli *armauthorization.RoleDefinitionsClient } +// NewRoleDefinitionsClient creates a new client for a given subscription and credentials func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleDefinitionsClient, error) { clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options) if err != nil { @@ -40,6 +42,7 @@ func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, return &RoleDefinitionsClient{cli: roleDefCli}, nil } +// ListRoleDefinitions returns role definitions for a given scope func (c *RoleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { pager := c.cli.NewListPager(scope, nil) roleDefs := make([]*armauthorization.RoleDefinition, 0, 128) diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 1f990fb401ff5..9ea76d1be74e1 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -38,6 +38,8 @@ import ( azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azure-sync" ) +// reconcileAccessGraphAzure fetches Azure resources, creates a set of resources to delete and upsert based on +// the previous fetch, and then sends the delete and upsert results to the Access Graph stream func (s *Server) reconcileAccessGraphAzure( ctx context.Context, currentTAGResources *azure_sync.Resources, @@ -114,6 +116,7 @@ func (s *Server) reconcileAccessGraphAzure( return nil } +// azurePushUpsertInBatches upserts resources to the Access Graph in batches func azurePushUpsertInBatches( client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, upsert *accessgraphv1alpha.AzureResourceList, @@ -139,6 +142,7 @@ func azurePushUpsertInBatches( return nil } +// azurePushDeleteInBatches deletes resources from the Access Graph in batches func azurePushDeleteInBatches( client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, toDel *accessgraphv1alpha.AzureResourceList, @@ -164,6 +168,7 @@ func azurePushDeleteInBatches( return nil } +// azurePush upserts and deletes Azure resources to/from the Access Graph func azurePush( client accessgraphv1alpha.AccessGraphService_AzureEventsStreamClient, upsert *accessgraphv1alpha.AzureResourceList, @@ -365,7 +370,9 @@ func (s *Server) initTAGAzureWatchers(ctx context.Context, cfg *Config) error { return nil } -func (s *Server) accessGraphAzureFetchersFromMatchers(matchers Matchers, discoveryConfigName string) ([]*azure_sync.Fetcher, error) { +// accessGraphAzureFetchersFromMatchers converts matcher configuration to fetchers for Azure resource synchronization +func (s *Server) accessGraphAzureFetchersFromMatchers( + matchers Matchers, discoveryConfigName string) ([]*azure_sync.Fetcher, error) { var fetchers []*azure_sync.Fetcher var errs []error if matchers.AccessGraph == nil { diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index 5fa7fd0e0a55e..3d7b35a4aa6b6 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -43,6 +43,7 @@ const ( const FetcherConcurrency = 5 +// Config defines parameters required for fetching resources from Azure type Config struct { CloudClients cloud.Clients SubscriptionID string @@ -51,6 +52,7 @@ type Config struct { DiscoveryConfigName string } +// Resources represents the set of resources fetched from Azure type Resources struct { Principals []*accessgraphv1alpha.AzurePrincipal RoleDefinitions []*accessgraphv1alpha.AzureRoleDefinition @@ -58,18 +60,22 @@ type Resources struct { VirtualMachines []*accessgraphv1alpha.AzureVirtualMachine } +// RoleDefinitionsClient specifies the methods used to fetch roles from Azure type RoleDefinitionsClient interface { ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) } +// RoleAssignmentsClient specifies the methods used to fetch role assignments from Azure type RoleAssignmentsClient interface { ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) } +// VirtualMachinesClient specifies the methods used to fetch virtual machines from Azure type VirtualMachinesClient interface { ListVirtualMachines(ctx context.Context, resourceGroup string) ([]*armcompute.VirtualMachine, error) } +// Fetcher provides the functionality for fetching resources from Azure type Fetcher struct { Config lastError error @@ -81,6 +87,7 @@ type Fetcher struct { roleAssignClient RoleAssignmentsClient } +// NewFetcher returns a new fetcher based on configuration parameters func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { // Establish the credential from the managed identity cred, err := azidentity.NewDefaultAzureCredential(nil) @@ -121,8 +128,7 @@ type Features struct { AKSClusters bool } -// BuildFeatures builds the feature flags based on supported types returned by Access Graph -// Azure endpoints. +// BuildFeatures builds the feature flags based on supported types returned by Access Graph Azure endpoints. func BuildFeatures(values ...string) Features { features := Features{} for _, value := range values { @@ -141,6 +147,7 @@ func BuildFeatures(values ...string) Features { return features } +// Poll fetches and deduplicates Azure resources specified by the Access Graph func (a *Fetcher) Poll(ctx context.Context, feats Features) (*Resources, error) { res, err := a.fetch(ctx, feats) if res == nil { @@ -153,6 +160,7 @@ func (a *Fetcher) Poll(ctx context.Context, feats Features) (*Resources, error) return res, trace.Wrap(err) } +// fetch returns the resources specified by the Access Graph func (a *Fetcher) fetch(ctx context.Context, feats Features) (*Resources, error) { // Accumulate Azure resources eg, ctx := errgroup.WithContext(ctx) @@ -229,23 +237,22 @@ func (a *Fetcher) fetch(ctx context.Context, feats Features) (*Resources, error) return result, nil } +// Status returns the number of resources last fetched and/or the last fetching/reconciling error func (a *Fetcher) Status() (uint64, error) { return a.lastDiscoveredResources, a.lastError } + +// DiscoveryConfigName returns the name of the configured discovery func (a *Fetcher) DiscoveryConfigName() string { return a.Config.DiscoveryConfigName } + +// IsFromDiscoveryConfig returns whether the discovery is from configuration or dynamic func (a *Fetcher) IsFromDiscoveryConfig() bool { return a.Config.DiscoveryConfigName != "" } + +// GetSubscriptionID returns the ID of the Azure subscription func (a *Fetcher) GetSubscriptionID() string { return a.Config.SubscriptionID } - -func ptrsToList(ptrs []*string) []string { - strList := make([]string, len(ptrs)) - for _, ptr := range ptrs { - strList = append(strList, *ptr) - } - return strList -} diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile.go b/lib/srv/discovery/fetchers/azure-sync/reconcile.go index a184c34972e57..8b93020c5e8c0 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile.go @@ -27,6 +27,7 @@ import ( "github.com/gravitational/teleport/lib/srv/discovery/common" ) +// MergeResources merges Azure resources fetched from multiple configured Azure fetchers func MergeResources(results ...*Resources) *Resources { if len(results) == 0 { return &Resources{} @@ -38,18 +39,25 @@ func MergeResources(results ...*Resources) *Resources { for _, r := range results { result.Principals = append(result.Principals, r.Principals...) result.VirtualMachines = append(result.VirtualMachines, r.VirtualMachines...) + result.RoleDefinitions = append(result.RoleDefinitions, r.RoleDefinitions...) + result.RoleAssignments = append(result.RoleAssignments, r.RoleAssignments...) } result.Principals = common.DeduplicateSlice(result.Principals, azurePrincipalsKey) result.VirtualMachines = common.DeduplicateSlice(result.VirtualMachines, azureVmKey) + result.RoleDefinitions = common.DeduplicateSlice(result.RoleDefinitions, azureRoleDefKey) + result.RoleAssignments = common.DeduplicateSlice(result.RoleAssignments, azureRoleAssignKey) return result } +// newResourceList creates a new resource list message func newResourceList() *accessgraphv1alpha.AzureResourceList { return &accessgraphv1alpha.AzureResourceList{ Resources: make([]*accessgraphv1alpha.AzureResource, 0), } } +// ReconcileResults compares previously and currently fetched results and determines which resources to upsert and +// which to delete. func ReconcileResults(old *Resources, new *Resources) (upsert, delete *accessgraphv1alpha.AzureResourceList) { upsert, delete = newResourceList(), newResourceList() reconciledResources := []*reconcilePair{ @@ -65,10 +73,12 @@ func ReconcileResults(old *Resources, new *Resources) (upsert, delete *accessgra return upsert, delete } +// reconcilePair contains the Azure resources to upsert and delete type reconcilePair struct { upsert, delete *accessgraphv1alpha.AzureResourceList } +// reconcile compares old and new items to build a list of resources to upsert and delete in the Access Graph func reconcile[T proto.Message]( oldItems []T, newItems []T, diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go index b598587ff74d8..d47ce7623b9ea 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -56,3 +56,11 @@ func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alp } return pbRoleDefs, nil } + +func ptrsToList(ptrs []*string) []string { + strList := make([]string, len(ptrs)) + for _, ptr := range ptrs { + strList = append(strList, *ptr) + } + return strList +} From 3c7e90843e5761a25ce7b4d250ab54619c568148 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 5 Dec 2024 17:14:20 -0600 Subject: [PATCH 33/36] Removing UMI client ID --- api/proto/teleport/legacy/types/types.proto | 3 +-- lib/config/configuration.go | 2 -- lib/config/fileconf.go | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 6c2a80850bd71..57ea363fc0b8f 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8049,6 +8049,5 @@ message AccessGraphAWSSync { message AccessGraphAzureSync { repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; string SubscriptionID = 2 [(gogoproto.jsontag) = "subscription_id,omitempty"]; - string UMIClientID = 3 [(gogoproto.jsontag) = "umi_client_id,omitempty"]; - string Integration = 4 [(gogoproto.jsontag) = "integration,omitempty"]; + string Integration = 3 [(gogoproto.jsontag) = "integration,omitempty"]; } diff --git a/lib/config/configuration.go b/lib/config/configuration.go index 1cb3f975ea4bd..33b3b406b46b5 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -1760,12 +1760,10 @@ kubernetes matchers are present`) return trace.BadParameter("missing regions in access_graph.azure") } subscriptionID := azureMatcher.SubscriptionID - umiClientID := azureMatcher.UMIClientID integration := azureMatcher.Integration tMatcher.Azure = append(tMatcher.Azure, &types.AccessGraphAzureSync{ Regions: regions, SubscriptionID: subscriptionID, - UMIClientID: umiClientID, Integration: integration, }) } diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index 7530388cc414d..89b668a0221b5 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -1543,7 +1543,6 @@ type AccessGraphAWSSync struct { type AccessGraphAzureSync struct { Regions []string `yaml:"regions,omitempty"` SubscriptionID string `yaml:"subscription_id,omitempty"` - UMIClientID string `yaml:"umi_client_id,omitempty"` Integration string `yaml:"integration,omitempty"` } From 21da3f3400614e5f16a55b1c9d3a346207f87571 Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Thu, 5 Dec 2024 22:59:19 -0600 Subject: [PATCH 34/36] PR feedback --- api/types/discoveryconfig/derived.gen.go | 1 - lib/srv/discovery/access_graph_azure.go | 14 ++++++ lib/srv/discovery/discovery.go | 4 ++ .../fetchers/azure-sync/azure-sync_test.go | 43 +++++++++++++++---- .../fetchers/azure-sync/roledefinitions.go | 7 +-- 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/api/types/discoveryconfig/derived.gen.go b/api/types/discoveryconfig/derived.gen.go index 9279ab6d4d824..0855486f8af8c 100644 --- a/api/types/discoveryconfig/derived.gen.go +++ b/api/types/discoveryconfig/derived.gen.go @@ -302,7 +302,6 @@ func deriveTeleportEqual_20(this, that *types.AccessGraphAzureSync) bool { this != nil && that != nil && deriveTeleportEqual_14(this.Regions, that.Regions) && this.SubscriptionID == that.SubscriptionID && - this.UMIClientID == that.UMIClientID && this.Integration == that.Integration } diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 9ea76d1be74e1..93896c808fbdf 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -305,6 +305,20 @@ func (s *Server) initializeAndWatchAzureAccessGraph(ctx context.Context, reloadC } }() + // Configure the poll interval + tickerInterval := defaultPollInterval + if s.Config.Matchers.AccessGraph != nil { + if s.Config.Matchers.AccessGraph.PollInterval > defaultPollInterval { + tickerInterval = s.Config.Matchers.AccessGraph.PollInterval + } else { + s.Log.WarnContext(ctx, + "Access graph Azure service poll interval cannot be less than the default", + "default_poll_interval", + defaultPollInterval) + } + } + s.Log.InfoContext(ctx, "Access graph Azure service poll interval", "poll_interval", tickerInterval) + // Reconciles the resources as they're imported from Azure azureResources := &azure_sync.Resources{} ticker := time.NewTicker(15 * time.Minute) diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index c39b934b1e15d..f52a4d2255617 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -1685,6 +1685,10 @@ func (s *Server) deleteDynamicFetchers(name string) { delete(s.dynamicTAGAWSFetchers, name) s.muDynamicTAGAWSFetchers.Unlock() + s.muDynamicTAGAzureFetchers.Lock() + delete(s.dynamicTAGAzureFetchers, name) + s.muDynamicTAGAzureFetchers.Unlock() + s.muDynamicKubeFetchers.Lock() delete(s.dynamicKubeFetchers, name) s.muDynamicKubeFetchers.Unlock() diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go index 013e7dba1b51a..7a7b709e45b35 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -66,12 +66,22 @@ func (t testVmCli) ListVirtualMachines(ctx context.Context, scope string) ([]*ar func newRoleDef(id string, name string) *armauthorization.RoleDefinition { role_name := "test_role_name" + action1 := "Microsoft.Compute/virtualMachines/read" + action2 := "Microsoft.Compute/virtualMachines/*" + action3 := "Microsoft.Compute/*" return &armauthorization.RoleDefinition{ ID: &id, Name: &name, Properties: &armauthorization.RoleDefinitionProperties{ - Permissions: []*armauthorization.Permission{}, - RoleName: &role_name, + Permissions: []*armauthorization.Permission{ + { + Actions: []*string{&action1, &action2}, + }, + { + Actions: []*string{&action3}, + }, + }, + RoleName: &role_name, }, } } @@ -112,7 +122,7 @@ func TestPoll(t *testing.T) { roleAssignClient := testRoleAssignCli{} vmClient := testVmCli{} fetcher := Fetcher{ - Config: Config{}, + Config: Config{SubscriptionID: "1234567890"}, lastResult: &Resources{}, roleDefClient: &roleDefClient, roleAssignClient: &roleAssignClient, @@ -189,14 +199,29 @@ func TestPoll(t *testing.T) { // Verify the results, based on the features set require.NotNil(t, resources) - if tt.feats.RoleDefinitions { - require.Len(t, resources.RoleDefinitions, len(tt.roleDefs)) + require.Equal(t, tt.feats.RoleDefinitions == false || len(tt.roleDefs) == 0, len(resources.RoleDefinitions) == 0) + for idx, resource := range resources.RoleDefinitions { + roleDef := tt.roleDefs[idx] + require.Equal(t, *roleDef.ID, resource.Id) + require.Equal(t, fetcher.SubscriptionID, resource.SubscriptionId) + require.Equal(t, *roleDef.Properties.RoleName, resource.Name) + require.Len(t, roleDef.Properties.Permissions, len(resource.Permissions)) } - if tt.feats.RoleAssignments { - require.Len(t, resources.RoleAssignments, len(tt.roleAssigns)) + require.Equal(t, tt.feats.RoleAssignments == false || len(tt.roleAssigns) == 0, len(resources.RoleAssignments) == 0) + for idx, resource := range resources.RoleAssignments { + roleAssign := tt.roleAssigns[idx] + require.Equal(t, *roleAssign.ID, resource.Id) + require.Equal(t, fetcher.SubscriptionID, resource.SubscriptionId) + require.Equal(t, *roleAssign.Properties.PrincipalID, resource.PrincipalId) + require.Equal(t, *roleAssign.Properties.RoleDefinitionID, resource.RoleDefinitionId) + require.Equal(t, *roleAssign.Properties.Scope, resource.Scope) } - if tt.feats.VirtualMachines { - require.Len(t, resources.VirtualMachines, len(tt.vms)) + require.Equal(t, tt.feats.VirtualMachines == false || len(tt.vms) == 0, len(resources.VirtualMachines) == 0) + for idx, resource := range resources.VirtualMachines { + vm := tt.vms[idx] + require.Equal(t, *vm.ID, resource.Id) + require.Equal(t, fetcher.SubscriptionID, resource.SubscriptionId) + require.Equal(t, *vm.Name, resource.Name) } } } diff --git a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go index d47ce7623b9ea..050cb0cadc816 100644 --- a/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go +++ b/lib/srv/discovery/fetchers/azure-sync/roledefinitions.go @@ -38,10 +38,11 @@ func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alp // Convert to protobuf format pbRoleDefs := make([]*accessgraphv1alpha.AzureRoleDefinition, 0, len(roleDefs)) for _, roleDef := range roleDefs { - pbPerms := make([]*accessgraphv1alpha.AzureRBACPermission, len(roleDef.Properties.Permissions)) + pbPerms := make([]*accessgraphv1alpha.AzureRBACPermission, 0, len(roleDef.Properties.Permissions)) for _, perm := range roleDef.Properties.Permissions { pbPerm := accessgraphv1alpha.AzureRBACPermission{ - Actions: ptrsToList(perm.Actions), + Actions: ptrsToList(perm.Actions), + NotActions: ptrsToList(perm.NotActions), } pbPerms = append(pbPerms, &pbPerm) } @@ -58,7 +59,7 @@ func (a *Fetcher) fetchRoleDefinitions(ctx context.Context) ([]*accessgraphv1alp } func ptrsToList(ptrs []*string) []string { - strList := make([]string, len(ptrs)) + strList := make([]string, 0, len(ptrs)) for _, ptr := range ptrs { strList = append(strList, *ptr) } From 38b6f654042878602aa12f9aefde09463156b03e Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 16 Dec 2024 17:43:26 -0600 Subject: [PATCH 35/36] Update lib/srv/discovery/fetchers/azure-sync/virtualmachines.go Co-authored-by: Marco Dinis --- lib/srv/discovery/fetchers/azure-sync/virtualmachines.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go index bc1c279a8b416..f681444ccb820 100644 --- a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go +++ b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go @@ -28,7 +28,6 @@ import ( ) func (a *Fetcher) fetchVirtualMachines(ctx context.Context) ([]*accessgraphv1alpha.AzureVirtualMachine, error) { - // Fetch the VMs vms, err := a.vmClient.ListVirtualMachines(ctx, "*") if err != nil { return nil, trace.Wrap(err) From 98b65bae64bf501af626353727f08f896b766ded Mon Sep 17 00:00:00 2001 From: Matt Brock Date: Mon, 16 Dec 2024 18:44:42 -0600 Subject: [PATCH 36/36] PR feedback --- api/proto/teleport/legacy/types/types.proto | 3 +- api/types/types.pb.go | 939 ++++++++---------- go.sum | 2 + integrations/event-handler/go.sum | 1 + integrations/terraform/go.sum | 1 + lib/cloud/azure/roleassignments.go | 2 +- lib/cloud/azure/roledefinitions.go | 2 +- lib/srv/discovery/access_graph_azure.go | 1 - lib/srv/discovery/discovery.go | 8 + .../fetchers/azure-sync/azure-sync.go | 55 +- .../fetchers/azure-sync/azure-sync_test.go | 4 +- .../fetchers/azure-sync/reconcile.go | 36 +- .../fetchers/azure-sync/virtualmachines.go | 4 +- 13 files changed, 494 insertions(+), 564 deletions(-) diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 57ea363fc0b8f..64f85e92956af 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -8025,7 +8025,7 @@ message OktaOptions { message AccessGraphSync { // AWS is a configuration for AWS Access Graph service poll service. repeated AccessGraphAWSSync AWS = 1 [(gogoproto.jsontag) = "aws,omitempty"]; - // PollInterval is the frequency at which to poll for AWS resources + // PollInterval is the frequency at which to poll for resources google.protobuf.Duration PollInterval = 2 [ (gogoproto.jsontag) = "poll_interval,omitempty", (gogoproto.nullable) = false, @@ -8047,7 +8047,6 @@ message AccessGraphAWSSync { // AccessGraphAzureSync is a configuration for Azure Access Graph service poll service. message AccessGraphAzureSync { - repeated string Regions = 1 [(gogoproto.jsontag) = "regions,omitempty"]; string SubscriptionID = 2 [(gogoproto.jsontag) = "subscription_id,omitempty"]; string Integration = 3 [(gogoproto.jsontag) = "integration,omitempty"]; } diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 694edf00ace6c..05e442cedce16 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -21376,10 +21376,14 @@ var xxx_messageInfo_OktaOptions proto.InternalMessageInfo // AccessGraphSync is a configuration for Access Graph service. type AccessGraphSync struct { // AWS is a configuration for AWS Access Graph service poll service. - AWS []*AccessGraphAWSSync `protobuf:"bytes,1,rep,name=AWS,proto3" json:"aws,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AWS []*AccessGraphAWSSync `protobuf:"bytes,1,rep,name=AWS,proto3" json:"aws,omitempty"` + // PollInterval is the frequency at which to poll for resources + PollInterval time.Duration `protobuf:"bytes,2,opt,name=PollInterval,proto3,stdduration" json:"poll_interval,omitempty"` + // Azure is a configuration for Azure Access Graph service poll service. + Azure []*AccessGraphAzureSync `protobuf:"bytes,3,rep,name=Azure,proto3" json:"azure,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AccessGraphSync) Reset() { *m = AccessGraphSync{} } @@ -21465,8 +21469,7 @@ var xxx_messageInfo_AccessGraphAWSSync proto.InternalMessageInfo type AccessGraphAzureSync struct { Regions []string `protobuf:"bytes,1,rep,name=Regions,proto3" json:"regions,omitempty"` SubscriptionID string `protobuf:"bytes,2,opt,name=SubscriptionID,proto3" json:"subscription_id,omitempty"` - UMIClientID string `protobuf:"bytes,3,opt,name=UMIClientID,proto3" json:"umi_client_id,omitempty"` - Integration string `protobuf:"bytes,4,opt,name=Integration,proto3" json:"integration,omitempty"` + Integration string `protobuf:"bytes,3,opt,name=Integration,proto3" json:"integration,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -21476,7 +21479,7 @@ func (m *AccessGraphAzureSync) Reset() { *m = AccessGraphAzureSync{} } func (m *AccessGraphAzureSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAzureSync) ProtoMessage() {} func (*AccessGraphAzureSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{359} + return fileDescriptor_9198ee693835762e, []int{372} } func (m *AccessGraphAzureSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21948,7 +21951,7 @@ func init() { func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 30381 bytes of a gzipped FileDescriptorProto + // 30427 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x70, 0x1c, 0x49, 0x76, 0x20, 0x36, 0xdd, 0x8d, 0x8f, 0xc6, 0xc3, 0x57, 0x23, 0x01, 0x92, 0x20, 0x66, 0x86, 0xcd, 0xa9, 0x99, 0xe1, 0x90, 0xb3, 0x33, 0xe4, 0x12, 0xdc, 0xe1, 0xee, 0xec, 0x7c, 0x6d, 0xa3, 0x1b, @@ -23433,421 +23436,424 @@ var fileDescriptor_9198ee693835762e = []byte{ 0x93, 0xb5, 0x1a, 0xfa, 0x9c, 0xa8, 0x9f, 0x28, 0xd0, 0xc9, 0x25, 0x80, 0xe8, 0x15, 0x9f, 0xbf, 0xb9, 0x98, 0x0a, 0xe4, 0xf3, 0x43, 0xff, 0xe7, 0x2f, 0x16, 0x33, 0x4b, 0x00, 0x79, 0x19, 0x21, 0xc7, 0x58, 0x85, 0x8b, 0x3d, 0xd7, 0x3d, 0xb9, 0x06, 0x85, 0x5d, 0x5b, 0x68, 0xfd, 0xea, 0xfb, - 0x76, 0xbb, 0xfd, 0xff, 0xb3, 0xf7, 0x2d, 0x31, 0x6e, 0x64, 0xd7, 0xa1, 0x2a, 0x92, 0xdd, 0xcd, - 0x3e, 0xec, 0x4f, 0xf5, 0xd5, 0xa7, 0x7b, 0x5a, 0x1a, 0x69, 0x54, 0xa3, 0x91, 0x25, 0x8e, 0x67, - 0x6c, 0x69, 0xde, 0x78, 0x66, 0x6c, 0x8f, 0xc7, 0xd5, 0xec, 0xea, 0x26, 0x25, 0xfe, 0x5c, 0x45, - 0xb6, 0x2c, 0xcb, 0x76, 0xb9, 0x44, 0x56, 0x77, 0x97, 0xcd, 0x66, 0xd1, 0x2c, 0x72, 0x64, 0x19, - 0x0f, 0x78, 0x36, 0x1e, 0x60, 0x03, 0xef, 0x25, 0x71, 0xe2, 0x24, 0xc8, 0x20, 0x1b, 0x2f, 0x62, - 0x04, 0x59, 0x64, 0x1b, 0x24, 0x88, 0xb3, 0xf1, 0xce, 0x80, 0x61, 0xc0, 0x40, 0x76, 0x4e, 0x30, - 0x48, 0x06, 0x48, 0x80, 0x7c, 0x76, 0x41, 0xb2, 0xf0, 0x2a, 0xb8, 0xe7, 0xde, 0x5b, 0x75, 0xeb, - 0x43, 0xaa, 0xe5, 0x19, 0x27, 0x31, 0xe0, 0x55, 0x37, 0xcf, 0x3d, 0xe7, 0xd4, 0xfd, 0xdf, 0x73, - 0xcf, 0x3d, 0x1f, 0x77, 0xc0, 0x77, 0xdc, 0x75, 0x01, 0xaf, 0x30, 0x30, 0xe3, 0xac, 0xbd, 0x05, - 0xe7, 0xb2, 0x06, 0x9c, 0x5c, 0x85, 0x15, 0x39, 0x18, 0x10, 0x67, 0x52, 0x72, 0x46, 0x9e, 0x08, - 0x07, 0xc4, 0x19, 0xfc, 0x40, 0x81, 0x4b, 0xf3, 0xb6, 0x0f, 0xb2, 0x0d, 0xc5, 0xd1, 0xd8, 0xf3, - 0x51, 0x4c, 0xe5, 0xd9, 0x16, 0xc4, 0x6f, 0x4c, 0xa4, 0x80, 0xf2, 0xd4, 0xc4, 0x39, 0xe2, 0x0e, - 0x1e, 0xe6, 0x32, 0x42, 0x3a, 0xce, 0x51, 0x40, 0x5e, 0x84, 0x8d, 0xbe, 0x7b, 0xe8, 0x4c, 0x07, - 0x13, 0x3b, 0xe8, 0x1d, 0xbb, 0x7d, 0x74, 0xc1, 0x42, 0xc3, 0x3d, 0x53, 0xe5, 0x05, 0x96, 0x80, - 0xa7, 0x6a, 0xbc, 0x30, 0xa3, 0xc6, 0x77, 0x0a, 0x45, 0x45, 0xcd, 0x99, 0x68, 0x29, 0xa5, 0x7d, - 0x23, 0x07, 0x5b, 0xb3, 0xd6, 0x0b, 0x79, 0x33, 0xab, 0x0f, 0xd8, 0xc3, 0x85, 0x0c, 0x97, 0x1f, - 0x2e, 0xa4, 0xaf, 0x91, 0xdb, 0x10, 0x3a, 0x50, 0x3d, 0x29, 0x18, 0x82, 0x80, 0x51, 0x9a, 0x91, - 0x13, 0x04, 0x8f, 0xe8, 0x96, 0x90, 0x97, 0x02, 0xea, 0x72, 0x98, 0x4c, 0x23, 0x60, 0xe4, 0x35, - 0x80, 0xde, 0xc0, 0x0f, 0x5c, 0xb4, 0x0f, 0xe0, 0xb2, 0x06, 0x33, 0x0b, 0x0f, 0xa1, 0xf2, 0x83, - 0x30, 0x42, 0x2b, 0x7e, 0xdf, 0xe5, 0x03, 0xe8, 0xc0, 0xe6, 0x8c, 0x0d, 0x92, 0x0e, 0x4f, 0x94, - 0x9d, 0x5e, 0xe4, 0xba, 0x9a, 0x86, 0x39, 0xea, 0x93, 0x3d, 0x9e, 0x9b, 0x35, 0x47, 0x1e, 0x03, - 0x49, 0xef, 0x82, 0x94, 0x3b, 0x37, 0x6e, 0x9e, 0x8e, 0x43, 0xee, 0x0c, 0xd2, 0x1d, 0x0f, 0xc8, - 0x15, 0x28, 0x89, 0x5c, 0x96, 0x54, 0x96, 0x67, 0xcc, 0x81, 0x83, 0xee, 0xba, 0x38, 0x79, 0x30, - 0x62, 0x2a, 0xba, 0xc9, 0x71, 0x29, 0x61, 0x19, 0x21, 0x9d, 0xc7, 0x23, 0xd1, 0xba, 0x4b, 0x62, - 0x7e, 0xc7, 0xcf, 0x26, 0x5e, 0xfa, 0xfb, 0x8a, 0x18, 0xfe, 0xf4, 0xe6, 0xfe, 0xa4, 0xfa, 0x11, - 0x40, 0x2f, 0x25, 0x5e, 0x31, 0xfc, 0x9f, 0x4a, 0x2d, 0x62, 0xd5, 0x71, 0xa9, 0x85, 0xff, 0x24, - 0xd7, 0x61, 0x7d, 0xcc, 0xec, 0x58, 0x27, 0x3e, 0xef, 0x4f, 0x96, 0x37, 0x64, 0x95, 0x81, 0x3b, - 0x3e, 0xf6, 0x29, 0xaf, 0xd7, 0x9d, 0xb0, 0xc3, 0xa4, 0xb3, 0x8e, 0xbc, 0x0c, 0xcb, 0xf4, 0xac, - 0xc3, 0x48, 0x3b, 0x09, 0xf7, 0x08, 0xc4, 0x43, 0xc9, 0xc1, 0x2c, 0x7e, 0x99, 0xff, 0xcf, 0x79, - 0xbd, 0x93, 0x13, 0xcc, 0xe4, 0x93, 0x96, 0x6c, 0xc2, 0x92, 0x3f, 0x3e, 0x92, 0x9a, 0xb6, 0xe8, - 0x8f, 0x8f, 0x68, 0xbb, 0x6e, 0x80, 0xca, 0xbc, 0x75, 0x58, 0xd4, 0x84, 0xe0, 0xf1, 0x90, 0x5d, - 0xc5, 0x8b, 0xe6, 0x1a, 0x83, 0x63, 0xc2, 0xfe, 0xc7, 0xc3, 0x1e, 0xc5, 0x0c, 0x02, 0xdf, 0x96, - 0x03, 0x6c, 0xf1, 0x66, 0xaf, 0x05, 0x81, 0x1f, 0x45, 0xda, 0xea, 0x93, 0x1d, 0x58, 0xa5, 0x7c, - 0xc2, 0x30, 0x5f, 0x5c, 0x10, 0x78, 0x36, 0x2d, 0x08, 0x3c, 0x1e, 0xf6, 0x44, 0x15, 0xcd, 0x95, - 0x40, 0xfa, 0x45, 0xee, 0x82, 0x2a, 0x49, 0x4c, 0xe8, 0xbe, 0x99, 0xb0, 0xa9, 0x8e, 0xd8, 0x48, - 0x92, 0x56, 0x6d, 0x78, 0xe8, 0x9b, 0xeb, 0xbd, 0x38, 0x80, 0x77, 0xcd, 0xf7, 0x14, 0xb1, 0x97, - 0x66, 0x10, 0x11, 0x0d, 0x56, 0x8f, 0x9d, 0xc0, 0x0e, 0x82, 0x13, 0x66, 0x23, 0xc6, 0x03, 0x0b, - 0x97, 0x8e, 0x9d, 0xc0, 0x0a, 0x4e, 0x44, 0xe2, 0x92, 0xf3, 0x14, 0xc7, 0x77, 0xa6, 0x93, 0x63, - 0x5b, 0x96, 0xff, 0x58, 0x8f, 0x9d, 0x3d, 0x76, 0x82, 0x16, 0x2d, 0x93, 0x78, 0x93, 0x6b, 0xb0, - 0x86, 0x7c, 0x7b, 0x9e, 0x60, 0x8c, 0x91, 0x2f, 0xcc, 0x15, 0xca, 0xb8, 0xe7, 0x31, 0xce, 0xbc, - 0x86, 0xff, 0x94, 0x83, 0x0b, 0xd9, 0xbd, 0x83, 0xd3, 0x93, 0xf6, 0x29, 0xfa, 0xe8, 0xf1, 0xba, - 0x2d, 0x53, 0x08, 0x8b, 0x5a, 0x92, 0x35, 0x38, 0xb9, 0xcc, 0xc1, 0x29, 0xc3, 0x06, 0x32, 0xe2, - 0x92, 0xe6, 0xc0, 0x0b, 0x26, 0x3c, 0x18, 0x87, 0xb9, 0x4e, 0x0b, 0xd8, 0x7e, 0x5e, 0xa7, 0x60, - 0xf2, 0x02, 0xac, 0x89, 0x1d, 0xd9, 0x7f, 0x34, 0xa4, 0x1f, 0x66, 0xdb, 0xf1, 0x2a, 0x87, 0xb6, - 0x10, 0x48, 0xce, 0xc3, 0xa2, 0x33, 0x1a, 0xd1, 0x4f, 0xb2, 0x5d, 0x78, 0xc1, 0x19, 0x8d, 0x58, - 0x72, 0x1d, 0xf4, 0x48, 0xb4, 0x0f, 0xd1, 0x4a, 0x88, 0x9b, 0x24, 0x9a, 0x2b, 0x08, 0x64, 0x96, - 0x43, 0x01, 0x5d, 0xf7, 0x94, 0x56, 0xa0, 0x2c, 0x21, 0x0a, 0x38, 0xa3, 0x10, 0xe1, 0x19, 0x28, - 0x8a, 0xf7, 0x6a, 0xe6, 0x58, 0x61, 0x2e, 0x39, 0xfc, 0xad, 0xfa, 0x55, 0xd8, 0xec, 0x7b, 0x01, - 0x4e, 0x5e, 0xd6, 0xa4, 0xd1, 0x88, 0xfb, 0x40, 0xb2, 0x20, 0xbd, 0xe6, 0x39, 0x5e, 0x4c, 0x7b, - 0x52, 0x1f, 0x8d, 0x98, 0x27, 0x24, 0xef, 0xeb, 0xd7, 0x61, 0x9d, 0x4b, 0x5c, 0xfc, 0x88, 0xc4, - 0xba, 0xf0, 0x05, 0x4c, 0xaf, 0x42, 0x3c, 0x9d, 0x11, 0x70, 0x50, 0xad, 0x2f, 0x28, 0xff, 0x56, - 0x81, 0xf3, 0x99, 0x22, 0x1b, 0xf9, 0x12, 0x30, 0x97, 0xaf, 0x89, 0x6f, 0x8f, 0xdd, 0x9e, 0x37, - 0xf2, 0x30, 0x86, 0x06, 0x53, 0x69, 0xde, 0x9e, 0x27, 0xec, 0xa1, 0xfb, 0x58, 0xc7, 0x37, 0x43, - 0x22, 0xa6, 0x6b, 0x51, 0xc7, 0x09, 0xf0, 0xf6, 0x03, 0x38, 0x9f, 0x89, 0x9a, 0xa1, 0x03, 0xf9, - 0x70, 0x3c, 0x99, 0xb4, 0x78, 0xa4, 0x4a, 0x34, 0x5a, 0xd2, 0x8d, 0xf0, 0xe6, 0xfd, 0x30, 0x6c, - 0x5e, 0x42, 0xb8, 0x23, 0x46, 0x72, 0x5d, 0x67, 0xdd, 0x4f, 0x04, 0xd1, 0xec, 0xa5, 0xfd, 0x00, - 0xce, 0xf3, 0xc9, 0x77, 0x34, 0x76, 0x46, 0xc7, 0x11, 0x3b, 0x56, 0xd1, 0x0f, 0x65, 0xb1, 0x63, - 0xb3, 0x72, 0x9f, 0xe2, 0x87, 0x5c, 0xcf, 0x3a, 0x69, 0x20, 0x6f, 0xc3, 0x37, 0x73, 0x62, 0xa9, - 0x67, 0x54, 0x27, 0x63, 0x5a, 0x2b, 0x59, 0xd3, 0xfa, 0xf4, 0x6b, 0xaa, 0x09, 0x44, 0xde, 0xac, - 0x98, 0xd6, 0x93, 0x1b, 0x54, 0x09, 0x39, 0x9d, 0x57, 0x44, 0xda, 0x1a, 0x2c, 0x96, 0xcc, 0x73, - 0xa3, 0x97, 0x04, 0x91, 0x8b, 0xb0, 0x1c, 0xe6, 0xcb, 0xe6, 0x07, 0x47, 0x91, 0x01, 0x6a, 0x7d, - 0xf2, 0x1c, 0xac, 0x30, 0x91, 0x3c, 0xb6, 0xe6, 0x00, 0x61, 0x3a, 0x5d, 0x78, 0xa2, 0x0f, 0x14, - 0x78, 0xee, 0x49, 0x7d, 0x48, 0xee, 0xc1, 0x05, 0x34, 0xeb, 0x08, 0xfc, 0x70, 0x18, 0xec, 0x9e, - 0xd3, 0x3b, 0x76, 0xf9, 0xac, 0xd5, 0x32, 0x07, 0x63, 0x34, 0xb2, 0xac, 0x96, 0x34, 0x0e, 0xa3, - 0x91, 0x15, 0xf8, 0xe2, 0x77, 0x85, 0x92, 0xf3, 0x3a, 0xf4, 0xe1, 0xe2, 0x1c, 0x4a, 0x69, 0xe3, - 0x50, 0xe4, 0x8d, 0xe3, 0x06, 0xa8, 0x87, 0x6e, 0x9f, 0xca, 0xc4, 0x6e, 0x1f, 0xab, 0xf6, 0xf6, - 0x6d, 0x96, 0x21, 0xde, 0x5c, 0x0b, 0xe1, 0x56, 0xe0, 0x1f, 0xdc, 0xe6, 0x5f, 0x39, 0x11, 0x47, - 0x9e, 0x7c, 0xad, 0x20, 0x2f, 0xc3, 0xd9, 0x44, 0x7c, 0x92, 0xc8, 0xe1, 0xdd, 0xdc, 0xa0, 0x45, - 0xf1, 0x68, 0x56, 0x57, 0x61, 0x45, 0xcc, 0x8a, 0x71, 0xe8, 0x07, 0x67, 0x96, 0x38, 0x8c, 0xae, - 0x3a, 0xfe, 0xb9, 0xa9, 0x68, 0x54, 0xe6, 0x8d, 0xe4, 0x14, 0xb2, 0x34, 0x79, 0x09, 0x48, 0x28, - 0xb7, 0x87, 0x1b, 0x05, 0xff, 0xe0, 0x86, 0x28, 0x09, 0x57, 0x38, 0xff, 0xec, 0x5f, 0xe5, 0xe0, - 0x6c, 0xc6, 0x55, 0x86, 0x5e, 0x02, 0xbc, 0xe1, 0xc4, 0x3d, 0x62, 0x57, 0x08, 0xb9, 0x91, 0xeb, - 0x12, 0x9c, 0xeb, 0xa7, 0x16, 0x59, 0x06, 0x74, 0xfe, 0x2d, 0xfe, 0x8b, 0x6e, 0x1e, 0xce, 0x58, - 0xa8, 0x5e, 0xe8, 0xbf, 0xa4, 0x06, 0x1b, 0x98, 0xd6, 0x21, 0xf0, 0x7c, 0xcc, 0x0e, 0x81, 0x42, - 0x48, 0x21, 0x76, 0xd9, 0xc1, 0x5a, 0xb4, 0x25, 0x24, 0x2a, 0x85, 0x98, 0xea, 0x28, 0x01, 0x21, - 0x9f, 0x80, 0x6d, 0xe9, 0xac, 0xb1, 0x13, 0x2b, 0x0f, 0x2d, 0xdd, 0xcd, 0x4d, 0x27, 0x3c, 0x75, - 0x76, 0x63, 0x6b, 0x70, 0x07, 0x2e, 0xe3, 0x20, 0x7a, 0xfd, 0x91, 0x9d, 0xca, 0x03, 0x82, 0x4d, - 0x65, 0x81, 0xf3, 0xb7, 0x29, 0x56, 0xad, 0x3f, 0x4a, 0xa4, 0x04, 0xa1, 0xad, 0xe6, 0xdd, 0xf7, - 0x00, 0xce, 0x67, 0xd6, 0x98, 0x1e, 0x30, 0x68, 0x48, 0x15, 0xc9, 0x46, 0x4b, 0xf4, 0x37, 0x15, - 0x8e, 0xae, 0xc2, 0xca, 0x43, 0xd7, 0x19, 0xbb, 0x63, 0x7e, 0x72, 0xf3, 0x29, 0xc1, 0x60, 0xf2, - 0xc1, 0xdd, 0x8f, 0x0f, 0x0d, 0xd7, 0x19, 0x91, 0x06, 0x9c, 0x65, 0x27, 0xa0, 0x77, 0x82, 0xc2, - 0x20, 0xd7, 0x33, 0x29, 0x31, 0x71, 0x08, 0x49, 0xf0, 0x68, 0xaa, 0x21, 0x16, 0xa3, 0x36, 0x37, - 0x8e, 0x92, 0x20, 0xba, 0xa2, 0x2f, 0x64, 0x63, 0x93, 0x1d, 0x28, 0x31, 0xe6, 0xec, 0x5a, 0xc0, - 0x1e, 0x08, 0xae, 0xce, 0xfd, 0x42, 0x05, 0xed, 0x8b, 0x83, 0xf0, 0x7f, 0x7a, 0x5e, 0xe3, 0x5b, - 0xac, 0x7d, 0x22, 0xbf, 0x7f, 0x98, 0x2b, 0x08, 0xe4, 0xef, 0x1e, 0xda, 0x5f, 0x2b, 0xa2, 0xa9, - 0xb1, 0xcb, 0x31, 0x9d, 0x5a, 0x81, 0x3b, 0x14, 0x6f, 0x40, 0xcb, 0x26, 0xff, 0xf5, 0x94, 0x53, - 0x9d, 0xbc, 0x06, 0x2b, 0x94, 0xed, 0xd1, 0x74, 0xc8, 0xa6, 0x5c, 0x3e, 0x16, 0x97, 0xa7, 0xc1, - 0x8a, 0xe8, 0xb0, 0x55, 0xcf, 0x98, 0xa5, 0x93, 0xe8, 0x27, 0x95, 0x96, 0x83, 0x93, 0xc9, 0x48, - 0x9e, 0xa8, 0x42, 0x51, 0x68, 0x35, 0x3a, 0x6d, 0x4e, 0x52, 0xa4, 0x38, 0x91, 0xb4, 0xbc, 0xb3, - 0xc8, 0x54, 0x85, 0xda, 0x8b, 0x50, 0x92, 0x78, 0xd3, 0xc6, 0x30, 0xcf, 0x19, 0xd1, 0x18, 0xf6, - 0x8b, 0x0f, 0xf6, 0x43, 0x28, 0x0a, 0x96, 0xf4, 0x5a, 0x70, 0xec, 0x07, 0x62, 0x91, 0xe3, 0xff, - 0x14, 0x46, 0x7b, 0x19, 0x1b, 0xb9, 0x60, 0xe2, 0xff, 0x78, 0x96, 0x4c, 0x1c, 0x7a, 0x1f, 0x18, - 0x04, 0xf6, 0x08, 0x2d, 0xb0, 0x42, 0xe1, 0x99, 0xc2, 0x3b, 0x83, 0x80, 0xd9, 0x65, 0xf1, 0x6f, - 0xfc, 0x45, 0x78, 0x08, 0x27, 0xb4, 0x09, 0xb3, 0xf6, 0xcc, 0xd8, 0x91, 0x91, 0x4b, 0x1f, 0x19, - 0x2c, 0xde, 0x0a, 0xa7, 0x64, 0x5f, 0x06, 0x84, 0xe1, 0x91, 0x21, 0xed, 0x0c, 0x85, 0xd8, 0xce, - 0x20, 0xdd, 0xc9, 0xa3, 0xd1, 0x63, 0x27, 0x8e, 0xb8, 0x93, 0x27, 0xf7, 0xa9, 0x3f, 0xce, 0x09, - 0x15, 0xc1, 0x8e, 0xef, 0x4f, 0x82, 0xc9, 0xd8, 0x19, 0xc5, 0x54, 0xa1, 0xe4, 0x04, 0x9e, 0x41, - 0x09, 0xfa, 0x36, 0xa6, 0xd0, 0xf0, 0xc7, 0x22, 0xc4, 0x47, 0x38, 0x73, 0x4b, 0xb7, 0x3f, 0x12, - 0x97, 0xf1, 0x75, 0x8a, 0xad, 0xcb, 0xc8, 0x74, 0xc2, 0x4a, 0x5c, 0xab, 0x67, 0xcc, 0x4d, 0xc6, - 0x33, 0x85, 0x45, 0xaa, 0x19, 0x8b, 0x38, 0xa9, 0x0b, 0xdd, 0x89, 0x56, 0x74, 0x9c, 0xab, 0xbc, - 0xd6, 0xc9, 0xa7, 0x60, 0xd9, 0xeb, 0xcb, 0x99, 0x22, 0x93, 0x5a, 0xb8, 0x5a, 0x9f, 0x45, 0xab, - 0x8e, 0x78, 0xd0, 0x39, 0xe7, 0x71, 0xe8, 0xce, 0x6a, 0x4c, 0x69, 0xac, 0xed, 0x88, 0xdb, 0x68, - 0x9a, 0x8c, 0xac, 0x41, 0x2e, 0x1c, 0xe1, 0x9c, 0xd7, 0x67, 0xcb, 0x2b, 0x8a, 0x97, 0x6d, 0xf2, - 0x5f, 0xda, 0xff, 0x86, 0x1b, 0xa7, 0xed, 0x23, 0xba, 0x14, 0x67, 0x74, 0xf8, 0x32, 0x0b, 0x55, - 0x19, 0xef, 0xb7, 0xab, 0x20, 0x87, 0xfb, 0xf5, 0xc4, 0xe6, 0x27, 0x60, 0xdd, 0xb1, 0xa7, 0xfd, - 0x79, 0x1e, 0xd6, 0xe2, 0x6a, 0x72, 0xf2, 0x22, 0x14, 0xa4, 0x1d, 0x68, 0x33, 0x43, 0x97, 0x8e, - 0xfb, 0x0e, 0x22, 0x9d, 0x6a, 0xc7, 0x21, 0x77, 0x60, 0x0d, 0x0d, 0xf7, 0x50, 0xf4, 0x9c, 0x78, - 0xfc, 0xf1, 0x65, 0xfe, 0xfb, 0x59, 0xf1, 0x47, 0xef, 0x5e, 0x39, 0x83, 0x4f, 0x65, 0x2b, 0x94, - 0x96, 0x4a, 0x7f, 0xb4, 0x50, 0xd2, 0x82, 0x16, 0x66, 0x6b, 0x41, 0x79, 0x53, 0x66, 0x68, 0x41, - 0x17, 0xe6, 0x68, 0x41, 0x23, 0x4a, 0x59, 0x0b, 0x8a, 0xba, 0xf0, 0xa5, 0x59, 0xba, 0xf0, 0x88, - 0x86, 0xe9, 0xc2, 0x23, 0x2d, 0x66, 0x71, 0xa6, 0x16, 0x33, 0xa2, 0xe1, 0x5a, 0xcc, 0x6b, 0xbc, - 0x8f, 0xc6, 0xce, 0x23, 0x1b, 0x3b, 0x8f, 0x1f, 0x8b, 0xd8, 0x7a, 0xd3, 0x79, 0x84, 0xc6, 0x35, - 0x3b, 0xcb, 0x20, 0x2c, 0x72, 0xb4, 0xdf, 0x55, 0x12, 0x9a, 0x40, 0x31, 0x7e, 0x2f, 0xc0, 0x1a, - 0x3b, 0xac, 0x78, 0x38, 0x53, 0x76, 0x5a, 0xad, 0x9a, 0xab, 0x02, 0xca, 0xee, 0x9b, 0x1f, 0x82, - 0xf5, 0x10, 0x8d, 0x5f, 0xb9, 0xd0, 0x53, 0xcf, 0x0c, 0xa9, 0x79, 0xd8, 0x99, 0x17, 0x61, 0x23, - 0x44, 0xe4, 0xda, 0x1c, 0x76, 0xdd, 0x5c, 0x35, 0x55, 0x51, 0xd0, 0xe6, 0x70, 0xed, 0x28, 0x79, - 0xf3, 0xf8, 0x25, 0xd5, 0x4a, 0xfb, 0x61, 0x3e, 0xa6, 0x25, 0x11, 0x9f, 0xa1, 0xa7, 0x68, 0xe0, - 0xdb, 0xbc, 0x93, 0xf8, 0x5e, 0x74, 0x75, 0xc6, 0x98, 0x71, 0x9b, 0x26, 0xcb, 0x6a, 0x99, 0x10, - 0x04, 0xbe, 0x30, 0x71, 0xb2, 0x99, 0x44, 0xcd, 0xce, 0x7d, 0x9c, 0xb3, 0x82, 0x1d, 0xdb, 0x78, - 0xca, 0xf3, 0xd9, 0x89, 0x6b, 0x2a, 0x9d, 0xb2, 0x28, 0x59, 0x87, 0xbf, 0xc4, 0x07, 0xba, 0x80, - 0x4a, 0xc5, 0x20, 0xce, 0x3c, 0x9f, 0x71, 0x77, 0x4a, 0x31, 0xc7, 0x5e, 0x42, 0xce, 0xea, 0x54, - 0xfc, 0x2b, 0xd8, 0x1a, 0xb0, 0x82, 0x3a, 0x0a, 0xc1, 0xb0, 0x90, 0xa1, 0x82, 0x4f, 0x37, 0xbe, - 0x52, 0x6b, 0x98, 0x25, 0x4a, 0x27, 0xd8, 0x1c, 0xc3, 0x33, 0xb2, 0x66, 0x21, 0x5e, 0xc9, 0x05, - 0x11, 0xc5, 0x77, 0x6e, 0x0f, 0x44, 0x0a, 0x08, 0xac, 0xea, 0x05, 0x27, 0x0e, 0xe0, 0x68, 0xda, - 0x31, 0x6c, 0xcf, 0x1e, 0x92, 0x39, 0x19, 0xa2, 0xa2, 0x03, 0x34, 0x27, 0x1f, 0xa0, 0xb2, 0x9e, - 0x21, 0x1f, 0xd3, 0x33, 0x68, 0x7f, 0x94, 0x87, 0xe7, 0x4f, 0x31, 0x5c, 0x73, 0xbe, 0xf9, 0xe9, - 0xb8, 0x78, 0x96, 0x8b, 0xdd, 0x0c, 0x29, 0x53, 0xbe, 0x41, 0xd2, 0x5b, 0x6a, 0xb6, 0x70, 0xf6, - 0x25, 0x58, 0x67, 0xbb, 0x20, 0x33, 0x4b, 0x3c, 0x9c, 0x0e, 0x4e, 0xb1, 0x0d, 0x5e, 0x14, 0x3e, - 0x54, 0x09, 0x52, 0xdc, 0x19, 0x71, 0xc7, 0xb0, 0x42, 0x18, 0xe9, 0x40, 0x09, 0xd1, 0x0e, 0x1d, - 0x6f, 0x70, 0x2a, 0x67, 0x1e, 0xe1, 0xa1, 0x25, 0x93, 0x31, 0x6b, 0x6a, 0x0a, 0xd8, 0xc3, 0xdf, - 0xe4, 0x3a, 0xac, 0x0f, 0xa7, 0x27, 0x54, 0xf0, 0x60, 0x73, 0x81, 0x5b, 0x7f, 0x2c, 0x98, 0xab, - 0xc3, 0xe9, 0x89, 0x3e, 0x1a, 0xe1, 0x90, 0xa2, 0x99, 0xc8, 0x06, 0xc5, 0x63, 0xab, 0x56, 0x60, - 0x2e, 0x22, 0x26, 0x65, 0xc0, 0xd6, 0x2d, 0xc7, 0x3d, 0x07, 0xcc, 0x68, 0x90, 0x67, 0xc8, 0x62, - 0x3f, 0xb4, 0xff, 0xc8, 0x89, 0xfb, 0xee, 0xec, 0x79, 0xff, 0xeb, 0x21, 0xca, 0x18, 0xa2, 0x1b, - 0xa0, 0xd2, 0xae, 0x8f, 0x36, 0x95, 0x70, 0x8c, 0xd6, 0x86, 0xd3, 0x93, 0xb0, 0xef, 0xe4, 0x8e, - 0x5f, 0x94, 0x3b, 0xfe, 0x35, 0x71, 0x1f, 0xce, 0xdc, 0x1e, 0x66, 0x77, 0xb9, 0xf6, 0xaf, 0x79, - 0xb8, 0x7e, 0xba, 0x4d, 0xe0, 0xd7, 0xe3, 0x96, 0x31, 0x6e, 0x09, 0xd5, 0xe9, 0x42, 0x4a, 0x75, - 0x9a, 0xb1, 0xf6, 0x16, 0xb3, 0xd6, 0x5e, 0x4a, 0x51, 0xbb, 0x94, 0xa1, 0xa8, 0xcd, 0x5c, 0xa0, - 0xc5, 0x27, 0x2c, 0xd0, 0x65, 0x79, 0x9e, 0xfc, 0x63, 0xa8, 0xc0, 0x88, 0xdf, 0x07, 0x1e, 0xc0, - 0x59, 0x71, 0x1f, 0x60, 0x27, 0x47, 0xa4, 0x7f, 0x2f, 0xdd, 0xbe, 0x99, 0x75, 0x13, 0x40, 0xb4, - 0x0c, 0x69, 0x7d, 0x83, 0xdf, 0x01, 0xa2, 0xf2, 0xff, 0x39, 0xd2, 0x3f, 0xb9, 0x0f, 0x17, 0x30, - 0xbe, 0x7c, 0x4f, 0x7e, 0x39, 0xb0, 0xc7, 0xee, 0x21, 0x9f, 0x0f, 0x57, 0x53, 0xb2, 0xb2, 0xd7, - 0x93, 0xaa, 0x63, 0xba, 0x87, 0xd5, 0x33, 0xe6, 0xb9, 0x20, 0x03, 0x9e, 0xbc, 0x58, 0xfc, 0xa9, - 0x02, 0xda, 0x93, 0xfb, 0x0b, 0x15, 0x55, 0xc9, 0x0e, 0x5f, 0x36, 0x4b, 0x8e, 0xd4, 0x7b, 0xcf, - 0xc3, 0xea, 0xd8, 0x3d, 0x1c, 0xbb, 0xc1, 0x71, 0x4c, 0x03, 0xb2, 0xc2, 0x81, 0xa2, 0x63, 0x44, - 0x50, 0xca, 0xa7, 0x92, 0xcc, 0x05, 0x91, 0xb6, 0x17, 0xde, 0x17, 0x33, 0xc7, 0x81, 0xce, 0x26, - 0xb9, 0x82, 0xec, 0xc7, 0x9d, 0x42, 0x31, 0xa7, 0xe6, 0x4d, 0x1e, 0x3a, 0xf3, 0xd0, 0x1b, 0xb8, - 0xda, 0x5f, 0x2a, 0x42, 0x22, 0xc8, 0xea, 0x3c, 0xf2, 0x40, 0x32, 0xe6, 0xcd, 0xa7, 0xc4, 0x90, - 0x2c, 0x12, 0xd9, 0xee, 0x91, 0x87, 0x67, 0x44, 0x40, 0x2c, 0x3c, 0x23, 0x42, 0xde, 0x87, 0x45, - 0x22, 0xbf, 0x35, 0xbf, 0x21, 0x2c, 0x82, 0xe8, 0x9e, 0x77, 0x70, 0x8b, 0xdc, 0x84, 0x25, 0x66, - 0x04, 0x24, 0xaa, 0xbb, 0x1e, 0xab, 0xee, 0xc1, 0x2d, 0x53, 0x94, 0x6b, 0xef, 0x84, 0xef, 0x5a, - 0xa9, 0x46, 0x1c, 0xdc, 0x22, 0xaf, 0x9d, 0xce, 0x38, 0xb7, 0x28, 0x8c, 0x73, 0x43, 0xc3, 0xdc, - 0xd7, 0x63, 0x86, 0xb9, 0xd7, 0xe6, 0xf7, 0x16, 0x7f, 0x8d, 0x64, 0xe1, 0x08, 0xa3, 0x30, 0x55, - 0x3f, 0xcb, 0xc1, 0xb3, 0x73, 0x29, 0xc8, 0x25, 0x28, 0xea, 0xed, 0x5a, 0x27, 0x1a, 0x5f, 0xba, - 0x66, 0x04, 0x84, 0xec, 0xc3, 0xf2, 0x8e, 0x13, 0x78, 0x3d, 0x3a, 0x8d, 0x33, 0x9f, 0x07, 0x52, - 0x6c, 0x43, 0xf4, 0xea, 0x19, 0x33, 0xa2, 0x25, 0x36, 0x6c, 0xe0, 0x5a, 0x88, 0xa5, 0x9e, 0xca, - 0x67, 0xe8, 0x1a, 0x52, 0x0c, 0x53, 0x64, 0x74, 0x9f, 0x49, 0x01, 0xc9, 0x43, 0x20, 0x96, 0x55, - 0xad, 0xb8, 0xe3, 0x09, 0xbf, 0x83, 0x4f, 0xbc, 0xd0, 0xd2, 0xf3, 0xa3, 0x4f, 0xe8, 0xbb, 0x14, - 0x5d, 0xf5, 0x8c, 0x99, 0xc1, 0x2d, 0xb9, 0xcc, 0xdf, 0x16, 0xf2, 0xce, 0xec, 0x4e, 0x78, 0x8a, - 0x50, 0xaf, 0x37, 0xa0, 0xd8, 0x16, 0xb6, 0x08, 0x92, 0xc5, 0xbc, 0xb0, 0x3b, 0x30, 0xc3, 0x52, - 0xed, 0x37, 0x14, 0xa1, 0x74, 0x78, 0x72, 0x67, 0x49, 0x99, 0xc1, 0xfa, 0xf3, 0x33, 0x83, 0xf5, - 0x7f, 0xc1, 0xcc, 0x60, 0x9a, 0x07, 0x37, 0x4f, 0xdd, 0xb1, 0xe4, 0x93, 0xa0, 0x62, 0x12, 0x25, - 0x47, 0x1a, 0x24, 0xb6, 0xbe, 0x36, 0xc2, 0xd8, 0xdf, 0x55, 0x9e, 0xa9, 0xce, 0x5c, 0xef, 0xc5, - 0xa9, 0xb5, 0x3f, 0xe1, 0x31, 0xdf, 0x6b, 0xfd, 0x76, 0x42, 0xd1, 0xfc, 0x7e, 0x9d, 0x2c, 0x8c, - 0xd8, 0x62, 0x7b, 0x5e, 0x4a, 0x62, 0x99, 0xfe, 0xd6, 0x6c, 0x5f, 0x0b, 0x69, 0xe5, 0xfd, 0x41, - 0x1e, 0x2e, 0xcd, 0x23, 0xcf, 0x4c, 0x93, 0xad, 0x3c, 0x5d, 0x9a, 0xec, 0x9b, 0x50, 0x64, 0xb0, - 0xd0, 0x83, 0x00, 0xc7, 0x96, 0x93, 0xd2, 0xb1, 0x15, 0xc5, 0xe4, 0x79, 0x58, 0xd4, 0x2b, 0x56, - 0x94, 0xb9, 0x0d, 0x4d, 0x7d, 0x9d, 0x5e, 0x80, 0x46, 0xa4, 0xbc, 0x88, 0x7c, 0x31, 0x9d, 0xac, - 0x90, 0xa7, 0x6c, 0xbb, 0x28, 0x75, 0x48, 0x2a, 0x1d, 0x03, 0xd6, 0x37, 0x4a, 0x1f, 0xc0, 0x23, - 0x72, 0x9b, 0xe9, 0xc4, 0x87, 0x1a, 0x2c, 0xb6, 0xc7, 0x6e, 0xe0, 0x4e, 0x64, 0x33, 0xdc, 0x11, - 0x42, 0x4c, 0x5e, 0xc2, 0x8d, 0x64, 0x9d, 0xc7, 0x2c, 0x26, 0xc2, 0xa2, 0x1c, 0xa7, 0x06, 0xad, - 0x6a, 0x29, 0xd8, 0x94, 0x50, 0x28, 0x41, 0xdd, 0x99, 0x0e, 0x7b, 0xc7, 0x5d, 0xb3, 0xce, 0x25, - 0x27, 0x46, 0x30, 0x40, 0x28, 0x6d, 0x60, 0x60, 0x4a, 0x28, 0xda, 0xb7, 0x15, 0x38, 0x97, 0xd5, - 0x0e, 0x72, 0x09, 0x0a, 0xc3, 0xcc, 0xbc, 0x8c, 0x43, 0xe6, 0xca, 0x5d, 0xa2, 0x7f, 0xed, 0x43, - 0x7f, 0x7c, 0xe2, 0x4c, 0x64, 0x63, 0x65, 0x09, 0x6c, 0x02, 0xfd, 0xb1, 0x87, 0xff, 0x93, 0x2b, - 0xe2, 0xc8, 0xc9, 0xa7, 0x32, 0x39, 0xe2, 0x1f, 0x4d, 0x07, 0xa8, 0xf5, 0xdb, 0xad, 0x11, 0x4b, - 0x07, 0xf0, 0x0a, 0x14, 0x68, 0xb5, 0x12, 0xb3, 0x97, 0xce, 0x1f, 0xbd, 0x51, 0xe7, 0x48, 0xac, - 0x56, 0x81, 0x73, 0x32, 0x30, 0x11, 0x59, 0xbb, 0x07, 0x6b, 0x71, 0x0c, 0x62, 0xc4, 0x23, 0xc2, - 0x96, 0x6e, 0xab, 0x9c, 0xd3, 0x8e, 0xef, 0x33, 0x87, 0x99, 0x9d, 0x67, 0x7e, 0xf6, 0xee, 0x15, - 0xa0, 0x3f, 0x19, 0x4d, 0x56, 0xc4, 0x58, 0xed, 0x3b, 0x39, 0x38, 0x17, 0xf9, 0xe8, 0x8b, 0x35, - 0xf4, 0x2b, 0xeb, 0x30, 0xaa, 0xc7, 0x1c, 0x1a, 0x85, 0xdc, 0x98, 0x6e, 0xe0, 0x1c, 0x3f, 0xaa, - 0x7d, 0xd8, 0x9a, 0x85, 0x4f, 0x5e, 0x84, 0x65, 0x0c, 0xeb, 0x34, 0x72, 0x7a, 0xae, 0xbc, 0xcd, - 0x0e, 0x05, 0xd0, 0x8c, 0xca, 0xb5, 0x9f, 0x28, 0xb0, 0xcd, 0xdd, 0x3c, 0x1a, 0x8e, 0x37, 0xc4, - 0x57, 0x82, 0x9e, 0xfb, 0xc1, 0x38, 0x3c, 0xef, 0xc7, 0xf6, 0xb1, 0x17, 0xe2, 0xde, 0x3c, 0xa9, - 0xaf, 0xcd, 0x6e, 0x2d, 0xb9, 0x89, 0xa1, 0xca, 0xf8, 0x2b, 0x7a, 0x81, 0x05, 0x98, 0x18, 0x52, - 0x80, 0x1c, 0x60, 0x02, 0x31, 0xb4, 0xff, 0x03, 0x97, 0xe7, 0x7f, 0x80, 0x7c, 0x01, 0x56, 0x31, - 0xf7, 0x56, 0x77, 0x74, 0x34, 0x76, 0xfa, 0xae, 0xd0, 0xec, 0x09, 0x6d, 0xac, 0x5c, 0xc6, 0x22, - 0xaf, 0xf1, 0x80, 0x07, 0x47, 0x98, 0xd5, 0x8b, 0x13, 0xc5, 0x7c, 0xa9, 0x64, 0x6e, 0xda, 0x37, - 0x14, 0x20, 0x69, 0x1e, 0xe4, 0x63, 0xb0, 0xd2, 0xed, 0x54, 0xac, 0x89, 0x33, 0x9e, 0x54, 0xfd, - 0xe9, 0x98, 0x87, 0x3d, 0x63, 0xfe, 0xef, 0x93, 0x9e, 0xcd, 0xde, 0x83, 0x8e, 0xfd, 0xe9, 0xd8, - 0x8c, 0xe1, 0x61, 0x8e, 0x27, 0xd7, 0xfd, 0x4a, 0xdf, 0x79, 0x1c, 0xcf, 0xf1, 0xc4, 0x61, 0xb1, - 0x1c, 0x4f, 0x1c, 0xa6, 0x7d, 0x5f, 0x81, 0x8b, 0xc2, 0x38, 0xb2, 0x9f, 0x51, 0x97, 0x0a, 0x46, - 0x79, 0x19, 0x8b, 0x38, 0xbb, 0xf3, 0x24, 0xf4, 0x0d, 0x11, 0x08, 0x09, 0x2b, 0x88, 0xa2, 0x3a, - 0xa3, 0x25, 0x9f, 0x86, 0x82, 0x35, 0xf1, 0x47, 0xa7, 0x88, 0x84, 0xa4, 0x86, 0x23, 0x3a, 0xf1, - 0x47, 0xc8, 0x02, 0x29, 0x35, 0x17, 0xce, 0xc9, 0x95, 0x13, 0x35, 0x26, 0x0d, 0x58, 0xe2, 0x21, - 0xef, 0x12, 0x76, 0x07, 0x73, 0xda, 0xb4, 0xb3, 0x2e, 0xc2, 0x2d, 0xf1, 0x38, 0xaf, 0xa6, 0xe0, - 0xa1, 0xfd, 0x96, 0x02, 0x25, 0x2a, 0xd8, 0xe0, 0xa5, 0xf4, 0xfd, 0x4e, 0xe9, 0xb8, 0x1c, 0x2c, - 0xcc, 0x68, 0x42, 0xf6, 0xa7, 0x3a, 0x8d, 0x5f, 0x85, 0xf5, 0x04, 0x01, 0xd1, 0x30, 0xd0, 0xc6, - 0xc0, 0xeb, 0x39, 0x2c, 0x65, 0x0c, 0x33, 0x41, 0x89, 0xc1, 0xb4, 0xff, 0xa7, 0xc0, 0xb9, 0xd6, - 0x57, 0x26, 0x0e, 0x7b, 0xb6, 0x35, 0xa7, 0x03, 0xb1, 0xde, 0xa9, 0xb0, 0x26, 0xac, 0x6c, 0x59, - 0x10, 0x00, 0x26, 0xac, 0x71, 0x98, 0x19, 0x96, 0x92, 0x2a, 0x14, 0xf9, 0xf9, 0x12, 0xf0, 0xf0, - 0xac, 0x97, 0x25, 0xdd, 0x48, 0xc4, 0x98, 0x23, 0xd1, 0x96, 0xe0, 0x16, 0xc6, 0x69, 0xcc, 0x90, - 0x5a, 0xfb, 0x37, 0x05, 0x36, 0x67, 0xd0, 0x90, 0x37, 0x61, 0x01, 0x1d, 0x14, 0xf9, 0xe8, 0x5d, - 0x9a, 0xf1, 0x89, 0x49, 0xef, 0xf8, 0xe0, 0x16, 0x3b, 0x88, 0x4e, 0xe8, 0x0f, 0x93, 0x51, 0x91, - 0x07, 0xb0, 0xac, 0xf7, 0xfb, 0xfc, 0x76, 0x96, 0x8b, 0xdd, 0xce, 0x66, 0x7c, 0xf1, 0xe5, 0x10, - 0x9f, 0xdd, 0xce, 0x98, 0xab, 0x4c, 0xbf, 0x6f, 0x73, 0xe7, 0xcb, 0x88, 0xdf, 0xf6, 0x27, 0x61, - 0x2d, 0x8e, 0xfc, 0x54, 0xfe, 0x62, 0xef, 0x28, 0xa0, 0xc6, 0xeb, 0xf0, 0xcb, 0x09, 0x14, 0x95, - 0x35, 0xcc, 0x4f, 0x98, 0x54, 0xbf, 0x93, 0x83, 0xf3, 0x99, 0x3d, 0x4c, 0x5e, 0x82, 0x45, 0x7d, - 0x34, 0xaa, 0xed, 0xf2, 0x59, 0xc5, 0x25, 0x24, 0x54, 0x7a, 0xc7, 0x2e, 0xaf, 0x0c, 0x89, 0xbc, - 0x02, 0x45, 0x66, 0x1d, 0xb0, 0x2b, 0x36, 0x1c, 0x8c, 0x7c, 0xc3, 0x4d, 0x17, 0xe2, 0x81, 0x52, - 0x05, 0x22, 0xd9, 0x83, 0x35, 0x1e, 0x33, 0xc6, 0x74, 0x8f, 0xdc, 0xaf, 0x85, 0x11, 0xfb, 0x31, - 0xa9, 0x80, 0xd0, 0xa4, 0xdb, 0x63, 0x56, 0x26, 0x47, 0x4d, 0x89, 0x53, 0x91, 0x3a, 0xa8, 0xc8, - 0x53, 0xe6, 0xc4, 0xa2, 0xb5, 0x62, 0x14, 0x1f, 0x56, 0x89, 0x19, 0xbc, 0x52, 0x94, 0xe1, 0x70, - 0xe9, 0x41, 0xe0, 0x1d, 0x0d, 0x4f, 0xdc, 0xe1, 0xe4, 0x97, 0x37, 0x5c, 0xd1, 0x37, 0x4e, 0x35, - 0x5c, 0xbf, 0x57, 0x60, 0x8b, 0x39, 0x49, 0x46, 0x25, 0x1a, 0x29, 0x40, 0x37, 0x4a, 0x34, 0xf4, - 0x7e, 0xc6, 0xa3, 0xa2, 0xec, 0xc2, 0x12, 0x8b, 0x56, 0x23, 0x56, 0xc6, 0xb3, 0x99, 0x55, 0x60, - 0x38, 0x07, 0xb7, 0x98, 0xf8, 0xc2, 0x3c, 0x25, 0x03, 0x53, 0x90, 0x92, 0x03, 0x28, 0x55, 0x06, - 0xae, 0x33, 0x9c, 0x8e, 0x3a, 0xa7, 0x7b, 0x41, 0xdd, 0xe2, 0x6d, 0x59, 0xe9, 0x31, 0x32, 0x7c, - 0x79, 0xc5, 0x9d, 0x5c, 0x66, 0x44, 0x3a, 0xa1, 0xf3, 0x54, 0x01, 0x15, 0xaf, 0x1f, 0x9d, 0xd3, - 0x3f, 0x49, 0x20, 0xd2, 0xc5, 0x3d, 0x03, 0xb9, 0x77, 0x95, 0x0d, 0x6b, 0x75, 0x27, 0x98, 0x74, - 0xc6, 0xce, 0x30, 0xc0, 0x28, 0x97, 0xa7, 0x88, 0x02, 0x76, 0x51, 0x64, 0x70, 0x46, 0x95, 0xe9, - 0x24, 0x24, 0x65, 0x0a, 0xd9, 0x38, 0x3b, 0x2a, 0x2f, 0xed, 0x79, 0x43, 0x67, 0xe0, 0x7d, 0x5d, - 0xf8, 0x98, 0x32, 0x79, 0xe9, 0x50, 0x00, 0xcd, 0xa8, 0x5c, 0xfb, 0x7c, 0x6a, 0xdc, 0x58, 0x2d, - 0x4b, 0xb0, 0xc4, 0x23, 0x10, 0x30, 0x8f, 0xfc, 0xb6, 0xd1, 0xdc, 0xad, 0x35, 0xf7, 0x55, 0x85, - 0xac, 0x01, 0xb4, 0xcd, 0x56, 0xc5, 0xb0, 0x2c, 0xfa, 0x3b, 0x47, 0x7f, 0x73, 0x77, 0xfd, 0xbd, - 0x6e, 0x5d, 0xcd, 0x4b, 0x1e, 0xfb, 0x05, 0xed, 0xc7, 0x0a, 0x5c, 0xc8, 0x1e, 0x4a, 0xd2, 0x01, - 0x8c, 0xd9, 0xc0, 0xdf, 0xd2, 0x3f, 0x36, 0x77, 0xdc, 0x33, 0xc1, 0xc9, 0xd8, 0x0f, 0x13, 0x16, - 0x53, 0x20, 0x27, 0xde, 0xbe, 0x98, 0x93, 0xa2, 0xd7, 0x37, 0x73, 0x5e, 0x5f, 0xab, 0xc0, 0xd6, - 0x2c, 0x1e, 0xf1, 0xa6, 0xae, 0x43, 0x49, 0x6f, 0xb7, 0xeb, 0xb5, 0x8a, 0xde, 0xa9, 0xb5, 0x9a, - 0xaa, 0x42, 0x96, 0x61, 0x61, 0xdf, 0x6c, 0x75, 0xdb, 0x6a, 0x4e, 0xfb, 0xae, 0x02, 0xab, 0xb5, - 0xc8, 0xea, 0xec, 0xfd, 0x2e, 0xbe, 0x8f, 0xc7, 0x16, 0xdf, 0x56, 0x18, 0xdd, 0x24, 0xfc, 0xc0, - 0xa9, 0x56, 0xde, 0x7b, 0x39, 0xd8, 0x48, 0xd1, 0x10, 0x0b, 0x96, 0xf4, 0x7b, 0x56, 0xab, 0xb6, - 0x5b, 0xe1, 0x35, 0xbb, 0x12, 0x99, 0x4b, 0x61, 0xbe, 0xab, 0xd4, 0x57, 0x98, 0x47, 0xf0, 0xa3, - 0xc0, 0xf6, 0xbd, 0xbe, 0x94, 0xfc, 0xb6, 0x7a, 0xc6, 0x14, 0x9c, 0xf0, 0x24, 0xfb, 0xfa, 0x74, - 0xec, 0x22, 0xdb, 0x5c, 0x4c, 0xaf, 0x1b, 0xc2, 0xd3, 0x8c, 0xd1, 0x7f, 0xc3, 0xa1, 0xe5, 0x69, - 0xd6, 0x11, 0x3f, 0xd2, 0x84, 0xc5, 0x7d, 0x6f, 0x52, 0x9d, 0x3e, 0xe4, 0xeb, 0xf7, 0x72, 0x94, - 0xfd, 0xa8, 0x3a, 0x7d, 0x98, 0x66, 0x8b, 0x2a, 0x4b, 0x16, 0xbd, 0x27, 0xc6, 0x92, 0x73, 0x49, - 0x3a, 0x31, 0x16, 0x9e, 0xca, 0x89, 0x71, 0x67, 0x15, 0x4a, 0xfc, 0x0e, 0x85, 0xd7, 0x93, 0x1f, - 0x2a, 0xb0, 0x35, 0xab, 0xe7, 0xe8, 0xb5, 0x2c, 0x1e, 0xac, 0xe0, 0x42, 0x98, 0x1e, 0x23, 0x1e, - 0xa5, 0x40, 0xa0, 0x91, 0xb7, 0xa0, 0x54, 0x0b, 0x82, 0xa9, 0x3b, 0xb6, 0x5e, 0xe9, 0x9a, 0x35, - 0x3e, 0x5d, 0x9f, 0xfd, 0xe7, 0x77, 0xaf, 0x6c, 0xa2, 0xcf, 0xc7, 0xd8, 0x0e, 0x5e, 0xb1, 0xa7, - 0x63, 0x2f, 0x96, 0x4a, 0x40, 0xa6, 0xa0, 0x52, 0xb4, 0x33, 0xed, 0x7b, 0xae, 0xb8, 0x43, 0x08, - 0x87, 0x6e, 0x0e, 0x93, 0xcf, 0x34, 0x01, 0xd3, 0xbe, 0xa5, 0xc0, 0xf6, 0xec, 0x61, 0xa2, 0xe7, - 0x64, 0x87, 0x99, 0x54, 0x09, 0x97, 0x6a, 0x3c, 0x27, 0x43, 0xbb, 0x2b, 0x99, 0xa7, 0x40, 0xa4, - 0x44, 0x61, 0x6a, 0xfc, 0x5c, 0x2a, 0x1f, 0x76, 0x9c, 0x48, 0x20, 0x6a, 0xf7, 0x61, 0x73, 0xc6, - 0xa0, 0x92, 0x4f, 0x65, 0x26, 0xdd, 0x41, 0x37, 0x25, 0x39, 0xe9, 0x4e, 0x2c, 0x7b, 0x9b, 0x04, - 0xd7, 0xfe, 0x25, 0x07, 0x17, 0xe8, 0xea, 0x1a, 0xb8, 0x41, 0xa0, 0x47, 0xf9, 0x69, 0xe9, 0xae, - 0xf8, 0x1a, 0x2c, 0x1e, 0x3f, 0x9d, 0xaa, 0x98, 0xa1, 0x13, 0x02, 0x78, 0x62, 0x09, 0xe7, 0x18, - 0xfa, 0x3f, 0xb9, 0x0a, 0x72, 0x72, 0xf3, 0x3c, 0x86, 0x37, 0xcd, 0x6d, 0x29, 0xe6, 0xf2, 0x28, - 0xcc, 0x43, 0xfc, 0x3a, 0x2c, 0xa0, 0x3e, 0x85, 0x9f, 0x1d, 0x42, 0xe6, 0xcf, 0xae, 0x1d, 0x6a, - 0x5b, 0x4c, 0x46, 0x40, 0x3e, 0x02, 0x10, 0x65, 0x86, 0xe0, 0x87, 0x83, 0xd0, 0x33, 0x84, 0xc9, - 0x21, 0xcc, 0xe5, 0x93, 0x43, 0x87, 0xa7, 0x5b, 0x28, 0xc3, 0x86, 0xe8, 0xf1, 0x91, 0x88, 0x8a, - 0xc8, 0x5f, 0x31, 0xd7, 0x59, 0x41, 0x6d, 0x24, 0x22, 0x23, 0x5e, 0x4b, 0x25, 0x68, 0xc6, 0xe0, - 0xc8, 0x89, 0x2c, 0xcc, 0xd7, 0x52, 0x59, 0x98, 0x8b, 0x0c, 0x4b, 0x4e, 0xb5, 0xac, 0xfd, 0x43, - 0x0e, 0x96, 0xef, 0x51, 0xa9, 0x0c, 0x75, 0x0d, 0xf3, 0x75, 0x17, 0xb7, 0xa1, 0x54, 0xf7, 0x1d, - 0xfe, 0x5c, 0xc4, 0x7d, 0x4a, 0x98, 0x4f, 0xf7, 0xc0, 0x77, 0xc4, 0xcb, 0x53, 0x60, 0xca, 0x48, - 0x4f, 0xf0, 0x47, 0xbf, 0x03, 0x8b, 0xec, 0xf9, 0x8e, 0xab, 0xd1, 0x84, 0x5c, 0x1e, 0xd6, 0xe8, - 0x65, 0x56, 0x2c, 0xbd, 0x70, 0xb0, 0x27, 0x40, 0x59, 0x48, 0xe4, 0x31, 0x5e, 0x25, 0xcd, 0xca, - 0xc2, 0xe9, 0x34, 0x2b, 0x52, 0x2c, 0xbb, 0xc5, 0xd3, 0xc4, 0xb2, 0xdb, 0x7e, 0x03, 0x4a, 0x52, - 0x7d, 0x9e, 0x4a, 0x4c, 0xff, 0x66, 0x0e, 0x56, 0xb1, 0x55, 0xa1, 0x2d, 0xcf, 0xaf, 0xa6, 0x9e, - 0xe8, 0xe3, 0x31, 0x3d, 0xd1, 0x96, 0x3c, 0x5e, 0xac, 0x65, 0x73, 0x14, 0x44, 0x77, 0x60, 0x23, - 0x85, 0x48, 0x5e, 0x85, 0x05, 0x5a, 0x7d, 0x71, 0xaf, 0x56, 0x93, 0x33, 0x20, 0x8a, 0x7b, 0x4c, - 0x1b, 0x1e, 0x98, 0x0c, 0x5b, 0xfb, 0x77, 0x05, 0x56, 0x78, 0xda, 0x91, 0xe1, 0xa1, 0xff, 0xc4, - 0xee, 0xbc, 0x9e, 0xec, 0x4e, 0x16, 0x5d, 0x85, 0x77, 0xe7, 0x7f, 0x75, 0x27, 0xbe, 0x11, 0xeb, - 0xc4, 0xcd, 0x30, 0x0a, 0xa2, 0x68, 0xce, 0x9c, 0x3e, 0xfc, 0x01, 0xc6, 0x05, 0x8e, 0x23, 0x92, - 0x2f, 0xc2, 0x72, 0xd3, 0x7d, 0x14, 0xbb, 0x9e, 0x5e, 0x9f, 0xc1, 0xf4, 0xe5, 0x10, 0x91, 0xad, - 0x29, 0x3c, 0xd9, 0x87, 0xee, 0x23, 0x3b, 0xf5, 0x72, 0x18, 0xb1, 0xa4, 0x37, 0xd4, 0x38, 0xd9, - 0xd3, 0x4c, 0x7d, 0xee, 0xe0, 0x8a, 0x01, 0x83, 0xbe, 0x9d, 0x07, 0x88, 0x7c, 0x03, 0xe9, 0x02, - 0x8c, 0x19, 0x4d, 0x08, 0xcd, 0x3e, 0x82, 0xe4, 0x39, 0x2e, 0x6c, 0x29, 0xae, 0x73, 0x0d, 0x74, - 0x6e, 0x76, 0x94, 0x4a, 0xd4, 0x45, 0x57, 0xb8, 0x33, 0x5a, 0xdf, 0x1d, 0x38, 0x6c, 0x6f, 0xcf, - 0xef, 0x5c, 0xc3, 0xa0, 0xc4, 0x21, 0x74, 0x46, 0xba, 0x69, 0x74, 0x59, 0xdb, 0xa5, 0x08, 0x29, - 0x7f, 0xdb, 0xc2, 0xd3, 0xf9, 0xdb, 0xb6, 0x61, 0xd9, 0x1b, 0xbe, 0xed, 0x0e, 0x27, 0xfe, 0xf8, - 0x31, 0xaa, 0xdd, 0x23, 0x7d, 0x1e, 0xed, 0x82, 0x9a, 0x28, 0x63, 0xe3, 0x80, 0x67, 0x6e, 0x88, - 0x2f, 0x0f, 0x43, 0x08, 0x0c, 0xfd, 0x85, 0x17, 0xd4, 0xc5, 0x3b, 0x85, 0xe2, 0xa2, 0xba, 0x74, - 0xa7, 0x50, 0x2c, 0xaa, 0xcb, 0x77, 0x0a, 0xc5, 0x65, 0x15, 0x4c, 0xe9, 0xcd, 0x2c, 0x7c, 0x13, + 0x76, 0xbb, 0xfd, 0xff, 0xb3, 0xf7, 0x6d, 0x31, 0x6e, 0x24, 0xd7, 0xa1, 0x6a, 0x92, 0x33, 0xc3, + 0x39, 0x9c, 0x47, 0x4f, 0xe9, 0x31, 0xb3, 0x92, 0x56, 0x5a, 0xf5, 0x6a, 0x65, 0x89, 0xeb, 0x5d, + 0x5b, 0xda, 0xbb, 0xde, 0x5d, 0xdb, 0xeb, 0x75, 0x0f, 0xa7, 0x67, 0x48, 0x89, 0x2f, 0x77, 0x93, + 0x23, 0xcb, 0xb2, 0xdd, 0x6e, 0x91, 0x3d, 0x33, 0x6d, 0x73, 0xd8, 0x34, 0x9b, 0x5c, 0x59, 0xc6, + 0x05, 0xae, 0x8d, 0x0b, 0xd8, 0xc0, 0xbd, 0x49, 0x9c, 0x38, 0x09, 0xb2, 0xc8, 0x8f, 0x3f, 0x62, + 0x04, 0xf9, 0xc8, 0x7f, 0x82, 0x38, 0x3f, 0xfe, 0x33, 0x60, 0x18, 0x30, 0x90, 0x3f, 0x27, 0x58, + 0x24, 0x0b, 0x24, 0x40, 0x1e, 0x7f, 0x41, 0xf2, 0x61, 0x20, 0x40, 0x50, 0xa7, 0xaa, 0xba, 0xab, + 0x1f, 0xa4, 0x66, 0xbc, 0xeb, 0x24, 0x06, 0xfc, 0x35, 0xc3, 0x53, 0xe7, 0x9c, 0xae, 0x77, 0x9d, + 0x3a, 0x75, 0x1e, 0xee, 0x80, 0xef, 0xb8, 0xeb, 0x02, 0x5e, 0x61, 0x60, 0xc6, 0x59, 0x7b, 0x0b, + 0xce, 0x65, 0x0d, 0x38, 0xb9, 0x06, 0x2b, 0x72, 0x30, 0x20, 0xce, 0xa4, 0xe4, 0x8c, 0x3c, 0x11, + 0x0e, 0x88, 0x33, 0xf8, 0x81, 0x02, 0x97, 0xe7, 0x6d, 0x1f, 0xe4, 0x22, 0x14, 0x47, 0x63, 0xcf, + 0x47, 0x31, 0x95, 0x67, 0x5b, 0x10, 0xbf, 0x31, 0x91, 0x02, 0xca, 0x53, 0x13, 0xe7, 0x90, 0x3b, + 0x78, 0x98, 0xcb, 0x08, 0xe9, 0x38, 0x87, 0x01, 0x79, 0x11, 0x36, 0xfa, 0xee, 0x81, 0x33, 0x1d, + 0x4c, 0xec, 0xa0, 0x77, 0xe4, 0xf6, 0xd1, 0x05, 0x0b, 0x0d, 0xf7, 0x4c, 0x95, 0x17, 0x58, 0x02, + 0x9e, 0xaa, 0xf1, 0xc2, 0x8c, 0x1a, 0xdf, 0x2d, 0x14, 0x15, 0x35, 0x67, 0xa2, 0xa5, 0x94, 0xf6, + 0x8d, 0x1c, 0x6c, 0xcd, 0x5a, 0x2f, 0xe4, 0xcd, 0xac, 0x3e, 0x60, 0x0f, 0x17, 0x32, 0x5c, 0x7e, + 0xb8, 0x90, 0xbe, 0x46, 0xee, 0x40, 0xe8, 0x40, 0xf5, 0xb4, 0x60, 0x08, 0x02, 0x46, 0x69, 0x46, + 0x4e, 0x10, 0x3c, 0xa6, 0x5b, 0x42, 0x5e, 0x0a, 0xa8, 0xcb, 0x61, 0x32, 0x8d, 0x80, 0x91, 0xd7, + 0x00, 0x7a, 0x03, 0x3f, 0x70, 0xd1, 0x3e, 0x80, 0xcb, 0x1a, 0xcc, 0x2c, 0x3c, 0x84, 0xca, 0x0f, + 0xc2, 0x08, 0xad, 0xf8, 0x7d, 0x97, 0x0f, 0xa0, 0x03, 0x9b, 0x33, 0x36, 0x48, 0x3a, 0x3c, 0x51, + 0x76, 0x7a, 0x91, 0xeb, 0x6a, 0x1a, 0xe6, 0xa8, 0x4f, 0xf6, 0x78, 0x6e, 0xd6, 0x1c, 0x79, 0x02, + 0x24, 0xbd, 0x0b, 0x52, 0xee, 0xdc, 0xb8, 0x79, 0x3a, 0x0e, 0xb9, 0x33, 0x48, 0x77, 0x3c, 0x20, + 0x57, 0xa1, 0x24, 0x72, 0x59, 0x52, 0x59, 0x9e, 0x31, 0x07, 0x0e, 0xba, 0xe7, 0xe2, 0xe4, 0xc1, + 0x88, 0xa9, 0xe8, 0x26, 0xc7, 0xa5, 0x84, 0x65, 0x84, 0x74, 0x9e, 0x8c, 0x44, 0xeb, 0x2e, 0x8b, + 0xf9, 0x1d, 0x3f, 0x9b, 0x78, 0xe9, 0xef, 0x2b, 0x62, 0xf8, 0xd3, 0x9b, 0xfb, 0xd3, 0xea, 0x47, + 0x00, 0xbd, 0x94, 0x78, 0xc5, 0xf0, 0x7f, 0x2a, 0xb5, 0x88, 0x55, 0xc7, 0xa5, 0x16, 0xfe, 0x93, + 0xdc, 0x80, 0xf5, 0x31, 0xb3, 0x63, 0x9d, 0xf8, 0xbc, 0x3f, 0x59, 0xde, 0x90, 0x55, 0x06, 0xee, + 0xf8, 0xd8, 0xa7, 0xbc, 0x5e, 0x77, 0xc3, 0x0e, 0x93, 0xce, 0x3a, 0xf2, 0x32, 0x2c, 0xd3, 0xb3, + 0x0e, 0x23, 0xed, 0x24, 0xdc, 0x23, 0x10, 0x0f, 0x25, 0x07, 0xb3, 0xf8, 0x65, 0xfe, 0x3f, 0xe7, + 0xf5, 0x4e, 0x4e, 0x30, 0x93, 0x4f, 0x5a, 0xb2, 0x09, 0x4b, 0xfe, 0xf8, 0x50, 0x6a, 0xda, 0xa2, + 0x3f, 0x3e, 0xa4, 0xed, 0xba, 0x09, 0x2a, 0xf3, 0xd6, 0x61, 0x51, 0x13, 0x82, 0x27, 0x43, 0x76, + 0x15, 0x2f, 0x9a, 0x6b, 0x0c, 0x8e, 0x09, 0xfb, 0x9f, 0x0c, 0x7b, 0x14, 0x33, 0x08, 0x7c, 0x5b, + 0x0e, 0xb0, 0xc5, 0x9b, 0xbd, 0x16, 0x04, 0x7e, 0x14, 0x69, 0xab, 0x4f, 0xb6, 0x61, 0x95, 0xf2, + 0x09, 0xc3, 0x7c, 0x71, 0x41, 0xe0, 0xd9, 0xb4, 0x20, 0xf0, 0x64, 0xd8, 0x13, 0x55, 0x34, 0x57, + 0x02, 0xe9, 0x17, 0xb9, 0x07, 0xaa, 0x24, 0x31, 0xa1, 0xfb, 0x66, 0xc2, 0xa6, 0x3a, 0x62, 0x23, + 0x49, 0x5a, 0xb5, 0xe1, 0x81, 0x6f, 0xae, 0xf7, 0xe2, 0x00, 0xde, 0x35, 0xdf, 0x53, 0xc4, 0x5e, + 0x9a, 0x41, 0x44, 0x34, 0x58, 0x3d, 0x72, 0x02, 0x3b, 0x08, 0x8e, 0x99, 0x8d, 0x18, 0x0f, 0x2c, + 0x5c, 0x3a, 0x72, 0x02, 0x2b, 0x38, 0x16, 0x89, 0x4b, 0xce, 0x53, 0x1c, 0xdf, 0x99, 0x4e, 0x8e, + 0x6c, 0x59, 0xfe, 0x63, 0x3d, 0x76, 0xf6, 0xc8, 0x09, 0x5a, 0xb4, 0x4c, 0xe2, 0x4d, 0xae, 0xc3, + 0x1a, 0xf2, 0xed, 0x79, 0x82, 0x31, 0x46, 0xbe, 0x30, 0x57, 0x28, 0xe3, 0x9e, 0xc7, 0x38, 0xf3, + 0x1a, 0xfe, 0x63, 0x0e, 0x2e, 0x64, 0xf7, 0x0e, 0x4e, 0x4f, 0xda, 0xa7, 0xe8, 0xa3, 0xc7, 0xeb, + 0xb6, 0x4c, 0x21, 0x2c, 0x6a, 0x49, 0xd6, 0xe0, 0xe4, 0x32, 0x07, 0xa7, 0x0c, 0x1b, 0xc8, 0x88, + 0x4b, 0x9a, 0x03, 0x2f, 0x98, 0xf0, 0x60, 0x1c, 0xe6, 0x3a, 0x2d, 0x60, 0xfb, 0x79, 0x9d, 0x82, + 0xc9, 0x0b, 0xb0, 0x26, 0x76, 0x64, 0xff, 0xf1, 0x90, 0x7e, 0x98, 0x6d, 0xc7, 0xab, 0x1c, 0xda, + 0x42, 0x20, 0x39, 0x0f, 0x8b, 0xce, 0x68, 0x44, 0x3f, 0xc9, 0x76, 0xe1, 0x05, 0x67, 0x34, 0x62, + 0xc9, 0x75, 0xd0, 0x23, 0xd1, 0x3e, 0x40, 0x2b, 0x21, 0x6e, 0x92, 0x68, 0xae, 0x20, 0x90, 0x59, + 0x0e, 0x05, 0x74, 0xdd, 0x53, 0x5a, 0x81, 0xb2, 0x84, 0x28, 0xe0, 0x8c, 0x42, 0x84, 0x67, 0xa0, + 0x28, 0xde, 0xab, 0x99, 0x63, 0x85, 0xb9, 0xe4, 0xf0, 0xb7, 0xea, 0x57, 0x61, 0xb3, 0xef, 0x05, + 0x38, 0x79, 0x59, 0x93, 0x46, 0x23, 0xee, 0x03, 0xc9, 0x82, 0xf4, 0x9a, 0xe7, 0x78, 0x31, 0xed, + 0x49, 0x7d, 0x34, 0x62, 0x9e, 0x90, 0xbc, 0xaf, 0x5f, 0x87, 0x75, 0x2e, 0x71, 0xf1, 0x23, 0x12, + 0xeb, 0xc2, 0x17, 0x30, 0xbd, 0x0a, 0xf1, 0x74, 0x46, 0xc0, 0x41, 0xb5, 0xbe, 0xa0, 0xfc, 0x1b, + 0x05, 0xce, 0x67, 0x8a, 0x6c, 0xe4, 0x4b, 0xc0, 0x5c, 0xbe, 0x26, 0xbe, 0x3d, 0x76, 0x7b, 0xde, + 0xc8, 0xc3, 0x18, 0x1a, 0x4c, 0xa5, 0x79, 0x67, 0x9e, 0xb0, 0x87, 0xee, 0x63, 0x1d, 0xdf, 0x0c, + 0x89, 0x98, 0xae, 0x45, 0x1d, 0x27, 0xc0, 0x17, 0x1f, 0xc2, 0xf9, 0x4c, 0xd4, 0x0c, 0x1d, 0xc8, + 0x87, 0xe3, 0xc9, 0xa4, 0xc5, 0x23, 0x55, 0xa2, 0xd1, 0x92, 0x6e, 0x84, 0x37, 0xef, 0x87, 0x61, + 0xf3, 0x12, 0xc2, 0x1d, 0x31, 0x92, 0xeb, 0x3a, 0xeb, 0x7e, 0x22, 0x88, 0x66, 0x2f, 0xed, 0x87, + 0x70, 0x9e, 0x4f, 0xbe, 0xc3, 0xb1, 0x33, 0x3a, 0x8a, 0xd8, 0xb1, 0x8a, 0x7e, 0x28, 0x8b, 0x1d, + 0x9b, 0x95, 0x7b, 0x14, 0x3f, 0xe4, 0x7a, 0xd6, 0x49, 0x03, 0x79, 0x1b, 0xbe, 0x99, 0x13, 0x4b, + 0x3d, 0xa3, 0x3a, 0x19, 0xd3, 0x5a, 0xc9, 0x9a, 0xd6, 0x27, 0x5f, 0x53, 0x4d, 0x20, 0xf2, 0x66, + 0xc5, 0xb4, 0x9e, 0xdc, 0xa0, 0x4a, 0xc8, 0xe9, 0xbc, 0x22, 0xd2, 0xd6, 0x60, 0xb1, 0x64, 0x9e, + 0x1b, 0xbd, 0x24, 0x88, 0x5c, 0x82, 0xe5, 0x30, 0x5f, 0x36, 0x3f, 0x38, 0x8a, 0x0c, 0x50, 0xeb, + 0x93, 0xe7, 0x60, 0x85, 0x89, 0xe4, 0xb1, 0x35, 0x07, 0x08, 0xd3, 0xe9, 0xc2, 0x13, 0x7d, 0xa0, + 0xc0, 0x73, 0x4f, 0xeb, 0x43, 0x72, 0x1f, 0x2e, 0xa0, 0x59, 0x47, 0xe0, 0x87, 0xc3, 0x60, 0xf7, + 0x9c, 0xde, 0x91, 0xcb, 0x67, 0xad, 0x96, 0x39, 0x18, 0xa3, 0x91, 0x65, 0xb5, 0xa4, 0x71, 0x18, + 0x8d, 0xac, 0xc0, 0x17, 0xbf, 0x2b, 0x94, 0x9c, 0xd7, 0xa1, 0x0f, 0x97, 0xe6, 0x50, 0x4a, 0x1b, + 0x87, 0x22, 0x6f, 0x1c, 0x37, 0x41, 0x3d, 0x70, 0xfb, 0x54, 0x26, 0x76, 0xfb, 0x58, 0xb5, 0xb7, + 0xef, 0xb0, 0x0c, 0xf1, 0xe6, 0x5a, 0x08, 0xb7, 0x02, 0x7f, 0xff, 0x0e, 0xff, 0xca, 0xb1, 0x38, + 0xf2, 0xe4, 0x6b, 0x05, 0x79, 0x19, 0xce, 0x26, 0xe2, 0x93, 0x44, 0x0e, 0xef, 0xe6, 0x06, 0x2d, + 0x8a, 0x47, 0xb3, 0xba, 0x06, 0x2b, 0x62, 0x56, 0x8c, 0x43, 0x3f, 0x38, 0xb3, 0xc4, 0x61, 0x74, + 0xd5, 0xf1, 0xcf, 0x4d, 0x45, 0xa3, 0x32, 0x6f, 0x24, 0x27, 0x90, 0xa5, 0xc9, 0x4b, 0x40, 0x42, + 0xb9, 0x3d, 0xdc, 0x28, 0xf8, 0x07, 0x37, 0x44, 0x49, 0xb8, 0xc2, 0xf9, 0x67, 0xff, 0x32, 0x07, + 0x67, 0x33, 0xae, 0x32, 0xf4, 0x12, 0xe0, 0x0d, 0x27, 0xee, 0x21, 0xbb, 0x42, 0xc8, 0x8d, 0x5c, + 0x97, 0xe0, 0x5c, 0x3f, 0xb5, 0xc8, 0x32, 0xa0, 0xf3, 0x6f, 0xf1, 0x5f, 0x74, 0xf3, 0x70, 0xc6, + 0x42, 0xf5, 0x42, 0xff, 0x25, 0x35, 0xd8, 0xc0, 0xb4, 0x0e, 0x81, 0xe7, 0x63, 0x76, 0x08, 0x14, + 0x42, 0x0a, 0xb1, 0xcb, 0x0e, 0xd6, 0xa2, 0x2d, 0x21, 0x51, 0x29, 0xc4, 0x54, 0x47, 0x09, 0x08, + 0xf9, 0x04, 0x5c, 0x94, 0xce, 0x1a, 0x3b, 0xb1, 0xf2, 0xd0, 0xd2, 0xdd, 0xdc, 0x74, 0xc2, 0x53, + 0x67, 0x27, 0xb6, 0x06, 0xb7, 0xe1, 0x0a, 0x0e, 0xa2, 0xd7, 0x1f, 0xd9, 0xa9, 0x3c, 0x20, 0xd8, + 0x54, 0x16, 0x38, 0xff, 0x22, 0xc5, 0xaa, 0xf5, 0x47, 0x89, 0x94, 0x20, 0xb4, 0xd5, 0xbc, 0xfb, + 0x1e, 0xc2, 0xf9, 0xcc, 0x1a, 0xd3, 0x03, 0x06, 0x0d, 0xa9, 0x22, 0xd9, 0x68, 0x89, 0xfe, 0xa6, + 0xc2, 0xd1, 0x35, 0x58, 0x79, 0xe4, 0x3a, 0x63, 0x77, 0xcc, 0x4f, 0x6e, 0x3e, 0x25, 0x18, 0x4c, + 0x3e, 0xb8, 0xfb, 0xf1, 0xa1, 0xe1, 0x3a, 0x23, 0xd2, 0x80, 0xb3, 0xec, 0x04, 0xf4, 0x8e, 0x51, + 0x18, 0xe4, 0x7a, 0x26, 0x25, 0x26, 0x0e, 0x21, 0x09, 0x1e, 0x4d, 0x35, 0xc4, 0x62, 0xd4, 0xe6, + 0xc6, 0x61, 0x12, 0x44, 0x57, 0xf4, 0x85, 0x6c, 0x6c, 0xb2, 0x0d, 0x25, 0xc6, 0x9c, 0x5d, 0x0b, + 0xd8, 0x03, 0xc1, 0xb5, 0xb9, 0x5f, 0xa8, 0xa0, 0x7d, 0x71, 0x10, 0xfe, 0x4f, 0xcf, 0x6b, 0x7c, + 0x8b, 0xb5, 0x8f, 0xe5, 0xf7, 0x0f, 0x73, 0x05, 0x81, 0xfc, 0xdd, 0x43, 0xfb, 0x2b, 0x45, 0x34, + 0x35, 0x76, 0x39, 0xa6, 0x53, 0x2b, 0x70, 0x87, 0xe2, 0x0d, 0x68, 0xd9, 0xe4, 0xbf, 0x4e, 0x39, + 0xd5, 0xc9, 0x6b, 0xb0, 0x42, 0xd9, 0x1e, 0x4e, 0x87, 0x6c, 0xca, 0xe5, 0x63, 0x71, 0x79, 0x1a, + 0xac, 0x88, 0x0e, 0x5b, 0xf5, 0x8c, 0x59, 0x3a, 0x8e, 0x7e, 0x52, 0x69, 0x39, 0x38, 0x9e, 0x8c, + 0xe4, 0x89, 0x2a, 0x14, 0x85, 0x56, 0xa3, 0xd3, 0xe6, 0x24, 0x45, 0x8a, 0x13, 0x49, 0xcb, 0xdb, + 0x8b, 0x4c, 0x55, 0xa8, 0xbd, 0x08, 0x25, 0x89, 0x37, 0x6d, 0x0c, 0xf3, 0x9c, 0x11, 0x8d, 0x61, + 0xbf, 0xf8, 0x60, 0x3f, 0x82, 0xa2, 0x60, 0x49, 0xaf, 0x05, 0x47, 0x7e, 0x20, 0x16, 0x39, 0xfe, + 0x4f, 0x61, 0xb4, 0x97, 0xb1, 0x91, 0x0b, 0x26, 0xfe, 0x8f, 0x67, 0xc9, 0xc4, 0xa1, 0xf7, 0x81, + 0x41, 0x60, 0x8f, 0xd0, 0x02, 0x2b, 0x14, 0x9e, 0x29, 0xbc, 0x33, 0x08, 0x98, 0x5d, 0x16, 0xff, + 0xc6, 0x9f, 0x87, 0x87, 0x70, 0x42, 0x9b, 0x30, 0x6b, 0xcf, 0x8c, 0x1d, 0x19, 0xb9, 0xf4, 0x91, + 0xc1, 0xe2, 0xad, 0x70, 0x4a, 0xf6, 0x65, 0x40, 0x18, 0x1e, 0x19, 0xd2, 0xce, 0x50, 0x88, 0xed, + 0x0c, 0xd2, 0x9d, 0x3c, 0x1a, 0x3d, 0x76, 0xe2, 0x88, 0x3b, 0x79, 0x72, 0x9f, 0xfa, 0xe3, 0x9c, + 0x50, 0x11, 0x6c, 0xfb, 0xfe, 0x24, 0x98, 0x8c, 0x9d, 0x51, 0x4c, 0x15, 0x4a, 0x8e, 0xe1, 0x19, + 0x94, 0xa0, 0xef, 0x60, 0x0a, 0x0d, 0x7f, 0x2c, 0x42, 0x7c, 0x84, 0x33, 0xb7, 0x74, 0xe7, 0x23, + 0x71, 0x19, 0x5f, 0xa7, 0xd8, 0xba, 0x8c, 0x4c, 0x27, 0xac, 0xc4, 0xb5, 0x7a, 0xc6, 0xdc, 0x64, + 0x3c, 0x53, 0x58, 0xa4, 0x9a, 0xb1, 0x88, 0x93, 0xba, 0xd0, 0xed, 0x68, 0x45, 0xc7, 0xb9, 0xca, + 0x6b, 0x9d, 0x7c, 0x0a, 0x96, 0xbd, 0xbe, 0x9c, 0x29, 0x32, 0xa9, 0x85, 0xab, 0xf5, 0x59, 0xb4, + 0xea, 0x88, 0x07, 0x9d, 0x73, 0x1e, 0x87, 0x6e, 0xaf, 0xc6, 0x94, 0xc6, 0xda, 0xb6, 0xb8, 0x8d, + 0xa6, 0xc9, 0xc8, 0x1a, 0xe4, 0xc2, 0x11, 0xce, 0x79, 0x7d, 0xb6, 0xbc, 0xa2, 0x78, 0xd9, 0x26, + 0xff, 0xa5, 0xfd, 0x6f, 0xb8, 0x79, 0xd2, 0x3e, 0xa2, 0x4b, 0x71, 0x46, 0x87, 0x2f, 0xb3, 0x50, + 0x95, 0xf1, 0x7e, 0xbb, 0x06, 0x72, 0xb8, 0x5f, 0x4f, 0x6c, 0x7e, 0x02, 0xd6, 0x1d, 0x7b, 0xda, + 0x9f, 0xe5, 0x61, 0x2d, 0xae, 0x26, 0x27, 0x2f, 0x42, 0x41, 0xda, 0x81, 0x36, 0x33, 0x74, 0xe9, + 0xb8, 0xef, 0x20, 0xd2, 0x89, 0x76, 0x1c, 0x72, 0x17, 0xd6, 0xd0, 0x70, 0x0f, 0x45, 0xcf, 0x89, + 0xc7, 0x1f, 0x5f, 0xe6, 0xbf, 0x9f, 0x15, 0x7f, 0xf4, 0xee, 0xd5, 0x33, 0xf8, 0x54, 0xb6, 0x42, + 0x69, 0xa9, 0xf4, 0x47, 0x0b, 0x25, 0x2d, 0x68, 0x61, 0xb6, 0x16, 0x94, 0x37, 0x65, 0x86, 0x16, + 0x74, 0x61, 0x8e, 0x16, 0x34, 0xa2, 0x94, 0xb5, 0xa0, 0xa8, 0x0b, 0x5f, 0x9a, 0xa5, 0x0b, 0x8f, + 0x68, 0x98, 0x2e, 0x3c, 0xd2, 0x62, 0x16, 0x67, 0x6a, 0x31, 0x23, 0x1a, 0xae, 0xc5, 0xbc, 0xce, + 0xfb, 0x68, 0xec, 0x3c, 0xb6, 0xb1, 0xf3, 0xf8, 0xb1, 0x88, 0xad, 0x37, 0x9d, 0xc7, 0x68, 0x5c, + 0xb3, 0xbd, 0x0c, 0xc2, 0x22, 0x47, 0xfb, 0x5d, 0x25, 0xa1, 0x09, 0x14, 0xe3, 0xf7, 0x02, 0xac, + 0xb1, 0xc3, 0x8a, 0x87, 0x33, 0x65, 0xa7, 0xd5, 0xaa, 0xb9, 0x2a, 0xa0, 0xec, 0xbe, 0xf9, 0x21, + 0x58, 0x0f, 0xd1, 0xf8, 0x95, 0x0b, 0x3d, 0xf5, 0xcc, 0x90, 0x9a, 0x87, 0x9d, 0x79, 0x11, 0x36, + 0x42, 0x44, 0xae, 0xcd, 0x61, 0xd7, 0xcd, 0x55, 0x53, 0x15, 0x05, 0x6d, 0x0e, 0xd7, 0x0e, 0x93, + 0x37, 0x8f, 0x5f, 0x52, 0xad, 0xb4, 0x1f, 0xe6, 0x63, 0x5a, 0x12, 0xf1, 0x19, 0x7a, 0x8a, 0x06, + 0xbe, 0xcd, 0x3b, 0x89, 0xef, 0x45, 0xd7, 0x66, 0x8c, 0x19, 0xb7, 0x69, 0xb2, 0xac, 0x96, 0x09, + 0x41, 0xe0, 0x0b, 0x13, 0x27, 0x9b, 0x49, 0xd4, 0xec, 0xdc, 0xc7, 0x39, 0x2b, 0xd8, 0xb1, 0x8d, + 0xa7, 0x3c, 0x9f, 0x9d, 0xb8, 0xa6, 0xd2, 0x29, 0x8b, 0x92, 0x75, 0xf8, 0x4b, 0x7c, 0xa0, 0x0b, + 0xa8, 0x54, 0x0c, 0xe2, 0xcc, 0xf3, 0x19, 0x77, 0xa7, 0x14, 0x73, 0xec, 0x25, 0xe4, 0xac, 0x4e, + 0xc5, 0xbf, 0x82, 0xad, 0x01, 0x2b, 0xa8, 0xa3, 0x10, 0x0c, 0x0b, 0x19, 0x2a, 0xf8, 0x74, 0xe3, + 0x2b, 0xb5, 0x86, 0x59, 0xa2, 0x74, 0x82, 0xcd, 0x11, 0x3c, 0x23, 0x6b, 0x16, 0xe2, 0x95, 0x5c, + 0x10, 0x51, 0x7c, 0xe7, 0xf6, 0x40, 0xa4, 0x80, 0xc0, 0xaa, 0x5e, 0x70, 0xe2, 0x00, 0x8e, 0xa6, + 0x1d, 0xc1, 0xc5, 0xd9, 0x43, 0x32, 0x27, 0x43, 0x54, 0x74, 0x80, 0xe6, 0xe4, 0x03, 0x54, 0xd6, + 0x33, 0xe4, 0x63, 0x7a, 0x06, 0xed, 0x8f, 0xf2, 0xf0, 0xfc, 0x09, 0x86, 0x6b, 0xce, 0x37, 0x3f, + 0x1d, 0x17, 0xcf, 0x72, 0xb1, 0x9b, 0x21, 0x65, 0xca, 0x37, 0x48, 0x7a, 0x4b, 0xcd, 0x16, 0xce, + 0xbe, 0x04, 0xeb, 0x6c, 0x17, 0x64, 0x66, 0x89, 0x07, 0xd3, 0xc1, 0x09, 0xb6, 0xc1, 0x4b, 0xc2, + 0x87, 0x2a, 0x41, 0x8a, 0x3b, 0x23, 0xee, 0x18, 0x56, 0x08, 0x23, 0x1d, 0x28, 0x21, 0xda, 0x81, + 0xe3, 0x0d, 0x4e, 0xe4, 0xcc, 0x23, 0x3c, 0xb4, 0x64, 0x32, 0x66, 0x4d, 0x4d, 0x01, 0xbb, 0xf8, + 0x9b, 0xdc, 0x80, 0xf5, 0xe1, 0xf4, 0x98, 0x0a, 0x1e, 0x6c, 0x2e, 0x70, 0xeb, 0x8f, 0x05, 0x73, + 0x75, 0x38, 0x3d, 0xd6, 0x47, 0x23, 0x1c, 0x52, 0x34, 0x13, 0xd9, 0xa0, 0x78, 0x6c, 0xd5, 0x0a, + 0xcc, 0x45, 0xc4, 0xa4, 0x0c, 0xd8, 0xba, 0xe5, 0xb8, 0xe7, 0x80, 0x19, 0x0d, 0xf2, 0x0c, 0x59, + 0xec, 0x87, 0xf6, 0xef, 0x39, 0x71, 0xdf, 0x9d, 0x3d, 0xef, 0x7f, 0x3d, 0x44, 0x19, 0x43, 0x74, + 0x13, 0x54, 0xda, 0xf5, 0xd1, 0xa6, 0x12, 0x8e, 0xd1, 0xda, 0x70, 0x7a, 0x1c, 0xf6, 0x9d, 0xdc, + 0xf1, 0x8b, 0x72, 0xc7, 0xbf, 0x26, 0xee, 0xc3, 0x99, 0xdb, 0xc3, 0xec, 0x2e, 0xd7, 0xfe, 0x25, + 0x0f, 0x37, 0x4e, 0xb6, 0x09, 0xfc, 0x7a, 0xdc, 0x32, 0xc6, 0x2d, 0xa1, 0x3a, 0x5d, 0x48, 0xa9, + 0x4e, 0x33, 0xd6, 0xde, 0x62, 0xd6, 0xda, 0x4b, 0x29, 0x6a, 0x97, 0x32, 0x14, 0xb5, 0x99, 0x0b, + 0xb4, 0xf8, 0x94, 0x05, 0xba, 0x2c, 0xcf, 0x93, 0x7f, 0x08, 0x15, 0x18, 0xf1, 0xfb, 0xc0, 0x43, + 0x38, 0x2b, 0xee, 0x03, 0xec, 0xe4, 0x88, 0xf4, 0xef, 0xa5, 0x3b, 0xb7, 0xb2, 0x6e, 0x02, 0x88, + 0x96, 0x21, 0xad, 0x6f, 0xf0, 0x3b, 0x40, 0x54, 0xfe, 0x3f, 0x47, 0xfa, 0x27, 0x0f, 0xe0, 0x02, + 0xc6, 0x97, 0xef, 0xc9, 0x2f, 0x07, 0xf6, 0xd8, 0x3d, 0xe0, 0xf3, 0xe1, 0x5a, 0x4a, 0x56, 0xf6, + 0x7a, 0x52, 0x75, 0x4c, 0xf7, 0xa0, 0x7a, 0xc6, 0x3c, 0x17, 0x64, 0xc0, 0x93, 0x17, 0x8b, 0x3f, + 0x55, 0x40, 0x7b, 0x7a, 0x7f, 0xa1, 0xa2, 0x2a, 0xd9, 0xe1, 0xcb, 0x66, 0xc9, 0x91, 0x7a, 0xef, + 0x79, 0x58, 0x1d, 0xbb, 0x07, 0x63, 0x37, 0x38, 0x8a, 0x69, 0x40, 0x56, 0x38, 0x50, 0x74, 0x8c, + 0x08, 0x4a, 0x79, 0x2a, 0xc9, 0x5c, 0x10, 0x69, 0xbb, 0xe1, 0x7d, 0x31, 0x73, 0x1c, 0xe8, 0x6c, + 0x92, 0x2b, 0xc8, 0x7e, 0xdc, 0x2d, 0x14, 0x73, 0x6a, 0xde, 0xe4, 0xa1, 0x33, 0x0f, 0xbc, 0x81, + 0xab, 0xfd, 0x85, 0x22, 0x24, 0x82, 0xac, 0xce, 0x23, 0x0f, 0x25, 0x63, 0xde, 0x7c, 0x4a, 0x0c, + 0xc9, 0x22, 0x91, 0xed, 0x1e, 0x79, 0x78, 0x46, 0x04, 0xc4, 0xc2, 0x33, 0x22, 0xe4, 0x7d, 0x58, + 0x24, 0xf2, 0x5b, 0xf3, 0x1b, 0xc2, 0x22, 0x88, 0xee, 0x79, 0xfb, 0xb7, 0xc9, 0x2d, 0x58, 0x62, + 0x46, 0x40, 0xa2, 0xba, 0xeb, 0xb1, 0xea, 0xee, 0xdf, 0x36, 0x45, 0xb9, 0xf6, 0x4e, 0xf8, 0xae, + 0x95, 0x6a, 0xc4, 0xfe, 0x6d, 0xf2, 0xda, 0xc9, 0x8c, 0x73, 0x8b, 0xc2, 0x38, 0x37, 0x34, 0xcc, + 0x7d, 0x3d, 0x66, 0x98, 0x7b, 0x7d, 0x7e, 0x6f, 0xf1, 0xd7, 0x48, 0x16, 0x8e, 0x30, 0x0a, 0x53, + 0xf5, 0xb3, 0x1c, 0x3c, 0x3b, 0x97, 0x82, 0x5c, 0x86, 0xa2, 0xde, 0xae, 0x75, 0xa2, 0xf1, 0xa5, + 0x6b, 0x46, 0x40, 0xc8, 0x1e, 0x2c, 0x6f, 0x3b, 0x81, 0xd7, 0xa3, 0xd3, 0x38, 0xf3, 0x79, 0x20, + 0xc5, 0x36, 0x44, 0xaf, 0x9e, 0x31, 0x23, 0x5a, 0x62, 0xc3, 0x06, 0xae, 0x85, 0x58, 0xea, 0xa9, + 0x7c, 0x86, 0xae, 0x21, 0xc5, 0x30, 0x45, 0x46, 0xf7, 0x99, 0x14, 0x90, 0x3c, 0x02, 0x62, 0x59, + 0xd5, 0x8a, 0x3b, 0x9e, 0xf0, 0x3b, 0xf8, 0xc4, 0x0b, 0x2d, 0x3d, 0x3f, 0xfa, 0x94, 0xbe, 0x4b, + 0xd1, 0x55, 0xcf, 0x98, 0x19, 0xdc, 0x92, 0xcb, 0xfc, 0x6d, 0x21, 0xef, 0xcc, 0xee, 0x84, 0x53, + 0x84, 0x7a, 0xbd, 0x09, 0xc5, 0xb6, 0xb0, 0x45, 0x90, 0x2c, 0xe6, 0x85, 0xdd, 0x81, 0x19, 0x96, + 0x6a, 0xbf, 0xa1, 0x08, 0xa5, 0xc3, 0xd3, 0x3b, 0x4b, 0xca, 0x0c, 0xd6, 0x9f, 0x9f, 0x19, 0xac, + 0xff, 0x0b, 0x66, 0x06, 0xd3, 0x3c, 0xb8, 0x75, 0xe2, 0x8e, 0x25, 0x9f, 0x04, 0x15, 0x93, 0x28, + 0x39, 0xd2, 0x20, 0xb1, 0xf5, 0xb5, 0x11, 0xc6, 0xfe, 0xae, 0xf2, 0x4c, 0x75, 0xe6, 0x7a, 0x2f, + 0x4e, 0xad, 0xfd, 0x09, 0x8f, 0xf9, 0x5e, 0xeb, 0xb7, 0x13, 0x8a, 0xe6, 0xf7, 0xeb, 0x64, 0x61, + 0xc4, 0x16, 0xdb, 0xf3, 0x52, 0x12, 0xcb, 0xf4, 0xb7, 0x66, 0xfb, 0x5a, 0x48, 0x2b, 0xef, 0x0f, + 0xf2, 0x70, 0x79, 0x1e, 0x79, 0x66, 0x9a, 0x6c, 0xe5, 0x74, 0x69, 0xb2, 0x6f, 0x41, 0x91, 0xc1, + 0x42, 0x0f, 0x02, 0x1c, 0x5b, 0x4e, 0x4a, 0xc7, 0x56, 0x14, 0x93, 0xe7, 0x61, 0x51, 0xaf, 0x58, + 0x51, 0xe6, 0x36, 0x34, 0xf5, 0x75, 0x7a, 0x01, 0x1a, 0x91, 0xf2, 0x22, 0xf2, 0xc5, 0x74, 0xb2, + 0x42, 0x9e, 0xb2, 0xed, 0x92, 0xd4, 0x21, 0xa9, 0x74, 0x0c, 0x58, 0xdf, 0x28, 0x7d, 0x00, 0x8f, + 0xc8, 0x6d, 0xa6, 0x13, 0x1f, 0x6a, 0xb0, 0xd8, 0x1e, 0xbb, 0x81, 0x3b, 0x91, 0xcd, 0x70, 0x47, + 0x08, 0x31, 0x79, 0x09, 0x37, 0x92, 0x75, 0x9e, 0xb0, 0x98, 0x08, 0x8b, 0x72, 0x9c, 0x1a, 0xb4, + 0xaa, 0xa5, 0x60, 0x53, 0x42, 0xa1, 0x04, 0x75, 0x67, 0x3a, 0xec, 0x1d, 0x75, 0xcd, 0x3a, 0x97, + 0x9c, 0x18, 0xc1, 0x00, 0xa1, 0xb4, 0x81, 0x81, 0x29, 0xa1, 0x68, 0xdf, 0x56, 0xe0, 0x5c, 0x56, + 0x3b, 0xc8, 0x65, 0x28, 0x0c, 0x33, 0xf3, 0x32, 0x0e, 0x99, 0x2b, 0x77, 0x89, 0xfe, 0xb5, 0x0f, + 0xfc, 0xf1, 0xb1, 0x33, 0x91, 0x8d, 0x95, 0x25, 0xb0, 0x09, 0xf4, 0xc7, 0x2e, 0xfe, 0x4f, 0xae, + 0x8a, 0x23, 0x27, 0x9f, 0xca, 0xe4, 0x88, 0x7f, 0x34, 0x1d, 0xa0, 0xd6, 0x6f, 0xb7, 0x46, 0x2c, + 0x1d, 0xc0, 0x2b, 0x50, 0xa0, 0xd5, 0x4a, 0xcc, 0x5e, 0x3a, 0x7f, 0xf4, 0x46, 0x9d, 0x23, 0xb1, + 0x5a, 0x05, 0xce, 0xf1, 0xc0, 0x44, 0x64, 0xed, 0x3e, 0xac, 0xc5, 0x31, 0x88, 0x11, 0x8f, 0x08, + 0x5b, 0xba, 0xa3, 0x72, 0x4e, 0xdb, 0xbe, 0xcf, 0x1c, 0x66, 0xb6, 0x9f, 0xf9, 0xd9, 0xbb, 0x57, + 0x81, 0xfe, 0x64, 0x34, 0x59, 0x11, 0x63, 0xb5, 0xef, 0xe4, 0xe0, 0x5c, 0xe4, 0xa3, 0x2f, 0xd6, + 0xd0, 0xaf, 0xac, 0xc3, 0xa8, 0x1e, 0x73, 0x68, 0x14, 0x72, 0x63, 0xba, 0x81, 0x73, 0xfc, 0xa8, + 0xf6, 0x60, 0x6b, 0x16, 0x3e, 0x79, 0x11, 0x96, 0x31, 0xac, 0xd3, 0xc8, 0xe9, 0xb9, 0xf2, 0x36, + 0x3b, 0x14, 0x40, 0x33, 0x2a, 0xd7, 0x7e, 0xa2, 0xc0, 0x45, 0xee, 0xe6, 0xd1, 0x70, 0xbc, 0x21, + 0xbe, 0x12, 0xf4, 0xdc, 0x0f, 0xc6, 0xe1, 0x79, 0x2f, 0xb6, 0x8f, 0xbd, 0x10, 0xf7, 0xe6, 0x49, + 0x7d, 0x6d, 0x76, 0x6b, 0xc9, 0x2d, 0x0c, 0x55, 0xc6, 0x5f, 0xd1, 0x0b, 0x2c, 0xc0, 0xc4, 0x90, + 0x02, 0xe4, 0x00, 0x13, 0x88, 0xa1, 0xfd, 0x1f, 0xb8, 0x32, 0xff, 0x03, 0xe4, 0x0b, 0xb0, 0x8a, + 0xb9, 0xb7, 0xba, 0xa3, 0xc3, 0xb1, 0xd3, 0x77, 0x85, 0x66, 0x4f, 0x68, 0x63, 0xe5, 0x32, 0x16, + 0x79, 0x8d, 0x07, 0x3c, 0x38, 0xc4, 0xac, 0x5e, 0x9c, 0x28, 0xe6, 0x4b, 0x25, 0x73, 0xd3, 0xbe, + 0xa1, 0x00, 0x49, 0xf3, 0x20, 0x1f, 0x83, 0x95, 0x6e, 0xa7, 0x62, 0x4d, 0x9c, 0xf1, 0xa4, 0xea, + 0x4f, 0xc7, 0x3c, 0xec, 0x19, 0xf3, 0x7f, 0x9f, 0xf4, 0x6c, 0xf6, 0x1e, 0x74, 0xe4, 0x4f, 0xc7, + 0x66, 0x0c, 0x0f, 0x73, 0x3c, 0xb9, 0xee, 0x57, 0xfa, 0xce, 0x93, 0x78, 0x8e, 0x27, 0x0e, 0x8b, + 0xe5, 0x78, 0xe2, 0x30, 0xed, 0xfb, 0x0a, 0x5c, 0x12, 0xc6, 0x91, 0xfd, 0x8c, 0xba, 0x54, 0x30, + 0xca, 0xcb, 0x58, 0xc4, 0xd9, 0x9d, 0x27, 0xa1, 0x6f, 0x88, 0x40, 0x48, 0x58, 0x41, 0x14, 0xd5, + 0x19, 0x2d, 0xf9, 0x34, 0x14, 0xac, 0x89, 0x3f, 0x3a, 0x41, 0x24, 0x24, 0x35, 0x1c, 0xd1, 0x89, + 0x3f, 0x42, 0x16, 0x48, 0xa9, 0xb9, 0x70, 0x4e, 0xae, 0x9c, 0xa8, 0x31, 0x69, 0xc0, 0x12, 0x0f, + 0x79, 0x97, 0xb0, 0x3b, 0x98, 0xd3, 0xa6, 0xed, 0x75, 0x11, 0x6e, 0x89, 0xc7, 0x79, 0x35, 0x05, + 0x0f, 0xed, 0xb7, 0x14, 0x28, 0x51, 0xc1, 0x06, 0x2f, 0xa5, 0xef, 0x77, 0x4a, 0xc7, 0xe5, 0x60, + 0x61, 0x46, 0x13, 0xb2, 0x3f, 0xd1, 0x69, 0xfc, 0x2a, 0xac, 0x27, 0x08, 0x88, 0x86, 0x81, 0x36, + 0x06, 0x5e, 0xcf, 0x61, 0x29, 0x63, 0x98, 0x09, 0x4a, 0x0c, 0xa6, 0xfd, 0x3f, 0x05, 0xce, 0xb5, + 0xbe, 0x32, 0x71, 0xd8, 0xb3, 0xad, 0x39, 0x1d, 0x88, 0xf5, 0x4e, 0x85, 0x35, 0x61, 0x65, 0xcb, + 0x82, 0x00, 0x30, 0x61, 0x8d, 0xc3, 0xcc, 0xb0, 0x94, 0x54, 0xa1, 0xc8, 0xcf, 0x97, 0x80, 0x87, + 0x67, 0xbd, 0x22, 0xe9, 0x46, 0x22, 0xc6, 0x1c, 0x89, 0xb6, 0x04, 0xb7, 0x30, 0x4e, 0x63, 0x86, + 0xd4, 0xda, 0xbf, 0x2a, 0xb0, 0x39, 0x83, 0x86, 0xbc, 0x09, 0x0b, 0xe8, 0xa0, 0xc8, 0x47, 0xef, + 0xf2, 0x8c, 0x4f, 0x4c, 0x7a, 0x47, 0xfb, 0xb7, 0xd9, 0x41, 0x74, 0x4c, 0x7f, 0x98, 0x8c, 0x8a, + 0x3c, 0x84, 0x65, 0xbd, 0xdf, 0xe7, 0xb7, 0xb3, 0x5c, 0xec, 0x76, 0x36, 0xe3, 0x8b, 0x2f, 0x87, + 0xf8, 0xec, 0x76, 0xc6, 0x5c, 0x65, 0xfa, 0x7d, 0x9b, 0x3b, 0x5f, 0x46, 0xfc, 0x2e, 0x7e, 0x12, + 0xd6, 0xe2, 0xc8, 0xa7, 0xf2, 0x17, 0x7b, 0x47, 0x01, 0x35, 0x5e, 0x87, 0x5f, 0x4e, 0xa0, 0xa8, + 0xac, 0x61, 0x7e, 0xca, 0xa4, 0xfa, 0x9d, 0x1c, 0x9c, 0xcf, 0xec, 0x61, 0xf2, 0x12, 0x2c, 0xea, + 0xa3, 0x51, 0x6d, 0x87, 0xcf, 0x2a, 0x2e, 0x21, 0xa1, 0xd2, 0x3b, 0x76, 0x79, 0x65, 0x48, 0xe4, + 0x15, 0x28, 0x32, 0xeb, 0x80, 0x1d, 0xb1, 0xe1, 0x60, 0xe4, 0x1b, 0x6e, 0xba, 0x10, 0x0f, 0x94, + 0x2a, 0x10, 0xc9, 0x2e, 0xac, 0xf1, 0x98, 0x31, 0xa6, 0x7b, 0xe8, 0x7e, 0x2d, 0x8c, 0xd8, 0x8f, + 0x49, 0x05, 0x84, 0x26, 0xdd, 0x1e, 0xb3, 0x32, 0x39, 0x6a, 0x4a, 0x9c, 0x8a, 0xd4, 0x41, 0x45, + 0x9e, 0x32, 0x27, 0x16, 0xad, 0x15, 0xa3, 0xf8, 0xb0, 0x4a, 0xcc, 0xe0, 0x95, 0xa2, 0x0c, 0x87, + 0x4b, 0x0f, 0x02, 0xef, 0x70, 0x78, 0xec, 0x0e, 0x27, 0xbf, 0xbc, 0xe1, 0x8a, 0xbe, 0x71, 0xa2, + 0xe1, 0xfa, 0xbd, 0x02, 0x5b, 0xcc, 0x49, 0x32, 0x2a, 0xd1, 0x48, 0x01, 0xba, 0x51, 0xa2, 0xa1, + 0xf7, 0x33, 0x1e, 0x15, 0x65, 0x07, 0x96, 0x58, 0xb4, 0x1a, 0xb1, 0x32, 0x9e, 0xcd, 0xac, 0x02, + 0xc3, 0xd9, 0xbf, 0xcd, 0xc4, 0x17, 0xe6, 0x29, 0x19, 0x98, 0x82, 0x94, 0xec, 0x43, 0xa9, 0x32, + 0x70, 0x9d, 0xe1, 0x74, 0xd4, 0x39, 0xd9, 0x0b, 0xea, 0x16, 0x6f, 0xcb, 0x4a, 0x8f, 0x91, 0xe1, + 0xcb, 0x2b, 0xee, 0xe4, 0x32, 0x23, 0xd2, 0x09, 0x9d, 0xa7, 0x0a, 0xa8, 0x78, 0xfd, 0xe8, 0x9c, + 0xfe, 0x49, 0x02, 0x91, 0x2e, 0xee, 0x19, 0xc8, 0xbd, 0xab, 0x6c, 0x58, 0xab, 0x3b, 0xc1, 0xa4, + 0x33, 0x76, 0x86, 0x01, 0x46, 0xb9, 0x3c, 0x41, 0x14, 0xb0, 0x4b, 0x22, 0x83, 0x33, 0xaa, 0x4c, + 0x27, 0x21, 0x29, 0x53, 0xc8, 0xc6, 0xd9, 0x51, 0x79, 0x69, 0xd7, 0x1b, 0x3a, 0x03, 0xef, 0xeb, + 0xc2, 0xc7, 0x94, 0xc9, 0x4b, 0x07, 0x02, 0x68, 0x46, 0xe5, 0xda, 0xe7, 0x53, 0xe3, 0xc6, 0x6a, + 0x59, 0x82, 0x25, 0x1e, 0x81, 0x80, 0x79, 0xe4, 0xb7, 0x8d, 0xe6, 0x4e, 0xad, 0xb9, 0xa7, 0x2a, + 0x64, 0x0d, 0xa0, 0x6d, 0xb6, 0x2a, 0x86, 0x65, 0xd1, 0xdf, 0x39, 0xfa, 0x9b, 0xbb, 0xeb, 0xef, + 0x76, 0xeb, 0x6a, 0x5e, 0xf2, 0xd8, 0x2f, 0x68, 0x3f, 0x56, 0xe0, 0x42, 0xf6, 0x50, 0x92, 0x0e, + 0x60, 0xcc, 0x06, 0xfe, 0x96, 0xfe, 0xb1, 0xb9, 0xe3, 0x9e, 0x09, 0x4e, 0xc6, 0x7e, 0x98, 0xb0, + 0x98, 0x02, 0x39, 0xf1, 0xf6, 0xc5, 0x9c, 0x14, 0xbd, 0xbe, 0x99, 0xf3, 0xfa, 0x5a, 0x05, 0xb6, + 0x66, 0xf1, 0x88, 0x37, 0x75, 0x1d, 0x4a, 0x7a, 0xbb, 0x5d, 0xaf, 0x55, 0xf4, 0x4e, 0xad, 0xd5, + 0x54, 0x15, 0xb2, 0x0c, 0x0b, 0x7b, 0x66, 0xab, 0xdb, 0x56, 0x73, 0xda, 0x77, 0x15, 0x58, 0xad, + 0x45, 0x56, 0x67, 0xef, 0x77, 0xf1, 0x7d, 0x3c, 0xb6, 0xf8, 0xb6, 0xc2, 0xe8, 0x26, 0xe1, 0x07, + 0x4e, 0xb4, 0xf2, 0xde, 0xcb, 0xc1, 0x46, 0x8a, 0x86, 0x58, 0xb0, 0xa4, 0xdf, 0xb7, 0x5a, 0xb5, + 0x9d, 0x0a, 0xaf, 0xd9, 0xd5, 0xc8, 0x5c, 0x0a, 0xf3, 0x5d, 0xa5, 0xbe, 0xc2, 0x3c, 0x82, 0x1f, + 0x07, 0xb6, 0xef, 0xf5, 0xa5, 0xe4, 0xb7, 0xd5, 0x33, 0xa6, 0xe0, 0x84, 0x27, 0xd9, 0xd7, 0xa7, + 0x63, 0x17, 0xd9, 0xe6, 0x62, 0x7a, 0xdd, 0x10, 0x9e, 0x66, 0x8c, 0xfe, 0x1b, 0x0e, 0x2d, 0x4f, + 0xb3, 0x8e, 0xf8, 0x91, 0x26, 0x2c, 0xee, 0x79, 0x93, 0xea, 0xf4, 0x11, 0x5f, 0xbf, 0x57, 0xa2, + 0xec, 0x47, 0xd5, 0xe9, 0xa3, 0x34, 0x5b, 0x54, 0x59, 0xb2, 0xe8, 0x3d, 0x31, 0x96, 0x9c, 0x4b, + 0xd2, 0x89, 0xb1, 0x70, 0x2a, 0x27, 0xc6, 0xed, 0x55, 0x28, 0xf1, 0x3b, 0x14, 0x5e, 0x4f, 0x7e, + 0xa8, 0xc0, 0xd6, 0xac, 0x9e, 0xa3, 0xd7, 0xb2, 0x78, 0xb0, 0x82, 0x0b, 0x61, 0x7a, 0x8c, 0x78, + 0x94, 0x02, 0x81, 0x46, 0xde, 0x82, 0x52, 0x2d, 0x08, 0xa6, 0xee, 0xd8, 0x7a, 0xa5, 0x6b, 0xd6, + 0xf8, 0x74, 0x7d, 0xf6, 0x9f, 0xde, 0xbd, 0xba, 0x89, 0x3e, 0x1f, 0x63, 0x3b, 0x78, 0xc5, 0x9e, + 0x8e, 0xbd, 0x58, 0x2a, 0x01, 0x99, 0x82, 0x4a, 0xd1, 0xce, 0xb4, 0xef, 0xb9, 0xe2, 0x0e, 0x21, + 0x1c, 0xba, 0x39, 0x4c, 0x3e, 0xd3, 0x04, 0x4c, 0xfb, 0x96, 0x02, 0x17, 0x67, 0x0f, 0x13, 0x3d, + 0x27, 0x3b, 0xcc, 0xa4, 0x4a, 0xb8, 0x54, 0xe3, 0x39, 0x19, 0xda, 0x5d, 0xc9, 0x3c, 0x05, 0x22, + 0x25, 0x0a, 0x53, 0xe3, 0xe7, 0x52, 0xf9, 0xb0, 0xe3, 0x44, 0x02, 0x51, 0x7b, 0x00, 0x9b, 0x33, + 0x06, 0x95, 0x7c, 0x2a, 0x33, 0xe9, 0x0e, 0xba, 0x29, 0xc9, 0x49, 0x77, 0x62, 0xd9, 0xdb, 0x24, + 0xb8, 0xf6, 0xcf, 0x39, 0xb8, 0x40, 0x57, 0xd7, 0xc0, 0x0d, 0x02, 0x3d, 0xca, 0x4f, 0x4b, 0x77, + 0xc5, 0xd7, 0x60, 0xf1, 0xe8, 0x74, 0xaa, 0x62, 0x86, 0x4e, 0x08, 0xe0, 0x89, 0x25, 0x9c, 0x63, + 0xe8, 0xff, 0xe4, 0x1a, 0xc8, 0xc9, 0xcd, 0xf3, 0x18, 0xde, 0x34, 0xb7, 0xa5, 0x98, 0xcb, 0xa3, + 0x30, 0x0f, 0xf1, 0xeb, 0xb0, 0x80, 0xfa, 0x14, 0x7e, 0x76, 0x08, 0x99, 0x3f, 0xbb, 0x76, 0xa8, + 0x6d, 0x31, 0x19, 0x01, 0xf9, 0x08, 0x40, 0x94, 0x19, 0x82, 0x1f, 0x0e, 0x42, 0xcf, 0x10, 0x26, + 0x87, 0x30, 0x97, 0x8f, 0x0f, 0x1c, 0x9e, 0x6e, 0xa1, 0x0c, 0x1b, 0xa2, 0xc7, 0x47, 0x22, 0x2a, + 0x22, 0x7f, 0xc5, 0x5c, 0x67, 0x05, 0xb5, 0x91, 0x88, 0x8c, 0x78, 0x3d, 0x95, 0xa0, 0x19, 0x83, + 0x23, 0x27, 0xb2, 0x30, 0x5f, 0x4f, 0x65, 0x61, 0x2e, 0x32, 0x2c, 0x39, 0xd5, 0xb2, 0xf6, 0xf7, + 0x39, 0x58, 0xbe, 0x4f, 0xa5, 0x32, 0xd4, 0x35, 0xcc, 0xd7, 0x5d, 0xdc, 0x81, 0x52, 0xdd, 0x77, + 0xf8, 0x73, 0x11, 0xf7, 0x29, 0x61, 0x3e, 0xdd, 0x03, 0xdf, 0x11, 0x2f, 0x4f, 0x81, 0x29, 0x23, + 0x3d, 0xc5, 0x1f, 0xfd, 0x2e, 0x2c, 0xb2, 0xe7, 0x3b, 0xae, 0x46, 0x13, 0x72, 0x79, 0x58, 0xa3, + 0x97, 0x59, 0xb1, 0xf4, 0xc2, 0xc1, 0x9e, 0x00, 0x65, 0x21, 0x91, 0xc7, 0x78, 0x95, 0x34, 0x2b, + 0x0b, 0x27, 0xd3, 0xac, 0x48, 0xb1, 0xec, 0x16, 0x4f, 0x12, 0xcb, 0xee, 0xe2, 0x1b, 0x50, 0x92, + 0xea, 0x73, 0x2a, 0x31, 0xfd, 0x9b, 0x39, 0x58, 0xc5, 0x56, 0x85, 0xb6, 0x3c, 0xbf, 0x9a, 0x7a, + 0xa2, 0x8f, 0xc7, 0xf4, 0x44, 0x5b, 0xf2, 0x78, 0xb1, 0x96, 0xcd, 0x51, 0x10, 0xdd, 0x85, 0x8d, + 0x14, 0x22, 0x79, 0x15, 0x16, 0x68, 0xf5, 0xc5, 0xbd, 0x5a, 0x4d, 0xce, 0x80, 0x28, 0xee, 0x31, + 0x6d, 0x78, 0x60, 0x32, 0x6c, 0xed, 0xdf, 0x14, 0x58, 0xe1, 0x69, 0x47, 0x86, 0x07, 0xfe, 0x53, + 0xbb, 0xf3, 0x46, 0xb2, 0x3b, 0x59, 0x74, 0x15, 0xde, 0x9d, 0xff, 0xd5, 0x9d, 0xf8, 0x46, 0xac, + 0x13, 0x37, 0xc3, 0x28, 0x88, 0xa2, 0x39, 0x73, 0xfa, 0xf0, 0x07, 0x18, 0x17, 0x38, 0x8e, 0x48, + 0xbe, 0x08, 0xcb, 0x4d, 0xf7, 0x71, 0xec, 0x7a, 0x7a, 0x63, 0x06, 0xd3, 0x97, 0x43, 0x44, 0xb6, + 0xa6, 0xf0, 0x64, 0x1f, 0xba, 0x8f, 0xed, 0xd4, 0xcb, 0x61, 0xc4, 0x92, 0xde, 0x50, 0xe3, 0x64, + 0xa7, 0x99, 0xfa, 0xdc, 0xc1, 0x15, 0x03, 0x06, 0x7d, 0x3b, 0x0f, 0x10, 0xf9, 0x06, 0xd2, 0x05, + 0x18, 0x33, 0x9a, 0x10, 0x9a, 0x7d, 0x04, 0xc9, 0x73, 0x5c, 0xd8, 0x52, 0xdc, 0xe0, 0x1a, 0xe8, + 0xdc, 0xec, 0x28, 0x95, 0xa8, 0x8b, 0xae, 0x70, 0x67, 0xb4, 0xbe, 0x3b, 0x70, 0xd8, 0xde, 0x9e, + 0xdf, 0xbe, 0x8e, 0x41, 0x89, 0x43, 0xe8, 0x8c, 0x74, 0xd3, 0xe8, 0xb2, 0xb6, 0x43, 0x11, 0x52, + 0xfe, 0xb6, 0x85, 0xd3, 0xf9, 0xdb, 0xb6, 0x61, 0xd9, 0x1b, 0xbe, 0xed, 0x0e, 0x27, 0xfe, 0xf8, + 0x09, 0xaa, 0xdd, 0x23, 0x7d, 0x1e, 0xed, 0x82, 0x9a, 0x28, 0x63, 0xe3, 0x80, 0x67, 0x6e, 0x88, + 0x2f, 0x0f, 0x43, 0x08, 0x0c, 0xfd, 0x85, 0x17, 0xd4, 0xc5, 0xbb, 0x85, 0xe2, 0xa2, 0xba, 0x74, + 0xb7, 0x50, 0x2c, 0xaa, 0xcb, 0x77, 0x0b, 0xc5, 0x65, 0x15, 0x4c, 0xe9, 0xcd, 0x2c, 0x7c, 0x13, 0x93, 0x9e, 0xb1, 0xe2, 0x4f, 0x54, 0xda, 0xcf, 0x73, 0x40, 0xd2, 0xd5, 0x20, 0x1f, 0x87, 0x12, 0xdb, 0x60, 0xed, 0x71, 0xf0, 0x55, 0xee, 0x6e, 0xc0, 0xc2, 0x2e, 0x49, 0x60, 0x39, 0xec, 0x12, 0x03, 0x9b, 0xc1, 0x57, 0x07, 0xe4, 0x0b, 0x70, 0x16, 0xbb, 0x77, 0xe4, 0x8e, 0x3d, 0xbf, 0x6f, 0x63, 0x8c, 0x5c, 0x67, 0xc0, 0x53, 0x43, 0xbe, 0x84, 0x39, 0x8c, 0xd3, 0xc5, 0x33, 0x86, 0x01, - 0x5d, 0x00, 0xdb, 0x88, 0xd9, 0x66, 0x88, 0xa4, 0x03, 0xaa, 0x4c, 0x7f, 0x38, 0x1d, 0x0c, 0xf8, - 0xc8, 0x96, 0xe9, 0x8d, 0x3e, 0x59, 0x36, 0x83, 0xf1, 0x5a, 0xc4, 0x78, 0x6f, 0x3a, 0x18, 0x90, - 0xd7, 0x00, 0xfc, 0xa1, 0x7d, 0xe2, 0x05, 0x01, 0x7b, 0xcc, 0x09, 0xbd, 0x95, 0x23, 0xa8, 0x3c, + 0x5d, 0x00, 0xdb, 0x88, 0xd9, 0x66, 0x88, 0xa4, 0x03, 0xaa, 0x4c, 0x7f, 0x30, 0x1d, 0x0c, 0xf8, + 0xc8, 0x96, 0xe9, 0x8d, 0x3e, 0x59, 0x36, 0x83, 0xf1, 0x5a, 0xc4, 0x78, 0x77, 0x3a, 0x18, 0x90, + 0xd7, 0x00, 0xfc, 0xa1, 0x7d, 0xec, 0x05, 0x01, 0x7b, 0xcc, 0x09, 0xbd, 0x95, 0x23, 0xa8, 0x3c, 0x18, 0xfe, 0xb0, 0xc1, 0x80, 0xe4, 0x7f, 0x01, 0x46, 0x6b, 0xc0, 0x30, 0x26, 0xcc, 0x1a, 0x89, - 0x67, 0x6f, 0x11, 0xc0, 0xb8, 0x73, 0xf4, 0x91, 0x6b, 0x79, 0x5f, 0x17, 0xae, 0x1e, 0x9f, 0x83, - 0x0d, 0x6e, 0x3c, 0x7c, 0xcf, 0x9b, 0x1c, 0xf3, 0xab, 0xc4, 0xfb, 0xb9, 0x87, 0x48, 0x77, 0x89, - 0xbf, 0x29, 0x00, 0xe8, 0xf7, 0x2c, 0x11, 0x21, 0xec, 0x26, 0x2c, 0xd0, 0x0b, 0x92, 0x50, 0xb4, + 0x67, 0x6f, 0x11, 0xc0, 0xb8, 0x73, 0xf4, 0xa1, 0x6b, 0x79, 0x5f, 0x17, 0xae, 0x1e, 0x9f, 0x83, + 0x0d, 0x6e, 0x3c, 0x7c, 0xdf, 0x9b, 0x1c, 0xf1, 0xab, 0xc4, 0xfb, 0xb9, 0x87, 0x48, 0x77, 0x89, + 0xbf, 0x2e, 0x00, 0xe8, 0xf7, 0x2d, 0x11, 0x21, 0xec, 0x16, 0x2c, 0xd0, 0x0b, 0x92, 0x50, 0xb4, 0xa0, 0x9a, 0x1a, 0xf9, 0xca, 0x6a, 0x6a, 0xc4, 0xa0, 0xab, 0xd1, 0x44, 0xa3, 0x7a, 0xa1, 0x64, 0xc1, 0xd5, 0xc8, 0xec, 0xec, 0x63, 0x11, 0x9a, 0x39, 0x16, 0xa9, 0x03, 0x44, 0x31, 0xbb, 0xb8, 0xc8, 0xbf, 0x11, 0x05, 0xbf, 0xe1, 0x05, 0x3c, 0x4b, 0x44, 0x14, 0xf7, 0x4b, 0x9e, 0x3e, 0x11, - 0x1a, 0xb9, 0x0b, 0x85, 0x8e, 0x13, 0xfa, 0xe2, 0xce, 0x88, 0x64, 0xf6, 0x1c, 0x4f, 0xdd, 0x19, + 0x1a, 0xb9, 0x07, 0x85, 0x8e, 0x13, 0xfa, 0xe2, 0xce, 0x88, 0x64, 0xf6, 0x1c, 0x4f, 0xdd, 0x19, 0x45, 0x33, 0x5b, 0x9b, 0x38, 0xb1, 0x0c, 0xc7, 0xc8, 0x84, 0x18, 0xb0, 0xc8, 0xd3, 0xb2, 0xcf, - 0x88, 0x80, 0xc9, 0xb3, 0xb2, 0xf3, 0xb8, 0xd7, 0x08, 0x94, 0x65, 0x0a, 0x9e, 0x80, 0xfd, 0x36, + 0x88, 0x80, 0xc9, 0xb3, 0xb2, 0xf3, 0xb8, 0xd7, 0x08, 0x94, 0x65, 0x0a, 0x9e, 0x80, 0xfd, 0x0e, 0xe4, 0x2d, 0xab, 0xc1, 0xe3, 0x77, 0xac, 0x46, 0xd7, 0x2f, 0xcb, 0x6a, 0xb0, 0x77, 0xdf, 0x20, - 0x38, 0x91, 0xc8, 0x28, 0x32, 0xf9, 0x04, 0x94, 0x24, 0xa1, 0x98, 0x47, 0xbe, 0xc1, 0x3e, 0x90, - 0xbc, 0x9d, 0xe4, 0x4d, 0x43, 0xc2, 0x26, 0x75, 0x50, 0xef, 0x4e, 0x1f, 0xba, 0xfa, 0x68, 0x84, + 0x38, 0x96, 0xc8, 0x28, 0x32, 0xf9, 0x04, 0x94, 0x24, 0xa1, 0x98, 0x47, 0xbe, 0xc1, 0x3e, 0x90, + 0xbc, 0x9d, 0xe4, 0x4d, 0x43, 0xc2, 0x26, 0x75, 0x50, 0xef, 0x4d, 0x1f, 0xb9, 0xfa, 0x68, 0x84, 0x6e, 0x90, 0x6f, 0xbb, 0x63, 0x26, 0xb6, 0x15, 0xa3, 0x90, 0xd1, 0xe8, 0x23, 0xd1, 0x17, 0xa5, - 0xb2, 0xb2, 0x29, 0x49, 0x49, 0xda, 0xb0, 0x61, 0xb9, 0x93, 0xe9, 0x88, 0xd9, 0xd7, 0xec, 0xf9, - 0x63, 0x7a, 0xbf, 0x61, 0x71, 0x72, 0x30, 0xba, 0x6e, 0x40, 0x0b, 0x85, 0x51, 0xd3, 0xa1, 0x3f, + 0xb2, 0xb2, 0x29, 0x49, 0x49, 0xda, 0xb0, 0x61, 0xb9, 0x93, 0xe9, 0x88, 0xd9, 0xd7, 0xec, 0xfa, + 0x63, 0x7a, 0xbf, 0x61, 0x71, 0x72, 0x30, 0xba, 0x6e, 0x40, 0x0b, 0x85, 0x51, 0xd3, 0x81, 0x3f, 0x4e, 0xdc, 0x75, 0xd2, 0xc4, 0x9a, 0x2b, 0x0f, 0x39, 0x3d, 0x55, 0xe3, 0xb7, 0x26, 0x3c, 0x55, 0xc5, 0xad, 0x29, 0xba, 0x2b, 0x7d, 0x24, 0x23, 0x96, 0x1b, 0xbe, 0x0c, 0x4a, 0xb1, 0xdc, 0x62, - 0x11, 0xdc, 0xbe, 0x5f, 0x90, 0xc2, 0x89, 0xf2, 0xb1, 0x78, 0x13, 0xe0, 0x8e, 0xef, 0x0d, 0x1b, - 0xee, 0xe4, 0xd8, 0xef, 0x4b, 0x21, 0xe5, 0x4a, 0x5f, 0xf6, 0xbd, 0xa1, 0x7d, 0x82, 0xe0, 0x9f, - 0xbf, 0x7b, 0x45, 0x42, 0x32, 0xa5, 0xff, 0xc9, 0x87, 0x61, 0x99, 0xfe, 0xea, 0x44, 0x56, 0x42, + 0x11, 0xdc, 0xbe, 0x5f, 0x90, 0xc2, 0x89, 0xf2, 0xb1, 0x78, 0x13, 0xe0, 0xae, 0xef, 0x0d, 0x1b, + 0xee, 0xe4, 0xc8, 0xef, 0x4b, 0x21, 0xe5, 0x4a, 0x5f, 0xf6, 0xbd, 0xa1, 0x7d, 0x8c, 0xe0, 0x9f, + 0xbf, 0x7b, 0x55, 0x42, 0x32, 0xa5, 0xff, 0xc9, 0x87, 0x61, 0x99, 0xfe, 0xea, 0x44, 0x56, 0x42, 0x4c, 0x27, 0x8b, 0xd4, 0x2c, 0xe9, 0x46, 0x84, 0x40, 0xde, 0xc0, 0x34, 0x33, 0xde, 0x68, 0x22, 0x09, 0xaf, 0x22, 0xa7, 0x8c, 0x37, 0x9a, 0x24, 0x23, 0x44, 0x4b, 0xc8, 0xa4, 0x1a, 0x56, 0x5d, 0x64, 0x86, 0xe2, 0xd9, 0x6c, 0x50, 0xf1, 0xc8, 0xe7, 0x9a, 0x2d, 0x42, 0xd3, 0xca, 0x29, 0x7f, - 0x13, 0x64, 0x58, 0x09, 0xab, 0xba, 0xcb, 0x5e, 0x8a, 0xb8, 0x50, 0xcb, 0x2a, 0x11, 0x1c, 0xf7, - 0xed, 0x1e, 0x82, 0x63, 0x95, 0x08, 0x91, 0xc9, 0x0e, 0xac, 0x33, 0x19, 0x3f, 0xcc, 0x30, 0xc9, - 0x45, 0x5c, 0xdc, 0xdb, 0xa2, 0x14, 0x94, 0xf2, 0xe7, 0x13, 0x04, 0x64, 0x0f, 0x16, 0xf0, 0xae, - 0xc9, 0x5d, 0x03, 0x2e, 0xca, 0x6a, 0x82, 0xe4, 0x3a, 0xc2, 0x7d, 0x05, 0x15, 0x04, 0xf2, 0xbe, + 0x13, 0x64, 0x58, 0x09, 0xab, 0xba, 0xc3, 0x5e, 0x8a, 0xb8, 0x50, 0xcb, 0x2a, 0x11, 0x1c, 0xf5, + 0xed, 0x1e, 0x82, 0x63, 0x95, 0x08, 0x91, 0xc9, 0x36, 0xac, 0x33, 0x19, 0x3f, 0xcc, 0x30, 0xc9, + 0x45, 0x5c, 0xdc, 0xdb, 0xa2, 0x14, 0x94, 0xf2, 0xe7, 0x13, 0x04, 0x64, 0x17, 0x16, 0xf0, 0xae, + 0xc9, 0x5d, 0x03, 0x2e, 0xc9, 0x6a, 0x82, 0xe4, 0x3a, 0xc2, 0x7d, 0x05, 0x15, 0x04, 0xf2, 0xbe, 0x82, 0xa8, 0xe4, 0xb3, 0x00, 0xc6, 0x70, 0xec, 0x0f, 0x06, 0x18, 0x3c, 0xb9, 0x88, 0x57, 0xa9, 0x67, 0xe3, 0xeb, 0x11, 0xb9, 0x44, 0x48, 0x3c, 0xd0, 0x1f, 0xfe, 0xb6, 0x13, 0x21, 0x96, 0x25, 0x5e, 0x5a, 0x0d, 0x16, 0xd9, 0x62, 0xc4, 0x40, 0xe4, 0x3c, 0xb5, 0x8a, 0x14, 0xc6, 0x9a, 0x05, - 0x22, 0xe7, 0xf0, 0x74, 0x20, 0x72, 0x89, 0x40, 0xbb, 0x0b, 0xe7, 0xb2, 0x1a, 0x16, 0xbb, 0x1d, - 0x2b, 0xa7, 0xbd, 0x1d, 0x7f, 0x2f, 0x0f, 0x2b, 0xc8, 0x4d, 0xec, 0xc2, 0x3a, 0xac, 0x5a, 0xd3, - 0x87, 0x61, 0x94, 0x2e, 0xb1, 0x1b, 0x63, 0xfd, 0x02, 0xb9, 0x40, 0x7e, 0xc3, 0x8b, 0x51, 0x10, - 0x03, 0xd6, 0xc4, 0x49, 0xb0, 0x2f, 0x3c, 0x07, 0xc2, 0x18, 0xe0, 0x22, 0xd2, 0x64, 0x3a, 0xc3, - 0x6e, 0x82, 0x28, 0x3a, 0x0f, 0xf2, 0x4f, 0x73, 0x1e, 0x14, 0x4e, 0x75, 0x1e, 0x3c, 0x80, 0x15, - 0xf1, 0x35, 0xdc, 0xc9, 0x17, 0xde, 0xdf, 0x4e, 0x1e, 0x63, 0x46, 0xea, 0xe1, 0x8e, 0xbe, 0x38, - 0x77, 0x47, 0xc7, 0x87, 0x51, 0xb1, 0xca, 0x46, 0x08, 0x4b, 0x6f, 0xec, 0x98, 0x82, 0x72, 0xbf, - 0xd2, 0xfe, 0x05, 0x4e, 0xc9, 0x57, 0x61, 0xb9, 0xee, 0x8b, 0x37, 0x31, 0xe9, 0x31, 0x62, 0x20, - 0x80, 0xb2, 0xb8, 0x10, 0x62, 0x86, 0xa7, 0x5b, 0xfe, 0x83, 0x38, 0xdd, 0xde, 0x00, 0xe0, 0x2e, - 0x29, 0x51, 0xea, 0x38, 0x5c, 0x32, 0x22, 0x42, 0x49, 0xfc, 0x4d, 0x44, 0x42, 0xa6, 0xbb, 0x13, - 0x37, 0xb7, 0xd1, 0x7b, 0x3d, 0x7f, 0x3a, 0x9c, 0xc4, 0x72, 0x2d, 0x0b, 0x0f, 0x56, 0x87, 0x97, - 0xc9, 0xdb, 0x43, 0x82, 0xec, 0x83, 0x1d, 0x10, 0xf2, 0x99, 0xd0, 0xf8, 0x71, 0x69, 0x5e, 0x0f, - 0x69, 0xa9, 0x1e, 0x9a, 0x69, 0xf2, 0xa8, 0xfd, 0x58, 0x91, 0x13, 0x30, 0xfc, 0x02, 0x43, 0xfd, - 0x3a, 0x40, 0x68, 0x94, 0x20, 0xc6, 0x9a, 0xdd, 0x97, 0x42, 0xa8, 0xdc, 0xcb, 0x11, 0xae, 0xd4, - 0x9a, 0xfc, 0x07, 0xd5, 0x9a, 0x0e, 0x94, 0x5a, 0x5f, 0x99, 0x38, 0x91, 0x15, 0x0b, 0x58, 0xa1, - 0x24, 0x8b, 0x3b, 0x53, 0x7e, 0xe7, 0x05, 0x3c, 0x1b, 0x22, 0x39, 0x78, 0x86, 0x08, 0x2c, 0x11, - 0x6a, 0x7f, 0xa6, 0xc0, 0xba, 0xec, 0x76, 0xff, 0x78, 0xd8, 0x23, 0x9f, 0x62, 0xf1, 0x60, 0x95, - 0xd8, 0x95, 0x45, 0x42, 0xa2, 0x5b, 0xee, 0xe3, 0x61, 0x8f, 0x09, 0x40, 0xce, 0x23, 0xb9, 0xb2, - 0x94, 0x90, 0x3c, 0x84, 0x95, 0xb6, 0x3f, 0x18, 0x50, 0xb1, 0x66, 0xfc, 0x36, 0xbf, 0x00, 0x50, - 0x46, 0xc9, 0xa7, 0x11, 0x51, 0xa1, 0x9d, 0xe7, 0xf9, 0x3d, 0x77, 0x73, 0x44, 0xf7, 0x7b, 0x8f, - 0xd3, 0x45, 0x6c, 0xdf, 0x41, 0x3f, 0x39, 0x99, 0xa7, 0xf6, 0x53, 0x05, 0x48, 0xba, 0x4a, 0xf2, - 0x96, 0xa5, 0xfc, 0x37, 0x88, 0xb0, 0x09, 0xd1, 0xaf, 0xf0, 0x34, 0xa2, 0x5f, 0xf9, 0xb7, 0x15, - 0x58, 0xaf, 0xe9, 0x0d, 0x9e, 0x92, 0x81, 0xbd, 0xe0, 0x5c, 0x85, 0x67, 0x6b, 0x7a, 0xc3, 0x6e, - 0xb7, 0xea, 0xb5, 0xca, 0x7d, 0x3b, 0x33, 0xd2, 0xf2, 0xb3, 0xf0, 0x4c, 0x1a, 0x25, 0x7a, 0xe9, - 0xb9, 0x04, 0x5b, 0xe9, 0x62, 0x11, 0x8d, 0x39, 0x9b, 0x58, 0x04, 0x6e, 0xce, 0x97, 0xdf, 0x82, - 0x75, 0x11, 0x79, 0xb8, 0x53, 0xb7, 0x30, 0xb7, 0xc1, 0x3a, 0x94, 0x0e, 0x0c, 0xb3, 0xb6, 0x77, - 0xdf, 0xde, 0xeb, 0xd6, 0xeb, 0xea, 0x19, 0xb2, 0x0a, 0xcb, 0x1c, 0x50, 0xd1, 0x55, 0x85, 0xac, - 0x40, 0xb1, 0xd6, 0xb4, 0x8c, 0x4a, 0xd7, 0x34, 0xd4, 0x5c, 0xf9, 0x2d, 0x58, 0x6b, 0x8f, 0xbd, - 0xb7, 0x9d, 0x89, 0x7b, 0xd7, 0x7d, 0x8c, 0x0f, 0x35, 0x4b, 0x90, 0x37, 0xf5, 0x7b, 0xea, 0x19, - 0x02, 0xb0, 0xd8, 0xbe, 0x5b, 0xb1, 0x6e, 0xdd, 0x52, 0x15, 0x52, 0x82, 0xa5, 0xfd, 0x4a, 0xdb, - 0xbe, 0xdb, 0xb0, 0xd4, 0x1c, 0xfd, 0xa1, 0xdf, 0xb3, 0xf0, 0x47, 0xbe, 0xfc, 0x51, 0xd8, 0x40, - 0x81, 0xa4, 0xee, 0x05, 0x13, 0x77, 0xe8, 0x8e, 0xb1, 0x0e, 0x2b, 0x50, 0xb4, 0x5c, 0xba, 0x93, - 0x4c, 0x5c, 0x56, 0x81, 0xc6, 0x74, 0x30, 0xf1, 0x46, 0x03, 0xf7, 0x6b, 0xaa, 0x52, 0x7e, 0x03, - 0xd6, 0x4d, 0x7f, 0x3a, 0xf1, 0x86, 0x47, 0xd6, 0x84, 0x62, 0x1c, 0x3d, 0x26, 0xe7, 0x61, 0xa3, - 0xdb, 0xd4, 0x1b, 0x3b, 0xb5, 0xfd, 0x6e, 0xab, 0x6b, 0xd9, 0x0d, 0xbd, 0x53, 0xa9, 0xb2, 0x67, - 0xa2, 0x46, 0xcb, 0xea, 0xd8, 0xa6, 0x51, 0x31, 0x9a, 0x1d, 0x55, 0x29, 0x7f, 0x07, 0x75, 0x2b, - 0x3d, 0x7f, 0xd8, 0xdf, 0x73, 0x7a, 0x13, 0x7f, 0x8c, 0x15, 0xd6, 0xe0, 0xb2, 0x65, 0x54, 0x5a, - 0xcd, 0x5d, 0x7b, 0x4f, 0xaf, 0x74, 0x5a, 0x66, 0x56, 0xa8, 0xef, 0x6d, 0xb8, 0x90, 0x81, 0xd3, - 0xea, 0xb4, 0x55, 0x85, 0x5c, 0x81, 0x8b, 0x19, 0x65, 0xf7, 0x8c, 0x1d, 0xbd, 0xdb, 0xa9, 0x36, - 0xd5, 0xdc, 0x0c, 0x62, 0xcb, 0x6a, 0xa9, 0xf9, 0xf2, 0xff, 0x57, 0x60, 0xad, 0x1b, 0x70, 0x93, - 0xf3, 0x2e, 0x7a, 0x9b, 0x3e, 0x07, 0x97, 0xba, 0x96, 0x61, 0xda, 0x9d, 0xd6, 0x5d, 0xa3, 0x69, - 0x77, 0x2d, 0x7d, 0x3f, 0x59, 0x9b, 0x2b, 0x70, 0x51, 0xc2, 0x30, 0x8d, 0x4a, 0xeb, 0xc0, 0x30, - 0xed, 0xb6, 0x6e, 0x59, 0xf7, 0x5a, 0xe6, 0xae, 0xaa, 0xd0, 0x2f, 0x66, 0x20, 0x34, 0xf6, 0x74, - 0x56, 0x9b, 0x58, 0x59, 0xd3, 0xb8, 0xa7, 0xd7, 0xed, 0x9d, 0x56, 0x47, 0xcd, 0x97, 0x1b, 0xf4, - 0x7c, 0xc7, 0x80, 0xbb, 0xcc, 0xb2, 0xb0, 0x08, 0x85, 0x66, 0xab, 0x69, 0x24, 0x1f, 0x17, 0x57, - 0xa0, 0xa8, 0xb7, 0xdb, 0x66, 0xeb, 0x00, 0xa7, 0x18, 0xc0, 0xe2, 0xae, 0xd1, 0xa4, 0x35, 0xcb, - 0xd3, 0x92, 0xb6, 0xd9, 0x6a, 0xb4, 0x3a, 0xc6, 0xae, 0x5a, 0x28, 0x9b, 0x62, 0x09, 0x0b, 0xa6, - 0x3d, 0x9f, 0xbd, 0xe4, 0xed, 0x1a, 0x7b, 0x7a, 0xb7, 0xde, 0xe1, 0x43, 0x74, 0xdf, 0x36, 0x8d, - 0xcf, 0x74, 0x0d, 0xab, 0x63, 0xa9, 0x0a, 0x51, 0x61, 0xa5, 0x69, 0x18, 0xbb, 0x96, 0x6d, 0x1a, - 0x07, 0x35, 0xe3, 0x9e, 0x9a, 0xa3, 0x3c, 0xd9, 0xff, 0xf4, 0x0b, 0xe5, 0xef, 0x2b, 0x40, 0x58, - 0xb0, 0x62, 0x91, 0x01, 0x07, 0x67, 0xcc, 0x65, 0xd8, 0xae, 0xd2, 0xa1, 0xc6, 0xa6, 0x35, 0x5a, - 0xbb, 0xc9, 0x2e, 0xbb, 0x00, 0x24, 0x51, 0xde, 0xda, 0xdb, 0x53, 0x15, 0x72, 0x11, 0xce, 0x26, - 0xe0, 0xbb, 0x66, 0xab, 0xad, 0xe6, 0xb6, 0x73, 0x45, 0x85, 0x6c, 0xa6, 0x0a, 0xef, 0x1a, 0x46, - 0x5b, 0xcd, 0xd3, 0x21, 0x4a, 0x14, 0x88, 0x25, 0xc1, 0xc8, 0x0b, 0xe5, 0x6f, 0x29, 0x70, 0x81, - 0x55, 0x53, 0xac, 0xaf, 0xb0, 0xaa, 0x97, 0x60, 0x8b, 0x87, 0x60, 0xcf, 0xaa, 0xe8, 0x39, 0x50, - 0x63, 0xa5, 0xac, 0x9a, 0xe7, 0x61, 0x23, 0x06, 0xc5, 0x7a, 0xe4, 0xe8, 0xee, 0x11, 0x03, 0xef, - 0x18, 0x56, 0xc7, 0x36, 0xf6, 0xf6, 0x5a, 0x66, 0x87, 0x55, 0x24, 0x5f, 0xd6, 0x60, 0xa3, 0xe2, - 0x8e, 0x27, 0xf4, 0xea, 0x35, 0x0c, 0x3c, 0x7f, 0x88, 0x55, 0x58, 0x85, 0x65, 0xe3, 0xb3, 0x1d, - 0xa3, 0x69, 0xd5, 0x5a, 0x4d, 0xf5, 0x4c, 0xf9, 0x52, 0x02, 0x47, 0xac, 0x63, 0xcb, 0xaa, 0xaa, - 0x67, 0xca, 0x0e, 0xac, 0x0a, 0xc3, 0x6b, 0x36, 0x2b, 0x2e, 0xc3, 0xb6, 0x98, 0x6b, 0xb8, 0xa3, - 0x24, 0x9b, 0xb0, 0x05, 0xe7, 0xd2, 0xe5, 0x46, 0x47, 0x55, 0xe8, 0x28, 0x24, 0x4a, 0x28, 0x3c, - 0x57, 0xfe, 0xbf, 0x0a, 0xac, 0x86, 0x8f, 0x26, 0xa8, 0xa6, 0xbd, 0x02, 0x17, 0x1b, 0x7b, 0xba, - 0xbd, 0x6b, 0x1c, 0xd4, 0x2a, 0x86, 0x7d, 0xb7, 0xd6, 0xdc, 0x4d, 0x7c, 0xe4, 0x19, 0x38, 0x9f, - 0x81, 0x80, 0x5f, 0xd9, 0x82, 0x73, 0xc9, 0xa2, 0x0e, 0x5d, 0xaa, 0x39, 0xda, 0xf5, 0xc9, 0x92, - 0x70, 0x9d, 0xe6, 0xcb, 0x07, 0xb0, 0x66, 0xe9, 0x8d, 0xfa, 0x9e, 0x3f, 0xee, 0xb9, 0xfa, 0x74, - 0x72, 0x3c, 0x24, 0x17, 0x61, 0x73, 0xaf, 0x65, 0x56, 0x0c, 0x1b, 0x51, 0x12, 0x35, 0x38, 0x0b, - 0xeb, 0x72, 0xe1, 0x7d, 0x83, 0x4e, 0x5f, 0x02, 0x6b, 0x32, 0xb0, 0xd9, 0x52, 0x73, 0xe5, 0xcf, - 0xc3, 0x4a, 0x2c, 0x11, 0xde, 0x26, 0x9c, 0x95, 0x7f, 0xb7, 0xdd, 0x61, 0xdf, 0x1b, 0x1e, 0xa9, - 0x67, 0x92, 0x05, 0xe6, 0x74, 0x38, 0xa4, 0x05, 0xb8, 0x9e, 0xe5, 0x82, 0x8e, 0x3b, 0x3e, 0xf1, - 0x86, 0xce, 0xc4, 0xed, 0xab, 0xb9, 0xf2, 0xcb, 0xb0, 0x1a, 0x0b, 0xbf, 0x4d, 0x07, 0xae, 0xde, - 0xe2, 0x1b, 0x70, 0xc3, 0xd8, 0xad, 0x75, 0x1b, 0xea, 0x02, 0x5d, 0xc9, 0xd5, 0xda, 0x7e, 0x55, - 0x85, 0xf2, 0x77, 0x15, 0x7a, 0xcf, 0xc0, 0xa4, 0x3a, 0x8d, 0x3d, 0x5d, 0x0c, 0x35, 0x9d, 0x66, - 0x2c, 0xa8, 0xbf, 0x61, 0x59, 0xec, 0x4d, 0xfd, 0x12, 0x6c, 0xf1, 0x1f, 0xb6, 0xde, 0xdc, 0xb5, - 0xab, 0xba, 0xb9, 0x7b, 0x4f, 0x37, 0xe9, 0xdc, 0xbb, 0xaf, 0xe6, 0x70, 0x41, 0x49, 0x10, 0xbb, - 0xd3, 0xea, 0x56, 0xaa, 0x6a, 0x9e, 0xce, 0xdf, 0x18, 0xbc, 0x5d, 0x6b, 0xaa, 0x05, 0x5c, 0x9e, - 0x29, 0x6c, 0x64, 0x4b, 0xcb, 0x17, 0xca, 0xef, 0x29, 0xb0, 0x69, 0x79, 0x47, 0x43, 0x67, 0x32, - 0x1d, 0xbb, 0xfa, 0xe0, 0xc8, 0x1f, 0x7b, 0x93, 0xe3, 0x13, 0x6b, 0xea, 0x4d, 0x5c, 0x72, 0x13, - 0x5e, 0xb0, 0x6a, 0xfb, 0x4d, 0xbd, 0x43, 0x97, 0x97, 0x5e, 0xdf, 0x6f, 0x99, 0xb5, 0x4e, 0xb5, - 0x61, 0x5b, 0xdd, 0x5a, 0x6a, 0xe6, 0x5d, 0x83, 0xe7, 0x66, 0xa3, 0xd6, 0x8d, 0x7d, 0xbd, 0x72, - 0x5f, 0x55, 0xe6, 0x33, 0xdc, 0xd1, 0xeb, 0x7a, 0xb3, 0x62, 0xec, 0xda, 0x07, 0xb7, 0xd4, 0x1c, - 0x79, 0x01, 0xae, 0xce, 0x46, 0xdd, 0xab, 0xb5, 0x2d, 0x8a, 0x96, 0x9f, 0xff, 0xdd, 0xaa, 0xd5, - 0xa0, 0x58, 0x85, 0xf2, 0x1f, 0x2a, 0xb0, 0x35, 0x2b, 0x06, 0x13, 0xb9, 0x0e, 0x9a, 0xd1, 0xec, - 0x98, 0x7a, 0x6d, 0xd7, 0xae, 0x98, 0xc6, 0xae, 0xd1, 0xec, 0xd4, 0xf4, 0xba, 0x65, 0x5b, 0xad, - 0x2e, 0x9d, 0x4d, 0x91, 0xe9, 0xc3, 0xf3, 0x70, 0x65, 0x0e, 0x5e, 0xab, 0xb6, 0x5b, 0x51, 0x15, - 0x72, 0x0b, 0x5e, 0x9a, 0x83, 0x64, 0xdd, 0xb7, 0x3a, 0x46, 0x43, 0x2e, 0x51, 0x73, 0xe5, 0x0a, - 0x6c, 0xcf, 0x0e, 0xd2, 0x42, 0xb7, 0xe9, 0x78, 0x4f, 0x17, 0xa1, 0xb0, 0x4b, 0x4f, 0x86, 0x58, - 0xee, 0x87, 0xb2, 0x07, 0x6a, 0x32, 0xce, 0x42, 0xca, 0x46, 0xc5, 0xec, 0x36, 0x9b, 0xec, 0x18, - 0x59, 0x87, 0x52, 0xab, 0x53, 0x35, 0x4c, 0x9e, 0x3d, 0x03, 0xd3, 0x65, 0x74, 0x9b, 0x74, 0xe1, - 0xb4, 0xcc, 0xda, 0xe7, 0xf0, 0x3c, 0xd9, 0x82, 0x73, 0x56, 0x5d, 0xaf, 0xdc, 0xb5, 0x9b, 0xad, - 0x8e, 0x5d, 0x6b, 0xda, 0x95, 0xaa, 0xde, 0x6c, 0x1a, 0x75, 0x15, 0xb0, 0x33, 0x67, 0xf9, 0x56, - 0x92, 0x0f, 0xc3, 0x8d, 0xd6, 0xdd, 0x8e, 0x6e, 0xb7, 0xeb, 0xdd, 0xfd, 0x5a, 0xd3, 0xb6, 0xee, - 0x37, 0x2b, 0x42, 0xf6, 0xa9, 0xa4, 0xb7, 0xdc, 0x1b, 0x70, 0x6d, 0x2e, 0x76, 0x94, 0xe7, 0xe2, - 0x3a, 0x68, 0x73, 0x31, 0x79, 0x43, 0xca, 0x3f, 0x51, 0xe0, 0xe2, 0x9c, 0x37, 0x64, 0xf2, 0x12, - 0xdc, 0xac, 0x1a, 0xfa, 0x6e, 0xdd, 0xb0, 0x2c, 0xdc, 0x28, 0xe8, 0x30, 0x30, 0x5b, 0x96, 0xcc, - 0x0d, 0xf5, 0x26, 0xbc, 0x30, 0x1f, 0x3d, 0x3a, 0x9a, 0x6f, 0xc0, 0xb5, 0xf9, 0xa8, 0xfc, 0xa8, - 0xce, 0x91, 0x32, 0x5c, 0x9f, 0x8f, 0x19, 0x1e, 0xf1, 0xf9, 0xf2, 0x6f, 0x2a, 0x70, 0x21, 0x5b, - 0x91, 0x43, 0xeb, 0x56, 0x6b, 0x5a, 0x1d, 0xbd, 0x5e, 0xb7, 0xdb, 0xba, 0xa9, 0x37, 0x6c, 0xa3, - 0x69, 0xb6, 0xea, 0xf5, 0xac, 0xa3, 0xed, 0x1a, 0x3c, 0x37, 0x1b, 0xd5, 0xaa, 0x98, 0xb5, 0x36, - 0xdd, 0xbd, 0x35, 0xb8, 0x3c, 0x1b, 0xcb, 0xa8, 0x55, 0x0c, 0x35, 0xb7, 0xf3, 0xe6, 0x8f, 0xfe, - 0xfe, 0xf2, 0x99, 0x1f, 0xbd, 0x77, 0x59, 0xf9, 0xe9, 0x7b, 0x97, 0x95, 0xbf, 0x7b, 0xef, 0xb2, - 0xf2, 0xb9, 0x17, 0x4f, 0x97, 0x22, 0x0a, 0xe5, 0xfe, 0x87, 0x8b, 0x78, 0x43, 0x79, 0xe5, 0x3f, - 0x03, 0x00, 0x00, 0xff, 0xff, 0x09, 0xed, 0xed, 0x8d, 0x2e, 0xbf, 0x01, 0x00, + 0x22, 0xe7, 0xf0, 0x74, 0x20, 0x72, 0x89, 0x40, 0xbb, 0x07, 0xe7, 0xb2, 0x1a, 0x16, 0xbb, 0x1d, + 0x2b, 0x27, 0xbd, 0x1d, 0x7f, 0x2f, 0x0f, 0x2b, 0xc8, 0x4d, 0xec, 0xc2, 0x3a, 0xac, 0x5a, 0xd3, + 0x47, 0x61, 0x94, 0x2e, 0xb1, 0x1b, 0x63, 0xfd, 0x02, 0xb9, 0x40, 0x7e, 0xc3, 0x8b, 0x51, 0x10, + 0x03, 0xd6, 0xc4, 0x49, 0xb0, 0x27, 0x3c, 0x07, 0xc2, 0x18, 0xe0, 0x22, 0xd2, 0x64, 0x3a, 0xc3, + 0x6e, 0x82, 0x28, 0x3a, 0x0f, 0xf2, 0xa7, 0x39, 0x0f, 0x0a, 0x27, 0x3a, 0x0f, 0x1e, 0xc2, 0x8a, + 0xf8, 0x1a, 0xee, 0xe4, 0x0b, 0xef, 0x6f, 0x27, 0x8f, 0x31, 0x23, 0xf5, 0x70, 0x47, 0x5f, 0x9c, + 0xbb, 0xa3, 0xe3, 0xc3, 0xa8, 0x58, 0x65, 0x23, 0x84, 0xa5, 0x37, 0x76, 0x4c, 0x41, 0xb9, 0x57, + 0x69, 0xff, 0x02, 0xa7, 0xe4, 0xab, 0xb0, 0x5c, 0xf7, 0xc5, 0x9b, 0x98, 0xf4, 0x18, 0x31, 0x10, + 0x40, 0x59, 0x5c, 0x08, 0x31, 0xc3, 0xd3, 0x2d, 0xff, 0x41, 0x9c, 0x6e, 0x6f, 0x00, 0x70, 0x97, + 0x94, 0x28, 0x75, 0x1c, 0x2e, 0x19, 0x11, 0xa1, 0x24, 0xfe, 0x26, 0x22, 0x21, 0xd3, 0xdd, 0x89, + 0x9b, 0xdb, 0xe8, 0xbd, 0x9e, 0x3f, 0x1d, 0x4e, 0x62, 0xb9, 0x96, 0x85, 0x07, 0xab, 0xc3, 0xcb, + 0xe4, 0xed, 0x21, 0x41, 0xf6, 0xc1, 0x0e, 0x08, 0xf9, 0x4c, 0x68, 0xfc, 0xb8, 0x34, 0xaf, 0x87, + 0xb4, 0x54, 0x0f, 0xcd, 0x34, 0x79, 0xd4, 0x7e, 0xac, 0xc8, 0x09, 0x18, 0x7e, 0x81, 0xa1, 0x7e, + 0x1d, 0x20, 0x34, 0x4a, 0x10, 0x63, 0xcd, 0xee, 0x4b, 0x21, 0x54, 0xee, 0xe5, 0x08, 0x57, 0x6a, + 0x4d, 0xfe, 0x83, 0x6a, 0x4d, 0x07, 0x4a, 0xad, 0xaf, 0x4c, 0x9c, 0xc8, 0x8a, 0x05, 0xac, 0x50, + 0x92, 0xc5, 0x9d, 0x29, 0xbf, 0xfd, 0x02, 0x9e, 0x0d, 0x91, 0x1c, 0x3c, 0x43, 0x04, 0x96, 0x08, + 0xb5, 0xff, 0x50, 0x60, 0x5d, 0x76, 0xbb, 0x7f, 0x32, 0xec, 0x91, 0x4f, 0xb1, 0x78, 0xb0, 0x4a, + 0xec, 0xca, 0x22, 0x21, 0xd1, 0x2d, 0xf7, 0xc9, 0xb0, 0xc7, 0x04, 0x20, 0xe7, 0xb1, 0x5c, 0x59, + 0x4a, 0x48, 0x1e, 0xc1, 0x4a, 0xdb, 0x1f, 0x0c, 0xa8, 0x58, 0x33, 0x7e, 0x9b, 0x5f, 0x00, 0x28, + 0xa3, 0xe4, 0xd3, 0x88, 0xa8, 0xd0, 0xf6, 0xf3, 0xfc, 0x9e, 0xbb, 0x39, 0xa2, 0xfb, 0xbd, 0xc7, + 0xe9, 0x22, 0xb6, 0xef, 0xa0, 0x9f, 0x9c, 0xcc, 0x33, 0x3a, 0x9b, 0xe2, 0x89, 0x04, 0xe4, 0x5a, + 0xd2, 0x62, 0xac, 0xe7, 0x9c, 0xb3, 0x49, 0xfb, 0xa9, 0x02, 0x24, 0xdd, 0x34, 0x79, 0xeb, 0x53, + 0xfe, 0x1b, 0x44, 0xe1, 0x84, 0x08, 0x59, 0x38, 0x8d, 0x08, 0x49, 0xa7, 0xfd, 0xb9, 0xac, 0x7e, + 0x38, 0x7d, 0xa3, 0x0c, 0x58, 0x93, 0xcf, 0xa0, 0x50, 0x74, 0xc3, 0x23, 0x47, 0x3e, 0xb6, 0xe2, + 0xe7, 0x60, 0x82, 0x28, 0xd9, 0x9a, 0xfc, 0x69, 0x5a, 0x53, 0xfe, 0x6d, 0x05, 0xd6, 0x6b, 0x7a, + 0x83, 0x27, 0xaa, 0x60, 0xef, 0x5a, 0xd7, 0xe0, 0xd9, 0x9a, 0xde, 0xb0, 0xdb, 0xad, 0x7a, 0xad, + 0xf2, 0xc0, 0xce, 0x8c, 0x3f, 0xfd, 0x2c, 0x3c, 0x93, 0x46, 0x89, 0xde, 0xbf, 0x2e, 0xc3, 0x56, + 0xba, 0x58, 0xc4, 0xa8, 0xce, 0x26, 0x16, 0xe1, 0xac, 0xf3, 0xe5, 0xb7, 0x60, 0x5d, 0xc4, 0x63, + 0xee, 0xd4, 0x2d, 0xcc, 0xf8, 0xb0, 0x0e, 0xa5, 0x7d, 0xc3, 0xac, 0xed, 0x3e, 0xb0, 0x77, 0xbb, + 0xf5, 0xba, 0x7a, 0x86, 0xac, 0xc2, 0x32, 0x07, 0x54, 0x74, 0x55, 0x21, 0x2b, 0x50, 0xac, 0x35, + 0x2d, 0xa3, 0xd2, 0x35, 0x0d, 0x35, 0x57, 0x7e, 0x0b, 0xd6, 0xda, 0x63, 0xef, 0x6d, 0x67, 0xe2, + 0xde, 0x73, 0x9f, 0xe0, 0xf3, 0xd5, 0x12, 0xe4, 0x4d, 0xfd, 0xbe, 0x7a, 0x86, 0x00, 0x2c, 0xb6, + 0xef, 0x55, 0xac, 0xdb, 0xb7, 0x55, 0x85, 0x94, 0x60, 0x69, 0xaf, 0xd2, 0xb6, 0xef, 0x35, 0x2c, + 0x35, 0x47, 0x7f, 0xe8, 0xf7, 0x2d, 0xfc, 0x91, 0x2f, 0x7f, 0x14, 0x36, 0x50, 0x4c, 0xab, 0x7b, + 0xc1, 0xc4, 0x1d, 0xba, 0x63, 0xac, 0xc3, 0x0a, 0x14, 0x2d, 0x97, 0xee, 0xaf, 0x13, 0x97, 0x55, + 0xa0, 0x31, 0x1d, 0x4c, 0xbc, 0xd1, 0xc0, 0xfd, 0x9a, 0xaa, 0x94, 0xdf, 0x80, 0x75, 0xd3, 0x9f, + 0x4e, 0xbc, 0xe1, 0xa1, 0x35, 0xa1, 0x18, 0x87, 0x4f, 0xc8, 0x79, 0xd8, 0xe8, 0x36, 0xf5, 0xc6, + 0x76, 0x6d, 0xaf, 0xdb, 0xea, 0x5a, 0x76, 0x43, 0xef, 0x54, 0xaa, 0xec, 0xf1, 0xac, 0xd1, 0xb2, + 0x3a, 0xb6, 0x69, 0x54, 0x8c, 0x66, 0x47, 0x55, 0xca, 0xdf, 0x41, 0x8d, 0x53, 0xcf, 0x1f, 0xf6, + 0x77, 0x9d, 0xde, 0xc4, 0x1f, 0x63, 0x85, 0x35, 0xb8, 0x62, 0x19, 0x95, 0x56, 0x73, 0xc7, 0xde, + 0xd5, 0x2b, 0x9d, 0x96, 0x99, 0x15, 0x00, 0xfd, 0x22, 0x5c, 0xc8, 0xc0, 0x69, 0x75, 0xda, 0xaa, + 0x42, 0xae, 0xc2, 0xa5, 0x8c, 0xb2, 0xfb, 0xc6, 0xb6, 0xde, 0xed, 0x54, 0x9b, 0x6a, 0x6e, 0x06, + 0xb1, 0x65, 0xb5, 0xd4, 0x7c, 0xf9, 0xff, 0x2b, 0xb0, 0xd6, 0x0d, 0xb8, 0x21, 0x7e, 0x17, 0x7d, + 0x70, 0x9f, 0x83, 0xcb, 0x5d, 0xcb, 0x30, 0xed, 0x4e, 0xeb, 0x9e, 0xd1, 0xb4, 0xbb, 0x96, 0xbe, + 0x97, 0xac, 0xcd, 0x55, 0xb8, 0x24, 0x61, 0x98, 0x46, 0xa5, 0xb5, 0x6f, 0x98, 0x76, 0x5b, 0xb7, + 0xac, 0xfb, 0x2d, 0x73, 0x47, 0x55, 0xe8, 0x17, 0x33, 0x10, 0x1a, 0xbb, 0x3a, 0xab, 0x4d, 0xac, + 0xac, 0x69, 0xdc, 0xd7, 0xeb, 0xf6, 0x76, 0xab, 0xa3, 0xe6, 0xcb, 0x0d, 0x2a, 0xf5, 0x60, 0x18, + 0x62, 0x66, 0x6f, 0x59, 0x84, 0x42, 0xb3, 0xd5, 0x34, 0x92, 0x4f, 0xae, 0x2b, 0x50, 0xd4, 0xdb, + 0x6d, 0xb3, 0xb5, 0x8f, 0x53, 0x0c, 0x60, 0x71, 0xc7, 0x68, 0xd2, 0x9a, 0xe5, 0x69, 0x49, 0xdb, + 0x6c, 0x35, 0x5a, 0x1d, 0x63, 0x47, 0x2d, 0x94, 0x4d, 0xb1, 0x21, 0x09, 0xa6, 0x3d, 0x9f, 0xbd, + 0x6f, 0xee, 0x18, 0xbb, 0x7a, 0xb7, 0xde, 0xe1, 0x43, 0xf4, 0xc0, 0x36, 0x8d, 0xcf, 0x74, 0x0d, + 0xab, 0x63, 0xa9, 0x0a, 0x51, 0x61, 0xa5, 0x69, 0x18, 0x3b, 0x96, 0x6d, 0x1a, 0xfb, 0x35, 0xe3, + 0xbe, 0x9a, 0xa3, 0x3c, 0xd9, 0xff, 0xf4, 0x0b, 0xe5, 0xef, 0x2b, 0x40, 0x58, 0x08, 0x67, 0x91, + 0x17, 0x08, 0x67, 0xcc, 0x15, 0xb8, 0x58, 0xa5, 0x43, 0x8d, 0x4d, 0x6b, 0xb4, 0x76, 0x92, 0x5d, + 0x76, 0x01, 0x48, 0xa2, 0xbc, 0xb5, 0xbb, 0xab, 0x2a, 0xe4, 0x12, 0x9c, 0x4d, 0xc0, 0x77, 0xcc, + 0x56, 0x5b, 0xcd, 0x5d, 0xcc, 0x15, 0x15, 0xb2, 0x99, 0x2a, 0xbc, 0x67, 0x18, 0x6d, 0x35, 0x4f, + 0x87, 0x28, 0x51, 0x20, 0x96, 0x04, 0x23, 0x2f, 0x94, 0xbf, 0xa5, 0xc0, 0x05, 0x56, 0x4d, 0xb1, + 0xbe, 0xc2, 0xaa, 0x5e, 0x86, 0x2d, 0x1e, 0x98, 0x3e, 0xab, 0xa2, 0xe7, 0x40, 0x8d, 0x95, 0xb2, + 0x6a, 0x9e, 0x87, 0x8d, 0x18, 0x14, 0xeb, 0x91, 0xa3, 0xbb, 0x47, 0x0c, 0xbc, 0x6d, 0x58, 0x1d, + 0xdb, 0xd8, 0xdd, 0x6d, 0x99, 0x1d, 0x56, 0x91, 0x7c, 0x59, 0x83, 0x8d, 0x8a, 0x3b, 0x9e, 0xd0, + 0x0b, 0xe9, 0x30, 0xf0, 0xfc, 0x21, 0x56, 0x61, 0x15, 0x96, 0x8d, 0xcf, 0x76, 0x8c, 0xa6, 0x55, + 0x6b, 0x35, 0xd5, 0x33, 0xe5, 0xcb, 0x09, 0x1c, 0xb1, 0x8e, 0x2d, 0xab, 0xaa, 0x9e, 0x29, 0x3b, + 0xb0, 0x2a, 0xcc, 0xd1, 0xd9, 0xac, 0xb8, 0x02, 0x17, 0xc5, 0x5c, 0xc3, 0x1d, 0x25, 0xd9, 0x84, + 0x2d, 0x38, 0x97, 0x2e, 0x37, 0x3a, 0xaa, 0x42, 0x47, 0x21, 0x51, 0x42, 0xe1, 0xb9, 0xf2, 0xff, + 0x55, 0x60, 0x35, 0x7c, 0x4a, 0x42, 0xe5, 0xf5, 0x55, 0xb8, 0xd4, 0xd8, 0xd5, 0xed, 0x1d, 0x63, + 0xbf, 0x56, 0x31, 0xec, 0x7b, 0xb5, 0xe6, 0x4e, 0xe2, 0x23, 0xcf, 0xc0, 0xf9, 0x0c, 0x04, 0xfc, + 0xca, 0x16, 0x9c, 0x4b, 0x16, 0x75, 0xe8, 0x52, 0xcd, 0xd1, 0xae, 0x4f, 0x96, 0x84, 0xeb, 0x34, + 0x5f, 0xde, 0x87, 0x35, 0x4b, 0x6f, 0xd4, 0x77, 0xfd, 0x71, 0xcf, 0xd5, 0xa7, 0x93, 0xa3, 0x21, + 0xb9, 0x04, 0x9b, 0xbb, 0x2d, 0xb3, 0x62, 0xd8, 0x88, 0x92, 0xa8, 0xc1, 0x59, 0x58, 0x97, 0x0b, + 0x1f, 0x18, 0x74, 0xfa, 0x12, 0x58, 0x93, 0x81, 0xcd, 0x96, 0x9a, 0x2b, 0x7f, 0x1e, 0x56, 0x62, + 0xe9, 0x01, 0x37, 0xe1, 0xac, 0xfc, 0xbb, 0xed, 0x0e, 0xfb, 0xde, 0xf0, 0x50, 0x3d, 0x93, 0x2c, + 0x30, 0xa7, 0xc3, 0x21, 0x2d, 0xc0, 0xf5, 0x2c, 0x17, 0x74, 0xdc, 0xf1, 0xb1, 0x37, 0x74, 0x26, + 0x6e, 0x5f, 0xcd, 0x95, 0x5f, 0x86, 0xd5, 0x58, 0x50, 0x72, 0x3a, 0x70, 0xf5, 0x16, 0xdf, 0x80, + 0x1b, 0xc6, 0x4e, 0xad, 0xdb, 0x50, 0x17, 0xe8, 0x4a, 0xae, 0xd6, 0xf6, 0xaa, 0x2a, 0x94, 0xbf, + 0xab, 0xd0, 0xdb, 0x17, 0xa6, 0x1a, 0x6a, 0xec, 0xea, 0x62, 0xa8, 0xe9, 0x34, 0x63, 0xa9, 0x0e, + 0x0c, 0xcb, 0x62, 0x96, 0x06, 0x97, 0x61, 0x8b, 0xff, 0xb0, 0xf5, 0xe6, 0x8e, 0x5d, 0xd5, 0xcd, + 0x9d, 0xfb, 0xba, 0x49, 0xe7, 0xde, 0x03, 0x35, 0x87, 0x0b, 0x4a, 0x82, 0xd8, 0x9d, 0x56, 0xb7, + 0x52, 0x55, 0xf3, 0x74, 0xfe, 0xc6, 0xe0, 0xed, 0x5a, 0x53, 0x2d, 0xe0, 0xf2, 0x4c, 0x61, 0x23, + 0x5b, 0x5a, 0xbe, 0x50, 0x7e, 0x4f, 0x81, 0x4d, 0xcb, 0x3b, 0x1c, 0x3a, 0x93, 0xe9, 0xd8, 0xd5, + 0x07, 0x87, 0xfe, 0xd8, 0x9b, 0x1c, 0x1d, 0x5b, 0x53, 0x6f, 0xe2, 0x92, 0x5b, 0xf0, 0x82, 0x55, + 0xdb, 0x6b, 0xea, 0x1d, 0xba, 0xbc, 0xf4, 0xfa, 0x5e, 0xcb, 0xac, 0x75, 0xaa, 0x0d, 0xdb, 0xea, + 0xd6, 0x52, 0x33, 0xef, 0x3a, 0x3c, 0x37, 0x1b, 0xb5, 0x6e, 0xec, 0xe9, 0x95, 0x07, 0xaa, 0x32, + 0x9f, 0xe1, 0xb6, 0x5e, 0xd7, 0x9b, 0x15, 0x63, 0xc7, 0xde, 0xbf, 0xad, 0xe6, 0xc8, 0x0b, 0x70, + 0x6d, 0x36, 0xea, 0x6e, 0xad, 0x6d, 0x51, 0xb4, 0xfc, 0xfc, 0xef, 0x56, 0xad, 0x06, 0xc5, 0x2a, + 0x94, 0xff, 0x50, 0x81, 0xad, 0x59, 0x91, 0xa9, 0xc8, 0x0d, 0xd0, 0x8c, 0x66, 0xc7, 0xd4, 0x6b, + 0x3b, 0x76, 0xc5, 0x34, 0x76, 0x8c, 0x66, 0xa7, 0xa6, 0xd7, 0x2d, 0xdb, 0x6a, 0x75, 0xe9, 0x6c, + 0x8a, 0x0c, 0x42, 0x9e, 0x87, 0xab, 0x73, 0xf0, 0x5a, 0xb5, 0x9d, 0x8a, 0xaa, 0x90, 0xdb, 0xf0, + 0xd2, 0x1c, 0x24, 0xeb, 0x81, 0xd5, 0x31, 0x1a, 0x72, 0x89, 0x9a, 0x2b, 0x57, 0xe0, 0xe2, 0xec, + 0xd0, 0x35, 0x74, 0x9b, 0x8e, 0xf7, 0x74, 0x11, 0x0a, 0x3b, 0xf4, 0x64, 0x88, 0x65, 0xc4, 0x28, + 0x7b, 0xa0, 0x26, 0xa3, 0x4f, 0xa4, 0x2c, 0x77, 0xcc, 0x6e, 0xb3, 0xc9, 0x8e, 0x91, 0x75, 0x28, + 0xb5, 0x3a, 0x55, 0xc3, 0xe4, 0x39, 0x45, 0x30, 0x89, 0x48, 0xb7, 0x49, 0x17, 0x4e, 0xcb, 0xac, + 0x7d, 0x0e, 0xcf, 0x93, 0x2d, 0x38, 0x67, 0xd5, 0xf5, 0xca, 0x3d, 0xbb, 0xd9, 0xea, 0xd8, 0xb5, + 0xa6, 0x5d, 0xa9, 0xea, 0xcd, 0xa6, 0x51, 0x57, 0x01, 0x3b, 0x73, 0x96, 0xc7, 0x29, 0xf9, 0x30, + 0xdc, 0x6c, 0xdd, 0xeb, 0xe8, 0x76, 0xbb, 0xde, 0xdd, 0xab, 0x35, 0x6d, 0xeb, 0x41, 0xb3, 0x22, + 0x64, 0x9f, 0x4a, 0x7a, 0xcb, 0xbd, 0x09, 0xd7, 0xe7, 0x62, 0x47, 0xd9, 0x3f, 0x6e, 0x80, 0x36, + 0x17, 0x93, 0x37, 0xa4, 0xfc, 0x13, 0x05, 0x2e, 0xcd, 0x79, 0x59, 0x27, 0x2f, 0xc1, 0xad, 0xaa, + 0xa1, 0xef, 0xd4, 0x0d, 0xcb, 0xc2, 0x8d, 0x82, 0x0e, 0x03, 0xb3, 0xf0, 0xc9, 0xdc, 0x50, 0x6f, + 0xc1, 0x0b, 0xf3, 0xd1, 0xa3, 0xa3, 0xf9, 0x26, 0x5c, 0x9f, 0x8f, 0xca, 0x8f, 0xea, 0x1c, 0x29, + 0xc3, 0x8d, 0xf9, 0x98, 0xe1, 0x11, 0x9f, 0x2f, 0xff, 0xa6, 0x02, 0x17, 0xb2, 0xd5, 0x5b, 0xb4, + 0x6e, 0xb5, 0xa6, 0xd5, 0xd1, 0xeb, 0x75, 0xbb, 0xad, 0x9b, 0x7a, 0xc3, 0x36, 0x9a, 0x66, 0xab, + 0x5e, 0xcf, 0x3a, 0xda, 0xae, 0xc3, 0x73, 0xb3, 0x51, 0xad, 0x8a, 0x59, 0x6b, 0xd3, 0xdd, 0x5b, + 0x83, 0x2b, 0xb3, 0xb1, 0x8c, 0x5a, 0xc5, 0x50, 0x73, 0xdb, 0x6f, 0xfe, 0xe8, 0xef, 0xae, 0x9c, + 0xf9, 0xd1, 0x7b, 0x57, 0x94, 0x9f, 0xbe, 0x77, 0x45, 0xf9, 0xdb, 0xf7, 0xae, 0x28, 0x9f, 0x7b, + 0xf1, 0x64, 0x89, 0xb3, 0xf0, 0x16, 0xf3, 0x68, 0x11, 0xef, 0x6d, 0xaf, 0xfc, 0x67, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x2f, 0x37, 0xd2, 0xf7, 0x44, 0xc0, 0x01, 0x00, } func (this *PluginSpecV1) Equal(that interface{}) bool { @@ -50405,6 +50411,20 @@ func (m *AccessGraphSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.Azure) > 0 { + for iNdEx := len(m.Azure) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Azure[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } n432, err432 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) if err432 != nil { return 0, err432 @@ -50514,70 +50534,6 @@ func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Integration) i = encodeVarintTypes(dAtA, i, uint64(len(m.Integration))) i-- - dAtA[i] = 0x22 - } - if len(m.UmiClientId) > 0 { - i -= len(m.UmiClientId) - copy(dAtA[i:], m.UmiClientId) - i = encodeVarintTypes(dAtA, i, uint64(len(m.UmiClientId))) - i-- - dAtA[i] = 0x1a - } - if len(m.SubscriptionID) > 0 { - i -= len(m.SubscriptionID) - copy(dAtA[i:], m.SubscriptionID) - i = encodeVarintTypes(dAtA, i, uint64(len(m.SubscriptionID))) - i-- - dAtA[i] = 0x12 - } - if len(m.Regions) > 0 { - for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Regions[iNdEx]) - copy(dAtA[i:], m.Regions[iNdEx]) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *AccessGraphAzureSync) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AccessGraphAzureSync) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AccessGraphAzureSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if len(m.Integration) > 0 { - i -= len(m.Integration) - copy(dAtA[i:], m.Integration) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Integration))) - i-- - dAtA[i] = 0x22 - } - if len(m.UMIClientID) > 0 { - i -= len(m.UMIClientID) - copy(dAtA[i:], m.UMIClientID) - i = encodeVarintTypes(dAtA, i, uint64(len(m.UMIClientID))) - i-- dAtA[i] = 0x1a } if len(m.SubscriptionID) > 0 { @@ -61962,14 +61918,14 @@ func (m *AccessGraphSync) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval) + n += 1 + l + sovTypes(uint64(l)) if len(m.Azure) > 0 { for _, e := range m.Azure { l = e.Size() n += 1 + l + sovTypes(uint64(l)) } } - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval) - n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -62018,10 +61974,6 @@ func (m *AccessGraphAzureSync) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - l = len(m.UMIClientID) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } l = len(m.Integration) if l > 0 { n += 1 + l + sovTypes(uint64(l)) @@ -134342,7 +134294,7 @@ func (m *AccessGraphSync) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Azure", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PollInterval", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -134369,12 +134321,11 @@ func (m *AccessGraphSync) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Azure = append(m.Azure, &AccessGraphAzureSync{}) - if err := m.Azure[len(m.Azure)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.PollInterval, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Azure", wireType) } @@ -134675,38 +134626,6 @@ func (m *AccessGraphAzureSync) Unmarshal(dAtA []byte) error { m.SubscriptionID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UMIClientID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UMIClientID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Integration", wireType) } diff --git a/go.sum b/go.sum index 6a73eda617b84..eacf5605716a1 100644 --- a/go.sum +++ b/go.sum @@ -668,6 +668,8 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLC github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 h1:zDeQI/PaWztI2tcrGO/9RIMey9NvqYbnyttf/0P3QWM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q= diff --git a/integrations/event-handler/go.sum b/integrations/event-handler/go.sum index 2d1840725368c..e8410ac24cbc3 100644 --- a/integrations/event-handler/go.sum +++ b/integrations/event-handler/go.sum @@ -631,6 +631,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvUL github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 h1:zDeQI/PaWztI2tcrGO/9RIMey9NvqYbnyttf/0P3QWM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q= diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index 1b7cf7ecfecec..1bc2349420356 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -644,6 +644,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvUL github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0 h1:zDeQI/PaWztI2tcrGO/9RIMey9NvqYbnyttf/0P3QWM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.1.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q= diff --git a/lib/cloud/azure/roleassignments.go b/lib/cloud/azure/roleassignments.go index 815ce0af67e13..114bceef88b96 100644 --- a/lib/cloud/azure/roleassignments.go +++ b/lib/cloud/azure/roleassignments.go @@ -45,7 +45,7 @@ func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, // ListRoleAssignments returns role assignments for a given scope func (c *RoleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) { pager := c.cli.NewListForScopePager(scope, nil) - roleDefs := make([]*armauthorization.RoleAssignment, 0, 128) + var roleDefs []*armauthorization.RoleAssignment for pager.More() { page, err := pager.NextPage(ctx) if err != nil { diff --git a/lib/cloud/azure/roledefinitions.go b/lib/cloud/azure/roledefinitions.go index 5c56b1a38e51b..cdc46196aa530 100644 --- a/lib/cloud/azure/roledefinitions.go +++ b/lib/cloud/azure/roledefinitions.go @@ -45,7 +45,7 @@ func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, // ListRoleDefinitions returns role definitions for a given scope func (c *RoleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) { pager := c.cli.NewListPager(scope, nil) - roleDefs := make([]*armauthorization.RoleDefinition, 0, 128) + var roleDefs []*armauthorization.RoleDefinition for pager.More() { page, err := pager.NextPage(ctx) if err != nil { diff --git a/lib/srv/discovery/access_graph_azure.go b/lib/srv/discovery/access_graph_azure.go index 93896c808fbdf..73baadc1e0345 100644 --- a/lib/srv/discovery/access_graph_azure.go +++ b/lib/srv/discovery/access_graph_azure.go @@ -396,7 +396,6 @@ func (s *Server) accessGraphAzureFetchersFromMatchers( fetcherCfg := azure_sync.Config{ CloudClients: s.CloudClients, SubscriptionID: matcher.SubscriptionID, - Regions: matcher.Regions, Integration: matcher.Integration, DiscoveryConfigName: discoveryConfigName, } diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index f52a4d2255617..db5fda2cadafd 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -1745,6 +1745,14 @@ func (s *Server) upsertDynamicMatchers(ctx context.Context, dc *discoveryconfig. s.dynamicTAGAWSFetchers[dc.GetName()] = awsSyncMatchers s.muDynamicTAGAWSFetchers.Unlock() + azureSyncMatchers, err := s.accessGraphAzureFetchersFromMatchers(matchers, dc.GetName()) + if err != nil { + return trace.Wrap(err) + } + s.muDynamicTAGAzureFetchers.Lock() + s.dynamicTAGAzureFetchers[dc.GetName()] = azureSyncMatchers + s.muDynamicTAGAzureFetchers.Unlock() + kubeFetchers, err := s.kubeFetchersFromMatchers(matchers, dc.GetName()) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go index 3d7b35a4aa6b6..0002c8e7a4282 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync.go @@ -24,7 +24,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6" "github.com/gravitational/trace" "golang.org/x/sync/errgroup" @@ -41,13 +41,14 @@ const ( featNameVms = "azure/virtualmachines" ) -const FetcherConcurrency = 5 +// FetcherConcurrency is an arbitrary per-resource type concurrency to ensure significant throughput. As we increase +// the number of resource types, we may increase this value or use some other approach to fetching concurrency. +const FetcherConcurrency = 4 // Config defines parameters required for fetching resources from Azure type Config struct { CloudClients cloud.Clients SubscriptionID string - Regions []string Integration string DiscoveryConfigName string } @@ -82,9 +83,9 @@ type Fetcher struct { lastDiscoveredResources uint64 lastResult *Resources - vmClient VirtualMachinesClient - roleDefClient RoleDefinitionsClient roleAssignClient RoleAssignmentsClient + roleDefClient RoleDefinitionsClient + vmClient VirtualMachinesClient } // NewFetcher returns a new fetcher based on configuration parameters @@ -96,7 +97,7 @@ func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { } // Create the clients - vmClient, err := azure.NewVirtualMachinesClient(cfg.SubscriptionID, cred, nil) + roleAssignClient, err := azure.NewRoleAssignmentsClient(cfg.SubscriptionID, cred, nil) if err != nil { return nil, trace.Wrap(err) } @@ -104,7 +105,7 @@ func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { if err != nil { return nil, trace.Wrap(err) } - roleAssignClient, err := azure.NewRoleAssignmentsClient(cfg.SubscriptionID, cred, nil) + vmClient, err := azure.NewVirtualMachinesClient(cfg.SubscriptionID, cred, nil) if err != nil { return nil, trace.Wrap(err) } @@ -113,19 +114,18 @@ func NewFetcher(cfg Config, ctx context.Context) (*Fetcher, error) { return &Fetcher{ Config: cfg, lastResult: &Resources{}, - vmClient: vmClient, - roleDefClient: roleDefClient, roleAssignClient: roleAssignClient, + roleDefClient: roleDefClient, + vmClient: vmClient, }, nil } +// Features is a set of booleans that are received from the Access Graph to indicate which resources it can receive type Features struct { - Principals bool - RoleDefinitions bool - RoleAssignments bool - VirtualMachines bool - ManagedDatabases bool - AKSClusters bool + Principals bool + RoleDefinitions bool + RoleAssignments bool + VirtualMachines bool } // BuildFeatures builds the feature flags based on supported types returned by Access Graph Azure endpoints. @@ -133,15 +133,14 @@ func BuildFeatures(values ...string) Features { features := Features{} for _, value := range values { switch value { - case featNameVms: - features.VirtualMachines = true case featNamePrincipals: features.Principals = true - case featNameRoleDefinitions: - features.RoleDefinitions = true case featNameRoleAssignments: features.RoleAssignments = true - features.AKSClusters = true + case featNameRoleDefinitions: + features.RoleDefinitions = true + case featNameVms: + features.VirtualMachines = true } } return features @@ -153,10 +152,10 @@ func (a *Fetcher) Poll(ctx context.Context, feats Features) (*Resources, error) if res == nil { return nil, err } - res.VirtualMachines = common.DeduplicateSlice(res.VirtualMachines, azureVmKey) res.Principals = common.DeduplicateSlice(res.Principals, azurePrincipalsKey) - res.RoleDefinitions = common.DeduplicateSlice(res.RoleDefinitions, azureRoleDefKey) res.RoleAssignments = common.DeduplicateSlice(res.RoleAssignments, azureRoleAssignKey) + res.RoleDefinitions = common.DeduplicateSlice(res.RoleDefinitions, azureRoleDefKey) + res.VirtualMachines = common.DeduplicateSlice(res.VirtualMachines, azureVmKey) return res, trace.Wrap(err) } @@ -179,25 +178,25 @@ func (a *Fetcher) fetch(ctx context.Context, feats Features) (*Resources, error) return nil }) } - if feats.RoleDefinitions { + if feats.RoleAssignments { eg.Go(func() error { - roleDefs, err := a.fetchRoleDefinitions(ctx) + roleAssigns, err := a.fetchRoleAssignments(ctx) if err != nil { errsCh <- err return err } - result.RoleDefinitions = roleDefs + result.RoleAssignments = roleAssigns return nil }) } - if feats.RoleAssignments { + if feats.RoleDefinitions { eg.Go(func() error { - roleAssigns, err := a.fetchRoleAssignments(ctx) + roleDefs, err := a.fetchRoleDefinitions(ctx) if err != nil { errsCh <- err return err } - result.RoleAssignments = roleAssigns + result.RoleDefinitions = roleDefs return nil }) } diff --git a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go index 7a7b709e45b35..d5c57d06edf1e 100644 --- a/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go +++ b/lib/srv/discovery/fetchers/azure-sync/azure-sync_test.go @@ -24,7 +24,7 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v3" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6" "github.com/stretchr/testify/require" ) @@ -57,7 +57,7 @@ type testVmCli struct { vms []*armcompute.VirtualMachine } -func (t testVmCli) ListVirtualMachines(ctx context.Context, scope string) ([]*armcompute.VirtualMachine, error) { +func (t testVmCli) ListVirtualMachines(ctx context.Context, resourceGroup string) ([]*armcompute.VirtualMachine, error) { if t.returnErr { return nil, fmt.Errorf("error") } diff --git a/lib/srv/discovery/fetchers/azure-sync/reconcile.go b/lib/srv/discovery/fetchers/azure-sync/reconcile.go index 8b93020c5e8c0..2b54c8cfac911 100644 --- a/lib/srv/discovery/fetchers/azure-sync/reconcile.go +++ b/lib/srv/discovery/fetchers/azure-sync/reconcile.go @@ -38,14 +38,14 @@ func MergeResources(results ...*Resources) *Resources { result := &Resources{} for _, r := range results { result.Principals = append(result.Principals, r.Principals...) - result.VirtualMachines = append(result.VirtualMachines, r.VirtualMachines...) - result.RoleDefinitions = append(result.RoleDefinitions, r.RoleDefinitions...) result.RoleAssignments = append(result.RoleAssignments, r.RoleAssignments...) + result.RoleDefinitions = append(result.RoleDefinitions, r.RoleDefinitions...) + result.VirtualMachines = append(result.VirtualMachines, r.VirtualMachines...) } result.Principals = common.DeduplicateSlice(result.Principals, azurePrincipalsKey) - result.VirtualMachines = common.DeduplicateSlice(result.VirtualMachines, azureVmKey) - result.RoleDefinitions = common.DeduplicateSlice(result.RoleDefinitions, azureRoleDefKey) result.RoleAssignments = common.DeduplicateSlice(result.RoleAssignments, azureRoleAssignKey) + result.RoleDefinitions = common.DeduplicateSlice(result.RoleDefinitions, azureRoleDefKey) + result.VirtualMachines = common.DeduplicateSlice(result.VirtualMachines, azureVmKey) return result } @@ -61,10 +61,10 @@ func newResourceList() *accessgraphv1alpha.AzureResourceList { func ReconcileResults(old *Resources, new *Resources) (upsert, delete *accessgraphv1alpha.AzureResourceList) { upsert, delete = newResourceList(), newResourceList() reconciledResources := []*reconcilePair{ - reconcile(old.VirtualMachines, new.VirtualMachines, azureVmKey, azureVmWrap), reconcile(old.Principals, new.Principals, azurePrincipalsKey, azurePrincipalsWrap), - reconcile(old.RoleDefinitions, new.RoleDefinitions, azureRoleDefKey, azureRoleDefWrap), reconcile(old.RoleAssignments, new.RoleAssignments, azureRoleAssignKey, azureRoleAssignWrap), + reconcile(old.RoleDefinitions, new.RoleDefinitions, azureRoleDefKey, azureRoleDefWrap), + reconcile(old.VirtualMachines, new.VirtualMachines, azureVmKey, azureVmWrap), } for _, res := range reconciledResources { upsert.Resources = append(upsert.Resources, res.upsert.Resources...) @@ -132,14 +132,6 @@ func reconcile[T proto.Message]( return &reconcilePair{upsertRes, deleteRes} } -func azureVmKey(vm *accessgraphv1alpha.AzureVirtualMachine) string { - return fmt.Sprintf("%s:%s", vm.SubscriptionId, vm.Id) -} - -func azureVmWrap(vm *accessgraphv1alpha.AzureVirtualMachine) *accessgraphv1alpha.AzureResource { - return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_VirtualMachine{VirtualMachine: vm}} -} - func azurePrincipalsKey(user *accessgraphv1alpha.AzurePrincipal) string { return fmt.Sprintf("%s:%s", user.SubscriptionId, user.Id) } @@ -148,6 +140,14 @@ func azurePrincipalsWrap(principal *accessgraphv1alpha.AzurePrincipal) *accessgr return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_Principal{Principal: principal}} } +func azureRoleAssignKey(roleAssign *accessgraphv1alpha.AzureRoleAssignment) string { + return fmt.Sprintf("%s:%s", roleAssign.SubscriptionId, roleAssign.Id) +} + +func azureRoleAssignWrap(roleAssign *accessgraphv1alpha.AzureRoleAssignment) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_RoleAssignment{RoleAssignment: roleAssign}} +} + func azureRoleDefKey(roleDef *accessgraphv1alpha.AzureRoleDefinition) string { return fmt.Sprintf("%s:%s", roleDef.SubscriptionId, roleDef.Id) } @@ -156,10 +156,10 @@ func azureRoleDefWrap(roleDef *accessgraphv1alpha.AzureRoleDefinition) *accessgr return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_RoleDefinition{RoleDefinition: roleDef}} } -func azureRoleAssignKey(roleAssign *accessgraphv1alpha.AzureRoleAssignment) string { - return fmt.Sprintf("%s:%s", roleAssign.SubscriptionId, roleAssign.Id) +func azureVmKey(vm *accessgraphv1alpha.AzureVirtualMachine) string { + return fmt.Sprintf("%s:%s", vm.SubscriptionId, vm.Id) } -func azureRoleAssignWrap(roleAssign *accessgraphv1alpha.AzureRoleAssignment) *accessgraphv1alpha.AzureResource { - return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_RoleAssignment{RoleAssignment: roleAssign}} +func azureVmWrap(vm *accessgraphv1alpha.AzureVirtualMachine) *accessgraphv1alpha.AzureResource { + return &accessgraphv1alpha.AzureResource{Resource: &accessgraphv1alpha.AzureResource_VirtualMachine{VirtualMachine: vm}} } diff --git a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go index f681444ccb820..1dbb254fc976c 100644 --- a/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go +++ b/lib/srv/discovery/fetchers/azure-sync/virtualmachines.go @@ -27,8 +27,10 @@ import ( accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" ) +const allResourceGroups = "*" + func (a *Fetcher) fetchVirtualMachines(ctx context.Context) ([]*accessgraphv1alpha.AzureVirtualMachine, error) { - vms, err := a.vmClient.ListVirtualMachines(ctx, "*") + vms, err := a.vmClient.ListVirtualMachines(ctx, allResourceGroups) if err != nil { return nil, trace.Wrap(err) }