clusterinfo.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package costmodel
  2. import (
  3. "fmt"
  4. "github.com/opencost/opencost/core/pkg/clusters"
  5. "github.com/opencost/opencost/core/pkg/log"
  6. "github.com/opencost/opencost/core/pkg/util/json"
  7. cloudProvider "github.com/opencost/opencost/pkg/cloud/models"
  8. "github.com/opencost/opencost/pkg/config"
  9. "github.com/opencost/opencost/pkg/env"
  10. "github.com/opencost/opencost/pkg/thanos"
  11. "k8s.io/client-go/kubernetes"
  12. )
  13. var (
  14. logCollectionEnabled bool = env.IsLogCollectionEnabled()
  15. productAnalyticsEnabled bool = env.IsProductAnalyticsEnabled()
  16. errorReportingEnabled bool = env.IsErrorReportingEnabled()
  17. valuesReportingEnabled bool = env.IsValuesReportingEnabled()
  18. clusterProfile string = env.GetClusterProfile()
  19. )
  20. // writeReportingFlags writes the reporting flags to the cluster info map
  21. func writeReportingFlags(clusterInfo map[string]string) {
  22. clusterInfo[clusters.ClusterInfoLogCollectionKey] = fmt.Sprintf("%t", logCollectionEnabled)
  23. clusterInfo[clusters.ClusterInfoProductAnalyticsKey] = fmt.Sprintf("%t", productAnalyticsEnabled)
  24. clusterInfo[clusters.ClusterInfoErrorReportingKey] = fmt.Sprintf("%t", errorReportingEnabled)
  25. clusterInfo[clusters.ClusterInfoValuesReportingKey] = fmt.Sprintf("%t", valuesReportingEnabled)
  26. }
  27. // writeClusterProfile writes the data associated with the cluster profile
  28. func writeClusterProfile(clusterInfo map[string]string) {
  29. clusterInfo[clusters.ClusterInfoProfileKey] = clusterProfile
  30. }
  31. // writeThanosFlags includes the configured thanos flags on the cluster info
  32. func writeThanosFlags(clusterInfo map[string]string) {
  33. // Include Thanos Offset Duration if Applicable
  34. clusterInfo[clusters.ClusterInfoThanosEnabledKey] = fmt.Sprintf("%t", thanos.IsEnabled())
  35. if thanos.IsEnabled() {
  36. clusterInfo[clusters.ClusterInfoThanosOffsetKey] = thanos.Offset()
  37. }
  38. }
  39. // localClusterInfoProvider gets the local cluster info from the cloud provider and kubernetes
  40. type localClusterInfoProvider struct {
  41. k8s kubernetes.Interface
  42. provider cloudProvider.Provider
  43. }
  44. // GetClusterInfo returns a string map containing the local cluster info
  45. func (dlcip *localClusterInfoProvider) GetClusterInfo() map[string]string {
  46. data, err := dlcip.provider.ClusterInfo()
  47. // Ensure we create the info object if it doesn't exist
  48. if data == nil {
  49. data = make(map[string]string)
  50. }
  51. kc, ok := dlcip.k8s.(*kubernetes.Clientset)
  52. if ok && data != nil {
  53. v, err := kc.ServerVersion()
  54. if err != nil {
  55. log.Infof("Could not get k8s version info: %s", err.Error())
  56. } else if v != nil {
  57. data[clusters.ClusterInfoVersionKey] = v.Major + "." + v.Minor
  58. }
  59. } else {
  60. log.Infof("Could not get k8s version info: %s", err.Error())
  61. }
  62. writeClusterProfile(data)
  63. writeReportingFlags(data)
  64. writeThanosFlags(data)
  65. return data
  66. }
  67. // NewLocalClusterInfoProvider creates a new clusters.LocalClusterInfoProvider implementation for providing local
  68. // cluster information
  69. func NewLocalClusterInfoProvider(k8s kubernetes.Interface, cloud cloudProvider.Provider) clusters.ClusterInfoProvider {
  70. return &localClusterInfoProvider{
  71. k8s: k8s,
  72. provider: cloud,
  73. }
  74. }
  75. // configuredClusterInfoProvider just provides the cluster info directly from the config file source.
  76. type configuredClusterInfoProvider struct {
  77. config *config.ConfigFile
  78. }
  79. // GetClusterInfo returns a string map containing the local cluster info
  80. func (ccip *configuredClusterInfoProvider) GetClusterInfo() map[string]string {
  81. clusterInfo := map[string]string{}
  82. data, err := ccip.config.Refresh()
  83. if err != nil {
  84. return clusterInfo
  85. }
  86. err = json.Unmarshal(data, &clusterInfo)
  87. if err != nil {
  88. log.Warnf("ClusterInfo failed to load from configuration: %s", err)
  89. return clusterInfo
  90. }
  91. return clusterInfo
  92. }
  93. // NewConfiguredClusterInfoProvider instantiates and returns a cluster info provider which loads cluster info from
  94. // a config file.
  95. func NewConfiguredClusterInfoProvider(config *config.ConfigFile) clusters.ClusterInfoProvider {
  96. return &configuredClusterInfoProvider{
  97. config: config,
  98. }
  99. }
  100. // clusterInfoWriteOnRequest writes the cluster info result to a config whenever it's requested
  101. type clusterInfoWriteOnRequest struct {
  102. clusterInfo clusters.ClusterInfoProvider
  103. config *config.ConfigFile
  104. }
  105. // GetClusterInfo returns a string map containing the local cluster info
  106. func (ciw *clusterInfoWriteOnRequest) GetClusterInfo() map[string]string {
  107. cInfo := ciw.clusterInfo.GetClusterInfo()
  108. result, err := json.Marshal(cInfo)
  109. if err != nil {
  110. log.Warnf("Failed to write the cluster info: %s", err)
  111. return cInfo
  112. }
  113. err = ciw.config.Write(result)
  114. if err != nil {
  115. log.Warnf("Failed to write the cluster info to config: %s", err)
  116. }
  117. return cInfo
  118. }
  119. // NewClusterInfoWriteOnRequest instantiates and returns a cluster info provider which writes the cluster info to a configuration
  120. // before each request.
  121. func NewClusterInfoWriteOnRequest(clusterInfo clusters.ClusterInfoProvider, config *config.ConfigFile) clusters.ClusterInfoProvider {
  122. return &clusterInfoWriteOnRequest{
  123. clusterInfo: clusterInfo,
  124. config: config,
  125. }
  126. }