blob: 30a9e8cb41dacffa7dfdd268ecc88a2ccb8250ae [file] [log] [blame]
<template>
<div class="app-container">
<div class="createPost-container">
<el-form :inline="true" :model="postForm" class="form-container">
<el-form-item class="postInfo-container-item" label="Cluster">
<el-select v-model="postForm.cluster" placeholder="select cluster" @change="getClusterList(postForm.cluster)">
<el-option v-for="(item,index) in clustersListOptions" :key="item+index" :label="item" :value="item"/>
</el-select>
</el-form-item>
<el-form-item v-if="created===false" class="postInfo-container-item" label="Policy">
<el-select v-model="postForm.policy" placeholder="select policy" @change="(postForm.cluster)">
<el-option v-for="(item,index) in policiesListOptions" :key="item+index" :label="item" :value="item"/>
</el-select>
</el-form-item>
</el-form>
</div>
<h2>Namespace Isolation Policy</h2>
<hr class="split-line">
<div v-if="created===true">
<h3>Policy Name</h3>
<hr class="split-line">
<el-input
v-model="policyName"
placeholder="Please Input policy name"
clearable
style="width:300px"/>
</div>
<h3>Namespaces</h3>
<hr class="split-line">
<span>Selected Namespace (Regex)
<el-tooltip :content="namespaceContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
</span>
<br>
<el-tag
v-for="(ntag, index) in namespaceDynamicTags"
:key="'namespace-' + index"
:disable-transitions="false"
closable
@close="handleCloseNamespace(ntag)">
{{ ntag }}
</el-tag>
<el-input
v-if="inputVisibleNamespace"
ref="saveTagInputNamespace"
v-model="inputValueNamespace"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirmNamespace"/>
<el-button v-else class="button-new-tag" size="small" @click="showInputNamespace">+ Regex</el-button>
<h3>Primary Brokers</h3>
<hr class="split-line">
<span>Selected Brokers (Regex)
<el-tooltip :content="brokerContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
</span>
<br>
<el-tag
v-for="(ptag, index) in primaryDynamicTags"
:key="'primary-' + index"
:disable-transitions="false"
closable
@close="handleClosePrimary(ptag)">
{{ ptag }}
</el-tag>
<el-input
v-if="inputVisiblePrimary"
ref="saveTagInputPrimary"
v-model="inputValuePrimary"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirmPrimary"/>
<el-button v-else class="button-new-tag" size="small" @click="showInputPrimary">+ Regex</el-button>
<h3>Secondary Brokers</h3>
<hr class="split-line">
<span>Selected Brokers (Regex)
<el-tooltip :content="secondaryBrokersContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
</span>
<br>
<el-tag
v-for="(stag, index) in secondaryDynamicTags"
:key="'secondary-' + index"
:disable-transitions="false"
closable
@close="handleCloseSecondary(stag)">
{{ stag }}
</el-tag>
<el-input
v-if="inputVisibleSecondary"
ref="saveTagInputSecondary"
v-model="inputValueSecondary"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirmSecondary"/>
<el-button v-else class="button-new-tag" size="small" @click="showInputSecondary">+ Regex</el-button>
<h3>Auto Failover Policy</h3>
<hr class="split-line">
<span>Policy Type
<el-tooltip :content="policyTypeContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
</span>
<br>
<el-select
v-model="autoFailoverPolicy"
placeholder="Please select Auto Failover Policy"
style="margin-top:20px;width:300px">
<el-option
v-for="item in autoFailoverPolicyOptions"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-form :inline="true" :model="form" :rules="rules">
<el-form-item prop="ensembelSize">
<span>Broker Usage Threshold (%)</span>
<el-tooltip :content="brokerUsageThresholdContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
<md-input
v-model="form.brokerUsageThreshold"
class="md-input-style"
name="brokerUsageThreshold"
placeholder="Please input brokerUsageThreshold"
@keyup.enter.native="handleIsolationPolicy"/>
</el-form-item>
<el-form-item prop="writeQuorumSize">
<span>Minimal Available Brokers</span>
<el-tooltip :content="minimalAvailableBrokerContent" class="item" effect="dark" placement="top">
<i class="el-icon-info"/>
</el-tooltip>
<md-input
v-model="form.minimalAvailableBroker"
class="md-input-style"
name="minimalAvailableBroker"
placeholder="Please input minimalAvailableBroker"
@keyup.enter.native="handleIsolationPolicy"/>
</el-form-item>
</el-form>
<div v-if="created===true">
<h4>Create Zone</h4>
<hr class="split-line">
<el-button type="primary" class="button" @click="handleIsolationPolicy">Create Policy</el-button>
</div>
<div v-if="created===false">
<h4>Danager Zone</h4>
<hr class="danger-line">
<el-button type="danger" class="button" @click="handleDelete">Delete Policy</el-button>
</div>
</div>
</template>
<script>
import { fetchClusters } from '@/api/clusters'
import { fetchIsolationPolicies, updateIsolationPolicies, deleteIsolationPolicies } from '@/api/isolationPolicies'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import MdInput from '@/components/MDinput'
const defaultForm = {
cluster: '',
policy: ''
}
export default {
name: 'NamespaceIsolationPolicy',
components: {
Pagination,
MdInput
},
data() {
return {
postForm: Object.assign({}, defaultForm),
clustersListOptions: [],
namespaceContent: 'This is namespaces Content',
brokerContent: 'This is broker content',
secondaryBrokersContent: 'This is secondary brokers content',
policyTypeContent: 'This is policy type content',
brokerUsageThresholdContent: 'This is brokerUsageThresholdContent',
minimalAvailableBrokerContent: 'This is minimalAvailableBrokerContent',
form: {
namespaces: '',
broker: '',
brokerUsageThreshold: '',
minimalAvailableBroker: ''
},
autoFailoverPolicy: 'min_available',
autoFailoverPolicyOptions: [],
rules: {
},
policiesListOptions: [],
primaryDynamicTags: [],
inputVisiblePrimary: false,
inputValuePrimary: '',
namespaceDynamicTags: [],
inputValueNamespace: '',
inputVisibleNamespace: false,
secondaryDynamicTags: [],
inputVisibleSecondary: false,
inputValueSecondary: '',
created: false,
policyName: ''
}
},
created() {
this.postForm.cluster = this.$route.params && this.$route.params.cluster
this.getClusterList()
if (this.$route.query && this.$route.query.created) {
this.created = true
} else {
this.postForm.policy = this.$route.params && this.$route.params.namespaceIsolation
this.getPoliciesList()
}
},
methods: {
getClusterList() {
fetchClusters().then(response => {
if (!response.data) return
for (var i = 0; i < response.data.data.length; i++) {
this.clustersListOptions.push(response.data.data[i].cluster)
}
})
},
getPoliciesList() {
fetchIsolationPolicies(this.postForm.cluster).then(response => {
if (!response.data) return
for (var key in response.data) {
this.policiesListOptions.push(key)
if (key === this.postForm.policy) {
this.namespaceDynamicTags = response.data[key].namespaces
this.primaryDynamicTags = response.data[key].primary
this.secondaryDynamicTags = response.data[key].secondary
this.autoFailoverPolicyOptions.push({
value: response.data[key].auto_failover_policy.policy_type,
label: response.data[key].auto_failover_policy.policy_type
})
this.form.minimalAvailableBroker = response.data[key].auto_failover_policy.parameters.min_limit
this.form.brokerUsageThreshold = response.data[key].auto_failover_policy.parameters.usage_threshold
}
}
})
},
handleIsolationPolicy() {
var policyName = this.postForm.policy
if (this.created) {
if (this.policyName.length <= 0) {
this.$notify({
title: 'error',
message: 'Policy Name cannot be empty',
type: 'error',
duration: 3000
})
return
}
if (this.namespaceDynamicTags.length <= 0) {
this.$notify({
title: 'error',
message: 'Namespace Regex cannot be empty',
type: 'error',
duration: 3000
})
return
}
if (this.primaryDynamicTags.length <= 0) {
this.$notify({
title: 'error',
message: 'Primary Broker Regex cannot be empty',
type: 'error',
duration: 3000
})
return
}
if (this.secondaryDynamicTags.length <= 0) {
this.$notify({
title: 'error',
message: 'Secondary Broker Regex cannot be empty',
type: 'error',
duration: 3000
})
return
}
if (this.form.minimalAvailableBroker <= 0) {
this.$notify({
title: 'error',
message: 'min_limit should greater than 0',
type: 'error',
duration: 3000
})
return
}
if (this.form.brokerUsageThreshold <= 0) {
this.$notify({
title: 'error',
message: 'usage_threshold should greater than 0',
type: 'error',
duration: 3000
})
return
}
policyName = this.policyName
}
const data = {
'namespaces': this.namespaceDynamicTags,
'primary': this.primaryDynamicTags,
'secondary': this.secondaryDynamicTags,
'auto_failover_policy': {
'policy_type': 0,
'parameters': {
'min_limit': this.form.minimalAvailableBroker,
'usage_threshold': this.form.brokerUsageThreshold
}
}
}
updateIsolationPolicies(this.postForm.cluster, policyName, data).then(response => {
this.$notify({
title: 'success',
message: 'Set policy success',
type: 'success',
duration: 3000
})
if (this.created) {
this.$router.push({ path: '/management/clusters/' + this.postForm.cluster + '/cluster?tab=isolationPolicies' })
}
})
},
handleClosePrimary(tag) {
this.primaryDynamicTags.splice(this.primaryDynamicTags.indexOf(tag), 1)
this.handleIsolationPolicy()
},
showInputPrimary() {
this.inputVisiblePrimary = true
this.$nextTick(_ => {
this.$refs.saveTagInputPrimary.$refs.input.focus()
})
},
handleInputConfirmPrimary() {
const inputValue = this.inputValuePrimary
if (this.primaryDynamicTags.indexOf(inputValue) > 0) {
this.$notify({
title: 'error',
message: 'This regex exist',
type: 'error',
duration: 3000
})
return
}
if (inputValue) {
this.primaryDynamicTags.push(inputValue)
}
this.inputVisiblePrimary = false
this.inputValuePrimary = ''
if (this.created) {
return
}
this.handleIsolationPolicy()
},
handleCloseNamespace(tag) {
this.namespaceDynamicTags.splice(this.namespaceDynamicTags.indexOf(tag), 1)
this.handleIsolationPolicy()
},
showInputNamespace() {
this.inputVisibleNamespace = true
this.$nextTick(_ => {
this.$refs.saveTagInputNamespace.$refs.input.focus()
})
},
handleInputConfirmNamespace() {
const inputValue = this.inputValueNamespace
if (this.namespaceDynamicTags.indexOf(inputValue) > 0) {
this.$notify({
title: 'error',
message: 'This regex exist',
type: 'success',
duration: 3000
})
return
}
if (inputValue) {
this.namespaceDynamicTags.push(inputValue)
}
this.inputVisibleNamespace = false
this.inputValueNamespace = ''
if (this.created) {
return
}
this.handleIsolationPolicy()
},
handleCloseSecondary(tag) {
this.secondaryDynamicTags.splice(this.secondaryDynamicTags.indexOf(tag), 1)
this.handleIsolationPolicy()
},
showInputSecondary() {
this.inputVisibleSecondary = true
this.$nextTick(_ => {
this.$refs.saveTagInputSecondary.$refs.input.focus()
})
},
handleInputConfirmSecondary() {
const inputValue = this.inputValueSecondary
if (this.secondaryDynamicTags.indexOf(inputValue) > 0) {
this.$notify({
title: 'error',
message: 'This regex exist',
type: 'error',
duration: 3000
})
return
}
if (inputValue) {
this.secondaryDynamicTags.push(inputValue)
}
this.inputVisibleSecondary = false
this.inputValueSecondary = ''
if (this.created) {
return
}
this.handleIsolationPolicy()
},
handleDelete() {
deleteIsolationPolicies(this.postForm.cluster, this.postForm.policy).then(response => {
this.$notify({
title: 'success',
message: 'Delete policy success',
type: 'success',
duration: 3000
})
this.$router.push({ path: '/management/clusters/' + this.postForm.cluster + '/cluster?tab=isolationPolicies' })
})
}
}
}
</script>
<style>
.split-line {
background: #e6e9f3;
border: none;
height: 1px;
}
.md-input-style {
width: 300px;
margin-top: 20px;
}
.danger-line {
background: red;
border: none;
height: 1px;
}
.el-tag + .el-tag {
margin-left: 10px;
}
.button-new-tag {
margin-top: 20px;
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-top: 20px;
margin-left: 10px;
vertical-align: bottom;
}
</style>