athenaconfiguration.go 5.4 KB

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