Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-39344: [C++][FS][Azure] Support azure cli auth #41976

Merged
merged 3 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cpp/src/arrow/filesystem/azurefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ Status AzureOptions::ExtractFromUriQuery(const Uri& uri) {
credential_kind = CredentialKind::kDefault;
} else if (kv.second == "anonymous") {
credential_kind = CredentialKind::kAnonymous;
} else if (kv.second == "cli") {
credential_kind = CredentialKind::kCLI;
} else if (kv.second == "workload_identity") {
credential_kind = CredentialKind::kWorkloadIdentity;
} else if (kv.second == "environment") {
Expand Down Expand Up @@ -170,6 +172,9 @@ Status AzureOptions::ExtractFromUriQuery(const Uri& uri) {
case CredentialKind::kAnonymous:
RETURN_NOT_OK(ConfigureAnonymousCredential());
break;
case CredentialKind::kCLI:
RETURN_NOT_OK(ConfigureCLICredential());
break;
case CredentialKind::kWorkloadIdentity:
RETURN_NOT_OK(ConfigureWorkloadIdentityCredential());
break;
Expand Down Expand Up @@ -255,6 +260,7 @@ bool AzureOptions::Equals(const AzureOptions& other) const {
return storage_shared_key_credential_->AccountName ==
other.storage_shared_key_credential_->AccountName;
case CredentialKind::kClientSecret:
case CredentialKind::kCLI:
case CredentialKind::kManagedIdentity:
case CredentialKind::kWorkloadIdentity:
case CredentialKind::kEnvironment:
Expand Down Expand Up @@ -337,6 +343,12 @@ Status AzureOptions::ConfigureManagedIdentityCredential(const std::string& clien
return Status::OK();
}

Status AzureOptions::ConfigureCLICredential() {
credential_kind_ = CredentialKind::kCLI;
token_credential_ = std::make_shared<Azure::Identity::AzureCliCredential>();
return Status::OK();
}

Status AzureOptions::ConfigureWorkloadIdentityCredential() {
credential_kind_ = CredentialKind::kWorkloadIdentity;
token_credential_ = std::make_shared<Azure::Identity::WorkloadIdentityCredential>();
Expand Down Expand Up @@ -364,6 +376,7 @@ Result<std::unique_ptr<Blobs::BlobServiceClient>> AzureOptions::MakeBlobServiceC
[[fallthrough]];
case CredentialKind::kClientSecret:
case CredentialKind::kManagedIdentity:
case CredentialKind::kCLI:
case CredentialKind::kWorkloadIdentity:
case CredentialKind::kEnvironment:
return std::make_unique<Blobs::BlobServiceClient>(AccountBlobUrl(account_name),
Expand Down Expand Up @@ -391,6 +404,7 @@ AzureOptions::MakeDataLakeServiceClient() const {
[[fallthrough]];
case CredentialKind::kClientSecret:
case CredentialKind::kManagedIdentity:
case CredentialKind::kCLI:
case CredentialKind::kWorkloadIdentity:
case CredentialKind::kEnvironment:
return std::make_unique<DataLake::DataLakeServiceClient>(
Expand Down
11 changes: 7 additions & 4 deletions cpp/src/arrow/filesystem/azurefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct ARROW_EXPORT AzureOptions {
kStorageSharedKey,
kClientSecret,
kManagedIdentity,
kCLI,
kWorkloadIdentity,
kEnvironment,
} credential_kind_ = CredentialKind::kDefault;
Expand Down Expand Up @@ -160,14 +161,15 @@ struct ARROW_EXPORT AzureOptions {
/// * blob_storage_authority: Set AzureOptions::blob_storage_authority
/// * dfs_storage_authority: Set AzureOptions::dfs_storage_authority
/// * enable_tls: If it's "false" or "0", HTTP not HTTPS is used.
/// * credential_kind: One of "default", "anonymous",
/// "workload_identity" or "environment". If "default" is specified, it's
/// * credential_kind: One of "default", "anonymous", "workload_identity",
/// "environment" or "cli". If "default" is specified, it's
/// just ignored. If "anonymous" is specified,
/// AzureOptions::ConfigureAnonymousCredential() is called. If
/// "workload_identity" is specified,
/// AzureOptions::ConfigureWorkloadIdentityCredential() is called, If
/// AzureOptions::ConfigureWorkloadIdentityCredential() is called. If
/// "environment" is specified,
/// AzureOptions::ConfigureEnvironmentCredential() is called.
/// AzureOptions::ConfigureEnvironmentCredential() is called. If "cli" is
/// specified, AzureOptions::ConfigureCLICredential() is called.
/// * tenant_id: You must specify "client_id" and "client_secret"
/// too. AzureOptions::ConfigureClientSecretCredential() is called.
/// * client_id: If you don't specify "tenant_id" and
Expand All @@ -190,6 +192,7 @@ struct ARROW_EXPORT AzureOptions {
const std::string& client_id,
const std::string& client_secret);
Status ConfigureManagedIdentityCredential(const std::string& client_id = std::string());
Status ConfigureCLICredential();
Status ConfigureWorkloadIdentityCredential();
Status ConfigureEnvironmentCredential();

Expand Down
17 changes: 17 additions & 0 deletions cpp/src/arrow/filesystem/azurefs_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,13 @@ TEST(AzureFileSystem, InitializeWithManagedIdentityCredential) {
EXPECT_OK_AND_ASSIGN(fs, AzureFileSystem::Make(options));
}

TEST(AzureFileSystem, InitializeWithCLICredential) {
AzureOptions options;
options.account_name = "dummy-account-name";
ARROW_EXPECT_OK(options.ConfigureCLICredential());
EXPECT_OK_AND_ASSIGN(auto fs, AzureFileSystem::Make(options));
}

TEST(AzureFileSystem, InitializeWithWorkloadIdentityCredential) {
AzureOptions options;
options.account_name = "dummy-account-name";
Expand Down Expand Up @@ -667,6 +674,15 @@ class TestAzureOptions : public ::testing::Test {
ASSERT_EQ(options.credential_kind_, AzureOptions::CredentialKind::kManagedIdentity);
}

void TestFromUriCredentialCLI() {
ASSERT_OK_AND_ASSIGN(
auto options,
AzureOptions::FromUri("abfs://account.blob.core.windows.net/container/dir/blob?"
"credential_kind=cli",
nullptr));
ASSERT_EQ(options.credential_kind_, AzureOptions::CredentialKind::kCLI);
}

void TestFromUriCredentialWorkloadIdentity() {
ASSERT_OK_AND_ASSIGN(
auto options,
Expand Down Expand Up @@ -733,6 +749,7 @@ TEST_F(TestAzureOptions, FromUriCredentialClientSecret) {
TEST_F(TestAzureOptions, FromUriCredentialManagedIdentity) {
TestFromUriCredentialManagedIdentity();
}
TEST_F(TestAzureOptions, FromUriCredentialCLI) { TestFromUriCredentialCLI(); }
TEST_F(TestAzureOptions, FromUriCredentialWorkloadIdentity) {
TestFromUriCredentialWorkloadIdentity();
}
Expand Down
Loading