github-actions[bot] commented on code in PR #68540:
URL: https://github.com/apache/doris/pull/68540#discussion_r4119930347
##########
fe/fe-core/src/main/java/org/apache/doris/cloud/storage/ObjectInfoAdapter.java:
##########
@@ -74,8 +74,17 @@ public static StorageAdapter toStorageAdapter(ObjectInfo
obj) {
case OSS:
return StorageAdapter.ofProvider("OSS",
buildS3CompatibleProps(obj));
case S3:
- case GCP:
return StorageAdapter.ofProvider("S3",
buildS3CompatibleProps(obj));
+ case GCP:
+ Map<String, String> gcpProperties =
buildS3CompatibleProps(obj);
+ gcpProperties.put("provider", "GCP");
Review Comment:
[P1] Pass the native stage credential into COPY INTO scan properties. The
new adapter forwards gs.credential_provider_type and
gs.impersonation_service_account for FE filesystem calls, but
CopyIntoInfo.validateStagePB builds brokerProperties manually from AK/SK,
endpoint, bucket, prefix and provider, omitting both fields. Even after
get_stage preserves the credential, the BrokerDesc sent to BE resolves GCP as
DEFAULT ADC, so COMPUTE_ENGINE or impersonated COPY reads use the wrong
identity. Please carry these fields into that broker map and test the BE scan
properties.
##########
cloud/src/meta-service/meta_service_resource.cpp:
##########
@@ -781,14 +782,23 @@ static void create_object_info_with_encrypt(const
InstanceInfoPB& instance, Obje
std::string external_endpoint = obj->has_external_endpoint() ?
obj->external_endpoint() : "";
std::string region = obj->has_region() ? obj->region() : "";
- if (obj->has_role_arn()) {
- if (obj->role_arn().empty() || !obj->has_cred_provider_type() ||
!obj->has_provider() ||
+ if (has_obj_credential(*obj)) {
Review Comment:
[P1] Preserve the GCP credential when returning an internal stage. This
branch now accepts and stores a native GCP credential for instance object
storage, but get_stage rebuilds the INTERNAL StagePB.obj_info field by field at
4199-4217 without old_obj.credential. A COMPUTE_ENGINE or impersonated instance
is then returned to FE as provider=GCP with no credential, so stage operations
silently use DEFAULT ADC. Please copy the credential envelope into the stage
response and cover the get_stage path in a test.
##########
regression-test/suites/object_storage_iam_p0/test_alter_resource_with_role.groovy:
##########
@@ -0,0 +1,234 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import groovy.json.JsonSlurper
+import org.apache.doris.regression.util.ObjectStorageIamTestUtils
+
+suite("test_alter_resource_with_role") {
+ if (!ObjectStorageIamTestUtils.isProvider(context.config.otherConfigs,
"AWS")) {
+ logger.info("skip ${name} because objectStorageIamProvider is not AWS")
+ return
+ }
+ def config =
ObjectStorageIamTestUtils.getConfig(context.config.otherConfigs)
+
+
+ if (isCloudMode()) {
+ logger.info("skip ${name} case, because it is cloud mode")
+ return
+ }
+
+ def tableName = "test_alter_resource_with_role"
+ def randomStr = UUID.randomUUID().toString().replace("-", "")
+ def resourceName = "alter_resource_${randomStr}"
+ def policyName = "alter_policy_${randomStr}"
+
+ def awsEndpoint = config.endpoint
+ def region = config.region
+ def bucket = config.bucket
+ def roleArn = config.roleArn
+ def externalId = config.externalId ?: ""
+ def prefix = config.prefix
+
+ def awsAccessKey = context.config.awsAccessKey
+ def awsSecretKey = context.config.awsSecretKey
+
+ sql """
+ CREATE RESOURCE IF NOT EXISTS "${resourceName}"
+ PROPERTIES(
+ "type"="s3",
+ "AWS_ENDPOINT" = "${awsEndpoint}",
+ "AWS_REGION" = "${region}",
+ "AWS_BUCKET" = "${bucket}",
+ "AWS_ROOT_PATH" =
"${prefix}/test_alter_resource_with_role/${randomStr}",
+ "AWS_ACCESS_KEY" = "error_ak",
+ "AWS_SECRET_KEY" = "error_sk",
+ "s3_validity_check" = "false"
+ );
+ """
+
+ sql """
+ CREATE STORAGE POLICY IF NOT EXISTS ${policyName}
+ PROPERTIES(
+ "storage_resource" = "${resourceName}",
+ "cooldown_ttl" = "1"
+ )
+ """
+
+ sql """
+ DROP TABLE IF EXISTS ${tableName} FORCE;
+ """
+
+ sql """
+ CREATE TABLE ${tableName}
+ (
+ siteid INT DEFAULT '10',
+ citycode SMALLINT NOT NULL,
+ username VARCHAR(32) DEFAULT '',
+ pv BIGINT SUM DEFAULT '0'
+ )
+ AGGREGATE KEY(siteid, citycode, username)
+ DISTRIBUTED BY HASH(siteid) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_policy" = "${policyName}"
+ )
+ """
+
+ sql """insert into ${tableName}(siteid, citycode, username, pv) values (1,
1, "xxx", 1),
+ (2, 2, "yyy", 2),
+ (3, 3, "zzz", 3)
+ """
+
+ def result = sql """ SHOW RESOURCES WHERE NAME = "${resourceName}"; """
+ log.info("result:${result}")
+ assertTrue(!result.toString().contains(roleArn))
+ assertTrue(!result.toString().contains(externalId));
Review Comment:
[P2] Handle an omitted external ID in this new AWS suite.
objectStorageIamAwsExternalId defaults to empty and getAwsAuthCases explicitly
omits it when empty, but externalId becomes "" here and
result.toString().contains("") is always true. This assertion fails before the
ALTER, and the same assertion at line 203 fails too. Please guard the absence
checks when externalId is nonempty.
##########
cloud/src/meta-service/meta_service_resource.cpp:
##########
@@ -781,14 +782,23 @@ static void create_object_info_with_encrypt(const
InstanceInfoPB& instance, Obje
std::string external_endpoint = obj->has_external_endpoint() ?
obj->external_endpoint() : "";
std::string region = obj->has_region() ? obj->region() : "";
- if (obj->has_role_arn()) {
- if (obj->role_arn().empty() || !obj->has_cred_provider_type() ||
!obj->has_provider() ||
+ if (has_obj_credential(*obj)) {
+ if (auto error = validate_and_normalize_obj_credential(obj);
error.has_value()) {
Review Comment:
[P1] Clear native GCP auth when legacy instance keys replace it. After this
branch stores a GCP credential in instance.obj_info,
ALTER_OBJ_INFO/LEGACY_UPDATE_AK_SK and update_ak_sk can set new AK/SK on that
same object without clearing credential. BE and recycler still select the
retained GCP OAuth client, so the update reports success while the new keys are
unused; FE may also reject the mixed credential state. Please clear the native
envelope on a key transition or reject the update, and test this sequence.
##########
regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Syncer.groovy:
##########
@@ -1027,25 +1027,15 @@ class Syncer {
"""
}
- void createS3RepositoryWithRole(String name, boolean readOnly = false) {
- String roleArn = suite.context.config.awsRoleArn
- String externalId = suite.context.config.awsExternalId
- String endpoint = suite.context.config.awsEndpoint
- String region = suite.context.config.awsRegion
- String bucket = suite.context.config.awsBucket
- String prefix = suite.context.config.awsPrefix
-
+ void createObjectStorageIamRepository(String name, Map iamConfig, Map
authCase, boolean readOnly = false) {
Review Comment:
[P2] Keep the existing AWS IAM backup/restore suite callable. This replaces
createS3RepositoryWithRole, but
aws_iam_role_p0/test_backup_restore_with_role.groovy:41 still calls
syncer.createS3RepositoryWithRole(repoName) when awsRoleArn is configured. That
suite now fails with MissingMethodException before exercising backup/restore.
Please retain a delegating helper or migrate the old suite to
createObjectStorageIamRepository.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]