diff --git a/config/config.go b/config/config.go index 65e20946f5..d37fc8127b 100644 --- a/config/config.go +++ b/config/config.go @@ -90,6 +90,7 @@ type AzureConfig struct { } type AzureClientOpt struct { + ClientCredentialsType string `config:"type"` ClientID string `config:"client_id"` TenantID string `config:"tenant_id"` ClientSecret string `config:"client_secret"` @@ -99,6 +100,13 @@ type AzureClientOpt struct { ClientCertificatePassword string `config:"client_certificate_password"` } +const ( + AzureClientCredentialsTypeManagedIdentity = "managed_identity" + AzureClientCredentialsTypeSecret = "service_principal_with_client_secret" + AzureClientCredentialsTypeCertificate = "service_principal_with_client_certificate" + AzureClientCredentialsTypeUsernamePassword = "service_principal_with_client_username_and_password" +) + const ( SingleAccount = "single-account" OrganizationAccount = "organization-account" diff --git a/resources/providers/azurelib/auth/credentials.go b/resources/providers/azurelib/auth/credentials.go index b2219d04d9..f829f13d78 100644 --- a/resources/providers/azurelib/auth/credentials.go +++ b/resources/providers/azurelib/auth/credentials.go @@ -39,19 +39,21 @@ type ConfigProvider struct { } func (p *ConfigProvider) GetAzureClientConfig(cfg config.AzureConfig) (*AzureFactoryConfig, error) { - switch { - case cfg.Credentials.ClientSecret != "": + switch cfg.Credentials.ClientCredentialsType { + case config.AzureClientCredentialsTypeSecret: return p.getSecretCredentialsConfig(cfg) - case cfg.Credentials.ClientCertificatePath != "": + case config.AzureClientCredentialsTypeCertificate: return p.getCertificateCredentialsConfig(cfg) - case cfg.Credentials.ClientUsername != "" || cfg.Credentials.ClientPassword != "": + case config.AzureClientCredentialsTypeUsernamePassword: if cfg.Credentials.ClientUsername == "" || cfg.Credentials.ClientPassword == "" { return nil, ErrIncompleteUsernamePassword } return p.getUsernamePasswordCredentialsConfig(cfg) + case "", config.AzureClientCredentialsTypeManagedIdentity: + return p.getDefaultCredentialsConfig() } - return p.getDefaultCredentialsConfig() + return nil, ErrWrongCredentialsType } func (p *ConfigProvider) getDefaultCredentialsConfig() (*AzureFactoryConfig, error) { @@ -115,4 +117,7 @@ func (p *ConfigProvider) getUsernamePasswordCredentialsConfig(cfg config.AzureCo }, nil } -var ErrIncompleteUsernamePassword = errors.New("incomplete username and password credentials") +var ( + ErrWrongCredentialsType = errors.New("wrong credentials type") + ErrIncompleteUsernamePassword = errors.New("incomplete username and password credentials") +) diff --git a/resources/providers/azurelib/auth/credentials_test.go b/resources/providers/azurelib/auth/credentials_test.go index b7d92c77ee..c5c4695ae0 100644 --- a/resources/providers/azurelib/auth/credentials_test.go +++ b/resources/providers/azurelib/auth/credentials_test.go @@ -44,13 +44,25 @@ func TestConfigProvider_GetAzureClientConfig(t *testing.T) { Credentials: &azidentity.DefaultAzureCredential{}, }, }, + { + name: "Should return a error on unknown client credentials type", + config: config.AzureConfig{ + Credentials: config.AzureClientOpt{ + ClientCredentialsType: "unknown", + }, + }, + authProviderInitFn: func(m *MockAzureAuthProviderAPI) {}, + want: nil, + wantErr: true, + }, { name: "Should return a ClientSecretCredential", config: config.AzureConfig{ Credentials: config.AzureClientOpt{ - TenantID: "tenant_a", - ClientID: "client_id", - ClientSecret: "secret", + ClientCredentialsType: config.AzureClientCredentialsTypeSecret, + TenantID: "tenant_a", + ClientID: "client_id", + ClientSecret: "secret", }, }, authProviderInitFn: func(m *MockAzureAuthProviderAPI) { @@ -68,10 +80,11 @@ func TestConfigProvider_GetAzureClientConfig(t *testing.T) { name: "Should return a UsernamePasswordCredential", config: config.AzureConfig{ Credentials: config.AzureClientOpt{ - TenantID: "tenant_a", - ClientID: "client_id", - ClientUsername: "username", - ClientPassword: "password", + ClientCredentialsType: config.AzureClientCredentialsTypeUsernamePassword, + TenantID: "tenant_a", + ClientID: "client_id", + ClientUsername: "username", + ClientPassword: "password", }, }, authProviderInitFn: func(m *MockAzureAuthProviderAPI) { @@ -89,10 +102,11 @@ func TestConfigProvider_GetAzureClientConfig(t *testing.T) { name: "Should return error on incomplete Username Password Credential (missing password)", config: config.AzureConfig{ Credentials: config.AzureClientOpt{ - TenantID: "tenant_a", - ClientID: "client_id", - ClientUsername: "username", - ClientPassword: "", + ClientCredentialsType: config.AzureClientCredentialsTypeUsernamePassword, + TenantID: "tenant_a", + ClientID: "client_id", + ClientUsername: "username", + ClientPassword: "", }, }, authProviderInitFn: func(m *MockAzureAuthProviderAPI) {}, @@ -103,10 +117,11 @@ func TestConfigProvider_GetAzureClientConfig(t *testing.T) { name: "Should return error on incomplete Username Password Credential (missing username)", config: config.AzureConfig{ Credentials: config.AzureClientOpt{ - TenantID: "tenant_a", - ClientID: "client_id", - ClientUsername: "", - ClientPassword: "password", + ClientCredentialsType: config.AzureClientCredentialsTypeUsernamePassword, + TenantID: "tenant_a", + ClientID: "client_id", + ClientUsername: "", + ClientPassword: "password", }, }, authProviderInitFn: func(m *MockAzureAuthProviderAPI) {}, @@ -117,6 +132,7 @@ func TestConfigProvider_GetAzureClientConfig(t *testing.T) { name: "Should return a ClientCertificateCredential", config: config.AzureConfig{ Credentials: config.AzureClientOpt{ + ClientCredentialsType: config.AzureClientCredentialsTypeCertificate, TenantID: "tenant_a", ClientID: "client_id", ClientCertificatePath: "/path/cert",