index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <div class="d-flex res-topology vpc-topology">
  3. <div class="c-left">
  4. <res-vpc :dataSource="dataSource" />
  5. </div>
  6. <div class="c-right" :class="{'bl-none': classic ? isEmpty(wires) : isEmpty(networks)}">
  7. <ul class="list">
  8. <template v-if="classic">
  9. <li class="item d-flex" v-for="(wire, nidx) in wires" :key="nidx">
  10. <res-wire :physical="physical" :dataSource="wire" />
  11. <div v-for="(obj, idx) in getHost(wire)" :key="idx">
  12. <res-common
  13. v-if="!obj.hidden"
  14. :type="RES_ICON_MAP[obj.host_type] || obj.host_type"
  15. :dataSource="obj"
  16. :isExist="isHostExist(wires, nidx, obj)"
  17. :schedTagColorsMap="schedTagColorsMap"
  18. :showStorageTag="true" />
  19. </div>
  20. </li>
  21. <li class="item d-flex" v-for="(item, sid) of getShareStorages(wires)" :key="sid">
  22. <res-share-storage
  23. :key="item.storage.id"
  24. :dataSource="item.storage" />
  25. <div v-for="(obj, idx) in getHosts(wires, item.storage.id)" :key="idx">
  26. <res-common
  27. v-if="!obj.hidden"
  28. :type="RES_ICON_MAP[obj.host_type] || obj.host_type"
  29. :dataSource="obj"
  30. :isExist="true"
  31. :schedTagColorsMap="schedTagColorsMap"
  32. :showStorageTag="true" />
  33. </div>
  34. </li>
  35. </template>
  36. <template v-else>
  37. <li class="item d-flex" v-for="(network, nidx) in networks" :key="nidx">
  38. <res-ipsubnet :dataSource="network" />
  39. <div v-for="(obj, idx) in getAddress(network)" :key="idx">
  40. <res-common
  41. v-if="!obj.hidden"
  42. :type="RES_ICON_MAP[obj.owner_type] || obj.owner_type"
  43. :dataSource="obj"
  44. :isExist="isAddrExist(networks, nidx, obj)" />
  45. </div>
  46. </li>
  47. </template>
  48. </ul>
  49. </div>
  50. </div>
  51. </template>
  52. <script>
  53. import { KVM_SHARE_STORAGES } from '@/constants/storage'
  54. import ResCommon from '@Network/sections/Topology/ResCommon'
  55. import { RES_ICON_MAP } from '@Network/sections/Topology/constants'
  56. import ResMixin from '@Network/sections/Topology/ResMixin'
  57. import ResVpc from '../ResVpc'
  58. import ResWire from '../ResWire'
  59. import ResIpsubnet from '../ResIpsubnet'
  60. import ResShareStorage from '../ResShareStorage'
  61. const COLORS = ['#E45826', '#874356', '#0E3EDA', '#139487', '#464E2E', '#A1B57D', '#6E3CBC', '#6FB2D2', '#C5D8A4', '#F473B9', '#D18CE0', '#203239']
  62. export default {
  63. name: 'VpcTopology',
  64. components: {
  65. ResVpc,
  66. ResWire,
  67. ResCommon,
  68. ResIpsubnet,
  69. ResShareStorage,
  70. },
  71. mixins: [ResMixin],
  72. props: {
  73. classic: Boolean,
  74. physical: Boolean,
  75. dataSource: Object,
  76. },
  77. data () {
  78. return {
  79. RES_ICON_MAP,
  80. }
  81. },
  82. computed: {
  83. wires () {
  84. return this.dataSource?.wires || []
  85. },
  86. networks () {
  87. let networks = []
  88. if (this.dataSource) {
  89. this.dataSource.wires.forEach(v => {
  90. if (v.networks && v.networks.length > 0) {
  91. networks = networks.concat(v.networks.filter(v => v.server_type === 'guest'))
  92. }
  93. })
  94. }
  95. return networks
  96. },
  97. schedTagColorsMap () {
  98. const ret = {}
  99. let index = 0
  100. const { wires = [], hosts = [] } = this.dataSource
  101. const originWires = wires.length ? wires : [{ hosts }]
  102. originWires.map(wire => {
  103. const { hosts = [] } = wire
  104. hosts.map(host => {
  105. const { schedtags = [] } = host
  106. schedtags.map(schedtag => {
  107. if (schedtag.name && !ret[schedtag.name]) {
  108. ret[schedtag.name] = COLORS[index % COLORS.length]
  109. index++
  110. }
  111. })
  112. })
  113. })
  114. return ret
  115. },
  116. },
  117. methods: {
  118. getMultiple (nidx, resArr, curObj) {
  119. if (this.physical) {
  120. if (resArr[nidx + 1]) {
  121. return resArr[nidx + 1].hosts.some((v, i) => {
  122. if (v.id === undefined || curObj.id === undefined) return false
  123. if (v.id === curObj.id) {
  124. resArr[nidx + 1].hosts[i].hidden = true
  125. }
  126. return v.id === curObj.id
  127. })
  128. }
  129. } else {
  130. if (resArr[nidx + 1]) {
  131. return resArr[nidx + 1].address.some((v, i) => {
  132. if (v.owner_id === undefined || curObj.owner_id === undefined) return false
  133. if (v.owner_id === curObj.owner_id) {
  134. resArr[nidx + 1].address[i].hidden = true
  135. }
  136. return v.owner_id === curObj.owner_id
  137. })
  138. }
  139. }
  140. return false
  141. },
  142. getHost (wire) {
  143. const resTypes = ['hypervisor', 'hosts', 'baremetal', 'esxi']
  144. return wire.hosts?.filter(v => resTypes.includes(v.host_type))
  145. },
  146. getAddress (network) {
  147. const resTypes = ['servers', 'hosts', 'loadbalancers', 'dbinstances']
  148. return network.address?.filter(v => resTypes.includes(v.owner_type))
  149. },
  150. isHostExist (wires, nidx, host) {
  151. let isExist = false
  152. // 跨 wire 查找
  153. for (let i = nidx - 1; i >= 0; i--) {
  154. const wire = wires[i]
  155. if (wire.hosts && wire.hosts.length > 0) {
  156. const hostArr = this.getHost(wire)
  157. isExist = hostArr.some(v => v.id === host.id)
  158. if (isExist) return true
  159. }
  160. }
  161. return isExist
  162. },
  163. isAddrExist (networks, nidx, addr) {
  164. let isExist = false
  165. // 跨 networks 查找
  166. for (let i = nidx - 1; i >= 0; i--) {
  167. const network = networks[i]
  168. if (network.address && network.address.length > 0) {
  169. const addressArr = this.getAddress(network)
  170. isExist = addressArr.some(v => v.owner_id === addr.owner_id)
  171. }
  172. }
  173. return isExist
  174. },
  175. getShareStoragesAndHosts (wires) {
  176. const shareStorages = []
  177. const storageHosts = []
  178. for (const wire of wires) {
  179. if (wire.hosts && wire.hosts.length > 0) {
  180. const hosts = []
  181. for (const host of wire.hosts) {
  182. if (host.storages && host.storages.length > 0) {
  183. for (const storage of host.storages) {
  184. const isExsit = shareStorages.find(item => item.storage.id === storage.id)
  185. if (KVM_SHARE_STORAGES.includes(storage.storage_type)) {
  186. hosts.push(host)
  187. storageHosts.push({ key: storage.id, value: hosts })
  188. !isExsit && shareStorages.push({ storage })
  189. }
  190. }
  191. }
  192. }
  193. }
  194. }
  195. return [shareStorages, storageHosts]
  196. },
  197. getShareStorages (wires) {
  198. return this.getShareStoragesAndHosts(wires)[0]
  199. },
  200. getHosts (wires, storageId) {
  201. const storageHosts = this.getShareStoragesAndHosts(wires)[1]
  202. const originHosts = []
  203. const hosts = storageHosts.filter(item => item.key === storageId).map(item => item.value).flat()
  204. hosts.forEach(item => {
  205. const isExist = originHosts.find(v => v.id === item.id)
  206. !isExist && originHosts.push(item)
  207. })
  208. return originHosts
  209. },
  210. },
  211. }
  212. </script>
  213. <style lang="scss" scoped>
  214. // @import "@Network/sections/Topology/index.scss";
  215. </style>