DatasourceAdd.jsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. import {
  2. ModalForm,
  3. ProFormSelect,
  4. ProFormText,
  5. ProFormRadio,
  6. ProFormTextArea,
  7. ProFormUploadButton,
  8. ProForm,
  9. } from '@ant-design/pro-components'
  10. import { Button, Col, message, Form } from 'antd'
  11. import { useState } from 'react'
  12. import {
  13. testDataSourceConnection,
  14. createDataSource,
  15. uploadFile,
  16. } from '../services'
  17. import Base64 from 'base-64'
  18. const DATA_TYPE_MYSQL = 'mysql'
  19. const KERBS_VALID_FALSE = false
  20. export default function DatasourceAdd({ updateDataSource }) {
  21. // 数据源类型
  22. const [dataType, setDataType] = useState(DATA_TYPE_MYSQL)
  23. // 是否开启kerbsValid验证
  24. const [kerbsValid, setKerbsValid] = useState(KERBS_VALID_FALSE)
  25. const [kerberosServiceName, setKerberosServiceName] = useState('')
  26. const [principal, setPrincipal] = useState('')
  27. // Loading状态
  28. const [loading, setLoading] = useState(false)
  29. const [keytabFile, setKeytabFile] = useState([])
  30. const [krb5File, setKrb5File] = useState([])
  31. const [useSSL, setUseSSL] = useState(false)
  32. // Form表单
  33. const [form] = Form.useForm()
  34. // 测试连接
  35. const testConnect = async () => {
  36. const fields = [
  37. 'datasource_name',
  38. 'datasource',
  39. 'database_name',
  40. 'jdbc_username',
  41. 'jdbc_password',
  42. 'jdbc_url',
  43. 'comments',
  44. 'tag',
  45. ]
  46. try {
  47. await form.validateFields(fields)
  48. setLoading(true)
  49. const testData = form.getFieldsValue(fields)
  50. const params = {
  51. ...testData,
  52. tag: form.getFieldValue('tag').join('/'),
  53. }
  54. if (params.jdbc_password) {
  55. params.jdbc_password = Base64.encode(params.jdbc_password)
  56. }
  57. params['use_ssl'] = useSSL ? 1 : 0
  58. params['kerberos'] = kerbsValid ? 1 : 0
  59. if (kerbsValid) {
  60. let keytab = ''
  61. let krb5config = ''
  62. if (keytabFile && keytabFile.length) {
  63. keytab = await uploadKerbFile(keytabFile)
  64. }
  65. if (krb5File && krb5File.length) {
  66. krb5config = await uploadKerbFile(krb5File)
  67. }
  68. params['keytab'] = keytab
  69. params['krb5config'] = krb5config
  70. params['kerberos_service_name'] = kerberosServiceName
  71. params['principal'] = principal
  72. if (checkKrb(keytab, krb5config, kerberosServiceName, principal)) {
  73. const { data } = await testDataSourceConnection(params)
  74. if (data.code === 200) {
  75. if (data.data) {
  76. message.success('连接成功')
  77. } else {
  78. message.error('连接失败')
  79. }
  80. } else {
  81. message.error(data.msg)
  82. }
  83. }
  84. } else {
  85. const { data } = await testDataSourceConnection(params)
  86. if (data.code === 200) {
  87. if (data.data) {
  88. message.success('连接成功')
  89. } else {
  90. message.error('连接失败')
  91. }
  92. } else {
  93. message.error(data.msg)
  94. }
  95. }
  96. } catch (error) {
  97. message.error('表单验证错误,请检查表单信息是否完整')
  98. }
  99. setLoading(false)
  100. }
  101. // 完成添加
  102. const finishAdd = async () => {
  103. const fields = [
  104. 'datasource_name',
  105. 'datasource',
  106. 'database_name',
  107. 'jdbc_username',
  108. 'jdbc_password',
  109. 'jdbc_url',
  110. 'comments',
  111. 'tag',
  112. ]
  113. const params = {
  114. ...form.getFieldsValue(fields),
  115. tag: form.getFieldValue('tag').join('/'),
  116. }
  117. if (params.jdbc_password) {
  118. params.jdbc_password = Base64.encode(params.jdbc_password)
  119. }
  120. params['use_ssl'] = useSSL ? 1 : 0
  121. params['kerberos'] = kerbsValid ? 1 : 0
  122. if (kerbsValid) {
  123. let keytab = ''
  124. let krb5config = ''
  125. if (keytabFile && keytabFile.length) {
  126. keytab = await uploadKerbFile(keytabFile)
  127. }
  128. if (krb5File && krb5File.length) {
  129. krb5config = await uploadKerbFile(krb5File)
  130. }
  131. params['keytab'] = keytab
  132. params['krb5config'] = krb5config
  133. params['kerberos_service_name'] = kerberosServiceName
  134. params['principal'] = principal
  135. if (checkKrb(keytab, krb5config, kerberosServiceName, principal)) {
  136. const { data } = await createDataSource(params)
  137. if (data.data) {
  138. message.success('添加成功')
  139. updateDataSource()
  140. } else {
  141. message.error(data.msg)
  142. }
  143. }
  144. } else {
  145. const { data } = await createDataSource(params)
  146. if (data.data) {
  147. message.success('连接成功')
  148. } else {
  149. message.error(data.msg)
  150. }
  151. }
  152. }
  153. // 校验krb
  154. const checkKrb = (keytab, krb5config, kerberos_service_name, principal) => {
  155. if (keytab) {
  156. if (krb5config) {
  157. if (kerberos_service_name) {
  158. if (principal) {
  159. return true
  160. } else {
  161. message.error('缺少principal')
  162. return false
  163. }
  164. } else {
  165. message.error('缺少kerberos_service_name')
  166. return false
  167. }
  168. } else {
  169. message.error('缺少krb5config')
  170. return false
  171. }
  172. } else {
  173. message.error('缺少keytab')
  174. return false
  175. }
  176. }
  177. const uploadKerbFile = async fileList => {
  178. const file = new FormData()
  179. fileList.forEach(item => {
  180. file.append('file', item)
  181. })
  182. file.append('project_id', 'test')
  183. file.append('file_type', 'kerberos')
  184. const { data } = await uploadFile(file)
  185. let uri = ''
  186. if (data.code === 200) {
  187. uri = data.data
  188. } else {
  189. message.error(data.msg)
  190. }
  191. return uri
  192. }
  193. // 测试连接按钮
  194. const testConnectBtn = (
  195. <Button onClick={testConnect} loading={loading}>
  196. 测试连接
  197. </Button>
  198. )
  199. //上传文件配置
  200. const keytabUpProps = {
  201. onRemove: file => {
  202. const index = keytabFile.indexOf(file)
  203. const newFileList = keytabFile.slice()
  204. newFileList.splice(index, 1)
  205. setKeytabFile(newFileList)
  206. },
  207. beforeUpload: file => {
  208. setKeytabFile([...keytabFile, file])
  209. return false
  210. },
  211. keytabFile,
  212. }
  213. const krd5UpProps = {
  214. onRemove: file => {
  215. const index = krb5File.indexOf(file)
  216. const newFileList = krb5File.slice()
  217. newFileList.splice(index, 1)
  218. setKrb5File(newFileList)
  219. },
  220. beforeUpload: file => {
  221. setKrb5File([...krb5File, file])
  222. return false
  223. },
  224. krb5File,
  225. }
  226. return (
  227. <ModalForm
  228. form={form}
  229. trigger={<Button type="primary">添加数据源</Button>}
  230. onFinish={finishAdd}
  231. initialValues={{
  232. datasource: DATA_TYPE_MYSQL,
  233. kerbsValid: KERBS_VALID_FALSE,
  234. use_ssl: false,
  235. comments: '',
  236. }}
  237. title="添加数据源"
  238. modalProps={{
  239. destroyOnClose: true,
  240. width: '70%',
  241. afterClose: () => {
  242. setDataType(DATA_TYPE_MYSQL)
  243. setKerbsValid(KERBS_VALID_FALSE)
  244. setUseSSL(false)
  245. form.resetFields()
  246. },
  247. okText: '确认添加',
  248. }}
  249. layout="horizontal"
  250. grid={true}
  251. labelCol={{ span: 8 }}
  252. colProps={{ span: 12 }}
  253. rowProps={{
  254. gutter: [45, 0],
  255. }}>
  256. <ProFormSelect
  257. label="选择数据源"
  258. name="datasource"
  259. fieldProps={{
  260. onChange: val => setDataType(val),
  261. }}
  262. valueEnum={{
  263. mysql: 'mysql',
  264. hive: 'hive',
  265. }}
  266. rules={[
  267. {
  268. required: true,
  269. message: '请选择数据源!',
  270. },
  271. ]}
  272. />
  273. <Col span={12} />
  274. <ProFormText
  275. label="数据源名称"
  276. name="datasource_name"
  277. rules={[
  278. {
  279. required: true,
  280. message: '请输入数据源名称!',
  281. },
  282. ]}
  283. />
  284. <ProFormSelect
  285. label="数据源标签"
  286. name="tag"
  287. fieldProps={{
  288. mode: 'tags',
  289. }}
  290. valueEnum={{
  291. 线上: '线上',
  292. 测试: '测试',
  293. 开发: '开发',
  294. }}
  295. rules={[
  296. {
  297. required: true,
  298. message: '请选择数据源标签!',
  299. },
  300. ]}
  301. />
  302. <ProFormText
  303. label="数据库地址"
  304. name="jdbc_url"
  305. rules={[
  306. {
  307. required: true,
  308. message: '请输入数据库地址!',
  309. },
  310. ]}
  311. />
  312. <ProFormText
  313. label="数据库名称"
  314. name="database_name"
  315. rules={[
  316. {
  317. required: true,
  318. message: '请输入数据库名称!',
  319. },
  320. ]}
  321. />
  322. {!kerbsValid && (
  323. <ProFormText
  324. label="用户名"
  325. name="jdbc_username"
  326. rules={[
  327. {
  328. required: true,
  329. message: '请输入用户名!',
  330. },
  331. ]}
  332. />
  333. )}
  334. {kerbsValid && <ProFormText label="用户名" name="jdbc_username" />}
  335. {!kerbsValid && (
  336. <ProFormText.Password
  337. label="密码"
  338. name="jdbc_password"
  339. rules={[
  340. {
  341. required: true,
  342. message: '请输入密码!',
  343. },
  344. ]}
  345. />
  346. )}
  347. {kerbsValid && <ProFormText.Password label="密码" name="jdbc_password" />}
  348. <ProFormTextArea
  349. label="详情"
  350. name="comments"
  351. fieldProps={{ autoSize: true }}
  352. />
  353. {dataType === 'mysql' && (
  354. <ProFormRadio.Group
  355. label="use SSL"
  356. name="use_ssl"
  357. rules={[
  358. {
  359. required: true,
  360. message: '请选择是否使用SSL!',
  361. },
  362. ]}
  363. fieldProps={{
  364. onChange: e => {
  365. setUseSSL(e.target.value)
  366. },
  367. value: useSSL,
  368. }}
  369. options={[
  370. {
  371. label: '是',
  372. value: true,
  373. },
  374. {
  375. label: '否',
  376. value: false,
  377. },
  378. ]}
  379. />
  380. )}
  381. {dataType === 'hive' && (
  382. <ProFormRadio.Group
  383. label="kerberos验证"
  384. name="kerberosValid"
  385. fieldProps={{
  386. onChange: e => setKerbsValid(e.target.value),
  387. value: kerbsValid,
  388. }}
  389. options={[
  390. {
  391. label: '是',
  392. value: true,
  393. },
  394. {
  395. label: '否',
  396. value: false,
  397. },
  398. ]}
  399. />
  400. )}
  401. <Col span={12} style={{ paddingLeft: '22.5px', paddingRight: '22.5px' }}>
  402. <ProForm.Item label="测试连接" name="success">
  403. {testConnectBtn}
  404. </ProForm.Item>
  405. </Col>
  406. {dataType === 'hive' && kerbsValid ? (
  407. <>
  408. <ProFormUploadButton
  409. label="keytab文件"
  410. name="keytab"
  411. title="上传keyTabPath"
  412. fieldProps={{ ...keytabUpProps }}
  413. max={1}
  414. />
  415. <Col span={12} />
  416. <ProFormUploadButton
  417. label="krb5config文件"
  418. name="krb5config"
  419. title="上传krb5config"
  420. fieldProps={{ ...krd5UpProps }}
  421. max={1}
  422. />
  423. <Col span={12} />
  424. <ProFormText
  425. label="kerberos_service_name"
  426. name="kerberos_service_name"
  427. placeholder="输入kerberos_service_name"
  428. fieldProps={{
  429. onChange: e => setKerberosServiceName(e.target.value),
  430. }}
  431. />
  432. <Col span={12} />
  433. <ProFormText
  434. label="Principal"
  435. name="principal"
  436. placeholder="ylaiuser@EMR-56L6ZNTS"
  437. fieldProps={{
  438. onChange: e => setPrincipal(e.target.value),
  439. }}
  440. />
  441. </>
  442. ) : (
  443. <></>
  444. )}
  445. </ModalForm>
  446. )
  447. }