index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. <template>
  2. <a-spin :spinning="loading">
  3. <page-header :title="$t('network.text_722')" />
  4. <page-body>
  5. <a-form :form="form.fc" v-bind="formItemLayout">
  6. <a-form-item :label="$t('network.text_21')">
  7. <a-input :disabled="!!lbAgentId" v-decorator="decorators.name" :placeholder="$t('network.text_44')" />
  8. </a-form-item>
  9. <a-form-item :label="$t('common.description')">
  10. <a-textarea :auto-size="{ minRows: 1, maxRows: 3 }" v-decorator="decorators.description" :placeholder="$t('common_367')" />
  11. </a-form-item>
  12. <a-form-item :label="$t('network.text_19')">
  13. <base-select
  14. :disabled="!!lbAgentId"
  15. v-decorator="decorators.cluster_id"
  16. resource="loadbalancerclusters"
  17. remote
  18. :remote-fn="q => ({ filter: `name.contains(${q})` })"
  19. showSync
  20. :select-props="{ placeholder: $t('network.text_79') }" />
  21. <p slot="extra">{{$t('network.text_80')}}<a-button type="link" size="small" @click="createCluster">{{$t('network.text_26')}}</a-button>
  22. </p>
  23. </a-form-item>
  24. <a-form-item :label="$t('network.priority')">
  25. <a-tooltip>
  26. <template slot="title">
  27. {{ $t('network.priority.extra') }}
  28. </template>
  29. <a-input-number
  30. v-decorator="decorators.priority"
  31. :min="1"
  32. :max="255"
  33. :step="1"
  34. :formatter="v => `${ isNaN(parseInt(v)) ? 1 : parseInt(v) }`"
  35. :parser="v => `${ isNaN(parseInt(v)) ? 1 : parseInt(v) }`" />
  36. </a-tooltip>
  37. </a-form-item>
  38. <a-collapse :bordered="false">
  39. <a-collapse-panel :header="$t('network.text_94')" key="1" forceRender>
  40. <a-collapse @change="handleCollapseChange">
  41. <a-collapse-panel key="telegraf" :header="$t('network.text_97')" forceRender>
  42. <a-form-item :label="$t('network.text_98')" :extra="$t('network.text_99')">
  43. <a-row :gutter="8">
  44. <a-col :span="12">
  45. <a-input v-decorator="decorators.telegraf_influx_db_output_url" :placeholder="$t('network.text_100')" />
  46. </a-col>
  47. <a-col :span="12">
  48. <a-checkbox class="ml-4" v-decorator="decorators.telegraf_influx_db_output_unsafe_ssl">{{$t('network.text_101')}}</a-checkbox>
  49. </a-col>
  50. </a-row>
  51. </a-form-item>
  52. <a-form-item :label="$t('network.text_102')">
  53. <a-input v-decorator="decorators.telegraf_influx_db_output_name" />
  54. </a-form-item>
  55. <a-form-item :label="$t('network.text_103')">
  56. <a-input v-decorator="decorators.telegraf_haproxy_input_interval" type="Number" :addonAfter="$t('network.text_76')" />
  57. </a-form-item>
  58. <a-form-item :label="$t('network.text_104')">
  59. <code-mirror v-decorator="decorators.telegraf_conf_tmpl" :options="cmOptions" />
  60. </a-form-item>
  61. </a-collapse-panel>
  62. <a-collapse-panel key="haproxy" :header="$t('network.text_105')" forceRender>
  63. <a-form-item :label="$t('network.text_106')">
  64. <a-input v-decorator="decorators.haproxy_global_nbthread" type="Number" />
  65. </a-form-item>
  66. <a-form-item :label="$t('network.text_107')" :extra="$t('network.text_108')">
  67. <a-input v-decorator="decorators.haproxy_global_log" :placeholder="$t('network.text_109')" />
  68. </a-form-item>
  69. <a-form-item :label="$t('network.text_110')">
  70. <a-switch v-decorator="decorators.haproxy_log_http" />
  71. </a-form-item>
  72. <a-form-item :label="$t('network.text_111')">
  73. <a-switch v-decorator="decorators.haproxy_log_tcp" />
  74. </a-form-item>
  75. <a-form-item :label="$t('network.text_112')">
  76. <a-switch v-decorator="decorators.haproxy_log_normal" />
  77. </a-form-item>
  78. <a-form-item :label="$t('network.text_113')">
  79. <a-input v-decorator="decorators.haproxy_tune_http_maxhdr" :extra="$t('network.text_114')" type="Number" />
  80. </a-form-item>
  81. <a-form-item :label="$t('network.text_104')">
  82. <code-mirror v-decorator="decorators.haproxy_conf_tmpl" :options="cmOptions" />
  83. </a-form-item>
  84. </a-collapse-panel>
  85. <a-collapse-panel key="keepalived" :header="$t('network.text_115')" forceRender>
  86. <a-form-item :label="$t('network.text_104')">
  87. <code-mirror v-decorator="decorators.keepalived_conf_tmpl" :options="cmOptions" />
  88. </a-form-item>
  89. </a-collapse-panel>
  90. </a-collapse>
  91. </a-collapse-panel>
  92. </a-collapse>
  93. </a-form>
  94. </page-body>
  95. <page-footer>
  96. <template v-slot:right>
  97. <a-button type="primary" :loading="submiting" @click="handleSubmit">{{ $t('common.ok') }}</a-button>
  98. <a-button class="ml-2" @click="handleCancel">{{ $t('dialog.cancel') }}</a-button>
  99. </template>
  100. </page-footer>
  101. </a-spin>
  102. </template>
  103. <script>
  104. import workflowMixin from '@/mixins/workflow'
  105. import WindowsMixin from '@/mixins/windows'
  106. export default {
  107. name: 'AgentCreate',
  108. components: {},
  109. mixins: [WindowsMixin, workflowMixin],
  110. data () {
  111. return {
  112. loading: false,
  113. submiting: false,
  114. defaultParams: {},
  115. form: {
  116. fc: this.$form.createForm(this),
  117. },
  118. cmOptions: {
  119. tabSize: 2,
  120. styleActiveLine: true,
  121. lineNumbers: true,
  122. line: true,
  123. mode: 'text/x-yaml',
  124. theme: 'material',
  125. autofocus: true,
  126. value: undefined,
  127. },
  128. decorators: {
  129. name: [
  130. 'name',
  131. {
  132. validateFirst: true,
  133. rules: [
  134. { required: true, message: this.$t('network.text_116') },
  135. { validator: this.$validate('resourceName') },
  136. ],
  137. },
  138. ],
  139. description: ['description'],
  140. cluster_id: [
  141. 'cluster_id',
  142. {
  143. rules: [
  144. { required: true, message: this.$t('network.text_79') },
  145. ],
  146. },
  147. ],
  148. priority: [
  149. 'priority',
  150. {
  151. initialValue: 1,
  152. },
  153. ],
  154. telegraf_influx_db_output_url: [
  155. 'telegraf.influx_db_output_url',
  156. ],
  157. telegraf_influx_db_output_unsafe_ssl: [
  158. 'telegraf.influx_db_output_unsafe_ssl',
  159. {
  160. valuePropName: 'checked',
  161. initialValue: true,
  162. },
  163. ],
  164. telegraf_influx_db_output_name: [
  165. 'telegraf.influx_db_output_name',
  166. ],
  167. telegraf_conf_tmpl: [
  168. 'telegraf_conf_tmpl',
  169. ],
  170. telegraf_haproxy_input_interval: [
  171. 'telegraf.haproxy_input_interval',
  172. {
  173. normalize: v => Number(v),
  174. rules: [
  175. { type: 'integer', min: 1, max: 600, message: this.$t('network.text_123'), trigger: 'blur' },
  176. ],
  177. },
  178. ],
  179. haproxy_global_nbthread: [
  180. 'haproxy.global_nbthread',
  181. {
  182. normalize: v => Number(v),
  183. rules: [
  184. { type: 'integer', min: 1, max: 64, message: this.$t('network.text_124'), trigger: 'blur' },
  185. ],
  186. },
  187. ],
  188. haproxy_global_log: [
  189. 'haproxy.global_log_path',
  190. ],
  191. haproxy_log_http: [
  192. 'haproxy.log_http',
  193. {
  194. valuePropName: 'checked',
  195. },
  196. ],
  197. haproxy_log_tcp: [
  198. 'haproxy.log_tcp',
  199. {
  200. valuePropName: 'checked',
  201. },
  202. ],
  203. haproxy_log_normal: [
  204. 'haproxy.log_normal',
  205. {
  206. valuePropName: 'checked',
  207. },
  208. ],
  209. haproxy_tune_http_maxhdr: [
  210. 'haproxy.tune_http_maxhdr',
  211. {
  212. initialValue: 101,
  213. normalize: v => Number(v),
  214. rules: [
  215. { type: 'integer', min: 1, max: 32767, message: this.$t('network.text_125'), trigger: 'blur' },
  216. ],
  217. },
  218. ],
  219. haproxy_conf_tmpl: [
  220. 'haproxy_conf_tmpl',
  221. ],
  222. keepalived_conf_tmpl: [
  223. 'keepalived_conf_tmpl',
  224. ],
  225. },
  226. formItemLayout: {
  227. wrapperCol: {
  228. md: { span: 14 },
  229. xl: { span: 16 },
  230. xxl: { span: 20 },
  231. },
  232. labelCol: {
  233. md: { span: 10 },
  234. xl: { span: 8 },
  235. xxl: { span: 4 },
  236. },
  237. },
  238. }
  239. },
  240. computed: {
  241. lbAgentId () {
  242. return this.$route.query.id
  243. },
  244. },
  245. created () {
  246. this.manager = new this.$Manager('loadbalanceragents')
  247. if (this.lbAgentId) {
  248. this.getFetchLbAgent()
  249. }
  250. },
  251. methods: {
  252. createCluster () {
  253. this.createDialog('LoadbalancerclusterCreateDialog', {
  254. title: this.$t('network.text_26'),
  255. })
  256. },
  257. handleClusterChange (id) {
  258. !this.lbAgentId && this.getFetchDefaultParams(id)
  259. },
  260. setValues (data) {
  261. if (!data || !Object.keys(data).length || !data.params) return false
  262. const params = {
  263. ...data.params,
  264. // 在handleCollapseChange赋值, 为了解决code-mirror赋值bug
  265. ...{
  266. telegraf_conf_tmpl: undefined,
  267. haproxy_conf_tmpl: undefined,
  268. keepalived_conf_tmpl: undefined,
  269. },
  270. }
  271. if (params.haproxy && params.haproxy.global_log) {
  272. params.haproxy.global_log_path = params.haproxy.global_log.split(' ')[1]
  273. }
  274. this.form.fc.setFieldsValue({
  275. name: data.name,
  276. description: data.description,
  277. cluster_id: data.cluster_id,
  278. priority: data.priority,
  279. ...params,
  280. })
  281. this.defaultParams = data.params
  282. },
  283. formatValues (values) {
  284. const templKeys = ['telegraf_conf_tmpl', 'haproxy_conf_tmpl', 'keepalived_conf_tmpl']
  285. templKeys.forEach(k => {
  286. if (values[k]) {
  287. values[k] = window.btoa(values[k])
  288. } else {
  289. values[k] = this.defaultParams[k]
  290. }
  291. })
  292. if (values.haproxy.global_log_path) {
  293. const logConfs = this.defaultParams.haproxy.global_log.split(' ')
  294. logConfs[1] = values.haproxy.global_log_path
  295. values.haproxy.global_log = logConfs.join(' ')
  296. delete values.global_log_path
  297. }
  298. const { name, description, cluster_id, priority, ...rest } = values
  299. if (this.lbAgentId) {
  300. return {
  301. name,
  302. description,
  303. cluster_id,
  304. priority,
  305. params: {
  306. ...rest,
  307. },
  308. }
  309. }
  310. return {
  311. name,
  312. description,
  313. cluster_id,
  314. priority,
  315. params: {
  316. ...rest,
  317. },
  318. }
  319. },
  320. async doUpdate (values) {
  321. const { params, ...rest } = this.formatValues(values)
  322. await this.manager.update({
  323. id: this.lbAgentId,
  324. data: rest,
  325. })
  326. await this.manager.performAction({
  327. action: 'params-patch',
  328. id: this.lbAgentId,
  329. data: { params },
  330. })
  331. },
  332. async handleCollapseChange (activeKeys) {
  333. activeKeys.forEach((k) => {
  334. const tk = `${k}_conf_tmpl`
  335. if (!this.form.fc.getFieldValue(tk)) {
  336. this.form.fc.setFieldsValue({
  337. [tk]: window.atob(this.defaultParams[tk]),
  338. })
  339. }
  340. })
  341. },
  342. async getFetchLbAgent () {
  343. const { id } = this.$route.query
  344. try {
  345. const { data = {} } = await this.manager.get(({
  346. id,
  347. }))
  348. this.setValues(data)
  349. } catch (err) {
  350. throw err
  351. }
  352. },
  353. async getFetchDefaultParams (cluster) {
  354. try {
  355. const { data = {} } = await this.manager.get(({
  356. id: 'default-params',
  357. params: {
  358. cluster,
  359. },
  360. }))
  361. if (data && data.params) {
  362. this.setValues(data)
  363. }
  364. } catch (err) {
  365. throw err
  366. }
  367. },
  368. async handleSubmit () {
  369. this.submiting = true
  370. try {
  371. const values = await this.form.fc.validateFields()
  372. if (this.lbAgentId) {
  373. await this.doUpdate(values)
  374. this.$store.commit('keepAlive/ADD_DELAY_EVENT', { name: 'ResourceListSingleRefresh', params: this.lbAgentId })
  375. }
  376. this.handleCancel()
  377. } catch (error) {
  378. throw error
  379. } finally {
  380. this.submiting = false
  381. }
  382. },
  383. handleCancel () {
  384. this.$router.push('/lbagent')
  385. },
  386. },
  387. }
  388. </script>