diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/EC2Config.java b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/EC2Config.java index 7605049..0353abc 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/EC2Config.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/EC2Config.java @@ -59,6 +59,8 @@ public class EC2Config { private boolean runAsSpotInstance; private String spotPrice; private Integer spotRequestExpiresAfter; + private Boolean dockerVolumeEncryption; + private Boolean operatingSystemVolumeEncryption; public String getAmi() { return ami; @@ -148,6 +150,10 @@ public Date getSpotRequestValidUntil() { return now().plusMinutes(spotRequestExpiresAfter).toDate(); } + public Boolean getDockerVolumeEncryption() { return dockerVolumeEncryption; } + + public Boolean getOperatingSystemVolumeEncryption() { return operatingSystemVolumeEncryption; } + public static class Builder { static final String NAME = "Name"; static final String CREATOR = "Creator"; @@ -211,10 +217,12 @@ private EC2Config createLinuxConfig() { ec2Config.operatingSystemVolumeType = pluginSettings.getLinuxOSVolumeType(); ec2Config.operationSystemVolumeSize = pluginSettings.getLinuxOSVolumeSize(); ec2Config.operationSystemVolumeProvisionedIOPS = pluginSettings.getLinuxOSVolumeProvisionedIOPS(); + ec2Config.operatingSystemVolumeEncryption = pluginSettings.getLinuxOSVolumeEncryption(); ec2Config.dockerVolumeType = pluginSettings.getLinuxVolumeType(); ec2Config.dockerVolumeSize = pluginSettings.getLinuxVolumeSize(); ec2Config.dockerVolumeProvisionedIOPS = pluginSettings.getLinuxVolumeProvisionedIOPS(); + ec2Config.dockerVolumeEncryption = pluginSettings.getLinuxVolumeEncryption(); ec2Config.registerTimeOut = pluginSettings.getLinuxRegisterTimeout(); ec2Config.maxInstancesAllowed = pluginSettings.getMaxLinuxInstancesAllowed(); ec2Config.minInstanceCount = pluginSettings.getMinLinuxInstanceCount(); diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/RunInstanceRequestBuilder.java b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/RunInstanceRequestBuilder.java index 2a5d8ed..27d4636 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/RunInstanceRequestBuilder.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/RunInstanceRequestBuilder.java @@ -65,15 +65,16 @@ private void blockOperatingSystemVolume(RunInstancesRequest request) { } request.withBlockDeviceMappings( - blockDeviceMapping(osDeviceName(), ec2Config.getOperatingSystemVolumeType(), Integer.parseInt(ec2Config.getOperationSystemVolumeSize()), ec2Config.getOperationSystemVolumeProvisionedIOPS()) + blockDeviceMapping(osDeviceName(), ec2Config.getOperatingSystemVolumeType(), Integer.parseInt(ec2Config.getOperationSystemVolumeSize()), ec2Config.getOperationSystemVolumeProvisionedIOPS(), ec2Config.getOperatingSystemVolumeEncryption()) ); } - private BlockDeviceMapping blockDeviceMapping(String deviceName, String volumeType, int volumeSize, Integer provisionedIOPS) { + private BlockDeviceMapping blockDeviceMapping(String deviceName, String volumeType, int volumeSize, Integer provisionedIOPS, Boolean volumeEncryption) { EbsBlockDevice ebsBlockDevice = new EbsBlockDevice() .withDeleteOnTermination(true) .withVolumeType(volumeType) - .withVolumeSize(volumeSize); + .withVolumeSize(volumeSize) + .withEncrypted(volumeEncryption); return new BlockDeviceMapping() .withEbs(withIops(ebsBlockDevice, volumeType, provisionedIOPS)) .withDeviceName(deviceName); @@ -90,7 +91,7 @@ private void blockDockerVolume(RunInstancesRequest request) { } request.withBlockDeviceMappings( - blockDeviceMapping(DEFAULT_LINUX_DOCKER_DEVICE_NAME, ec2Config.getDockerVolumeType(), Integer.parseInt(ec2Config.getDockerVolumeSize()), ec2Config.getDockerVolumeProvisionedIOPS()) + blockDeviceMapping(DEFAULT_LINUX_DOCKER_DEVICE_NAME, ec2Config.getDockerVolumeType(), Integer.parseInt(ec2Config.getDockerVolumeSize()), ec2Config.getDockerVolumeProvisionedIOPS(), ec2Config.getDockerVolumeEncryption()) ); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/SpotInstanceRequestBuilder.java b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/SpotInstanceRequestBuilder.java index cda77d4..6d60da1 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/SpotInstanceRequestBuilder.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/aws/SpotInstanceRequestBuilder.java @@ -87,15 +87,16 @@ private void blockOperatingSystemVolume(LaunchSpecification launchSpecification) } launchSpecification.withBlockDeviceMappings( - blockDeviceMapping(osDeviceName(), ec2Config.getOperatingSystemVolumeType(), Integer.parseInt(ec2Config.getOperationSystemVolumeSize()), ec2Config.getOperationSystemVolumeProvisionedIOPS()) + blockDeviceMapping(osDeviceName(), ec2Config.getOperatingSystemVolumeType(), Integer.parseInt(ec2Config.getOperationSystemVolumeSize()), ec2Config.getOperationSystemVolumeProvisionedIOPS(), ec2Config.getOperatingSystemVolumeEncryption()) ); } - private BlockDeviceMapping blockDeviceMapping(String deviceName, String volumeType, int volumeSize, Integer provisionedIOPS) { + private BlockDeviceMapping blockDeviceMapping(String deviceName, String volumeType, int volumeSize, Integer provisionedIOPS, boolean volumeEncryption) { EbsBlockDevice ebsBlockDevice = new EbsBlockDevice() .withDeleteOnTermination(true) .withVolumeType(volumeType) - .withVolumeSize(volumeSize); + .withVolumeSize(volumeSize) + .withEncrypted(volumeEncryption); return new BlockDeviceMapping() .withEbs(withIops(ebsBlockDevice, volumeType, provisionedIOPS)) .withDeviceName(deviceName); @@ -112,7 +113,7 @@ private void blockDockerVolume(LaunchSpecification launchSpecification) { } launchSpecification.withBlockDeviceMappings( - blockDeviceMapping(DEFAULT_LINUX_DOCKER_DEVICE_NAME, ec2Config.getDockerVolumeType(), Integer.parseInt(ec2Config.getDockerVolumeSize()), ec2Config.getDockerVolumeProvisionedIOPS()) + blockDeviceMapping(DEFAULT_LINUX_DOCKER_DEVICE_NAME, ec2Config.getDockerVolumeType(), Integer.parseInt(ec2Config.getDockerVolumeSize()), ec2Config.getDockerVolumeProvisionedIOPS(), ec2Config.getDockerVolumeEncryption()) ); } diff --git a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/domain/PluginSettings.java b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/domain/PluginSettings.java index e94ac7b..b60d46e 100644 --- a/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/domain/PluginSettings.java +++ b/src/main/java/com/thoughtworks/gocd/elasticagent/ecs/domain/PluginSettings.java @@ -314,6 +314,16 @@ public class PluginSettings { @Metadata(key = "EfsDnsOrIP", required = false, secure = false) private String efsDnsOrIP; + @Expose + @SerializedName("LinuxVolumeEncryption") + @Metadata(key = "LinuxVolumeEncryption", required = false, secure = false) + private Boolean linuxVolumeEncryption; + + @Expose + @SerializedName("LinuxDockerEncryption") + @Metadata(key = "LinuxDockerEncryption", required = false, secure = false) + private Boolean linuxDockerEncryption; + public String getAccessKeyId() { return accessKeyId; } @@ -413,6 +423,10 @@ public Integer getLinuxVolumeProvisionedIOPS() { return getIntOrDefault(linuxVolumeProvisionedIOPS, null); } + public Boolean getLinuxOSVolumeEncryption() { return linuxVolumeEncryption; } + + public Boolean getLinuxVolumeEncryption() { return linuxDockerEncryption; } + public Period getLinuxRegisterTimeout() { return new Period().withMinutes(getIntOrDefault(this.linuxRegisterTimeout, 5)); } @@ -626,12 +640,14 @@ public boolean equals(Object o) { Objects.equals(privateDockerRegistryEmail, that.privateDockerRegistryEmail) && Objects.equals(privateDockerRegistryUsername, that.privateDockerRegistryUsername) && Objects.equals(privateDockerRegistryPassword, that.privateDockerRegistryPassword) && - Objects.equals(efsDnsOrIP, that.efsDnsOrIP); + Objects.equals(efsDnsOrIP, that.efsDnsOrIP) && + Objects.equals(linuxVolumeEncryption, that.linuxVolumeEncryption) && + Objects.equals(linuxDockerEncryption, that.linuxDockerEncryption); } @Override public int hashCode() { - return Objects.hash(goServerUrl, clusterName, region, accessKeyId, secretAccessKey, environmentVariables, containerAutoregisterTimeout, maxContainerDataVolumeSize, keyPairName, iamInstanceProfile, subnetIds, securityGroupIds, logDriverName, logOptions, linuxAMI, linuxInstanceType, linuxRegisterTimeout, minLinuxInstanceCount, maxLinuxInstancesAllowed, maxLinuxSpotInstanceAllowed, linuxVolumeType, linuxVolumeSize, linuxVolumeProvisionedIOPS, linuxOSVolumeType, linuxOSVolumeSize, linuxOSVolumeProvisionedIOPS, linuxUserdataScript, linuxStopPolicy, stopLinuxInstanceAfter, terminateStoppedLinuxInstanceAfter, terminateIdleLinuxSpotInstanceAfter, windowsAMI, windowsInstanceType, windowsVolumeType, windowsVolumeSize, windowsOSVolumeProvisionedIOPS, windowsRegisterTimeout, minWindowsInstanceCount, maxWindowsInstancesAllowed, maxWindowsSpotInstanceAllowed, windowsUserdataScript, windowsStopPolicy, stopWindowsInstanceAfter, terminateStoppedWindowsInstanceAfter, terminateIdleWindowsSpotInstanceAfter, privateDockerRegistryAuthType, privateDockerRegistryAuthToken, privateDockerRegistryUrl, privateDockerRegistryEmail, privateDockerRegistryUsername, privateDockerRegistryPassword, efsDnsOrIP); + return Objects.hash(goServerUrl, clusterName, region, accessKeyId, secretAccessKey, environmentVariables, containerAutoregisterTimeout, maxContainerDataVolumeSize, keyPairName, iamInstanceProfile, subnetIds, securityGroupIds, logDriverName, logOptions, linuxAMI, linuxInstanceType, linuxRegisterTimeout, minLinuxInstanceCount, maxLinuxInstancesAllowed, maxLinuxSpotInstanceAllowed, linuxVolumeType, linuxVolumeSize, linuxVolumeProvisionedIOPS, linuxOSVolumeType, linuxOSVolumeSize, linuxOSVolumeProvisionedIOPS, linuxUserdataScript, linuxStopPolicy, stopLinuxInstanceAfter, terminateStoppedLinuxInstanceAfter, terminateIdleLinuxSpotInstanceAfter, windowsAMI, windowsInstanceType, windowsVolumeType, windowsVolumeSize, windowsOSVolumeProvisionedIOPS, windowsRegisterTimeout, minWindowsInstanceCount, maxWindowsInstancesAllowed, maxWindowsSpotInstanceAllowed, windowsUserdataScript, windowsStopPolicy, stopWindowsInstanceAfter, terminateStoppedWindowsInstanceAfter, terminateIdleWindowsSpotInstanceAfter, privateDockerRegistryAuthType, privateDockerRegistryAuthToken, privateDockerRegistryUrl, privateDockerRegistryEmail, privateDockerRegistryUsername, privateDockerRegistryPassword, efsDnsOrIP, linuxVolumeEncryption, linuxDockerEncryption); } public String uuid() { diff --git a/src/main/resources/cluster-profile.template.html b/src/main/resources/cluster-profile.template.html index b2e8bd7..2ec70ff 100644 --- a/src/main/resources/cluster-profile.template.html +++ b/src/main/resources/cluster-profile.template.html @@ -556,6 +556,13 @@ {{GOINPUTNAME[LinuxOSVolumeProvisionedIOPS].$error.server}} + +
+ + + {{GOINPUTNAME[LinuxVolumeEncryption].$error.server}} +

Allows to override default operating system volume. This is used to store operating system and @@ -600,6 +607,13 @@ {{GOINPUTNAME[LinuxDockerVolumeProvisionedIOPS].$error.server}} + +

+ + + {{GOINPUTNAME[LinuxDockerEncryption].$error.server}} +

Allows to override default storage with specified type and size. This is used to store docker images and diff --git a/src/test/java/com/thoughtworks/gocd/elasticagent/ecs/executors/GetClusterProfileMetadataExecutorTest.java b/src/test/java/com/thoughtworks/gocd/elasticagent/ecs/executors/GetClusterProfileMetadataExecutorTest.java index bbcde5c..03059d2 100644 --- a/src/test/java/com/thoughtworks/gocd/elasticagent/ecs/executors/GetClusterProfileMetadataExecutorTest.java +++ b/src/test/java/com/thoughtworks/gocd/elasticagent/ecs/executors/GetClusterProfileMetadataExecutorTest.java @@ -408,6 +408,20 @@ void assertJsonStructure() throws Exception { " \"required\": false,\n" + " \"secure\": false\n" + " }\n" + + " },\n" + + " {\n" + + " \"key\": \"LinuxVolumeEncryption\",\n" + + " \"metadata\": {\n" + + " \"required\": false,\n" + + " \"secure\": false\n" + + " }\n" + + " },\n" + + " {\n" + + " \"key\": \"LinuxDockerEncryption\",\n" + + " \"metadata\": {\n" + + " \"required\": false,\n" + + " \"secure\": false\n" + + " }\n" + " }\n" + "]\n";