index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <div>
  3. <page-header :title="$t('helm.text_87')" />
  4. <page-body>
  5. <div>
  6. <template v-if="!chartDetail.metadata">
  7. <loading-block :layout="loadingLayout" />
  8. </template>
  9. <template v-else>
  10. <page-card-detail
  11. class="mt-3 mb-4"
  12. :img="chartDetail.metadata.icon"
  13. :page-title="chartDetail.metadata.name || ''"
  14. :description="chartDetail.metadata.description" />
  15. <a-form
  16. v-bind="formItemLayout"
  17. :form="form.fc">
  18. <a-form-item :label="$t('helm.text_16')">
  19. <a-input v-decorator="decorators.release_name" :placeholder="$t('helm.text_28')" disabled />
  20. </a-form-item>
  21. <a-form-item :label="$t('helm.text_29')">
  22. <a-select v-decorator="decorators.version" :placeholder="$t('helm.text_30')" @change="versionChange">
  23. <a-select-option
  24. v-for="item in versions"
  25. :key="item.key"
  26. :value="item.key">
  27. {{ item.label }}
  28. </a-select-option>
  29. </a-select>
  30. </a-form-item>
  31. <a-form-item :label="$t('helm.text_88')">
  32. <code-mirror v-decorator="decorators.yaml" :options="cmOptions" />
  33. </a-form-item>
  34. </a-form>
  35. <template-preview :previewFiles="previewFiles" />
  36. </template>
  37. </div>
  38. </page-body>
  39. <page-footer>
  40. <div slot="right">
  41. <a-button class="mr-3" type="primary" @click="confirm" :loading="loading">{{$t('helm.text_35')}}</a-button>
  42. <a-button @click="cancel">{{$t('helm.text_36')}}</a-button>
  43. </div>
  44. </page-footer>
  45. </div>
  46. </template>
  47. <script>
  48. import * as R from 'ramda'
  49. import marked from 'marked'
  50. import { Base64 } from 'js-base64'
  51. import jsYaml from 'js-yaml'
  52. import TemplatePreview from '@K8S/sections/TemplatePreview'
  53. import { validateYaml } from '@/utils/validate'
  54. export default {
  55. name: 'K8SChartCreate',
  56. components: {
  57. TemplatePreview,
  58. },
  59. data () {
  60. const validator = (rule, value, _callback) => {
  61. validateYaml(value)
  62. .then(() => {
  63. return _callback()
  64. })
  65. .catch(() => {
  66. return _callback(this.$t('helm.text_37'))
  67. })
  68. }
  69. return {
  70. versions: [],
  71. previewFiles: [],
  72. currentVersion: {},
  73. loading: false,
  74. chartDetail: {
  75. readme: '',
  76. chart: {},
  77. metadata: {},
  78. },
  79. releaseDetail: {},
  80. formItemLayout: {
  81. labelCol: { span: 4 },
  82. wrapperCol: { span: 20 },
  83. },
  84. cmOptions: {
  85. tabSize: 2,
  86. styleActiveLine: true,
  87. lineNumbers: true,
  88. line: true,
  89. mode: 'text/x-yaml',
  90. theme: 'material',
  91. },
  92. loadingLayout: [
  93. [10],
  94. [8, 9],
  95. [2, 4, 7, 5],
  96. [13, 9],
  97. [4, 3, 8],
  98. [8, 6, 8],
  99. [13, 9],
  100. ],
  101. form: {
  102. fc: this.$form.createForm(this),
  103. },
  104. decorators: {
  105. release_name: [
  106. 'release_name',
  107. {
  108. validateFirst: true,
  109. rules: [
  110. { required: true, message: this.$t('helm.text_28') },
  111. { min: 2, max: 24, message: this.$t('helm.text_38'), trigger: 'blur' },
  112. { validator: this.$validate('k8sName') },
  113. ],
  114. },
  115. ],
  116. version: [
  117. 'version',
  118. {
  119. rules: [
  120. { required: true, message: this.$t('helm.text_30'), trigger: 'blur' },
  121. ],
  122. },
  123. ],
  124. yaml: [
  125. 'yaml',
  126. {
  127. validateFirst: true,
  128. rules: [
  129. { required: true, message: this.$t('helm.text_43') },
  130. { validator },
  131. ],
  132. },
  133. ],
  134. },
  135. }
  136. },
  137. computed: {
  138. compiledMarkdown () {
  139. const markdownDoc = Base64.decode(this.chartDetail.readme)
  140. return marked(markdownDoc, { sanitize: true })
  141. },
  142. },
  143. created () {
  144. this.chartsM = new this.$Manager('charts', 'v1')
  145. this.releaseM = new this.$Manager('releases', 'v1')
  146. this.getRelease()
  147. },
  148. methods: {
  149. versionChange (key) {
  150. this.currentVersion = this.versions.find(val => val.key === key)
  151. this.getChart()
  152. },
  153. async getChart () {
  154. const repo = this.currentVersion.repo
  155. const name = this.currentVersion.chart.name
  156. const { data } = await this.chartsM.get({
  157. id: name,
  158. params: {
  159. repo,
  160. },
  161. })
  162. if (data) {
  163. this.previewFiles = data.files
  164. }
  165. },
  166. async getRelease () {
  167. const { name } = this.$route.params
  168. const { data } = await this.releaseM.get({
  169. id: `${name}`,
  170. params: {
  171. cluster: this.$route.query.cluster,
  172. namespace: this.$route.query.namespace,
  173. },
  174. })
  175. if (!R.isNil(data) && !R.isEmpty(data)) {
  176. this.releaseDetail = data
  177. this.chartDetail = this.releaseDetail.chart
  178. this.form.fc.setFieldsValue({
  179. [this.decorators.release_name[0]]: this.releaseDetail.name,
  180. [this.decorators.yaml[0]]: jsYaml.safeDump(this.releaseDetail.config || {}, { lineWidth: Infinity }),
  181. })
  182. this.getChartVersion()
  183. }
  184. },
  185. async getChartVersion () {
  186. this.versionLoading = true
  187. const { data: { data = [] } } = await this.chartsM.list({
  188. params: {
  189. name: this.chartDetail.metadata.name,
  190. all_version: true,
  191. limit: 0,
  192. version: `^${this.chartDetail.metadata.version}`,
  193. },
  194. })
  195. if (data.length === 0) {
  196. this.$message.error(this.$t('helm.text_44'))
  197. return
  198. }
  199. this.versions = data.map(v => {
  200. return {
  201. ...v,
  202. label: `${v.repo}-${v.version}`,
  203. key: `${v.repo}-${v.version}`,
  204. }
  205. })
  206. if (this.versions && this.versions.length) {
  207. let defaultVersion = this.versions[0].key
  208. const findVersion = this.versions.find(val => val.version === this.chartDetail.metadata.version)
  209. if (findVersion) {
  210. defaultVersion = findVersion.key
  211. }
  212. this.form.fc.setFieldsValue({
  213. [this.decorators.version[0]]: defaultVersion,
  214. })
  215. this.versionChange(defaultVersion)
  216. }
  217. },
  218. async doUpdate (values) {
  219. const data = {
  220. chart_name: this.chartDetail.metadata.name,
  221. release_name: values.release_name,
  222. cluster: this.$route.query.cluster,
  223. namespace: this.$route.query.namespace,
  224. values: values.yaml,
  225. }
  226. if (!R.isNil(values.version) && !R.isEmpty(values.version)) {
  227. const [repo, v] = values.version.split('-')
  228. data.repo = repo
  229. data.version = v
  230. }
  231. await this.releaseM.update({
  232. id: values.release_name,
  233. data,
  234. })
  235. },
  236. async confirm () {
  237. try {
  238. this.loading = true
  239. const values = await this.form.fc.validateFields()
  240. await this.doUpdate(values)
  241. this.$message.success(this.$t('helm.text_45'))
  242. this.loading = false
  243. this.cancel()
  244. } catch (error) {
  245. this.loading = false
  246. throw error
  247. }
  248. },
  249. cancel () {
  250. this.$router.push('/k8s-release')
  251. },
  252. },
  253. }
  254. </script>