feat: update dns zone
1. fix dns zone api fetch in the zone list page 2. udpate create dns zone 3. update dns zone list 4. update dns zone detail 5. update edit dns zone 6. update delete dns zone Closes-Bug: #2032857 Change-Id: Ieb5023f8596c1c401ad2d0868c99f0155c1c45a8
This commit is contained in:
parent
521b965a23
commit
28c14c426c
@ -29,7 +29,7 @@ export class DesignateClient extends Base {
|
||||
key: 'recordsets',
|
||||
responseKey: 'recordset',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'reverse',
|
||||
@ -53,7 +53,8 @@ export class DesignateClient extends Base {
|
||||
key: 'setReverse',
|
||||
generate: (id, data) =>
|
||||
this.request.patch(
|
||||
this.getSubResourceUrlById('reverse', id, 'floatingips'), data,
|
||||
this.getSubResourceUrlById('reverse', id, 'floatingips'),
|
||||
data,
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
@ -66,7 +67,8 @@ export class DesignateClient extends Base {
|
||||
key: 'unsetReverse',
|
||||
generate: (id, data) =>
|
||||
this.request.patch(
|
||||
this.getSubResourceUrlById('reverse', id, 'floatingips'), data,
|
||||
this.getSubResourceUrlById('reverse', id, 'floatingips'),
|
||||
data,
|
||||
null,
|
||||
{
|
||||
headers: {
|
||||
@ -81,11 +83,11 @@ export class DesignateClient extends Base {
|
||||
key: 'floatingips',
|
||||
responseKey: 'floatingip',
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const designateClient = new DesignateClient();
|
||||
export default designateClient;
|
||||
export default designateClient;
|
||||
|
@ -29,6 +29,7 @@ import barbican from './barbican';
|
||||
import zun from './zun';
|
||||
import magnum from './magnum';
|
||||
import masakari from './masakari';
|
||||
import designate from './designate';
|
||||
|
||||
const client = {
|
||||
skyline,
|
||||
@ -48,6 +49,7 @@ const client = {
|
||||
zun,
|
||||
magnum,
|
||||
masakari,
|
||||
designate,
|
||||
};
|
||||
|
||||
window.client = client;
|
||||
|
@ -195,7 +195,7 @@ export default class index extends Component {
|
||||
return (
|
||||
<Input
|
||||
value={item.value}
|
||||
placeholder={t('Please input')}
|
||||
placeholder={placeholder || t('Please input')}
|
||||
style={{ width }}
|
||||
onChange={(e) => {
|
||||
this.onItemChange(e.currentTarget.value, index);
|
||||
|
@ -887,6 +887,7 @@
|
||||
"El Salvador": "El Salvador",
|
||||
"Email": "Email",
|
||||
"Email Address": "Email Address",
|
||||
"Email for the zone. Used in SOA records for the zone.": "Email for the zone. Used in SOA records for the zone.",
|
||||
"Enable": "Enable",
|
||||
"Enable Admin State": "Enable Admin State",
|
||||
"Enable Compute Host": "Enable Compute Host",
|
||||
@ -1479,6 +1480,7 @@
|
||||
"Manageable": "Manageable",
|
||||
"Management": "Management",
|
||||
"Management Reason": "Management Reason",
|
||||
"Mandatory for secondary zones. The servers to slave from to get DNS information.": "Mandatory for secondary zones. The servers to slave from to get DNS information.",
|
||||
"Manu": "Manu",
|
||||
"Manual input": "Manual input",
|
||||
"Manually Assigned Address": "Manually Assigned Address",
|
||||
@ -1555,6 +1557,7 @@
|
||||
"Montserrat": "Montserrat",
|
||||
"More": "More",
|
||||
"More Actions": "More Actions",
|
||||
"More than one label is required, such as: \"example.org.\"": "More than one label is required, such as: \"example.org.\"",
|
||||
"Morocco": "Morocco",
|
||||
"Mount ISO": "Mount ISO",
|
||||
"Mount snapshot support": "Mount snapshot support",
|
||||
@ -1813,6 +1816,7 @@
|
||||
"Please input container name": "Please input container name",
|
||||
"Please input file name": "Please input file name",
|
||||
"Please input image": "Please input image",
|
||||
"Please input ip address": "Please input ip address",
|
||||
"Please input ipv4": "Please input ipv4",
|
||||
"Please input ipv6": "Please input ipv6",
|
||||
"Please input key": "Please input key",
|
||||
@ -1907,6 +1911,7 @@
|
||||
"Prepare Template": "Prepare Template",
|
||||
"Previous": "Previous",
|
||||
"Primary": "Primary",
|
||||
"Primary is controlled by Designate, Secondary zones are slaved from another DNS Server.": "Primary is controlled by Designate, Secondary zones are slaved from another DNS Server.",
|
||||
"Private": "Private",
|
||||
"Private Key": "Private Key",
|
||||
"Profile": "Profile",
|
||||
@ -2379,6 +2384,7 @@
|
||||
"TCP Connections": "TCP Connections",
|
||||
"TLS Disabled": "TLS Disabled",
|
||||
"TTL": "TTL",
|
||||
"TTL (Time to Live) for the zone.": "TTL (Time to Live) for the zone.",
|
||||
"Tag is no longer than 60 characters": "Tag is no longer than 60 characters",
|
||||
"Tags": "Tags",
|
||||
"Tags Info": "Tags Info",
|
||||
@ -2437,6 +2443,7 @@
|
||||
"The instances in the affinity group are strictly allocated to the same physical machine. When there are no more physical machines to allocate, the allocation fails.": "The instances in the affinity group are strictly allocated to the same physical machine. When there are no more physical machines to allocate, the allocation fails.",
|
||||
"The instances in the anti-affinity group are allocated to different physical machines as much as possible. When there are no more physical machines to allocate, the normal allocation strategy is returned.": "The instances in the anti-affinity group are allocated to different physical machines as much as possible. When there are no more physical machines to allocate, the normal allocation strategy is returned.",
|
||||
"The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.": "The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.",
|
||||
"The ip address {ip} is duplicated, please modify it.": "The ip address {ip} is duplicated, please modify it.",
|
||||
"The ip is not within the allocated pool!": "The ip is not within the allocated pool!",
|
||||
"The ip of external members can be any, including the public network ip.": "The ip of external members can be any, including the public network ip.",
|
||||
"The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.": "The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.",
|
||||
@ -2498,6 +2505,7 @@
|
||||
"The volume type needs to be consistent with the volume type when the snapshot is created.": "The volume type needs to be consistent with the volume type when the snapshot is created.",
|
||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.",
|
||||
"The working directory for commands to run in": "The working directory for commands to run in",
|
||||
"The zone name should end with \".\"": "The zone name should end with \".\"",
|
||||
"The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.",
|
||||
"The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.",
|
||||
"The {name} has already been used by other {resource}({content}), please change.": "The {name} has already been used by other {resource}({content}), please change.",
|
||||
@ -2617,7 +2625,6 @@
|
||||
"Update Status": "Update Status",
|
||||
"Update Template": "Update Template",
|
||||
"Update User Password": "Update User Password",
|
||||
"Update Zone": "Update Zone",
|
||||
"Update user password": "Update user password",
|
||||
"Updated": "Updated",
|
||||
"Updated At": "Updated At",
|
||||
|
@ -887,6 +887,7 @@
|
||||
"El Salvador": "",
|
||||
"Email": "",
|
||||
"Email Address": "",
|
||||
"Email for the zone. Used in SOA records for the zone.": "영역에 대한 이메일입니다. 영역의 SOA 레코드에 사용됩니다.",
|
||||
"Enable": "활성화",
|
||||
"Enable Admin State": "Admin State 활성화",
|
||||
"Enable Compute Host": "Compute Host 활성화",
|
||||
@ -1479,6 +1480,7 @@
|
||||
"Manageable": "관리 가능",
|
||||
"Management": "관리",
|
||||
"Management Reason": "관리 영역",
|
||||
"Mandatory for secondary zones. The servers to slave from to get DNS information.": "보조 영역의 경우 필수입니다. DNS 정보를 얻기 위해 슬레이브할 서버입니다.",
|
||||
"Manu": "",
|
||||
"Manual input": "수동 입력",
|
||||
"Manually Assigned Address": "수동으로 할당된 주소",
|
||||
@ -1555,6 +1557,7 @@
|
||||
"Montserrat": "",
|
||||
"More": "더",
|
||||
"More Actions": "추가 작업",
|
||||
"More than one label is required, such as: \"example.org.\"": "\"example.org.\"와 같이 두 개 이상의 라벨이 필요합니다.",
|
||||
"Morocco": "",
|
||||
"Mount ISO": "",
|
||||
"Mount snapshot support": "",
|
||||
@ -1813,6 +1816,7 @@
|
||||
"Please input container name": "",
|
||||
"Please input file name": "",
|
||||
"Please input image": "",
|
||||
"Please input ip address": "IP 주소를 입력해주세요",
|
||||
"Please input ipv4": "",
|
||||
"Please input ipv6": "",
|
||||
"Please input key": "",
|
||||
@ -1907,6 +1911,7 @@
|
||||
"Prepare Template": "템플릿 준비",
|
||||
"Previous": "이전",
|
||||
"Primary": "기본",
|
||||
"Primary is controlled by Designate, Secondary zones are slaved from another DNS Server.": "기본 영역은 Designate에 의해 제어되고, 보조 영역은 다른 DNS 서버에서 슬레이브됩니다.",
|
||||
"Private": "사설",
|
||||
"Private Key": "개인 키",
|
||||
"Profile": "프로필",
|
||||
@ -2379,7 +2384,8 @@
|
||||
"TCP Connections": "",
|
||||
"TLS Disabled": "",
|
||||
"TTL": "",
|
||||
"Tag is no longer than 60 characters": "",
|
||||
"TTL (Time to Live) for the zone.": "영역의 TTL(Time to Live)입니다.",
|
||||
"Tag is no longer than 60 characters": "태그는 60자(영문 기준) 이하여야 합니다.",
|
||||
"Tags": "태그",
|
||||
"Tags Info": "태그 정보",
|
||||
"Tags are not case sensitive": "",
|
||||
@ -2437,6 +2443,7 @@
|
||||
"The instances in the affinity group are strictly allocated to the same physical machine. When there are no more physical machines to allocate, the allocation fails.": "\"affinity group\"의 인스턴스는 동일한 물리적 시스템에만 할당됩니다. 할당할 물리적 시스템이 더 이상 없으면 할당이 실패합니다.",
|
||||
"The instances in the anti-affinity group are allocated to different physical machines as much as possible. When there are no more physical machines to allocate, the normal allocation strategy is returned.": "\"anti-affinity group\"의 인스턴스는 가능한 한 서로 다른 물리적 시스템에 할당됩니다. 할당할 물리적 시스템이 더 이상 없으면 일반적인 할당 전략을 따르게 됩니다.",
|
||||
"The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.": "\"anti-affinity group\"의 인스턴스는 서로 다른 물리적 시스템에만 할당됩니다. 할당할 물리적 시스템이 더 이상 없으면 할당이 실패합니다.",
|
||||
"The ip address {ip} is duplicated, please modify it.": "IP 주소 {ip}이(가) 중복되었습니다. 수정해 주세요.",
|
||||
"The ip is not within the allocated pool!": "해당 ip는 할당된 pool 안에 없습니다!",
|
||||
"The ip of external members can be any, including the public network ip.": "외부 구성원의 IP 주소는 공용 네트워크 IP를 포함하여 어떤 것이든 가능합니다.",
|
||||
"The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.": "키페어는 새로 생성한 인스턴스에 SSH로 접속할 수 있도록 해줍니다. 기존의 키페어를 선택하거나, 키페어를 가져오거나, 새로운 키페어를 생성할 수 있습니다.",
|
||||
@ -2498,6 +2505,7 @@
|
||||
"The volume type needs to be consistent with the volume type when the snapshot is created.": "볼륨 타입은 스냅샷 생성 시의 볼륨 타입과 일치해야 합니다.",
|
||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "공유 볼륨 속성을 지원하려면 메타데이터에 \"multiattach\"를 설정해야 합니다.",
|
||||
"The working directory for commands to run in": "실행할 명령의 작업 디렉토리",
|
||||
"The zone name should end with \".\"": "영역 이름은 \".\"로 끝나야 합니다.",
|
||||
"The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action} 명령이 {name} 인스턴스에 대해 실행되었습니다. 목록 데이터의 변경 사항을 확인하기 위해 몇 초를 기다리거나 수동으로 데이터를 새로 고쳐 최종 결과를 얻을 수 있습니다.",
|
||||
"The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action} 명령이 실행되었습니다. 목록 데이터의 변경 사항을 확인하려면 몇 초 기다리거나 수동으로 데이터를 새로 고쳐 최종 표시 결과를 얻을 수 있습니다.",
|
||||
"The {name} has already been used by other {resource}({content}), please change.": "{name}은(는) 이미 다른 {resource}({content})에서 사용 중입니다. 다른 이름으로 변경해주세요.",
|
||||
@ -2617,7 +2625,6 @@
|
||||
"Update Status": "상태 업데이트",
|
||||
"Update Template": "템플릿 업데이트",
|
||||
"Update User Password": "사용자 암호 업데이트",
|
||||
"Update Zone": "업데이트 존",
|
||||
"Update user password": "사용자 암호 업데이트",
|
||||
"Updated": "",
|
||||
"Updated At": "갱신 시점",
|
||||
|
@ -887,6 +887,7 @@
|
||||
"El Salvador": "萨尔瓦多",
|
||||
"Email": "邮箱",
|
||||
"Email Address": "邮箱地址",
|
||||
"Email for the zone. Used in SOA records for the zone.": "该区域的电子邮件。用于区域的 SOA 记录。",
|
||||
"Enable": "启用",
|
||||
"Enable Admin State": "启用管理状态",
|
||||
"Enable Compute Host": "启用计算节点",
|
||||
@ -1479,6 +1480,7 @@
|
||||
"Manageable": "可管理",
|
||||
"Management": "维护",
|
||||
"Management Reason": "维护原因",
|
||||
"Mandatory for secondary zones. The servers to slave from to get DNS information.": "对于次要区域是必填的。从服务器获取 DNS 信息。",
|
||||
"Manu": "手动",
|
||||
"Manual input": "手动输入",
|
||||
"Manually Assigned Address": "手动分配地址",
|
||||
@ -1488,7 +1490,7 @@
|
||||
"Master Node Addresses": "主节点地址",
|
||||
"Master Node Flavor": "主节点类型",
|
||||
"Master Node LB Enabled": "启用主节点负载均衡",
|
||||
"Masters": "主要的",
|
||||
"Masters": "主服务器",
|
||||
"Mauritania": "毛里塔尼亚",
|
||||
"Mauritius": "毛里求斯",
|
||||
"Max Avail": "最大可用量",
|
||||
@ -1555,6 +1557,7 @@
|
||||
"Montserrat": "蒙特塞拉特",
|
||||
"More": "更多",
|
||||
"More Actions": "更多操作",
|
||||
"More than one label is required, such as: \"example.org.\"": "至少需要 2 个以上标签,如:\"example.org.\"",
|
||||
"Morocco": "摩洛哥",
|
||||
"Mount ISO": "挂载ISO",
|
||||
"Mount snapshot support": "支持挂载快照",
|
||||
@ -1813,6 +1816,7 @@
|
||||
"Please input container name": "请输入容器名称",
|
||||
"Please input file name": "请输入文件名称",
|
||||
"Please input image": "请输入镜像",
|
||||
"Please input ip address": "请输入 IP 地址",
|
||||
"Please input ipv4": "请输入IPV4",
|
||||
"Please input ipv6": "请输入IPV6",
|
||||
"Please input key": "请输入键",
|
||||
@ -1907,6 +1911,7 @@
|
||||
"Prepare Template": "准备模板",
|
||||
"Previous": "上一步",
|
||||
"Primary": "主要",
|
||||
"Primary is controlled by Designate, Secondary zones are slaved from another DNS Server.": "主要区域由 Designate 控制,次要区域由另一个 DNS 服务器从属。",
|
||||
"Private": "私有",
|
||||
"Private Key": "私钥",
|
||||
"Profile": "概要",
|
||||
@ -2379,6 +2384,7 @@
|
||||
"TCP Connections": "TCP连接数",
|
||||
"TLS Disabled": "TLS禁用",
|
||||
"TTL": "TTL",
|
||||
"TTL (Time to Live) for the zone.": "区域的 TTL(生存时间)。",
|
||||
"Tag is no longer than 60 characters": "标签名长度不超过60个字符",
|
||||
"Tags": "标签",
|
||||
"Tags Info": "标签信息",
|
||||
@ -2437,6 +2443,7 @@
|
||||
"The instances in the affinity group are strictly allocated to the same physical machine. When there are no more physical machines to allocate, the allocation fails.": "将亲和组内的云主机严格分配到同一物理机上,当没有更多物理机可分配时,则分配失败。",
|
||||
"The instances in the anti-affinity group are allocated to different physical machines as much as possible. When there are no more physical machines to allocate, the normal allocation strategy is returned.": "将反亲和组内的云主机尽量分配到不同物理机上,当没有更多物理机可分配时,回归普通分配策略。",
|
||||
"The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.": "将反亲和组内的云主机严格分配到不同物理机上,当没有更多物理机可分配时,则分配失败。",
|
||||
"The ip address {ip} is duplicated, please modify it.": "IP 地址 {ip} 已重复,请修改。",
|
||||
"The ip is not within the allocated pool!": "该ip不在分配的资源池范围内!",
|
||||
"The ip of external members can be any, including the public network ip.": "外部成员的IP可以是任何IP,包括公网IP。",
|
||||
"The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.": "密钥对允许您SSH到您新创建的实例。 您可以选择一个已存在的密钥对、导入一个密钥对或生成一个新的密钥对。",
|
||||
@ -2498,6 +2505,7 @@
|
||||
"The volume type needs to be consistent with the volume type when the snapshot is created.": "创建云硬盘的云硬盘类型需要和创建快照时间点的云硬盘类型保持一致。",
|
||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "云硬盘类型需在元数据中设置\"multiattach\",才可支持共享盘属性。",
|
||||
"The working directory for commands to run in": "用于运行命令的工作目录",
|
||||
"The zone name should end with \".\"": "区域名称应以“.”结尾。",
|
||||
"The {action} instruction has been issued, instance: {name}. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action}指令已下发,实例名称:{name}。 \n 您可等待几秒关注列表数据的变更或是手动刷新数据,以获取最终展示结果。",
|
||||
"The {action} instruction has been issued. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.": "{action}指令已下发。 \n 您可等待几秒关注列表数据的变更或是手动刷新数据,以获取最终展示结果。",
|
||||
"The {name} has already been used by other {resource}({content}), please change.": "{name} 已经被其他{resource}使用({content}),请修改。",
|
||||
@ -2617,7 +2625,6 @@
|
||||
"Update Status": "更新状态",
|
||||
"Update Template": "更新模板",
|
||||
"Update User Password": "修改用户密码",
|
||||
"Update Zone": "修改区域",
|
||||
"Update user password": "修改用户密码",
|
||||
"Updated": "更新于",
|
||||
"Updated At": "更新于",
|
||||
|
@ -11,10 +11,11 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { DNSZonesStore } from 'stores/designate/zones';
|
||||
import Base from 'containers/TabDetail';
|
||||
import { ZONE_STATUS, ZONE_TYPES } from 'resources/dns/zone';
|
||||
import BaseDetail from './BaseDetail';
|
||||
import RecordSets from './RecordSets';
|
||||
import { DNSZonesStore } from 'src/stores/designate/zones';
|
||||
|
||||
export class ZonesDetail extends Base {
|
||||
init() {
|
||||
@ -30,7 +31,7 @@ export class ZonesDetail extends Base {
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'get_images';
|
||||
return 'get_zone';
|
||||
}
|
||||
|
||||
get detailInfos() {
|
||||
@ -46,15 +47,17 @@ export class ZonesDetail extends Base {
|
||||
{
|
||||
title: t('Type'),
|
||||
dataIndex: 'type',
|
||||
valueMap: ZONE_TYPES,
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
valueMap: ZONE_STATUS,
|
||||
},
|
||||
{
|
||||
title: t('Email'),
|
||||
dataIndex: 'email',
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -69,13 +72,11 @@ export class ZonesDetail extends Base {
|
||||
title: t('Record Sets'),
|
||||
key: 'record_sets',
|
||||
component: RecordSets,
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
return tabs;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ZonesDetail));
|
||||
export default inject('rootStore')(observer(ZonesDetail));
|
||||
|
@ -12,14 +12,21 @@
|
||||
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import {
|
||||
ZONE_TYPE_ENUM,
|
||||
validateZoneName,
|
||||
zoneNameMessage,
|
||||
zoneTypeOptions,
|
||||
} from 'src/resources/dns/zone';
|
||||
import globalDNSZonesStore from 'src/stores/designate/zones';
|
||||
import { emailValidate } from 'utils/validate';
|
||||
import { emailValidate, ipValidate } from 'utils/validate';
|
||||
|
||||
export class Create extends ModalAction {
|
||||
init() {
|
||||
this.store = globalDNSZonesStore;
|
||||
}
|
||||
|
||||
static id = 'create-dns-zone';
|
||||
static id = 'create_zone';
|
||||
|
||||
static title = t('Create Zone');
|
||||
|
||||
@ -31,7 +38,7 @@ export class Create extends ModalAction {
|
||||
return t('Create Zone');
|
||||
}
|
||||
|
||||
static policy = 'get_images';
|
||||
static policy = 'create_zone';
|
||||
|
||||
static allowed() {
|
||||
return Promise.resolve(true);
|
||||
@ -40,51 +47,119 @@ export class Create extends ModalAction {
|
||||
get defaultValue() {
|
||||
return {
|
||||
ttl: 3600,
|
||||
type: 'PRIMARY'
|
||||
}
|
||||
type: ZONE_TYPE_ENUM.primary,
|
||||
};
|
||||
}
|
||||
|
||||
get nameForStateUpdate() {
|
||||
return ['type'];
|
||||
}
|
||||
|
||||
validateMasters = (rule, value) => {
|
||||
if (!value || !value.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const errorItem = value.find((v) => {
|
||||
if (!v.value) {
|
||||
return true;
|
||||
}
|
||||
if (!ipValidate.isIPv4(v.value) && !!ipValidate.isIpv6(v.value)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (errorItem) {
|
||||
return Promise.reject(t('Please input a valid ip!'));
|
||||
}
|
||||
const sameItem = value.find((v) => {
|
||||
const theSame = value.find((vv) => {
|
||||
return vv.value === v.value && vv.index !== v.index;
|
||||
});
|
||||
return !!theSame;
|
||||
});
|
||||
if (sameItem) {
|
||||
return Promise.reject(
|
||||
t('The ip address {ip} is duplicated, please modify it.', {
|
||||
ip: sameItem.value,
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
get formItems() {
|
||||
const { type = ZONE_TYPE_ENUM.primary } = this.state;
|
||||
const isPrimaryType = type === ZONE_TYPE_ENUM.primary;
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
label: t('Name'),
|
||||
type: 'input',
|
||||
required: true
|
||||
required: true,
|
||||
extra: zoneNameMessage,
|
||||
validator: validateZoneName,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
type: 'textarea'
|
||||
type: 'textarea',
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: t('Type'),
|
||||
type: 'select',
|
||||
options: zoneTypeOptions,
|
||||
tip: t(
|
||||
'Primary is controlled by Designate, Secondary zones are slaved from another DNS Server.'
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
label: t('Email Address'),
|
||||
type: 'input',
|
||||
required: true,
|
||||
required: isPrimaryType,
|
||||
hidden: !isPrimaryType,
|
||||
validator: emailValidate,
|
||||
extra: t('Email for the zone. Used in SOA records for the zone.'),
|
||||
},
|
||||
{
|
||||
name: 'ttl',
|
||||
label: t('TTL'),
|
||||
type: 'input-number',
|
||||
min: 0,
|
||||
required: true
|
||||
required: isPrimaryType,
|
||||
hidden: !isPrimaryType,
|
||||
extra: t('TTL (Time to Live) for the zone.'),
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: t('Type'),
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: t('Primary'), value: 'PRIMARY' },
|
||||
{ label: t('Secondary'), value: 'SECONDARY' },
|
||||
]
|
||||
name: 'masters',
|
||||
label: t('Masters'),
|
||||
type: 'add-select',
|
||||
isInput: true,
|
||||
placeholder: t('Please input ip address'),
|
||||
tip: t(
|
||||
'Mandatory for secondary zones. The servers to slave from to get DNS information.'
|
||||
),
|
||||
minCount: 1,
|
||||
hidden: isPrimaryType,
|
||||
required: !isPrimaryType,
|
||||
validator: this.validateMasters,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
return this.store.create(values);
|
||||
const { masters = [], type, email, ttl, ...rest } = values;
|
||||
const body = {
|
||||
...rest,
|
||||
type,
|
||||
masters: masters.map((m) => m.value),
|
||||
};
|
||||
if (type === 'PRIMARY') {
|
||||
body.email = email;
|
||||
body.ttl = ttl;
|
||||
}
|
||||
return this.store.create(body);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,13 @@ export default class Delete extends ConfirmAction {
|
||||
return true;
|
||||
}
|
||||
|
||||
get isAsyncAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowedCheckFunction = () => true;
|
||||
|
||||
policy = 'instance:delete';
|
||||
policy = 'delete_zone';
|
||||
|
||||
confirmContext = (data) => {
|
||||
const name = this.getName(data);
|
||||
@ -49,4 +53,4 @@ export default class Delete extends ConfirmAction {
|
||||
onSubmit = (item) => {
|
||||
return globalDNSZonesStore.delete({ id: item.id });
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -10,85 +10,67 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import globalDNSZonesStore from 'src/stores/designate/zones';
|
||||
import { emailValidate } from 'utils/validate';
|
||||
export class Update extends ModalAction {
|
||||
import globalDNSZonesStore from 'stores/designate/zones';
|
||||
import { Create } from './Create';
|
||||
|
||||
export class Update extends Create {
|
||||
init() {
|
||||
this.store = globalDNSZonesStore;
|
||||
}
|
||||
|
||||
static id = 'update-dns-zone';
|
||||
|
||||
static title = t('Update Zone');
|
||||
static title = t('Edit');
|
||||
|
||||
get name() {
|
||||
return t('Update Zone');
|
||||
return t('Edit');
|
||||
}
|
||||
|
||||
static policy = 'get_images';
|
||||
static policy = 'update_zone';
|
||||
|
||||
static allowed() {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
get defaultValue() {
|
||||
|
||||
const { name, description, email, ttl, type } = this.props.item;
|
||||
|
||||
const { masters = [], ...rest } = this.item;
|
||||
const mastersValue = masters.map((m, index) => ({
|
||||
index,
|
||||
value: m,
|
||||
}));
|
||||
return {
|
||||
name: name,
|
||||
description: description,
|
||||
email: email,
|
||||
ttl: ttl,
|
||||
type: type
|
||||
}
|
||||
...rest,
|
||||
masters: mastersValue,
|
||||
};
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
label: t('Name'),
|
||||
type: 'input',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
type: 'textarea'
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
label: t('Email Address'),
|
||||
type: 'input',
|
||||
required: true,
|
||||
validator: emailValidate,
|
||||
},
|
||||
{
|
||||
name: 'ttl',
|
||||
label: t('TTL'),
|
||||
type: 'input-number',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
label: t('Type'),
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: t('Primary'), value: 'PRIMARY' },
|
||||
{ label: t('Secondary'), value: 'SECONDARY' },
|
||||
],
|
||||
disabled: true
|
||||
},
|
||||
]
|
||||
const items = super.formItems;
|
||||
return items.map((it) => {
|
||||
if (it.name === 'name' || it.name === 'type') {
|
||||
return {
|
||||
...it,
|
||||
disabled: true,
|
||||
};
|
||||
}
|
||||
return it;
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { id } = this.item;
|
||||
const { name, type, ...val } = values;
|
||||
return this.store.update({ id: id }, val);
|
||||
const { type } = this.item;
|
||||
const { masters = [], email, ttl, description } = values;
|
||||
const body = {
|
||||
description,
|
||||
masters: masters.map((m) => m.value),
|
||||
};
|
||||
if (type === 'PRIMARY') {
|
||||
body.email = email;
|
||||
body.ttl = ttl;
|
||||
}
|
||||
return this.store.update({ id }, body);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,10 @@ import CreateRecords from './Records/Create';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: CreateRecords,
|
||||
firstAction: Update,
|
||||
moreActions: [
|
||||
{
|
||||
action: Update,
|
||||
action: CreateRecords,
|
||||
},
|
||||
{
|
||||
action: Delete,
|
||||
@ -30,7 +30,7 @@ const actionConfigs = {
|
||||
],
|
||||
},
|
||||
primaryActions: [Create],
|
||||
batchActions: [Delete]
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
export default actionConfigs;
|
||||
|
@ -13,6 +13,7 @@
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalDNSZonesStore, { DNSZonesStore } from 'src/stores/designate/zones';
|
||||
import { ZONE_STATUS, ZONE_TYPES } from 'resources/dns/zone';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class Zones extends Base {
|
||||
@ -22,7 +23,7 @@ export class Zones extends Base {
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'get_images';
|
||||
return 'get_zones';
|
||||
}
|
||||
|
||||
get name() {
|
||||
@ -39,22 +40,29 @@ export class Zones extends Base {
|
||||
dataIndex: 'name',
|
||||
isHideable: true,
|
||||
isLink: true,
|
||||
routeName: 'dnsZonesDetail'
|
||||
routeName: 'dnsZonesDetail',
|
||||
},
|
||||
{
|
||||
title: t('Type'),
|
||||
dataIndex: 'type',
|
||||
isHideable: true,
|
||||
sorter: false
|
||||
sorter: false,
|
||||
valueMap: ZONE_TYPES,
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
isHideable: true,
|
||||
valueMap: ZONE_STATUS,
|
||||
sorter: false,
|
||||
},
|
||||
]
|
||||
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'sinceTime',
|
||||
sorter: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Zones));
|
||||
export default inject('rootStore')(observer(Zones));
|
||||
|
39
src/resources/dns/zone.js
Normal file
39
src/resources/dns/zone.js
Normal file
@ -0,0 +1,39 @@
|
||||
import { getOptions } from 'utils';
|
||||
|
||||
export const ZONE_TYPE_ENUM = {
|
||||
primary: 'PRIMARY',
|
||||
secondary: 'SECONDARY',
|
||||
};
|
||||
|
||||
export const ZONE_TYPES = {
|
||||
[ZONE_TYPE_ENUM.primary]: t('Primary'),
|
||||
[ZONE_TYPE_ENUM.secondary]: t('Secondary'),
|
||||
};
|
||||
|
||||
export const zoneTypeOptions = getOptions(ZONE_TYPES);
|
||||
|
||||
export const zoneNameRegex = /^.+\.$/;
|
||||
|
||||
export const zoneNameMessage = t('The zone name should end with "."');
|
||||
|
||||
export const validateZoneName = (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!zoneNameRegex.test(value)) {
|
||||
return Promise.reject(zoneNameMessage);
|
||||
}
|
||||
const labels = value.trim().split('.');
|
||||
if (labels.length <= 1) {
|
||||
return Promise.reject(
|
||||
new Error(t('More than one label is required, such as: "example.org."'))
|
||||
);
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const ZONE_STATUS = {
|
||||
ACTIVE: t('Active'),
|
||||
PENDING: t('Pending'),
|
||||
ERROR: t('Error'),
|
||||
};
|
@ -15,7 +15,6 @@ import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
|
||||
export class DNSZonesStore extends Base {
|
||||
|
||||
get client() {
|
||||
return client.designate.zones;
|
||||
}
|
||||
@ -30,8 +29,7 @@ export class DNSZonesStore extends Base {
|
||||
|
||||
@action
|
||||
update = ({ id }, body) => this.submitting(this.client.patch(id, body));
|
||||
|
||||
}
|
||||
|
||||
const globalDNSZonesStore = new DNSZonesStore();
|
||||
export default globalDNSZonesStore;
|
||||
export default globalDNSZonesStore;
|
||||
|
Loading…
Reference in New Issue
Block a user