| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package azure
- import (
- "fmt"
- "github.com/Azure/azure-sdk-for-go/sdk/azcore"
- "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
- "github.com/opencost/opencost/core/pkg/util/json"
- "github.com/opencost/opencost/pkg/cloud"
- )
- const (
- DefaultCredentialAuthorizerType = "AzureDefaultCredential"
- ClientSecretCredentialType = "AzureClientSecretCredential"
- )
- // Authorizer configs provide credentials from azidentity to connect to Azure services.
- type Authorizer interface {
- cloud.Authorizer
- GetCredential() (azcore.TokenCredential, error)
- }
- // SelectAuthorizerByType is an implementation of AuthorizerSelectorFn and acts as a register for Authorizer types
- func SelectAuthorizerByType(typeStr string) (Authorizer, error) {
- switch typeStr {
- case DefaultCredentialAuthorizerType:
- return &DefaultAzureCredentialHolder{}, nil
- case ClientSecretCredentialType:
- return &ClientSecretCredential{}, nil
- default:
- return nil, fmt.Errorf("azure: provider authorizer type '%s' is not valid", typeStr)
- }
- }
- type DefaultAzureCredentialHolder struct{}
- func (dac *DefaultAzureCredentialHolder) MarshalJSON() ([]byte, error) {
- fmap := make(map[string]any, 1)
- fmap[cloud.AuthorizerTypeProperty] = DefaultCredentialAuthorizerType
- return json.Marshal(fmap)
- }
- func (dac *DefaultAzureCredentialHolder) Validate() error {
- return nil
- }
- func (dac *DefaultAzureCredentialHolder) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- _, ok := config.(*DefaultAzureCredentialHolder)
- if !ok {
- return false
- }
- return true
- }
- func (dac *DefaultAzureCredentialHolder) Sanitize() cloud.Config {
- return &DefaultAzureCredentialHolder{}
- }
- func (dac *DefaultAzureCredentialHolder) GetCredential() (azcore.TokenCredential, error) {
- return azidentity.NewDefaultAzureCredential(nil)
- }
- type ClientSecretCredential struct {
- TenantID string `json:"tenantID"`
- ClientID string `json:"clientID"`
- ClientSecret string `json:"clientSecret"`
- }
- func (csc *ClientSecretCredential) Validate() error {
- if csc.TenantID == "" {
- return fmt.Errorf("ClientSecretCredential: missing Tenant ID")
- }
- if csc.ClientID == "" {
- return fmt.Errorf("ClientSecretCredential: missing Client ID")
- }
- if csc.ClientSecret == "" {
- return fmt.Errorf("ClientSecretCredential: missing Client Secret")
- }
- return nil
- }
- func (csc *ClientSecretCredential) Sanitize() cloud.Config {
- return &ClientSecretCredential{
- TenantID: csc.TenantID,
- ClientID: csc.ClientID,
- ClientSecret: cloud.Redacted,
- }
- }
- func (csc *ClientSecretCredential) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- thatConfig, ok := config.(*ClientSecretCredential)
- if !ok {
- return false
- }
- if csc.TenantID != thatConfig.TenantID {
- return false
- }
- if csc.ClientID != thatConfig.ClientID {
- return false
- }
- if csc.ClientSecret != thatConfig.ClientSecret {
- return false
- }
- return true
- }
- func (csc *ClientSecretCredential) MarshalJSON() ([]byte, error) {
- fmap := make(map[string]any, 1)
- fmap[cloud.AuthorizerTypeProperty] = ClientSecretCredentialType
- fmap["tenantID"] = csc.TenantID
- fmap["clientID"] = csc.ClientID
- fmap["clientSecret"] = csc.ClientSecret
- return json.Marshal(fmap)
- }
- func (csc *ClientSecretCredential) GetCredential() (azcore.TokenCredential, error) {
- cred, err := azidentity.NewClientSecretCredential(csc.TenantID, csc.ClientID, csc.ClientSecret, nil)
- if err != nil {
- return nil, fmt.Errorf("ClientSecretCredential: failed to retrieve credentials: %w", err)
- }
- return cred, nil
- }
|