You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by db...@apache.org on 2016/06/14 10:14:36 UTC
ambari git commit: AMBARI-17162. View config- Allows remote cluster
creation using a user having no permissions on the cluster. (Gaurav Nagar via
dipayanb)
Repository: ambari
Updated Branches:
refs/heads/branch-2.4 92dbf64ca -> 4cb2ba5d1
AMBARI-17162. View config- Allows remote cluster creation using a user having no permissions on the cluster. (Gaurav Nagar via dipayanb)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4cb2ba5d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4cb2ba5d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4cb2ba5d
Branch: refs/heads/branch-2.4
Commit: 4cb2ba5d1567f8b83843481394f122ae44d62358
Parents: 92dbf64
Author: Dipayan Bhowmick <di...@gmail.com>
Authored: Tue Jun 14 15:44:14 2016 +0530
Committer: Dipayan Bhowmick <di...@gmail.com>
Committed: Tue Jun 14 15:44:14 2016 +0530
----------------------------------------------------------------------
.../ambari/server/view/RemoteAmbariCluster.java | 115 ++++++++++++++-----
.../view/RemoteAmbariClusterRegistry.java | 14 ++-
.../apache/ambari/server/view/ViewRegistry.java | 7 +-
.../server/view/RemoteAmbariClusterTest.java | 16 +--
4 files changed, 110 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/4cb2ba5d/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java
index 1135424..6a4f04a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java
@@ -32,6 +32,8 @@ import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -44,10 +46,31 @@ import java.util.concurrent.TimeUnit;
*/
public class RemoteAmbariCluster implements Cluster {
+ public static final String AMBARI_OR_CLUSTER_ADMIN = "/api/v1/users/%s?privileges/PrivilegeInfo/permission_name=AMBARI.ADMINISTRATOR|" +
+ "(privileges/PrivilegeInfo/permission_name=CLUSTER.ADMINISTRATOR&privileges/PrivilegeInfo/cluster_name=%s)";
+
+ /**
+ * Name of the remote Ambari Cluster
+ */
private String name;
+ /**
+ * StreamProvider for the remote cluster
+ * Base path will be http://host:port
+ */
private AmbariStreamProvider streamProvider;
+ /**
+ * Path for the cluster.
+ * Value will be like : /api/v1/clusters/clusterName
+ */
+ private String clusterPath;
+
+ /**
+ * User for the cluster
+ */
+ private String username;
+
private final LoadingCache<String, JsonElement> configurationCache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.SECONDS)
.build(new CacheLoader<String, JsonElement>() {
@@ -63,16 +86,29 @@ public class RemoteAmbariCluster implements Cluster {
*
* @param remoteAmbariClusterEntity
*/
- public RemoteAmbariCluster(RemoteAmbariClusterEntity remoteAmbariClusterEntity, Configuration config) {
- String [] urlSplit = remoteAmbariClusterEntity.getUrl().split("/");
+ public RemoteAmbariCluster(RemoteAmbariClusterEntity remoteAmbariClusterEntity, Configuration config) throws MalformedURLException {
+
+ this.name = getClusterName(remoteAmbariClusterEntity);
+ this.username = remoteAmbariClusterEntity.getUsername();
+
+ URL url = new URL(remoteAmbariClusterEntity.getUrl());
+
+ String portString = url.getPort() == -1 ? "" : ":" + url.getPort();
+ String baseUrl = url.getProtocol() + "://" + url.getHost() + portString;
+
+ this.clusterPath = url.getPath();
+
+ this.streamProvider = new RemoteAmbariStreamProvider(
+ baseUrl, remoteAmbariClusterEntity.getUsername(),
+ remoteAmbariClusterEntity.getPassword(), config.getRequestConnectTimeout(), config.getRequestReadTimeout());
+ }
+
+ private String getClusterName(RemoteAmbariClusterEntity remoteAmbariClusterEntity) {
+ String[] urlSplit = remoteAmbariClusterEntity.getUrl().split("/");
// remoteAmbariClusterEntity.getName() is not the actual name of Remote Cluster
// We need to extract the name from cluster url which is like. http://host:port/api/vi/clusters/${clusterName}
- this.name = urlSplit[urlSplit.length -1];
-
- this.streamProvider = new RemoteAmbariStreamProvider(
- remoteAmbariClusterEntity.getUrl(), remoteAmbariClusterEntity.getUsername(),
- remoteAmbariClusterEntity.getPassword(),config.getRequestConnectTimeout(),config.getRequestReadTimeout());
+ return urlSplit[urlSplit.length - 1];
}
/**
@@ -81,8 +117,9 @@ public class RemoteAmbariCluster implements Cluster {
* @param name
* @param streamProvider
*/
- public RemoteAmbariCluster(String name, AmbariStreamProvider streamProvider) {
+ public RemoteAmbariCluster(String name, String clusterPath, AmbariStreamProvider streamProvider) {
this.name = name;
+ this.clusterPath = clusterPath;
this.streamProvider = streamProvider;
}
@@ -96,45 +133,45 @@ public class RemoteAmbariCluster implements Cluster {
JsonElement config = null;
try {
String desiredTag = getDesiredConfig(type);
- if(desiredTag != null){
- config = configurationCache.get(String.format("/configurations?(type=%s&tag=%s)", type, desiredTag));
+ if (desiredTag != null) {
+ config = configurationCache.get(String.format("%s/configurations?(type=%s&tag=%s)",this.clusterPath, type, desiredTag));
}
} catch (ExecutionException e) {
throw new RemoteAmbariConfigurationReadException("Can't retrieve configuration from Remote Ambari", e);
}
- if(config == null || !config.isJsonObject()) return null;
+ if (config == null || !config.isJsonObject()) return null;
JsonElement items = config.getAsJsonObject().get("items");
- if(items == null || !items.isJsonArray()) return null;
+ if (items == null || !items.isJsonArray()) return null;
JsonElement item = items.getAsJsonArray().get(0);
- if(item == null || !item.isJsonObject()) return null;
+ if (item == null || !item.isJsonObject()) return null;
JsonElement properties = item.getAsJsonObject().get("properties");
- if(properties == null || !properties.isJsonObject()) return null;
+ if (properties == null || !properties.isJsonObject()) return null;
JsonElement property = properties.getAsJsonObject().get(key);
- if(property == null || !property.isJsonPrimitive()) return null;
+ if (property == null || !property.isJsonPrimitive()) return null;
return property.getAsJsonPrimitive().getAsString();
}
@Override
public List<String> getHostsForServiceComponent(String serviceName, String componentName) {
- String url = String.format("services/%s/components/%s?" +
- "fields=host_components/HostRoles/host_name",serviceName,componentName);
+ String url = String.format("%s/services/%s/components/%s?" +
+ "fields=host_components/HostRoles/host_name", this.clusterPath, serviceName, componentName);
List<String> hosts = new ArrayList<String>();
try {
JsonElement response = configurationCache.get(url);
- if(response == null || !response.isJsonObject()) return hosts;
+ if (response == null || !response.isJsonObject()) return hosts;
JsonElement hostComponents = response.getAsJsonObject().get("host_components");
- if(hostComponents == null || !hostComponents.isJsonArray()) return hosts;
+ if (hostComponents == null || !hostComponents.isJsonArray()) return hosts;
for (JsonElement element : hostComponents.getAsJsonArray()) {
JsonElement hostRoles = element.getAsJsonObject().get("HostRoles");
@@ -156,15 +193,15 @@ public class RemoteAmbariCluster implements Cluster {
*/
public Set<String> getServices() throws IOException, AmbariHttpException {
Set<String> services = new HashSet<String>();
- String path = "?fields=services/ServiceInfo/service_name";
+ String path = this.clusterPath + "?fields=services/ServiceInfo/service_name";
JsonElement config = configurationCache.getUnchecked(path);
- if(config != null && config.isJsonObject()){
+ if (config != null && config.isJsonObject()) {
JsonElement items = config.getAsJsonObject().get("services");
- if(items != null && items.isJsonArray()){
+ if (items != null && items.isJsonArray()) {
for (JsonElement item : items.getAsJsonArray()) {
- JsonElement serviceInfo = item.getAsJsonObject().get("ServiceInfo");
- if(serviceInfo != null && serviceInfo.isJsonObject()){
+ JsonElement serviceInfo = item.getAsJsonObject().get("ServiceInfo");
+ if (serviceInfo != null && serviceInfo.isJsonObject()) {
String serviceName = serviceInfo.getAsJsonObject().get("service_name").getAsString();
services.add(serviceName);
}
@@ -175,6 +212,22 @@ public class RemoteAmbariCluster implements Cluster {
return services;
}
+ public boolean isAmbariOrClusterAdmin() throws AmbariHttpException {
+
+ if (username == null) return false;
+
+ String url = String.format(AMBARI_OR_CLUSTER_ADMIN, username, name);
+ JsonElement response = configurationCache.getUnchecked(url);
+
+ if (response != null && response.isJsonObject()) {
+ JsonElement privileges = response.getAsJsonObject().get("privileges");
+ if (privileges != null && privileges.isJsonArray()) {
+ if (privileges.getAsJsonArray().size() > 0) return true;
+ }
+ }
+ return false;
+ }
+
/**
* Get the current tag for the config type
*
@@ -183,21 +236,21 @@ public class RemoteAmbariCluster implements Cluster {
* @throws ExecutionException
*/
private String getDesiredConfig(String type) throws ExecutionException {
- JsonElement desiredConfigResponse = configurationCache.get("?fields=services/ServiceInfo,hosts,Clusters");
+ JsonElement desiredConfigResponse = configurationCache.get(this.clusterPath +"?fields=services/ServiceInfo,hosts,Clusters");
- if(desiredConfigResponse == null || !desiredConfigResponse.isJsonObject()) return null;
+ if (desiredConfigResponse == null || !desiredConfigResponse.isJsonObject()) return null;
JsonElement clusters = desiredConfigResponse.getAsJsonObject().get("Clusters");
- if(clusters == null || !clusters.isJsonObject()) return null;
+ if (clusters == null || !clusters.isJsonObject()) return null;
JsonElement desiredConfig = clusters.getAsJsonObject().get("desired_configs");
- if(desiredConfig == null || !desiredConfig.isJsonObject()) return null;
+ if (desiredConfig == null || !desiredConfig.isJsonObject()) return null;
JsonElement desiredConfigForType = desiredConfig.getAsJsonObject().get(type);
- if(desiredConfigForType == null || !desiredConfigForType.isJsonObject()) return null;
+ if (desiredConfigForType == null || !desiredConfigForType.isJsonObject()) return null;
JsonElement typeJson = desiredConfigForType.getAsJsonObject().get("tag");
- if( typeJson == null || !(typeJson.isJsonPrimitive())) return null;
+ if (typeJson == null || !(typeJson.isJsonPrimitive())) return null;
return typeJson.getAsJsonPrimitive().getAsString();
}
@@ -211,7 +264,7 @@ public class RemoteAmbariCluster implements Cluster {
* @throws AmbariHttpException
*/
private JsonElement readFromUrlJSON(String url) throws IOException, AmbariHttpException {
- InputStream inputStream = streamProvider.readFrom(url, "GET", (String)null, null);
+ InputStream inputStream = streamProvider.readFrom(url, "GET", (String) null, null);
String response = IOUtils.toString(inputStream);
return new JsonParser().parse(response);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4cb2ba5d/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
index fb59485..5e168ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.view;
+import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.orm.dao.RemoteAmbariClusterDAO;
import org.apache.ambari.server.orm.entities.RemoteAmbariClusterEntity;
@@ -27,6 +28,7 @@ import org.apache.ambari.view.AmbariHttpException;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
@@ -46,7 +48,7 @@ public class RemoteAmbariClusterRegistry {
@Inject
private Configuration configuration;
- public RemoteAmbariCluster get(Long clusterId) {
+ public RemoteAmbariCluster get(Long clusterId) throws MalformedURLException {
RemoteAmbariCluster remoteAmbariCluster = clusterMap.get(clusterId);
if (remoteAmbariCluster == null) {
RemoteAmbariCluster cluster = getCluster(clusterId);
@@ -58,7 +60,7 @@ public class RemoteAmbariClusterRegistry {
}
- private RemoteAmbariCluster getCluster(Long clusterId) {
+ private RemoteAmbariCluster getCluster(Long clusterId) throws MalformedURLException {
RemoteAmbariClusterEntity remoteAmbariClusterEntity = remoteAmbariClusterDAO.findById(clusterId);
RemoteAmbariCluster remoteAmbariCluster = new RemoteAmbariCluster(remoteAmbariClusterEntity, configuration);
return remoteAmbariCluster;
@@ -93,8 +95,14 @@ public class RemoteAmbariClusterRegistry {
* @throws AmbariHttpException
*/
public void saveOrUpdate(RemoteAmbariClusterEntity entity, boolean update) throws IOException, AmbariHttpException {
- RemoteAmbariCluster cluster = new RemoteAmbariCluster(entity,configuration);
+
+ RemoteAmbariCluster cluster = new RemoteAmbariCluster(entity, configuration);
Set<String> services = cluster.getServices();
+
+ if (!cluster.isAmbariOrClusterAdmin()) {
+ throw new AmbariException("User must be Ambari or Cluster Adminstrator.");
+ }
+
Collection<RemoteAmbariClusterServiceEntity> serviceEntities = new ArrayList<RemoteAmbariClusterServiceEntity>();
for (String service : services) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/4cb2ba5d/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
index 90144e2..9760c28 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -113,6 +113,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.Collection;
@@ -936,7 +937,11 @@ public class ViewRegistry {
LOG.warn("Could not find the cluster identified by " + clusterId + ".");
}
} else if(clusterId != null && viewInstance.getClusterType() == ClusterType.REMOTE_AMBARI){
- return remoteAmbariClusterRegistry.get(clusterId);
+ try {
+ return remoteAmbariClusterRegistry.get(clusterId);
+ } catch (MalformedURLException e) {
+ LOG.warn("Cannot get Remote Cluster ." + e.getMessage() ,e);
+ }
}
}
return null;
http://git-wip-us.apache.org/repos/asf/ambari/blob/4cb2ba5d/ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java
index 2b6e014..0e76cc8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java
@@ -57,8 +57,9 @@ public class RemoteAmbariClusterTest {
final String configurationString = "{\"items\": [{\"properties\": {\"test.property.name\": \"test property value\"}}]}";
final int[] desiredConfigPolls = {0};
final int[] testConfigPolls = {0};
+ final String clusterPath = "/api/v1/clusters/Test";
- expect(clusterStreamProvider.readFrom(eq( "?fields=services/ServiceInfo,hosts,Clusters"),
+ expect(clusterStreamProvider.readFrom(eq( clusterPath + "?fields=services/ServiceInfo,hosts,Clusters"),
eq("GET"), (String) isNull(), (Map<String, String>) anyObject())).andAnswer(new IAnswer<InputStream>() {
@Override
public InputStream answer() throws Throwable {
@@ -67,7 +68,7 @@ public class RemoteAmbariClusterTest {
}
}).anyTimes();
- expect(clusterStreamProvider.readFrom(eq( "/configurations?(type=test-site&tag=TAG)"),
+ expect(clusterStreamProvider.readFrom(eq(clusterPath + "/configurations?(type=test-site&tag=TAG)"),
eq("GET"), (String)isNull(), (Map<String, String>) anyObject())).andAnswer(new IAnswer<InputStream>() {
@Override
public InputStream answer() throws Throwable {
@@ -80,7 +81,7 @@ public class RemoteAmbariClusterTest {
replay(clusterStreamProvider,entity);
- RemoteAmbariCluster cluster = new RemoteAmbariCluster("Test", clusterStreamProvider);
+ RemoteAmbariCluster cluster = new RemoteAmbariCluster("Test", clusterPath, clusterStreamProvider);
String value = cluster.getConfigurationValue("test-site", "test.property.name");
assertEquals(value, "test property value");
@@ -108,9 +109,10 @@ public class RemoteAmbariClusterTest {
String service = "SERVICE";
String component = "COMPONENT";
+ final String clusterPath = "/api/v1/clusters/Test";
- expect(clusterStreamProvider.readFrom(eq(String.format("services/%s/components/%s?" +
- "fields=host_components/HostRoles/host_name",service,component)),
+ expect(clusterStreamProvider.readFrom(eq(String.format("%s/services/%s/components/%s?" +
+ "fields=host_components/HostRoles/host_name", clusterPath, service, component)),
eq("GET"), (String) isNull(), (Map<String, String>) anyObject()))
.andReturn(new ByteArrayInputStream(componentHostsString.getBytes()));
@@ -118,7 +120,7 @@ public class RemoteAmbariClusterTest {
replay(clusterStreamProvider,entity);
- RemoteAmbariCluster cluster = new RemoteAmbariCluster("Test", clusterStreamProvider);
+ RemoteAmbariCluster cluster = new RemoteAmbariCluster("Test", clusterPath, clusterStreamProvider);
List<String> hosts = cluster.getHostsForServiceComponent(service,component);
Assert.assertEquals(2, hosts.size());
@@ -128,4 +130,4 @@ public class RemoteAmbariClusterTest {
verify(clusterStreamProvider, entity);
}
-}
\ No newline at end of file
+}