mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-05 14:46:12 +02:00
feat: allow reader access to join token
Explicitly allow readers to read join tokens Signed-off-by: Edward Sammut Alessi <edward.sammutalessi@siderolabs.com>
This commit is contained in:
parent
f221168823
commit
be67f710f8
@ -196,6 +196,10 @@ type PermissionsSpec struct {
|
||||
CanManageBackupStore bool `protobuf:"varint,11,opt,name=can_manage_backup_store,json=canManageBackupStore,proto3" json:"can_manage_backup_store,omitempty"`
|
||||
CanAccessMaintenanceNodes bool `protobuf:"varint,12,opt,name=can_access_maintenance_nodes,json=canAccessMaintenanceNodes,proto3" json:"can_access_maintenance_nodes,omitempty"`
|
||||
CanReadAuditLog bool `protobuf:"varint,13,opt,name=can_read_audit_log,json=canReadAuditLog,proto3" json:"can_read_audit_log,omitempty"`
|
||||
CanReadJoinTokens bool `protobuf:"varint,14,opt,name=can_read_join_tokens,json=canReadJoinTokens,proto3" json:"can_read_join_tokens,omitempty"`
|
||||
CanManageJoinTokens bool `protobuf:"varint,15,opt,name=can_manage_join_tokens,json=canManageJoinTokens,proto3" json:"can_manage_join_tokens,omitempty"`
|
||||
CanReadInstallationMedia bool `protobuf:"varint,16,opt,name=can_read_installation_media,json=canReadInstallationMedia,proto3" json:"can_read_installation_media,omitempty"`
|
||||
CanManageInstallationMedia bool `protobuf:"varint,17,opt,name=can_manage_installation_media,json=canManageInstallationMedia,proto3" json:"can_manage_installation_media,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -307,22 +311,55 @@ func (x *PermissionsSpec) GetCanReadAuditLog() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PermissionsSpec) GetCanReadJoinTokens() bool {
|
||||
if x != nil {
|
||||
return x.CanReadJoinTokens
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PermissionsSpec) GetCanManageJoinTokens() bool {
|
||||
if x != nil {
|
||||
return x.CanManageJoinTokens
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PermissionsSpec) GetCanReadInstallationMedia() bool {
|
||||
if x != nil {
|
||||
return x.CanReadInstallationMedia
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PermissionsSpec) GetCanManageInstallationMedia() bool {
|
||||
if x != nil {
|
||||
return x.CanManageInstallationMedia
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ClusterPermissionsSpec struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
CanAddMachines bool `protobuf:"varint,1,opt,name=can_add_machines,json=canAddMachines,proto3" json:"can_add_machines,omitempty"`
|
||||
CanRemoveMachines bool `protobuf:"varint,2,opt,name=can_remove_machines,json=canRemoveMachines,proto3" json:"can_remove_machines,omitempty"`
|
||||
CanRebootMachines bool `protobuf:"varint,3,opt,name=can_reboot_machines,json=canRebootMachines,proto3" json:"can_reboot_machines,omitempty"`
|
||||
CanUpdateKubernetes bool `protobuf:"varint,4,opt,name=can_update_kubernetes,json=canUpdateKubernetes,proto3" json:"can_update_kubernetes,omitempty"`
|
||||
CanDownloadKubeconfig bool `protobuf:"varint,5,opt,name=can_download_kubeconfig,json=canDownloadKubeconfig,proto3" json:"can_download_kubeconfig,omitempty"`
|
||||
CanSyncKubernetesManifests bool `protobuf:"varint,6,opt,name=can_sync_kubernetes_manifests,json=canSyncKubernetesManifests,proto3" json:"can_sync_kubernetes_manifests,omitempty"`
|
||||
CanUpdateTalos bool `protobuf:"varint,7,opt,name=can_update_talos,json=canUpdateTalos,proto3" json:"can_update_talos,omitempty"`
|
||||
CanDownloadTalosconfig bool `protobuf:"varint,8,opt,name=can_download_talosconfig,json=canDownloadTalosconfig,proto3" json:"can_download_talosconfig,omitempty"`
|
||||
CanReadConfigPatches bool `protobuf:"varint,9,opt,name=can_read_config_patches,json=canReadConfigPatches,proto3" json:"can_read_config_patches,omitempty"`
|
||||
CanManageConfigPatches bool `protobuf:"varint,10,opt,name=can_manage_config_patches,json=canManageConfigPatches,proto3" json:"can_manage_config_patches,omitempty"`
|
||||
CanManageClusterFeatures bool `protobuf:"varint,11,opt,name=can_manage_cluster_features,json=canManageClusterFeatures,proto3" json:"can_manage_cluster_features,omitempty"`
|
||||
CanDownloadSupportBundle bool `protobuf:"varint,12,opt,name=can_download_support_bundle,json=canDownloadSupportBundle,proto3" json:"can_download_support_bundle,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
CanAddMachines bool `protobuf:"varint,1,opt,name=can_add_machines,json=canAddMachines,proto3" json:"can_add_machines,omitempty"`
|
||||
CanRemoveMachines bool `protobuf:"varint,2,opt,name=can_remove_machines,json=canRemoveMachines,proto3" json:"can_remove_machines,omitempty"`
|
||||
CanRebootMachines bool `protobuf:"varint,3,opt,name=can_reboot_machines,json=canRebootMachines,proto3" json:"can_reboot_machines,omitempty"`
|
||||
CanUpdateKubernetes bool `protobuf:"varint,4,opt,name=can_update_kubernetes,json=canUpdateKubernetes,proto3" json:"can_update_kubernetes,omitempty"`
|
||||
CanDownloadKubeconfig bool `protobuf:"varint,5,opt,name=can_download_kubeconfig,json=canDownloadKubeconfig,proto3" json:"can_download_kubeconfig,omitempty"`
|
||||
CanSyncKubernetesManifests bool `protobuf:"varint,6,opt,name=can_sync_kubernetes_manifests,json=canSyncKubernetesManifests,proto3" json:"can_sync_kubernetes_manifests,omitempty"`
|
||||
CanUpdateTalos bool `protobuf:"varint,7,opt,name=can_update_talos,json=canUpdateTalos,proto3" json:"can_update_talos,omitempty"`
|
||||
CanDownloadTalosconfig bool `protobuf:"varint,8,opt,name=can_download_talosconfig,json=canDownloadTalosconfig,proto3" json:"can_download_talosconfig,omitempty"`
|
||||
CanReadConfigPatches bool `protobuf:"varint,9,opt,name=can_read_config_patches,json=canReadConfigPatches,proto3" json:"can_read_config_patches,omitempty"`
|
||||
CanManageConfigPatches bool `protobuf:"varint,10,opt,name=can_manage_config_patches,json=canManageConfigPatches,proto3" json:"can_manage_config_patches,omitempty"`
|
||||
CanManageClusterFeatures bool `protobuf:"varint,11,opt,name=can_manage_cluster_features,json=canManageClusterFeatures,proto3" json:"can_manage_cluster_features,omitempty"`
|
||||
CanDownloadSupportBundle bool `protobuf:"varint,12,opt,name=can_download_support_bundle,json=canDownloadSupportBundle,proto3" json:"can_download_support_bundle,omitempty"`
|
||||
CanReadMachineConfig bool `protobuf:"varint,13,opt,name=can_read_machine_config,json=canReadMachineConfig,proto3" json:"can_read_machine_config,omitempty"`
|
||||
CanManageMachineConfig bool `protobuf:"varint,14,opt,name=can_manage_machine_config,json=canManageMachineConfig,proto3" json:"can_manage_machine_config,omitempty"`
|
||||
CanReadKernelArgs bool `protobuf:"varint,15,opt,name=can_read_kernel_args,json=canReadKernelArgs,proto3" json:"can_read_kernel_args,omitempty"`
|
||||
CanManageKernelArgs bool `protobuf:"varint,16,opt,name=can_manage_kernel_args,json=canManageKernelArgs,proto3" json:"can_manage_kernel_args,omitempty"`
|
||||
CanReadMachinePendingUpdates bool `protobuf:"varint,17,opt,name=can_read_machine_pending_updates,json=canReadMachinePendingUpdates,proto3" json:"can_read_machine_pending_updates,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) Reset() {
|
||||
@ -439,6 +476,41 @@ func (x *ClusterPermissionsSpec) GetCanDownloadSupportBundle() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) GetCanReadMachineConfig() bool {
|
||||
if x != nil {
|
||||
return x.CanReadMachineConfig
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) GetCanManageMachineConfig() bool {
|
||||
if x != nil {
|
||||
return x.CanManageMachineConfig
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) GetCanReadKernelArgs() bool {
|
||||
if x != nil {
|
||||
return x.CanReadKernelArgs
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) GetCanManageKernelArgs() bool {
|
||||
if x != nil {
|
||||
return x.CanManageKernelArgs
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClusterPermissionsSpec) GetCanReadMachinePendingUpdates() bool {
|
||||
if x != nil {
|
||||
return x.CanReadMachinePendingUpdates
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type LabelsCompletionSpec struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Items map[string]*LabelsCompletionSpec_Values `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
@ -755,7 +827,7 @@ const file_omni_specs_virtual_proto_rawDesc = "" +
|
||||
"\x0fCurrentUserSpec\x12\x1a\n" +
|
||||
"\bidentity\x18\x01 \x01(\tR\bidentity\x12\x12\n" +
|
||||
"\x04role\x18\x03 \x01(\tR\x04role\x12\x17\n" +
|
||||
"\auser_id\x18\x04 \x01(\tR\x06userIdJ\x04\b\x02\x10\x03\"\xdb\x04\n" +
|
||||
"\auser_id\x18\x04 \x01(\tR\x06userIdJ\x04\b\x02\x10\x03\"\xc3\x06\n" +
|
||||
"\x0fPermissionsSpec\x12*\n" +
|
||||
"\x11can_read_clusters\x18\x01 \x01(\bR\x0fcanReadClusters\x12.\n" +
|
||||
"\x13can_create_clusters\x18\x02 \x01(\bR\x11canCreateClusters\x12(\n" +
|
||||
@ -768,7 +840,11 @@ const file_omni_specs_virtual_proto_rawDesc = "" +
|
||||
" \x01(\bR\x1dcanManageMachineConfigPatches\x125\n" +
|
||||
"\x17can_manage_backup_store\x18\v \x01(\bR\x14canManageBackupStore\x12?\n" +
|
||||
"\x1ccan_access_maintenance_nodes\x18\f \x01(\bR\x19canAccessMaintenanceNodes\x12+\n" +
|
||||
"\x12can_read_audit_log\x18\r \x01(\bR\x0fcanReadAuditLog\"\xa5\x05\n" +
|
||||
"\x12can_read_audit_log\x18\r \x01(\bR\x0fcanReadAuditLog\x12/\n" +
|
||||
"\x14can_read_join_tokens\x18\x0e \x01(\bR\x11canReadJoinTokens\x123\n" +
|
||||
"\x16can_manage_join_tokens\x18\x0f \x01(\bR\x13canManageJoinTokens\x12=\n" +
|
||||
"\x1bcan_read_installation_media\x18\x10 \x01(\bR\x18canReadInstallationMedia\x12A\n" +
|
||||
"\x1dcan_manage_installation_media\x18\x11 \x01(\bR\x1acanManageInstallationMedia\"\xc5\a\n" +
|
||||
"\x16ClusterPermissionsSpec\x12(\n" +
|
||||
"\x10can_add_machines\x18\x01 \x01(\bR\x0ecanAddMachines\x12.\n" +
|
||||
"\x13can_remove_machines\x18\x02 \x01(\bR\x11canRemoveMachines\x12.\n" +
|
||||
@ -782,7 +858,12 @@ const file_omni_specs_virtual_proto_rawDesc = "" +
|
||||
"\x19can_manage_config_patches\x18\n" +
|
||||
" \x01(\bR\x16canManageConfigPatches\x12=\n" +
|
||||
"\x1bcan_manage_cluster_features\x18\v \x01(\bR\x18canManageClusterFeatures\x12=\n" +
|
||||
"\x1bcan_download_support_bundle\x18\f \x01(\bR\x18canDownloadSupportBundle\"\xd2\x01\n" +
|
||||
"\x1bcan_download_support_bundle\x18\f \x01(\bR\x18canDownloadSupportBundle\x125\n" +
|
||||
"\x17can_read_machine_config\x18\r \x01(\bR\x14canReadMachineConfig\x129\n" +
|
||||
"\x19can_manage_machine_config\x18\x0e \x01(\bR\x16canManageMachineConfig\x12/\n" +
|
||||
"\x14can_read_kernel_args\x18\x0f \x01(\bR\x11canReadKernelArgs\x123\n" +
|
||||
"\x16can_manage_kernel_args\x18\x10 \x01(\bR\x13canManageKernelArgs\x12F\n" +
|
||||
" can_read_machine_pending_updates\x18\x11 \x01(\bR\x1ccanReadMachinePendingUpdates\"\xd2\x01\n" +
|
||||
"\x14LabelsCompletionSpec\x12<\n" +
|
||||
"\x05items\x18\x01 \x03(\v2&.specs.LabelsCompletionSpec.ItemsEntryR\x05items\x1a\x1e\n" +
|
||||
"\x06Values\x12\x14\n" +
|
||||
|
||||
@ -22,6 +22,10 @@ message PermissionsSpec {
|
||||
bool can_manage_backup_store = 11;
|
||||
bool can_access_maintenance_nodes = 12;
|
||||
bool can_read_audit_log = 13;
|
||||
bool can_read_join_tokens = 14;
|
||||
bool can_manage_join_tokens = 15;
|
||||
bool can_read_installation_media = 16;
|
||||
bool can_manage_installation_media = 17;
|
||||
}
|
||||
|
||||
message ClusterPermissionsSpec {
|
||||
@ -37,6 +41,11 @@ message ClusterPermissionsSpec {
|
||||
bool can_manage_config_patches = 10;
|
||||
bool can_manage_cluster_features = 11;
|
||||
bool can_download_support_bundle = 12;
|
||||
bool can_read_machine_config = 13;
|
||||
bool can_manage_machine_config = 14;
|
||||
bool can_read_kernel_args = 15;
|
||||
bool can_manage_kernel_args = 16;
|
||||
bool can_read_machine_pending_updates = 17;
|
||||
}
|
||||
|
||||
message LabelsCompletionSpec {
|
||||
|
||||
@ -55,6 +55,10 @@ func (m *PermissionsSpec) CloneVT() *PermissionsSpec {
|
||||
r.CanManageBackupStore = m.CanManageBackupStore
|
||||
r.CanAccessMaintenanceNodes = m.CanAccessMaintenanceNodes
|
||||
r.CanReadAuditLog = m.CanReadAuditLog
|
||||
r.CanReadJoinTokens = m.CanReadJoinTokens
|
||||
r.CanManageJoinTokens = m.CanManageJoinTokens
|
||||
r.CanReadInstallationMedia = m.CanReadInstallationMedia
|
||||
r.CanManageInstallationMedia = m.CanManageInstallationMedia
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
@ -83,6 +87,11 @@ func (m *ClusterPermissionsSpec) CloneVT() *ClusterPermissionsSpec {
|
||||
r.CanManageConfigPatches = m.CanManageConfigPatches
|
||||
r.CanManageClusterFeatures = m.CanManageClusterFeatures
|
||||
r.CanDownloadSupportBundle = m.CanDownloadSupportBundle
|
||||
r.CanReadMachineConfig = m.CanReadMachineConfig
|
||||
r.CanManageMachineConfig = m.CanManageMachineConfig
|
||||
r.CanReadKernelArgs = m.CanReadKernelArgs
|
||||
r.CanManageKernelArgs = m.CanManageKernelArgs
|
||||
r.CanReadMachinePendingUpdates = m.CanReadMachinePendingUpdates
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
@ -272,6 +281,18 @@ func (this *PermissionsSpec) EqualVT(that *PermissionsSpec) bool {
|
||||
if this.CanReadAuditLog != that.CanReadAuditLog {
|
||||
return false
|
||||
}
|
||||
if this.CanReadJoinTokens != that.CanReadJoinTokens {
|
||||
return false
|
||||
}
|
||||
if this.CanManageJoinTokens != that.CanManageJoinTokens {
|
||||
return false
|
||||
}
|
||||
if this.CanReadInstallationMedia != that.CanReadInstallationMedia {
|
||||
return false
|
||||
}
|
||||
if this.CanManageInstallationMedia != that.CanManageInstallationMedia {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
@ -324,6 +345,21 @@ func (this *ClusterPermissionsSpec) EqualVT(that *ClusterPermissionsSpec) bool {
|
||||
if this.CanDownloadSupportBundle != that.CanDownloadSupportBundle {
|
||||
return false
|
||||
}
|
||||
if this.CanReadMachineConfig != that.CanReadMachineConfig {
|
||||
return false
|
||||
}
|
||||
if this.CanManageMachineConfig != that.CanManageMachineConfig {
|
||||
return false
|
||||
}
|
||||
if this.CanReadKernelArgs != that.CanReadKernelArgs {
|
||||
return false
|
||||
}
|
||||
if this.CanManageKernelArgs != that.CanManageKernelArgs {
|
||||
return false
|
||||
}
|
||||
if this.CanReadMachinePendingUpdates != that.CanReadMachinePendingUpdates {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
@ -581,6 +617,50 @@ func (m *PermissionsSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if m.CanManageInstallationMedia {
|
||||
i--
|
||||
if m.CanManageInstallationMedia {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1
|
||||
i--
|
||||
dAtA[i] = 0x88
|
||||
}
|
||||
if m.CanReadInstallationMedia {
|
||||
i--
|
||||
if m.CanReadInstallationMedia {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1
|
||||
i--
|
||||
dAtA[i] = 0x80
|
||||
}
|
||||
if m.CanManageJoinTokens {
|
||||
i--
|
||||
if m.CanManageJoinTokens {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x78
|
||||
}
|
||||
if m.CanReadJoinTokens {
|
||||
i--
|
||||
if m.CanReadJoinTokens {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x70
|
||||
}
|
||||
if m.CanReadAuditLog {
|
||||
i--
|
||||
if m.CanReadAuditLog {
|
||||
@ -724,6 +804,60 @@ func (m *ClusterPermissionsSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if m.CanReadMachinePendingUpdates {
|
||||
i--
|
||||
if m.CanReadMachinePendingUpdates {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1
|
||||
i--
|
||||
dAtA[i] = 0x88
|
||||
}
|
||||
if m.CanManageKernelArgs {
|
||||
i--
|
||||
if m.CanManageKernelArgs {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1
|
||||
i--
|
||||
dAtA[i] = 0x80
|
||||
}
|
||||
if m.CanReadKernelArgs {
|
||||
i--
|
||||
if m.CanReadKernelArgs {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x78
|
||||
}
|
||||
if m.CanManageMachineConfig {
|
||||
i--
|
||||
if m.CanManageMachineConfig {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x70
|
||||
}
|
||||
if m.CanReadMachineConfig {
|
||||
i--
|
||||
if m.CanReadMachineConfig {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x68
|
||||
}
|
||||
if m.CanDownloadSupportBundle {
|
||||
i--
|
||||
if m.CanDownloadSupportBundle {
|
||||
@ -1233,6 +1367,18 @@ func (m *PermissionsSpec) SizeVT() (n int) {
|
||||
if m.CanReadAuditLog {
|
||||
n += 2
|
||||
}
|
||||
if m.CanReadJoinTokens {
|
||||
n += 2
|
||||
}
|
||||
if m.CanManageJoinTokens {
|
||||
n += 2
|
||||
}
|
||||
if m.CanReadInstallationMedia {
|
||||
n += 3
|
||||
}
|
||||
if m.CanManageInstallationMedia {
|
||||
n += 3
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
@ -1279,6 +1425,21 @@ func (m *ClusterPermissionsSpec) SizeVT() (n int) {
|
||||
if m.CanDownloadSupportBundle {
|
||||
n += 2
|
||||
}
|
||||
if m.CanReadMachineConfig {
|
||||
n += 2
|
||||
}
|
||||
if m.CanManageMachineConfig {
|
||||
n += 2
|
||||
}
|
||||
if m.CanReadKernelArgs {
|
||||
n += 2
|
||||
}
|
||||
if m.CanManageKernelArgs {
|
||||
n += 3
|
||||
}
|
||||
if m.CanReadMachinePendingUpdates {
|
||||
n += 3
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
@ -1809,6 +1970,86 @@ func (m *PermissionsSpec) UnmarshalVT(dAtA []byte) error {
|
||||
}
|
||||
}
|
||||
m.CanReadAuditLog = bool(v != 0)
|
||||
case 14:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanReadJoinTokens", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanReadJoinTokens = bool(v != 0)
|
||||
case 15:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanManageJoinTokens", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanManageJoinTokens = bool(v != 0)
|
||||
case 16:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanReadInstallationMedia", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanReadInstallationMedia = bool(v != 0)
|
||||
case 17:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanManageInstallationMedia", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanManageInstallationMedia = bool(v != 0)
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
@ -2100,6 +2341,106 @@ func (m *ClusterPermissionsSpec) UnmarshalVT(dAtA []byte) error {
|
||||
}
|
||||
}
|
||||
m.CanDownloadSupportBundle = bool(v != 0)
|
||||
case 13:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanReadMachineConfig", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanReadMachineConfig = bool(v != 0)
|
||||
case 14:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanManageMachineConfig", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanManageMachineConfig = bool(v != 0)
|
||||
case 15:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanReadKernelArgs", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanReadKernelArgs = bool(v != 0)
|
||||
case 16:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanManageKernelArgs", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanManageKernelArgs = bool(v != 0)
|
||||
case 17:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CanReadMachinePendingUpdates", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.CanReadMachinePendingUpdates = bool(v != 0)
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
|
||||
@ -103,11 +103,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/Tabs/TabButton.vue": {
|
||||
"vue/define-props-destructuring": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/Tabs/TabContent.vue": {
|
||||
"vue/define-props-destructuring": {
|
||||
"count": 1
|
||||
|
||||
@ -35,6 +35,10 @@ export type PermissionsSpec = {
|
||||
can_manage_backup_store?: boolean
|
||||
can_access_maintenance_nodes?: boolean
|
||||
can_read_audit_log?: boolean
|
||||
can_read_join_tokens?: boolean
|
||||
can_manage_join_tokens?: boolean
|
||||
can_read_installation_media?: boolean
|
||||
can_manage_installation_media?: boolean
|
||||
}
|
||||
|
||||
export type ClusterPermissionsSpec = {
|
||||
@ -50,6 +54,11 @@ export type ClusterPermissionsSpec = {
|
||||
can_manage_config_patches?: boolean
|
||||
can_manage_cluster_features?: boolean
|
||||
can_download_support_bundle?: boolean
|
||||
can_read_machine_config?: boolean
|
||||
can_manage_machine_config?: boolean
|
||||
can_read_kernel_args?: boolean
|
||||
can_manage_kernel_args?: boolean
|
||||
can_read_machine_pending_updates?: boolean
|
||||
}
|
||||
|
||||
export type LabelsCompletionSpecValues = {
|
||||
|
||||
@ -7,6 +7,7 @@ included in the LICENSE file.
|
||||
<script setup lang="ts">
|
||||
import { TabsTrigger, type TabsTriggerProps, useForwardPropsEmits } from 'reka-ui'
|
||||
|
||||
// eslint-disable-next-line vue/define-props-destructuring
|
||||
const props = defineProps<TabsTriggerProps>()
|
||||
const forwarded = useForwardPropsEmits(props)
|
||||
</script>
|
||||
@ -14,7 +15,8 @@ const forwarded = useForwardPropsEmits(props)
|
||||
<template>
|
||||
<TabsTrigger
|
||||
v-bind="forwarded"
|
||||
class="text-sm transition-colors hover:text-naturals-n13 data-[state=active]:text-naturals-n13"
|
||||
:as="disabled ? 'button' : as"
|
||||
class="text-sm transition-colors not-data-disabled:hover:text-naturals-n13 data-disabled:cursor-not-allowed data-disabled:opacity-75 data-[state=active]:text-naturals-n13"
|
||||
>
|
||||
<slot></slot>
|
||||
</TabsTrigger>
|
||||
|
||||
@ -79,6 +79,10 @@ const permissions = authScope.run(() => {
|
||||
canReadMachineLogs: computed(() => spec.value?.can_read_machine_logs ?? false),
|
||||
canReadMachines: computed(() => spec.value?.can_read_machines ?? false),
|
||||
canRemoveMachines: computed(() => spec.value?.can_remove_machines ?? false),
|
||||
canReadJoinTokens: computed(() => spec.value?.can_read_join_tokens ?? false),
|
||||
canManageJoinTokens: computed(() => spec.value?.can_manage_join_tokens ?? false),
|
||||
canReadInstallationMedia: computed(() => spec.value?.can_read_installation_media ?? false),
|
||||
canManageInstallationMedia: computed(() => spec.value?.can_manage_installation_media ?? false),
|
||||
}
|
||||
})!
|
||||
|
||||
@ -129,6 +133,13 @@ export function useClusterPermissions(cluster: MaybeRefOrGetter<string | undefin
|
||||
canRebootMachines: computed(() => spec.value?.can_reboot_machines ?? false),
|
||||
canRemoveMachines: computed(() => spec.value?.can_remove_machines ?? false),
|
||||
canManageClusterFeatures: computed(() => spec.value?.can_manage_cluster_features ?? false),
|
||||
canReadMachineConfig: computed(() => spec.value?.can_read_machine_config ?? false),
|
||||
canManageMachineConfig: computed(() => spec.value?.can_manage_machine_config ?? false),
|
||||
canReadKernelArgs: computed(() => spec.value?.can_read_kernel_args ?? false),
|
||||
canManageKernelArgs: computed(() => spec.value?.can_manage_kernel_args ?? false),
|
||||
canReadMachinePendingUpdates: computed(
|
||||
() => spec.value?.can_read_machine_pending_updates ?? false,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,13 +14,16 @@ import { DefaultNamespace, MachineStatusType } from '@/api/resources'
|
||||
import TabButton from '@/components/Tabs/TabButton.vue'
|
||||
import TabContent from '@/components/Tabs/TabContent.vue'
|
||||
import Tabs from '@/components/Tabs/Tabs.vue'
|
||||
import { useClusterPermissions } from '@/methods/auth'
|
||||
import { useResourceGet } from '@/methods/useResourceGet'
|
||||
import NodesHeader from '@/views/Nodes/NodesHeader.vue'
|
||||
|
||||
definePage({ name: 'NodeDetails' })
|
||||
|
||||
const route = useRoute()
|
||||
const machine = computed(() => route.params.machine as string)
|
||||
const machine = computed(() => route.params.machine)
|
||||
const { canReadMachineConfig, canReadConfigPatches, canReadMachinePendingUpdates } =
|
||||
useClusterPermissions(() => route.params.cluster)
|
||||
|
||||
const routes = computed(() => {
|
||||
return [
|
||||
@ -39,18 +42,22 @@ const routes = computed(() => {
|
||||
{
|
||||
name: 'Config',
|
||||
to: { name: 'NodeConfig', params: { machine: machine.value } },
|
||||
disabled: !canReadMachineConfig.value,
|
||||
},
|
||||
{
|
||||
name: 'Pending Updates',
|
||||
to: { name: 'NodePendingUpdates', params: { machine: machine.value } },
|
||||
disabled: !canReadMachinePendingUpdates.value,
|
||||
},
|
||||
{
|
||||
name: 'Config History',
|
||||
to: { name: 'NodeConfigDiffs', params: { machine: machine.value } },
|
||||
disabled: !canReadMachineConfig.value,
|
||||
},
|
||||
{
|
||||
name: 'Patches',
|
||||
to: { name: 'NodePatches', params: { machine: machine.value } },
|
||||
disabled: !canReadConfigPatches.value,
|
||||
},
|
||||
{
|
||||
name: 'Disks',
|
||||
@ -96,7 +103,14 @@ const nodeName = computed(
|
||||
tabs-list-class="px-4 md:px-6"
|
||||
>
|
||||
<template #triggers>
|
||||
<TabButton v-for="{ name, to } in routes" :key="name" :as="RouterLink" :value="to.name" :to>
|
||||
<TabButton
|
||||
v-for="{ name, to, disabled } in routes"
|
||||
:key="name"
|
||||
:as="RouterLink"
|
||||
:value="to.name"
|
||||
:to
|
||||
:disabled
|
||||
>
|
||||
{{ name }}
|
||||
</TabButton>
|
||||
</template>
|
||||
|
||||
@ -15,6 +15,7 @@ import PageHeader from '@/components/PageHeader.vue'
|
||||
import TabButton from '@/components/Tabs/TabButton.vue'
|
||||
import TabContent from '@/components/Tabs/TabContent.vue'
|
||||
import Tabs from '@/components/Tabs/Tabs.vue'
|
||||
import { usePermissions } from '@/methods/auth'
|
||||
import { useResourceGet } from '@/methods/useResourceGet'
|
||||
|
||||
definePage({
|
||||
@ -24,6 +25,8 @@ definePage({
|
||||
},
|
||||
})
|
||||
|
||||
const { canReadMachineConfigPatches } = usePermissions()
|
||||
|
||||
const routes = computed(() => {
|
||||
return [
|
||||
{
|
||||
@ -33,6 +36,7 @@ const routes = computed(() => {
|
||||
{
|
||||
name: 'Patches',
|
||||
to: { name: 'MachineConfigPatches' },
|
||||
disabled: !canReadMachineConfigPatches.value,
|
||||
},
|
||||
]
|
||||
})
|
||||
@ -73,7 +77,14 @@ const hasMatchingTab = computed(() =>
|
||||
tabs-list-class="px-4 md:px-6"
|
||||
>
|
||||
<template #triggers>
|
||||
<TabButton v-for="{ name, to } in routes" :key="name" :as="RouterLink" :value="to.name" :to>
|
||||
<TabButton
|
||||
v-for="{ name, to, disabled } in routes"
|
||||
:key="name"
|
||||
:as="RouterLink"
|
||||
:value="to.name"
|
||||
:to
|
||||
:disabled
|
||||
>
|
||||
{{ name }}
|
||||
</TabButton>
|
||||
</template>
|
||||
|
||||
@ -38,7 +38,7 @@ definePage({ name: 'JoinTokens' })
|
||||
|
||||
const router = useRouter()
|
||||
const { copy } = useClipboard()
|
||||
const { canManageUsers } = usePermissions()
|
||||
const { canManageJoinTokens, canReadJoinTokens } = usePermissions()
|
||||
|
||||
const showTokens = ref(false)
|
||||
|
||||
@ -129,7 +129,7 @@ const openDeleteToken = (token: string) => {
|
||||
icon="plus"
|
||||
icon-position="left"
|
||||
variant="highlighted"
|
||||
:disabled="!canManageUsers"
|
||||
:disabled="!canManageJoinTokens"
|
||||
@click="openUserCreate"
|
||||
>
|
||||
Create Join Token
|
||||
@ -175,14 +175,23 @@ const openDeleteToken = (token: string) => {
|
||||
</div>
|
||||
<TActionsBox>
|
||||
<template v-if="item.spec.state === JoinTokenStatusSpecState.ACTIVE">
|
||||
<TActionsBoxItem icon="copy" @select="() => copyValue(item.metadata.id!)">
|
||||
<TActionsBoxItem
|
||||
icon="copy"
|
||||
:disabled="!canReadJoinTokens"
|
||||
@select="() => copyValue(item.metadata.id!)"
|
||||
>
|
||||
Copy Token
|
||||
</TActionsBoxItem>
|
||||
<TActionsBoxItem icon="copy" @select="() => copyKernelParams(item.metadata.id!)">
|
||||
<TActionsBoxItem
|
||||
icon="copy"
|
||||
:disabled="!canReadJoinTokens"
|
||||
@select="() => copyKernelParams(item.metadata.id!)"
|
||||
>
|
||||
Copy Kernel Params
|
||||
</TActionsBoxItem>
|
||||
<TActionsBoxItem
|
||||
icon="long-arrow-down"
|
||||
:disabled="!canReadJoinTokens"
|
||||
@select="() => getMachineJoinConfig(item.metadata.id!)"
|
||||
>
|
||||
Download Machine Join Config
|
||||
@ -191,6 +200,7 @@ const openDeleteToken = (token: string) => {
|
||||
<TActionsBoxItem
|
||||
v-if="!item.spec.is_default"
|
||||
icon="check"
|
||||
:disabled="!canManageJoinTokens"
|
||||
@select="() => makeDefault(item.metadata.id!)"
|
||||
>
|
||||
Make Default
|
||||
@ -199,18 +209,24 @@ const openDeleteToken = (token: string) => {
|
||||
<TActionsBoxItem
|
||||
icon="error"
|
||||
danger
|
||||
:disabled="!canManageJoinTokens"
|
||||
@select="() => openRevokeToken(item.metadata.id!)"
|
||||
>
|
||||
Revoke
|
||||
</TActionsBoxItem>
|
||||
</template>
|
||||
<template v-else>
|
||||
<TActionsBoxItem icon="reset" @select="unrevokeJoinToken(item.metadata.id!)">
|
||||
<TActionsBoxItem
|
||||
icon="reset"
|
||||
:disabled="!canManageJoinTokens"
|
||||
@select="unrevokeJoinToken(item.metadata.id!)"
|
||||
>
|
||||
Unrevoke
|
||||
</TActionsBoxItem>
|
||||
<TActionsBoxItem
|
||||
icon="delete"
|
||||
danger
|
||||
:disabled="!canManageJoinTokens"
|
||||
@select="() => openDeleteToken(item.metadata.id!)"
|
||||
>
|
||||
Delete
|
||||
|
||||
@ -37,7 +37,7 @@ import { useResourceWatch } from '@/methods/useResourceWatch'
|
||||
import HomeGeneralInformationCopyable from '@/views/Home/HomeGeneralInformationCopyable.vue'
|
||||
|
||||
const features = useFeatures()
|
||||
const { canReadAuditLog } = usePermissions()
|
||||
const { canReadJoinTokens, canReadAuditLog } = usePermissions()
|
||||
const auditLogAvailable = computed(() => !!features.data.value?.spec.audit_log_enabled)
|
||||
|
||||
const { copy, copied } = useClipboard()
|
||||
@ -104,6 +104,7 @@ const {
|
||||
/>
|
||||
|
||||
<HomeGeneralInformationCopyable
|
||||
v-if="canReadJoinTokens"
|
||||
title="Join Token"
|
||||
secret
|
||||
:value="joinTokenData?.spec.token_id"
|
||||
@ -124,11 +125,21 @@ const {
|
||||
Download Installation Media
|
||||
</TButton>
|
||||
|
||||
<TButton icon="long-arrow-down" icon-position="left" @click="downloadMachineJoinConfig()">
|
||||
<TButton
|
||||
v-if="canReadJoinTokens"
|
||||
icon="long-arrow-down"
|
||||
icon-position="left"
|
||||
@click="downloadMachineJoinConfig()"
|
||||
>
|
||||
Download Machine Join Config
|
||||
</TButton>
|
||||
|
||||
<TButton :icon="copied ? 'check' : 'copy'" icon-position="left" @click="copyKernelArgs">
|
||||
<TButton
|
||||
v-if="canReadJoinTokens"
|
||||
:icon="copied ? 'check' : 'copy'"
|
||||
icon-position="left"
|
||||
@click="copyKernelArgs"
|
||||
>
|
||||
Copy Kernel Parameters
|
||||
</TButton>
|
||||
</section>
|
||||
|
||||
@ -13,14 +13,14 @@ import WordHighlighter from 'vue-word-highlighter'
|
||||
import type { Resource } from '@/api/grpc'
|
||||
import type { MachineStatusLinkSpec } from '@/api/omni/specs/ephemeral.pb'
|
||||
import { MachineStatusSpecPowerState } from '@/api/omni/specs/omni.pb'
|
||||
import { MachineStatusLabelInstalled } from '@/api/resources'
|
||||
import { LabelCluster, MachineStatusLabelInstalled } from '@/api/resources'
|
||||
import TActionsBox from '@/components/ActionsBox/TActionsBox.vue'
|
||||
import TActionsBoxItem from '@/components/ActionsBox/TActionsBoxItem.vue'
|
||||
import TCheckbox from '@/components/Checkbox/TCheckbox.vue'
|
||||
import CopyButton from '@/components/CopyButton/CopyButton.vue'
|
||||
import TIcon from '@/components/Icon/TIcon.vue'
|
||||
import Tooltip from '@/components/Tooltip/Tooltip.vue'
|
||||
import { usePermissions } from '@/methods/auth'
|
||||
import { useClusterPermissions, usePermissions } from '@/methods/auth'
|
||||
import type { Label } from '@/methods/labels'
|
||||
import { addMachineLabels, removeMachineLabels } from '@/methods/machine'
|
||||
import ItemLabels from '@/views/ItemLabels/ItemLabels.vue'
|
||||
@ -43,6 +43,10 @@ const { copy } = useClipboard()
|
||||
const { canAccessMaintenanceNodes, canReadClusters, canReadMachineLogs, canRemoveMachines } =
|
||||
usePermissions()
|
||||
|
||||
const { canManageKernelArgs, canReadConfigPatches } = useClusterPermissions(
|
||||
() => machine.metadata.labels?.[LabelCluster],
|
||||
)
|
||||
|
||||
const machineName = computed(() => {
|
||||
return machine.spec.message_status?.network?.hostname ?? machine.metadata.id
|
||||
})
|
||||
@ -157,6 +161,7 @@ const maintenanceUpdateDescription = computed(() => {
|
||||
<TActionsBox>
|
||||
<TActionsBoxItem
|
||||
icon="settings"
|
||||
:disabled="!canReadConfigPatches"
|
||||
@select="
|
||||
$router.push({
|
||||
name: 'MachineConfigPatches',
|
||||
@ -169,6 +174,7 @@ const maintenanceUpdateDescription = computed(() => {
|
||||
|
||||
<TActionsBoxItem
|
||||
icon="settings"
|
||||
:disabled="!canManageKernelArgs"
|
||||
@select="
|
||||
$router.push({
|
||||
query: {
|
||||
@ -186,9 +192,9 @@ const maintenanceUpdateDescription = computed(() => {
|
||||
</TActionsBoxItem>
|
||||
|
||||
<TActionsBoxItem
|
||||
v-if="canRemoveMachines"
|
||||
icon="delete"
|
||||
danger
|
||||
:disabled="!canRemoveMachines"
|
||||
@select="
|
||||
$router.push({
|
||||
query: {
|
||||
|
||||
@ -635,6 +635,10 @@ func (s *managementServer) MaintenanceUpgrade(ctx context.Context, req *manageme
|
||||
}
|
||||
|
||||
func (s *managementServer) GetMachineJoinConfig(ctx context.Context, request *management.GetMachineJoinConfigRequest) (*management.GetMachineJoinConfigResponse, error) {
|
||||
if _, err := auth.CheckGRPC(ctx, auth.WithRole(role.Reader)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx = actor.MarkContextAsInternalActor(ctx)
|
||||
|
||||
apiConfig, err := safe.StateGetByID[*siderolinkres.APIConfig](ctx, s.omniState, siderolinkres.ConfigID)
|
||||
|
||||
@ -456,6 +456,8 @@ func filterAccess(ctx context.Context, access state.Access) error {
|
||||
siderolink.PendingMachineType,
|
||||
siderolink.LinkStatusType,
|
||||
siderolink.JoinTokenStatusType,
|
||||
siderolink.JoinTokenType,
|
||||
siderolink.DefaultJoinTokenType,
|
||||
siderolink.NodeUniqueTokenStatusType,
|
||||
siderolink.GRPCTunnelConfigType,
|
||||
omni.MachineClassType,
|
||||
@ -485,6 +487,10 @@ func filterAccess(ctx context.Context, access state.Access) error {
|
||||
virtual.MetalPlatformConfigType,
|
||||
virtual.KubernetesUsageType:
|
||||
_, err = auth.CheckGRPC(ctx, auth.WithRole(verbToRole(access.Verb)))
|
||||
|
||||
if err == nil && access.Verb == state.Create && access.ResourceType == siderolink.JoinTokenType {
|
||||
err = status.Error(codes.PermissionDenied, "only read, update and destroy access is permitted, create should be done via the management.CreateJoinToken API call")
|
||||
}
|
||||
case
|
||||
meta.NamespaceType,
|
||||
meta.ResourceDefinitionType,
|
||||
@ -514,17 +520,11 @@ func filterAccess(ctx context.Context, access state.Access) error {
|
||||
authres.ServiceAccountStatusType,
|
||||
authres.SAMLLabelRuleType,
|
||||
authres.AccessPolicyType,
|
||||
siderolink.JoinTokenType,
|
||||
siderolink.DefaultJoinTokenType,
|
||||
omni.EtcdBackupS3ConfType,
|
||||
infra.ProviderType,
|
||||
omni.InfraMachineBMCConfigType:
|
||||
_, err = auth.CheckGRPC(ctx, auth.WithRole(role.Admin))
|
||||
|
||||
if err == nil && access.Verb == state.Create && access.ResourceType == siderolink.JoinTokenType {
|
||||
err = status.Error(codes.PermissionDenied, "only read, update and destroy access is permitted, create should be done via the management.CreateJoinToken API call")
|
||||
}
|
||||
|
||||
// Restrict direct mutations on Identity and User resources — these must go through ManagementService gRPC endpoints.
|
||||
if err == nil && !access.Verb.Readonly() && (access.ResourceType == authres.IdentityType || access.ResourceType == authres.UserType) {
|
||||
err = status.Errorf(codes.PermissionDenied, "only read access is permitted on resource %v, mutations should be done via ManagementService API calls", access.ResourceType)
|
||||
|
||||
@ -255,17 +255,21 @@ func (v *State) permissions(ctx context.Context) (*virtual.Permissions, error) {
|
||||
permissions.TypedSpec().Value.CanReadMachineLogs = isReader
|
||||
permissions.TypedSpec().Value.CanReadClusters = isReader
|
||||
permissions.TypedSpec().Value.CanReadMachines = isReader
|
||||
permissions.TypedSpec().Value.CanReadJoinTokens = isReader
|
||||
permissions.TypedSpec().Value.CanReadInstallationMedia = isReader
|
||||
|
||||
isOperator := userRole.Check(role.Operator) == nil
|
||||
permissions.TypedSpec().Value.CanRemoveMachines = isOperator
|
||||
permissions.TypedSpec().Value.CanCreateClusters = isOperator
|
||||
permissions.TypedSpec().Value.CanManageMachineConfigPatches = isOperator
|
||||
permissions.TypedSpec().Value.CanAccessMaintenanceNodes = isOperator
|
||||
permissions.TypedSpec().Value.CanManageInstallationMedia = isOperator
|
||||
|
||||
isAdmin := userRole.Check(role.Admin) == nil
|
||||
permissions.TypedSpec().Value.CanManageUsers = isAdmin
|
||||
permissions.TypedSpec().Value.CanManageBackupStore = isAdmin
|
||||
permissions.TypedSpec().Value.CanReadAuditLog = isAdmin
|
||||
permissions.TypedSpec().Value.CanManageJoinTokens = isAdmin
|
||||
|
||||
if !permissions.TypedSpec().Value.CanCreateClusters {
|
||||
_, err := safe.StateGet[*authres.AccessPolicy](ctx, v.PrimaryState, authres.NewAccessPolicy().Metadata())
|
||||
@ -299,6 +303,9 @@ func (v *State) clusterPermissions(ctx context.Context, ptr resource.Pointer) (*
|
||||
clusterPermissions.TypedSpec().Value.CanDownloadKubeconfig = true
|
||||
clusterPermissions.TypedSpec().Value.CanDownloadTalosconfig = true
|
||||
clusterPermissions.TypedSpec().Value.CanReadConfigPatches = true
|
||||
clusterPermissions.TypedSpec().Value.CanReadMachineConfig = true
|
||||
clusterPermissions.TypedSpec().Value.CanReadKernelArgs = true
|
||||
clusterPermissions.TypedSpec().Value.CanReadMachinePendingUpdates = true
|
||||
}
|
||||
|
||||
if userRole.Check(role.Operator) == nil {
|
||||
@ -311,6 +318,8 @@ func (v *State) clusterPermissions(ctx context.Context, ptr resource.Pointer) (*
|
||||
clusterPermissions.TypedSpec().Value.CanSyncKubernetesManifests = true
|
||||
clusterPermissions.TypedSpec().Value.CanManageClusterFeatures = true
|
||||
clusterPermissions.TypedSpec().Value.CanDownloadSupportBundle = true
|
||||
clusterPermissions.TypedSpec().Value.CanManageMachineConfig = true
|
||||
clusterPermissions.TypedSpec().Value.CanManageKernelArgs = true
|
||||
}
|
||||
|
||||
version, err := resource.ParseVersion("1")
|
||||
|
||||
@ -858,12 +858,10 @@ func AssertResourceAuthz(rootCtx context.Context, rootCli *client.Client, client
|
||||
{
|
||||
resource: joinToken,
|
||||
allowedVerbSet: xslices.ToSet([]state.Verb{state.Get, state.List, state.Update, state.Destroy}),
|
||||
isAdminOnly: true,
|
||||
},
|
||||
{
|
||||
resource: defaultJoinToken,
|
||||
allowedVerbSet: allVerbsSet,
|
||||
isAdminOnly: true,
|
||||
isDestroyNotAllowed: true,
|
||||
},
|
||||
{
|
||||
@ -1483,26 +1481,20 @@ func AssertResourceAuthz(rootCtx context.Context, rootCli *client.Client, client
|
||||
isOperator := testRole.Check(role.Operator) == nil
|
||||
isAdmin := testRole.Check(role.Admin) == nil
|
||||
_, verbAllowed := tc.allowedVerbSet[testVerb]
|
||||
sufficientRole := true
|
||||
|
||||
if tc.isAdminOnly {
|
||||
if !isAdmin {
|
||||
sufficientRole = false
|
||||
}
|
||||
} else {
|
||||
if testVerb.Readonly() {
|
||||
if !isReader {
|
||||
sufficientRole = false
|
||||
}
|
||||
} else {
|
||||
if !isOperator {
|
||||
sufficientRole = false
|
||||
}
|
||||
}
|
||||
}
|
||||
var sufficientRole bool
|
||||
|
||||
if tc.isSignatureSufficient || tc.isPublic {
|
||||
switch {
|
||||
case tc.isSignatureSufficient || tc.isPublic:
|
||||
sufficientRole = true
|
||||
case tc.isAdminOnly:
|
||||
sufficientRole = isAdmin
|
||||
default:
|
||||
if testVerb.Readonly() {
|
||||
sufficientRole = isReader
|
||||
} else {
|
||||
sufficientRole = isOperator
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user