2
0

clusterinfo.go 4.5 KB

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