index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <div>
  3. <page-header :title="$t('helm.text_87')" />
  4. <page-body needMarginBottom>
  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. version: [
  109. 'version',
  110. {
  111. rules: [
  112. { required: true, message: this.$t('helm.text_30'), trigger: 'blur' },
  113. ],
  114. },
  115. ],
  116. yaml: [
  117. 'yaml',
  118. {
  119. validateFirst: true,
  120. rules: [
  121. { required: true, message: this.$t('helm.text_43') },
  122. { validator },
  123. ],
  124. },
  125. ],
  126. },
  127. }
  128. },
  129. computed: {
  130. compiledMarkdown () {
  131. const markdownDoc = Base64.decode(this.chartDetail.readme)
  132. return marked(markdownDoc, { sanitize: true })
  133. },
  134. },
  135. created () {
  136. this.chartsM = new this.$Manager('charts', 'v1')
  137. this.releaseM = new this.$Manager('releases', 'v1')
  138. this.getRelease()
  139. },
  140. methods: {
  141. versionChange (key) {
  142. this.currentVersion = this.versions.find(val => val.key === key)
  143. this.getChart()
  144. },
  145. async getChart () {
  146. const repo = this.currentVersion.repo
  147. const name = this.currentVersion.chart.name
  148. const { data } = await this.chartsM.get({
  149. id: name,
  150. params: {
  151. repo,
  152. },
  153. })
  154. if (data) {
  155. this.previewFiles = data.files
  156. }
  157. },
  158. async getRelease () {
  159. const { id } = this.$route.params
  160. const { data } = await this.releaseM.get({
  161. id,
  162. params: {
  163. cluster: this.$route.query.cluster,
  164. namespace: this.$route.query.namespace,
  165. },
  166. })
  167. if (!R.isNil(data) && !R.isEmpty(data)) {
  168. this.releaseDetail = data
  169. this.chartDetail = this.releaseDetail.chart_info
  170. this.form.fc.setFieldsValue({
  171. [this.decorators.release_name[0]]: this.releaseDetail.name,
  172. [this.decorators.yaml[0]]: jsYaml.safeDump(this.releaseDetail.config || {}, { lineWidth: Infinity }),
  173. })
  174. this.getChartVersion()
  175. }
  176. },
  177. async getChartVersion () {
  178. this.versionLoading = true
  179. const { data: { data = [] } } = await this.chartsM.list({
  180. params: {
  181. repo: this.releaseDetail.repo_id,
  182. name: this.chartDetail.metadata.name,
  183. all_version: true,
  184. limit: 0,
  185. version: `^${this.chartDetail.metadata.version}`,
  186. },
  187. })
  188. if (data.length === 0) {
  189. this.$message.error(this.$t('helm.text_44'))
  190. return
  191. }
  192. this.versions = data.map(v => {
  193. return {
  194. ...v,
  195. label: `${v.repo}-${v.version}`,
  196. key: `${v.repo}$$${v.version}`,
  197. }
  198. })
  199. if (this.versions && this.versions.length) {
  200. let defaultVersion = this.versions[0].key
  201. const findVersion = this.versions.find(val => val.version === this.chartDetail.metadata.version)
  202. if (findVersion) {
  203. defaultVersion = findVersion.key
  204. }
  205. this.form.fc.setFieldsValue({
  206. [this.decorators.version[0]]: defaultVersion,
  207. })
  208. this.versionChange(defaultVersion)
  209. }
  210. },
  211. async doUpdate (values) {
  212. const data = {
  213. chart_name: this.chartDetail.metadata.name,
  214. release_name: values.release_name,
  215. cluster: this.$route.query.cluster,
  216. namespace: this.$route.query.namespace,
  217. values: values.yaml,
  218. }
  219. if (!R.isNil(values.version) && !R.isEmpty(values.version)) {
  220. const [repo, v] = values.version.split('$$')
  221. data.repo = repo
  222. data.version = v
  223. }
  224. const { id } = this.$route.params
  225. await this.releaseM.performAction({
  226. id,
  227. action: 'upgrade',
  228. data,
  229. })
  230. },
  231. async confirm () {
  232. try {
  233. this.loading = true
  234. const values = await this.form.fc.validateFields()
  235. await this.doUpdate(values)
  236. this.$message.success(this.$t('helm.text_45'))
  237. this.loading = false
  238. this.cancel()
  239. } catch (error) {
  240. this.loading = false
  241. throw error
  242. }
  243. },
  244. cancel () {
  245. this.$router.push('/k8s-release')
  246. },
  247. },
  248. }
  249. </script>