clusterexporter.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package clustercache
  2. import (
  3. "time"
  4. cc "github.com/opencost/opencost/core/pkg/clustercache"
  5. "github.com/opencost/opencost/core/pkg/log"
  6. "github.com/opencost/opencost/core/pkg/util/atomic"
  7. "github.com/opencost/opencost/core/pkg/util/json"
  8. "github.com/opencost/opencost/pkg/config"
  9. )
  10. // clusterEncoding is used to represent the cluster objects in the encoded states.
  11. type clusterEncoding struct {
  12. Namespaces []*cc.Namespace `json:"namespaces,omitempty"`
  13. Nodes []*cc.Node `json:"nodes,omitempty"`
  14. Pods []*cc.Pod `json:"pods,omitempty"`
  15. Services []*cc.Service `json:"services,omitempty"`
  16. DaemonSets []*cc.DaemonSet `json:"daemonSets,omitempty"`
  17. Deployments []*cc.Deployment `json:"deployments,omitempty"`
  18. StatefulSets []*cc.StatefulSet `json:"statefulSets,omitempty"`
  19. ReplicaSets []*cc.ReplicaSet `json:"replicaSets,omitempty"`
  20. PersistentVolumes []*cc.PersistentVolume `json:"persistentVolumes,omitempty"`
  21. PersistentVolumeClaims []*cc.PersistentVolumeClaim `json:"persistentVolumeClaims,omitempty"`
  22. StorageClasses []*cc.StorageClass `json:"storageClasses,omitempty"`
  23. Jobs []*cc.Job `json:"jobs,omitempty"`
  24. PodDisruptionBudgets []*cc.PodDisruptionBudget `json:"podDisruptionBudgets,omitempty"`
  25. ReplicationControllers []*cc.ReplicationController `json:"replicationController,omitempty"`
  26. }
  27. // ClusterExporter manages and runs an file export process which dumps the local kubernetes cluster to a target location.
  28. type ClusterExporter struct {
  29. cluster cc.ClusterCache
  30. target *config.ConfigFile
  31. interval time.Duration
  32. runState atomic.AtomicRunState
  33. }
  34. // NewClusterExporter creates a new ClusterExporter instance for exporting the kubernetes cluster.
  35. func NewClusterExporter(cluster cc.ClusterCache, target *config.ConfigFile, interval time.Duration) *ClusterExporter {
  36. return &ClusterExporter{
  37. cluster: cluster,
  38. target: target,
  39. interval: interval,
  40. }
  41. }
  42. // Run starts the automated process of running Export on a specific interval.
  43. func (ce *ClusterExporter) Run() {
  44. // in the event there is a race that occurs between Run() and Stop(), we
  45. // ensure that we wait for the reset to occur before starting again
  46. ce.runState.WaitForReset()
  47. if !ce.runState.Start() {
  48. log.Warnf("ClusterExporter already running")
  49. return
  50. }
  51. go func() {
  52. for {
  53. err := ce.Export()
  54. if err != nil {
  55. log.Warnf("Failed to export cluster: %s", err)
  56. }
  57. select {
  58. case <-time.After(ce.interval):
  59. case <-ce.runState.OnStop():
  60. ce.runState.Reset()
  61. return
  62. }
  63. }
  64. }()
  65. }
  66. // Stop halts the Cluster export on an interval
  67. func (ce *ClusterExporter) Stop() {
  68. ce.runState.Stop()
  69. }
  70. // Export stores the cluster cache data into a PODO, marshals as JSON, and saves it to the
  71. // target location.
  72. func (ce *ClusterExporter) Export() error {
  73. c := ce.cluster
  74. encoding := &clusterEncoding{
  75. Namespaces: c.GetAllNamespaces(),
  76. Nodes: c.GetAllNodes(),
  77. Pods: c.GetAllPods(),
  78. Services: c.GetAllServices(),
  79. DaemonSets: c.GetAllDaemonSets(),
  80. Deployments: c.GetAllDeployments(),
  81. StatefulSets: c.GetAllStatefulSets(),
  82. ReplicaSets: c.GetAllReplicaSets(),
  83. PersistentVolumes: c.GetAllPersistentVolumes(),
  84. PersistentVolumeClaims: c.GetAllPersistentVolumeClaims(),
  85. StorageClasses: c.GetAllStorageClasses(),
  86. Jobs: c.GetAllJobs(),
  87. PodDisruptionBudgets: c.GetAllPodDisruptionBudgets(),
  88. ReplicationControllers: c.GetAllReplicationControllers(),
  89. }
  90. data, err := json.Marshal(encoding)
  91. if err != nil {
  92. return err
  93. }
  94. return ce.target.Write(data)
  95. }