diff --git a/bubble-server/pom.xml b/bubble-server/pom.xml
index f6214c5b..ff8494e0 100644
--- a/bubble-server/pom.xml
+++ b/bubble-server/pom.xml
@@ -106,6 +106,12 @@
jetty-proxy
${jetty.version}
+
+
+ com.amazonaws
+ aws-java-sdk-ec2
+ 1.11.762
+
diff --git a/bubble-server/src/main/java/bubble/cloud/compute/amazonEC2/AmazonEC2Driver.java b/bubble-server/src/main/java/bubble/cloud/compute/amazonEC2/AmazonEC2Driver.java
deleted file mode 100644
index d7defcf9..00000000
--- a/bubble-server/src/main/java/bubble/cloud/compute/amazonEC2/AmazonEC2Driver.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Copyright (c) 2020 Bubble, Inc. All rights reserved.
- * For personal (non-commercial) use, see license: https://bubblev.com/bubble-license/
- */
-package bubble.cloud.compute.amazonEC2;
-
-import bubble.cloud.compute.ComputeServiceDriverBase;
-import bubble.model.cloud.BubbleNode;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSStaticCredentialsProvider;
-import com.amazonaws.auth.BasicAWSCredentials;
-import com.amazonaws.regions.Regions;
-import com.amazonaws.services.ec2.AmazonEC2;
-import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
-import com.amazonaws.services.ec2.model.*;
-import lombok.extern.slf4j.Slf4j;
-import org.cobbzilla.util.http.HttpRequestBean;
-import org.cobbzilla.util.http.HttpResponseBean;
-
-import java.io.IOException;
-import java.util.List;
-
-import static org.cobbzilla.util.string.StringUtil.urlEncode;
-
-@Slf4j
-public class AmazonEC2Driver extends ComputeServiceDriverBase {
-
- private static final AWSCredentials AWS_CREDENTIALS;
-
- static {
- // Your accesskey and secretkey
- AWS_CREDENTIALS = new BasicAWSCredentials(
- "Your-ID",
- "Your secret-key"
- );
- }
-
- @Override
- protected String readSshKeyId(HttpResponseBean keyResponse) {
- return null;
- }
-
- @Override
- protected HttpRequestBean registerSshKeyRequest(BubbleNode node) {
-
- return null;
- }
-
- @Override
- public List listNodes() throws IOException {
- return null;
- }
-
- @Override
- public BubbleNode start(BubbleNode node) throws Exception {
- AmazonEC2 ec2Client = AmazonEC2ClientBuilder.standard()
- .withCredentials(new AWSStaticCredentialsProvider(AWS_CREDENTIALS))
- .withRegion(Regions.US_EAST_1)
- .build();
-
- ec2Client.importKeyPair(new ImportKeyPairRequest(node.getUuid(), node.getSshKey().getSshPublicKey()));
- RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-0080e4c5bc078760e")
- .withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
- .withMinCount(1)
- .withMaxCount(1)
- .withKeyName(node.getUuid())
- .withNetworkInterfaces(new InstanceNetworkInterfaceSpecification()
- .withAssociatePublicIpAddress(true)
- .withDeviceIndex(0)
- .withSubnetId("subnet-id")
- .withGroups("sg-id"));
-
- RunInstancesResult runInstancesResult = ec2Client.runInstances(runInstancesRequest);
-
- Instance instance = runInstancesResult.getReservation().getInstances().get(0);
- String instanceId = instance.getInstanceId();
-
- // Setting up the tags for the instance
- CreateTagsRequest createTagsRequest = new CreateTagsRequest()
- .withResources(instance.getInstanceId())
- .withTags(new Tag("Name", "Edurekademo"));
- ec2Client.createTags(createTagsRequest);
-
- // Starting the Instance
- StartInstancesRequest startInstancesRequest = new StartInstancesRequest().withInstanceIds(instanceId);
-
- ec2Client.startInstances(startInstancesRequest);
- return null;
- }
-
- @Override
- public BubbleNode cleanupStart(BubbleNode node) throws Exception {
- return null;
- }
-
- @Override
- public BubbleNode stop(BubbleNode node) throws Exception {
- return null;
- }
-
- @Override
- public BubbleNode status(BubbleNode node) throws Exception {
- return null;
- }
-}
diff --git a/bubble-server/src/main/java/bubble/cloud/compute/ec2/AmazonEC2Driver.java b/bubble-server/src/main/java/bubble/cloud/compute/ec2/AmazonEC2Driver.java
new file mode 100644
index 00000000..28af8ba4
--- /dev/null
+++ b/bubble-server/src/main/java/bubble/cloud/compute/ec2/AmazonEC2Driver.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2020 Bubble, Inc. All rights reserved.
+ * For personal (non-commercial) use, see license: https://bubblev.com/bubble-license/
+ */
+package bubble.cloud.compute.ec2;
+
+import bubble.cloud.compute.ComputeServiceDriverBase;
+import bubble.cloud.shared.aws.BubbleAwsCredentialsProvider;
+import bubble.model.cloud.BubbleNode;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.regions.Regions;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
+import com.amazonaws.services.ec2.model.*;
+import com.amazonaws.services.route53.AmazonRoute53;
+import com.amazonaws.services.route53.AmazonRoute53ClientBuilder;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.cobbzilla.util.http.HttpRequestBean;
+import org.cobbzilla.util.http.HttpResponseBean;
+
+import java.io.IOException;
+import java.util.List;
+
+import static bubble.model.cloud.BubbleNode.TAG_SSH_KEY_ID;
+import static org.cobbzilla.util.daemon.ZillaRuntime.die;
+import static org.cobbzilla.util.http.HttpStatusCodes.OK;
+
+@Slf4j
+public class AmazonEC2Driver extends ComputeServiceDriverBase {
+
+ @Getter(lazy=true) private final AWSCredentialsProvider ec2credentials = new BubbleAwsCredentialsProvider(cloud, getCredentials());
+
+ @Getter(lazy=true) private final AmazonEC2 ec2Client = initEC2Client();
+ private AmazonEC2 initEC2Client() {
+ final Regions region;
+ final String regionName = config.getRegion(Regions.DEFAULT_REGION.getName()).getName();
+ try {
+ region = Regions.valueOf(regionName);
+ } catch (Exception e) {
+ return die("initEC2Client: invalid region: " + regionName);
+ }
+ return AmazonEC2ClientBuilder.standard()
+ .withRegion(region)
+ .withCredentials(getEc2credentials())
+ .build();
+ }
+
+
+
+ @Override public void postSetup() {
+
+ super.postSetup();
+ }
+
+ @Override protected String readSshKeyId(HttpResponseBean keyResponse) {
+ return null;
+ }
+
+ @Override protected HttpRequestBean registerSshKeyRequest(BubbleNode node) {
+ final AmazonEC2 ec2Client = getEc2Client();
+ ec2Client.importKeyPair(new ImportKeyPairRequest(node.getUuid(), node.getSshKey().getSshPublicKey()));
+ return null;
+ }
+
+ @Override public List listNodes() throws IOException {
+ return null;
+ }
+
+ @Override public BubbleNode start(BubbleNode node) throws Exception {
+
+ // TODO: imageID, dibnetID, Group
+ RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-0080e4c5bc078760e")
+ .withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
+ .withMinCount(1)
+ .withMaxCount(1)
+ .withKeyName(node.getUuid())
+ .withNetworkInterfaces(new InstanceNetworkInterfaceSpecification()
+ .withAssociatePublicIpAddress(true)
+ .withDeviceIndex(0)
+ .withSubnetId("subnet-id")
+ .withGroups("sg-id"));
+
+ final AmazonEC2 ec2Client = getEc2Client();
+ RunInstancesResult runInstancesResult = ec2Client.runInstances(runInstancesRequest);
+
+ Instance instance = runInstancesResult.getReservation().getInstances().get(0);
+ String instanceId = instance.getInstanceId();
+
+ // TODO: tags
+ // Setting up the tags for the instance
+ CreateTagsRequest createTagsRequest = new CreateTagsRequest()
+ .withResources(instance.getInstanceId())
+ .withTags(new Tag("", ""));
+ ec2Client.createTags(createTagsRequest);
+
+ // Starting the Instance
+ StartInstancesRequest startInstancesRequest = new StartInstancesRequest().withInstanceIds(instanceId);
+
+ ec2Client.startInstances(startInstancesRequest);
+ return null;
+ }
+
+ @Override public BubbleNode cleanupStart(BubbleNode node) throws Exception {
+ deleteEC2KeyPair(node);
+ return node;
+ }
+
+ @Override public BubbleNode stop(BubbleNode node) throws Exception {
+ //Stop EC2 Instance
+ //TODO: instanceID
+ String instanceID = "";
+ StopInstancesRequest stopInstancesRequest = new StopInstancesRequest()
+ .withInstanceIds(instanceID);
+
+ final AmazonEC2 ec2Client = getEc2Client();
+ ec2Client.stopInstances(stopInstancesRequest)
+ .getStoppingInstances()
+ .get(0)
+ .getPreviousState()
+ .getName();
+ return node;
+ }
+
+ @Override public BubbleNode status(BubbleNode node) throws Exception {
+ return null;
+ }
+
+ public void deleteEC2KeyPair(BubbleNode node) throws IOException {
+ if (node.hasTag(TAG_SSH_KEY_ID)) {
+ DeleteKeyPairRequest request = new DeleteKeyPairRequest()
+ .withKeyName(node.getUuid());
+
+ // destroy key, check response
+ final AmazonEC2 ec2Client = getEc2Client();
+ DeleteKeyPairResult response = ec2Client.deleteKeyPair(request);
+
+ if (response.getSdkHttpMetadata().getHttpStatusCode() != OK) {
+ log.warn("deleteEC2KeyPair: error deleting EC2keyPair, node: "+ node.getUuid());
+ }
+ }
+ }
+}
diff --git a/bubble-server/src/test/resources/models/system/cloudService.json b/bubble-server/src/test/resources/models/system/cloudService.json
index a6245b5e..670802e8 100644
--- a/bubble-server/src/test/resources/models/system/cloudService.json
+++ b/bubble-server/src/test/resources/models/system/cloudService.json
@@ -233,6 +233,21 @@
"template": true
},
+ {
+ "_subst": true,
+ "name": "AmazonEC2Driver",
+ "type": "compute",
+ "driverClass": "bubble.cloud.compute.ec2.AmazonEC2Driver",
+ "driverConfig": {},
+ "credentials": {
+ "params": [
+ {"name": "AWS_ACCESS_KEY_ID", "value": "{{AWS_ACCESS_KEY_ID}}"},
+ {"name": "AWS_SECRET_KEY", "value": "{{AWS_SECRET_KEY}}"}
+ ]
+ },
+ "template": true
+ },
+
{
"_subst": true,
"name": "InviteCode",
diff --git a/utils/cobbzilla-wizard b/utils/cobbzilla-wizard
index 073dbbc3..23e6ab73 160000
--- a/utils/cobbzilla-wizard
+++ b/utils/cobbzilla-wizard
@@ -1 +1 @@
-Subproject commit 073dbbc3f8401e946b731e2269f6e253b04bee68
+Subproject commit 23e6ab7399be669a1f9bb9abf64186f3d029eda5