This is an automated email from the ASF dual-hosted git repository. pvillard pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push: new 3219c10 NIFI-9728: Added support for User Assigned Managed Identity authentication for Azure ADLS and Blob_v12 processors 3219c10 is described below commit 3219c105ebd6d3a648c84684b2cb78efe81da438 Author: Peter Turcsanyi <turcsa...@apache.org> AuthorDate: Sat Mar 5 13:49:46 2022 +0100 NIFI-9728: Added support for User Assigned Managed Identity authentication for Azure ADLS and Blob_v12 processors Also bumped Azure dependencies. Signed-off-by: Pierre Villard <pierre.villard...@gmail.com> This closes #5846. --- .../nifi-azure-processors/pom.xml | 6 +-- .../azure/AbstractAzureBlobProcessor_v12.java | 10 ++-- .../AbstractAzureDataLakeStorageProcessor.java | 2 + .../azure/storage/utils/AzureStorageUtils.java | 11 ++++ .../storage/ADLSCredentialsControllerService.java | 61 ++++++++++++++-------- ...ureStorageCredentialsControllerService_v12.java | 17 ++++-- .../TestADLSCredentialsControllerService.java | 47 ++++++++++++++++- ...ureStorageCredentialsControllerService_v12.java | 24 ++++----- .../azure/storage/ADLSCredentialsDetails.java | 15 +++++- .../AzureStorageCredentialsDetails_v12.java | 54 +++++++++++-------- nifi-nar-bundles/nifi-azure-bundle/pom.xml | 7 ++- 11 files changed, 178 insertions(+), 76 deletions(-) diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml index ceccc48..4a14fd2 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/pom.xml @@ -22,9 +22,9 @@ <properties> <azure-eventhubs.version>3.3.0</azure-eventhubs.version> <azure-eventhubs-eph.version>3.3.0</azure-eventhubs-eph.version> - <azure-keyvault.version>1.2.4</azure-keyvault.version> - <azure-storage-file-datalake.version>12.7.1</azure-storage-file-datalake.version> - <azure-storage-blob.version>12.14.1</azure-storage-blob.version> + <azure-keyvault.version>1.2.6</azure-keyvault.version> + <azure-storage-file-datalake.version>12.7.4</azure-storage-file-datalake.version> + <azure-storage-blob.version>12.14.4</azure-storage-blob.version> </properties> <dependencies> <dependency> diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureBlobProcessor_v12.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureBlobProcessor_v12.java index 0186452..91e4420 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureBlobProcessor_v12.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureBlobProcessor_v12.java @@ -130,13 +130,15 @@ public abstract class AbstractAzureBlobProcessor_v12 extends AbstractProcessor { clientBuilder.credential(new AzureSasCredential(credentialsDetails.getSasToken())); break; case MANAGED_IDENTITY: - clientBuilder.credential(new ManagedIdentityCredentialBuilder().build()); + clientBuilder.credential(new ManagedIdentityCredentialBuilder() + .clientId(credentialsDetails.getManagedIdentityClientId()) + .build()); break; case SERVICE_PRINCIPAL: clientBuilder.credential(new ClientSecretCredentialBuilder() - .tenantId(credentialsDetails.getTenantId()) - .clientId(credentialsDetails.getClientId()) - .clientSecret(credentialsDetails.getClientSecret()) + .tenantId(credentialsDetails.getServicePrincipalTenantId()) + .clientId(credentialsDetails.getServicePrincipalClientId()) + .clientSecret(credentialsDetails.getServicePrincipalClientSecret()) .build()); break; case ACCESS_TOKEN: diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureDataLakeStorageProcessor.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureDataLakeStorageProcessor.java index d371e12..39e2ad2 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureDataLakeStorageProcessor.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/AbstractAzureDataLakeStorageProcessor.java @@ -129,6 +129,7 @@ public abstract class AbstractAzureDataLakeStorageProcessor extends AbstractProc final AccessToken accessToken = credentialsDetails.getAccessToken(); final String endpointSuffix = credentialsDetails.getEndpointSuffix(); final boolean useManagedIdentity = credentialsDetails.getUseManagedIdentity(); + final String managedIdentityClientId = credentialsDetails.getManagedIdentityClientId(); final String servicePrincipalTenantId = credentialsDetails.getServicePrincipalTenantId(); final String servicePrincipalClientId = credentialsDetails.getServicePrincipalClientId(); final String servicePrincipalClientSecret = credentialsDetails.getServicePrincipalClientSecret(); @@ -151,6 +152,7 @@ public abstract class AbstractAzureDataLakeStorageProcessor extends AbstractProc .buildClient(); } else if (useManagedIdentity) { final ManagedIdentityCredential misCredential = new ManagedIdentityCredentialBuilder() + .clientId(managedIdentityClientId) .build(); storageClient = new DataLakeServiceClientBuilder() .endpoint(endpoint) diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/AzureStorageUtils.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/AzureStorageUtils.java index 1e898da..a73c108 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/AzureStorageUtils.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/processors/azure/storage/utils/AzureStorageUtils.java @@ -156,6 +156,17 @@ public final class AzureStorageUtils { .required(false) .build(); + public static final PropertyDescriptor MANAGED_IDENTITY_CLIENT_ID = new PropertyDescriptor.Builder() + .name("managed-identity-client-id") + .displayName("Managed Identity Client ID") + .description("Client ID of the managed identity. The property is required when User Assigned Managed Identity is used for authentication. " + + "It must be empty in case of System Assigned Managed Identity.") + .sensitive(true) + .required(false) + .addValidator(StandardValidators.NON_BLANK_VALIDATOR) + .expressionLanguageSupported(ExpressionLanguageScope.NONE) + .build(); + public static final PropertyDescriptor SERVICE_PRINCIPAL_TENANT_ID = new PropertyDescriptor.Builder() .name("service-principal-tenant-id") .displayName("Service Principal Tenant ID") diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java index 8699a79..b075322 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsControllerService.java @@ -68,13 +68,15 @@ public class ADLSCredentialsControllerService extends AbstractControllerService public static final PropertyDescriptor USE_MANAGED_IDENTITY = new PropertyDescriptor.Builder() .name("storage-use-managed-identity") .displayName("Use Azure Managed Identity") - .description("Choose whether or not to use the managed identity of Azure VM/VMSS ") + .description("Choose whether or not to use the managed identity of Azure VM/VMSS") .required(false) .defaultValue("false") .allowableValues("true", "false") .addValidator(StandardValidators.BOOLEAN_VALIDATOR) .build(); + public static final PropertyDescriptor MANAGED_IDENTITY_CLIENT_ID = AzureStorageUtils.MANAGED_IDENTITY_CLIENT_ID; + public static final PropertyDescriptor SERVICE_PRINCIPAL_TENANT_ID = AzureStorageUtils.SERVICE_PRINCIPAL_TENANT_ID; public static final PropertyDescriptor SERVICE_PRINCIPAL_CLIENT_ID = AzureStorageUtils.SERVICE_PRINCIPAL_CLIENT_ID; @@ -87,6 +89,7 @@ public class ADLSCredentialsControllerService extends AbstractControllerService AzureStorageUtils.ACCOUNT_KEY, AzureStorageUtils.PROP_SAS_TOKEN, USE_MANAGED_IDENTITY, + MANAGED_IDENTITY_CLIENT_ID, SERVICE_PRINCIPAL_TENANT_ID, SERVICE_PRINCIPAL_CLIENT_ID, SERVICE_PRINCIPAL_CLIENT_SECRET @@ -103,39 +106,50 @@ public class ADLSCredentialsControllerService extends AbstractControllerService protected Collection<ValidationResult> customValidate(ValidationContext validationContext) { final List<ValidationResult> results = new ArrayList<>(); - boolean accountKeySet = StringUtils.isNotBlank(validationContext.getProperty(AzureStorageUtils.ACCOUNT_KEY).getValue()); - boolean sasTokenSet = StringUtils.isNotBlank(validationContext.getProperty(AzureStorageUtils.PROP_SAS_TOKEN).getValue()); - boolean useManagedIdentitySet = validationContext.getProperty(USE_MANAGED_IDENTITY).asBoolean(); + final boolean accountKeySet = StringUtils.isNotBlank(validationContext.getProperty(AzureStorageUtils.ACCOUNT_KEY).getValue()); + final boolean sasTokenSet = StringUtils.isNotBlank(validationContext.getProperty(AzureStorageUtils.PROP_SAS_TOKEN).getValue()); + final boolean useManagedIdentitySet = validationContext.getProperty(USE_MANAGED_IDENTITY).asBoolean(); + + final boolean servicePrincipalTenantIdSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_TENANT_ID).getValue()); + final boolean servicePrincipalClientIdSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_CLIENT_ID).getValue()); + final boolean servicePrincipalClientSecretSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_CLIENT_SECRET).getValue()); - boolean servicePrincipalTenantIdSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_TENANT_ID).getValue()); - boolean servicePrincipalClientIdSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_CLIENT_ID).getValue()); - boolean servicePrincipalClientSecretSet = StringUtils.isNotBlank(validationContext.getProperty(SERVICE_PRINCIPAL_CLIENT_SECRET).getValue()); + final boolean servicePrincipalSet = servicePrincipalTenantIdSet || servicePrincipalClientIdSet || servicePrincipalClientSecretSet; - boolean servicePrincipalSet = servicePrincipalTenantIdSet || servicePrincipalClientIdSet || servicePrincipalClientSecretSet; + final String managedIdentityClientId = validationContext.getProperty(MANAGED_IDENTITY_CLIENT_ID).getValue(); if (!onlyOneSet(accountKeySet, sasTokenSet, useManagedIdentitySet, servicePrincipalSet)) { results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) .valid(false) .explanation("one and only one authentication method of [Account Key, SAS Token, Managed Identity, Service Principal] should be used") .build()); - } else if (servicePrincipalSet) { - String template = "'%s' must be set when Service Principal authentication is being configured"; - if (!servicePrincipalTenantIdSet) { - results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) - .valid(false) - .explanation(String.format(template, SERVICE_PRINCIPAL_TENANT_ID.getDisplayName())) - .build()); - } - if (!servicePrincipalClientIdSet) { - results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) - .valid(false) - .explanation(String.format(template, SERVICE_PRINCIPAL_CLIENT_ID.getDisplayName())) - .build()); + } else { + if (servicePrincipalSet) { + final String template = "'%s' must be set when Service Principal authentication is being configured"; + if (!servicePrincipalTenantIdSet) { + results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) + .valid(false) + .explanation(String.format(template, SERVICE_PRINCIPAL_TENANT_ID.getDisplayName())) + .build()); + } + if (!servicePrincipalClientIdSet) { + results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) + .valid(false) + .explanation(String.format(template, SERVICE_PRINCIPAL_CLIENT_ID.getDisplayName())) + .build()); + } + if (!servicePrincipalClientSecretSet) { + results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) + .valid(false) + .explanation(String.format(template, SERVICE_PRINCIPAL_CLIENT_SECRET.getDisplayName())) + .build()); + } } - if (!servicePrincipalClientSecretSet) { + + if (!useManagedIdentitySet && StringUtils.isNotEmpty(managedIdentityClientId)) { results.add(new ValidationResult.Builder().subject(this.getClass().getSimpleName()) .valid(false) - .explanation(String.format(template, SERVICE_PRINCIPAL_CLIENT_SECRET.getDisplayName())) + .explanation(String.format("'%s' can only be configured when '%s' is set to true", MANAGED_IDENTITY_CLIENT_ID.getDisplayName(), USE_MANAGED_IDENTITY.getDisplayName())) .build()); } } @@ -165,6 +179,7 @@ public class ADLSCredentialsControllerService extends AbstractControllerService setValue(credentialsBuilder, AzureStorageUtils.PROP_SAS_TOKEN, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setSasToken, attributes); setValue(credentialsBuilder, ENDPOINT_SUFFIX, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setEndpointSuffix, attributes); setValue(credentialsBuilder, USE_MANAGED_IDENTITY, PropertyValue::asBoolean, ADLSCredentialsDetails.Builder::setUseManagedIdentity, attributes); + setValue(credentialsBuilder, MANAGED_IDENTITY_CLIENT_ID, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setManagedIdentityClientId, attributes); setValue(credentialsBuilder, SERVICE_PRINCIPAL_TENANT_ID, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setServicePrincipalTenantId, attributes); setValue(credentialsBuilder, SERVICE_PRINCIPAL_CLIENT_ID, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setServicePrincipalClientId, attributes); setValue(credentialsBuilder, SERVICE_PRINCIPAL_CLIENT_SECRET, PropertyValue::getValue, ADLSCredentialsDetails.Builder::setServicePrincipalClientSecret, attributes); diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java index b46ab3e..ba8101d 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsControllerService_v12.java @@ -85,6 +85,11 @@ public class AzureStorageCredentialsControllerService_v12 extends AbstractContro .dependsOn(CREDENTIALS_TYPE, AzureStorageCredentialsType.SAS_TOKEN.getAllowableValue()) .build(); + public static final PropertyDescriptor MANAGED_IDENTITY_CLIENT_ID = new PropertyDescriptor.Builder() + .fromPropertyDescriptor(AzureStorageUtils.MANAGED_IDENTITY_CLIENT_ID) + .dependsOn(CREDENTIALS_TYPE, AzureStorageCredentialsType.MANAGED_IDENTITY.getAllowableValue()) + .build(); + public static final PropertyDescriptor SERVICE_PRINCIPAL_TENANT_ID = new PropertyDescriptor.Builder() .fromPropertyDescriptor(AzureStorageUtils.SERVICE_PRINCIPAL_TENANT_ID) .required(true) @@ -109,6 +114,7 @@ public class AzureStorageCredentialsControllerService_v12 extends AbstractContro CREDENTIALS_TYPE, ACCOUNT_KEY, SAS_TOKEN, + MANAGED_IDENTITY_CLIENT_ID, SERVICE_PRINCIPAL_TENANT_ID, SERVICE_PRINCIPAL_CLIENT_ID, SERVICE_PRINCIPAL_CLIENT_SECRET @@ -140,12 +146,13 @@ public class AzureStorageCredentialsControllerService_v12 extends AbstractContro String sasToken = context.getProperty(SAS_TOKEN).getValue(); return AzureStorageCredentialsDetails_v12.createWithSasToken(accountName, endpointSuffix, sasToken); case MANAGED_IDENTITY: - return AzureStorageCredentialsDetails_v12.createWithManagedIdentity(accountName, endpointSuffix); + String managedIdentityClientId = context.getProperty(MANAGED_IDENTITY_CLIENT_ID).getValue(); + return AzureStorageCredentialsDetails_v12.createWithManagedIdentity(accountName, endpointSuffix, managedIdentityClientId); case SERVICE_PRINCIPAL: - String tenantId = context.getProperty(SERVICE_PRINCIPAL_TENANT_ID).getValue(); - String clientId = context.getProperty(SERVICE_PRINCIPAL_CLIENT_ID).getValue(); - String clientSecret = context.getProperty(SERVICE_PRINCIPAL_CLIENT_SECRET).getValue(); - return AzureStorageCredentialsDetails_v12.createWithServicePrincipal(accountName, endpointSuffix, tenantId, clientId, clientSecret); + String servicePrincipalTenantId = context.getProperty(SERVICE_PRINCIPAL_TENANT_ID).getValue(); + String servicePrincipalClientId = context.getProperty(SERVICE_PRINCIPAL_CLIENT_ID).getValue(); + String servicePrincipalClientSecret = context.getProperty(SERVICE_PRINCIPAL_CLIENT_SECRET).getValue(); + return AzureStorageCredentialsDetails_v12.createWithServicePrincipal(accountName, endpointSuffix, servicePrincipalTenantId, servicePrincipalClientId, servicePrincipalClientSecret); default: throw new IllegalArgumentException("Unhandled credentials type: " + credentialsType); } diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerService.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerService.java index 69e2b2d..a113aa4 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerService.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestADLSCredentialsControllerService.java @@ -41,6 +41,7 @@ public class TestADLSCredentialsControllerService { private static final String ACCOUNT_KEY_VALUE = "AccountKey"; private static final String SAS_TOKEN_VALUE = "SasToken"; private static final String END_POINT_SUFFIX_VALUE = "end.point.suffix"; + private static final String MANAGED_IDENTITY_CLIENT_ID_VALUE = "ManagedIdentityClientID"; private static final String SERVICE_PRINCIPAL_TENANT_ID_VALUE = "ServicePrincipalTenantID"; private static final String SERVICE_PRINCIPAL_CLIENT_ID_VALUE = "ServicePrincipalClientID"; private static final String SERVICE_PRINCIPAL_CLIENT_SECRET_VALUE = "ServicePrincipalClientSecret"; @@ -255,6 +256,16 @@ public class TestADLSCredentialsControllerService { } @Test + public void testNotValidBecauseManagedIdentityClientIdSpecifiedButUseManagedIdentityIsFalse() { + configureAccountName(); + configureAccountKey(); + + configureManagedIdentityClientId(); + + runner.assertNotValid(credentialsService); + } + + @Test public void testNotValidBecauseNoTenantIdSpecifiedForServicePrincipal() { configureAccountName(); @@ -300,6 +311,7 @@ public class TestADLSCredentialsControllerService { assertEquals(ACCOUNT_KEY_VALUE, actual.getAccountKey()); assertNull(actual.getSasToken()); assertFalse(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); assertNotNull(actual.getEndpointSuffix()); assertNull(actual.getServicePrincipalTenantId()); assertNull(actual.getServicePrincipalClientId()); @@ -322,6 +334,7 @@ public class TestADLSCredentialsControllerService { assertEquals(ACCOUNT_KEY_VALUE, actual.getAccountKey()); assertNull(actual.getSasToken()); assertFalse(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); assertNotNull(actual.getEndpointSuffix()); assertNull(actual.getServicePrincipalTenantId()); assertNull(actual.getServicePrincipalClientId()); @@ -344,6 +357,7 @@ public class TestADLSCredentialsControllerService { assertEquals(SAS_TOKEN_VALUE, actual.getSasToken()); assertNull(actual.getAccountKey()); assertFalse(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); assertNotNull(actual.getEndpointSuffix()); assertNull(actual.getServicePrincipalTenantId()); assertNull(actual.getServicePrincipalClientId()); @@ -362,6 +376,7 @@ public class TestADLSCredentialsControllerService { assertEquals(SAS_TOKEN_VALUE, actual.getSasToken()); assertNull(actual.getAccountKey()); assertFalse(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); assertNotNull(actual.getEndpointSuffix()); assertNull(actual.getServicePrincipalTenantId()); assertNull(actual.getServicePrincipalClientId()); @@ -369,7 +384,7 @@ public class TestADLSCredentialsControllerService { } @Test - public void testGetCredentialsDetailsWithUseManagedIdentity() throws Exception { + public void testGetCredentialsDetailsWithSystemAssignedManagedIdentity() throws Exception { // GIVEN configureAccountName(); configureUseManagedIdentity(); @@ -382,6 +397,31 @@ public class TestADLSCredentialsControllerService { // THEN assertEquals(ACCOUNT_NAME_VALUE, actual.getAccountName()); assertTrue(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); + assertNull(actual.getAccountKey()); + assertNull(actual.getSasToken()); + assertNotNull(actual.getEndpointSuffix()); + assertNull(actual.getServicePrincipalTenantId()); + assertNull(actual.getServicePrincipalClientId()); + assertNull(actual.getServicePrincipalClientSecret()); + } + + @Test + public void testGetCredentialsDetailsWithUserAssignedManagedIdentity() throws Exception { + // GIVEN + configureAccountName(); + configureUseManagedIdentity(); + configureManagedIdentityClientId(); + + runner.enableControllerService(credentialsService); + + // WHEN + ADLSCredentialsDetails actual = credentialsService.getCredentialsDetails(new HashMap<>()); + + // THEN + assertEquals(ACCOUNT_NAME_VALUE, actual.getAccountName()); + assertTrue(actual.getUseManagedIdentity()); + assertEquals(MANAGED_IDENTITY_CLIENT_ID_VALUE, actual.getManagedIdentityClientId()); assertNull(actual.getAccountKey()); assertNull(actual.getSasToken()); assertNotNull(actual.getEndpointSuffix()); @@ -408,6 +448,7 @@ public class TestADLSCredentialsControllerService { assertNull(actual.getAccountKey()); assertNull(actual.getSasToken()); assertFalse(actual.getUseManagedIdentity()); + assertNull(actual.getManagedIdentityClientId()); assertNotNull(actual.getEndpointSuffix()); assertEquals(SERVICE_PRINCIPAL_TENANT_ID_VALUE, actual.getServicePrincipalTenantId()); assertEquals(SERVICE_PRINCIPAL_CLIENT_ID_VALUE, actual.getServicePrincipalClientId()); @@ -475,6 +516,10 @@ public class TestADLSCredentialsControllerService { runner.setProperty(credentialsService, ADLSCredentialsControllerService.USE_MANAGED_IDENTITY, "true"); } + private void configureManagedIdentityClientId() { + runner.setProperty(credentialsService, ADLSCredentialsControllerService.MANAGED_IDENTITY_CLIENT_ID, MANAGED_IDENTITY_CLIENT_ID_VALUE); + } + private void configureEndpointSuffix() { runner.setProperty(credentialsService, ADLSCredentialsControllerService.ENDPOINT_SUFFIX, END_POINT_SUFFIX_VALUE); } diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestAzureStorageCredentialsControllerService_v12.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestAzureStorageCredentialsControllerService_v12.java index 3f0a94d..6bda55e 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestAzureStorageCredentialsControllerService_v12.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-processors/src/test/java/org/apache/nifi/services/azure/storage/TestAzureStorageCredentialsControllerService_v12.java @@ -165,9 +165,9 @@ public class TestAzureStorageCredentialsControllerService_v12 { assertEquals(ACCOUNT_KEY, actual.getCredentialsType()); assertEquals(ACCOUNT_KEY_VALUE, actual.getAccountKey()); assertNull(actual.getSasToken()); - assertNull(actual.getTenantId()); - assertNull(actual.getClientId()); - assertNull(actual.getClientSecret()); + assertNull(actual.getServicePrincipalTenantId()); + assertNull(actual.getServicePrincipalClientId()); + assertNull(actual.getServicePrincipalClientSecret()); } @Test @@ -185,9 +185,9 @@ public class TestAzureStorageCredentialsControllerService_v12 { assertEquals(SAS_TOKEN, actual.getCredentialsType()); assertNull(actual.getAccountKey()); assertEquals(SAS_TOKEN_VALUE, actual.getSasToken()); - assertNull(actual.getTenantId()); - assertNull(actual.getClientId()); - assertNull(actual.getClientSecret()); + assertNull(actual.getServicePrincipalTenantId()); + assertNull(actual.getServicePrincipalClientId()); + assertNull(actual.getServicePrincipalClientSecret()); } @Test @@ -204,9 +204,9 @@ public class TestAzureStorageCredentialsControllerService_v12 { assertEquals(MANAGED_IDENTITY, actual.getCredentialsType()); assertNull(actual.getAccountKey()); assertNull(actual.getSasToken()); - assertNull(actual.getTenantId()); - assertNull(actual.getClientId()); - assertNull(actual.getClientSecret()); + assertNull(actual.getServicePrincipalTenantId()); + assertNull(actual.getServicePrincipalClientId()); + assertNull(actual.getServicePrincipalClientSecret()); } @Test @@ -226,9 +226,9 @@ public class TestAzureStorageCredentialsControllerService_v12 { assertEquals(SERVICE_PRINCIPAL, actual.getCredentialsType()); assertNull(actual.getAccountKey()); assertNull(actual.getSasToken()); - assertEquals(SERVICE_PRINCIPAL_TENANT_ID_VALUE, actual.getTenantId()); - assertEquals(SERVICE_PRINCIPAL_CLIENT_ID_VALUE, actual.getClientId()); - assertEquals(SERVICE_PRINCIPAL_CLIENT_SECRET_VALUE, actual.getClientSecret()); + assertEquals(SERVICE_PRINCIPAL_TENANT_ID_VALUE, actual.getServicePrincipalTenantId()); + assertEquals(SERVICE_PRINCIPAL_CLIENT_ID_VALUE, actual.getServicePrincipalClientId()); + assertEquals(SERVICE_PRINCIPAL_CLIENT_SECRET_VALUE, actual.getServicePrincipalClientSecret()); } @Test diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java index 03143ed..eb3b123 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/ADLSCredentialsDetails.java @@ -28,6 +28,7 @@ public class ADLSCredentialsDetails { private final AccessToken accessToken; private final boolean useManagedIdentity; + private final String managedIdentityClientId; private final String servicePrincipalTenantId; private final String servicePrincipalClientId; @@ -40,6 +41,7 @@ public class ADLSCredentialsDetails { String endpointSuffix, AccessToken accessToken, boolean useManagedIdentity, + String managedIdentityClientId, String servicePrincipalTenantId, String servicePrincipalClientId, String servicePrincipalClientSecret @@ -50,6 +52,7 @@ public class ADLSCredentialsDetails { this.endpointSuffix = endpointSuffix; this.accessToken = accessToken; this.useManagedIdentity = useManagedIdentity; + this.managedIdentityClientId = managedIdentityClientId; this.servicePrincipalTenantId = servicePrincipalTenantId; this.servicePrincipalClientId = servicePrincipalClientId; this.servicePrincipalClientSecret = servicePrincipalClientSecret; @@ -79,6 +82,10 @@ public class ADLSCredentialsDetails { return useManagedIdentity; } + public String getManagedIdentityClientId() { + return managedIdentityClientId; + } + public String getServicePrincipalTenantId() { return servicePrincipalTenantId; } @@ -98,6 +105,7 @@ public class ADLSCredentialsDetails { private String endpointSuffix; private AccessToken accessToken; private boolean useManagedIdentity; + private String managedIdentityClientId; private String servicePrincipalTenantId; private String servicePrincipalClientId; private String servicePrincipalClientSecret; @@ -138,6 +146,11 @@ public class ADLSCredentialsDetails { return this; } + public Builder setManagedIdentityClientId(String useManagedIdentityClientId) { + this.managedIdentityClientId = useManagedIdentityClientId; + return this; + } + public Builder setServicePrincipalTenantId(String servicePrincipalTenantId) { this.servicePrincipalTenantId = servicePrincipalTenantId; return this; @@ -154,7 +167,7 @@ public class ADLSCredentialsDetails { } public ADLSCredentialsDetails build() { - return new ADLSCredentialsDetails(accountName, accountKey, sasToken, endpointSuffix, accessToken, useManagedIdentity, + return new ADLSCredentialsDetails(accountName, accountKey, sasToken, endpointSuffix, accessToken, useManagedIdentity, managedIdentityClientId, servicePrincipalTenantId, servicePrincipalClientId, servicePrincipalClientSecret); } } diff --git a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java index 7851bec..6ab1545 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java +++ b/nifi-nar-bundles/nifi-azure-bundle/nifi-azure-services-api/src/main/java/org/apache/nifi/services/azure/storage/AzureStorageCredentialsDetails_v12.java @@ -25,22 +25,24 @@ public class AzureStorageCredentialsDetails_v12 { private final AzureStorageCredentialsType credentialsType; private final String accountKey; private final String sasToken; - private final String tenantId; - private final String clientId; - private final String clientSecret; + private final String managedIdentityClientId; + private final String servicePrincipalTenantId; + private final String servicePrincipalClientId; + private final String servicePrincipalClientSecret; private final AccessToken accessToken; private AzureStorageCredentialsDetails_v12( - String accountName, String endpointSuffix, AzureStorageCredentialsType credentialsType, String accountKey, - String sasToken, String tenantId, String clientId, String clientSecret, AccessToken accessToken) { + String accountName, String endpointSuffix, AzureStorageCredentialsType credentialsType, String accountKey, String sasToken, String managedIdentityClientId, + String servicePrincipalTenantId, String servicePrincipalClientId, String servicePrincipalClientSecret, AccessToken accessToken) { this.accountName = accountName; this.endpointSuffix = endpointSuffix; this.credentialsType = credentialsType; this.accountKey = accountKey; this.sasToken = sasToken; - this.tenantId = tenantId; - this.clientId = clientId; - this.clientSecret = clientSecret; + this.managedIdentityClientId = managedIdentityClientId; + this.servicePrincipalTenantId = servicePrincipalTenantId; + this.servicePrincipalClientId = servicePrincipalClientId; + this.servicePrincipalClientSecret = servicePrincipalClientSecret; this.accessToken = accessToken; } @@ -64,16 +66,20 @@ public class AzureStorageCredentialsDetails_v12 { return sasToken; } - public String getTenantId() { - return tenantId; + public String getManagedIdentityClientId() { + return managedIdentityClientId; } - public String getClientId() { - return clientId; + public String getServicePrincipalTenantId() { + return servicePrincipalTenantId; } - public String getClientSecret() { - return clientSecret; + public String getServicePrincipalClientId() { + return servicePrincipalClientId; + } + + public String getServicePrincipalClientSecret() { + return servicePrincipalClientSecret; } public AccessToken getAccessToken() { @@ -84,35 +90,37 @@ public class AzureStorageCredentialsDetails_v12 { String accountName, String endpointSuffix, String accountKey) { - return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.ACCOUNT_KEY, accountKey, null, null, null, null, null); + return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.ACCOUNT_KEY, accountKey, null, null, null, null, null, null); } public static AzureStorageCredentialsDetails_v12 createWithSasToken( String accountName, String endpointSuffix, String sasToken) { - return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.SAS_TOKEN, null, sasToken, null, null, null, null); + return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.SAS_TOKEN, null, sasToken, null, null, null, null, null); } public static AzureStorageCredentialsDetails_v12 createWithManagedIdentity( String accountName, - String endpointSuffix) { - return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.MANAGED_IDENTITY, null, null, null, null, null, null); + String endpointSuffix, + String managedIdentityClientId) { + return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.MANAGED_IDENTITY, null, null, managedIdentityClientId, null, null, null, null); } public static AzureStorageCredentialsDetails_v12 createWithServicePrincipal( String accountName, String endpointSuffix, - String tenantId, - String clientId, - String clientSecret) { - return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.SERVICE_PRINCIPAL, null, null, tenantId, clientId, clientSecret, null); + String servicePrincipalTenantId, + String servicePrincipalClientId, + String servicePrincipalClientSecret) { + return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.SERVICE_PRINCIPAL, null, null, null, + servicePrincipalTenantId, servicePrincipalClientId, servicePrincipalClientSecret, null); } public static AzureStorageCredentialsDetails_v12 createWithAccessToken( String accountName, String endpointSuffix, AccessToken accessToken) { - return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.ACCESS_TOKEN, null, null, null, null, null, accessToken); + return new AzureStorageCredentialsDetails_v12(accountName, endpointSuffix, AzureStorageCredentialsType.ACCESS_TOKEN, null, null, null, null, null, null, accessToken); } } diff --git a/nifi-nar-bundles/nifi-azure-bundle/pom.xml b/nifi-nar-bundles/nifi-azure-bundle/pom.xml index 469445c..e18c5a1 100644 --- a/nifi-nar-bundles/nifi-azure-bundle/pom.xml +++ b/nifi-nar-bundles/nifi-azure-bundle/pom.xml @@ -27,12 +27,11 @@ <properties> <azure-storage.version>8.6.6</azure-storage.version> - <azure.core.version>1.21.0</azure.core.version> - <!-- upgrade azure-identity to 1.4.x only after https://github.com/Azure/azure-sdk-for-java/issues/25084 has been fixed --> - <azure.identity.version>1.3.7</azure.identity.version> + <azure.core.version>1.26.0</azure.core.version> + <azure.identity.version>1.4.5</azure.identity.version> <!-- azure-identity depends on msal4j transitively, keep these versions consistent --> <msal4j.version>1.11.0</msal4j.version> - <azure-cosmos.version>4.20.0</azure-cosmos.version> + <azure-cosmos.version>4.26.0</azure-cosmos.version> </properties> <modules>