2
0

key.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package costmodel
  2. import (
  3. "fmt"
  4. coreenv "github.com/opencost/opencost/core/pkg/env"
  5. "github.com/opencost/opencost/core/pkg/opencost"
  6. )
  7. func newResultPodKey(cluster string, namespace string, pod string) (podKey, error) {
  8. if cluster == "" {
  9. cluster = coreenv.GetClusterID()
  10. }
  11. if namespace == "" {
  12. return podKey{}, fmt.Errorf("namespace is required")
  13. }
  14. if pod == "" {
  15. return podKey{}, fmt.Errorf("pod is required")
  16. }
  17. return newPodKey(cluster, namespace, pod), nil
  18. }
  19. type podKey struct {
  20. namespaceKey
  21. Pod string
  22. }
  23. func (k podKey) String() string {
  24. return fmt.Sprintf("%s/%s/%s", k.Cluster, k.Namespace, k.Pod)
  25. }
  26. func newPodKey(cluster, namespace, pod string) podKey {
  27. return podKey{
  28. namespaceKey: namespaceKey{
  29. Cluster: cluster,
  30. Namespace: namespace,
  31. },
  32. Pod: pod,
  33. }
  34. }
  35. // getUnmountedPodKey while certain Unmounted costs can have a namespace, all unmounted costs for a single cluster will be represented by the same asset
  36. func getUnmountedPodKey(cluster string) podKey {
  37. return newPodKey(cluster, opencost.UnmountedSuffix, opencost.UnmountedSuffix)
  38. }
  39. type namespaceKey struct {
  40. Cluster string
  41. Namespace string
  42. }
  43. func (k namespaceKey) String() string {
  44. return fmt.Sprintf("%s/%s", k.Cluster, k.Namespace)
  45. }
  46. func newNamespaceKey(cluster, namespace string) namespaceKey {
  47. return namespaceKey{
  48. Cluster: cluster,
  49. Namespace: namespace,
  50. }
  51. }
  52. func newResultNamespaceKey(cluster string, namespace string) (namespaceKey, error) {
  53. if cluster == "" {
  54. cluster = coreenv.GetClusterID()
  55. }
  56. if namespace == "" {
  57. return namespaceKey{}, fmt.Errorf("namespace is required")
  58. }
  59. return newNamespaceKey(cluster, namespace), nil
  60. }
  61. type controllerKey struct {
  62. Cluster string
  63. Namespace string
  64. ControllerKind string
  65. Controller string
  66. }
  67. func (k controllerKey) String() string {
  68. return fmt.Sprintf("%s/%s/%s/%s", k.Cluster, k.Namespace, k.ControllerKind, k.Controller)
  69. }
  70. func newControllerKey(cluster, namespace, controllerKind, controller string) controllerKey {
  71. return controllerKey{
  72. Cluster: cluster,
  73. Namespace: namespace,
  74. ControllerKind: controllerKind,
  75. Controller: controller,
  76. }
  77. }
  78. func newResultControllerKey(cluster, namespace, controller, controllerKind string) (controllerKey, error) {
  79. if cluster == "" {
  80. cluster = coreenv.GetClusterID()
  81. }
  82. if namespace == "" {
  83. return controllerKey{}, fmt.Errorf("namespace is required")
  84. }
  85. if controller == "" {
  86. return controllerKey{}, fmt.Errorf("controller is required")
  87. }
  88. return newControllerKey(cluster, namespace, controllerKind, controller), nil
  89. }
  90. type serviceKey struct {
  91. Cluster string
  92. Namespace string
  93. Service string
  94. }
  95. func (k serviceKey) String() string {
  96. return fmt.Sprintf("%s/%s/%s", k.Cluster, k.Namespace, k.Service)
  97. }
  98. func newServiceKey(cluster, namespace, service string) serviceKey {
  99. return serviceKey{
  100. Cluster: cluster,
  101. Namespace: namespace,
  102. Service: service,
  103. }
  104. }
  105. func newResultServiceKey(cluster, namespace, service string) (serviceKey, error) {
  106. if cluster == "" {
  107. cluster = coreenv.GetClusterID()
  108. }
  109. if namespace == "" {
  110. return serviceKey{}, fmt.Errorf("namespace is required")
  111. }
  112. if service == "" {
  113. return serviceKey{}, fmt.Errorf("service is required")
  114. }
  115. return newServiceKey(cluster, namespace, service), nil
  116. }
  117. type nodeKey struct {
  118. Cluster string
  119. Node string
  120. }
  121. func (k nodeKey) String() string {
  122. return fmt.Sprintf("%s/%s", k.Cluster, k.Node)
  123. }
  124. func newNodeKey(cluster, node string) nodeKey {
  125. return nodeKey{
  126. Cluster: cluster,
  127. Node: node,
  128. }
  129. }
  130. func newResultNodeKey(cluster string, node string) (nodeKey, error) {
  131. if cluster == "" {
  132. cluster = coreenv.GetClusterID()
  133. }
  134. if node == "" {
  135. return nodeKey{}, fmt.Errorf("node is required")
  136. }
  137. return newNodeKey(cluster, node), nil
  138. }
  139. type pvcKey struct {
  140. Cluster string
  141. Namespace string
  142. PersistentVolumeClaim string
  143. }
  144. func (k pvcKey) String() string {
  145. return fmt.Sprintf("%s/%s/%s", k.Cluster, k.Namespace, k.PersistentVolumeClaim)
  146. }
  147. func newPVCKey(cluster, namespace, persistentVolumeClaim string) pvcKey {
  148. return pvcKey{
  149. Cluster: cluster,
  150. Namespace: namespace,
  151. PersistentVolumeClaim: persistentVolumeClaim,
  152. }
  153. }
  154. // resultPVCKey converts a Prometheus query result to a pvcKey by
  155. // looking up values associated with the given label names. For example,
  156. // passing "cluster_id" for clusterLabel will use the value of the label
  157. // "cluster_id" as the pvcKey's Cluster field. If a given field does not
  158. // exist on the result, an error is returned. (The only exception to that is
  159. // clusterLabel, which we expect may not exist, but has a default value.)
  160. func newResultPVCKey(cluster, namespace, pvc string) (pvcKey, error) {
  161. if cluster == "" {
  162. cluster = coreenv.GetClusterID()
  163. }
  164. if namespace == "" {
  165. return pvcKey{}, fmt.Errorf("namespace is required")
  166. }
  167. if pvc == "" {
  168. return pvcKey{}, fmt.Errorf("persistentvolumeclaim is required")
  169. }
  170. return newPVCKey(cluster, namespace, pvc), nil
  171. }
  172. type pvKey struct {
  173. Cluster string
  174. PersistentVolume string
  175. }
  176. func (k pvKey) String() string {
  177. return fmt.Sprintf("%s/%s", k.Cluster, k.PersistentVolume)
  178. }
  179. func newPVKey(cluster, persistentVolume string) pvKey {
  180. return pvKey{
  181. Cluster: cluster,
  182. PersistentVolume: persistentVolume,
  183. }
  184. }
  185. func newResultPVKey(cluster, pv string) (pvKey, error) {
  186. if cluster == "" {
  187. cluster = coreenv.GetClusterID()
  188. }
  189. if pv == "" {
  190. return pvKey{}, fmt.Errorf("persistentvolume is required")
  191. }
  192. return newPVKey(cluster, pv), nil
  193. }