You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by bh...@apache.org on 2019/08/15 15:43:52 UTC

[hadoop] branch trunk updated: HDDS-1768. Audit xxxAcl methods in OzoneManager (#1204)

This is an automated email from the ASF dual-hosted git repository.

bharat pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c801f7a  HDDS-1768. Audit xxxAcl methods in OzoneManager (#1204)
c801f7a is described below

commit c801f7a26c08d367e902d3b18000853ad7ba2c82
Author: dineshchitlangia <di...@gmail.com>
AuthorDate: Thu Aug 15 11:43:47 2019 -0400

    HDDS-1768. Audit xxxAcl methods in OzoneManager (#1204)
---
 .../java/org/apache/hadoop/ozone/OzoneConsts.java  |   2 +
 .../org/apache/hadoop/ozone/audit/OMAction.java    |   6 +
 .../apache/hadoop/ozone/security/acl/OzoneObj.java |  13 +
 .../rpc/TestOzoneRpcClientForAclAuditLog.java      | 284 +++++++++++++++++++++
 .../src/test/resources/log4j2.properties           |  76 ++++++
 .../org/apache/hadoop/ozone/om/OzoneManager.java   | 197 +++++++++-----
 6 files changed, 510 insertions(+), 68 deletions(-)

diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
index 67bd22d..d9b33d8 100644
--- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
+++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java
@@ -248,6 +248,7 @@ public final class OzoneConsts {
   public static final String MAX_KEYS = "maxKeys";
   public static final String PREFIX = "prefix";
   public static final String KEY_PREFIX = "keyPrefix";
+  public static final String ACL = "acl";
   public static final String ACLS = "acls";
   public static final String USER_ACL = "userAcl";
   public static final String ADD_ACLS = "addAcls";
@@ -255,6 +256,7 @@ public final class OzoneConsts {
   public static final String MAX_NUM_OF_BUCKETS = "maxNumOfBuckets";
   public static final String TO_KEY_NAME = "toKeyName";
   public static final String STORAGE_TYPE = "storageType";
+  public static final String RESOURCE_TYPE = "resourceType";
   public static final String IS_VERSION_ENABLED = "isVersionEnabled";
   public static final String CREATION_TIME = "creationTime";
   public static final String DATA_SIZE = "dataSize";
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
index e72beff..ebcd439 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
@@ -58,6 +58,12 @@ public enum OMAction implements AuditAction {
   LIST_MULTIPART_UPLOAD_PARTS,
   ABORT_MULTIPART_UPLOAD,
 
+  //ACL Actions
+  ADD_ACL,
+  GET_ACL,
+  SET_ACL,
+  REMOVE_ACL,
+
   //FS Actions
   GET_FILE_STATUS,
   CREATE_DIRECTORY,
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneObj.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneObj.java
index 6e9ac25..4a95e55 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneObj.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneObj.java
@@ -22,6 +22,8 @@ import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneObj.ObjectType;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
 import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneObj.StoreType.*;
 
 /**
@@ -131,4 +133,15 @@ public abstract class OzoneObj implements IOzoneObj {
       value = objType;
     }
   }
+
+  public Map<String, String> toAuditMap() {
+    Map<String, String> auditMap = new LinkedHashMap<>();
+    auditMap.put(OzoneConsts.RESOURCE_TYPE, this.getResourceType().value);
+    auditMap.put(OzoneConsts.STORAGE_TYPE, this.getStoreType().value);
+    auditMap.put(OzoneConsts.VOLUME, this.getVolumeName());
+    auditMap.put(OzoneConsts.BUCKET, this.getBucketName());
+    auditMap.put(OzoneConsts.KEY, this.getKeyName());
+    return auditMap;
+  }
+
 }
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientForAclAuditLog.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientForAclAuditLog.java
new file mode 100644
index 0000000..9320fec
--- /dev/null
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientForAclAuditLog.java
@@ -0,0 +1,284 @@
+package org.apache.hadoop.ozone.client.rpc;
+
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.scm.protocolPB.StorageContainerLocationProtocolClientSideTranslatorPB;
+import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.OzoneAcl;
+import org.apache.hadoop.ozone.audit.AuditEventStatus;
+import org.apache.hadoop.ozone.audit.OMAction;
+import org.apache.hadoop.ozone.client.ObjectStore;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.client.OzoneClientFactory;
+import org.apache.hadoop.ozone.client.OzoneVolume;
+import org.apache.hadoop.ozone.client.VolumeArgs;
+import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
+import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.security.acl.OzoneObjInfo;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.test.GenericTestUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import static org.apache.hadoop.ozone.OzoneAcl.AclScope.ACCESS;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_AUTHORIZER_CLASS;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_AUTHORIZER_CLASS_NATIVE;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_ENABLED;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS_WILDCARD;
+import static org.apache.hadoop.ozone.security.acl.OzoneObj.ResourceType.VOLUME;
+import static org.apache.hadoop.ozone.security.acl.OzoneObj.StoreType.OZONE;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This class is to test audit logs for xxxACL APIs of Ozone Client.
+ * It is annotated as NotThreadSafe intentionally since this test reads from
+ * the generated audit logs to verify the operations. Since the
+ * maven test plugin will trigger parallel test execution, there is a
+ * possibility of other audit events being logged and leading to failure of
+ * all assertion based test in this class.
+ */
+@NotThreadSafe
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestOzoneRpcClientForAclAuditLog {
+
+  private static final Logger LOG =
+      LoggerFactory.getLogger(TestOzoneRpcClientForAclAuditLog.class);
+  private static UserGroupInformation ugi;
+  private static final OzoneAcl USER_ACL =
+      new OzoneAcl(IAccessAuthorizer.ACLIdentityType.USER,
+      "johndoe", IAccessAuthorizer.ACLType.ALL, ACCESS);
+  private static final OzoneAcl USER_ACL_2 =
+      new OzoneAcl(IAccessAuthorizer.ACLIdentityType.USER,
+      "jane", IAccessAuthorizer.ACLType.ALL, ACCESS);
+  private static List<OzoneAcl> aclListToAdd = new ArrayList<>();
+  private static MiniOzoneCluster cluster = null;
+  private static OzoneClient ozClient = null;
+  private static ObjectStore store = null;
+  private static StorageContainerLocationProtocolClientSideTranslatorPB
+      storageContainerLocationClient;
+  private static String scmId = UUID.randomUUID().toString();
+
+
+  /**
+   * Create a MiniOzoneCluster for testing.
+   *
+   * Ozone is made active by setting OZONE_ENABLED = true
+   *
+   * @throws IOException
+   */
+  @BeforeClass
+  public static void init() throws Exception {
+    System.setProperty("log4j.configurationFile", "log4j2.properties");
+    ugi = UserGroupInformation.getCurrentUser();
+    OzoneConfiguration conf = new OzoneConfiguration();
+    conf.setBoolean(OZONE_ACL_ENABLED, true);
+    conf.set(OZONE_ADMINISTRATORS, OZONE_ADMINISTRATORS_WILDCARD);
+    conf.set(OZONE_ACL_AUTHORIZER_CLASS,
+        OZONE_ACL_AUTHORIZER_CLASS_NATIVE);
+    startCluster(conf);
+    aclListToAdd.add(USER_ACL);
+    aclListToAdd.add(USER_ACL_2);
+    emptyAuditLog();
+  }
+
+  /**
+   * Create a MiniOzoneCluster for testing.
+   * @param conf Configurations to start the cluster.
+   * @throws Exception
+   */
+  private static void startCluster(OzoneConfiguration conf) throws Exception {
+    cluster = MiniOzoneCluster.newBuilder(conf)
+        .setNumDatanodes(3)
+        .setScmId(scmId)
+        .build();
+    cluster.waitForClusterToBeReady();
+    ozClient = OzoneClientFactory.getRpcClient(conf);
+    store = ozClient.getObjectStore();
+    storageContainerLocationClient =
+        cluster.getStorageContainerLocationClient();
+  }
+
+  /**
+   * Close OzoneClient and shutdown MiniOzoneCluster.
+   */
+  @AfterClass
+  public static void teardown() throws IOException {
+    shutdownCluster();
+    deleteAuditLog();
+  }
+
+  private static void deleteAuditLog() throws IOException {
+    File file = new File("audit.log");
+    if (FileUtils.deleteQuietly(file)) {
+      LOG.info(file.getName() +
+          " has been deleted.");
+    } else {
+      LOG.info("audit.log could not be deleted.");
+    }
+  }
+
+  private static void emptyAuditLog() throws IOException {
+    File file = new File("audit.log");
+    FileUtils.writeLines(file, new ArrayList<>(), false);
+  }
+
+  /**
+   * Close OzoneClient and shutdown MiniOzoneCluster.
+   */
+  private static void shutdownCluster() throws IOException {
+    if(ozClient != null) {
+      ozClient.close();
+    }
+
+    if (storageContainerLocationClient != null) {
+      storageContainerLocationClient.close();
+    }
+
+    if (cluster != null) {
+      cluster.shutdown();
+    }
+  }
+
+  @Test
+  public void testXXXAclSuccessAudits() throws Exception {
+
+    String userName = ugi.getUserName();
+    String adminName = ugi.getUserName();
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+
+    VolumeArgs createVolumeArgs = VolumeArgs.newBuilder()
+        .setAdmin(adminName)
+        .setOwner(userName)
+        .build();
+    store.createVolume(volumeName, createVolumeArgs);
+    verifyLog(OMAction.CREATE_VOLUME.name(), volumeName,
+        AuditEventStatus.SUCCESS.name());
+    OzoneVolume retVolumeinfo = store.getVolume(volumeName);
+    verifyLog(OMAction.READ_VOLUME.name(), volumeName,
+        AuditEventStatus.SUCCESS.name());
+    Assert.assertTrue(retVolumeinfo.getName().equalsIgnoreCase(volumeName));
+
+    OzoneObj volObj = new OzoneObjInfo.Builder()
+        .setVolumeName(volumeName)
+        .setResType(VOLUME)
+        .setStoreType(OZONE)
+        .build();
+
+    //Testing getAcl
+    List<OzoneAcl> acls = store.getAcl(volObj);
+    verifyLog(OMAction.GET_ACL.name(), volumeName,
+        AuditEventStatus.SUCCESS.name());
+    Assert.assertTrue(acls.size() > 0);
+
+    //Testing addAcl
+    store.addAcl(volObj, USER_ACL);
+    verifyLog(OMAction.ADD_ACL.name(), volumeName, "johndoe",
+        AuditEventStatus.SUCCESS.name());
+
+    //Testing removeAcl
+    store.removeAcl(volObj, USER_ACL);
+    verifyLog(OMAction.REMOVE_ACL.name(), volumeName, "johndoe",
+        AuditEventStatus.SUCCESS.name());
+
+    //Testing setAcl
+    store.setAcl(volObj, aclListToAdd);
+    verifyLog(OMAction.SET_ACL.name(), volumeName, "johndoe", "jane",
+        AuditEventStatus.SUCCESS.name());
+
+  }
+
+  @Test
+  public void testXXXAclFailureAudits() throws Exception {
+
+    String userName = "bilbo";
+    String adminName = "bilbo";
+    String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
+
+    VolumeArgs createVolumeArgs = VolumeArgs.newBuilder()
+        .setAdmin(adminName)
+        .setOwner(userName)
+        .build();
+    store.createVolume(volumeName, createVolumeArgs);
+    verifyLog(OMAction.CREATE_VOLUME.name(), volumeName,
+        AuditEventStatus.SUCCESS.name());
+
+    OzoneObj volObj = new OzoneObjInfo.Builder()
+        .setVolumeName(volumeName)
+        .setResType(VOLUME)
+        .setStoreType(OZONE)
+        .build();
+
+    // xxxAcl will fail as current ugi user doesn't have the required access
+    // for volume
+    try{
+      List<OzoneAcl> acls = store.getAcl(volObj);
+    } catch (Exception ex) {
+      verifyLog(OMAction.GET_ACL.name(), volumeName,
+          AuditEventStatus.FAILURE.name());
+    }
+
+    try{
+      store.addAcl(volObj, USER_ACL);
+    } catch (Exception ex) {
+      verifyLog(OMAction.ADD_ACL.name(), volumeName,
+          AuditEventStatus.FAILURE.name());
+    }
+
+    try{
+      store.removeAcl(volObj, USER_ACL);
+    } catch (Exception ex) {
+      verifyLog(OMAction.REMOVE_ACL.name(), volumeName,
+          AuditEventStatus.FAILURE.name());
+    }
+
+    try{
+      store.setAcl(volObj, aclListToAdd);
+    } catch (Exception ex) {
+      verifyLog(OMAction.SET_ACL.name(), volumeName, "johndoe", "jane",
+          AuditEventStatus.FAILURE.name());
+    }
+
+  }
+
+  private void verifyLog(String... expected) throws Exception {
+    File file = new File("audit.log");
+    final List<String> lines = FileUtils.readLines(file, (String)null);
+    GenericTestUtils.waitFor(() ->
+        (lines != null) ? true : false, 100, 60000);
+
+    try{
+      // When log entry is expected, the log file will contain one line and
+      // that must be equal to the expected string
+      assertTrue(lines.size() != 0);
+      for(String exp: expected){
+        assertTrue(lines.get(0).contains(exp));
+      }
+    } catch (AssertionError ex){
+      LOG.error("Error occurred in log verification", ex);
+      if(lines.size() != 0){
+        LOG.error("Actual line ::: " + lines.get(0));
+        LOG.error("Expected tokens ::: " + Arrays.toString(expected));
+      }
+      throw ex;
+    } finally {
+      emptyAuditLog();
+    }
+  }
+
+}
diff --git a/hadoop-ozone/integration-test/src/test/resources/log4j2.properties b/hadoop-ozone/integration-test/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..19daa6f
--- /dev/null
+++ b/hadoop-ozone/integration-test/src/test/resources/log4j2.properties
@@ -0,0 +1,76 @@
+#
+# 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
+# <p>
+# http://www.apache.org/licenses/LICENSE-2.0
+# <p>
+# 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.
+#
+name=PropertiesConfig
+
+# Checks for config change periodically and reloads
+monitorInterval=5
+
+filter=read, write
+# filter.read.onMatch = DENY avoids logging all READ events
+# filter.read.onMatch = ACCEPT permits logging all READ events
+# The above two settings ignore the log levels in configuration
+# filter.read.onMatch = NEUTRAL permits logging of only those READ events
+# which are attempted at log level equal or greater than log level specified
+# in the configuration
+filter.read.type = MarkerFilter
+filter.read.marker = READ
+filter.read.onMatch = NEUTRAL
+filter.read.onMismatch = NEUTRAL
+
+# filter.write.onMatch = DENY avoids logging all WRITE events
+# filter.write.onMatch = ACCEPT permits logging all WRITE events
+# The above two settings ignore the log levels in configuration
+# filter.write.onMatch = NEUTRAL permits logging of only those WRITE events
+# which are attempted at log level equal or greater than log level specified
+# in the configuration
+filter.write.type = MarkerFilter
+filter.write.marker = WRITE
+filter.write.onMatch = NEUTRAL
+filter.write.onMismatch = NEUTRAL
+
+# Log Levels are organized from most specific to least:
+# OFF (most specific, no logging)
+# FATAL (most specific, little data)
+# ERROR
+# WARN
+# INFO
+# DEBUG
+# TRACE (least specific, a lot of data)
+# ALL (least specific, all data)
+
+appenders = console, audit
+appender.console.type = Console
+appender.console.name = STDOUT
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{DEFAULT} | %-5level | %c{1} | %msg | %throwable{3} %n
+
+appender.audit.type = File
+appender.audit.name = AUDITLOG
+appender.audit.fileName=audit.log
+appender.audit.layout.type=PatternLayout
+appender.audit.layout.pattern= %d{DEFAULT} | %-5level | %c{1} | %msg | %throwable{3} %n
+
+loggers=audit
+logger.audit.type=AsyncLogger
+logger.audit.name=OMAudit
+logger.audit.level = INFO
+logger.audit.appenderRefs = audit
+logger.audit.appenderRef.file.ref = AUDITLOG
+
+rootLogger.level = INFO
+rootLogger.appenderRefs = stdout
+rootLogger.appenderRef.stdout.ref = STDOUT
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index bbf6a6b..c006f7a 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -30,6 +30,7 @@ import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.KeyPair;
 import java.security.cert.CertificateException;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Objects;
 
@@ -2989,6 +2990,22 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
     }
   }
 
+  private void auditAcl(OzoneObj ozoneObj, List<OzoneAcl> ozoneAcl,
+      OMAction omAction, Exception ex) {
+    Map<String, String> auditMap = ozoneObj.toAuditMap();
+    if(ozoneAcl != null) {
+      auditMap.put(OzoneConsts.ACL, ozoneAcl.toString());
+    }
+
+    if(ex == null) {
+      AUDIT.logWriteSuccess(
+          buildAuditMessageForSuccess(omAction, auditMap));
+    } else {
+      AUDIT.logWriteFailure(
+          buildAuditMessageForFailure(omAction, auditMap, ex));
+    }
+  }
+
   /**
    * Add acl for Ozone object. Return true if acl is added successfully else
    * false.
@@ -2999,23 +3016,34 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
    */
   @Override
   public boolean addAcl(OzoneObj obj, OzoneAcl acl) throws IOException {
-    if(isAclEnabled) {
-      checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
-          obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
-    }
-    // TODO: Audit ACL operation.
-    switch (obj.getResourceType()) {
-    case VOLUME:
-      return volumeManager.addAcl(obj, acl);
-    case BUCKET:
-      return bucketManager.addAcl(obj, acl);
-    case KEY:
-      return keyManager.addAcl(obj, acl);
-    case PREFIX:
-      return prefixManager.addAcl(obj, acl);
-    default:
-      throw new OMException("Unexpected resource type: " +
-          obj.getResourceType(), INVALID_REQUEST);
+    boolean auditSuccess = true;
+
+    try{
+      if(isAclEnabled) {
+        checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
+            obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
+      }
+      switch (obj.getResourceType()) {
+      case VOLUME:
+        return volumeManager.addAcl(obj, acl);
+      case BUCKET:
+        return bucketManager.addAcl(obj, acl);
+      case KEY:
+        return keyManager.addAcl(obj, acl);
+      case PREFIX:
+        return prefixManager.addAcl(obj, acl);
+      default:
+        throw new OMException("Unexpected resource type: " +
+            obj.getResourceType(), INVALID_REQUEST);
+      }
+    } catch(Exception ex) {
+      auditSuccess = false;
+      auditAcl(obj, Arrays.asList(acl), OMAction.ADD_ACL, ex);
+      throw ex;
+    } finally {
+      if(auditSuccess){
+        auditAcl(obj, Arrays.asList(acl), OMAction.ADD_ACL, null);
+      }
     }
   }
 
@@ -3029,24 +3057,35 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
    */
   @Override
   public boolean removeAcl(OzoneObj obj, OzoneAcl acl) throws IOException {
-    if(isAclEnabled) {
-      checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
-          obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
-    }
-    // TODO: Audit ACL operation.
-    switch (obj.getResourceType()) {
-    case VOLUME:
-      return volumeManager.removeAcl(obj, acl);
-    case BUCKET:
-      return bucketManager.removeAcl(obj, acl);
-    case KEY:
-      return keyManager.removeAcl(obj, acl);
-    case PREFIX:
-      return prefixManager.removeAcl(obj, acl);
+    boolean auditSuccess = true;
 
-    default:
-      throw new OMException("Unexpected resource type: " +
-          obj.getResourceType(), INVALID_REQUEST);
+    try{
+      if(isAclEnabled) {
+        checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
+            obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
+      }
+      switch (obj.getResourceType()) {
+      case VOLUME:
+        return volumeManager.removeAcl(obj, acl);
+      case BUCKET:
+        return bucketManager.removeAcl(obj, acl);
+      case KEY:
+        return keyManager.removeAcl(obj, acl);
+      case PREFIX:
+        return prefixManager.removeAcl(obj, acl);
+
+      default:
+        throw new OMException("Unexpected resource type: " +
+            obj.getResourceType(), INVALID_REQUEST);
+      }
+    } catch(Exception ex) {
+      auditSuccess = false;
+      auditAcl(obj, Arrays.asList(acl), OMAction.REMOVE_ACL, ex);
+      throw ex;
+    } finally {
+      if(auditSuccess){
+        auditAcl(obj, Arrays.asList(acl), OMAction.REMOVE_ACL, null);
+      }
     }
   }
 
@@ -3060,23 +3099,34 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
    */
   @Override
   public boolean setAcl(OzoneObj obj, List<OzoneAcl> acls) throws IOException {
-    if(isAclEnabled) {
-      checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
-          obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
-    }
-    // TODO: Audit ACL operation.
-    switch (obj.getResourceType()) {
-    case VOLUME:
-      return volumeManager.setAcl(obj, acls);
-    case BUCKET:
-      return bucketManager.setAcl(obj, acls);
-    case KEY:
-      return keyManager.setAcl(obj, acls);
-    case PREFIX:
-      return prefixManager.setAcl(obj, acls);
-    default:
-      throw new OMException("Unexpected resource type: " +
-          obj.getResourceType(), INVALID_REQUEST);
+    boolean auditSuccess = true;
+
+    try{
+      if(isAclEnabled) {
+        checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.WRITE_ACL,
+            obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
+      }
+      switch (obj.getResourceType()) {
+      case VOLUME:
+        return volumeManager.setAcl(obj, acls);
+      case BUCKET:
+        return bucketManager.setAcl(obj, acls);
+      case KEY:
+        return keyManager.setAcl(obj, acls);
+      case PREFIX:
+        return prefixManager.setAcl(obj, acls);
+      default:
+        throw new OMException("Unexpected resource type: " +
+            obj.getResourceType(), INVALID_REQUEST);
+      }
+    } catch(Exception ex) {
+      auditSuccess = false;
+      auditAcl(obj, acls, OMAction.SET_ACL, ex);
+      throw ex;
+    } finally {
+      if(auditSuccess){
+        auditAcl(obj, acls, OMAction.SET_ACL, null);
+      }
     }
   }
 
@@ -3088,24 +3138,35 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
    */
   @Override
   public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
-    if(isAclEnabled) {
-      checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.READ_ACL,
-          obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
-    }
-    // TODO: Audit ACL operation.
-    switch (obj.getResourceType()) {
-    case VOLUME:
-      return volumeManager.getAcl(obj);
-    case BUCKET:
-      return bucketManager.getAcl(obj);
-    case KEY:
-      return keyManager.getAcl(obj);
-    case PREFIX:
-      return prefixManager.getAcl(obj);
+    boolean auditSuccess = true;
 
-    default:
-      throw new OMException("Unexpected resource type: " +
-          obj.getResourceType(), INVALID_REQUEST);
+    try{
+      if(isAclEnabled) {
+        checkAcls(obj.getResourceType(), obj.getStoreType(), ACLType.READ_ACL,
+            obj.getVolumeName(), obj.getBucketName(), obj.getKeyName());
+      }
+      switch (obj.getResourceType()) {
+      case VOLUME:
+        return volumeManager.getAcl(obj);
+      case BUCKET:
+        return bucketManager.getAcl(obj);
+      case KEY:
+        return keyManager.getAcl(obj);
+      case PREFIX:
+        return prefixManager.getAcl(obj);
+
+      default:
+        throw new OMException("Unexpected resource type: " +
+            obj.getResourceType(), INVALID_REQUEST);
+      }
+    } catch(Exception ex) {
+      auditSuccess = false;
+      auditAcl(obj, null, OMAction.GET_ACL, ex);
+      throw ex;
+    } finally {
+      if(auditSuccess){
+        auditAcl(obj, null, OMAction.GET_ACL, null);
+      }
     }
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org