Update.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('cloudenv.text_298')}}</div>
  4. <div slot="body">
  5. <dialog-selected-tips :name="$t('dictionary.cloudaccount')" :count="params.data.length" :action="$t('cloudenv.text_298')" />
  6. <dialog-table class="mb-2" :data="params.data" :columns="params.columns.slice(0, 3)" />
  7. <a-form
  8. :form="form.fc"
  9. v-bind="formItemLayout">
  10. <upload-json-file :fc="form.fc" v-if="isGoogle">
  11. <a-form-item :label="field.label.k">
  12. <a-textarea :autosize="{ minRows: 3, maxRows: 7 }" v-decorator="decorators.keyId" :placeholder="field.placeholder.k" />
  13. </a-form-item>
  14. <a-form-item :label="field.label.s">
  15. <a-input-password v-decorator="decorators.keySecret" :placeholder="field.placeholder.s" type="password" />
  16. </a-form-item>
  17. </upload-json-file>
  18. <div v-else>
  19. <h2 class="mt-3 mb-3" v-if="isHcs">{{ $t('cloudenv.operation_info_input') }}</h2>
  20. <a-form-item :label="field.label.k">
  21. <a-input v-decorator="decorators.keyId" :placeholder="field.placeholder.k" />
  22. </a-form-item>
  23. <a-form-item :label="$t('cloudenv.text_300')" v-if="isAzure">
  24. <a-input v-decorator="decorators.directory_id" :placeholder="$t('cloudenv.text_243')" />
  25. <div slot="extra" v-if="showDocsLink()">
  26. <help-link :href="doc">{{$t('cloudenv.text_301')}}</help-link>
  27. </div>
  28. </a-form-item>
  29. <a-form-item :label="field.label.s">
  30. <a-input-password v-decorator="decorators.keySecret" :placeholder="field.placeholder.s" type="password" />
  31. </a-form-item>
  32. <!-- <template v-if="isVMware">
  33. <a-form-item :label="$t('cloudenv.text_264')" :extra="this.$t('common_572')">
  34. <a-input v-decorator="decorators.host" />
  35. </a-form-item>
  36. <a-form-item :label="$t('cloudenv.text_266')">
  37. <a-input v-decorator="decorators.port" />
  38. </a-form-item>
  39. </template> -->
  40. </div>
  41. <!-- <a-form-item :label="$t('cloudenv.text_242')" v-if="isAzure">
  42. <a-textarea v-decorator="decorators.balanceKey" rows="4" />
  43. </a-form-item> -->
  44. <a-form-item label="project_id" v-if="isUcloud">
  45. <a-input v-decorator="decorators.ucloud_project_id" :placeholder="$t('cloudenv.text_247')" />
  46. </a-form-item>
  47. <a-form-item :label="$t('cloudenv.text_254')" v-if="isOpenStack">
  48. <a-input v-decorator="decorators.project_name" :placeholder="$t('cloudenv.text_255')" />
  49. </a-form-item>
  50. <a-form-item :label="$t('cloudenv.text_304')" v-if="isOpenStack">
  51. <a-select v-decorator="decorators.endpoint_type" :placeholder="$t('cloudenv.text_305')">
  52. <a-select-option
  53. v-for="item in endpointTypeOpts"
  54. :key="item.key"
  55. :value="item.key">{{ item.label }}</a-select-option>
  56. </a-select>
  57. </a-form-item>
  58. <template v-if="isHcs">
  59. <h2 class="mb-3">{{ $t('cloudenv.operation_and_maintenance_info_input') }}</h2>
  60. <a-form-item :label="$t('cloudenv.text_94')">
  61. <a-input v-decorator="decorators.options.account" :placeholder="$t('common.tips.input', [$t('cloudenv.text_94')])" />
  62. </a-form-item>
  63. <a-form-item :label="$t('cloudenv.text_147')">
  64. <a-input-password v-decorator="decorators.options.password" :placeholder="$t('common.tips.input', [$t('cloudenv.text_147')])" />
  65. </a-form-item>
  66. </template>
  67. <upload-pem-file :fc="form.fc" :decorators="decorators" v-if="isOraclecloud">
  68. <a-textarea
  69. v-decorator="decorators.oracle_private_key"
  70. :placeholder="$t('common.tips.input', [$t('cloudenv.private_key')])"
  71. :auto-size="{ minRows: 6, maxRows: 8 }" />
  72. </upload-pem-file>
  73. <template v-if="isCephFS">
  74. <a-form-item label="Name">
  75. <a-input v-decorator="decorators.option_name" />
  76. </a-form-item>
  77. <a-form-item label="Mon Host" :extra="$t('cloudenv.mon_host_extra')">
  78. <a-input v-decorator="decorators.mon_host" />
  79. </a-form-item>
  80. <a-form-item label="Secret">
  81. <a-input-password v-decorator="decorators.secret" />
  82. </a-form-item>
  83. </template>
  84. </a-form>
  85. </div>
  86. <div slot="footer">
  87. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  88. <test-button :post="testPost" />
  89. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  90. </div>
  91. </base-dialog>
  92. </template>
  93. <script>
  94. import * as R from 'ramda'
  95. import UploadJsonFile from '@Cloudenv/views/cloudaccount/components/UploadJsonFile'
  96. import UploadPemFile from '@Cloudenv/views/cloudaccount/components/UploadPemFile'
  97. import TestButton from '@/sections/TestButton'
  98. import { HYPERVISORS_MAP, EXTRA_HYPERVISORS } from '@/constants'
  99. import DialogMixin from '@/mixins/dialog'
  100. import WindowsMixin from '@/mixins/windows'
  101. import regexp from '@/utils/regexp'
  102. import { DOCS_MAP, showDocsLink } from '@/constants/docs'
  103. import { keySecretFields } from '../constants'
  104. export default {
  105. name: 'CloudaccountUpdateDialog',
  106. components: { UploadJsonFile, TestButton, UploadPemFile },
  107. mixins: [DialogMixin, WindowsMixin],
  108. data () {
  109. const provider = this.params.data[0].brand.toLowerCase()
  110. // const isVMware = provider === HYPERVISORS_MAP.esxi.provider.toLowerCase()
  111. const { options = {} } = this.params.data[0]
  112. const initMonHost = options.mon_host || ''
  113. const initName = options.name || ''
  114. const field = keySecretFields[provider] || {}
  115. return {
  116. showDocsLink,
  117. loading: false,
  118. form: {
  119. fc: this.$form.createForm(this),
  120. },
  121. provider,
  122. decorators: {
  123. oracle_private_key: [
  124. 'oracle_private_key',
  125. {
  126. rules: [
  127. { required: true, message: this.$t('common.tips.input', [this.$t('cloudenv.private_key')]) },
  128. ],
  129. },
  130. ],
  131. oracle_private_pem: [
  132. 'oracle_private_pem',
  133. {
  134. rules: [
  135. { required: true, message: this.$t('cloudenv.private_pem_message') },
  136. ],
  137. },
  138. ],
  139. keyId: [
  140. keySecretFields[provider].k,
  141. {
  142. initialValue: undefined,
  143. rules: [
  144. { required: true, message: field.placeholder?.k || this.$t('cloudenv.text_149') },
  145. ],
  146. },
  147. ],
  148. keySecret: [
  149. keySecretFields[provider].s,
  150. {
  151. rules: [
  152. { required: true, message: field.placeholder?.s || this.$t('cloudenv.text_150') },
  153. ],
  154. },
  155. ],
  156. ucloud_project_id: [
  157. 'ucloud_project_id',
  158. {
  159. rules: [
  160. { required: false },
  161. ],
  162. },
  163. ],
  164. directory_id: [
  165. 'directory_id',
  166. {
  167. rules: [
  168. { required: true, message: this.$t('cloudenv.text_243') },
  169. ],
  170. },
  171. ],
  172. balanceKey: [
  173. 'balanceKey',
  174. ],
  175. endpoint_type: [
  176. 'endpoint_type',
  177. ],
  178. project_name: [
  179. 'project_name',
  180. {
  181. rules: [
  182. { required: true, message: this.$t('cloudenv.text_308') },
  183. ],
  184. },
  185. ],
  186. host: [
  187. 'host',
  188. {
  189. rules: [
  190. { required: true, message: this.$t('cloudenv.text_268') },
  191. { validator: this.$validate(['domain', 'IPv4'], true, 'some'), trigger: ['blur', 'change'], message: this.$t('cloudenv.text_269') },
  192. ],
  193. },
  194. ],
  195. port: [
  196. 'port',
  197. {
  198. rules: [
  199. { type: 'number', min: 0, max: 65535, message: this.$t('cloudenv.text_270'), trigger: 'blur', transform: (v) => parseFloat(v) },
  200. ],
  201. },
  202. ],
  203. options: {
  204. account: ['options.account'],
  205. password: ['options.password'],
  206. },
  207. option_name: [
  208. 'option_name',
  209. {
  210. initialValue: initName,
  211. },
  212. ],
  213. mon_host: [
  214. 'mon_host',
  215. {
  216. initialValue: initMonHost,
  217. rules: [
  218. {
  219. validator: (rule, value, callback) => {
  220. if (!value) callback()
  221. const list = value.split(',')
  222. if (list.every(str => {
  223. return regexp.isIPv4AndPort(str)
  224. })) {
  225. callback()
  226. }
  227. callback(new Error(this.$t('cloudenv.check_mon_host')))
  228. },
  229. },
  230. ],
  231. },
  232. ],
  233. secret: [
  234. 'secret',
  235. ],
  236. },
  237. endpointTypeOpts: [
  238. { key: 'internal', label: 'internal' },
  239. { key: 'admin', label: 'admin' },
  240. { key: 'public', label: 'public' },
  241. ],
  242. }
  243. },
  244. computed: {
  245. field () {
  246. return keySecretFields[this.provider]
  247. },
  248. doc () {
  249. return DOCS_MAP.cloudaccount()[this.provider]
  250. },
  251. isQcloud () {
  252. return this.provider === HYPERVISORS_MAP.qcloud.key
  253. },
  254. isAzure () {
  255. return this.provider === HYPERVISORS_MAP.azure.key
  256. },
  257. isOpenStack () {
  258. return this.provider === HYPERVISORS_MAP.openstack.key
  259. },
  260. isUcloud () {
  261. return this.provider === HYPERVISORS_MAP.ucloud.key
  262. },
  263. isGoogle () {
  264. return this.provider === HYPERVISORS_MAP.google.key
  265. },
  266. isVMware () {
  267. return this.provider === HYPERVISORS_MAP.esxi.provider.toLowerCase()
  268. },
  269. isHcs () {
  270. return this.provider === HYPERVISORS_MAP.hcs.key
  271. },
  272. isCephFS () {
  273. return this.provider === EXTRA_HYPERVISORS.CephFS.key.toLowerCase()
  274. },
  275. isOraclecloud () {
  276. return this.provider === HYPERVISORS_MAP.oracle.provider.toLowerCase()
  277. },
  278. formItemLayout () {
  279. const ret = {
  280. wrapperCol: {
  281. span: 21,
  282. },
  283. labelCol: {
  284. span: 3,
  285. },
  286. }
  287. if (this.isAzure || this.isGoogle) {
  288. ret.wrapperCol.span = 19
  289. ret.labelCol.span = 5
  290. }
  291. return ret
  292. },
  293. offsetFormLayout () {
  294. const ret = {
  295. wrapperCol: {
  296. span: 21,
  297. offset: 3,
  298. },
  299. }
  300. if (this.isAzure || this.isGoogle) {
  301. ret.wrapperCol.span = 19
  302. ret.wrapperCol.offset = 5
  303. }
  304. return ret
  305. },
  306. },
  307. created () {
  308. this.init()
  309. },
  310. methods: {
  311. init () {
  312. if (this.isVMware) {
  313. const { hostname, port, protocol } = this.parseUrl(this.params.data[0].access_url)
  314. this.setHost(hostname)
  315. this.setPort(port || (protocol === 'http' ? 80 : 443))
  316. }
  317. },
  318. validateForm () {
  319. return new Promise((resolve, reject) => {
  320. this.form.fc.validateFields((err, values) => {
  321. if (err) {
  322. reject(err)
  323. } else {
  324. const params = {}
  325. R.forEachObjIndexed((value, key) => {
  326. if (R.is(String, value)) {
  327. params[key] = value.trim()
  328. } else {
  329. params[key] = value
  330. }
  331. }, values)
  332. // 针对oracle cloud oracle_private_pem参数做转换处理
  333. if (params.oracle_private_pem) {
  334. params.oracle_private_key = params.oracle_private_pem
  335. delete params.oracle_private_pem
  336. }
  337. if (this.isCephFS) {
  338. params.options = params.options || {}
  339. params.options.mon_host = params.mon_host
  340. params.options.password = params.secret
  341. params.options.name = params.option_name
  342. delete params.mon_host
  343. delete params.secret
  344. delete params.option_name
  345. }
  346. resolve(params)
  347. }
  348. })
  349. })
  350. },
  351. async handleConfirm () {
  352. this.loading = true
  353. try {
  354. const values = await this.validateForm()
  355. const params = values
  356. if (params.ucloud_project_id && params.access_key_id) {
  357. params.access_key_id = params.access_key_id + '::' + params.ucloud_project_id
  358. delete params.ucloud_project_id
  359. }
  360. let options
  361. if (params.options) {
  362. options = params.options
  363. delete params.options
  364. }
  365. await this.params.onManager('performAction', {
  366. id: this.params.data[0].id,
  367. managerArgs: {
  368. action: 'update-credential',
  369. data: params,
  370. },
  371. })
  372. if (options) {
  373. await this.params.onManager('update', {
  374. id: this.params.data[0].id,
  375. managerArgs: {
  376. data: {
  377. options,
  378. },
  379. },
  380. })
  381. }
  382. this.loading = false
  383. this.cancelDialog()
  384. } catch (error) {
  385. this.loading = false
  386. }
  387. },
  388. async testPost () {
  389. const values = await this.validateForm()
  390. await this.params.onManager('performAction', {
  391. id: this.params.data[0].id,
  392. managerArgs: {
  393. action: 'test-connectivity',
  394. data: values,
  395. },
  396. })
  397. },
  398. parseUrl (url) {
  399. return new URL(url)
  400. },
  401. setHost (host) {
  402. this.$nextTick(() => {
  403. this.form.fc.setFieldsValue({ host })
  404. })
  405. },
  406. setPort (port) {
  407. this.$nextTick(() => {
  408. this.form.fc.setFieldsValue({ port })
  409. })
  410. },
  411. },
  412. }
  413. </script>