storageauthorizer.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package azure
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
  6. "github.com/opencost/opencost/pkg/cloud"
  7. )
  8. const SharedKeyAuthorizerType = "AzureAccessKey"
  9. // StorageAuthorizer is a service specific Authorizer for Azure Storage, it exists so that we can support existing Shared
  10. // Key configurations while allowing the Authorizer to have a service agnostic api
  11. type StorageAuthorizer interface {
  12. cloud.Authorizer
  13. GetBlobClient(serviceURL string) (*azblob.Client, error)
  14. }
  15. // SelectStorageAuthorizerByType is an implementation of AuthorizerSelectorFn and acts as a register for Authorizer types
  16. func SelectStorageAuthorizerByType(typeStr string) (StorageAuthorizer, error) {
  17. switch typeStr {
  18. case SharedKeyAuthorizerType:
  19. return &SharedKeyCredential{}, nil
  20. default:
  21. authorizer, err := SelectAuthorizerByType(typeStr)
  22. if err != nil {
  23. return nil, err
  24. }
  25. return &AuthorizerHolder{authorizer}, nil
  26. }
  27. }
  28. // SharedKeyCredential is a StorageAuthorizer with credentials which cannot be used to authorize other services. This
  29. // is a legacy auth method which is not included in azidentity
  30. type SharedKeyCredential struct {
  31. AccessKey string `json:"accessKey"`
  32. Account string `json:"account"`
  33. }
  34. func (skc *SharedKeyCredential) MarshalJSON() ([]byte, error) {
  35. fmap := make(map[string]any, 3)
  36. fmap[cloud.AuthorizerTypeProperty] = SharedKeyAuthorizerType
  37. fmap["accessKey"] = skc.AccessKey
  38. fmap["account"] = skc.Account
  39. return json.Marshal(fmap)
  40. }
  41. func (skc *SharedKeyCredential) Validate() error {
  42. if skc.AccessKey == "" {
  43. return fmt.Errorf("SharedKeyCredential: missing access key")
  44. }
  45. if skc.Account == "" {
  46. return fmt.Errorf("SharedKeyCredential: missing account")
  47. }
  48. return nil
  49. }
  50. func (skc *SharedKeyCredential) Equals(config cloud.Config) bool {
  51. if config == nil {
  52. return false
  53. }
  54. thatConfig, ok := config.(*SharedKeyCredential)
  55. if !ok {
  56. return false
  57. }
  58. if skc.AccessKey != thatConfig.AccessKey {
  59. return false
  60. }
  61. if skc.Account != thatConfig.Account {
  62. return false
  63. }
  64. return true
  65. }
  66. func (skc *SharedKeyCredential) Sanitize() cloud.Config {
  67. return &SharedKeyCredential{
  68. AccessKey: cloud.Redacted,
  69. Account: skc.Account,
  70. }
  71. }
  72. func (skc *SharedKeyCredential) GetBlobClient(serviceURL string) (*azblob.Client, error) {
  73. credential, err := azblob.NewSharedKeyCredential(skc.Account, skc.AccessKey)
  74. if err != nil {
  75. return nil, err
  76. }
  77. client, err := azblob.NewClientWithSharedKeyCredential(serviceURL, credential, nil)
  78. return client, err
  79. }
  80. // AuthorizerHolder is a StorageAuthorizer implementation that wraps an Authorizer implementation
  81. type AuthorizerHolder struct {
  82. Authorizer
  83. }
  84. func (ah *AuthorizerHolder) Equals(config cloud.Config) bool {
  85. if config == nil {
  86. return false
  87. }
  88. that, ok := config.(*AuthorizerHolder)
  89. if !ok {
  90. return false
  91. }
  92. return ah.Authorizer.Equals(that.Authorizer)
  93. }
  94. func (ah *AuthorizerHolder) Sanitize() cloud.Config {
  95. return &AuthorizerHolder{Authorizer: ah.Authorizer.Sanitize().(Authorizer)}
  96. }
  97. func (ah *AuthorizerHolder) GetBlobClient(serviceURL string) (*azblob.Client, error) {
  98. // Create a default request pipeline using your storage account name and account key.
  99. cred, err := ah.GetCredential()
  100. if err != nil {
  101. return nil, fmt.Errorf("error retrieving credentials: %w", err)
  102. }
  103. client, err := azblob.NewClient(serviceURL, cred, nil)
  104. return client, err
  105. }