diff --git a/client/api/omni/specs/virtual.pb.go b/client/api/omni/specs/virtual.pb.go
index cdde29cf..60adeee4 100644
--- a/client/api/omni/specs/virtual.pb.go
+++ b/client/api/omni/specs/virtual.pb.go
@@ -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" +
diff --git a/client/api/omni/specs/virtual.proto b/client/api/omni/specs/virtual.proto
index f6b3d757..111a79a3 100644
--- a/client/api/omni/specs/virtual.proto
+++ b/client/api/omni/specs/virtual.proto
@@ -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 {
diff --git a/client/api/omni/specs/virtual_vtproto.pb.go b/client/api/omni/specs/virtual_vtproto.pb.go
index 4abefd27..eeda0f0f 100644
--- a/client/api/omni/specs/virtual_vtproto.pb.go
+++ b/client/api/omni/specs/virtual_vtproto.pb.go
@@ -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:])
diff --git a/frontend/eslint-suppressions.json b/frontend/eslint-suppressions.json
index 7e31c39d..c1eda14d 100644
--- a/frontend/eslint-suppressions.json
+++ b/frontend/eslint-suppressions.json
@@ -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
diff --git a/frontend/src/api/omni/specs/virtual.pb.ts b/frontend/src/api/omni/specs/virtual.pb.ts
index b474a02b..c6bc083f 100644
--- a/frontend/src/api/omni/specs/virtual.pb.ts
+++ b/frontend/src/api/omni/specs/virtual.pb.ts
@@ -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 = {
diff --git a/frontend/src/components/Tabs/TabButton.vue b/frontend/src/components/Tabs/TabButton.vue
index eade101c..ce479b0d 100644
--- a/frontend/src/components/Tabs/TabButton.vue
+++ b/frontend/src/components/Tabs/TabButton.vue
@@ -7,6 +7,7 @@ included in the LICENSE file.
@@ -14,7 +15,8 @@ const forwarded = useForwardPropsEmits(props)
diff --git a/frontend/src/methods/auth.ts b/frontend/src/methods/auth.ts
index b42a360b..a0fe47f3 100644
--- a/frontend/src/methods/auth.ts
+++ b/frontend/src/methods/auth.ts
@@ -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 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,
+ ),
}
}
diff --git a/frontend/src/pages/(authenticated)/clusters/[cluster]/machine/[machine].vue b/frontend/src/pages/(authenticated)/clusters/[cluster]/machine/[machine].vue
index a963393a..a6c4877e 100644
--- a/frontend/src/pages/(authenticated)/clusters/[cluster]/machine/[machine].vue
+++ b/frontend/src/pages/(authenticated)/clusters/[cluster]/machine/[machine].vue
@@ -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"
>
-
+
{{ name }}
diff --git a/frontend/src/pages/(authenticated)/machines/[machine].vue b/frontend/src/pages/(authenticated)/machines/[machine].vue
index 15b29111..75e1295e 100644
--- a/frontend/src/pages/(authenticated)/machines/[machine].vue
+++ b/frontend/src/pages/(authenticated)/machines/[machine].vue
@@ -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"
>
-
+
{{ name }}
diff --git a/frontend/src/pages/(authenticated)/machines/jointokens.vue b/frontend/src/pages/(authenticated)/machines/jointokens.vue
index e39064b6..2bb1e776 100644
--- a/frontend/src/pages/(authenticated)/machines/jointokens.vue
+++ b/frontend/src/pages/(authenticated)/machines/jointokens.vue
@@ -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) => {
- copyValue(item.metadata.id!)">
+ copyValue(item.metadata.id!)"
+ >
Copy Token
- copyKernelParams(item.metadata.id!)">
+ copyKernelParams(item.metadata.id!)"
+ >
Copy Kernel Params
getMachineJoinConfig(item.metadata.id!)"
>
Download Machine Join Config
@@ -191,6 +200,7 @@ const openDeleteToken = (token: string) => {
makeDefault(item.metadata.id!)"
>
Make Default
@@ -199,18 +209,24 @@ const openDeleteToken = (token: string) => {
openRevokeToken(item.metadata.id!)"
>
Revoke
-
+
Unrevoke
openDeleteToken(item.metadata.id!)"
>
Delete
diff --git a/frontend/src/views/Home/HomeGeneralInformation.vue b/frontend/src/views/Home/HomeGeneralInformation.vue
index 307aa372..f6fb1b1d 100644
--- a/frontend/src/views/Home/HomeGeneralInformation.vue
+++ b/frontend/src/views/Home/HomeGeneralInformation.vue
@@ -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 {
/>
-
+
Download Machine Join Config
-
+
Copy Kernel Parameters
diff --git a/frontend/src/views/Machines/MachineItem.vue b/frontend/src/views/Machines/MachineItem.vue
index 6f2893e5..db3d88d6 100644
--- a/frontend/src/views/Machines/MachineItem.vue
+++ b/frontend/src/views/Machines/MachineItem.vue
@@ -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(() => {
{
{