| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package azure
- import (
- "encoding/json"
- "fmt"
- "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
- "github.com/opencost/opencost/pkg/cloud"
- )
- const SharedKeyAuthorizerType = "AzureAccessKey"
- // StorageAuthorizer is a service specific Authorizer for Azure Storage, it exists so that we can support existing Shared
- // Key configurations while allowing the Authorizer to have a service agnostic api
- type StorageAuthorizer interface {
- cloud.Authorizer
- GetBlobClient(serviceURL string) (*azblob.Client, error)
- }
- // SelectStorageAuthorizerByType is an implementation of AuthorizerSelectorFn and acts as a register for Authorizer types
- func SelectStorageAuthorizerByType(typeStr string) (StorageAuthorizer, error) {
- switch typeStr {
- case SharedKeyAuthorizerType:
- return &SharedKeyCredential{}, nil
- default:
- authorizer, err := SelectAuthorizerByType(typeStr)
- if err != nil {
- return nil, err
- }
- return &AuthorizerHolder{authorizer}, nil
- }
- }
- // SharedKeyCredential is a StorageAuthorizer with credentials which cannot be used to authorize other services. This
- // is a legacy auth method which is not included in azidentity
- type SharedKeyCredential struct {
- AccessKey string `json:"accessKey"`
- Account string `json:"account"`
- }
- func (skc *SharedKeyCredential) MarshalJSON() ([]byte, error) {
- fmap := make(map[string]any, 3)
- fmap[cloud.AuthorizerTypeProperty] = SharedKeyAuthorizerType
- fmap["accessKey"] = skc.AccessKey
- fmap["account"] = skc.Account
- return json.Marshal(fmap)
- }
- func (skc *SharedKeyCredential) Validate() error {
- if skc.AccessKey == "" {
- return fmt.Errorf("SharedKeyCredential: missing access key")
- }
- if skc.Account == "" {
- return fmt.Errorf("SharedKeyCredential: missing account")
- }
- return nil
- }
- func (skc *SharedKeyCredential) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- thatConfig, ok := config.(*SharedKeyCredential)
- if !ok {
- return false
- }
- if skc.AccessKey != thatConfig.AccessKey {
- return false
- }
- if skc.Account != thatConfig.Account {
- return false
- }
- return true
- }
- func (skc *SharedKeyCredential) Sanitize() cloud.Config {
- return &SharedKeyCredential{
- AccessKey: cloud.Redacted,
- Account: skc.Account,
- }
- }
- func (skc *SharedKeyCredential) GetBlobClient(serviceURL string) (*azblob.Client, error) {
- credential, err := azblob.NewSharedKeyCredential(skc.Account, skc.AccessKey)
- if err != nil {
- return nil, err
- }
- client, err := azblob.NewClientWithSharedKeyCredential(serviceURL, credential, nil)
- return client, err
- }
- // AuthorizerHolder is a StorageAuthorizer implementation that wraps an Authorizer implementation
- type AuthorizerHolder struct {
- Authorizer
- }
- func (ah *AuthorizerHolder) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- that, ok := config.(*AuthorizerHolder)
- if !ok {
- return false
- }
- return ah.Authorizer.Equals(that.Authorizer)
- }
- func (ah *AuthorizerHolder) Sanitize() cloud.Config {
- return &AuthorizerHolder{Authorizer: ah.Authorizer.Sanitize().(Authorizer)}
- }
- func (ah *AuthorizerHolder) GetBlobClient(serviceURL string) (*azblob.Client, error) {
- // Create a default request pipeline using your storage account name and account key.
- cred, err := ah.GetCredential()
- if err != nil {
- return nil, fmt.Errorf("error retrieving credentials: %w", err)
- }
- client, err := azblob.NewClient(serviceURL, cred, nil)
- return client, err
- }
|