You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by st...@apache.org on 2016/03/30 21:51:17 UTC
[3/7] ambari git commit: AMBARI-15241. Basic Operational Audit
Logging. (Daniel Gergely via stoader)
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
new file mode 100644
index 0000000..6b7bb2b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator ignores recommendation post requests
+ * For resource type {@link Resource.Type#Recommendation}
+ * and request types {@link Request.Type#POST}
+ */
+public class RecommendationIgnoreEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Recommendation).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ // intentionally skipping this event
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
new file mode 100644
index 0000000..fe6f8cc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
@@ -0,0 +1,132 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.AddRepositoryRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.UpdateRepositoryRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles privilege requests
+ * For resource type {@link Resource.Type#Repository}
+ * and request types {@link Request.Type#POST} and {@link Request.Type#PUT}
+ */
+public class RepositoryEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Repository).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ switch (request.getRequestType()) {
+ case POST:
+ return AddRepositoryRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withRepo(getProperty(request, PropertyHelper.getPropertyId("Repositories", "repo_id")))
+ .withStackName(getProperty(request, PropertyHelper.getPropertyId("Repositories", "stack_name")))
+ .withStackVersion(getProperty(request, PropertyHelper.getPropertyId("Repositories", "stack_version")))
+ .withOsType(getProperty(request, PropertyHelper.getPropertyId("Repositories", "os_type")))
+ .withBaseUrl(getProperty(request, PropertyHelper.getPropertyId("Repositories", "base_url")))
+ .build();
+ case PUT:
+ return UpdateRepositoryRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withRepo(getProperty(request, PropertyHelper.getPropertyId("Repositories", "repo_id")))
+ .withStackName(getProperty(request, PropertyHelper.getPropertyId("Repositories", "stack_name")))
+ .withStackVersion(getProperty(request, PropertyHelper.getPropertyId("Repositories", "stack_version")))
+ .withOsType(getProperty(request, PropertyHelper.getPropertyId("Repositories", "os_type")))
+ .withBaseUrl(getProperty(request, PropertyHelper.getPropertyId("Repositories", "base_url")))
+ .build();
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns a property from the request based on the propertyId parameter
+ * @param request
+ * @param properyId
+ * @return
+ */
+ private String getProperty(Request request, String properyId) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(properyId));
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryVersionEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryVersionEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryVersionEventCreator.java
new file mode 100644
index 0000000..7c9c731
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryVersionEventCreator.java
@@ -0,0 +1,215 @@
+/*
+ * 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.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.AddRepositoryVersionRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.ChangeRepositoryVersionRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.DeleteRepositoryVersionRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles privilege requests
+ * For resource type {@link Resource.Type#Repository}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and {@link Request.Type#DELETE}
+ */
+public class RepositoryVersionEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, Request.Type.DELETE).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.RepositoryVersion).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ switch (request.getRequestType()) {
+ case POST:
+ return AddRepositoryVersionRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withStackName(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "stack_name")))
+ .withStackVersion(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "stack_version")))
+ .withDisplayName(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "display_name")))
+ .withRepoVersion(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "repository_version")))
+ .withRepos(getRepos(request))
+ .build();
+ case PUT:
+ return ChangeRepositoryVersionRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withStackName(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "stack_name")))
+ .withStackVersion(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "stack_version")))
+ .withDisplayName(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "display_name")))
+ .withRepoVersion(getProperty(request, PropertyHelper.getPropertyId("RepositoryVersions", "repository_version")))
+ .withRepos(getRepos(request))
+ .build();
+ case DELETE:
+ return DeleteRepositoryVersionRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withStackName(request.getResource().getKeyValueMap().get(Resource.Type.Stack))
+ .withStackVersion(request.getResource().getKeyValueMap().get(Resource.Type.StackVersion))
+ .withRepoVersion(request.getResource().getKeyValueMap().get(Resource.Type.RepositoryVersion))
+ .build();
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Assembles repositories from the request
+ * operating system -> list of repositories where the repository is a map of properties (repo_id, repo_name, base_url)
+ * @param request
+ * @return a map of repositories
+ */
+ private Map<String, List<Map<String, String>>> getRepos(Request request) {
+
+ Map<String, List<Map<String, String>>> result = new HashMap<String, List<Map<String, String>>>();
+
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ if (request.getBody().getPropertySets().iterator().next().get("operating_systems") instanceof Set) {
+ Set<Object> set = (Set<Object>) request.getBody().getPropertySets().iterator().next().get("operating_systems");
+
+ result = createResultForOperationSystems(set);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns repos for the set of operating systems
+ * @param set
+ * @return
+ */
+ private Map<String, List<Map<String, String>>> createResultForOperationSystems(Set<Object> set) {
+ Map<String, List<Map<String, String>>> result = new HashMap<String, List<Map<String, String>>>();
+ for (Object entry : set) {
+ if (entry instanceof Map) {
+ Map<String, Object> map = (Map<String, Object>) entry;
+ String osType = (String) map.get(PropertyHelper.getPropertyId("OperatingSystems", "os_type"));
+ if (!result.containsKey(osType)) {
+ result.put(osType, new LinkedList<Map<String, String>>());
+ }
+ if (map.get("repositories") instanceof Set) {
+ Set<Object> repos = (Set<Object>) map.get("repositories");
+ for (Object repo : repos) {
+ if (repo instanceof Map) {
+ Map<String, String> resultMap = buildResultRepo((Map<String, String>) repo);
+ result.get(osType).add(resultMap);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns a map with the repository properties (repo_id, repo_name, base_url)
+ * @param repo
+ * @return
+ */
+ private Map<String, String> buildResultRepo(Map<String, String> repo) {
+ Map<String, String> m = repo;
+ String repoId = m.get(PropertyHelper.getPropertyId("Repositories", "repo_id"));
+ String repo_name = m.get(PropertyHelper.getPropertyId("Repositories", "repo_name"));
+ String baseUrl = m.get(PropertyHelper.getPropertyId("Repositories", "base_url"));
+ Map<String, String> resultMap = new HashMap<>();
+ resultMap.put("repo_id", repoId);
+ resultMap.put("repo_name", repo_name);
+ resultMap.put("base_url", baseUrl);
+ return resultMap;
+ }
+
+ /**
+ * Returns property from the request based on the propertyId parameter
+ * @param request
+ * @param properyId
+ * @return
+ */
+ private String getProperty(Request request, String properyId) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(properyId));
+ }
+ return null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/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..fd13973
--- /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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.AddRequestRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.internal.RequestOperationLevel;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * 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 = ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Request).build();
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @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(System.currentTimeMillis())
+ .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/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceConfigDownloadEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceConfigDownloadEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceConfigDownloadEventCreator.java
new file mode 100644
index 0000000..681cfb8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceConfigDownloadEventCreator.java
@@ -0,0 +1,92 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.ClientConfigDownloadRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles service config download requests
+ * For resource type {@link Resource.Type#Service}
+ * and request types {@link Request.Type#GET}
+ */
+public class ServiceConfigDownloadEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.GET).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.ClientConfig).build();
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+ return ClientConfigDownloadRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withService(request.getResource().getKeyValueMap().get(Resource.Type.Service))
+ .withComponent(request.getResource().getKeyValueMap().get(Resource.Type.Component))
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceEventCreator.java
new file mode 100644
index 0000000..2e2b91d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ServiceEventCreator.java
@@ -0,0 +1,179 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.DeleteServiceRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.StartOperationRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+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.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles operation requests (start, stop, install, etc)
+ * For resource type {@link Resource.Type#Service}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and {@link Request.Type#DELETE}
+ */
+public class ServiceEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, Request.Type.DELETE).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Service).build();
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ if (request.getRequestType() == Request.Type.DELETE) {
+ return DeleteServiceRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withService(request.getResource().getKeyValueMap().get(Resource.Type.Service))
+ .build();
+ }
+
+ String operation = getOperation(request);
+
+ Long requestId = null;
+ if (containsRequestId(result)) {
+ requestId = getRequestId(result);
+ }
+
+ StartOperationRequestAuditEvent.StartOperationAuditEventBuilder auditEventBuilder = StartOperationRequestAuditEvent.builder()
+ .withOperation(operation)
+ .withUserName(username)
+ .withRemoteIp(request.getRemoteAddress())
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestId(String.valueOf(requestId));
+
+ if (result.getStatus().isErrorState()) {
+ auditEventBuilder.withReasonOfFailure(result.getStatus().getMessage());
+ }
+
+ return auditEventBuilder.build();
+ }
+
+ /**
+ * Generates operation name based on the request. It checks the operation level, the host name, the service name, the status
+ * and whether this is a maintenance mode switch change.
+ * @param request
+ * @return
+ */
+ private String getOperation(Request request) {
+ if (request.getBody().getRequestInfoProperties().containsKey(RequestOperationLevel.OPERATION_LEVEL_ID)) {
+ String operation = "";
+ if ("CLUSTER".equals(request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_LEVEL_ID))) {
+ for (Map<String, Object> map : request.getBody().getPropertySets()) {
+ if (map.containsKey(PropertyHelper.getPropertyId("ServiceInfo", "state"))) {
+ operation = String.valueOf(map.get(PropertyHelper.getPropertyId("ServiceInfo", "state"))) + ": all services"
+ + " (" + request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID) + ")";
+ break;
+ }
+ }
+ }
+ if ("SERVICE".equals(request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_LEVEL_ID))) {
+ for (Map<String, Object> map : request.getBody().getPropertySets()) {
+ if (map.containsKey(PropertyHelper.getPropertyId("ServiceInfo", "state"))) {
+ operation = String.valueOf(map.get(PropertyHelper.getPropertyId("ServiceInfo", "state"))) + ": " + map.get(PropertyHelper.getPropertyId("ServiceInfo", "service_name"))
+ + " (" + request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID) + ")";
+ break;
+ }
+ }
+ }
+ return operation;
+ }
+
+ for (Map<String, Object> map : request.getBody().getPropertySets()) {
+ if (map.containsKey(PropertyHelper.getPropertyId("ServiceInfo", "maintenance_state"))) {
+ return "Turn " + map.get(PropertyHelper.getPropertyId("ServiceInfo", "maintenance_state")) + " Maintenance Mode for " + map.get(PropertyHelper.getPropertyId("ServiceInfo", "service_name"));
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns request id from the result
+ * @param result
+ * @return
+ */
+ private Long getRequestId(Result result) {
+ return (Long) result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests").get("id");
+ }
+
+ /**
+ * Checks if request id can be found in the result
+ * @param result
+ * @return
+ */
+ private boolean containsRequestId(Result result) {
+ return result.getResultTree().getChild("request") != null
+ && result.getResultTree().getChild("request").getObject() != null
+ && result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests") != null
+ && result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests").get("id") != null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UnauthorizedEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UnauthorizedEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UnauthorizedEventCreator.java
new file mode 100644
index 0000000..d53aa68
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UnauthorizedEventCreator.java
@@ -0,0 +1,86 @@
+/*
+ * 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.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.event.AccessUnauthorizedAuditEvent;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles unauthorized actions
+ * For result status {@link ResultStatus.STATUS#UNAUTHORIZED} and {@link ResultStatus.STATUS#FORBIDDEN}
+ */
+public class UnauthorizedEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<ResultStatus.STATUS> statuses = ImmutableSet.<ResultStatus.STATUS>builder().add(ResultStatus.STATUS.UNAUTHORIZED, ResultStatus.STATUS.FORBIDDEN).build();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Request.Type> getRequestTypes() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Resource.Type> getResourceTypes() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<ResultStatus.STATUS> getResultStatuses() {
+ return statuses;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+ AccessUnauthorizedAuditEvent ae = AccessUnauthorizedAuditEvent.builder()
+ .withRemoteIp(request.getRemoteAddress())
+ .withResourcePath(request.getURI())
+ .withTimestamp(System.currentTimeMillis())
+ .withUserName(username)
+ .build();
+
+ return ae;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
new file mode 100644
index 0000000..b8a6873
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeEventCreator.java
@@ -0,0 +1,110 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.AddUpgradeRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles upgrade requests
+ * For resource type {@link Resource.Type#Upgrade}
+ * and request types {@link Request.Type#POST}
+ */
+public class UpgradeEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Upgrade).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ return AddUpgradeRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withRepositoryVersion(getProperty(request, "repository_version"))
+ .withUpgradeType(getProperty(request, "upgrade_type"))
+ .withClusterName(getProperty(request, "cluster_name"))
+ .build();
+
+ }
+
+ /**
+ * Returns property from the request based on the propertyName parameter
+ * @param request
+ * @param propertyName
+ * @return
+ */
+ private String getProperty(Request request, String propertyName) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Upgrade", propertyName)));
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/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
new file mode 100644
index 0000000..9f83172
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UpgradeItemEventCreator.java
@@ -0,0 +1,110 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.UpdateUpgradeItemRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles upgrade requests
+ * For resource type {@link Resource.Type#Upgrade}
+ * and request types {@link Request.Type#PUT}
+ */
+public class UpgradeItemEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.UpgradeItem).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ return UpdateUpgradeItemRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withStatus(getProperty(request, "status"))
+ .withStageId(getProperty(request, "stage_id"))
+ .withRequestId(getProperty(request, "request_id"))
+ .build();
+
+ }
+
+ /**
+ * Returns property from the request based on the propertyName parameter
+ * @param request
+ * @param propertyName
+ * @return
+ */
+ private String getProperty(Request request, String propertyName) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("UpgradeItem", propertyName)));
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UserEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UserEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UserEventCreator.java
new file mode 100644
index 0000000..2b4e5c1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/UserEventCreator.java
@@ -0,0 +1,211 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.ActivateUserRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.AdminUserRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.CreateUserRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.DeleteUserRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.UserPasswordChangeRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles user requests
+ * For resource type {@link Resource.Type#User}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and {@link Request.Type#DELETE}
+ */
+public class UserEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, Request.Type.DELETE).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.User).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ switch (request.getRequestType()) {
+ case POST:
+ return CreateUserRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withCreatedUsername(getUsername(request))
+ .withActive(isActive(request))
+ .withAdmin(isAdmin(request))
+ .build();
+ case DELETE:
+ return DeleteUserRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withDeletedUsername(request.getResource().getKeyValueMap().get(Resource.Type.User))
+ .build();
+ case PUT:
+ if (hasActive(request)) {
+ return ActivateUserRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withAffectedUsername(getUsername(request))
+ .withActive(isActive(request))
+ .build();
+ }
+ if (hasAdmin(request)) {
+ return AdminUserRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withAffectedUsername(getUsername(request))
+ .withAdmin(isAdmin(request))
+ .build();
+ }
+ if (hasOldPassword(request)) {
+ return UserPasswordChangeRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withAffectedUsername(getUsername(request))
+ .build();
+ }
+ default:
+ break;
+ }
+ return null;
+ }
+
+
+ /**
+ * Returns fromt he request if the user has admin rights
+ * @param request
+ * @return
+ */
+ private boolean isAdmin(Request request) {
+ return hasAdmin(request) && "true".equals(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Users", "admin")));
+ }
+
+ /**
+ * Returns from the request if the user is active
+ * @param request
+ * @return
+ */
+ private boolean isActive(Request request) {
+ return hasActive(request) && "true".equals(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Users", "active")));
+ }
+
+ /**
+ * Returns if the request contains admin property
+ * @param request
+ * @return
+ */
+ private boolean hasAdmin(Request request) {
+ return !request.getBody().getPropertySets().isEmpty() && request.getBody().getPropertySets().iterator().next().containsKey(PropertyHelper.getPropertyId("Users", "admin"));
+ }
+
+ /**
+ * Returns if the request contains active property
+ * @param request
+ * @return
+ */
+ private boolean hasActive(Request request) {
+ return !request.getBody().getPropertySets().isEmpty() && request.getBody().getPropertySets().iterator().next().containsKey(PropertyHelper.getPropertyId("Users", "active"));
+ }
+
+ /**
+ * Returns if the request contains old password field
+ * @param request
+ * @return
+ */
+ private boolean hasOldPassword(Request request) {
+ return !request.getBody().getPropertySets().isEmpty() && request.getBody().getPropertySets().iterator().next().containsKey(PropertyHelper.getPropertyId("Users", "old_password"));
+ }
+
+ /**
+ * Returns the username from the request
+ * @param request
+ * @return
+ */
+ private String getUsername(Request request) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Users", "user_name")));
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ValidationIgnoreEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ValidationIgnoreEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ValidationIgnoreEventCreator.java
new file mode 100644
index 0000000..081f3d3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ValidationIgnoreEventCreator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator ignores validation post requests
+ * For resource type {@link Resource.Type#Validation}
+ * and request types {@link Request.Type#POST}
+ */
+public class ValidationIgnoreEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.Validation).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ // intentionally skipping this event
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewInstanceEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewInstanceEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewInstanceEventCreator.java
new file mode 100644
index 0000000..611b1ea
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewInstanceEventCreator.java
@@ -0,0 +1,149 @@
+/*
+ * 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.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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.AddViewInstanceRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.ChangeViewInstanceRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.DeleteViewInstanceRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles view instance requests
+ * For resource type {@link Resource.Type#ViewInstance}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and {@link Request.Type#DELETE}
+ */
+public class ViewInstanceEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, Request.Type.DELETE).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.ViewInstance).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+ switch (request.getRequestType()) {
+
+ case POST:
+ return AddViewInstanceRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withType(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "view_name")))
+ .withVersion(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "version")))
+ .withName(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "instance_name")))
+ .withDisplayName(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "label")))
+ .withDescription(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "description")))
+ .build();
+
+ case PUT:
+ return ChangeViewInstanceRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withType(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "view_name")))
+ .withVersion(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "version")))
+ .withName(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "instance_name")))
+ .withDisplayName(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "label")))
+ .withDescription(getProperty(request, PropertyHelper.getPropertyId("ViewInstanceInfo", "description")))
+ .build();
+
+ case DELETE:
+ return DeleteViewInstanceRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withType(request.getResource().getKeyValueMap().get(Resource.Type.View))
+ .withVersion(request.getResource().getKeyValueMap().get(Resource.Type.ViewVersion))
+ .withName(request.getResource().getKeyValueMap().get(Resource.Type.ViewInstance))
+ .build();
+
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns property from the requet based on the propertyId parameter
+ * @param request
+ * @param properyId
+ * @return
+ */
+ private String getProperty(Request request, String properyId) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(properyId));
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewPrivilegeEventCreator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewPrivilegeEventCreator.java b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewPrivilegeEventCreator.java
new file mode 100644
index 0000000..18b860a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ViewPrivilegeEventCreator.java
@@ -0,0 +1,145 @@
+/*
+ * 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.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+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.event.AuditEvent;
+import org.apache.ambari.server.audit.event.request.ViewPrivilegeChangeRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles view privilege requests
+ * For resource type {@link Resource.Type#ViewInstance}
+ * and request types {@link Request.Type#PUT}
+ */
+public class ViewPrivilegeEventCreator implements RequestAuditEventCreator {
+
+ /**
+ * Set of {@link Request.Type}s that are handled by this plugin
+ */
+ private Set<Request.Type> requestTypes = ImmutableSet.<Request.Type>builder().add(Request.Type.PUT).build();
+
+ /**
+ * Set of {@link Resource.Type}s that are handled by this plugin
+ */
+ private Set<Resource.Type> resourceTypes = ImmutableSet.<Resource.Type>builder().add(Resource.Type.ViewPrivilege).build();
+
+ /**
+ * {@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() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AuditEvent createAuditEvent(Request request, Result result) {
+ String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+
+ Map<String, List<String>> users = getEntities(request, "USER");
+ Map<String, List<String>> groups = getEntities(request, "GROUP");
+
+ return ViewPrivilegeChangeRequestAuditEvent.builder()
+ .withTimestamp(System.currentTimeMillis())
+ .withRequestType(request.getRequestType())
+ .withResultStatus(result.getStatus())
+ .withUrl(request.getURI())
+ .withRemoteIp(request.getRemoteAddress())
+ .withUserName(username)
+ .withType(getProperty(request, PropertyHelper.getPropertyId("PrivilegeInfo", "view_name")))
+ .withVersion(getProperty(request, PropertyHelper.getPropertyId("PrivilegeInfo", "version")))
+ .withName(getProperty(request, PropertyHelper.getPropertyId("PrivilegeInfo", "instance_name")))
+ .withUsers(users)
+ .withGroups(groups)
+ .build();
+
+ }
+
+ /**
+ * Returns property from the request based on the propertyId parameter
+ * @param request
+ * @param properyId
+ * @return
+ */
+ private String getProperty(Request request, String properyId) {
+ if (!request.getBody().getPropertySets().isEmpty()) {
+ return String.valueOf(request.getBody().getPropertySets().iterator().next().get(properyId));
+ }
+ return null;
+ }
+
+ /**
+ * Assembles entities from the request. The result can contain users or groups based on the value of type parameter
+ * @param request
+ * @param type
+ * @return a map of role -> [user|group] names
+ */
+ private Map<String, List<String>> getEntities(final Request request, final String type) {
+ Map<String, List<String>> entities = new HashMap<String, List<String>>();
+
+ for (Map<String, Object> propertyMap : request.getBody().getPropertySets()) {
+ String ptype = String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", "principal_type")));
+ if (type.equals(ptype)) {
+ String role = String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", "permission_name")));
+ String name = String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", "principal_name")));
+ if (!entities.containsKey(role)) {
+ entities.put(role, new LinkedList<String>());
+ }
+
+ entities.get(role).add(name);
+ }
+ }
+ return entities;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 0302b6e..7767fb2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -676,6 +676,17 @@ public class Configuration {
"custom.oracle.jdbc.name", "custom.postgres.jdbc.name", "custom.mssql.jdbc.name", "custom.hsqldb.jdbc.name",
"custom.sqlanywhere.jdbc.name"));
+ /**
+ * Main switch for audit log feature
+ */
+ private static final String AUDIT_LOG_ENABLED = "auditlog.enabled";
+
+ /**
+ * Audit logger capacity
+ */
+ private static final String AUDIT_LOGGER_CAPACITY = "auditlog.logger.capacity";
+ private static final int AUDIT_LOGGER_CAPACITY_DEFAULT = 10000;
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
@@ -2840,4 +2851,17 @@ public class Configuration {
public String isAgentStackRetryOnInstallEnabled(){
return properties.getProperty(AGENT_STACK_RETRY_ON_REPO_UNAVAILABILITY_KEY, AGENT_STACK_RETRY_ON_REPO_UNAVAILABILITY_DEFAULT);
}
+
+ public boolean isAuditLogEnabled() {
+ return Boolean.parseBoolean(properties.getProperty(AUDIT_LOG_ENABLED,Boolean.TRUE.toString()));
+ }
+
+ /**
+ * @return the capacity of async audit logger
+ */
+ public int getAuditLoggerCapacity() {
+ return NumberUtils.toInt(
+ properties.getProperty(AUDIT_LOGGER_CAPACITY),
+ AUDIT_LOGGER_CAPACITY_DEFAULT);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/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 4b769e3..5802f08 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
@@ -44,11 +44,17 @@ import org.apache.ambari.server.api.MethodOverrideFilter;
import org.apache.ambari.server.api.UserNameOverrideFilter;
import org.apache.ambari.server.api.rest.BootStrapResource;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.BaseService;
import org.apache.ambari.server.api.services.KeyService;
+import org.apache.ambari.server.api.services.LogoutService;
import org.apache.ambari.server.api.services.PersistKeyValueImpl;
import org.apache.ambari.server.api.services.PersistKeyValueService;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorBlueprintProcessor;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorHelper;
+import org.apache.ambari.server.audit.AuditLogger;
+import org.apache.ambari.server.audit.request.RequestAuditLogger;
+import org.apache.ambari.server.audit.AuditLoggerModule;
+import org.apache.ambari.server.security.authentication.AmbariAuthenticationFilter;
import org.apache.ambari.server.bootstrap.BootStrapImpl;
import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
import org.apache.ambari.server.configuration.Configuration;
@@ -92,6 +98,8 @@ import org.apache.ambari.server.security.SecurityFilter;
import org.apache.ambari.server.security.authorization.AmbariAuthorizationFilter;
import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsService;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.PermissionHelper;
import org.apache.ambari.server.security.authorization.Users;
import org.apache.ambari.server.security.authorization.internal.AmbariInternalAuthenticationProvider;
import org.apache.ambari.server.security.authorization.jwt.JwtAuthenticationFilter;
@@ -99,6 +107,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;
@@ -294,19 +303,25 @@ public class AmbariServer {
factory.registerSingleton("guiceInjector", injector);
factory.registerSingleton("passwordEncoder",
- injector.getInstance(PasswordEncoder.class));
+ injector.getInstance(PasswordEncoder.class));
+ factory.registerSingleton("auditLogger",
+ injector.getInstance(AuditLogger.class));
+ factory.registerSingleton("permissionHelper",
+ injector.getInstance(PermissionHelper.class));
factory.registerSingleton("ambariLocalUserService",
- injector.getInstance(AmbariLocalUserDetailsService.class));
+ injector.getInstance(AmbariLocalUserDetailsService.class));
factory.registerSingleton("ambariLdapAuthenticationProvider",
- injector.getInstance(AmbariLdapAuthenticationProvider.class));
+ injector.getInstance(AmbariLdapAuthenticationProvider.class));
factory.registerSingleton("ambariLdapDataPopulator",
- injector.getInstance(AmbariLdapDataPopulator.class));
+ injector.getInstance(AmbariLdapDataPopulator.class));
factory.registerSingleton("ambariAuthorizationFilter",
- injector.getInstance(AmbariAuthorizationFilter.class));
+ injector.getInstance(AmbariAuthorizationFilter.class));
factory.registerSingleton("ambariInternalAuthenticationProvider",
- injector.getInstance(AmbariInternalAuthenticationProvider.class));
+ injector.getInstance(AmbariInternalAuthenticationProvider.class));
factory.registerSingleton("ambariJwtAuthenticationFilter",
- injector.getInstance(JwtAuthenticationFilter.class));
+ injector.getInstance(JwtAuthenticationFilter.class));
+ factory.registerSingleton("ambariAuthenticationFilter",
+ injector.getInstance(AmbariAuthenticationFilter.class));
// Spring Security xml config depends on this Bean
String[] contextLocations = {SPRING_CONTEXT_LOCATION};
@@ -698,9 +713,9 @@ public class AmbariServer {
}
LOG.info(
- "Jetty is configuring {} with {} reserved acceptors/selectors and a total pool size of {} for {} processors.",
- threadPoolName, acceptorThreads * 2, configuredThreadPoolSize,
- Runtime.getRuntime().availableProcessors());
+ "Jetty is configuring {} with {} reserved acceptors/selectors and a total pool size of {} for {} processors.",
+ threadPoolName, acceptorThreads * 2, configuredThreadPoolSize,
+ Runtime.getRuntime().availableProcessors());
final QueuedThreadPool qtp = server.getBean(QueuedThreadPool.class);
qtp.setName(threadPoolName);
@@ -843,7 +858,7 @@ public class AmbariServer {
StageUtils.setGson(injector.getInstance(Gson.class));
StageUtils.setTopologyManager(injector.getInstance(TopologyManager.class));
WorkflowJsonService.setDBProperties(
- injector.getInstance(Configuration.class));
+ injector.getInstance(Configuration.class));
SecurityFilter.init(injector.getInstance(Configuration.class));
StackDefinedPropertyProvider.init(injector);
AbstractControllerResourceProvider.init(injector.getInstance(ResourceProviderFactory.class));
@@ -872,6 +887,8 @@ public class AmbariServer {
StackAdvisorBlueprintProcessor.init(injector.getInstance(StackAdvisorHelper.class));
ThreadPoolEnabledPropertyProvider.init(injector.getInstance(Configuration.class));
+ BaseService.init(injector.getInstance(RequestAuditLogger.class));
+
RetryHelper.init(configs.getOperationsRetryAttempts());
}
@@ -909,7 +926,7 @@ public class AmbariServer {
}
public static void main(String[] args) throws Exception {
- Injector injector = Guice.createInjector(new ControllerModule());
+ Injector injector = Guice.createInjector(new ControllerModule(), new AuditLoggerModule());
AmbariServer server = null;
try {
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/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 daca64d..91d6b4d 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
@@ -377,7 +377,6 @@ public class ControllerModule extends AbstractModule {
registerUpgradeChecks();
}
-
// ----- helper methods ----------------------------------------------------
private PersistModule buildJpaPersistModule() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/46a34ccd/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
index 985e9ad..3a86aef 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java
@@ -376,7 +376,7 @@ public class CalculatedStatus {
*
* @return summary request status based on statuses of tasks in different states.
*/
- private static HostRoleStatus calculateSummaryStatusOfStage(Map<HostRoleStatus, Integer> counters,
+ public static HostRoleStatus calculateSummaryStatusOfStage(Map<HostRoleStatus, Integer> counters,
int total, boolean skippable) {
if (counters.get(HostRoleStatus.PENDING) == total) {
return HostRoleStatus.PENDING;