persistentvolume.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package render
  2. import (
  3. "context"
  4. "strings"
  5. "github.com/weaveworks/scope/report"
  6. )
  7. // KubernetesVolumesRenderer is a Renderer which combines all Kubernetes
  8. // volumes components such as stateful Pods, Persistent Volume, Persistent Volume Claim, Storage Class.
  9. var KubernetesVolumesRenderer = MakeReduce(
  10. VolumesRenderer,
  11. PodToVolumeRenderer,
  12. PVCToStorageClassRenderer,
  13. PVToSnapshotRenderer,
  14. VolumeSnapshotRenderer,
  15. )
  16. // VolumesRenderer is a Renderer which produces a renderable kubernetes PV & PVC
  17. // graph by merging the pods graph and the Persistent Volume topology.
  18. var VolumesRenderer = volumesRenderer{}
  19. // volumesRenderer is a Renderer to render PV & PVC nodes.
  20. type volumesRenderer struct{}
  21. // Render renders PV & PVC nodes along with adjacency
  22. func (v volumesRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
  23. nodes := make(report.Nodes)
  24. for id, n := range rpt.PersistentVolumeClaim.Nodes {
  25. volume, _ := n.Latest.Lookup(report.KubernetesVolumeName)
  26. for _, p := range rpt.PersistentVolume.Nodes {
  27. volumeName, _ := p.Latest.Lookup(report.KubernetesName)
  28. if volume == volumeName {
  29. n.Adjacency = n.Adjacency.Add(p.ID)
  30. n.Children = n.Children.Add(p)
  31. }
  32. }
  33. nodes[id] = n
  34. }
  35. return Nodes{Nodes: nodes}
  36. }
  37. // PodToVolumeRenderer is a Renderer which produces a renderable kubernetes Pod
  38. // graph by merging the pods graph and the Persistent Volume Claim topology.
  39. // Pods having persistent volumes are rendered.
  40. var PodToVolumeRenderer = podToVolumesRenderer{}
  41. // VolumesRenderer is a Renderer to render Pods & PVCs.
  42. type podToVolumesRenderer struct{}
  43. // Render renders the Pod nodes having volumes adjacency.
  44. func (v podToVolumesRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
  45. nodes := make(report.Nodes)
  46. for podID, podNode := range rpt.Pod.Nodes {
  47. claimNames, found := podNode.Latest.Lookup(report.KubernetesVolumeClaim)
  48. if !found {
  49. continue
  50. }
  51. podNamespace, _ := podNode.Latest.Lookup(report.KubernetesNamespace)
  52. claimNameList := strings.Split(claimNames, report.ScopeDelim)
  53. for _, ClaimName := range claimNameList {
  54. for _, pvcNode := range rpt.PersistentVolumeClaim.Nodes {
  55. pvcName, _ := pvcNode.Latest.Lookup(report.KubernetesName)
  56. pvcNamespace, _ := pvcNode.Latest.Lookup(report.KubernetesNamespace)
  57. if (pvcName == ClaimName) && (podNamespace == pvcNamespace) {
  58. podNode.Adjacency = podNode.Adjacency.Add(pvcNode.ID)
  59. podNode.Children = podNode.Children.Add(pvcNode)
  60. break
  61. }
  62. }
  63. }
  64. nodes[podID] = podNode
  65. }
  66. return Nodes{Nodes: nodes}
  67. }
  68. // PVCToStorageClassRenderer is a Renderer which produces a renderable kubernetes PVC
  69. // & Storage class graph.
  70. var PVCToStorageClassRenderer = pvcToStorageClassRenderer{}
  71. // pvcToStorageClassRenderer is a Renderer to render PVC & StorageClass.
  72. type pvcToStorageClassRenderer struct{}
  73. // Render renders the PVC & Storage Class nodes with adjacency.
  74. func (v pvcToStorageClassRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
  75. nodes := make(report.Nodes)
  76. for scID, scNode := range rpt.StorageClass.Nodes {
  77. storageClass, _ := scNode.Latest.Lookup(report.KubernetesName)
  78. for _, pvcNode := range rpt.PersistentVolumeClaim.Nodes {
  79. storageClassName, _ := pvcNode.Latest.Lookup(report.KubernetesStorageClassName)
  80. if storageClassName == storageClass {
  81. scNode.Adjacency = scNode.Adjacency.Add(pvcNode.ID)
  82. scNode.Children = scNode.Children.Add(pvcNode)
  83. }
  84. }
  85. nodes[scID] = scNode
  86. }
  87. return Nodes{Nodes: nodes}
  88. }
  89. //PVToSnapshotRenderer is a Renderer which produces a renderable kubernetes PV
  90. var PVToSnapshotRenderer = pvToSnapshotRenderer{}
  91. //pvToSnapshotRenderer is a Renderer to render PV & Snapshot.
  92. type pvToSnapshotRenderer struct{}
  93. //Render renders the PV & Snapshot nodes with adjacency.
  94. func (v pvToSnapshotRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
  95. nodes := make(report.Nodes)
  96. for pvNodeID, p := range rpt.PersistentVolume.Nodes {
  97. volumeName, _ := p.Latest.Lookup(report.KubernetesName)
  98. for _, volumeSnapshotNode := range rpt.VolumeSnapshot.Nodes {
  99. snapshotPVName, _ := volumeSnapshotNode.Latest.Lookup(report.KubernetesVolumeName)
  100. if volumeName == snapshotPVName {
  101. p.Adjacency = p.Adjacency.Add(volumeSnapshotNode.ID)
  102. p.Children = p.Children.Add(volumeSnapshotNode)
  103. }
  104. }
  105. nodes[pvNodeID] = p
  106. }
  107. return Nodes{Nodes: nodes}
  108. }
  109. // VolumeSnapshotRenderer is a renderer which produces a renderable Kubernetes Volume Snapshot and Volume Snapshot Data
  110. var VolumeSnapshotRenderer = volumeSnapshotRenderer{}
  111. // volumeSnapshotRenderer is a render to volume snapshot & volume snapshot data
  112. type volumeSnapshotRenderer struct{}
  113. // Render renders the volumeSnapshots & volumeSnapshotData with adjacency
  114. // It checks for the volumeSnapshotData name in volumeSnapshot, adjacency is created by matching the volumeSnapshotData name.
  115. func (v volumeSnapshotRenderer) Render(ctx context.Context, rpt report.Report) Nodes {
  116. nodes := make(report.Nodes)
  117. for volumeSnapshotID, volumeSnapshotNode := range rpt.VolumeSnapshot.Nodes {
  118. snapshotData, _ := volumeSnapshotNode.Latest.Lookup(report.KubernetesSnapshotData)
  119. for volumeSnapshotDataID, volumeSnapshotDataNode := range rpt.VolumeSnapshotData.Nodes {
  120. snapshotDataName, _ := volumeSnapshotDataNode.Latest.Lookup(report.KubernetesName)
  121. if snapshotDataName == snapshotData {
  122. volumeSnapshotNode.Adjacency = volumeSnapshotNode.Adjacency.Add(volumeSnapshotDataNode.ID)
  123. volumeSnapshotNode.Children = volumeSnapshotNode.Children.Add(volumeSnapshotDataNode)
  124. }
  125. nodes[volumeSnapshotDataID] = volumeSnapshotDataNode
  126. }
  127. nodes[volumeSnapshotID] = volumeSnapshotNode
  128. }
  129. return Nodes{Nodes: nodes}
  130. }