diff --git a/src/locales/en.json b/src/locales/en.json index 96dba2c1..3e414f28 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -542,6 +542,7 @@ "Create Project": "Create Project", "Create QoS Policy": "Create QoS Policy", "Create QoS Spec": "Create QoS Spec", + "Create RBAC Policy": "Create RBAC Policy", "Create Record Set": "Create Record Set", "Create Role": "Create Role", "Create Router": "Create Router", @@ -734,6 +735,7 @@ "Delete Project": "Delete Project", "Delete QoS Policy": "Delete QoS Policy", "Delete QoS Spec": "Delete QoS Spec", + "Delete RBAC Policy": "Delete RBAC Policy", "Delete Record Set": "Delete Record Set", "Delete Role": "Delete Role", "Delete Router": "Delete Router", @@ -1234,6 +1236,7 @@ "IPv6-Route": "IPv6-Route", "ISO - Optical disc image format": "ISO - Optical disc image format", "Iceland": "Iceland", + "Id": "Id", "Identifier of the physical port on the switch to which node’s port is connected to": "Identifier of the physical port on the switch to which node’s port is connected to", "Identity": "Identity", "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.": "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.", @@ -1745,9 +1748,14 @@ "OS Version": "OS Version", "OSDs": "OSDs", "OSPF": "OSPF", + "Object": "Object", "Object Count": "Object Count", "Object Count ": "Object Count ", + "Object ID": "Object ID", + "Object ID/Name": "Object ID/Name", + "Object Name": "Object Name", "Object Storage": "Object Storage", + "Object Type": "Object Type", "Off": "Off", "Offline": "Offline", "Oman": "Oman", @@ -2060,6 +2068,8 @@ "RAM": "RAM", "RAM (MiB)": "RAM (MiB)", "RAW - Raw disk image format": "RAW - Raw disk image format", + "RBAC Policies": "RBAC Policies", + "RBAC Policy Detail": "RBAC Policy Detail", "REJECT": "REJECT", "RESTORE COMPLETE": "RESTORE COMPLETE", "RESUME COMPLETE": "RESUME COMPLETE", @@ -2074,6 +2084,7 @@ "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ": "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ", "Ramdisk ID": "Ramdisk ID", "Ramdisk Image": "Ramdisk Image", + "Rbac Policy": "Rbac Policy", "Read and write": "Read and write", "Read only": "Read only", "Real Name": "Real Name", @@ -2251,9 +2262,13 @@ "Select Project Role": "Select Project Role", "Select User Group": "Select User Group", "Select Volume Snapshot": "Select Volume Snapshot", + "Select a QoS Policy": "Select a QoS Policy", "Select a domain": "Select a domain", "Select a login type": "Select a login type", + "Select a network": "Select a network", + "Select a project": "Select a project", "Select a region": "Select a region", + "Select an object type": "Select an object type", "Selected": "Selected", "Selected Members": "Selected Members", "Selected list": "Selected list", @@ -2321,6 +2336,7 @@ "Shared Network": "Shared Network", "Shared Networks": "Shared Networks", "Shared QoS Policies": "Shared QoS Policies", + "Shared QoS Policy": "Shared QoS Policy", "Shared policy only can insert shared rules.": "Shared policy only can insert shared rules.", "Shares": "Shares", "Shelve": "Shelve", @@ -2497,7 +2513,12 @@ "Target Compute Host": "Target Compute Host", "Target IP Address": "Target IP Address", "Target Port": "Target Port", + "Target Project": "Target Project", + "Target Project ID": "Target Project ID", + "Target Project ID/Name": "Target Project ID/Name", + "Target Project Name": "Target Project Name", "Target Storage Backend": "Target Storage Backend", + "Target Tenant": "Target Tenant", "Task State": "Task State", "Template Content": "Template Content", "Template Name": "Template Name", @@ -2883,6 +2904,7 @@ "You are not allowed to {action}.": "You are not allowed to {action}.", "You can manually specify a physical node to create an instance.": "You can manually specify a physical node to create an instance.", "You don't have access to get {name}.": "You don't have access to get {name}.", + "You may update the editable properties of the RBAC policy here.": "You may update the editable properties of the RBAC policy here.", "Yugoslavia": "Yugoslavia", "Zambia": "Zambia", "Zimbabwe": "Zimbabwe", diff --git a/src/locales/ko-kr.json b/src/locales/ko-kr.json index e14bf768..f4327b09 100644 --- a/src/locales/ko-kr.json +++ b/src/locales/ko-kr.json @@ -542,6 +542,7 @@ "Create Project": "프로젝트 생성", "Create QoS Policy": "QoS 정책 생성", "Create QoS Spec": "QOS 스펙 생성", + "Create RBAC Policy": "", "Create Record Set": "레코드셋 생성", "Create Role": "역할 생성", "Create Router": "라우터 생성", @@ -734,6 +735,7 @@ "Delete Project": "Project 삭제", "Delete QoS Policy": "QoS Policy 삭제", "Delete QoS Spec": "QOS Spec 삭제", + "Delete RBAC Policy": "", "Delete Record Set": "Record Set 삭제", "Delete Role": "Role 삭제", "Delete Router": "Router 삭제", @@ -1234,6 +1236,7 @@ "IPv6-Route": "", "ISO - Optical disc image format": "ISO - 광디스크 이미지 포멧", "Iceland": "", + "Id": "", "Identifier of the physical port on the switch to which node’s port is connected to": "노드의 포트가 연결된 스위치의 물리 포트 식별자", "Identity": "", "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.": "만약 \"사용\"이 롤백에 실패하면 리소스는 생성 실패 후 삭제되고 \"사용 안 함\"이 롤백에 실패하면 리소스는 생성 실패 후에도 보존됩니다.", @@ -1745,9 +1748,14 @@ "OS Version": "OS 버전", "OSDs": "", "OSPF": "", + "Object": "", "Object Count": "", "Object Count ": "", + "Object ID": "", + "Object ID/Name": "", + "Object Name": "", "Object Storage": "", + "Object Type": "", "Off": "", "Offline": "", "Oman": "", @@ -2060,6 +2068,8 @@ "RAM": "", "RAM (MiB)": "", "RAW - Raw disk image format": "RAW - 원본 디스크 이미지 형식", + "RBAC Policies": "", + "RBAC Policy Detail": "", "REJECT": "", "RESTORE COMPLETE": "복원 완료", "RESUME COMPLETE": "재개 완료", @@ -2074,6 +2084,7 @@ "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ": "Ram 값은 { ram }이며, NUMA RAM 값은 { totalRam }이어야 합니다. ", "Ramdisk ID": "램디스크 ID", "Ramdisk Image": "램디스크 이미지", + "Rbac Policy": "", "Read and write": "읽기 및 쓰기", "Read only": "읽기 전용", "Real Name": "실제 이름", @@ -2251,9 +2262,13 @@ "Select Project Role": "", "Select User Group": "", "Select Volume Snapshot": "", + "Select a QoS Policy": "", "Select a domain": "도메인 선택", "Select a login type": "로그인 유형 선택", + "Select a network": "", + "Select a project": "", "Select a region": "지역 선택", + "Select an object type": "", "Selected": "", "Selected Members": "", "Selected list": "", @@ -2321,6 +2336,7 @@ "Shared Network": "공유 네트워크", "Shared Networks": "공유 네트워크", "Shared QoS Policies": "공유 QoS 정책", + "Shared QoS Policy": "", "Shared policy only can insert shared rules.": "", "Shares": "", "Shelve": "", @@ -2497,7 +2513,12 @@ "Target Compute Host": "", "Target IP Address": "", "Target Port": "", + "Target Project": "", + "Target Project ID": "", + "Target Project ID/Name": "", + "Target Project Name": "", "Target Storage Backend": "", + "Target Tenant": "", "Task State": "", "Template Content": "템플릿 내용", "Template Name": "템플릿 이름", @@ -2883,6 +2904,7 @@ "You are not allowed to {action}.": "", "You can manually specify a physical node to create an instance.": "", "You don't have access to get {name}.": "", + "You may update the editable properties of the RBAC policy here.": "", "Yugoslavia": "", "Zambia": "", "Zimbabwe": "", diff --git a/src/locales/ru.json b/src/locales/ru.json index 057ae1c4..81bfe637 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -542,6 +542,7 @@ "Create Project": "Создать проект", "Create QoS Policy": "Создать политику QoS", "Create QoS Spec": "Создать спецификацию QoS", + "Create RBAC Policy": "", "Create Record Set": "Создать набор записей", "Create Role": "Создать роль", "Create Router": "Создать маршрутизатор", @@ -734,6 +735,7 @@ "Delete Project": "Удалить проект", "Delete QoS Policy": "Удалить политику QoS", "Delete QoS Spec": "Удалить спецификацию QoS", + "Delete RBAC Policy": "", "Delete Record Set": "Удалить набор записей", "Delete Role": "Удалить роль", "Delete Router": "Удалить маршрутизатор", @@ -1234,6 +1236,7 @@ "IPv6-Route": "IPv6-Route", "ISO - Optical disc image format": "ISO - Формат оптического диска", "Iceland": "Исландия", + "Id": "", "Identifier of the physical port on the switch to which node’s port is connected to": "Идентификатор физического порта на коммутаторе, к которому подключен порт узла", "Identity": "Идентификация", "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.": "Если \"Включение\" не удается откатить, ресурс будет удален после неудачного создания; если \"Отключение\" не удается откатить, ресурс останется после неудачного создания.", @@ -1745,9 +1748,14 @@ "OS Version": "Версия ОС", "OSDs": "ОСД", "OSPF": "OSPF", + "Object": "", "Object Count": "Количество объектов", "Object Count ": "Количество объектов ", + "Object ID": "", + "Object ID/Name": "", + "Object Name": "", "Object Storage": "Хранилище объектов", + "Object Type": "", "Off": "Выключено", "Offline": "Не в сети", "Oman": "Оман", @@ -2060,6 +2068,8 @@ "RAM": "ОЗУ", "RAM (MiB)": "ОЗУ (МиБ)", "RAW - Raw disk image format": "RAW", + "RBAC Policies": "", + "RBAC Policy Detail": "", "REJECT": "", "RESTORE COMPLETE": "ВОССТАНОВЛЕНИЕ ЗАВЕРШЕНО", "RESUME COMPLETE": "ВОЗОБНОВЛЕНИЕ ЗАВЕРШЕНО", @@ -2074,6 +2084,7 @@ "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ": "Значение ОЗУ равно { ram }, значение ОЗУ NUMA равно { totalRam }, должны быть равны.", "Ramdisk ID": "Идентификатор дискеты ОЗУ", "Ramdisk Image": "Образ дискеты ОЗУ", + "Rbac Policy": "", "Read and write": "Чтение и запись", "Read only": "Только чтение", "Real Name": "Фактическое имя", @@ -2251,9 +2262,13 @@ "Select Project Role": "Выберите роль проекта", "Select User Group": "Выберите группу пользователей", "Select Volume Snapshot": "Выберите снимок диска", + "Select a QoS Policy": "", "Select a domain": "Выберите домен", "Select a login type": "Выберите тип входа", + "Select a network": "", + "Select a project": "", "Select a region": "Выберите регион", + "Select an object type": "", "Selected": "Выбран", "Selected Members": "Выбранные участники", "Selected list": "Выбранный список", @@ -2321,6 +2336,7 @@ "Shared Network": "Общая сеть", "Shared Networks": "Общие сети", "Shared QoS Policies": "Общие политики QoS", + "Shared QoS Policy": "", "Shared policy only can insert shared rules.": "", "Shares": "Общий доступ", "Shelve": "Архивировать", @@ -2497,7 +2513,12 @@ "Target Compute Host": "Целевой хост вычислений", "Target IP Address": "Целевой IP-адрес", "Target Port": "Целевой порт", + "Target Project": "", + "Target Project ID": "", + "Target Project ID/Name": "", + "Target Project Name": "", "Target Storage Backend": "Целевой бэкенд хранилища", + "Target Tenant": "", "Task State": "Состояние задачи", "Template Content": "Содержание шаблона", "Template Name": "Имя шаблона", @@ -2883,6 +2904,7 @@ "You are not allowed to {action}.": "Вам запрещено {action}.", "You can manually specify a physical node to create an instance.": "Вы можете вручную указать физический узел для создания инстанса.", "You don't have access to get {name}.": "У вас нет доступа к получению {name}.", + "You may update the editable properties of the RBAC policy here.": "", "Yugoslavia": "Югославия", "Zambia": "Замбия", "Zimbabwe": "Зимбабве", diff --git a/src/locales/tr-tr.json b/src/locales/tr-tr.json index 06b19e89..8725916b 100644 --- a/src/locales/tr-tr.json +++ b/src/locales/tr-tr.json @@ -542,6 +542,7 @@ "Create Project": "Proje Oluştur", "Create QoS Policy": "QoS İlkesi Oluştur", "Create QoS Spec": "QoS Belirlemesi Oluştur", + "Create RBAC Policy": "", "Create Record Set": "Kayıt Kümesi Oluştur", "Create Role": "Rol Oluştur", "Create Router": "Yönlendirici Oluştur", @@ -734,6 +735,7 @@ "Delete Project": "Projeyi Sil", "Delete QoS Policy": "QoS İlkesini Sil", "Delete QoS Spec": "QoS Belirlemesini Sil", + "Delete RBAC Policy": "", "Delete Record Set": "Kayıt Setini Sil", "Delete Role": "Rolü Sil", "Delete Router": "Yönlendiriciyi Sil", @@ -1234,6 +1236,7 @@ "IPv6-Route": "IPv6-Route", "ISO - Optical disc image format": "ISO - Optik disk görüntü biçimi", "Iceland": "İzlanda", + "Id": "", "Identifier of the physical port on the switch to which node’s port is connected to": "Düğümün bağlı olduğu anahtarın fiziksel ağ adaptörünün tanımlayıcısı", "Identity": "Kimlik", "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.": "\"Etkin\" işlemi geri alınamazsa, kaynak oluşturma başarısız olduktan sonra kaynak silinecektir; \"Etkin Değil\" işlemi geri alınamazsa, kaynak oluşturma başarısız olduktan sonra kaynak korunacaktır.", @@ -1745,9 +1748,14 @@ "OS Version": "İşletim Sistemi Sürümü", "OSDs": "OSD'ler", "OSPF": "OSPF", + "Object": "", "Object Count": "Nesne Sayısı", "Object Count ": "Nesne Sayısı ", + "Object ID": "", + "Object ID/Name": "", + "Object Name": "", "Object Storage": "Nesne Depolama", + "Object Type": "", "Off": "Kapalı", "Offline": "Çevrimdışı", "Oman": "Umman", @@ -2060,6 +2068,8 @@ "RAM": "RAM", "RAM (MiB)": "RAM (MiB)", "RAW - Raw disk image format": "RAW - Ham disk imaj formatı", + "RBAC Policies": "", + "RBAC Policy Detail": "", "REJECT": "", "RESTORE COMPLETE": "GERİ YÜKLEME TAMAMLANDI", "RESUME COMPLETE": "DEVAM ET TAMAMLANDI", @@ -2074,6 +2084,7 @@ "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ": "Ram değeri { ram } ,NUMA RAM değeri { totalRam }'ne eşit olmalıdır.", "Ramdisk ID": "Ramdisk ID'si", "Ramdisk Image": "Ramdisk İmajı", + "Rbac Policy": "", "Read and write": "Okuma ve yazma", "Read only": "Sadece okunur", "Real Name": "Gerçek İsim", @@ -2251,9 +2262,13 @@ "Select Project Role": "Proje Rolü Seçin", "Select User Group": "Kullanıcı Grubu Seçin", "Select Volume Snapshot": "Disk Anlık Görüntüsü Seçin", + "Select a QoS Policy": "", "Select a domain": "Bir etki alanı seçin", "Select a login type": "Bir giriş türü seçin", + "Select a network": "", + "Select a project": "", "Select a region": "Bir bölge seçin", + "Select an object type": "", "Selected": "Seçilen", "Selected Members": "Seçilen Üyeler", "Selected list": "Seçilen liste", @@ -2321,6 +2336,7 @@ "Shared Network": "Paylaşılan Ağ", "Shared Networks": "Paylaşılan Ağlar", "Shared QoS Policies": "Paylaşılan QoS İlkeleri", + "Shared QoS Policy": "", "Shared policy only can insert shared rules.": "", "Shares": "Paylaşımlar", "Shelve": "Rafa Kaldır", @@ -2497,7 +2513,12 @@ "Target Compute Host": "Hedef Hesaplama Ana Bilgisayarı", "Target IP Address": "Hedef IP Adresi", "Target Port": "Hedef Ağ Adaptörü", + "Target Project": "", + "Target Project ID": "", + "Target Project ID/Name": "", + "Target Project Name": "", "Target Storage Backend": "Hedef Depolama Arkayüzü", + "Target Tenant": "", "Task State": "Görev Durumu", "Template Content": "Taslak İçeriği", "Template Name": "Taslak Adı", @@ -2883,6 +2904,7 @@ "You are not allowed to {action}.": "{action} işlemi yapma izniniz yok.", "You can manually specify a physical node to create an instance.": "Bir sanal makine oluşturmak için fiziksel bir düğümü manuel olarak belirleyebilirsiniz.", "You don't have access to get {name}.": "{name} öğesini almak için erişim izniniz yok.", + "You may update the editable properties of the RBAC policy here.": "", "Yugoslavia": "Yugoslavya", "Zambia": "Zambiya", "Zimbabwe": "Zimbabve", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index 0e6fe7e9..22965bc0 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -542,6 +542,7 @@ "Create Project": "创建项目", "Create QoS Policy": "创建QoS策略", "Create QoS Spec": "创建QoS规格", + "Create RBAC Policy": "创建RBAC策略", "Create Record Set": "创建记录集", "Create Role": "创建角色", "Create Router": "创建路由器", @@ -734,6 +735,7 @@ "Delete Project": "删除项目", "Delete QoS Policy": "删除QoS策略", "Delete QoS Spec": "删除QoS规格", + "Delete RBAC Policy": "删除RBAC策略", "Delete Record Set": "删除记录集", "Delete Role": "删除角色", "Delete Router": "删除路由器", @@ -1234,6 +1236,7 @@ "IPv6-Route": "", "ISO - Optical disc image format": "ISO - 光盘映像格式", "Iceland": "冰岛", + "Id": "", "Identifier of the physical port on the switch to which node’s port is connected to": "节点端口所连接的交换机物理端口ID", "Identity": "身份管理", "If \"Enable\" fails to roll back, the resource will be deleted after the creation fails; if \"Disable\" fails to roll back, the resource will be retained after the creation fails.": "若“启用”失败回滚,创建失败后会删除资源;若“禁用”失败回滚,创建失败后会保留资源。", @@ -1745,9 +1748,14 @@ "OS Version": "系统版本", "OSDs": "", "OSPF": "", + "Object": "对象", "Object Count": "对象数量", "Object Count ": "Object数量", + "Object ID": "对象ID", + "Object ID/Name": "对象ID/名称", + "Object Name": "对象名称", "Object Storage": "对象存储", + "Object Type": "对象类型", "Off": "关", "Offline": "离线", "Oman": "阿曼", @@ -2060,6 +2068,8 @@ "RAM": "内存", "RAM (MiB)": "内存 (MiB)", "RAW - Raw disk image format": "RAW - 原始磁盘映像格式", + "RBAC Policies": "RBAC策略", + "RBAC Policy Detail": "RBAC策略详情", "REJECT": "拒绝", "RESTORE COMPLETE": "恢复完成", "RESUME COMPLETE": "恢复完成", @@ -2074,6 +2084,7 @@ "Ram value is { ram }, NUMA RAM value is { totalRam }, need to be equal. ": "内存是 { ram }MiB,NUMA节点的内存是{ totalRam }MiB,需要一致。", "Ramdisk ID": "内存盘ID", "Ramdisk Image": "Ramdisk镜像", + "Rbac Policy": "RBAC策略", "Read and write": "可读可写", "Read only": "只读", "Real Name": "真实姓名", @@ -2251,9 +2262,13 @@ "Select Project Role": "选择项目角色", "Select User Group": "选择用户组", "Select Volume Snapshot": "选择云硬盘快照", + "Select a QoS Policy": "请选择Qos策略", "Select a domain": "请选择Domain", "Select a login type": "请选择登录方式", + "Select a network": "请选择网络", + "Select a project": "请选择项目", "Select a region": "请选择Region", + "Select an object type": "请选择对象类型", "Selected": "已选", "Selected Members": "已选择成员", "Selected list": "已选列表", @@ -2321,6 +2336,7 @@ "Shared Network": "共享网络", "Shared Networks": "共享网络", "Shared QoS Policies": "共享QoS策略", + "Shared QoS Policy": "共享QoS策略", "Shared policy only can insert shared rules.": "共享的策略只可以插入共享的规则。", "Shares": "共享", "Shelve": "归档", @@ -2497,7 +2513,12 @@ "Target Compute Host": "目标计算节点", "Target IP Address": "目标IP地址", "Target Port": "目标网卡", + "Target Project": "目标项目", + "Target Project ID": "目标项目ID", + "Target Project ID/Name": "目标项目ID/名称", + "Target Project Name": "目标项目名称", "Target Storage Backend": "目标存储后端", + "Target Tenant": "目标项目", "Task State": "任务状态", "Template Content": "模板内容", "Template Name": "模板名称", @@ -2883,6 +2904,7 @@ "You are not allowed to {action}.": "无法{ action }。", "You can manually specify a physical node to create an instance.": "您可以手动指定一台物理节点来创建云主机。", "You don't have access to get {name}.": "您没有权限访问{name}。", + "You may update the editable properties of the RBAC policy here.": "您可以在此处更新 RBAC 策略的可编辑属性。", "Yugoslavia": "南斯拉夫", "Zambia": "赞比亚", "Zimbabwe": "津巴布韦", diff --git a/src/pages/network/containers/RbacPolicies/Detail/Detail.jsx b/src/pages/network/containers/RbacPolicies/Detail/Detail.jsx index 86b49548..303b55d7 100644 --- a/src/pages/network/containers/RbacPolicies/Detail/Detail.jsx +++ b/src/pages/network/containers/RbacPolicies/Detail/Detail.jsx @@ -12,6 +12,7 @@ import { inject, observer } from 'mobx-react'; import Base from 'containers/BaseDetail'; +import { objectTypes } from 'resources/neutron/rbac-policy'; export class BaseDetail extends Base { get leftCards() { @@ -21,21 +22,30 @@ export class BaseDetail extends Base { get baseInfoCard() { const options = [ - { - label: t('ID'), - dataIndex: 'id', - }, - { - label: t('Project ID'), - dataIndex: 'project_id', - }, { label: t('Object Type'), dataIndex: 'object_type', + valueMap: objectTypes, }, { label: t('Object ID'), dataIndex: 'object_id', + render: (value) => { + const { object_type } = this.detailData; + if (object_type === 'network') { + return this.getLinkRender('networkDetail', value, { id: value }); + } + if (object_type === 'qos_policy') { + return this.getLinkRender('networkQosDetail', value, { + id: value, + }); + } + return value; + }, + }, + { + label: t('Object Name'), + dataIndex: 'object.name', }, { label: t('Action'), @@ -44,11 +54,24 @@ export class BaseDetail extends Base { { label: t('Target Tenant'), dataIndex: 'target_tenant', + render: (value) => { + if (value === '*') { + return value; + } + const { targetProject } = this.detailData; + return this.getLinkRender( + 'projectDetail', + targetProject?.name || value, + { + id: value, + } + ); + }, }, ]; return { - title: t('Rbac Policy Detail'), + title: t('Detail Info'), options, }; } diff --git a/src/pages/network/containers/RbacPolicies/Detail/index.jsx b/src/pages/network/containers/RbacPolicies/Detail/index.jsx index 3f41b385..4960de77 100644 --- a/src/pages/network/containers/RbacPolicies/Detail/index.jsx +++ b/src/pages/network/containers/RbacPolicies/Detail/index.jsx @@ -22,13 +22,22 @@ export class RbacPolicyDetail extends Base { } get listUrl() { - return this.getRoutePath('rbacPoliciesAdmin'); + return this.getRoutePath('rbacPolicy'); } get actionConfigs() { return actionConfigs; } + get detailInfos() { + return [ + { + title: t('Project ID'), + dataIndex: 'project_id', + }, + ]; + } + get tabs() { const tabs = [ { diff --git a/src/pages/network/containers/RbacPolicies/actions/Create.jsx b/src/pages/network/containers/RbacPolicies/actions/Create.jsx index 99dd64f9..a94d7ca1 100644 --- a/src/pages/network/containers/RbacPolicies/actions/Create.jsx +++ b/src/pages/network/containers/RbacPolicies/actions/Create.jsx @@ -12,30 +12,34 @@ import { inject, observer } from 'mobx-react'; import { ModalAction } from 'containers/Action'; -import Notify from 'src/components/Notify'; import { RbacPoliciesStore } from 'src/stores/neutron/rbac-policies'; import { ProjectStore } from 'stores/keystone/project'; import { NetworkStore } from 'stores/neutron/network'; import { QoSPolicyStore } from 'stores/neutron/qos-policy'; -import { observable } from 'mobx'; +import { qosEndpoint } from 'client/client/constants'; +import { anyProject } from 'resources/neutron/rbac-policy'; export class Create extends ModalAction { static id = 'create-policy'; - static title = t('Create'); + static title = t('Create RBAC Policy'); - @observable allNetworks; - - @observable allProjects; + static policy = 'create_rbac_policy'; get name() { return t('Create'); } + get messageHasItemName() { + return false; + } + init() { this.state = { ...this.state, isReady: false, + allNetworks: [], + qosPolices: [], }; this.store = new RbacPoliciesStore(); this.projectStore = new ProjectStore(); @@ -53,33 +57,31 @@ export class Create extends ModalAction { this.setState({ isReady: true }); } - get tips() { - return t('From here you can create a rbac policy.'); + get enableQosPolicy() { + return qosEndpoint(); } async getProjects() { - this.allProjects = await this.projectStore.pureFetchList(); - this.addNewElementToProjectList(); - } - - addNewElementToProjectList() { - const newElement = { - id: '*', - name: '*', - }; - this.allProjects.unshift(newElement); + const allProjects = await this.projectStore.pureFetchList(); + allProjects.unshift(anyProject); + this.setState({ allProjects }); } async getQoSPolicy() { + if (!this.enableQosPolicy) { + return; + } await this.qosPolicyStore.fetchList(); } async getNetworks() { - this.allNetworks = await this.networkStore.pureFetchList(); + const allNetworks = await this.networkStore.pureFetchList(); + this.setState({ allNetworks }); } get projects() { - return (this.allProjects || []).map((it) => ({ + const { allProjects } = this.state; + return (allProjects || []).map((it) => ({ value: it.id, label: it.name, })); @@ -92,49 +94,65 @@ export class Create extends ModalAction { })); } - get networks() { - return (this.allNetworks || []).map((it) => ({ - value: it.id, - label: it.name, - })); + get sharedNetworks() { + const { allNetworks } = this.state; + return (allNetworks || []) + .filter((it) => it.shared === true) + .map((it) => ({ + value: it.id, + label: it.name, + })); + } + + get externalNetworks() { + const { allNetworks } = this.state; + return (allNetworks || []) + .filter((it) => it['router:external'] === true) + .map((it) => ({ + value: it.id, + label: it.name, + })); } onSubmit = async (values) => { - try { - const { object_type, ...rest } = values; - const action = - object_type === 'network' || object_type === 'qos_policy' - ? 'access_as_shared' - : 'access_as_external'; - const updatedType = - object_type === 'external-network' ? 'network' : object_type; - const body = { - ...rest, - object_type: updatedType, - action, - }; + const { object_type, ...rest } = values; + const action = + object_type === 'network' || object_type === 'qos_policy' + ? 'access_as_shared' + : 'access_as_external'; + const updatedType = + object_type === 'external-network' ? 'network' : object_type; + const body = { + ...rest, + object_type: updatedType, + action, + }; - await this.store.create(body); - } catch (error) { - Notify.errorWithDetail(null, error.toString()); - return Promise.reject(error); - } + return this.store.create(body); }; static allowed = () => Promise.resolve(true); get createObjectList() { - return [ + const items = [ { value: 'network', label: t('Shared Network') }, { value: 'external-network', label: t('External Network') }, - { value: 'qos_policy', label: t('Shared QoS Policy') }, ]; + if (this.enableQosPolicy) { + items.push({ value: 'qos_policy', label: t('Shared QoS Policy') }); + } + return items; } onChangeHandler = async (value) => { - this.setState({ - object_type: value, - }); + this.setState( + { + object_type: value, + }, + () => { + this.updateFormValue('object_id', undefined); + } + ); }; get formItems() { @@ -156,8 +174,8 @@ export class Create extends ModalAction { }, { name: 'object_type', - label: t('Action and Object Type'), - placeholder: t('Select action and object type'), + label: t('Object Type'), + placeholder: t('Select an object type'), type: 'select', onChange: this.onChangeHandler, options: this.createObjectList, @@ -168,10 +186,9 @@ export class Create extends ModalAction { label: t('Shared Network'), placeholder: t('Select a network'), type: 'select', - options: this.networks, + options: this.sharedNetworks, hidden: !isNetwork, isLoading: !this.state.isReady, - onChange: this.onSourceEnvironmentChange, required: true, }, { @@ -179,7 +196,7 @@ export class Create extends ModalAction { label: t('External Network'), placeholder: t('Select a network'), type: 'select', - options: this.networks, + options: this.externalNetworks, hidden: !isExternalNetwork, isLoading: !this.state.isReady, required: true, diff --git a/src/pages/network/containers/RbacPolicies/actions/Delete.jsx b/src/pages/network/containers/RbacPolicies/actions/Delete.jsx index c6029f7f..0e3931a3 100644 --- a/src/pages/network/containers/RbacPolicies/actions/Delete.jsx +++ b/src/pages/network/containers/RbacPolicies/actions/Delete.jsx @@ -14,6 +14,8 @@ import { ConfirmAction } from 'containers/Action'; import globalRbacPoliciesStore from 'stores/neutron/rbac-policies'; export default class Delete extends ConfirmAction { + policy = 'delete_rbac_policy'; + get id() { return 'delete'; } @@ -30,6 +32,10 @@ export default class Delete extends ConfirmAction { return t('Delete'); } + get messageHasItemName() { + return false; + } + get actionName() { return t('delete'); } diff --git a/src/pages/network/containers/RbacPolicies/actions/Edit.jsx b/src/pages/network/containers/RbacPolicies/actions/Edit.jsx index 7c383680..0fb14613 100644 --- a/src/pages/network/containers/RbacPolicies/actions/Edit.jsx +++ b/src/pages/network/containers/RbacPolicies/actions/Edit.jsx @@ -12,22 +12,30 @@ import { inject, observer } from 'mobx-react'; import { ModalAction } from 'containers/Action'; -import Notify from 'src/components/Notify'; import { RbacPoliciesStore } from 'src/stores/neutron/rbac-policies'; import { ProjectStore } from 'stores/keystone/project'; +import { anyProject } from 'src/resources/neutron/rbac-policy'; export class Edit extends ModalAction { static id = 'edit-policy'; static title = t('Edit'); + static policy = 'update_rbac_policy'; + get name() { return t('Edit'); } + get messageHasItemName() { + return false; + } + init() { this.store = new RbacPoliciesStore(); this.projectStore = new ProjectStore(); + this.state.projects = []; + this.state.isReady = false; this.getProjects(); } @@ -36,26 +44,29 @@ export class Edit extends ModalAction { } async getProjects() { - await this.projectStore.fetchProjectsWithDomain(); - this.setState({ ...this.state, isReady: true }); + const projects = await this.projectStore.pureFetchList(); + projects.unshift(anyProject); + this.setState({ projects, isReady: true }); } get projects() { - return (this.projectStore.list.data || []).map((it) => ({ + const { projects } = this.state; + return (projects || []).map((it) => ({ value: it.id, label: it.name, })); } + get defaultValue() { + const { target_tenant } = this.item; + return { + target_tenant, + }; + } + onSubmit = async (values) => { const { id } = this.item; - try { - const { ...body } = values; - await this.store.update(id, body); - } catch (error) { - Notify.errorWithDetail(null, error.toString()); - return Promise.reject(error); - } + return this.store.update({ id }, values); }; static allowed = () => Promise.resolve(true); @@ -68,7 +79,7 @@ export class Edit extends ModalAction { placeholder: t('Select a project'), type: 'select', options: this.projects, - isLoading: this.projectStore.list.isLoading, + loading: !this.state.isReady, required: true, }, ]; diff --git a/src/pages/network/containers/RbacPolicies/index.jsx b/src/pages/network/containers/RbacPolicies/index.jsx index 4addb0c5..3b7ab5db 100644 --- a/src/pages/network/containers/RbacPolicies/index.jsx +++ b/src/pages/network/containers/RbacPolicies/index.jsx @@ -13,6 +13,8 @@ import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import { RbacPoliciesStore } from 'src/stores/neutron/rbac-policies'; +import { objectTypes } from 'resources/neutron/rbac-policy'; +import { getOptions } from 'utils'; import actionConfigRbacPolicies from './actions'; export class RbacPolicies extends Base { @@ -21,8 +23,8 @@ export class RbacPolicies extends Base { this.downloadStore = new RbacPoliciesStore(); } - get hasTab() { - return false; + get policy() { + return 'get_rbac_policy'; } get name() { @@ -33,53 +35,74 @@ export class RbacPolicies extends Base { return actionConfigRbacPolicies; } - getColumns = () => { + getColumns() { const columns = [ - { - title: t('Project'), - dataIndex: 'project_name', - }, { title: t('ID'), dataIndex: 'id', routeName: this.getRouteName('rbacPolicyDetail'), isLink: true, + withoutName: true, + }, + { + title: t('Project ID/Name'), + dataIndex: 'project_name', + isHideable: true, }, { title: t('Object Type'), dataIndex: 'object_type', + isHideable: true, + valueMap: objectTypes, }, { - title: t('Object'), + title: t('Object ID/Name'), dataIndex: 'object_name', + isHideable: true, + idKey: 'object_id', + isLink: true, + getRouteName: (value, record) => { + const { object_type } = record || {}; + if (object_type === 'network') { + return this.getRouteName('networkDetail'); + } + if (object_type === 'qos_policy') { + return this.getRouteName('networkQosDetail'); + } + return ''; + }, }, { - title: t('Target Project'), + title: t('Target Project ID/Name'), dataIndex: 'target_tenant_name', + isHideable: true, + idKey: 'target_tenant_id', + routeName: this.getRouteName('projectDetail'), + isLink: true, + emptyRender: () => { + return '*'; + }, }, ]; return columns; - }; + } get objectTypes() { - return [ - { key: 'network', label: t('Network') }, - { key: 'qos_policy', label: t('QoS Policy') }, - ]; + return getOptions(objectTypes); } get searchFilters() { return [ - { - label: t('Project'), - name: 'project_name', - }, { label: t('Id'), name: 'id', }, { - label: t('Target Project'), + label: t('Target Project ID'), + name: 'target_tenant', + }, + { + label: t('Target Project Name'), name: 'target_tenant_name', }, { @@ -91,6 +114,14 @@ export class RbacPolicies extends Base { label: t('Object'), name: 'object_name', }, + { + label: t('Project ID'), + name: 'project_id', + }, + { + label: t('Project Name'), + name: 'project_name', + }, ]; } } diff --git a/src/resources/neutron/rbac-policy.js b/src/resources/neutron/rbac-policy.js new file mode 100644 index 00000000..5422c9bb --- /dev/null +++ b/src/resources/neutron/rbac-policy.js @@ -0,0 +1,9 @@ +export const objectTypes = { + network: t('Network'), + qos_policy: t('QoS Policy'), +}; + +export const anyProject = { + id: '*', + name: '*', +}; diff --git a/src/resources/skyline/policy.js b/src/resources/skyline/policy.js index 975937db..250f7deb 100644 --- a/src/resources/skyline/policy.js +++ b/src/resources/skyline/policy.js @@ -60,6 +60,7 @@ export const policyMap = { 'floatingip', 'vpnservice', 'ipsec_site_connection', + 'rbac_policy', ], octavia: ['os_load-balancer_api'], // keystone: ['identity:'], diff --git a/src/stores/neutron/rbac-policies.js b/src/stores/neutron/rbac-policies.js index 52ceeece..5bd7a8c9 100644 --- a/src/stores/neutron/rbac-policies.js +++ b/src/stores/neutron/rbac-policies.js @@ -1,5 +1,6 @@ import Base from 'stores/base'; import client from 'client'; +import { qosEndpoint } from 'client/client/constants'; export class RbacPoliciesStore extends Base { get client() { @@ -26,25 +27,31 @@ export class RbacPoliciesStore extends Base { return client.neutron.networks; } + get enableQosPolicy() { + return qosEndpoint(); + } + async listDidFetch(items) { const [ { networks: allNetworks }, - { policies: allPolicies }, + qosPoliciesResult, { projects: allProjects }, ] = await Promise.all([ this.networkClient.list(), - this.qosClient.list(), + this.enableQosPolicy ? this.qosClient.list() : null, this.projectClient.list(), ]); + const { policies: allPolicies = [] } = qosPoliciesResult || {}; const updatedItems = items.map((item) => { + const { object_id, target_tenant } = item; const networkOfItem = allNetworks.find( - (network) => network.id === item.object_id + (network) => network.id === object_id ); const policyOfItem = allPolicies.find( - (policy) => policy.id === item.object_id + (policy) => policy.id === object_id ); const targetTenant = allProjects.find( - (project) => project.id === item.target_tenant + (project) => project.id === target_tenant ); return { ...item, @@ -54,21 +61,34 @@ export class RbacPoliciesStore extends Base { ? policyOfItem.name : '-', target_tenant_name: targetTenant ? targetTenant.name : '*', + target_tenant_id: target_tenant === '*' ? '' : target_tenant, }; }); return updatedItems; } - async getProjects() { - await this.projectClient.list(); - } - - async getQoSPolicy() { - await this.qosPolicyClient.list(); - } - - async getNetworks() { - await this.networkClient.list(); + async detailDidFetch(item) { + const { object_type, object_id, target_tenant } = item; + let objectRequest = null; + let projectRequest = null; + if (object_type === 'network') { + objectRequest = this.networkClient.show(object_id); + } else if (object_type === 'qos_policy') { + objectRequest = this.qosClient.show(object_id); + } + if (target_tenant !== '*') { + projectRequest = this.projectClient.show(target_tenant); + } + const [objectResult, projectResult] = await Promise.allSettled([ + objectRequest, + projectRequest, + ]); + const { network, qos_policy } = objectResult.value || {}; + return { + ...item, + object: network || qos_policy, + targetProject: projectResult.value?.project, + }; } } diff --git a/src/utils/table.jsx b/src/utils/table.jsx index 20f44d5e..b93b3290 100644 --- a/src/utils/table.jsx +++ b/src/utils/table.jsx @@ -268,7 +268,9 @@ export const getNameRenderByRouter = (render, column, rowKey) => { const { dataIndex, idKey, + emptyRender, routeName, + getRouteName, routeParamsKey = 'id', routeQuery = {}, routeParamsFunc, @@ -282,12 +284,15 @@ export const getNameRenderByRouter = (render, column, rowKey) => { const nameValue = value || get(record, dataIndex) || '-'; const isBold = isNameBold(dataIndex, title, boldName, withoutId); const nameRender = getNameRenderWithStyle(nameValue, isBold); - if (!routeName) { + const currentRouteName = getRouteName + ? getRouteName(value, record) + : routeName; + if (!currentRouteName) { return nameValue; } const idValue = get(record, idKey || rowKey); if (!idValue) { - return '-'; + return emptyRender ? emptyRender() : '-'; } const idRender = getIdRender(idValue, copyable, true); const params = routeParamsFunc @@ -296,7 +301,7 @@ export const getNameRenderByRouter = (render, column, rowKey) => { const query = routeQuery; if (!withoutId) { const link = getLinkRender({ - key: routeName, + key: currentRouteName, params, query, value: idRender, @@ -309,7 +314,7 @@ export const getNameRenderByRouter = (render, column, rowKey) => { ); } const link = getLinkRender({ - key: routeName, + key: currentRouteName, params, query, value: nameRender,