athenaconfiguration.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package aws
  2. import (
  3. "fmt"
  4. "github.com/opencost/opencost/pkg/cloud/config"
  5. "github.com/opencost/opencost/pkg/util/json"
  6. )
  7. // AthenaConfiguration
  8. type AthenaConfiguration struct {
  9. Bucket string `json:"bucket"`
  10. Region string `json:"region"`
  11. Database string `json:"database"`
  12. Table string `json:"table"`
  13. Workgroup string `json:"workgroup"`
  14. Account string `json:"account"`
  15. Authorizer Authorizer `json:"authorizer"`
  16. }
  17. func (ac *AthenaConfiguration) Validate() error {
  18. // Validate Authorizer
  19. if ac.Authorizer == nil {
  20. return fmt.Errorf("AthenaConfiguration: missing Authorizer")
  21. }
  22. err := ac.Authorizer.Validate()
  23. if err != nil {
  24. return fmt.Errorf("AthenaConfiguration: %s", err)
  25. }
  26. // Validate base properties
  27. if ac.Bucket == "" {
  28. return fmt.Errorf("AthenaConfiguration: missing bucket")
  29. }
  30. if ac.Region == "" {
  31. return fmt.Errorf("AthenaConfiguration: missing region")
  32. }
  33. if ac.Database == "" {
  34. return fmt.Errorf("AthenaConfiguration: missing database")
  35. }
  36. if ac.Table == "" {
  37. return fmt.Errorf("AthenaConfiguration: missing table")
  38. }
  39. if ac.Account == "" {
  40. return fmt.Errorf("AthenaConfiguration: missing account")
  41. }
  42. return nil
  43. }
  44. func (ac *AthenaConfiguration) Equals(config config.Config) bool {
  45. if config == nil {
  46. return false
  47. }
  48. thatConfig, ok := config.(*AthenaConfiguration)
  49. if !ok {
  50. return false
  51. }
  52. if ac.Authorizer != nil {
  53. if !ac.Authorizer.Equals(thatConfig.Authorizer) {
  54. return false
  55. }
  56. } else {
  57. if thatConfig.Authorizer != nil {
  58. return false
  59. }
  60. }
  61. if ac.Bucket != thatConfig.Bucket {
  62. return false
  63. }
  64. if ac.Region != thatConfig.Region {
  65. return false
  66. }
  67. if ac.Database != thatConfig.Database {
  68. return false
  69. }
  70. if ac.Table != thatConfig.Table {
  71. return false
  72. }
  73. if ac.Workgroup != thatConfig.Workgroup {
  74. return false
  75. }
  76. if ac.Account != thatConfig.Account {
  77. return false
  78. }
  79. return true
  80. }
  81. func (ac *AthenaConfiguration) Sanitize() config.Config {
  82. return &AthenaConfiguration{
  83. Bucket: ac.Bucket,
  84. Region: ac.Region,
  85. Database: ac.Database,
  86. Table: ac.Table,
  87. Workgroup: ac.Workgroup,
  88. Account: ac.Account,
  89. Authorizer: ac.Authorizer.Sanitize().(Authorizer),
  90. }
  91. }
  92. func (ac *AthenaConfiguration) Key() string {
  93. return fmt.Sprintf("%s/%s", ac.Account, ac.Bucket)
  94. }
  95. func (ac *AthenaConfiguration) UnmarshalJSON(b []byte) error {
  96. var f interface{}
  97. err := json.Unmarshal(b, &f)
  98. if err != nil {
  99. return err
  100. }
  101. fmap := f.(map[string]interface{})
  102. bucket, err := config.GetInterfaceValue[string](fmap, "bucket")
  103. if err != nil {
  104. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  105. }
  106. ac.Bucket = bucket
  107. region, err := config.GetInterfaceValue[string](fmap, "region")
  108. if err != nil {
  109. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  110. }
  111. ac.Region = region
  112. database, err := config.GetInterfaceValue[string](fmap, "database")
  113. if err != nil {
  114. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  115. }
  116. ac.Database = database
  117. table, err := config.GetInterfaceValue[string](fmap, "table")
  118. if err != nil {
  119. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  120. }
  121. ac.Table = table
  122. workgroup, err := config.GetInterfaceValue[string](fmap, "workgroup")
  123. if err != nil {
  124. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  125. }
  126. ac.Workgroup = workgroup
  127. account, err := config.GetInterfaceValue[string](fmap, "account")
  128. if err != nil {
  129. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  130. }
  131. ac.Account = account
  132. authAny, ok := fmap["authorizer"]
  133. if !ok {
  134. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: missing authorizer")
  135. }
  136. authorizer, err := config.AuthorizerFromInterface(authAny, SelectAuthorizerByType)
  137. if err != nil {
  138. return fmt.Errorf("AthenaConfiguration: UnmarshalJSON: %s", err.Error())
  139. }
  140. ac.Authorizer = authorizer
  141. return nil
  142. }
  143. // ConvertAwsAthenaInfoToConfig takes a legacy config and generates a Config based on the presence of properties to match
  144. // legacy behavior
  145. func ConvertAwsAthenaInfoToConfig(aai AwsAthenaInfo) config.KeyedConfig {
  146. if aai.IsEmpty() {
  147. return nil
  148. }
  149. var authorizer Authorizer
  150. if aai.ServiceKeyName == "" && aai.ServiceKeySecret == "" {
  151. authorizer = &ServiceAccount{}
  152. } else {
  153. authorizer = &AccessKey{
  154. ID: aai.ServiceKeyName,
  155. Secret: aai.ServiceKeySecret,
  156. }
  157. }
  158. // Wrap Authorizer with AssumeRole if MasterPayerArn is set
  159. if aai.MasterPayerARN != "" {
  160. authorizer = &AssumeRole{
  161. Authorizer: authorizer,
  162. RoleARN: aai.MasterPayerARN,
  163. }
  164. }
  165. var config config.KeyedConfig
  166. if aai.AthenaTable != "" || aai.AthenaDatabase != "" {
  167. config = &AthenaConfiguration{
  168. Bucket: aai.AthenaBucketName,
  169. Region: aai.AthenaRegion,
  170. Database: aai.AthenaDatabase,
  171. Table: aai.AthenaTable,
  172. Workgroup: aai.AthenaWorkgroup,
  173. Account: aai.AccountID,
  174. Authorizer: authorizer,
  175. }
  176. } else {
  177. config = &S3Configuration{
  178. Bucket: aai.AthenaBucketName,
  179. Region: aai.AthenaRegion,
  180. Account: aai.AccountID,
  181. Authorizer: authorizer,
  182. }
  183. }
  184. return config
  185. }