diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config index 8133eb1073e6..dd89f7cae8b7 100644 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config @@ -178,3 +178,9 @@ OZONE-SITE.XML_hdds.secret.key.expiry.duration=1h OZONE-SITE.XML_ozone.manager.delegation.token.max-lifetime=30m OZONE-SITE.XML_ozone.manager.delegation.token.renew-interval=5m OZONE-SITE.XML_ozone.manager.delegation.remover.scan.interval=1m + +# Enable Ozone lifecycle service +OZONE-SITE.XML_ozone.lifecycle.service.enabled=true +OZONE-SITE.XML_ozone.lifecycle.service.interval=30s +OZONE-SITE.XML_ozone.lifecycle.service.timeout=10s + diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh new file mode 100644 index 000000000000..7d70973a9888 --- /dev/null +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-om-lifecycle.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# 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. + +#suite:HA-secure + +set -u -o pipefail + +COMPOSE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export COMPOSE_DIR + +export SECURITY_ENABLED=true +export OM_SERVICE_ID="omservice" +export SCM=scm1.org + +# shellcheck source=/dev/null +source "$COMPOSE_DIR/../testlib.sh" + +start_docker_env + +execute_robot_test s3g kinit.robot + +execute_robot_test s3g admincli/om-lifecycle.robot + +execute_robot_test s3g s3/bucketlifecycle.robot diff --git a/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot new file mode 100644 index 000000000000..a3d97b4b5316 --- /dev/null +++ b/hadoop-ozone/dist/src/main/smoketest/admincli/om-lifecycle.robot @@ -0,0 +1,119 @@ +# 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. + +*** Settings *** +Documentation Ozone admin om lifecycle commands +Library OperatingSystem +Resource ../commonlib.robot +Test Timeout 5 minutes + +*** Variables *** +${OM_SERVICE_ID} om + +*** Test Cases *** +Test Lifecycle Status + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' + Should Contain ${output} IsEnabled + Should Contain ${output} IsSuspended + +Test Lifecycle Suspend And Resume + ${output} = Execute ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' + Should Contain ${output} IsSuspended: true + + ${output} = Execute ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' + Should Contain ${output} Lifecycle Service has been resumed + + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' + Should Contain ${output} IsSuspended: false + +Test Lifecycle Status After Leader Transfer + ${output} = Execute ozone admin om roles --service-id '${OM_SERVICE_ID}' + ${is_ha} = Run Keyword And Return Status Should Contain ${output} FOLLOWER + IF ${is_ha} + ${output} = Execute ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute ozone admin om transfer --service-id '${OM_SERVICE_ID}' -r + Should Contain ${output} Transfer leadership successfully + + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' + Should Contain ${output} IsSuspended: true + + ${output} = Execute ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' + Should Contain ${output} Lifecycle Service has been resumed + + ${output} = Execute ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' + Should Contain ${output} IsSuspended: false + ELSE + Pass Execution Cluster is not HA, skipping leader transfer test + END + +Test Lifecycle Suspend And Resume Requires Admin + # This test verifies that suspend and resume commands require admin privileges + # while the status command does not. + # The Requires admin privilege keyword automatically switches to testuser2 via kinit + # in secure environments and verifies access is denied. + + Get Security Enabled From Config + IF '${SECURITY_ENABLED}' == 'true' + # First switch to non-admin user + Kinit test user testuser2 testuser2.keytab + + # Status should work for non-admin + ${output} = Execute and checkrc ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} IsEnabled + + # Suspend should fail for non-admin + Access should be denied ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' + + # Resume should fail for non-admin + Access should be denied ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' + + # Switch back to admin user for subsequent tests + Kinit test user testuser testuser.keytab + + # Verify admin can suspend and resume + ${output} = Execute and checkrc ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute and checkrc ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} Lifecycle Service has been resumed + ELSE + # In non-secure environments, we can test by passing a different user via HADOOP_USER_NAME + + # Status should work for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle status --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} IsEnabled + + # Suspend should fail for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 255 + Should Contain ${output} Access denied + Should Contain ${output} Superuser privilege is required + + # Resume should fail for non-admin + ${output} = Execute and checkrc env HADOOP_USER_NAME=testuser2 ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 255 + Should Contain ${output} Access denied + Should Contain ${output} Superuser privilege is required + + # Verify admin (default user) can suspend and resume + ${output} = Execute and checkrc ozone admin om lifecycle suspend --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} Lifecycle Service has been suspended + + ${output} = Execute and checkrc ozone admin om lifecycle resume --service-id '${OM_SERVICE_ID}' 0 + Should Contain ${output} Lifecycle Service has been resumed + END diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot new file mode 100644 index 000000000000..39b46c1b82a8 --- /dev/null +++ b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot @@ -0,0 +1,53 @@ +# 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. + +*** Settings *** +Documentation S3 gateway test with aws cli for bucket lifecycle +Library OperatingSystem +Library String +Resource ../commonlib.robot +Resource commonawslib.robot +Test Timeout 5 minutes +Suite Setup Setup s3 tests + +*** Variables *** +${ENDPOINT_URL} http://s3g:9878 +${BUCKET} generated + +*** Test Cases *** + +Set bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + Should Be Empty ${result} + +Get bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + ${result} = Execute AWSS3APICli get-bucket-lifecycle-configuration --bucket ${bucket} + Should contain ${result} Rule1 + Should contain ${result} prefix1/ + Should contain ${result} Enabled + +Delete bucket lifecycle configuration + ${bucket} = Create bucket + ${lifecycle_json} = Set Variable {"Rules": [{"ID": "Rule1", "Prefix": "prefix1/", "Status": "Enabled", "Expiration": {"Days": 1}}]} + ${result} = Execute AWSS3APICli put-bucket-lifecycle-configuration --bucket ${bucket} --lifecycle-configuration '${lifecycle_json}' + ${result} = Execute AWSS3APICli delete-bucket-lifecycle --bucket ${bucket} + Should Be Empty ${result} + ${result} = Execute AWSS3APICli and checkrc get-bucket-lifecycle-configuration --bucket ${bucket} 255 + Should contain ${result} NoSuchLifecycleConfiguration