Kerberos related audit events

Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a885ef5a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a885ef5a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a885ef5a

Branch: refs/heads/audit_logging
Commit: a885ef5a4df3cda4cda413be32a6e81e2ea73275
Parents: 4abfc3e
Author: Daniel Gergely <dgerg...@hortonworks.com>
Authored: Mon Feb 29 11:30:55 2016 +0100
Committer: Toader, Sebastian <stoa...@hortonworks.com>
Committed: Thu Mar 24 13:06:47 2016 +0100

----------------------------------------------------------------------
 .../ambari/server/audit/AbstractAuditEvent.java |   2 +-
 .../kerberos/AbstractKerberosAuditEvent.java    |  76 +++++++
 .../ChangeSecurityStateKerberosAuditEvent.java  |  99 ++++++++
 .../CreateKeyTabKerberosAuditEvent.java         |  95 ++++++++
 .../CreatePrincipalKerberosAuditEvent.java      |  72 ++++++
 .../DestroyPrincipalKerberosAuditEvent.java     |  73 ++++++
 .../event/AddCredentialRequestAuditEvent.java   | 105 +++++++++
 .../event/AddRequestRequestAuditEvent.java      |  84 +++++++
 .../eventcreator/CredentialEventCreator.java    | 103 +++++++++
 .../eventcreator/RequestEventCreator.java       | 101 +++++++++
 .../eventcreator/UpgradeItemEventCreator.java   |   2 +-
 .../ambari/server/controller/AmbariServer.java  |   3 +
 .../server/controller/ControllerModule.java     |   4 +
 .../serveraction/AbstractServerAction.java      |  25 ++
 .../kerberos/CreateKeytabFilesServerAction.java | 227 ++++++++++---------
 .../kerberos/CreatePrincipalsServerAction.java  | 155 +++++++------
 .../kerberos/DestroyPrincipalsServerAction.java |  51 +++--
 .../kerberos/FinalizeKerberosServerAction.java  |  10 +
 .../kerberos/KerberosServerAction.java          |   1 +
 19 files changed, 1089 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/AbstractAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/AbstractAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/AbstractAuditEvent.java
index 639b78f..d3c7be3 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/AbstractAuditEvent.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/AbstractAuditEvent.java
@@ -37,7 +37,7 @@ public abstract class AbstractAuditEvent implements  
AuditEvent {
    * @param <T> the type of the concrete audit event built by this builder
    * @param <TBuilder> the type of the concrete audit event builder.
    */
-  static abstract class AbstractAuditEventBuilder<T extends 
AbstractAuditEvent, TBuilder extends AbstractAuditEventBuilder<T, TBuilder>>
+  protected static abstract class AbstractAuditEventBuilder<T extends 
AbstractAuditEvent, TBuilder extends AbstractAuditEventBuilder<T, TBuilder>>
     implements AuditEventBuilder<T> {
 
     private DateTime timestamp;

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/AbstractKerberosAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/AbstractKerberosAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/AbstractKerberosAuditEvent.java
new file mode 100644
index 0000000..899432c
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/AbstractKerberosAuditEvent.java
@@ -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
+ *
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.kerberos;
+
+
+import javax.annotation.concurrent.Immutable;
+
+import org.apache.ambari.server.audit.AbstractAuditEvent;
+
+@Immutable
+public class AbstractKerberosAuditEvent extends AbstractAuditEvent {
+  static abstract class AbstractKerberosAuditEventBuilder<T extends 
AbstractKerberosAuditEvent, TBuilder extends 
AbstractKerberosAuditEventBuilder<T, TBuilder>>
+    extends AbstractAuditEvent.AbstractAuditEventBuilder<T, TBuilder> {
+
+    protected String operation;
+    protected String reasonOfFailure;
+
+    /**
+     * Builds and audit log message based on the member variables
+     * @param builder builder for the audit event details.
+     */
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      builder
+        .append("Operation(")
+        .append(operation);
+
+      builder.append("), Status(")
+        .append(reasonOfFailure == null ? "Success" : "Failed");
+
+      if(reasonOfFailure != null) {
+        builder.append("), Reason of failure(")
+          .append(reasonOfFailure);
+      }
+
+      builder.append(")");
+    }
+
+    public TBuilder withOperation(String operation) {
+      this.operation = operation;
+      return (TBuilder) this;
+    }
+
+    public TBuilder withReasonOfFailure(String reasonOfFailure) {
+      this.reasonOfFailure = reasonOfFailure;
+      return (TBuilder) this;
+    }
+  }
+
+  protected AbstractKerberosAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected AbstractKerberosAuditEvent(AbstractKerberosAuditEventBuilder<?, ?> 
builder) {
+    super(builder);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/ChangeSecurityStateKerberosAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/ChangeSecurityStateKerberosAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/ChangeSecurityStateKerberosAuditEvent.java
new file mode 100644
index 0000000..899addc
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/ChangeSecurityStateKerberosAuditEvent.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.kerberos;
+
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class ChangeSecurityStateKerberosAuditEvent extends 
AbstractKerberosAuditEvent {
+
+  public static class ChangeSecurityStateKerberosAuditEventBuilder extends 
AbstractKerberosAuditEventBuilder<ChangeSecurityStateKerberosAuditEvent, 
ChangeSecurityStateKerberosAuditEventBuilder> {
+
+    private String service;
+    private String component;
+    private String hostName;
+    private String state;
+
+    private ChangeSecurityStateKerberosAuditEventBuilder() {
+      this.withOperation("Security state change");
+    }
+
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+
+      builder
+        .append(", Hostname(")
+        .append(hostName)
+        .append("), Service(")
+        .append(service)
+        .append("), Component(")
+        .append(component)
+        .append("), State(")
+        .append(state)
+        .append(")");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected ChangeSecurityStateKerberosAuditEvent newAuditEvent() {
+      return new ChangeSecurityStateKerberosAuditEvent(this);
+    }
+
+    public ChangeSecurityStateKerberosAuditEventBuilder withService(String 
service) {
+      this.service = service;
+      return this;
+    }
+
+    public ChangeSecurityStateKerberosAuditEventBuilder withComponent(String 
component) {
+      this.component = component;
+      return this;
+    }
+
+    public ChangeSecurityStateKerberosAuditEventBuilder withHostName(String 
hostName) {
+      this.hostName = hostName;
+      return this;
+    }
+
+    public ChangeSecurityStateKerberosAuditEventBuilder withState(String 
state) {
+      this.state = state;
+      return this;
+    }
+  }
+
+  private ChangeSecurityStateKerberosAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  private 
ChangeSecurityStateKerberosAuditEvent(ChangeSecurityStateKerberosAuditEventBuilder
 builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link ChangeSecurityStateKerberosAuditEvent}
+   * @return a builder instance
+   */
+  public static ChangeSecurityStateKerberosAuditEventBuilder builder() {
+    return new ChangeSecurityStateKerberosAuditEventBuilder();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreateKeyTabKerberosAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreateKeyTabKerberosAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreateKeyTabKerberosAuditEvent.java
new file mode 100644
index 0000000..1c2d52b
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreateKeyTabKerberosAuditEvent.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.kerberos;
+
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class CreateKeyTabKerberosAuditEvent extends AbstractKerberosAuditEvent 
{
+
+  public static class CreateKeyTabKerberosAuditEventBuilder extends 
AbstractKerberosAuditEventBuilder<CreateKeyTabKerberosAuditEvent, 
CreateKeyTabKerberosAuditEventBuilder> {
+
+    private String keyTabFilePath;
+    private String hostName;
+    private String principal;
+
+    private CreateKeyTabKerberosAuditEventBuilder() {
+      this.withOperation("Keytab file creation");
+    }
+
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+
+      builder
+        .append(", Principal(")
+        .append(principal)
+        .append("), Hostname(")
+        .append(hostName)
+        .append("), Keytab file(")
+        .append(keyTabFilePath)
+        .append(")");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected CreateKeyTabKerberosAuditEvent newAuditEvent() {
+      return new CreateKeyTabKerberosAuditEvent(this);
+    }
+
+    public CreateKeyTabKerberosAuditEventBuilder withKeyTabFilePath(String 
keyTabFilePath) {
+      this.keyTabFilePath = keyTabFilePath;
+      return this;
+    }
+
+    public CreateKeyTabKerberosAuditEventBuilder withHostName(String hostName) 
{
+      this.hostName = hostName;
+      return this;
+    }
+
+    public CreateKeyTabKerberosAuditEventBuilder withPrincipal(String 
principal) {
+      this.principal = principal;
+      return this;
+    }
+
+    public boolean hasPrincipal() {
+      return principal != null;
+    }
+  }
+
+  private CreateKeyTabKerberosAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  private CreateKeyTabKerberosAuditEvent(CreateKeyTabKerberosAuditEventBuilder 
builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link CreateKeyTabKerberosAuditEvent}
+   * @return a builder instance
+   */
+  public static CreateKeyTabKerberosAuditEventBuilder builder() {
+    return new CreateKeyTabKerberosAuditEventBuilder();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreatePrincipalKerberosAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreatePrincipalKerberosAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreatePrincipalKerberosAuditEvent.java
new file mode 100644
index 0000000..82790ab
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/CreatePrincipalKerberosAuditEvent.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.kerberos;
+
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class CreatePrincipalKerberosAuditEvent extends 
AbstractKerberosAuditEvent {
+
+  public static class CreatePrincipalKerberosAuditEventBuilder extends 
AbstractKerberosAuditEventBuilder<CreatePrincipalKerberosAuditEvent, 
CreatePrincipalKerberosAuditEventBuilder> {
+
+    private String principal;
+
+    private CreatePrincipalKerberosAuditEventBuilder() {
+      this.withOperation("Principal creation");
+    }
+
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+      builder.append("), Principal(")
+        .append(principal);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected CreatePrincipalKerberosAuditEvent newAuditEvent() {
+      return new CreatePrincipalKerberosAuditEvent(this);
+    }
+
+    public CreatePrincipalKerberosAuditEventBuilder withPrincipal(String 
principal) {
+      this.principal = principal;
+      return this;
+    }
+  }
+
+  private CreatePrincipalKerberosAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  private 
CreatePrincipalKerberosAuditEvent(CreatePrincipalKerberosAuditEventBuilder 
builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link CreatePrincipalKerberosAuditEvent}
+   * @return a builder instance
+   */
+  public static CreatePrincipalKerberosAuditEventBuilder builder() {
+    return new CreatePrincipalKerberosAuditEventBuilder();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/DestroyPrincipalKerberosAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/DestroyPrincipalKerberosAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/DestroyPrincipalKerberosAuditEvent.java
new file mode 100644
index 0000000..911f82c
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/kerberos/DestroyPrincipalKerberosAuditEvent.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.kerberos;
+
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class DestroyPrincipalKerberosAuditEvent extends 
AbstractKerberosAuditEvent {
+
+  public static class DestroyPrincipalKerberosAuditEventBuilder extends 
AbstractKerberosAuditEventBuilder<DestroyPrincipalKerberosAuditEvent, 
DestroyPrincipalKerberosAuditEventBuilder> {
+
+    private String principal;
+
+    private DestroyPrincipalKerberosAuditEventBuilder() {
+      this.withOperation("Principal removal");
+    }
+
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+
+      builder.append("), Principal(")
+        .append(principal);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected DestroyPrincipalKerberosAuditEvent newAuditEvent() {
+      return new DestroyPrincipalKerberosAuditEvent(this);
+    }
+
+    public DestroyPrincipalKerberosAuditEventBuilder withPrincipal(String 
principal) {
+      this.principal = principal;
+      return this;
+    }
+  }
+
+  private DestroyPrincipalKerberosAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  private 
DestroyPrincipalKerberosAuditEvent(DestroyPrincipalKerberosAuditEventBuilder 
builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link DestroyPrincipalKerberosAuditEvent}
+   * @return a builder instance
+   */
+  public static DestroyPrincipalKerberosAuditEventBuilder builder() {
+    return new DestroyPrincipalKerberosAuditEventBuilder();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddCredentialRequestAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddCredentialRequestAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddCredentialRequestAuditEvent.java
new file mode 100644
index 0000000..780e2eb
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddCredentialRequestAuditEvent.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.request.event;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ambari.server.audit.request.RequestAuditEvent;
+
+public class AddCredentialRequestAuditEvent extends RequestAuditEvent {
+
+  public static class AddCredentialAuditEventBuilder extends 
RequestAuditEventBuilder<AddCredentialRequestAuditEvent, 
AddCredentialAuditEventBuilder> {
+
+    private String type;
+
+    private String clusterName;
+
+    private String principal;
+    
+    private String alias;
+
+    public AddCredentialAuditEventBuilder() {
+      super.withOperation("Credential addition");
+    }
+
+    @Override
+    protected AddCredentialRequestAuditEvent newAuditEvent() {
+      return new AddCredentialRequestAuditEvent(this);
+    }
+
+    /**
+     * Appends to the event the details of the incoming request.
+     * @param builder builder for the audit event details.
+     */
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+
+      builder.append(", Type(")
+        .append(type)
+        .append("), Principal(")
+        .append(principal)
+        .append("), Alias(")
+        .append(alias)
+        .append("), Cluster name(")
+        .append(clusterName)
+        .append(")");
+    }
+
+    public AddCredentialAuditEventBuilder withType(String type) {
+      this.type = type;
+      return this;
+    }
+
+    public AddCredentialAuditEventBuilder withClusterName(String clusterName) {
+      this.clusterName = clusterName;
+      return this;
+    }
+
+    public AddCredentialAuditEventBuilder withPrincipal(String principal) {
+      this.principal = principal;
+      return this;
+    }
+
+    public AddCredentialAuditEventBuilder withAlias(String alias) {
+      this.alias = alias;
+      return this;
+    }
+  }
+
+  protected AddCredentialRequestAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected AddCredentialRequestAuditEvent(AddCredentialAuditEventBuilder 
builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link AddCredentialRequestAuditEvent}
+   * @return a builder instance
+   */
+  public static AddCredentialAuditEventBuilder builder() {
+    return new AddCredentialAuditEventBuilder();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddRequestRequestAuditEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddRequestRequestAuditEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddRequestRequestAuditEvent.java
new file mode 100644
index 0000000..2332269
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/event/AddRequestRequestAuditEvent.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.request.event;
+
+import org.apache.ambari.server.audit.request.RequestAuditEvent;
+
+public class AddRequestRequestAuditEvent extends RequestAuditEvent {
+
+  public static class AddRequestAuditEventBuilder extends 
RequestAuditEventBuilder<AddRequestRequestAuditEvent, 
AddRequestAuditEventBuilder> {
+
+    private String command;
+
+    private String clusterName;
+
+    public AddRequestAuditEventBuilder() {
+      super.withOperation("Request from server");
+    }
+
+    @Override
+    protected AddRequestRequestAuditEvent newAuditEvent() {
+      return new AddRequestRequestAuditEvent(this);
+    }
+
+    /**
+     * Appends to the event the details of the incoming request.
+     * @param builder builder for the audit event details.
+     */
+    @Override
+    protected void buildAuditMessage(StringBuilder builder) {
+      super.buildAuditMessage(builder);
+
+      builder.append("), Command(")
+        .append(command)
+        .append("), Cluster name(")
+        .append(clusterName)
+        .append(")");
+    }
+
+    public AddRequestAuditEventBuilder withClusterName(String clusterName) {
+      this.clusterName = clusterName;
+      return this;
+    }
+
+    public AddRequestAuditEventBuilder withCommand(String command) {
+      this.command = command;
+      return this;
+    }
+  }
+
+  protected AddRequestRequestAuditEvent() {
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected AddRequestRequestAuditEvent(AddRequestAuditEventBuilder builder) {
+    super(builder);
+  }
+
+  /**
+   * Returns an builder for {@link AddRequestRequestAuditEvent}
+   * @return a builder instance
+   */
+  public static AddRequestAuditEventBuilder builder() {
+    return new AddRequestAuditEventBuilder();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
new file mode 100644
index 0000000..ed7c95d
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.request.eventcreator;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import 
org.apache.ambari.server.audit.request.event.AddCredentialRequestAuditEvent;
+import 
org.apache.ambari.server.audit.request.event.UpdateUpgradeItemRequestAuditEvent;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+/**
+ * This creator handles crednetial requests
+ * For resource type {@link Resource.Type#Upgrade}
+ * and request types {@link Request.Type#POST}
+ */
+public class CredentialEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = new HashSet<Request.Type>();
+
+  {
+    requestTypes.add(Request.Type.POST);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return Collections.singleton(Resource.Type.Credential);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    return AddCredentialRequestAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withRequestType(request.getRequestType())
+      .withResultStatus(result.getStatus())
+      .withUrl(request.getURI())
+      .withRemoteIp(request.getRemoteAddress())
+      .withUserName(username)
+      .withClusterName(getProperty(request, "cluster_name"))
+      .withType(getProperty(request, "type"))
+      .withAlias(getProperty(request, "alias"))
+      .withPrincipal(getProperty(request, "principal"))
+      .build();
+
+  }
+
+  private String getProperty(Request request, String propertyName) {
+    if(!request.getBody().getPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Credential",propertyName)));
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RequestEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RequestEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RequestEventCreator.java
new file mode 100644
index 0000000..d96edf2
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RequestEventCreator.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.audit.request.eventcreator;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.AuditEvent;
+import org.apache.ambari.server.audit.StartOperationFailedAuditEvent;
+import org.apache.ambari.server.audit.StartOperationSucceededAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import 
org.apache.ambari.server.audit.request.event.AddRequestRequestAuditEvent;
+import 
org.apache.ambari.server.audit.request.event.DeleteServiceRequestAuditEvent;
+import org.apache.ambari.server.controller.internal.RequestOperationLevel;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+/**
+ * This creator handles request type requests
+ * For resource type {@link Resource.Type#Request}
+ * and request types {@link Request.Type#POST}
+ */
+public class RequestEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = new HashSet<Request.Type>();
+
+  {
+    requestTypes.add(Request.Type.POST);
+  }
+
+  private Set<Resource.Type> resourceTypes = new HashSet<Resource.Type>();
+  {
+    resourceTypes.add(Resource.Type.Request);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    // null makes this default
+    return null;
+  }
+
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch(request.getRequestType()) {
+      case POST:
+        return AddRequestRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withCommand(request.getBody().getRequestInfoProperties().get("command"))
+          
.withClusterName(request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID))
+          .build();
+      default:
+        return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
index dff546c..6118dad 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
@@ -38,7 +38,7 @@ import org.springframework.security.core.userdetails.User;
 /**
  * This creator handles upgrade requests
  * For resource type {@link Resource.Type#Upgrade}
- * and request types {@link Request.Type#POST}
+ * and request types {@link Request.Type#PUT}
  */
 public class UpgradeItemEventCreator implements RequestAuditEventCreator {
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index a5dcdf2..9436e5d 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -104,6 +104,7 @@ import 
org.apache.ambari.server.security.ldap.AmbariLdapDataPopulator;
 import org.apache.ambari.server.security.unsecured.rest.CertificateDownload;
 import org.apache.ambari.server.security.unsecured.rest.CertificateSign;
 import org.apache.ambari.server.security.unsecured.rest.ConnectionInfo;
+import org.apache.ambari.server.serveraction.AbstractServerAction;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.topology.AmbariContext;
 import org.apache.ambari.server.topology.BlueprintFactory;
@@ -884,6 +885,8 @@ public class AmbariServer {
     LogoutService.init(injector.getInstance(AuditLogger.class));
 
     RetryHelper.init(configs.getOperationsRetryAttempts());
+
+    AbstractServerAction.init(injector);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index f489f54..74cd698 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -48,6 +48,7 @@ import 
org.apache.ambari.server.audit.request.eventcreator.AlertGroupEventCreato
 import 
org.apache.ambari.server.audit.request.eventcreator.AlertTargetEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.BlueprintEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.BlueprintExportEventCreator;
+import 
org.apache.ambari.server.audit.request.eventcreator.CredentialEventCreator;
 import org.apache.ambari.server.audit.request.eventcreator.HostEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.PrivilegeEventCreator;
 import org.apache.ambari.server.audit.request.eventcreator.GroupEventCreator;
@@ -55,6 +56,7 @@ import 
org.apache.ambari.server.audit.request.eventcreator.MemberEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.RecommendationIgnoreEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.RepositoryEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.RepositoryVersionEventCreator;
+import org.apache.ambari.server.audit.request.eventcreator.RequestEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.ServiceConfigDownloadEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.UnauthorizedEventCreator;
 import 
org.apache.ambari.server.audit.request.eventcreator.ConfigurationChangeEventCreator;
@@ -434,6 +436,8 @@ public class ControllerModule extends AbstractModule {
     auditLogEventCreatorBinder.addBinding().to(UpgradeItemEventCreator.class);
     
auditLogEventCreatorBinder.addBinding().to(RecommendationIgnoreEventCreator.class);
     
auditLogEventCreatorBinder.addBinding().to(ValidationIgnoreEventCreator.class);
+    auditLogEventCreatorBinder.addBinding().to(CredentialEventCreator.class);
+    auditLogEventCreatorBinder.addBinding().to(RequestEventCreator.class);
 
     bind(RequestAuditLogger.class).to(RequestAuditLoggerImpl.class);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/AbstractServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/AbstractServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/AbstractServerAction.java
index 33191bf..0fd530a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/AbstractServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/AbstractServerAction.java
@@ -24,11 +24,16 @@ import 
org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.audit.AuditEvent;
+import org.apache.ambari.server.audit.AuditLogger;
+import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.utils.StageUtils;
 
 import java.util.Collections;
 import java.util.Map;
 
+import com.google.inject.Injector;
+
 /**
  * AbstractServerActionImpl is an abstract implementation of a ServerAction.
  * <p/>
@@ -52,6 +57,22 @@ public abstract class AbstractServerAction implements 
ServerAction {
    */
   protected ActionLog actionLog = new ActionLog();
 
+  /**
+   * Guice injector
+   */
+  private static Injector injector;
+
+  /**
+   * Statically initialize the Injector
+   * <p/>
+   * This should only be used for unit tests.
+   *
+   * @param injector the Injector to (manually) statically inject
+   */
+  public static void init(Injector injector) {
+    AbstractServerAction.injector = injector;
+  }
+
   @Override
   public ExecutionCommand getExecutionCommand() {
     return this.executionCommand;
@@ -175,4 +196,8 @@ public abstract class AbstractServerAction implements 
ServerAction {
     return getConfigurations().get(configurationName);
   }
 
+  protected void auditLog(AuditEvent ae) {
+    injector.getInstance(AuditLogger.class).log(ae);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
index 8aa816d..1af0245 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
@@ -22,6 +22,8 @@ import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.audit.kerberos.AbstractKerberosAuditEvent;
+import org.apache.ambari.server.audit.kerberos.CreateKeyTabKerberosAuditEvent;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
@@ -31,6 +33,7 @@ import 
org.apache.ambari.server.orm.entities.KerberosPrincipalEntity;
 import org.apache.ambari.server.serveraction.ActionLog;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -147,138 +150,150 @@ public class CreateKeytabFilesServerAction extends 
KerberosServerAction {
                                           Map<String, String> 
kerberosConfiguration,
                                           Map<String, Object> 
requestSharedDataContext)
       throws AmbariException {
-    CommandReport commandReport = null;
 
-    if (identityRecord != null) {
-      String message;
-      String dataDirectory = getDataDirectoryPath();
-
-      if (operationHandler == null) {
-        message = String.format("Failed to create keytab file for %s, missing 
KerberosOperationHandler", evaluatedPrincipal);
-        actionLog.writeStdErr(message);
-        LOG.error(message);
-        commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", 
actionLog.getStdOut(), actionLog.getStdErr());
-      } else if (dataDirectory == null) {
-        message = "The data directory has not been set. Generated keytab files 
can not be stored.";
-        LOG.error(message);
-        commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", 
actionLog.getStdOut(), actionLog.getStdErr());
-      } else {
-        Map<String, String> principalPasswordMap = 
getPrincipalPasswordMap(requestSharedDataContext);
-        Map<String, Integer> principalKeyNumberMap = 
getPrincipalKeyNumberMap(requestSharedDataContext);
-
-        String hostName = 
identityRecord.get(KerberosIdentityDataFileReader.HOSTNAME);
-        String keytabFilePath = 
identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_PATH);
-
-        if ((hostName != null) && !hostName.isEmpty() && (keytabFilePath != 
null) && !keytabFilePath.isEmpty()) {
-          Set<String> visitedPrincipalKeys = 
visitedIdentities.get(evaluatedPrincipal);
-          String visitationKey = String.format("%s|%s", hostName, 
keytabFilePath);
-
-          if ((visitedPrincipalKeys == null) || 
!visitedPrincipalKeys.contains(visitationKey)) {
-            // Look up the current evaluatedPrincipal's password.
-            // If found create the keytab file, else try to find it in the 
cache.
-            String password = principalPasswordMap.get(evaluatedPrincipal);
-            Integer keyNumber = principalKeyNumberMap.get(evaluatedPrincipal);
-
-            message = String.format("Creating keytab file for %s on host %s", 
evaluatedPrincipal, hostName);
-            LOG.info(message);
-            actionLog.writeStdOut(message);
-
-            // Determine where to store the keytab file.  It should go into a 
host-specific
-            // directory under the previously determined data directory.
-            File hostDirectory = new File(dataDirectory, hostName);
-
-            // Ensure the host directory exists...
-            if (!hostDirectory.exists() && hostDirectory.mkdirs()) {
-              // Make sure only Ambari has access to this directory.
-              ensureAmbariOnlyAccess(hostDirectory);
-            }
 
-            if (hostDirectory.exists()) {
-              File destinationKeytabFile = new File(hostDirectory, 
DigestUtils.sha1Hex(keytabFilePath));
-              HostEntity hostEntity = hostDAO.findByName(hostName);
-              if (hostEntity == null) {
-                message = "Failed to find HostEntity for hostname = " + 
hostName;
-                actionLog.writeStdErr(message);
-                LOG.error(message);
-                commandReport = createCommandReport(1, HostRoleStatus.FAILED, 
"{}", actionLog.getStdOut(), actionLog.getStdErr());
-                return commandReport;
+    CreateKeyTabKerberosAuditEvent.CreateKeyTabKerberosAuditEventBuilder 
auditEventBuilder = 
CreateKeyTabKerberosAuditEvent.builder().withTimestamp(DateTime.now());
+    CommandReport commandReport = null;
+    String message = null;
+    try {
+      if (identityRecord != null) {
+        String dataDirectory = getDataDirectoryPath();
+
+        if (operationHandler == null) {
+          message = String.format("Failed to create keytab file for %s, 
missing KerberosOperationHandler", evaluatedPrincipal);
+          actionLog.writeStdErr(message);
+          LOG.error(message);
+          commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", 
actionLog.getStdOut(), actionLog.getStdErr());
+        } else if (dataDirectory == null) {
+          message = "The data directory has not been set. Generated keytab 
files can not be stored.";
+          LOG.error(message);
+          commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", 
actionLog.getStdOut(), actionLog.getStdErr());
+        } else {
+          Map<String, String> principalPasswordMap = 
getPrincipalPasswordMap(requestSharedDataContext);
+          Map<String, Integer> principalKeyNumberMap = 
getPrincipalKeyNumberMap(requestSharedDataContext);
+
+          String hostName = 
identityRecord.get(KerberosIdentityDataFileReader.HOSTNAME);
+          String keytabFilePath = 
identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_PATH);
+
+          if ((hostName != null) && !hostName.isEmpty() && (keytabFilePath != 
null) && !keytabFilePath.isEmpty()) {
+            Set<String> visitedPrincipalKeys = 
visitedIdentities.get(evaluatedPrincipal);
+            String visitationKey = String.format("%s|%s", hostName, 
keytabFilePath);
+
+            if ((visitedPrincipalKeys == null) || 
!visitedPrincipalKeys.contains(visitationKey)) {
+              // Look up the current evaluatedPrincipal's password.
+              // If found create the keytab file, else try to find it in the 
cache.
+              String password = principalPasswordMap.get(evaluatedPrincipal);
+              Integer keyNumber = 
principalKeyNumberMap.get(evaluatedPrincipal);
+
+              message = String.format("Creating keytab file for %s on host 
%s", evaluatedPrincipal, hostName);
+              LOG.info(message);
+              actionLog.writeStdOut(message);
+              
auditEventBuilder.withPrincipal(evaluatedPrincipal).withHostName(hostName).withKeyTabFilePath(keytabFilePath);
+
+              // Determine where to store the keytab file.  It should go into 
a host-specific
+              // directory under the previously determined data directory.
+              File hostDirectory = new File(dataDirectory, hostName);
+
+              // Ensure the host directory exists...
+              if (!hostDirectory.exists() && hostDirectory.mkdirs()) {
+                // Make sure only Ambari has access to this directory.
+                ensureAmbariOnlyAccess(hostDirectory);
               }
 
-              if (password == null) {
-                if (kerberosPrincipalHostDAO.exists(evaluatedPrincipal, 
hostEntity.getHostId())) {
-                  // There is nothing to do for this since it must already 
exist and we don't want to
-                  // regenerate the keytab
-                  message = String.format("Skipping keytab file for %s, 
missing password indicates nothing to do", evaluatedPrincipal);
-                  LOG.debug(message);
-                } else {
-                  KerberosPrincipalEntity principalEntity = 
kerberosPrincipalDAO.find(evaluatedPrincipal);
-                  String cachedKeytabPath = (principalEntity == null) ? null : 
principalEntity.getCachedKeytabPath();
+              if (hostDirectory.exists()) {
+                File destinationKeytabFile = new File(hostDirectory, 
DigestUtils.sha1Hex(keytabFilePath));
+                HostEntity hostEntity = hostDAO.findByName(hostName);
+                if (hostEntity == null) {
+                  message = "Failed to find HostEntity for hostname = " + 
hostName;
+                  actionLog.writeStdErr(message);
+                  LOG.error(message);
+                  commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+                  return commandReport;
+                }
 
-                  if (cachedKeytabPath == null) {
-                    message = String.format("Failed to create keytab for %s, 
missing cached file", evaluatedPrincipal);
-                    actionLog.writeStdErr(message);
-                    LOG.error(message);
-                    commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+                if (password == null) {
+                  if (kerberosPrincipalHostDAO.exists(evaluatedPrincipal, 
hostEntity.getHostId())) {
+                    // There is nothing to do for this since it must already 
exist and we don't want to
+                    // regenerate the keytab
+                    message = String.format("Skipping keytab file for %s, 
missing password indicates nothing to do", evaluatedPrincipal);
+                    LOG.debug(message);
                   } else {
-                    try {
-                      operationHandler.createKeytabFile(new 
File(cachedKeytabPath), destinationKeytabFile);
-                    } catch (KerberosOperationException e) {
-                      message = String.format("Failed to create keytab file 
for %s - %s", evaluatedPrincipal, e.getMessage());
+                    KerberosPrincipalEntity principalEntity = 
kerberosPrincipalDAO.find(evaluatedPrincipal);
+                    String cachedKeytabPath = (principalEntity == null) ? null 
: principalEntity.getCachedKeytabPath();
+
+                    if (cachedKeytabPath == null) {
+                      message = String.format("Failed to create keytab for %s, 
missing cached file", evaluatedPrincipal);
                       actionLog.writeStdErr(message);
-                      LOG.error(message, e);
+                      LOG.error(message);
                       commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+                    } else {
+                      try {
+                        operationHandler.createKeytabFile(new 
File(cachedKeytabPath), destinationKeytabFile);
+                      } catch (KerberosOperationException e) {
+                        message = String.format("Failed to create keytab file 
for %s - %s", evaluatedPrincipal, e.getMessage());
+                        actionLog.writeStdErr(message);
+                        LOG.error(message, e);
+                        commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+                      }
                     }
                   }
-                }
-              } else {
-                boolean canCache = 
("true".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_IS_CACHABLE)));
-
-                Keytab keytab = createKeytab(evaluatedPrincipal, password, 
keyNumber, operationHandler, visitedPrincipalKeys != null, canCache, actionLog);
+                } else {
+                  boolean canCache = 
("true".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_IS_CACHABLE)));
 
-                if (keytab != null) {
-                  try {
-                    if (operationHandler.createKeytabFile(keytab, 
destinationKeytabFile)) {
-                      ensureAmbariOnlyAccess(destinationKeytabFile);
+                  Keytab keytab = createKeytab(evaluatedPrincipal, password, 
keyNumber, operationHandler, visitedPrincipalKeys != null, canCache, actionLog);
 
-                      message = String.format("Successfully created keytab 
file for %s at %s", evaluatedPrincipal, 
destinationKeytabFile.getAbsolutePath());
-                      LOG.debug(message);
-                    } else {
-                      message = String.format("Failed to create keytab file 
for %s at %s", evaluatedPrincipal, destinationKeytabFile.getAbsolutePath());
+                  if (keytab != null) {
+                    try {
+                      if (operationHandler.createKeytabFile(keytab, 
destinationKeytabFile)) {
+                        ensureAmbariOnlyAccess(destinationKeytabFile);
+
+                        message = String.format("Successfully created keytab 
file for %s at %s", evaluatedPrincipal, 
destinationKeytabFile.getAbsolutePath());
+                        LOG.debug(message);
+                        
auditEventBuilder.withPrincipal(evaluatedPrincipal).withHostName(hostName).withKeyTabFilePath(destinationKeytabFile.getAbsolutePath());
+                      } else {
+                        message = String.format("Failed to create keytab file 
for %s at %s", evaluatedPrincipal, destinationKeytabFile.getAbsolutePath());
+                        actionLog.writeStdErr(message);
+                        LOG.error(message);
+                        commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+                      }
+                    } catch (KerberosOperationException e) {
+                      message = String.format("Failed to create keytab file 
for %s - %s", evaluatedPrincipal, e.getMessage());
                       actionLog.writeStdErr(message);
-                      LOG.error(message);
+                      LOG.error(message, e);
                       commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
                     }
-                  } catch (KerberosOperationException e) {
-                    message = String.format("Failed to create keytab file for 
%s - %s", evaluatedPrincipal, e.getMessage());
-                    actionLog.writeStdErr(message);
-                    LOG.error(message, e);
+                  } else {
                     commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
                   }
-                } else {
-                  commandReport = createCommandReport(1, 
HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
-                }
 
-                if (visitedPrincipalKeys == null) {
-                  visitedPrincipalKeys = new HashSet<String>();
-                  visitedIdentities.put(evaluatedPrincipal, 
visitedPrincipalKeys);
-                }
+                  if (visitedPrincipalKeys == null) {
+                    visitedPrincipalKeys = new HashSet<String>();
+                    visitedIdentities.put(evaluatedPrincipal, 
visitedPrincipalKeys);
+                  }
 
-                visitedPrincipalKeys.add(visitationKey);
+                  visitedPrincipalKeys.add(visitationKey);
+                }
+              } else {
+                message = String.format("Failed to create keytab file for %s, 
the container directory does not exist: %s",
+                  evaluatedPrincipal, hostDirectory.getAbsolutePath());
+                actionLog.writeStdErr(message);
+                LOG.error(message);
+                commandReport = createCommandReport(1, HostRoleStatus.FAILED, 
"{}", actionLog.getStdOut(), actionLog.getStdErr());
               }
             } else {
-              message = String.format("Failed to create keytab file for %s, 
the container directory does not exist: %s",
-                  evaluatedPrincipal, hostDirectory.getAbsolutePath());
-              actionLog.writeStdErr(message);
-              LOG.error(message);
-              commandReport = createCommandReport(1, HostRoleStatus.FAILED, 
"{}", actionLog.getStdOut(), actionLog.getStdErr());
+              LOG.debug(String.format("Skipping previously processed keytab 
for %s on host %s", evaluatedPrincipal, hostName));
             }
-          } else {
-            LOG.debug(String.format("Skipping previously processed keytab for 
%s on host %s", evaluatedPrincipal, hostName));
           }
         }
       }
+    } finally {
+      if(commandReport != null && 
HostRoleStatus.FAILED.toString().equals(commandReport.getStatus())) {
+        auditEventBuilder.withReasonOfFailure(message == null ? "Unknown 
error" : message);
+      }
+      if(commandReport != null || auditEventBuilder.hasPrincipal()) {
+        auditLog(auditEventBuilder.build());
+      }
     }
-
     return commandReport;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
index 8009ae1..09df299 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
@@ -22,12 +22,14 @@ import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
+import 
org.apache.ambari.server.audit.kerberos.CreatePrincipalKerberosAuditEvent;
 import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
 import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
 import org.apache.ambari.server.orm.entities.KerberosPrincipalEntity;
 import org.apache.ambari.server.security.SecurePasswordHelper;
 import org.apache.ambari.server.serveraction.ActionLog;
 import org.apache.commons.lang.StringUtils;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -173,92 +175,103 @@ public class CreatePrincipalsServerAction extends 
KerberosServerAction {
                                                Map<String, String> 
kerberosConfiguration,
                                                KerberosOperationHandler 
kerberosOperationHandler,
                                                ActionLog actionLog) {
+    CreatePrincipalKerberosAuditEvent.CreatePrincipalKerberosAuditEventBuilder 
auditEventBuilder = CreatePrincipalKerberosAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withPrincipal(principal);
     CreatePrincipalResult result = null;
+    String message = null;
+    try {
 
-    String message = String.format("Creating principal, %s", principal);
-    LOG.info(message);
-    if (actionLog != null) {
-      actionLog.writeStdOut(message);
-    }
-
-    Integer length;
-    Integer minLowercaseLetters;
-    Integer minUppercaseLetters;
-    Integer minDigits;
-    Integer minPunctuation;
-    Integer minWhitespace;
-
-    if (kerberosConfiguration == null) {
-      length = null;
-      minLowercaseLetters = null;
-      minUppercaseLetters = null;
-      minDigits = null;
-      minPunctuation = null;
-      minWhitespace = null;
-    } else {
-      length = toInt(kerberosConfiguration.get("password_length"));
-      minLowercaseLetters = 
toInt(kerberosConfiguration.get("password_min_lowercase_letters"));
-      minUppercaseLetters = 
toInt(kerberosConfiguration.get("password_min_uppercase_letters"));
-      minDigits = toInt(kerberosConfiguration.get("password_min_digits"));
-      minPunctuation = 
toInt(kerberosConfiguration.get("password_min_punctuation"));
-      minWhitespace = 
toInt(kerberosConfiguration.get("password_min_whitespace"));
-    }
-
-    String password = securePasswordHelper.createSecurePassword(length, 
minLowercaseLetters, minUppercaseLetters, minDigits, minPunctuation, 
minWhitespace);
+      message = String.format("Creating principal, %s", principal);
+      LOG.info(message);
+      if (actionLog != null) {
+        actionLog.writeStdOut(message);
+      }
 
-    try {
+      Integer length;
+      Integer minLowercaseLetters;
+      Integer minUppercaseLetters;
+      Integer minDigits;
+      Integer minPunctuation;
+      Integer minWhitespace;
+
+      if (kerberosConfiguration == null) {
+        length = null;
+        minLowercaseLetters = null;
+        minUppercaseLetters = null;
+        minDigits = null;
+        minPunctuation = null;
+        minWhitespace = null;
+      } else {
+        length = toInt(kerberosConfiguration.get("password_length"));
+        minLowercaseLetters = 
toInt(kerberosConfiguration.get("password_min_lowercase_letters"));
+        minUppercaseLetters = 
toInt(kerberosConfiguration.get("password_min_uppercase_letters"));
+        minDigits = toInt(kerberosConfiguration.get("password_min_digits"));
+        minPunctuation = 
toInt(kerberosConfiguration.get("password_min_punctuation"));
+        minWhitespace = 
toInt(kerberosConfiguration.get("password_min_whitespace"));
+      }
 
-      if (kerberosOperationHandler.principalExists(principal)) {
-        // Create a new password since we need to know what it is.
-        // A new password/key would have been generated after exporting the 
keytab anyways.
-        message = String.format("Principal, %s, already exists, setting new 
password", principal);
-        LOG.warn(message);
-        if (actionLog != null) {
-          actionLog.writeStdOut(message);
-        }
+      String password = securePasswordHelper.createSecurePassword(length, 
minLowercaseLetters, minUppercaseLetters, minDigits, minPunctuation, 
minWhitespace);
 
-        Integer keyNumber = 
kerberosOperationHandler.setPrincipalPassword(principal, password);
+      try {
 
-        if (keyNumber != null) {
-          result = new CreatePrincipalResult(principal, password, keyNumber);
-          message = String.format("Successfully set password for %s", 
principal);
-          LOG.debug(message);
-        } else {
-          message = String.format("Failed to set password for %s - unknown 
reason", principal);
-          LOG.error(message);
+        if (kerberosOperationHandler.principalExists(principal)) {
+          // Create a new password since we need to know what it is.
+          // A new password/key would have been generated after exporting the 
keytab anyways.
+          message = String.format("Principal, %s, already exists, setting new 
password", principal);
+          LOG.warn(message);
           if (actionLog != null) {
-            actionLog.writeStdErr(message);
+            actionLog.writeStdOut(message);
           }
-        }
-      } else {
-        message = String.format("Creating new principal, %s", principal);
-        LOG.debug(message);
 
-        Integer keyNumber = 
kerberosOperationHandler.createPrincipal(principal, password, 
isServicePrincipal);
-
-        if (keyNumber != null) {
-          result = new CreatePrincipalResult(principal, password, keyNumber);
-          message = String.format("Successfully created new principal, %s", 
principal);
-          LOG.debug(message);
+          Integer keyNumber = 
kerberosOperationHandler.setPrincipalPassword(principal, password);
+
+          if (keyNumber != null) {
+            result = new CreatePrincipalResult(principal, password, keyNumber);
+            message = String.format("Successfully set password for %s", 
principal);
+            LOG.debug(message);
+          } else {
+            message = String.format("Failed to set password for %s - unknown 
reason", principal);
+            LOG.error(message);
+            if (actionLog != null) {
+              actionLog.writeStdErr(message);
+            }
+          }
         } else {
-          message = String.format("Failed to create principal, %s - unknown 
reason", principal);
-          LOG.error(message);
-          if (actionLog != null) {
-            actionLog.writeStdErr(message);
+          message = String.format("Creating new principal, %s", principal);
+          LOG.debug(message);
+
+          Integer keyNumber = 
kerberosOperationHandler.createPrincipal(principal, password, 
isServicePrincipal);
+
+          if (keyNumber != null) {
+            result = new CreatePrincipalResult(principal, password, keyNumber);
+            message = String.format("Successfully created new principal, %s", 
principal);
+            LOG.debug(message);
+          } else {
+            message = String.format("Failed to create principal, %s - unknown 
reason", principal);
+            LOG.error(message);
+            if (actionLog != null) {
+              actionLog.writeStdErr(message);
+            }
           }
         }
-      }
 
-      if (!kerberosPrincipalDAO.exists(principal)) {
-        kerberosPrincipalDAO.create(principal, isServicePrincipal);
-      }
+        if (!kerberosPrincipalDAO.exists(principal)) {
+          kerberosPrincipalDAO.create(principal, isServicePrincipal);
+        }
 
-    } catch (KerberosOperationException e) {
-      message = String.format("Failed to create principal, %s - %s", 
principal, e.getMessage());
-      LOG.error(message, e);
-      if (actionLog != null) {
-        actionLog.writeStdErr(message);
+      } catch (KerberosOperationException e) {
+        message = String.format("Failed to create principal, %s - %s", 
principal, e.getMessage());
+        LOG.error(message, e);
+        if (actionLog != null) {
+          actionLog.writeStdErr(message);
+        }
+      }
+    } finally {
+      if(result == null) {
+        auditEventBuilder.withReasonOfFailure(message == null ? "Unknown 
error" : message);
       }
+      auditLog(auditEventBuilder.build());
     }
 
     return result;

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
index 93daae8..ce46af4 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
@@ -21,8 +21,10 @@ package org.apache.ambari.server.serveraction.kerberos;
 import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.agent.CommandReport;
+import 
org.apache.ambari.server.audit.kerberos.DestroyPrincipalKerberosAuditEvent;
 import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
 import org.apache.ambari.server.orm.entities.KerberosPrincipalEntity;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -89,35 +91,44 @@ public class DestroyPrincipalsServerAction extends 
KerberosServerAction {
     String message = String.format("Destroying identity, %s", 
evaluatedPrincipal);
     LOG.info(message);
     actionLog.writeStdOut(message);
+    
DestroyPrincipalKerberosAuditEvent.DestroyPrincipalKerberosAuditEventBuilder 
auditEventBuilder = DestroyPrincipalKerberosAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withPrincipal(evaluatedPrincipal);
 
     try {
-      operationHandler.removePrincipal(evaluatedPrincipal);
-    } catch (KerberosOperationException e) {
-      message = String.format("Failed to remove identity for %s from the KDC - 
%s", evaluatedPrincipal, e.getMessage());
-      LOG.warn(message);
-      actionLog.writeStdErr(message);
-    }
 
-    try {
-      KerberosPrincipalEntity principalEntity = 
kerberosPrincipalDAO.find(evaluatedPrincipal);
+      try {
+        operationHandler.removePrincipal(evaluatedPrincipal);
+      } catch (KerberosOperationException e) {
+        message = String.format("Failed to remove identity for %s from the KDC 
- %s", evaluatedPrincipal, e.getMessage());
+        LOG.warn(message);
+        actionLog.writeStdErr(message);
+        auditEventBuilder.withReasonOfFailure(message);
+      }
 
-      if(principalEntity != null) {
-        String cachedKeytabPath = principalEntity.getCachedKeytabPath();
+      try {
+        KerberosPrincipalEntity principalEntity = 
kerberosPrincipalDAO.find(evaluatedPrincipal);
 
-        kerberosPrincipalDAO.remove(principalEntity);
+        if (principalEntity != null) {
+          String cachedKeytabPath = principalEntity.getCachedKeytabPath();
 
-        // If a cached  keytabs file exists for this principal, delete it.
-        if (cachedKeytabPath != null) {
-          if (!new File(cachedKeytabPath).delete()) {
-            LOG.debug(String.format("Failed to remove cached keytab for %s", 
evaluatedPrincipal));
+          kerberosPrincipalDAO.remove(principalEntity);
+
+          // If a cached  keytabs file exists for this principal, delete it.
+          if (cachedKeytabPath != null) {
+            if (!new File(cachedKeytabPath).delete()) {
+              LOG.debug(String.format("Failed to remove cached keytab for %s", 
evaluatedPrincipal));
+            }
           }
         }
+      } catch (Throwable t) {
+        message = String.format("Failed to remove identity for %s from the 
Ambari database - %s", evaluatedPrincipal, t.getMessage());
+        LOG.warn(message);
+        actionLog.writeStdErr(message);
+        auditEventBuilder.withReasonOfFailure(message);
       }
-    }
-    catch (Throwable t) {
-      message = String.format("Failed to remove identity for %s from the 
Ambari database - %s", evaluatedPrincipal, t.getMessage());
-      LOG.warn(message);
-      actionLog.writeStdErr(message);
+    } finally {
+      auditLog(auditEventBuilder.build());
     }
 
     // There is no reason to fail this task if an identity was not removed. 
The cluster will work

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerAction.java
index c710b8e..55b1fbb 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerAction.java
@@ -21,11 +21,13 @@ package org.apache.ambari.server.serveraction.kerberos;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
+import 
org.apache.ambari.server.audit.kerberos.ChangeSecurityStateKerberosAuditEvent;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.commons.io.FileUtils;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,6 +93,14 @@ public class FinalizeKerberosServerAction extends 
KerberosServerAction {
             actionLog.writeStdOut(message);
 
             sch.setSecurityState(sch.getDesiredSecurityState());
+            ChangeSecurityStateKerberosAuditEvent auditEvent = 
ChangeSecurityStateKerberosAuditEvent.builder()
+              .withTimestamp(DateTime.now())
+              .withService(sch.getServiceName())
+              .withComponent(sch.getServiceComponentName())
+              .withHostName(sch.getHostName())
+              .withState(sch.getDesiredSecurityState().toString())
+              .build();
+            auditLog(auditEvent);
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a885ef5a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
index 90d9414..6ff6069 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.server.serveraction.kerberos;
 
 import com.google.inject.Inject;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;

Reply via email to