Merge "feat: Support manila share"
This commit is contained in:
commit
9ad847728e
@ -184,6 +184,13 @@ export default class BaseClient {
|
||||
conf
|
||||
);
|
||||
},
|
||||
showDetail: (id, params, conf) => {
|
||||
return this.request.get(
|
||||
`${this.getDetailUrl(resourceName, id)}/detail`,
|
||||
params,
|
||||
conf
|
||||
);
|
||||
},
|
||||
create: (data, ...args) => this.request.post(listUrl, data, ...args),
|
||||
update: (id, data, ...args) =>
|
||||
this.request.put(this.getDetailUrl(resourceName, id), data, ...args),
|
||||
|
@ -37,6 +37,23 @@ export class ManilaClient extends Base {
|
||||
{
|
||||
key: 'shares',
|
||||
responseKey: 'share',
|
||||
subResources: [
|
||||
{
|
||||
name: 'exportLocations',
|
||||
key: 'export_locations',
|
||||
responseKey: 'export_location',
|
||||
},
|
||||
{
|
||||
key: 'metadata',
|
||||
responseKey: 'metadata',
|
||||
},
|
||||
],
|
||||
extendOperations: [
|
||||
{
|
||||
key: 'action',
|
||||
method: 'post',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'types',
|
||||
@ -133,6 +150,29 @@ export class ManilaClient extends Base {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'shareAccessRules',
|
||||
key: 'share-access-rules',
|
||||
responseKey: 'access_list',
|
||||
extendOperations: [
|
||||
{
|
||||
name: 'updateMetadata',
|
||||
key: 'metadata',
|
||||
method: 'put',
|
||||
},
|
||||
],
|
||||
subResources: [
|
||||
{
|
||||
key: 'metadata',
|
||||
responseKey: 'metadata',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'quotaSets',
|
||||
key: 'quota-sets',
|
||||
responseKey: 'quota_set',
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -405,6 +405,22 @@ const renderMenu = (t) => {
|
||||
key: 'fileStorageAdmin',
|
||||
icon: <SwitcherOutlined />,
|
||||
children: [
|
||||
{
|
||||
path: '/share/share-admin',
|
||||
name: t('Share'),
|
||||
key: 'shareAdmin',
|
||||
level: 1,
|
||||
endpoints: 'manilav2',
|
||||
children: [
|
||||
{
|
||||
path: /^\/share\/share-admin\/detail\/.[^/]+$/,
|
||||
name: t('Share Detail'),
|
||||
key: 'shareDetailAdmin',
|
||||
level: 2,
|
||||
routePath: '/share/share-admin/detail/:id',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/share/share-type-admin',
|
||||
name: t('Share Type'),
|
||||
|
@ -384,6 +384,28 @@ const renderMenu = (t) => {
|
||||
key: 'fileStorage',
|
||||
icon: <SwitcherOutlined />,
|
||||
children: [
|
||||
{
|
||||
path: '/share/share',
|
||||
name: t('Share'),
|
||||
key: 'share',
|
||||
level: 1,
|
||||
endpoints: 'manilav2',
|
||||
children: [
|
||||
{
|
||||
path: /^\/share\/share\/detail\/.[^/]+$/,
|
||||
name: t('Share Detail'),
|
||||
key: 'shareDetail',
|
||||
level: 2,
|
||||
routePath: '/share/share/detail/:id',
|
||||
},
|
||||
{
|
||||
path: '/share/share/create',
|
||||
name: t('Create Share'),
|
||||
key: 'shareCreate',
|
||||
level: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/share/share-network',
|
||||
name: t('Share Network'),
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
" You can go to the console to ": " You can go to the console to ",
|
||||
"\"Shared\" volume can be mounted on multiple instances": "\"Shared\" volume can be mounted on multiple instances",
|
||||
"'ip' rule represents IPv4 or IPv6 address, 'cert' rule represents TLS certificate, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID.": "'ip' rule represents IPv4 or IPv6 address, 'cert' rule represents TLS certificate, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID.",
|
||||
"-1 means no connection limit": "-1 means no connection limit",
|
||||
".": ".",
|
||||
"1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.": "1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.",
|
||||
@ -37,7 +38,11 @@
|
||||
"Abandoning this stack will preserve the resources deployed by the stack.": "Abandoning this stack will preserve the resources deployed by the stack.",
|
||||
"Accept Volume Transfer": "Accept Volume Transfer",
|
||||
"Access Control": "Access Control",
|
||||
"Access Key": "Access Key",
|
||||
"Access Level": "Access Level",
|
||||
"Access Rule": "Access Rule",
|
||||
"Access Rules Status": "Access Rules Status",
|
||||
"Access To": "Access To",
|
||||
"Access Type": "Access Type",
|
||||
"Access Type Setting": "Access Type Setting",
|
||||
"Action": "Action",
|
||||
@ -45,6 +50,7 @@
|
||||
"Active": "Active",
|
||||
"Active Status": "Active Status",
|
||||
"Add": "Add",
|
||||
"Add Access Rule": "Add Access Rule",
|
||||
"Add Custom Metadata": "Add Custom Metadata",
|
||||
"Add Data Disks": "Add Data Disks",
|
||||
"Add External Members": "Add External Members",
|
||||
@ -52,6 +58,7 @@
|
||||
"Add Extra Spec": "Add Extra Spec",
|
||||
"Add IP": "Add IP",
|
||||
"Add Member": "Add Member",
|
||||
"Add Metadata": "Add Metadata",
|
||||
"Add NUMA Node": "Add NUMA Node",
|
||||
"Add Network": "Add Network",
|
||||
"Add Property": "Add Property",
|
||||
@ -243,6 +250,7 @@
|
||||
"Burundi": "Burundi",
|
||||
"CIDR": "CIDR",
|
||||
"CIDR Format Error(e.g. 192.168.0.0/24, 2001:DB8::/48)": "CIDR Format Error(e.g. 192.168.0.0/24, 2001:DB8::/48)",
|
||||
"CIFS": "CIFS",
|
||||
"CPU": "CPU",
|
||||
"CPU Arch": "CPU Arch",
|
||||
"CPU Cores": "CPU Cores",
|
||||
@ -269,6 +277,9 @@
|
||||
"Cayman Islands": "Cayman Islands",
|
||||
"CentOS": "CentOS",
|
||||
"Central African Republic": "Central African Republic",
|
||||
"CephFS": "CephFS",
|
||||
"Cephx": "Cephx",
|
||||
"Cert": "Cert",
|
||||
"Chad": "Chad",
|
||||
"Change Password": "Change Password",
|
||||
"Change Type": "Change Type",
|
||||
@ -414,8 +425,10 @@
|
||||
"Create Rule": "Create Rule",
|
||||
"Create Security Group": "Create Security Group",
|
||||
"Create Server Group": "Create Server Group",
|
||||
"Create Share": "Create Share",
|
||||
"Create Share Group": "Create Share Group",
|
||||
"Create Share Group Type": "Create Share Group Type",
|
||||
"Create Share Metadata": "Create Share Metadata",
|
||||
"Create Share Network": "Create Share Network",
|
||||
"Create Share Type": "Create Share Type",
|
||||
"Create Snapshot": "Create Snapshot",
|
||||
@ -560,8 +573,11 @@
|
||||
"Delete Rule": "Delete Rule",
|
||||
"Delete Security Group": "Delete Security Group",
|
||||
"Delete Server Group": "Delete Server Group",
|
||||
"Delete Share": "Delete Share",
|
||||
"Delete Share Access Rule": "Delete Share Access Rule",
|
||||
"Delete Share Group": "Delete Share Group",
|
||||
"Delete Share Group Type": "Delete Share Group Type",
|
||||
"Delete Share Metadata": "Delete Share Metadata",
|
||||
"Delete Share Network": "Delete Share Network",
|
||||
"Delete Share Type": "Delete Share Type",
|
||||
"Delete Snapshot": "Delete Snapshot",
|
||||
@ -583,6 +599,7 @@
|
||||
"Deleting this stack will delete all resources deployed by the stack.": "Deleting this stack will delete all resources deployed by the stack.",
|
||||
"Democratic Republic of the Congo": "Democratic Republic of the Congo",
|
||||
"Denmark": "Denmark",
|
||||
"Denying": "Denying",
|
||||
"Deploy Failed": "Deploy Failed",
|
||||
"Deploy Wait": "Deploy Wait",
|
||||
"Deploying": "Deploying",
|
||||
@ -687,6 +704,7 @@
|
||||
"Edit Quota": "Edit Quota",
|
||||
"Edit Router": "Edit Router",
|
||||
"Edit Rule": "Edit Rule",
|
||||
"Edit Share Metadata": "Edit Share Metadata",
|
||||
"Edit Subnet": "Edit Subnet",
|
||||
"Edit System Permission": "Edit System Permission",
|
||||
"Edit User Group": "Edit User Group",
|
||||
@ -856,6 +874,7 @@
|
||||
"Gigabytes(GB)": "Gigabytes(GB)",
|
||||
"Given IP": "Given IP",
|
||||
"Global Setting": "Global Setting",
|
||||
"GlusterFS": "GlusterFS",
|
||||
"Greece": "Greece",
|
||||
"Greenland": "Greenland",
|
||||
"Grenada": "Grenada",
|
||||
@ -865,6 +884,7 @@
|
||||
"Guinea": "Guinea",
|
||||
"Guinea Bissau": "Guinea Bissau",
|
||||
"Guyana": "Guyana",
|
||||
"HDFS": "HDFS",
|
||||
"HTTP Version not supported (code: 505) ": "HTTP Version not supported (code: 505) ",
|
||||
"Haiti": "Haiti",
|
||||
"Hard Reboot": "Hard Reboot",
|
||||
@ -952,6 +972,7 @@
|
||||
"If no gateway is specified, the first IP address will be defaulted.": "If no gateway is specified, the first IP address will be defaulted.",
|
||||
"If not provided, the roles assigned to the application credential will be the same as the roles in the current token.": "If not provided, the roles assigned to the application credential will be the same as the roles in the current token.",
|
||||
"If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.": "If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.",
|
||||
"If set then all tenants will be able to see this share.": "If set then all tenants will be able to see this share.",
|
||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.",
|
||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).",
|
||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project",
|
||||
@ -1175,6 +1196,7 @@
|
||||
"Luxembourg": "Luxembourg",
|
||||
"MAC Address": "MAC Address",
|
||||
"MAC Learning State": "MAC Learning State",
|
||||
"MAPRFS": "MAPRFS",
|
||||
"MTU": "MTU",
|
||||
"Mac Address": "Mac Address",
|
||||
"MacVTap": "MacVTap",
|
||||
@ -1189,6 +1211,7 @@
|
||||
"Mali": "Mali",
|
||||
"Malta": "Malta",
|
||||
"Manage Access": "Manage Access",
|
||||
"Manage Access Rule": "Manage Access Rule",
|
||||
"Manage Error": "Manage Error",
|
||||
"Manage Host": "Manage Host",
|
||||
"Manage Metadata": "Manage Metadata",
|
||||
@ -1273,12 +1296,14 @@
|
||||
"More Actions": "More Actions",
|
||||
"Morocco": "Morocco",
|
||||
"Mount ISO": "Mount ISO",
|
||||
"Mount snapshot support": "Mount snapshot support",
|
||||
"Mozambique": "Mozambique",
|
||||
"Multiple filter tags are separated by enter": "Multiple filter tags are separated by enter",
|
||||
"My Role": "My Role",
|
||||
"MySQL Actions": "MySQL Actions",
|
||||
"Myanmar": "Myanmar",
|
||||
"N/A": "N/A",
|
||||
"NFS": "NFS",
|
||||
"NOOP": "NOOP",
|
||||
"NUMA Node": "NUMA Node",
|
||||
"NUMA Node Count": "NUMA Node Count",
|
||||
@ -1612,6 +1637,8 @@
|
||||
"QoS policies": "QoS policies",
|
||||
"Qos Policy": "Qos Policy",
|
||||
"Queued": "Queued",
|
||||
"Queued To Apply": "Queued To Apply",
|
||||
"Queued To Deny": "Queued To Deny",
|
||||
"Quota Overview": "Quota Overview",
|
||||
"Quota exceeded": "Quota exceeded",
|
||||
"Quota is not enough for extend volume.": "Quota is not enough for extend volume.",
|
||||
@ -1628,6 +1655,8 @@
|
||||
"Ramdisk ID": "Ramdisk ID",
|
||||
"Ramdisk Image": "Ramdisk Image",
|
||||
"Read And Write": "Read And Write",
|
||||
"Read and write": "Read and write",
|
||||
"Read only": "Read only",
|
||||
"Reader": "Reader",
|
||||
"Real Name": "Real Name",
|
||||
"Reason": "Reason",
|
||||
@ -1778,7 +1807,10 @@
|
||||
"Set Boot Device": "Set Boot Device",
|
||||
"Set IP": "Set IP",
|
||||
"Seychelles": "Seychelles",
|
||||
"Share": "Share",
|
||||
"Share Detail": "Share Detail",
|
||||
"Share File Storage": "Share File Storage",
|
||||
"Share Gigabytes(GiB)": "Share Gigabytes(GiB)",
|
||||
"Share Group": "Share Group",
|
||||
"Share Group Detail": "Share Group Detail",
|
||||
"Share Group Type": "Share Group Type",
|
||||
@ -1790,9 +1822,13 @@
|
||||
"Share Network Detail": "Share Network Detail",
|
||||
"Share Network Subnet": "Share Network Subnet",
|
||||
"Share Network Subnets": "Share Network Subnets",
|
||||
"Share Protocol": "Share Protocol",
|
||||
"Share Replica ID": "Share Replica ID",
|
||||
"Share Server": "Share Server",
|
||||
"Share Type": "Share Type",
|
||||
"Share Type Detail": "Share Type Detail",
|
||||
"Share Type ID": "Share Type ID",
|
||||
"Share Type Name": "Share Type Name",
|
||||
"Share Types": "Share Types",
|
||||
"Shared": "Shared",
|
||||
"Shared Image": "Shared Image",
|
||||
@ -2254,6 +2290,7 @@
|
||||
"Zambia": "Zambia",
|
||||
"Zimbabwe": "Zimbabwe",
|
||||
"abandon stack": "abandon stack",
|
||||
"add access rule": "add access rule",
|
||||
"add network": "add network",
|
||||
"add router": "add router",
|
||||
"all": "all",
|
||||
@ -2299,6 +2336,7 @@
|
||||
"create ipsec site connection": "create ipsec site connection",
|
||||
"create network": "create network",
|
||||
"create router": "create router",
|
||||
"create share": "create share",
|
||||
"create share group": "create share group",
|
||||
"create share group type": "create share group type",
|
||||
"create share network": "create share network",
|
||||
@ -2451,11 +2489,14 @@
|
||||
"server groups": "server groups",
|
||||
"services": "services",
|
||||
"settings": "settings",
|
||||
"share": "share",
|
||||
"share access rules": "share access rules",
|
||||
"share group": "share group",
|
||||
"share group type": "share group type",
|
||||
"share groups": "share groups",
|
||||
"share instance": "share instance",
|
||||
"share instances": "share instances",
|
||||
"share metadata": "share metadata",
|
||||
"share network": "share network",
|
||||
"share type": "share type",
|
||||
"share types": "share types",
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
" You can go to the console to ": "您可以前往控制台 ",
|
||||
"\"Shared\" volume can be mounted on multiple instances": "“共享”云硬盘类型的云硬盘,可挂载到多台云主机上",
|
||||
"'ip' rule represents IPv4 or IPv6 address, 'cert' rule represents TLS certificate, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID.": "'IP' 规则代表 IPv4 或 IPv6 地址,'Cert' 规则代表TLS 证书,'用户' 规则代表用户名或用户组,'Cephx' 规则代表 ceph auth ID。",
|
||||
"-1 means no connection limit": "-1表示无连接限制",
|
||||
".": "。",
|
||||
"1. The backup can only capture the data that has been written to the volume at the beginning of the backup task, excluding the data in the cache at that time.": "1. 备份只能捕获在备份任务开始时已经写入磁盘的数据,不包括当时位于缓存的数据。",
|
||||
@ -37,7 +38,11 @@
|
||||
"Abandoning this stack will preserve the resources deployed by the stack.": "废弃此堆栈将保留堆栈部署的资源。",
|
||||
"Accept Volume Transfer": "接受云硬盘转让",
|
||||
"Access Control": "访问控制",
|
||||
"Access Key": "访问密钥",
|
||||
"Access Level": "访问级别",
|
||||
"Access Rule": "访问规则",
|
||||
"Access Rules Status": "访问规则状态",
|
||||
"Access To": "访问",
|
||||
"Access Type": "访问类型",
|
||||
"Access Type Setting": "访问类型设置",
|
||||
"Action": "操作",
|
||||
@ -45,6 +50,7 @@
|
||||
"Active": "运行中",
|
||||
"Active Status": "运行",
|
||||
"Add": "添加",
|
||||
"Add Access Rule": "添加访问规则",
|
||||
"Add Custom Metadata": "添加自定义元数据",
|
||||
"Add Data Disks": "添加数据盘",
|
||||
"Add External Members": "添加外部成员",
|
||||
@ -52,6 +58,7 @@
|
||||
"Add Extra Spec": "添加额外规格",
|
||||
"Add IP": "增加IP",
|
||||
"Add Member": "添加成员",
|
||||
"Add Metadata": "添加元数据",
|
||||
"Add NUMA Node": "添加NUMA节点",
|
||||
"Add Network": "添加网络",
|
||||
"Add Property": "添加属性",
|
||||
@ -243,6 +250,7 @@
|
||||
"Burundi": "布隆迪",
|
||||
"CIDR": "网络地址",
|
||||
"CIDR Format Error(e.g. 192.168.0.0/24, 2001:DB8::/48)": "CIDR格式错误(如:192.168.0.0/24, 2001:DB8::/48)",
|
||||
"CIFS": "",
|
||||
"CPU": "",
|
||||
"CPU Arch": "CPU架构",
|
||||
"CPU Cores": "CPU核数",
|
||||
@ -269,6 +277,9 @@
|
||||
"Cayman Islands": "开曼群岛",
|
||||
"CentOS": "",
|
||||
"Central African Republic": "中非共和国",
|
||||
"CephFS": "",
|
||||
"Cephx": "",
|
||||
"Cert": "",
|
||||
"Chad": "乍得",
|
||||
"Change Password": "修改密码",
|
||||
"Change Type": "修改类型",
|
||||
@ -414,8 +425,10 @@
|
||||
"Create Rule": "创建规则",
|
||||
"Create Security Group": "创建安全组",
|
||||
"Create Server Group": "创建云主机组",
|
||||
"Create Share": "创建共享",
|
||||
"Create Share Group": "创建共享组",
|
||||
"Create Share Group Type": "创建共享组类型",
|
||||
"Create Share Metadata": "创建共享元数据",
|
||||
"Create Share Network": "创建共享网络",
|
||||
"Create Share Type": "创建共享类型",
|
||||
"Create Snapshot": "创建快照",
|
||||
@ -560,8 +573,11 @@
|
||||
"Delete Rule": "删除规则",
|
||||
"Delete Security Group": "删除安全组",
|
||||
"Delete Server Group": "删除云主机组",
|
||||
"Delete Share": "删除共享",
|
||||
"Delete Share Access Rule": "删除共享访问规则",
|
||||
"Delete Share Group": "删除共享组",
|
||||
"Delete Share Group Type": "删除共享组类型",
|
||||
"Delete Share Metadata": "删除共享元数据",
|
||||
"Delete Share Network": "删除共享网络",
|
||||
"Delete Share Type": "删除共享类型",
|
||||
"Delete Snapshot": "删除快照",
|
||||
@ -583,6 +599,7 @@
|
||||
"Deleting this stack will delete all resources deployed by the stack.": "删除此堆栈将删除所有堆栈部署的资源。",
|
||||
"Democratic Republic of the Congo": "刚果民主共和国",
|
||||
"Denmark": "丹麦",
|
||||
"Denying": "拒绝中",
|
||||
"Deploy Failed": "部署失败",
|
||||
"Deploy Wait": "等待部署",
|
||||
"Deploying": "部署中",
|
||||
@ -687,6 +704,7 @@
|
||||
"Edit Quota": "编辑配额",
|
||||
"Edit Router": "编辑路由器",
|
||||
"Edit Rule": "编辑规则",
|
||||
"Edit Share Metadata": "编辑共享元数据",
|
||||
"Edit Subnet": "编辑子网",
|
||||
"Edit System Permission": "编辑系统角色",
|
||||
"Edit User Group": "编辑用户组",
|
||||
@ -856,6 +874,7 @@
|
||||
"Gigabytes(GB)": "云硬盘容量(GB)",
|
||||
"Given IP": "指定IP",
|
||||
"Global Setting": "平台配置",
|
||||
"GlusterFS": "",
|
||||
"Greece": "希腊",
|
||||
"Greenland": "格陵兰",
|
||||
"Grenada": "格林纳达",
|
||||
@ -865,6 +884,7 @@
|
||||
"Guinea": "几内亚",
|
||||
"Guinea Bissau": "几内亚比绍",
|
||||
"Guyana": "圭亚那",
|
||||
"HDFS": "",
|
||||
"HTTP Version not supported (code: 505) ": "",
|
||||
"Haiti": "海地",
|
||||
"Hard Reboot": "硬重启",
|
||||
@ -952,6 +972,7 @@
|
||||
"If no gateway is specified, the first IP address will be defaulted.": "如果不指定网关IP,默认是第一个地址。",
|
||||
"If not provided, the roles assigned to the application credential will be the same as the roles in the current token.": "如果不选择,那么分配给应用凭证的角色将与当前用户的角色相同。",
|
||||
"If nova-compute on the host is disabled, it will be forbidden to be selected as the target host.": "如果计算节点上的nova-compute被禁用,将禁止其作为目标节点。",
|
||||
"If set then all tenants will be able to see this share.": "如果设置,则所有租户都将能够看到此共享。",
|
||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "如果云硬盘容量较大,修改云硬盘类型可能需要花费几个小时,请您谨慎操作。",
|
||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "若快照关联的云硬盘修改过云硬盘类型,请手动修改此选项;若快照关联的云硬盘保持云硬盘类型不变,请忽略此选项(不需要做变更)。",
|
||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "您未被授权访问任何项目,或您参与中的项目已被删除或禁用,可联系平台管理员重新分配项目",
|
||||
@ -1175,6 +1196,7 @@
|
||||
"Luxembourg": "卢森堡",
|
||||
"MAC Address": "MAC地址",
|
||||
"MAC Learning State": "MAC学习状态",
|
||||
"MAPRFS": "",
|
||||
"MTU": "",
|
||||
"Mac Address": "Mac地址",
|
||||
"MacVTap": "",
|
||||
@ -1189,6 +1211,7 @@
|
||||
"Mali": "马里",
|
||||
"Malta": "马尔他",
|
||||
"Manage Access": "访问管理",
|
||||
"Manage Access Rule": "管理访问规则",
|
||||
"Manage Error": "管理失败",
|
||||
"Manage Host": "管理主机",
|
||||
"Manage Metadata": "管理元数据",
|
||||
@ -1273,12 +1296,14 @@
|
||||
"More Actions": "更多操作",
|
||||
"Morocco": "摩洛哥",
|
||||
"Mount ISO": "挂载ISO",
|
||||
"Mount snapshot support": "支持挂载快照",
|
||||
"Mozambique": "莫桑比克",
|
||||
"Multiple filter tags are separated by enter": "多个过滤标签用回车键分隔",
|
||||
"My Role": "我的角色",
|
||||
"MySQL Actions": "",
|
||||
"Myanmar": "缅甸",
|
||||
"N/A": "",
|
||||
"NFS": "",
|
||||
"NOOP": "",
|
||||
"NUMA Node": "NUMA节点",
|
||||
"NUMA Node Count": "NUMA节点数量",
|
||||
@ -1612,6 +1637,8 @@
|
||||
"QoS policies": "QoS策略",
|
||||
"Qos Policy": "QoS策略",
|
||||
"Queued": "已排队",
|
||||
"Queued To Apply": "排队申请",
|
||||
"Queued To Deny": "排队拒绝",
|
||||
"Quota Overview": "配额概况",
|
||||
"Quota exceeded": "配额用尽",
|
||||
"Quota is not enough for extend volume.": "配额不足以扩容云硬盘。",
|
||||
@ -1628,6 +1655,8 @@
|
||||
"Ramdisk ID": "内存盘ID",
|
||||
"Ramdisk Image": "Ramdisk镜像",
|
||||
"Read And Write": "",
|
||||
"Read and write": "可读可写",
|
||||
"Read only": "只读",
|
||||
"Reader": "只读",
|
||||
"Real Name": "真实姓名",
|
||||
"Reason": "原因",
|
||||
@ -1778,7 +1807,10 @@
|
||||
"Set Boot Device": "设置引导设备",
|
||||
"Set IP": "设置IP",
|
||||
"Seychelles": "塞舌尔",
|
||||
"Share": "共享",
|
||||
"Share Detail": "共享详情",
|
||||
"Share File Storage": "文件存储",
|
||||
"Share Gigabytes(GiB)": "共享容量(GiB)",
|
||||
"Share Group": "共享组",
|
||||
"Share Group Detail": "共享组详情",
|
||||
"Share Group Type": "共享组类型",
|
||||
@ -1790,9 +1822,13 @@
|
||||
"Share Network Detail": "共享网络详情",
|
||||
"Share Network Subnet": "共享网络子网",
|
||||
"Share Network Subnets": "共享网络子网",
|
||||
"Share Protocol": "共享协议",
|
||||
"Share Replica ID": "共享副本ID",
|
||||
"Share Server": "共享服务器",
|
||||
"Share Type": "共享类型",
|
||||
"Share Type Detail": "共享类型详情",
|
||||
"Share Type ID": "共享类型ID",
|
||||
"Share Type Name": "共享类型名称",
|
||||
"Share Types": "共享类型",
|
||||
"Shared": "共享",
|
||||
"Shared Image": "共享镜像",
|
||||
@ -2254,6 +2290,7 @@
|
||||
"Zambia": "赞比亚",
|
||||
"Zimbabwe": "津巴布韦",
|
||||
"abandon stack": "废弃堆栈",
|
||||
"add access rule": "添加访问规则",
|
||||
"add network": "添加网络",
|
||||
"add router": "添加路由器",
|
||||
"all": "所有",
|
||||
@ -2299,6 +2336,7 @@
|
||||
"create ipsec site connection": "创建IPsec站点连接",
|
||||
"create network": "创建网络",
|
||||
"create router": "创建路由",
|
||||
"create share": "创建共享",
|
||||
"create share group": "创建共享组",
|
||||
"create share group type": "创建共享组类型",
|
||||
"create share network": "创建共享网络",
|
||||
@ -2451,11 +2489,14 @@
|
||||
"server groups": "云主机组",
|
||||
"services": "服务",
|
||||
"settings": "配置",
|
||||
"share": "共享",
|
||||
"share access rules": "共享访问规则",
|
||||
"share group": "共享组",
|
||||
"share group type": "共享组类型",
|
||||
"share groups": "共享组",
|
||||
"share instance": "共享实例",
|
||||
"share instances": "共享实例",
|
||||
"share metadata": "共享元数据",
|
||||
"share network": "共享网络",
|
||||
"share type": "共享类型",
|
||||
"share types": "共享类型",
|
||||
|
@ -80,6 +80,20 @@ export const quotaCardList = [
|
||||
},
|
||||
];
|
||||
|
||||
export const shareQuotaCard = {
|
||||
text: t('Share'),
|
||||
type: 'share',
|
||||
value: [
|
||||
{ text: t('Share'), key: 'shares' },
|
||||
{
|
||||
text: t('Share Gigabytes(GiB)'),
|
||||
key: 'share_gigabytes',
|
||||
},
|
||||
{ text: t('Share Network'), key: 'share_networks' },
|
||||
{ text: t('Share Group'), key: 'share_groups' },
|
||||
],
|
||||
};
|
||||
|
||||
export const getVolumeTypeCards = (data) => {
|
||||
const value = data.map((item, index) => {
|
||||
return {
|
||||
@ -146,6 +160,10 @@ export class QuotaOverview extends Component {
|
||||
return globalRootStore.checkEndpoint('cinder');
|
||||
}
|
||||
|
||||
get enableShare() {
|
||||
return globalRootStore.checkEndpoint('manilav2');
|
||||
}
|
||||
|
||||
get volumeTypeData() {
|
||||
const { volumeTypeData } = this.props;
|
||||
return volumeTypeData || this.volumeTypeStore.list.data;
|
||||
@ -157,10 +175,14 @@ export class QuotaOverview extends Component {
|
||||
|
||||
get quotaCardList() {
|
||||
const list = this.props.quotaCardList || quotaCardList;
|
||||
let newList = [...list];
|
||||
if (!this.enableCinder) {
|
||||
return list.filter((it) => it.type !== 'storage');
|
||||
newList = newList.filter((it) => it.type !== 'storage');
|
||||
}
|
||||
return list;
|
||||
if (this.enableShare) {
|
||||
newList.push(shareQuotaCard);
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
|
||||
get quotaAction() {
|
||||
@ -244,13 +266,13 @@ export class QuotaOverview extends Component {
|
||||
if (isLoading) {
|
||||
return <Spin />;
|
||||
}
|
||||
return this.renderQuotaCart(
|
||||
return this.renderQuotaCard(
|
||||
this.projectStore.quota,
|
||||
this.getFilteredValue(item.value)
|
||||
);
|
||||
}
|
||||
|
||||
renderQuotaCart = (data, item = []) =>
|
||||
renderQuotaCard = (data, item = []) =>
|
||||
item.map((i) => <div key={i.text}>{this.getItemInfo(data, i)}</div>);
|
||||
|
||||
renderVolumeTypes = () => {
|
||||
|
@ -0,0 +1,139 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
|
||||
import { keyValueValidator } from 'pages/share/containers/ShareType/actions/Create';
|
||||
import KeyValueInput from 'components/FormItem/KeyValueInput';
|
||||
import { updateAddSelectValueToObj } from 'utils/index';
|
||||
|
||||
export const metadataFormItem = {
|
||||
name: 'metadata',
|
||||
label: t('Metadata'),
|
||||
type: 'add-select',
|
||||
itemComponent: KeyValueInput,
|
||||
addText: t('Add Metadata'),
|
||||
keySpan: 8,
|
||||
validator: keyValueValidator,
|
||||
};
|
||||
|
||||
export class Create extends ModalAction {
|
||||
static id = 'create';
|
||||
|
||||
static title = t('Add Access Rule');
|
||||
|
||||
get name() {
|
||||
return t('add access rule');
|
||||
}
|
||||
|
||||
static get modalSize() {
|
||||
return 'middle';
|
||||
}
|
||||
|
||||
getModalSize() {
|
||||
return 'middle';
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareAccessRuleStore;
|
||||
}
|
||||
|
||||
static policy = 'manila:share:allow_access';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get typeOptions() {
|
||||
return [
|
||||
{
|
||||
value: 'ip',
|
||||
label: t('IP'),
|
||||
},
|
||||
{
|
||||
value: 'cert',
|
||||
label: t('Cert'),
|
||||
},
|
||||
{
|
||||
value: 'user',
|
||||
label: t('User'),
|
||||
},
|
||||
{
|
||||
value: 'cephx',
|
||||
label: t('Cephx'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get levelOptions() {
|
||||
return [
|
||||
{
|
||||
value: 'rw',
|
||||
label: t('Read and write'),
|
||||
},
|
||||
{
|
||||
value: 'ro',
|
||||
label: t('Read only'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get defaultValue() {
|
||||
return { isPublic: true };
|
||||
}
|
||||
|
||||
get typeTip() {
|
||||
return t(
|
||||
"'ip' rule represents IPv4 or IPv6 address, 'cert' rule represents TLS certificate, 'user' rule represents username or usergroup, 'cephx' rule represents ceph auth ID."
|
||||
);
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'access_type',
|
||||
label: t('Access Type'),
|
||||
type: 'select',
|
||||
options: this.typeOptions,
|
||||
required: true,
|
||||
tip: this.typeTip,
|
||||
},
|
||||
{
|
||||
name: 'access_level',
|
||||
label: t('Access Level'),
|
||||
type: 'select',
|
||||
options: this.levelOptions,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'access_to',
|
||||
label: t('Access To'),
|
||||
type: 'input',
|
||||
required: true,
|
||||
},
|
||||
metadataFormItem,
|
||||
];
|
||||
}
|
||||
|
||||
onSubmit = (values, containerProps) => {
|
||||
const { detail: { id } = {} } = containerProps;
|
||||
const { metadata, ...rest } = values;
|
||||
const body = {
|
||||
...rest,
|
||||
metadata: updateAddSelectValueToObj(metadata),
|
||||
};
|
||||
return this.store.create(id, body);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Create));
|
@ -0,0 +1,45 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ConfirmAction } from 'containers/Action';
|
||||
import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
|
||||
|
||||
export default class Delete extends ConfirmAction {
|
||||
get id() {
|
||||
return 'delete';
|
||||
}
|
||||
|
||||
get title() {
|
||||
return t('Delete Share Access Rule');
|
||||
}
|
||||
|
||||
get buttonType() {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
get buttonText() {
|
||||
return t('Delete');
|
||||
}
|
||||
|
||||
get actionName() {
|
||||
return t('Delete Share Access Rule');
|
||||
}
|
||||
|
||||
policy = 'manila:share:deny_access';
|
||||
|
||||
onSubmit = (data, containerProps) => {
|
||||
const { detail: { id } = {} } = containerProps;
|
||||
return globalShareAccessRuleStore.delete(id, data.id);
|
||||
};
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import {
|
||||
updateAddSelectValueToObj,
|
||||
updateObjToAddSelectArray,
|
||||
} from 'utils/index';
|
||||
import { metadataFormItem } from './Create';
|
||||
|
||||
export class ManageMetadata extends ModalAction {
|
||||
static id = 'manage-metadata';
|
||||
|
||||
static title = t('Manage Metadata');
|
||||
|
||||
init() {
|
||||
this.store = globalShareAccessRuleStore;
|
||||
}
|
||||
|
||||
static get modalSize() {
|
||||
return 'large';
|
||||
}
|
||||
|
||||
getModalSize() {
|
||||
return 'large';
|
||||
}
|
||||
|
||||
static policy = [
|
||||
'manila:share_access_metadata:update',
|
||||
'manila:share_access_metadata:delete',
|
||||
];
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get messageHasItemName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('Manage Metadata');
|
||||
}
|
||||
|
||||
get defaultValue() {
|
||||
const { metadata } = this.item;
|
||||
return {
|
||||
metadata: updateObjToAddSelectArray(metadata || {}),
|
||||
};
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
return [metadataFormItem];
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { metadata = {} } = values;
|
||||
const { id, metadata: oldValue = {} } = this.item;
|
||||
const newValue = updateAddSelectValueToObj(metadata);
|
||||
const dels = Object.keys(oldValue).filter(
|
||||
(key) => !Object.keys(newValue).includes(key)
|
||||
);
|
||||
return this.store.manageMetadata(id, newValue, dels);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ManageMetadata));
|
@ -0,0 +1,41 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Create from './Create';
|
||||
import Delete from './Delete';
|
||||
import ManageMetadata from './ManageMetadata';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [
|
||||
{
|
||||
action: ManageMetadata,
|
||||
},
|
||||
],
|
||||
},
|
||||
primaryActions: [Create],
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
const actionConfigsAdmin = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [],
|
||||
},
|
||||
primaryActions: [],
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
export default { actionConfigs, actionConfigsAdmin };
|
81
src/pages/share/containers/Share/Detail/AccessRule/index.jsx
Normal file
81
src/pages/share/containers/Share/Detail/AccessRule/index.jsx
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
|
||||
import { shareAccessRuleState } from 'resources/manila/share';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class ShareAccessRule extends Base {
|
||||
init() {
|
||||
this.store = globalShareAccessRuleStore;
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share_access_rule:index';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('share access rules');
|
||||
}
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
getColumns = () => [
|
||||
{
|
||||
title: t('ID'),
|
||||
dataIndex: 'id',
|
||||
},
|
||||
{
|
||||
title: t('Access Type'),
|
||||
dataIndex: 'access_type',
|
||||
},
|
||||
{
|
||||
title: t('Access To'),
|
||||
dataIndex: 'access_to',
|
||||
},
|
||||
{
|
||||
title: t('Access Level'),
|
||||
dataIndex: 'access_level',
|
||||
},
|
||||
{
|
||||
title: t('State'),
|
||||
dataIndex: 'state',
|
||||
render: (value) => shareAccessRuleState[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Access Key'),
|
||||
dataIndex: 'access_key',
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'toLocalTime',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Updated At'),
|
||||
dataIndex: 'updated_at',
|
||||
valueRender: 'toLocalTime',
|
||||
isHideable: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ShareAccessRule));
|
237
src/pages/share/containers/Share/Detail/BaseDetail.jsx
Normal file
237
src/pages/share/containers/Share/Detail/BaseDetail.jsx
Normal file
@ -0,0 +1,237 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from 'react';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import Base from 'containers/BaseDetail';
|
||||
import { shareProtocol } from 'resources/manila/share';
|
||||
import { getYesNo, toLocalTimeFilter } from 'utils/index';
|
||||
|
||||
export class BaseDetail extends Base {
|
||||
get leftCards() {
|
||||
const cards = [this.baseInfoCard, this.shareTypeCard];
|
||||
const { share_network_id, share_group_id } = this.detailData;
|
||||
if (share_network_id) {
|
||||
cards.push(this.shareNetworkCard);
|
||||
}
|
||||
if (share_group_id) {
|
||||
cards.push(this.shareGroupCard);
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
|
||||
get rightCards() {
|
||||
return [this.exportLocationsCard, this.accessCard];
|
||||
}
|
||||
|
||||
get baseInfoCard() {
|
||||
const options = [
|
||||
{
|
||||
label: t('Project ID'),
|
||||
dataIndex: 'project_id',
|
||||
},
|
||||
{
|
||||
label: t('Availability Zone'),
|
||||
dataIndex: 'availability_zone',
|
||||
},
|
||||
{
|
||||
label: t('Host'),
|
||||
dataIndex: 'host',
|
||||
},
|
||||
{
|
||||
label: t('Size'),
|
||||
dataIndex: 'size',
|
||||
render: (value) => `${value}GiB`,
|
||||
},
|
||||
{
|
||||
label: t('Protocol'),
|
||||
dataIndex: 'share_proto',
|
||||
render: (value) => shareProtocol[value] || value,
|
||||
},
|
||||
{
|
||||
label: t('Public'),
|
||||
dataIndex: 'is_public',
|
||||
valueRender: 'yesNo',
|
||||
},
|
||||
{
|
||||
label: t('Mount snapshot support'),
|
||||
dataIndex: 'mount_snapshot_support',
|
||||
valueRender: 'yesNo',
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
title: t('Base Info'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get shareTypeCard() {
|
||||
const options = [
|
||||
{
|
||||
label: t('Share Type ID'),
|
||||
dataIndex: 'share_type',
|
||||
},
|
||||
{
|
||||
label: t('Share Type Name'),
|
||||
dataIndex: 'share_type_name',
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
title: t('Share Type'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get shareNetworkCard() {
|
||||
const { shareNetwork } = this.detailData;
|
||||
const options = [
|
||||
{
|
||||
label: t('Share Network'),
|
||||
dataIndex: 'share_network_id',
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender(
|
||||
'shareNetworkDetail',
|
||||
shareNetwork.name,
|
||||
{
|
||||
id: value,
|
||||
}
|
||||
);
|
||||
return link;
|
||||
},
|
||||
},
|
||||
];
|
||||
return {
|
||||
title: t('Share Network'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get shareGroupCard() {
|
||||
const { shareGroup } = this.detailData;
|
||||
const options = [
|
||||
{
|
||||
label: t('Share Group'),
|
||||
dataIndex: 'share_group_id',
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender('shareGroupDetail', shareGroup.name, {
|
||||
id: value,
|
||||
});
|
||||
return link;
|
||||
},
|
||||
},
|
||||
];
|
||||
return {
|
||||
title: t('Share Group'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get exportLocationsCard() {
|
||||
const { exportLocations = [] } = this.detailData || {};
|
||||
const options = exportLocations.map((location, index) => {
|
||||
return {
|
||||
label: `${t('Export Location')} ${index + 1}`,
|
||||
dataIndex: 'exportLocations',
|
||||
render: () => {
|
||||
return (
|
||||
<div key={location.id}>
|
||||
<div>
|
||||
<span style={{ fontWeight: 'bold' }}>{t('Path')}: </span>
|
||||
{location.path}
|
||||
</div>
|
||||
<div>
|
||||
<span style={{ fontWeight: 'bold' }}>{t('Preferred')}: </span>
|
||||
{getYesNo(location.preferred)}
|
||||
</div>
|
||||
<div>
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
{t('Is admin only')}:
|
||||
</span>
|
||||
{getYesNo(location.is_admin_only)}
|
||||
</div>
|
||||
<div>
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
{t('Share Replica ID')}:{' '}
|
||||
</span>
|
||||
{location.share_instance_id}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
});
|
||||
return {
|
||||
title: t('Export Locations'),
|
||||
options,
|
||||
labelCol: 4,
|
||||
};
|
||||
}
|
||||
|
||||
get accessCard() {
|
||||
const { accessList = [] } = this.detailData;
|
||||
const access = accessList[0] || {};
|
||||
const options = [
|
||||
{
|
||||
label: t('Access Type'),
|
||||
dataIndex: 'access_type',
|
||||
render: () => access.access_type,
|
||||
},
|
||||
{
|
||||
label: t('Access To'),
|
||||
dataIndex: 'access_to',
|
||||
render: () => access.access_to,
|
||||
},
|
||||
{
|
||||
label: t('Access Level'),
|
||||
dataIndex: 'access_level',
|
||||
render: () => access.access_level,
|
||||
},
|
||||
{
|
||||
label: t('State'),
|
||||
dataIndex: 'state',
|
||||
render: () => access.state,
|
||||
},
|
||||
{
|
||||
label: t('Access Key'),
|
||||
dataIndex: 'access_key',
|
||||
render: () => access.access_key,
|
||||
},
|
||||
{
|
||||
label: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
render: () => toLocalTimeFilter(access.created_at),
|
||||
},
|
||||
{
|
||||
label: t('Updated At'),
|
||||
dataIndex: 'updated_at',
|
||||
render: () => toLocalTimeFilter(access.updated_at),
|
||||
},
|
||||
];
|
||||
return {
|
||||
title: t('Access Rule'),
|
||||
options,
|
||||
labelCol: 4,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(BaseDetail));
|
@ -0,0 +1,71 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareMetadataStore from 'stores/manila/share-metadata';
|
||||
|
||||
export class Create extends ModalAction {
|
||||
static id = 'create';
|
||||
|
||||
static title = t('Create Share Metadata');
|
||||
|
||||
get name() {
|
||||
return t('Create Share Metadata');
|
||||
}
|
||||
|
||||
static policy = 'manila:share:update_share_metadata';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get defaultValue() {
|
||||
return {};
|
||||
}
|
||||
|
||||
get instanceName() {
|
||||
return this.values.keyName;
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'keyName',
|
||||
label: t('Key'),
|
||||
type: 'input',
|
||||
required: true,
|
||||
placeholder: t('Please input key'),
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
label: t('Value'),
|
||||
type: 'input',
|
||||
placeholder: t('Please input value'),
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareMetadataStore;
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { id } = this.containerProps.detail;
|
||||
const { keyName, value } = values;
|
||||
const metadata = { [keyName]: value };
|
||||
return this.store.createOrUpdate(id, metadata);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Create));
|
@ -0,0 +1,52 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ConfirmAction } from 'containers/Action';
|
||||
import globalShareMetadataStore from 'stores/manila/share-metadata';
|
||||
|
||||
export default class Delete extends ConfirmAction {
|
||||
get id() {
|
||||
return 'delete';
|
||||
}
|
||||
|
||||
get title() {
|
||||
return t('Delete Share Metadata');
|
||||
}
|
||||
|
||||
get buttonType() {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
get buttonText() {
|
||||
return t('Delete');
|
||||
}
|
||||
|
||||
get actionName() {
|
||||
return t('Delete Share Metadata');
|
||||
}
|
||||
|
||||
policy = 'manila:share:delete_share_metadata';
|
||||
|
||||
allowedCheckFunc = () => true;
|
||||
|
||||
onSubmit = (data) => {
|
||||
const { id } = this.containerProps.detail;
|
||||
const { keyName } = data;
|
||||
const body = {
|
||||
id,
|
||||
keyName,
|
||||
};
|
||||
return globalShareMetadataStore.delete(body);
|
||||
};
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareMetadataStore from 'stores/manila/share-metadata';
|
||||
|
||||
export class Edit extends ModalAction {
|
||||
static id = 'edit';
|
||||
|
||||
static title = t('Edit Share Metadata');
|
||||
|
||||
static buttonText = t('Edit');
|
||||
|
||||
get name() {
|
||||
return t('Edit Share Metadata');
|
||||
}
|
||||
|
||||
get instanceName() {
|
||||
return this.item.keyName;
|
||||
}
|
||||
|
||||
get defaultValue() {
|
||||
const { keyName, value } = this.item;
|
||||
const defaultValue = {
|
||||
keyName,
|
||||
value,
|
||||
};
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static policy = 'manila:share:update_share_metadata';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'keyName',
|
||||
label: t('Key'),
|
||||
type: 'input',
|
||||
disabled: true,
|
||||
placeholder: t('Please input key'),
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
label: t('Value'),
|
||||
type: 'input',
|
||||
placeholder: t('Please input value'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareMetadataStore;
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { id } = this.containerProps.detail;
|
||||
const { keyName, value } = values;
|
||||
const extra_specs = { [keyName]: value };
|
||||
return this.store.createOrUpdate(id, extra_specs);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Edit));
|
@ -0,0 +1,41 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Create from './Create';
|
||||
import Edit from './Edit';
|
||||
import Delete from './Delete';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [
|
||||
{
|
||||
action: Edit,
|
||||
},
|
||||
],
|
||||
},
|
||||
batchActions: [Delete],
|
||||
primaryActions: [Create],
|
||||
};
|
||||
|
||||
const actionConfigsAdmin = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [],
|
||||
},
|
||||
batchActions: [Delete],
|
||||
primaryActions: [],
|
||||
};
|
||||
|
||||
export default { actionConfigs, actionConfigsAdmin };
|
60
src/pages/share/containers/Share/Detail/Metadata/index.jsx
Normal file
60
src/pages/share/containers/Share/Detail/Metadata/index.jsx
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import { ShareMetadataStore } from 'stores/manila/share-metadata';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class Metadata extends Base {
|
||||
init() {
|
||||
this.store = new ShareMetadataStore();
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share:get_share_metadata';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('share metadata');
|
||||
}
|
||||
|
||||
getColumns = () => [
|
||||
{
|
||||
title: t('Key'),
|
||||
dataIndex: 'keyName',
|
||||
},
|
||||
{
|
||||
title: t('Value'),
|
||||
dataIndex: 'value',
|
||||
},
|
||||
];
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
get searchFilters() {
|
||||
return [
|
||||
{
|
||||
label: t('Key'),
|
||||
name: 'keyName',
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Metadata));
|
96
src/pages/share/containers/Share/Detail/index.jsx
Normal file
96
src/pages/share/containers/Share/Detail/index.jsx
Normal file
@ -0,0 +1,96 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ShareStore } from 'stores/manila/share';
|
||||
import Base from 'containers/TabDetail';
|
||||
import { shareStatus } from 'resources/manila/share';
|
||||
import BaseDetail from './BaseDetail';
|
||||
import Metadata from './Metadata';
|
||||
import AccessRule from './AccessRule';
|
||||
import actionConfigs from '../actions';
|
||||
|
||||
export class Detail extends Base {
|
||||
get name() {
|
||||
return t('share');
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share:get';
|
||||
}
|
||||
|
||||
get listUrl() {
|
||||
return this.getRoutePath('share');
|
||||
}
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
get detailInfos() {
|
||||
return [
|
||||
{
|
||||
title: t('Name'),
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => shareStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'toLocalTime',
|
||||
},
|
||||
{
|
||||
title: t('Updated'),
|
||||
dataIndex: 'updated_at',
|
||||
valueRender: 'toLocalTime',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get tabs() {
|
||||
return [
|
||||
{
|
||||
title: t('Base Info'),
|
||||
key: 'baseInfo',
|
||||
component: BaseDetail,
|
||||
},
|
||||
{
|
||||
title: t('Metadata'),
|
||||
key: 'metadata',
|
||||
component: Metadata,
|
||||
},
|
||||
{
|
||||
title: t('Access Rule'),
|
||||
key: 'rule',
|
||||
component: AccessRule,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = new ShareStore();
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Detail));
|
267
src/pages/share/containers/Share/actions/Create.jsx
Normal file
267
src/pages/share/containers/Share/actions/Create.jsx
Normal file
@ -0,0 +1,267 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { toJS } from 'mobx';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { FormAction } from 'containers/Action';
|
||||
import globalShareStore, { ShareStore } from 'stores/manila/share';
|
||||
import { ShareNetworkStore } from 'stores/manila/share-network';
|
||||
import { ShareGroupStore } from 'stores/manila/share-group';
|
||||
import { ShareTypeStore } from 'stores/manila/share-type';
|
||||
import {
|
||||
getShareGroupColumns,
|
||||
shareGroupFilters,
|
||||
} from 'src/resources/manila/share-group';
|
||||
import {
|
||||
shareTypeColumns,
|
||||
shareTypeFilters,
|
||||
checkShareTypeSupportServer,
|
||||
shareTypeTip,
|
||||
} from 'src/resources/manila/share-type';
|
||||
import {
|
||||
getShareNetworkColumns,
|
||||
shareNetworkFilters,
|
||||
} from 'src/resources/manila/share-network';
|
||||
import { shareProtocol } from 'src/resources/manila/share';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { idNameColumn } from 'utils/table';
|
||||
import { extraFormItem } from 'pages/share/containers/ShareType/actions/Create';
|
||||
import { updateAddSelectValueToObj, getOptions } from 'utils/index';
|
||||
|
||||
export class Create extends FormAction {
|
||||
static id = 'create';
|
||||
|
||||
static title = t('Create Share');
|
||||
|
||||
static path = '/share/share/create';
|
||||
|
||||
get name() {
|
||||
return t('create share');
|
||||
}
|
||||
|
||||
get listUrl() {
|
||||
return this.getRoutePath('share');
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareStore;
|
||||
this.networkStore = new ShareNetworkStore();
|
||||
this.shareTypeStore = new ShareTypeStore();
|
||||
this.shareStore = new ShareStore();
|
||||
this.shareGroupStore = new ShareGroupStore();
|
||||
this.shareStore.fetchQuota();
|
||||
this.shareTypeStore.fetchList();
|
||||
this.networkStore.fetchList();
|
||||
this.shareGroupStore.fetchList();
|
||||
this.shareStore.fetchAvailableZones();
|
||||
this.state.showNetworks = false;
|
||||
this.state.shareGroups = [];
|
||||
}
|
||||
|
||||
static policy = 'manila:share:create';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get defaultValue() {
|
||||
const size = this.quotaIsLimit && this.maxSize < 10 ? this.maxSize : 10;
|
||||
const values = {
|
||||
size,
|
||||
project: this.currentProjectName,
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
onShareTypeChange = (value) => {
|
||||
const { selectedRows = [], selectedRowKeys = [] } = value;
|
||||
if (selectedRows.length === 0) {
|
||||
this.setState({ showNetworks: false, shareGroups: [] });
|
||||
return;
|
||||
}
|
||||
const disabledItem = selectedRows.some((it) => {
|
||||
return !checkShareTypeSupportServer(it);
|
||||
});
|
||||
const shareGroups = (this.shareGroupStore.list.data || []).filter((it) => {
|
||||
return (it.share_types || []).includes(selectedRowKeys[0]);
|
||||
});
|
||||
this.setState({
|
||||
showNetworks: !disabledItem,
|
||||
shareGroups,
|
||||
});
|
||||
};
|
||||
|
||||
get quota() {
|
||||
const { shares: { limit = 10, in_use = 0, reserved = 0 } = {} } =
|
||||
toJS(this.shareStore.quotaSet) || {};
|
||||
if (limit === -1) {
|
||||
return Infinity;
|
||||
}
|
||||
return limit - in_use - reserved;
|
||||
}
|
||||
|
||||
get quotaIsLimit() {
|
||||
const { gigabytes: { limit } = {} } = toJS(this.shareStore.quotaSet) || {};
|
||||
return limit !== -1;
|
||||
}
|
||||
|
||||
get maxSize() {
|
||||
const { gigabytes: { limit = 10, in_use = 0, reserved = 0 } = {} } =
|
||||
toJS(this.shareStore.quotaSet) || {};
|
||||
return limit - in_use - reserved;
|
||||
}
|
||||
|
||||
get shareTypeColumns() {
|
||||
const [, ...rest] = cloneDeep(shareTypeColumns);
|
||||
return [idNameColumn, ...rest];
|
||||
}
|
||||
|
||||
get shareNetworkColumns() {
|
||||
const [, ...rest] = getShareNetworkColumns(this);
|
||||
return [idNameColumn, ...rest];
|
||||
}
|
||||
|
||||
get shareGroupColumns() {
|
||||
const [, ...rest] = getShareGroupColumns(this);
|
||||
return [idNameColumn, ...rest];
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
const { showNetworks = false, shareGroups = [] } = this.state;
|
||||
const minSize = 1;
|
||||
const metadataItem = {
|
||||
...extraFormItem,
|
||||
name: 'metadata',
|
||||
label: t('Metadata'),
|
||||
addText: t('Add Metadata'),
|
||||
};
|
||||
return [
|
||||
{
|
||||
name: 'project',
|
||||
label: t('Project'),
|
||||
type: 'label',
|
||||
},
|
||||
{
|
||||
name: 'availability_zone',
|
||||
label: t('Availability Zone'),
|
||||
type: 'select',
|
||||
options: this.shareStore.zoneOptions,
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
label: t('Name'),
|
||||
type: 'input-name',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
type: 'textarea',
|
||||
},
|
||||
{
|
||||
name: 'share_proto',
|
||||
label: t('Share Protocol'),
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: getOptions(shareProtocol),
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
label: t('Capacity (GB)'),
|
||||
type: 'slider-input',
|
||||
max: this.maxSize,
|
||||
min: minSize,
|
||||
description: `${minSize}GB-${this.maxSize}GB`,
|
||||
required: this.quotaIsLimit,
|
||||
display: this.quotaIsLimit,
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
label: t('Capacity (GB)'),
|
||||
type: 'input-int',
|
||||
min: minSize,
|
||||
display: !this.quotaIsLimit,
|
||||
required: !this.quotaIsLimit,
|
||||
},
|
||||
{
|
||||
name: 'is_public',
|
||||
label: t('Public'),
|
||||
type: 'check',
|
||||
content: t('Public'),
|
||||
tip: t('If set then all tenants will be able to see this share.'),
|
||||
},
|
||||
{
|
||||
name: 'shareType',
|
||||
label: t('Share Type'),
|
||||
type: 'select-table',
|
||||
required: true,
|
||||
columns: this.shareTypeColumns,
|
||||
filterParams: shareTypeFilters,
|
||||
isLoading: this.shareTypeStore.list.isLoading,
|
||||
data: this.shareTypeStore.list.data || [],
|
||||
onChange: this.onShareTypeChange,
|
||||
extra: shareTypeTip,
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'shareNetwork',
|
||||
label: t('Share Network'),
|
||||
type: 'select-table',
|
||||
columns: this.shareNetworkColumns,
|
||||
filterParams: shareNetworkFilters,
|
||||
isLoading: this.networkStore.list.isLoading,
|
||||
data: this.networkStore.list.data || [],
|
||||
display: showNetworks,
|
||||
},
|
||||
{
|
||||
name: 'shareGroup',
|
||||
label: t('Share Group'),
|
||||
type: 'select-table',
|
||||
columns: this.shareGroupColumns,
|
||||
filterParams: shareGroupFilters,
|
||||
isLoading: this.shareGroupStore.list.isLoading,
|
||||
data: shareGroups,
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
metadataItem,
|
||||
];
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { shareType, shareNetwork, shareGroup, project, metadata, ...rest } =
|
||||
values;
|
||||
const { showNetworks = false } = this.state;
|
||||
const body = {
|
||||
...rest,
|
||||
share_type: shareType.selectedRowKeys[0],
|
||||
metadata: updateAddSelectValueToObj(metadata),
|
||||
};
|
||||
const { selectedRowKeys: networkKeys = [] } = shareNetwork || {};
|
||||
const { selectedRowKeys: groupKeys = [] } = shareGroup || {};
|
||||
if (showNetworks && networkKeys.length) {
|
||||
body.share_network_id = networkKeys[0];
|
||||
}
|
||||
if (groupKeys.length) {
|
||||
body.share_group_id = groupKeys[0];
|
||||
}
|
||||
return this.store.create(body);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Create));
|
42
src/pages/share/containers/Share/actions/Delete.jsx
Normal file
42
src/pages/share/containers/Share/actions/Delete.jsx
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ConfirmAction } from 'containers/Action';
|
||||
import globalShareStore from 'stores/manila/share';
|
||||
|
||||
export default class Delete extends ConfirmAction {
|
||||
get id() {
|
||||
return 'delete';
|
||||
}
|
||||
|
||||
get title() {
|
||||
return t('Delete Share');
|
||||
}
|
||||
|
||||
get buttonType() {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
get buttonText() {
|
||||
return t('Delete');
|
||||
}
|
||||
|
||||
get actionName() {
|
||||
return t('Delete Share');
|
||||
}
|
||||
|
||||
policy = 'manila:share:delete';
|
||||
|
||||
onSubmit = (data) => globalShareStore.delete(data);
|
||||
}
|
71
src/pages/share/containers/Share/actions/Edit.jsx
Normal file
71
src/pages/share/containers/Share/actions/Edit.jsx
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareStore from 'stores/manila/share';
|
||||
|
||||
export class Edit extends ModalAction {
|
||||
static id = 'edit';
|
||||
|
||||
static title = t('Edit');
|
||||
|
||||
get defaultValue() {
|
||||
const { name, description, is_public } = this.item;
|
||||
const value = {
|
||||
display_name: name,
|
||||
display_description: description,
|
||||
is_public,
|
||||
};
|
||||
return value;
|
||||
}
|
||||
|
||||
static policy = 'manila:share:update';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'display_name',
|
||||
label: t('Name'),
|
||||
type: 'input-name',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'display_description',
|
||||
label: t('Description'),
|
||||
type: 'textarea',
|
||||
},
|
||||
{
|
||||
name: 'is_public',
|
||||
label: t('Public'),
|
||||
type: 'check',
|
||||
content: t('Public'),
|
||||
tip: t('If set then all tenants will be able to see this share.'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareStore;
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { id } = this.item;
|
||||
return this.store.update(id, values);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Edit));
|
@ -0,0 +1,44 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { getPath } from 'utils/route-map';
|
||||
import { FormAction } from 'containers/Action';
|
||||
|
||||
export class ManageAccessRule extends FormAction {
|
||||
static id = 'manage-access-rule';
|
||||
|
||||
static title = t('Manage Access Rule');
|
||||
|
||||
static path = (item, containerProp) => {
|
||||
const { isAdminPage } = containerProp;
|
||||
const key = isAdminPage ? 'shareDetailAdmin' : 'shareDetail';
|
||||
const { id } = item;
|
||||
return getPath({ key, params: { id }, query: { tab: 'rule' } });
|
||||
};
|
||||
|
||||
get listUrl() {
|
||||
return this.getRoutePath('share');
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('Manage Access Rule');
|
||||
}
|
||||
|
||||
static policy = 'manila:share_access_rule:index';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ManageAccessRule));
|
44
src/pages/share/containers/Share/actions/ManageMetadata.jsx
Normal file
44
src/pages/share/containers/Share/actions/ManageMetadata.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { getPath } from 'utils/route-map';
|
||||
import { FormAction } from 'containers/Action';
|
||||
|
||||
export class ManageMetadata extends FormAction {
|
||||
static id = 'manage-metadata';
|
||||
|
||||
static title = t('Manage Metadata');
|
||||
|
||||
static path = (item, containerProp) => {
|
||||
const { isAdminPage } = containerProp;
|
||||
const key = isAdminPage ? 'shareDetailAdmin' : 'shareDetail';
|
||||
const { id } = item;
|
||||
return getPath({ key, params: { id }, query: { tab: 'metadata' } });
|
||||
};
|
||||
|
||||
get listUrl() {
|
||||
return this.getRoutePath('share');
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('Manage Metadata');
|
||||
}
|
||||
|
||||
static policy = 'manila:share:update_share_metadata';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ManageMetadata));
|
49
src/pages/share/containers/Share/actions/index.jsx
Normal file
49
src/pages/share/containers/Share/actions/index.jsx
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Create from './Create';
|
||||
import Delete from './Delete';
|
||||
import Edit from './Edit';
|
||||
import ManageMetadata from './ManageMetadata';
|
||||
import ManageAccessRule from './ManageAccessRule';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: Edit,
|
||||
moreActions: [
|
||||
{
|
||||
action: Delete,
|
||||
},
|
||||
{
|
||||
action: ManageMetadata,
|
||||
},
|
||||
{
|
||||
action: ManageAccessRule,
|
||||
},
|
||||
],
|
||||
},
|
||||
primaryActions: [Create],
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
const actionConfigsAdmin = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [],
|
||||
},
|
||||
primaryActions: [],
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
export default { actionConfigs, actionConfigsAdmin };
|
138
src/pages/share/containers/Share/index.jsx
Normal file
138
src/pages/share/containers/Share/index.jsx
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalShareStore, { ShareStore } from 'stores/manila/share';
|
||||
import { shareStatus, shareProtocol } from 'resources/manila/share';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class Share extends Base {
|
||||
init() {
|
||||
this.store = globalShareStore;
|
||||
this.downloadStore = new ShareStore();
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share:get_all';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('share');
|
||||
}
|
||||
|
||||
get isFilterByBackend() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
getColumns = () => [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: this.getRouteName('shareDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Project ID/Name'),
|
||||
dataIndex: 'project_name',
|
||||
isHideable: true,
|
||||
hidden: !this.isAdminPage,
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Availability Zone'),
|
||||
dataIndex: 'availability_zone',
|
||||
},
|
||||
{
|
||||
title: t('Share Type'),
|
||||
dataIndex: 'share_type_name',
|
||||
render: (value, record) => value || record.share_type,
|
||||
},
|
||||
{
|
||||
title: t('Size'),
|
||||
dataIndex: 'size',
|
||||
render: (value) => `${value}GiB`,
|
||||
},
|
||||
{
|
||||
title: t('Protocol'),
|
||||
dataIndex: 'share_proto',
|
||||
render: (value) => shareProtocol[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Public'),
|
||||
dataIndex: 'is_public',
|
||||
isHideable: true,
|
||||
valueRender: 'yesNo',
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => shareStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Share Network'),
|
||||
dataIndex: 'share_network_id',
|
||||
isHideable: true,
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender('shareNetworkDetail', value, {
|
||||
id: value,
|
||||
});
|
||||
return link;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Share Group'),
|
||||
dataIndex: 'share_group_id',
|
||||
isHideable: true,
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender('shareGroupDetail', value, {
|
||||
id: value,
|
||||
});
|
||||
return link;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
isHideable: true,
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
];
|
||||
|
||||
get searchFilters() {
|
||||
return [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Share));
|
@ -17,7 +17,10 @@ import Base from 'containers/List';
|
||||
import globalShareGroupStore, {
|
||||
ShareGroupStore,
|
||||
} from 'stores/manila/share-group';
|
||||
import { shareGroupStatus } from 'resources/manila/share-group';
|
||||
import {
|
||||
getShareGroupColumns,
|
||||
shareGroupFilters,
|
||||
} from 'resources/manila/share-group';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class ShareGroup extends Base {
|
||||
@ -44,59 +47,10 @@ export class ShareGroup extends Base {
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
getColumns = () => [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: this.getRouteName('shareGroupDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Project ID/Name'),
|
||||
dataIndex: 'project_name',
|
||||
isHideable: true,
|
||||
hidden: !this.isAdminPage,
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: t('Availability Zone'),
|
||||
dataIndex: 'availability_zone',
|
||||
},
|
||||
{
|
||||
title: t('Share Network'),
|
||||
dataIndex: 'share_network_id',
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = this.getLinkRender('shareNetworkDetail', value, {
|
||||
id: value,
|
||||
});
|
||||
return link;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => shareGroupStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
isHideable: true,
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
];
|
||||
getColumns = () => getShareGroupColumns(this);
|
||||
|
||||
get searchFilters() {
|
||||
return [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
];
|
||||
return shareGroupFilters;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,17 @@ import { isEmpty } from 'lodash';
|
||||
import { yesNoOptions } from 'resources/manila/share-type';
|
||||
import { updateAddSelectValueToObj } from 'utils/index';
|
||||
|
||||
const checkKeyValue = (values) => {
|
||||
export const keyValueValidator = (rule, values) => {
|
||||
if (isEmpty(values)) {
|
||||
return true;
|
||||
return Promise.resolve();
|
||||
}
|
||||
const item = values.find((it) => {
|
||||
const { key, value } = it.value || {};
|
||||
return !key || value === undefined || value === null;
|
||||
return !key || !value;
|
||||
});
|
||||
return !item;
|
||||
return item
|
||||
? Promise.reject(t('Please enter complete key value!'))
|
||||
: Promise.resolve();
|
||||
};
|
||||
|
||||
export const extraFormItem = {
|
||||
@ -40,13 +42,7 @@ export const extraFormItem = {
|
||||
itemComponent: KeyValueInput,
|
||||
addText: t('Add Extra Spec'),
|
||||
keySpan: 8,
|
||||
validator: (rule, value) => {
|
||||
if (!checkKeyValue(value)) {
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
return Promise.reject(t('Please enter complete key value!'));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
validator: keyValueValidator,
|
||||
};
|
||||
|
||||
export class Create extends ModalAction {
|
||||
|
@ -24,6 +24,9 @@ import ShareNetwork from '../containers/ShareNetwork';
|
||||
import ShareNetworkDetail from '../containers/ShareNetwork/Detail';
|
||||
import ShareGroup from '../containers/ShareGroup';
|
||||
import ShareGroupDetail from '../containers/ShareGroup/Detail';
|
||||
import Share from '../containers/Share';
|
||||
import ShareDetail from '../containers/Share/Detail';
|
||||
import ShareCreate from '../containers/Share/actions/Create';
|
||||
|
||||
const PATH = '/share';
|
||||
export default [
|
||||
@ -97,6 +100,31 @@ export default [
|
||||
component: ShareGroupDetail,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share`,
|
||||
component: Share,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share/detail/:id`,
|
||||
component: ShareDetail,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share/create`,
|
||||
component: ShareCreate,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-admin`,
|
||||
component: Share,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-admin/detail/:id`,
|
||||
component: ShareDetail,
|
||||
exact: true,
|
||||
},
|
||||
{ path: '*', component: E404 },
|
||||
],
|
||||
},
|
||||
|
@ -448,7 +448,6 @@ export class Create extends FormAction {
|
||||
description: `${minSize}GB-${this.maxSize}GB`,
|
||||
required: this.quotaIsLimit,
|
||||
hidden: !this.quotaIsLimit,
|
||||
onChange: this.onChangeSize,
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
@ -457,7 +456,6 @@ export class Create extends FormAction {
|
||||
min: minSize,
|
||||
hidden: this.quotaIsLimit,
|
||||
required: !this.quotaIsLimit,
|
||||
onChange: this.onChangeSize,
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
|
@ -23,6 +23,6 @@ export const shareGroupTypeColumns = [
|
||||
export const shareGroupTypeFilters = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'name',
|
||||
label: t('Name'),
|
||||
},
|
||||
];
|
||||
|
@ -4,3 +4,59 @@ export const shareGroupStatus = {
|
||||
creating: t('Creating'),
|
||||
deleting: t('Deleting'),
|
||||
};
|
||||
|
||||
export const getShareGroupColumns = (self) => {
|
||||
return [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: self.getRouteName('shareGroupDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Project ID/Name'),
|
||||
dataIndex: 'project_name',
|
||||
isHideable: true,
|
||||
hidden: !self.isAdminPage,
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Availability Zone'),
|
||||
dataIndex: 'availability_zone',
|
||||
},
|
||||
{
|
||||
title: t('Share Network'),
|
||||
dataIndex: 'share_network_id',
|
||||
render: (value) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
const link = self.getLinkRender('shareNetworkDetail', value, {
|
||||
id: value,
|
||||
});
|
||||
return link;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => shareGroupStatus[value] || value,
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
isHideable: true,
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const shareGroupFilters = [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
];
|
||||
|
@ -18,6 +18,7 @@ export const getShareNetworkColumns = (self) => {
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Neutron Net'),
|
||||
@ -74,6 +75,6 @@ export const getShareNetworkColumns = (self) => {
|
||||
export const shareNetworkFilters = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'name',
|
||||
label: t('Name'),
|
||||
},
|
||||
];
|
||||
|
@ -25,7 +25,7 @@ export const shareTypeColumns = [
|
||||
export const shareTypeFilters = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'name',
|
||||
label: t('Name'),
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -36,3 +36,26 @@ export const replicaState = {
|
||||
in_sync: t('Syncing'),
|
||||
out_of_sync: t('Out of Sync'),
|
||||
};
|
||||
|
||||
export const shareProtocol = {
|
||||
NFS: t('NFS'),
|
||||
CIFS: t('CIFS'),
|
||||
GlusterFS: t('GlusterFS'),
|
||||
HDFS: t('HDFS'),
|
||||
CephFS: t('CephFS'),
|
||||
MAPRFS: t('MAPRFS'),
|
||||
};
|
||||
|
||||
export const shareVisibility = {
|
||||
public: t('Public'),
|
||||
private: t('Private'),
|
||||
};
|
||||
|
||||
export const shareAccessRuleState = {
|
||||
new: t('New'),
|
||||
active: t('Active'),
|
||||
error: t('Error'),
|
||||
queued_to_apply: t('Queued To Apply'),
|
||||
queued_to_deny: t('Queued To Deny'),
|
||||
denying: t('Denying'),
|
||||
};
|
||||
|
@ -413,13 +413,13 @@ export default class BaseStore {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
parseMarker(data, result, allData) {
|
||||
parseMarker(data, result, allData, params) {
|
||||
return data.length === 0 ? '' : get(data[data.length - 1], this.markerKey);
|
||||
}
|
||||
|
||||
@action
|
||||
updateMarker(data, page, result, allData) {
|
||||
const marker = this.parseMarker(data, result, allData);
|
||||
updateMarker(data, page, result, allData, params) {
|
||||
const marker = this.parseMarker(data, result, allData, params);
|
||||
if (page === 1) {
|
||||
this.list.markers = [marker];
|
||||
} else {
|
||||
@ -457,7 +457,7 @@ export default class BaseStore {
|
||||
this.list.isLoading = true;
|
||||
// todo: no page, no limit, fetch all
|
||||
const { tab, all_projects, ...rest } = filters;
|
||||
const params = { limit, ...rest };
|
||||
const params = { limit, ...rest, current: page };
|
||||
this.updateParamsSortPage(params, sortKey, sortOrder);
|
||||
if (all_projects) {
|
||||
if (!this.listFilterByProject) {
|
||||
@ -472,7 +472,7 @@ export default class BaseStore {
|
||||
const newParams = this.paramsFuncPage(params, all_projects);
|
||||
const result = await this.requestListByPage(newParams, page, filters);
|
||||
const allData = this.getListDataFromResult(result);
|
||||
this.updateMarker(allData, page, result, allData);
|
||||
this.updateMarker(allData, page, result, allData, params);
|
||||
const allDataNew = allData.map(this.mapperBeforeFetchProject);
|
||||
let newData = await this.listDidFetchProject(allDataNew, all_projects);
|
||||
newData = await this.listDidFetch(newData, all_projects, filters);
|
||||
|
@ -63,6 +63,10 @@ export class ProjectStore extends Base {
|
||||
return client.neutron.quotas;
|
||||
}
|
||||
|
||||
get shareQuotaClient() {
|
||||
return client.manila.quotaSets;
|
||||
}
|
||||
|
||||
async fetchProjects(filters) {
|
||||
const { tags } = filters;
|
||||
|
||||
@ -190,6 +194,10 @@ export class ProjectStore extends Base {
|
||||
return globalRootStore.checkEndpoint('cinder');
|
||||
}
|
||||
|
||||
get enableShare() {
|
||||
return globalRootStore.checkEndpoint('manilav2');
|
||||
}
|
||||
|
||||
@action
|
||||
async enable({ id }) {
|
||||
const reqBody = {
|
||||
@ -283,24 +291,40 @@ export class ProjectStore extends Base {
|
||||
this.novaQuotaClient.detail(project_id),
|
||||
this.neutronQuotaClient.details(project_id),
|
||||
];
|
||||
if (this.enableCinder) {
|
||||
promiseArr.push(
|
||||
this.cinderQuotaClient.show(project_id, { usage: 'True' })
|
||||
);
|
||||
}
|
||||
const [novaResult, neutronResult, cinderResult = {}] = await Promise.all(
|
||||
promiseArr
|
||||
promiseArr.push(
|
||||
this.enableCinder
|
||||
? this.cinderQuotaClient.show(project_id, { usage: 'True' })
|
||||
: null
|
||||
);
|
||||
promiseArr.push(
|
||||
this.enableShare ? this.shareQuotaClient.showDetail(project_id) : null
|
||||
);
|
||||
const [novaResult, neutronResult, cinderResult, shareResult] =
|
||||
await Promise.all(promiseArr);
|
||||
this.isSubmitting = false;
|
||||
const { quota_set: novaQuota } = novaResult;
|
||||
const { ram } = novaQuota;
|
||||
const { quota_set: cinderQuota = {} } = cinderResult;
|
||||
const { quota_set: cinderQuota = {} } = cinderResult || {};
|
||||
const { quota: neutronQuota } = neutronResult;
|
||||
const { quota_set: shareQuota = {} } = shareResult || {};
|
||||
novaQuota.ram = {
|
||||
in_use: getGBValue(ram.in_use),
|
||||
limit: ram.limit === -1 ? ram.limit : getGBValue(ram.limit),
|
||||
};
|
||||
const quota = { ...novaQuota, ...cinderQuota, ...neutronQuota };
|
||||
const renameShareQuota = Object.keys(shareQuota).reduce((pre, cur) => {
|
||||
if (cur === 'gigabytes') {
|
||||
pre.share_gigabytes = shareQuota[cur];
|
||||
} else {
|
||||
pre[cur] = shareQuota[cur];
|
||||
}
|
||||
return pre;
|
||||
}, {});
|
||||
const quota = {
|
||||
...novaQuota,
|
||||
...cinderQuota,
|
||||
...neutronQuota,
|
||||
...renameShareQuota,
|
||||
};
|
||||
const quotaKey = Object.keys(quota);
|
||||
quotaKey.forEach((it) => {
|
||||
if (quota[it].in_use !== undefined) {
|
||||
|
83
src/stores/manila/share-access-rule.js
Normal file
83
src/stores/manila/share-access-rule.js
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
export class ShareAccessRuleStore extends Base {
|
||||
get client() {
|
||||
return client.manila.shareAccessRules;
|
||||
}
|
||||
|
||||
get shareClient() {
|
||||
return client.manila.shares;
|
||||
}
|
||||
|
||||
get listResponseKey() {
|
||||
return this.responseKey;
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return (params) => {
|
||||
const { id, ...rest } = params;
|
||||
return {
|
||||
...rest,
|
||||
share_id: id,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
update(id, data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(this.client.update(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
create(id, data) {
|
||||
const body = {
|
||||
allow_access: data,
|
||||
};
|
||||
return this.submitting(this.shareClient.action(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
delete = (id, accessId) => {
|
||||
const body = {
|
||||
deny_access: {
|
||||
access_id: accessId,
|
||||
},
|
||||
};
|
||||
return this.submitting(this.shareClient.action(id, body));
|
||||
};
|
||||
|
||||
@action
|
||||
manageMetadata = async (id, updates, dels) => {
|
||||
if (!isEmpty(updates)) {
|
||||
await this.client.updateMetadata(id, {
|
||||
metadata: updates,
|
||||
});
|
||||
}
|
||||
const delReqs = dels.map((key) => {
|
||||
return this.client.metadata.delete(id, key);
|
||||
});
|
||||
return this.submitting(Promise.all(delReqs));
|
||||
};
|
||||
}
|
||||
|
||||
const globalShareAccessRuleStore = new ShareAccessRuleStore();
|
||||
export default globalShareAccessRuleStore;
|
58
src/stores/manila/share-metadata.js
Normal file
58
src/stores/manila/share-metadata.js
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2021 99cloud
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
|
||||
export class ShareMetadataStore extends Base {
|
||||
get client() {
|
||||
return client.manila.shares.metadata;
|
||||
}
|
||||
|
||||
get isSubResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getFatherResourceId = (params) => params.id;
|
||||
|
||||
getListDataFromResult = (result) => {
|
||||
const { metadata } = result;
|
||||
const data = [];
|
||||
Object.keys(metadata).forEach((key) => {
|
||||
data.push({
|
||||
id: key,
|
||||
keyName: key,
|
||||
name: key,
|
||||
value: metadata[key],
|
||||
});
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
@action
|
||||
createOrUpdate(id, data) {
|
||||
const body = {
|
||||
metadata: data,
|
||||
};
|
||||
return this.submitting(this.client.create(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
delete = ({ id, keyName }) => {
|
||||
return this.submitting(this.client.delete(id, keyName));
|
||||
};
|
||||
}
|
||||
const globalShareMetadataStore = new ShareMetadataStore();
|
||||
export default globalShareMetadataStore;
|
@ -23,6 +23,9 @@ export class ShareStore extends Base {
|
||||
@observable
|
||||
zoneOptions = [];
|
||||
|
||||
@observable
|
||||
quotaSet = {};
|
||||
|
||||
get client() {
|
||||
return client.manila.shares;
|
||||
}
|
||||
@ -31,10 +34,49 @@ export class ShareStore extends Base {
|
||||
return client.manila.azones;
|
||||
}
|
||||
|
||||
get accessClient() {
|
||||
return client.manila.shareAccessRules;
|
||||
}
|
||||
|
||||
get quotaClient() {
|
||||
return client.manila.quotaSets;
|
||||
}
|
||||
|
||||
get shareGroupClient() {
|
||||
return client.manila.shareGroups;
|
||||
}
|
||||
|
||||
get shareNetworkClient() {
|
||||
return client.manila.shareNetworks;
|
||||
}
|
||||
|
||||
get listWithDetail() {
|
||||
return true;
|
||||
}
|
||||
|
||||
parseMarker() {
|
||||
return '';
|
||||
}
|
||||
|
||||
updateMarkerParams = (limit, marker) => ({
|
||||
limit,
|
||||
offset: marker,
|
||||
});
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params) => {
|
||||
const { current = 1, all_projects, limit = 10, ...rest } = params;
|
||||
const marker = current === 1 ? '' : (current - 1) * limit;
|
||||
return {
|
||||
...rest,
|
||||
// with_count: 'True',
|
||||
all_tenants: all_projects ? 1 : 0,
|
||||
offset: marker,
|
||||
limit,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchAvailableZones() {
|
||||
const { availability_zones: zones = [] } = await this.zoneClient.list();
|
||||
@ -46,6 +88,41 @@ export class ShareStore extends Base {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async detailDidFetch(item) {
|
||||
const { id, share_group_id, share_network_id } = item || {};
|
||||
const newItem = { ...item };
|
||||
const reqs = [
|
||||
this.client.exportLocations.list(id),
|
||||
this.accessClient.list({ share_id: id }),
|
||||
share_group_id ? this.shareGroupClient.show(share_group_id) : null,
|
||||
share_network_id ? this.shareNetworkClient.show(share_network_id) : null,
|
||||
];
|
||||
const [exportLocationResult, accessResult, groupResult, networkResult] =
|
||||
await Promise.all(reqs);
|
||||
newItem.exportLocations = exportLocationResult.export_locations;
|
||||
if (share_group_id) {
|
||||
newItem.shareGroup = groupResult.share_group;
|
||||
}
|
||||
if (share_network_id) {
|
||||
newItem.shareNetwork = networkResult.share_network;
|
||||
}
|
||||
newItem.accessList = accessResult.access_list;
|
||||
return newItem;
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchQuota() {
|
||||
const result = await this.quotaClient.showDetail(this.currentProjectId);
|
||||
this.quotaSet = result.quota_set;
|
||||
}
|
||||
|
||||
@action
|
||||
update(id, data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(this.client.update(id, body));
|
||||
}
|
||||
}
|
||||
|
||||
const globalShareStore = new ShareStore();
|
||||
|
Loading…
Reference in New Issue
Block a user