Repository: incubator-brooklyn Updated Branches: refs/heads/master 5bb7cc693 -> 841db6a25
Adds mongoDB authentication Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1d0e2548 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1d0e2548 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1d0e2548 Branch: refs/heads/master Commit: 1d0e2548cc9b5a5ddf81138c4753c5e915644129 Parents: 07ec193 Author: Martin Harris <[email protected]> Authored: Fri Aug 14 14:13:55 2015 +0100 Committer: Martin Harris <[email protected]> Committed: Mon Sep 14 16:36:21 2015 +0100 ---------------------------------------------------------------------- .../hello-world-sql/src/main/webapp/mongo.jsp | 12 ++- software/nosql/pom.xml | 1 + .../nosql/mongodb/AbstractMongoDBServer.java | 3 +- .../nosql/mongodb/AbstractMongoDBSshDriver.java | 81 ++++++++++++++++---- .../mongodb/MongoDBAuthenticationMixins.java | 51 ++++++++++++ .../mongodb/MongoDBAuthenticationUtils.java | 79 +++++++++++++++++++ .../nosql/mongodb/MongoDBClientSupport.java | 26 +++++-- .../entity/nosql/mongodb/MongoDBReplicaSet.java | 2 +- .../nosql/mongodb/MongoDBReplicaSetImpl.java | 8 +- .../entity/nosql/mongodb/MongoDBServerImpl.java | 1 - .../sharding/CoLocatedMongoDBRouterImpl.java | 44 ++++++++--- .../sharding/MongoDBRouterSshDriver.java | 4 + .../sharding/MongoDBShardedDeploymentImpl.java | 40 +++++++--- .../nosql/src/test/resources/mongodb-keyfile | 16 ++++ .../resources/mongo-sharded-authentication.yaml | 45 +++++++++++ .../src/test/resources/mongo-sharded.yaml | 6 +- usage/launcher/src/test/resources/mongo.key | 16 ++++ .../apache/brooklyn/util/ssh/BashCommands.java | 7 ++ 18 files changed, 392 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp ---------------------------------------------------------------------- diff --git a/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp b/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp index 50a9a68..7e110cc 100644 --- a/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp +++ b/examples/webapps/hello-world-sql/src/main/webapp/mongo.jsp @@ -1,4 +1,5 @@ <%@ page language="java" import="java.sql.*,com.mongodb.*"%> +<%@ page import="java.util.Arrays" %> <html> <!-- @@ -39,6 +40,9 @@ <% String port=System.getProperty("brooklyn.example.mongodb.port"); +String username=System.getProperty("brooklyn.example.mongodb.username"); +String password=System.getProperty("brooklyn.example.mongodb.password"); +String authenticationDatabase=System.getProperty("brooklyn.example.mongodb.authenticationDatabase"); //URL should be supplied e.g. ""-Dbrooklyn.example.db.url=jdbc:mysql://localhost/visitors?user=brooklyn&password=br00k11n" //(note quoting needed due to ampersand) if (port==null) { @@ -51,7 +55,13 @@ if (port==null) { <% /* begin database-enabled block */ } -MongoClient client = new MongoClient("localhost", new Integer(port)); +MongoCredential credential = MongoCredential.createMongoCRCredential(username, authenticationDatabase, password.toCharArray()); +ServerAddress address = new ServerAddress("localhost", new Integer(port)); +MongoClientOptions connectionOptions = MongoClientOptions.builder() + .autoConnectRetry(true) + .socketKeepAlive(true) + .build(); +MongoClient client = new MongoClient(address, Arrays.asList(credential),connectionOptions); DB database = client.getDB("visitors"); DBCollection messages = database.getCollection("messages"); int i=0; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/pom.xml ---------------------------------------------------------------------- diff --git a/software/nosql/pom.xml b/software/nosql/pom.xml index b0d5b6c..be0887d 100644 --- a/software/nosql/pom.xml +++ b/software/nosql/pom.xml @@ -265,6 +265,7 @@ <exclude>src/test/resources/test-mongodb.conf</exclude> <exclude>src/test/resources/test-mongodb-configserver.conf</exclude> <exclude>src/test/resources/test-mongodb-router.conf</exclude> + <exclude>src/test/resources/mongodb-keyfile</exclude> <exclude>src/main/resources/org/apache/brooklyn/entity/nosql/redis/redis.conf</exclude> <exclude>src/main/resources/org/apache/brooklyn/entity/nosql/redis/slave.conf</exclude> <exclude>src/main/resources/org/apache/brooklyn/entity/nosql/riak/app.config</exclude> http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java index 52e24d8..5947a43 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java @@ -27,7 +27,7 @@ import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey; import org.apache.brooklyn.entity.software.base.SoftwareProcess; import org.apache.brooklyn.util.core.flags.SetFromFlag; -public interface AbstractMongoDBServer extends SoftwareProcess, Entity { +public interface AbstractMongoDBServer extends SoftwareProcess, Entity, MongoDBAuthenticationMixins { // TODO Need to properly test v2.4.x and v2.5.x support. // I think the v2.5.x were dev releases. @@ -58,4 +58,5 @@ public interface AbstractMongoDBServer extends SoftwareProcess, Entity { @SetFromFlag("port") PortAttributeSensorAndConfigKey PORT = new PortAttributeSensorAndConfigKey("mongodb.server.port", "Server port", "27017+"); + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java index c6974d4..9fe949d 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java @@ -27,6 +27,8 @@ import org.apache.brooklyn.api.location.OsDetails; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver; import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper; +import org.apache.brooklyn.util.time.Duration; +import org.apache.brooklyn.util.time.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.brooklyn.location.ssh.SshMachineLocation; @@ -63,7 +65,7 @@ public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSs commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs)); commands.add(BashCommands.INSTALL_TAR); commands.add("tar xzfv " + saveAs); - + newScript(INSTALLING) .failOnNonZeroResultCode() .body.append(commands).execute(); @@ -73,14 +75,40 @@ public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSs public void customize() { Map<?,?> ports = ImmutableMap.of("port", getServerPort()); Networking.checkPortsValid(ports); - String command = String.format("mkdir -p %s", getDataDirectory()); + List<String> commands = new LinkedList<String>(); + commands.add(String.format("mkdir -p %s", getDataDirectory())); + + if (MongoDBAuthenticationUtils.usesAuthentication(entity)) { + String destinationLocation = Os.mergePaths(getRunDir(), "mongodb-keyfile"); + entity.sensors().set(AbstractMongoDBServer.MONGODB_KEYFILE_DESTINATION, destinationLocation); + String keyfileContents = entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_CONTENTS); + if (keyfileContents == null) { + String keyfileUrl = entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_URL); + copyResource(keyfileUrl, destinationLocation); + } else { + commands.add(BashCommands.pipeTextToFile(keyfileContents, destinationLocation)); + commands.add("chmod 600 " + destinationLocation); + } + } + newScript(CUSTOMIZING) .updateTaskAndFailOnNonZeroResultCode() - .body.append(command).execute(); + .body.append(commands).execute(); String templateUrl = entity.getConfig(MongoDBServer.MONGODB_CONF_TEMPLATE_URL); if (!Strings.isNullOrEmpty(templateUrl)) copyTemplate(templateUrl, getConfFile()); + if (MongoDBAuthenticationUtils.usesAuthentication(entity)) { + launch(getArgsBuilderWithNoAuthentication((AbstractMongoDBServer) getEntity()) + .add("--dbpath", getDataDirectory())); + newScript("create-user") + .body.append(String.format("%s --port %s" + + " --host localhost admin --eval \"db.createUser({user: '%s',pwd: '%s',roles: [ 'root' ]})\"", + Os.mergePaths(getExpandedInstallDir(), "bin/mongo"), getServerPort(), getRootUsername(), MongoDBAuthenticationUtils.getRootPassword(entity))) + .updateTaskAndFailOnNonZeroResultCode() + .execute(); + stop(); + } } - + @Override public boolean isRunning() { try { @@ -102,7 +130,14 @@ public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSs // We could also use SIGTERM (15) new ScriptHelper(this, "Send SIGINT to MongoDB server") - .body.append("kill -2 $(cat " + getPidFile() + ")") + .body.append("MONGO_PID=$(cat " + getPidFile() + ")\n") + .body.append("kill -2 $MONGO_PID\n") + .body.append("for i in {1..10}\n" + + "do\n" + + " kill -0 $MONGO_PID || exit \n" + + " sleep 1\n" + + "done\n" + + "echo \"mongoDB process still running after 10 seconds; continuing but may subsequently fail\"") .execute(); } @@ -151,24 +186,38 @@ public abstract class AbstractMongoDBSshDriver extends AbstractSoftwareProcessSs return getRunDir() + "/mongo.conf"; } + protected String getRootUsername() { + return entity.config().get(AbstractMongoDBServer.ROOT_USERNAME); + } + protected ImmutableList.Builder<String> getArgsBuilderWithDefaults(AbstractMongoDBServer server) { - Integer port = server.getAttribute(MongoDBServer.PORT); + ImmutableList.Builder<String> builder = getArgsBuilderWithNoAuthentication(server); + String keyfileContents = entity.config().get(AbstractMongoDBServer.MONGODB_KEYFILE_CONTENTS); + if (keyfileContents != null) { + builder.add("--keyFile", entity.getAttribute(AbstractMongoDBServer.MONGODB_KEYFILE_DESTINATION)); + } + return builder; + } - return ImmutableList.<String>builder() - .add("--config", getConfFile()) - .add("--pidfilepath", getPidFile()) - .add("--logpath", getLogFile()) - .add("--port", port.toString()) - .add("--fork"); + protected ImmutableList.Builder<String> getArgsBuilderWithNoAuthentication(AbstractMongoDBServer server) { + Integer port = server.getAttribute(MongoDBServer.PORT); + ImmutableList.Builder<String> builder = ImmutableList.builder(); + builder.add("--config", getConfFile()); + builder.add("--pidfilepath", getPidFile()); + builder.add("--logpath", getLogFile()); + builder.add("--port", port.toString()); + builder.add("--fork"); + return builder; } protected void launch(ImmutableList.Builder<String> argsBuilder) { String args = Joiner.on(" ").join(argsBuilder.build()); - String command = String.format("%s/bin/mongod %s > out.log 2> err.log < /dev/null", getExpandedInstallDir(), args); - LOG.info(command); + List<String> commands = new LinkedList<String>(); + commands.add(String.format("%s/bin/mongod %s > out.log 2> err.log < /dev/null", getExpandedInstallDir(), args)); + newScript(LAUNCHING) .updateTaskAndFailOnNonZeroResultCode() - .body.append(command).execute(); + .body.append(commands).execute(); } - + } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java new file mode 100644 index 0000000..a47c384 --- /dev/null +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationMixins.java @@ -0,0 +1,51 @@ +/* + * 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.brooklyn.entity.nosql.mongodb; + +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey; +import org.apache.brooklyn.core.sensor.Sensors; +import org.apache.brooklyn.util.core.flags.SetFromFlag; + +public interface MongoDBAuthenticationMixins { + @SetFromFlag("mongodbKeyfileContents") + ConfigKey<String> MONGODB_KEYFILE_CONTENTS = ConfigKeys.newStringConfigKey( + "mongodb.keyfile.contents", "Contents of the keyfile used for authentication"); + + @SetFromFlag("mongodbKeyfileUrl") + ConfigKey<String> MONGODB_KEYFILE_URL = ConfigKeys.newStringConfigKey( + "mongodb.keyfile.url", "Location of the keyfile used for authentication"); + + @SetFromFlag("rootUsername") + BasicAttributeSensorAndConfigKey<String> ROOT_USERNAME = + new BasicAttributeSensorAndConfigKey<>(String.class, "mongodb.root.username", "Username of the initial admin user", "superuser"); + + @SetFromFlag("rootPassword") + BasicAttributeSensorAndConfigKey<String> ROOT_PASSWORD = + new BasicAttributeSensorAndConfigKey<>(String.class, "mongodb.root.password", "Password for the initial admin user, auto-generated if not set"); + + @SetFromFlag("authenticationDatabase") + BasicAttributeSensorAndConfigKey<String> AUTHENTICATION_DATABASE = + new BasicAttributeSensorAndConfigKey<>(String.class, "mongodb.authentication.database", "Database to be used to store authentication details (if used)", "admin"); + + AttributeSensor<String> MONGODB_KEYFILE_DESTINATION = Sensors.newStringSensor("mongodb.keyfile.destination", + "Destination of the keyfile used for authentication on the target server"); +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java new file mode 100644 index 0000000..0c337a0 --- /dev/null +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBAuthenticationUtils.java @@ -0,0 +1,79 @@ +/* + * 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.brooklyn.entity.nosql.mongodb; + +import org.apache.brooklyn.util.text.Strings; + +import org.apache.brooklyn.api.entity.EntitySpec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.brooklyn.api.entity.Entity; + + +public class MongoDBAuthenticationUtils { + + private static final Logger LOG = LoggerFactory.getLogger(MongoDBAuthenticationUtils.class); + + private MongoDBAuthenticationUtils(){} + + /** + * @return true if either the keyfile contents or keyfile url is set, false otherwise. If both are set, an IllegalStateException is thrown + */ + public static boolean usesAuthentication(Entity entity) { + String keyfileContents = entity.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS); + String keyfileUrl = entity.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL); + if (!(Strings.isEmpty(keyfileContents) || Strings.isEmpty(keyfileUrl))) { + throw new IllegalStateException("keyfile contents and keyfile location cannot both be set"); + } + if (Strings.isEmpty(keyfileContents) && Strings.isEmpty(keyfileUrl)) { + return false; + } + return true; + } + + public static String getRootPassword(Entity entity) { + String password = entity.config().get(MongoDBAuthenticationMixins.ROOT_PASSWORD); + if (Strings.isEmpty(password)) { + LOG.debug(entity + " has no password specified for " + MongoDBAuthenticationMixins.ROOT_PASSWORD.getName() + "; using a random string"); + password = Strings.makeRandomId(8); + entity.sensors().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, password); + entity.config().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, password); + } + return password; + } + + public static void setAuthenticationConfig(EntitySpec<?> spec, Entity source) { + if (MongoDBAuthenticationUtils.usesAuthentication(source)) { + spec.configure(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS, source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS)); + spec.configure(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL, source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL)); + spec.configure(MongoDBAuthenticationMixins.ROOT_USERNAME, source.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME)); + spec.configure(MongoDBAuthenticationMixins.ROOT_PASSWORD, getRootPassword(source)); + } + } + + public static void setAuthenticationConfig(Entity entity, Entity source) { + if (MongoDBAuthenticationUtils.usesAuthentication(source)) { + entity.config().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS, source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS)); + entity.config().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL, source.config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_URL)); + entity.config().set(MongoDBAuthenticationMixins.ROOT_USERNAME, source.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME)); + entity.config().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, getRootPassword(source)); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java index 3a6c398..fa2022f 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java @@ -27,6 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; import com.google.common.net.HostAndPort; import com.mongodb.BasicDBObject; import com.mongodb.CommandResult; @@ -34,6 +35,7 @@ import com.mongodb.DB; import com.mongodb.DBObject; import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; +import com.mongodb.MongoCredential; import com.mongodb.MongoException; import com.mongodb.ServerAddress; @@ -45,11 +47,20 @@ import com.mongodb.ServerAddress; public class MongoDBClientSupport { private static final Logger LOG = LoggerFactory.getLogger(MongoDBClientSupport.class); - private ServerAddress address; - + + private boolean usesAuthentication; + private String username; + private String password; + private String authenticationDatabase; + private MongoClient client() { - return new MongoClient(address, connectionOptions); + if (usesAuthentication) { + MongoCredential credential = MongoCredential.createMongoCRCredential(username, authenticationDatabase, password.toCharArray()); + return new MongoClient(address, ImmutableList.of(credential), connectionOptions); + } else { + return new MongoClient(address, connectionOptions); + } } // Set client to automatically reconnect to servers. @@ -60,9 +71,13 @@ public class MongoDBClientSupport { private static final BasicBSONObject EMPTY_RESPONSE = new BasicBSONObject(); - public MongoDBClientSupport(ServerAddress standalone) { + public MongoDBClientSupport(ServerAddress standalone, boolean usesAuthentication, String username, String password, String authenticationDatabase) { // We could also use a MongoClient to access an entire replica set. See MongoClient(List<ServerAddress>). address = standalone; + this.usesAuthentication = usesAuthentication; + this.username = username; + this.password = password; + this.authenticationDatabase = authenticationDatabase; } /** @@ -71,7 +86,8 @@ public class MongoDBClientSupport { public static MongoDBClientSupport forServer(AbstractMongoDBServer standalone) throws UnknownHostException { HostAndPort hostAndPort = BrooklynAccessUtils.getBrooklynAccessibleAddress(standalone, standalone.getAttribute(MongoDBServer.PORT)); ServerAddress address = new ServerAddress(hostAndPort.getHostText(), hostAndPort.getPort()); - return new MongoDBClientSupport(address); + return new MongoDBClientSupport(address, MongoDBAuthenticationUtils.usesAuthentication(standalone), standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_USERNAME), + standalone.sensors().get(MongoDBAuthenticationMixins.ROOT_PASSWORD), standalone.sensors().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE)); } private ServerAddress getServerAddress() { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java index 14d0eb8..12bbe87 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java @@ -46,7 +46,7 @@ import com.google.common.reflect.TypeToken; * @see <a href="http://docs.mongodb.org/manual/replication/">http://docs.mongodb.org/manual/replication/</a> */ @ImplementedBy(MongoDBReplicaSetImpl.class) -public interface MongoDBReplicaSet extends DynamicCluster { +public interface MongoDBReplicaSet extends DynamicCluster, MongoDBAuthenticationMixins { @SetFromFlag("replicaSetName") ConfigKey<String> REPLICA_SET_NAME = ConfigKeys.newStringConfigKey( http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java index 399ea91..a9db033 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java @@ -141,7 +141,12 @@ public class MongoDBReplicaSetImpl extends DynamicClusterImpl implements MongoDB @Override protected EntitySpec<?> getMemberSpec() { - return getConfig(MEMBER_SPEC, EntitySpec.create(MongoDBServer.class)); + EntitySpec<?> spec = config().get(MEMBER_SPEC); + if (spec == null) { + spec = EntitySpec.create(MongoDBServer.class); + } + MongoDBAuthenticationUtils.setAuthenticationConfig(spec, this); + return spec; } /** @@ -200,6 +205,7 @@ public class MongoDBReplicaSetImpl extends DynamicClusterImpl implements MongoDB setAttribute(PRIMARY_ENTITY, server); setAttribute(Startable.SERVICE_UP, true); } else { + ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator(this, "initialization", "replicaset failed to initialize"); ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE); } } else { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java index ea9c406..941dd8e 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java @@ -210,5 +210,4 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer .add("port", getAttribute(PORT)) .toString(); } - } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java index 7817dbc..0c81de2 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java @@ -19,32 +19,47 @@ package org.apache.brooklyn.entity.nosql.mongodb.sharding; import java.util.Collection; +import java.util.concurrent.ExecutionException; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.sensor.DependentConfiguration; import org.apache.brooklyn.enricher.stock.Enrichers; +import org.apache.brooklyn.entity.group.AbstractGroup; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationMixins; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationUtils; import org.apache.brooklyn.entity.software.base.SameServerEntityImpl; +import org.apache.brooklyn.util.exceptions.Exceptions; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; -public class CoLocatedMongoDBRouterImpl extends SameServerEntityImpl implements CoLocatedMongoDBRouter { +public class CoLocatedMongoDBRouterImpl extends SameServerEntityImpl implements CoLocatedMongoDBRouter, MongoDBAuthenticationMixins { + + private MongoDBRouter router; + @Override public void init() { super.init(); - + router = addChild(EntitySpec.create(MongoDBRouter.class) + .configure(MongoDBRouter.CONFIG_SERVERS, + DependentConfiguration.attributeWhenReady( + getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT), + MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES))); for (EntitySpec<?> siblingSpec : getConfig(CoLocatedMongoDBRouter.SIBLING_SPECS)) { addChild(siblingSpec); } + sensors().set(ROUTER, (MongoDBRouter) Iterables.tryFind(getChildren(), Predicates.instanceOf(MongoDBRouter.class)).get()); } @Override protected void doStart(Collection<? extends Location> locations) { + // TODO Changed to create the router child after init as a workaround. - // When we use `mongo-sharded.yaml`, and we call + // When we use `mongo-sharded.yaml`, and we call // `getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT)`, // the value is `$brooklyn:component("shardeddeployment")`. // To look up the component, it tries to do `entity().getApplication()` to @@ -54,17 +69,24 @@ public class CoLocatedMongoDBRouterImpl extends SameServerEntityImpl implements // // We should move this code back to `init()` once we have a solution for that. // We can also remove the call to Entities.manage() once this is in init() again. - - MongoDBRouter router = addChild(EntitySpec.create(MongoDBRouter.class) - .configure(MongoDBRouter.CONFIG_SERVERS, - DependentConfiguration.attributeWhenReady( - getConfig(CoLocatedMongoDBRouter.SHARDED_DEPLOYMENT), - MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES))); + + try { + // Do not attempt to read the configuration until after the router has been added to the cluster + // as it is at this point that the authentication configuration is set + Task<?> clusterTask = DependentConfiguration.attributeWhenReady(router, AbstractGroup.FIRST); + Entities.submit(this, clusterTask); + clusterTask.get(); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + } + MongoDBAuthenticationUtils.setAuthenticationConfig(router, this); + router.sensors().set(MongoDBAuthenticationMixins.ROOT_PASSWORD, router.config().get(MongoDBAuthenticationMixins.ROOT_PASSWORD)); + router.sensors().set(MongoDBAuthenticationMixins.ROOT_USERNAME, router.config().get(MongoDBAuthenticationMixins.ROOT_USERNAME)); + router.sensors().set(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE, router.config().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE)); Entities.manage(router); - setAttribute(ROUTER, (MongoDBRouter) Iterables.tryFind(getChildren(), Predicates.instanceOf(MongoDBRouter.class)).get()); addEnricher(Enrichers.builder().propagating(MongoDBRouter.PORT).from(router).build()); super.doStart(locations); - setAttribute(Startable.SERVICE_UP, true); + sensors().set(Startable.SERVICE_UP, true); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java index 816906d..df73868 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java @@ -48,4 +48,8 @@ public class MongoDBRouterSshDriver extends AbstractMongoDBSshDriver implements .body.append(command).execute(); } + @Override + public boolean isRunning() { + return super.isRunning(); + } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java ---------------------------------------------------------------------- diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java index 9ef50b9..0b8a1b6 100644 --- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java +++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java @@ -25,7 +25,6 @@ import java.util.List; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; -import org.apache.brooklyn.api.entity.Group; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.core.entity.AbstractEntity; @@ -42,10 +41,12 @@ import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationMixins; +import org.apache.brooklyn.entity.nosql.mongodb.MongoDBAuthenticationUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -public class MongoDBShardedDeploymentImpl extends AbstractEntity implements MongoDBShardedDeployment { +public class MongoDBShardedDeploymentImpl extends AbstractEntity implements MongoDBShardedDeployment, MongoDBAuthenticationMixins { @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(MongoDBShardedDeploymentImpl.class); @@ -53,22 +54,36 @@ public class MongoDBShardedDeploymentImpl extends AbstractEntity implements Mong @Override public void init() { super.init(); - - setAttribute(CONFIG_SERVER_CLUSTER, addChild(EntitySpec.create(MongoDBConfigServerCluster.class) + + EntitySpec<MongoDBConfigServerCluster> configServerClusterSpec = EntitySpec.create(MongoDBConfigServerCluster.class) .configure(MongoDBConfigServerCluster.MEMBER_SPEC, getConfig(MONGODB_CONFIG_SERVER_SPEC)) - .configure(DynamicCluster.INITIAL_SIZE, getConfig(CONFIG_CLUSTER_SIZE)))); - setAttribute(ROUTER_CLUSTER, addChild(EntitySpec.create(MongoDBRouterCluster.class) + .configure(DynamicCluster.INITIAL_SIZE, getConfig(CONFIG_CLUSTER_SIZE)); + MongoDBAuthenticationUtils.setAuthenticationConfig(configServerClusterSpec, this); + sensors().set(CONFIG_SERVER_CLUSTER, addChild(configServerClusterSpec)); + + EntitySpec<MongoDBRouterCluster> routerClusterSpec = EntitySpec.create(MongoDBRouterCluster.class) .configure(MongoDBRouterCluster.MEMBER_SPEC, getConfig(MONGODB_ROUTER_SPEC)) .configure(DynamicCluster.INITIAL_SIZE, getConfig(INITIAL_ROUTER_CLUSTER_SIZE)) - .configure(MongoDBRouter.CONFIG_SERVERS, attributeWhenReady(getAttribute(CONFIG_SERVER_CLUSTER), MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES)))); - setAttribute(SHARD_CLUSTER, addChild(EntitySpec.create(MongoDBShardCluster.class) + .configure(MongoDBRouter.CONFIG_SERVERS, attributeWhenReady(getAttribute(CONFIG_SERVER_CLUSTER), MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES)); + MongoDBAuthenticationUtils.setAuthenticationConfig(routerClusterSpec, this); + sensors().set(ROUTER_CLUSTER, addChild(routerClusterSpec)); + + EntitySpec<MongoDBShardCluster> shardClusterSpec = EntitySpec.create(MongoDBShardCluster.class) .configure(MongoDBShardCluster.MEMBER_SPEC, getConfig(MONGODB_REPLICA_SET_SPEC)) - .configure(DynamicCluster.INITIAL_SIZE, getConfig(INITIAL_SHARD_CLUSTER_SIZE)))); + .configure(DynamicCluster.INITIAL_SIZE, getConfig(INITIAL_SHARD_CLUSTER_SIZE)); + MongoDBAuthenticationUtils.setAuthenticationConfig(shardClusterSpec, this); + sensors().set(SHARD_CLUSTER, addChild(shardClusterSpec)); + addEnricher(Enrichers.builder() .propagating(MongoDBConfigServerCluster.CONFIG_SERVER_ADDRESSES) .from(getAttribute(CONFIG_SERVER_CLUSTER)) .build()); - + + // Advertise even if default are used (root password is set in MongoDBAuthenticationUtils) + sensors().set(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE, config().get(MongoDBAuthenticationMixins.AUTHENTICATION_DATABASE)); + sensors().set(MongoDBAuthenticationMixins.ROOT_USERNAME, config().get(MongoDBAuthenticationMixins.ROOT_USERNAME)); + sensors().set(MongoDBAuthenticationMixins.MONGODB_KEYFILE_DESTINATION, config().get(MongoDBAuthenticationMixins.MONGODB_KEYFILE_CONTENTS)); + ServiceNotUpLogic.updateNotUpIndicator(this, Attributes.SERVICE_STATE_ACTUAL, "stopped"); } @@ -85,7 +100,7 @@ public class MongoDBShardedDeploymentImpl extends AbstractEntity implements Mong if (getConfigRaw(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP, true).isPresent()) { addPolicy(PolicySpec.create(ColocatedRouterTrackingPolicy.class) .displayName("Co-located router tracker") - .configure("group", (Group)getConfig(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP))); + .configure("group", getConfig(MongoDBShardedDeployment.CO_LOCATED_ROUTER_GROUP))); } ServiceNotUpLogic.clearNotUpIndicator(this, Attributes.SERVICE_STATE_ACTUAL); ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING); @@ -99,6 +114,7 @@ public class MongoDBShardedDeploymentImpl extends AbstractEntity implements Mong public static class ColocatedRouterTrackingPolicy extends AbstractMembershipTrackingPolicy { @Override protected void onEntityAdded(Entity member) { + MongoDBAuthenticationUtils.setAuthenticationConfig(member, entity); MongoDBRouterCluster cluster = entity.getAttribute(ROUTER_CLUSTER); cluster.addMember(member.getAttribute(CoLocatedMongoDBRouter.ROUTER)); } @@ -107,7 +123,7 @@ public class MongoDBShardedDeploymentImpl extends AbstractEntity implements Mong MongoDBRouterCluster cluster = entity.getAttribute(ROUTER_CLUSTER); cluster.removeMember(member.getAttribute(CoLocatedMongoDBRouter.ROUTER)); } - }; + } @Override public void stop() { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/software/nosql/src/test/resources/mongodb-keyfile ---------------------------------------------------------------------- diff --git a/software/nosql/src/test/resources/mongodb-keyfile b/software/nosql/src/test/resources/mongodb-keyfile new file mode 100644 index 0000000..6d4640a --- /dev/null +++ b/software/nosql/src/test/resources/mongodb-keyfile @@ -0,0 +1,16 @@ +df1DzycxICi2RFa1xsDP5uiVcVtZ4EQBxffQ+FDuD4n81iOGW7pNOS49aH4t9PW6 +s0t+mASRnY/IVOsiTNT5VQWeMhf6b0/aYuXJp9ZZNQ9PmyA60a8x5x9K3YIoGYAd +/RGenkIOIG9EjXnqTT1QgN66xVIUp8v2w0iuER0jiG+GcjBVVWGgqKcj6ZLQRecC +6xSETYuJRbXdPanpnlk8oRYrtWFgcmQ8pl0/0hc/8i82PjTC8DdkqRqYQzhAvexh +Fo8ZOPiS8xmiDWDsKBJscf6J5KKlgr/3ws0Kv5Qqxmq7oelAmZ+xRvyFBYbao3cz +3XKBC9SBYfexnl25S9Ef94IV6bqls6SwQMTNS5W0sn3L/Mi55yEWFN44pcYCJ4ng +oHMDaQyOC+Fi0rRcRduFZWYHlw7ibX0AaRQhwhh0YEbgFY2O7QoTNxwNycxLeKLr +VMY8ZcTRzvmypAfetWHlwx97G+yXebCsZZ+TbAR/txficwmLFw/M5Qit8Op7YVFM +zsrKnJZq/Ar8kLzw2UrIFfecaRl3hqT4CI8htaVW+fbc94RHNiZpHg5k/I+aNT45 +9uxRNNPcZiDln7ZV3skhVwQ0UeUZUBp0UZj33N2f/5JXxoRc5slb2mMFEKe+FH6a +0M86QphH356jrIBSalm7duLAFzB8oyf7+JQgbpwooiO5D+KqIJevpwZXtjuaKVCU +4bOJNq8AaJU6yjPNihHiGuGLv3/TmXP1Q8Cr4XSyzpv9pxZvvb0XYdlxWIQg0szv +5QSTkgx6CCBoeDbVoWJh4bE3lobFponKC9o5j3nVAqPbxZocq6Lr6TWrXfwlNRcg +Cvenxs8mjRQV7Hg7956P/dJtavN3UpSTwbius5h/oIf9ywBmVLNAIhbOS3kcacOC +YlnJZGN+m1Wo9AvsmLz+yl5GB3W/zA4vUyhWnUY24BoKKEFYef594wi2sagz9TVC +nLrWCE8djB9j4tudcz6PdFFhQHmB http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml ---------------------------------------------------------------------- diff --git a/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml b/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml new file mode 100644 index 0000000..2d59f1c --- /dev/null +++ b/usage/launcher/src/test/resources/mongo-sharded-authentication.yaml @@ -0,0 +1,45 @@ +name: Sharded MongoDB With Web App +description: Auto-scaling web app backed by MongoDB +location: softlayer:ams01 +services: +- type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment + id: mongo + name: Mongo DB Backend + brooklyn.config: + initialShardClusterSize: 5 + shardReplicaSetSize: 3 + coLocatedRouterGroup: $brooklyn:component("webappcluster").attributeWhenReady("controlleddynamicwebappcluster.cluster") + mongodb.keyfile.url: classpath://mongo.key + mongodb.root.username: mongouser + +- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster + id: webappcluster + brooklyn.config: + memberSpec: + $brooklyn:entitySpec: + type: org.apache.brooklyn.entity.nosql.mongodb.sharding.CoLocatedMongoDBRouter + brooklyn.enrichers: + - type: brooklyn.enricher.basic.Propagator + brooklyn.config: + enricher.propagating.sensorMapping: + $brooklyn:sensor("org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", "http.port"): $brooklyn:sensor("org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", "http.port") + enricher.producer: $brooklyn:component("child", "appserver") + brooklyn.config: + mongodb.keyfile.url: classpath://mongo.key + brooklyn.example.mongodb.username: $brooklyn:component("mongo").attributeWhenReady("mongodb.root.username") + brooklyn.example.mongodb.password: $brooklyn:component("mongo").attributeWhenReady("mongodb.root.password") + brooklyn.example.mongodb.authenticationDatabase: $brooklyn:component("mongo").attributeWhenReady("mongodb.authentication.database") + shardedDeployment: $brooklyn:component("mongo") + siblingSpecs: + - $brooklyn:entitySpec: + id: appserver + type: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer + brooklyn.config: + war: "classpath://brooklyn-example-hello-world-sql-webapp.war" + java.sysprops: + brooklyn.example.mongodb.port: $brooklyn:component("parent", "").attributeWhenReady("mongodb.server.port") + brooklyn.example.mongodb.username: $brooklyn:component("mongo").attributeWhenReady("mongodb.root.username") + brooklyn.example.mongodb.password: $brooklyn:component("mongo").attributeWhenReady("mongodb.root.password") + brooklyn.example.mongodb.authenticationDatabase: $brooklyn:component("mongo").attributeWhenReady("mongodb.authentication.database") + - $brooklyn:entitySpec: + type: brooklyn.entity.basic.EmptySoftwareProcess http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo-sharded.yaml ---------------------------------------------------------------------- diff --git a/usage/launcher/src/test/resources/mongo-sharded.yaml b/usage/launcher/src/test/resources/mongo-sharded.yaml index 1a7a0bc..75b5413 100644 --- a/usage/launcher/src/test/resources/mongo-sharded.yaml +++ b/usage/launcher/src/test/resources/mongo-sharded.yaml @@ -24,10 +24,11 @@ services: id: mongo name: Mongo DB Backend brooklyn.config: - initialRouterClusterSize: 1 initialShardClusterSize: 5 shardReplicaSetSize: 3 coLocatedRouterGroup: $brooklyn:component("webappcluster").attributeWhenReady("controlleddynamicwebappcluster.cluster") + mongodb.keyfile.url: classpath://mongo.key + mongodb.root.user: mongouser - type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster id: webappcluster @@ -51,5 +52,8 @@ services: war: "classpath://brooklyn-example-hello-world-sql-webapp.war" java.sysprops: brooklyn.example.mongodb.port: $brooklyn:component("parent", "").attributeWhenReady("mongodb.server.port") + brooklyn.example.mongodb.username: $brooklyn:component("parent", "").attributeWhenReady("mongodb.root.username") + brooklyn.example.mongodb.password: $brooklyn:component("parent", "").attributeWhenReady("mongodb.root.password") + brooklyn.example.mongodb.authenticationDatabase: $brooklyn:component("parent", "").attributeWhenReady("mongodb.root.password") - $brooklyn:entitySpec: type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/usage/launcher/src/test/resources/mongo.key ---------------------------------------------------------------------- diff --git a/usage/launcher/src/test/resources/mongo.key b/usage/launcher/src/test/resources/mongo.key new file mode 100644 index 0000000..029e424 --- /dev/null +++ b/usage/launcher/src/test/resources/mongo.key @@ -0,0 +1,16 @@ +df1DzycxICi2RFa1xsDP5uiVcVtZ4EQBxffQ+FDuD4n81iOGW7pNOS49aH4t9PW6 +s0t+mASRnY/IVOsiTNT5VQWeMhf6b0/aYuXJp9ZZNQ9PmyA60a8x5x9K3YIoGYAd +/RGenkIOIG9EjXnqTT1QgN66xVIUp8v2w0iuER0jiG+GcjBVVWGgqKcj6ZLQRecC +6xSETYuJRbXdPanpnlk8oRYrtWFgcmQ8pl0/0hc/8i82PjTC8DdkqRqYQzhAvexh +Fo8ZOPiS8xmiDWDsKBJscf6J5KKlgr/3ws0Kv5Qqxmq7oelAmZ+xRvyFBYbao3cz +3XKBC9SBYfexnl25S9Ef94IV6bqls6SwQMTNS5W0sn3L/Mi55yEWFN44pcYCJ4ng +oHMDaQyOC+Fi0rRcRduFZWYHlw7ibX0AaRQhwhh0YEbgFY2O7QoTNxwNycxLeKLr +VMY8ZcTRzvmypAfetWHlwx97G+yXebCsZZ+TbAR/txficwmLFw/M5Qit8Op7YVFM +zsrKnJZq/Ar8kLzw2UrIFfecaRl3hqT4CI8htaVW+fbc94RHNiZpHg5k/I+aNT45 +9uxRNNPcZiDln7ZV3skhVwQ0UeUZUBp0UZj33N2f/5JXxoRc5slb2mMFEKe+FH6a +0M86QphH356jrIBSalm7duLAFzB8oyf7+JQgbpwooiO5D+KqIJevpwZXtjuaKVCU +4bOJNq8AaJU6yjPNihHiGuGLv3/TmXP1Q8Cr4XSyzpv9pxZvvb0XYdlxWIQg0szv +5QSTkgx6CCBoeDbVoWJh4bE3lobFponKC9o5j3nVAqPbxZocq6Lr6TWrXfwlNRcg +Cvenxs8mjRQV7Hg7956P/dJtavN3UpSTwbius5h/oIf9ywBmVLNAIhbOS3kcacOC +YlnJZGN+m1Wo9AvsmLz+yl5GB3W/zA4vUyhWnUY24BoKKEFYef594wi2sagz9TVC +nLrWCE8djB9j4tudcz6PdFFhQHm \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1d0e2548/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java b/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java index 4019a67..e91d60c 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/ssh/BashCommands.java @@ -625,6 +625,13 @@ public class BashCommands { +"\n"+"EOF_"+id+"\n"; } + public static String pipeTextToFile(String text, String filepath) { + String id = Identifiers.makeRandomId(8); + return "cat > " + filepath + " << EOL_" + id + "\n" + + text + + "EOL_" + id + "\n"; + } + public static String prependToEtcHosts(String ip, String... hostnames) { String tempFileId = "bak"+Identifiers.makeRandomId(4); return sudo(String.format("sed -i."+tempFileId+" -e '1i\\\n%s %s' /etc/hosts", ip, Joiner.on(" ").join(hostnames)));
