diff --git a/docs/Home.md b/docs/Home.md index 090abfa4..eb00392f 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -108,6 +108,7 @@ Instance configurations have many options that were not listed above. A few of t * GPUs - attach 1 or more GPUs to the instance. For more info, visit the GCE GPU docs. * Service Account E-mail - sets the service account that the instance will be able to access from metadata. For more info, review the service account documentation. +* Enable Secure Boot - Enables the Shielded VM Secure Boot option which helps protect against boot-level and kernel-level malware and rootkits. # No delay provisioning diff --git a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java index 03a9f02a..1f9646f0 100644 --- a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java +++ b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java @@ -34,6 +34,7 @@ import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.Scheduling; import com.google.api.services.compute.model.ServiceAccount; +import com.google.api.services.compute.model.ShieldedInstanceConfig; import com.google.api.services.compute.model.Tags; import com.google.api.services.compute.model.Zone; import com.google.cloud.graphite.platforms.plugin.client.ClientFactory; @@ -155,6 +156,7 @@ public class InstanceConfiguration implements Describable private Integer launchTimeoutSeconds; private Long bootDiskSizeGb; private transient Set labelSet; + private boolean enableSecureBoot; @Getter(AccessLevel.PROTECTED) @Setter(AccessLevel.PROTECTED) @@ -400,6 +402,7 @@ public Instance instance() throws IOException { instance.setGuestAccelerators(accelerators()); instance.setNetworkInterfaces(networkInterfaces()); instance.setServiceAccounts(serviceAccounts()); + instance.setShieldedInstanceConfig(shieldedInstanceConfig()); // optional if (notNullOrEmpty(minCpuPlatform)) { @@ -532,6 +535,12 @@ private List serviceAccounts() { } } + private ShieldedInstanceConfig shieldedInstanceConfig() { + ShieldedInstanceConfig shieldedInstanceConfig = new ShieldedInstanceConfig(); + shieldedInstanceConfig.setEnableSecureBoot(enableSecureBoot); + return shieldedInstanceConfig; + } + @Extension public static final class DescriptorImpl extends Descriptor { private static ComputeClient computeClient; @@ -978,6 +987,7 @@ public InstanceConfiguration build() { if (googleLabels != null) { instanceConfiguration.appendLabels(this.googleLabels); } + instanceConfiguration.setEnableSecureBoot(enableSecureBoot); return instanceConfiguration; } diff --git a/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly index e9befa51..049515bf 100644 --- a/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly +++ b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly @@ -134,6 +134,11 @@ + + + + + diff --git a/src/test/java/com/google/jenkins/plugins/computeengine/ConfigAsCodeTest.java b/src/test/java/com/google/jenkins/plugins/computeengine/ConfigAsCodeTest.java index e6e5e617..d2367408 100644 --- a/src/test/java/com/google/jenkins/plugins/computeengine/ConfigAsCodeTest.java +++ b/src/test/java/com/google/jenkins/plugins/computeengine/ConfigAsCodeTest.java @@ -54,6 +54,7 @@ public void shouldCreateCloudInstanceFromCode() { assertEquals("Wrong configurations runAsUser", "jenkins", configuration.getRunAsUser()); assertEquals("Wrong configurations remoteFs", "agent", configuration.getRemoteFs()); assertEquals("Wrong configurations javaExecPath", "java", configuration.getJavaExecPath()); + assertEquals("Wrong configurations enableSecureBoot", true, configuration.isEnableSecureBoot()); } @Test diff --git a/src/test/java/com/google/jenkins/plugins/computeengine/InstanceConfigurationTest.java b/src/test/java/com/google/jenkins/plugins/computeengine/InstanceConfigurationTest.java index a348b0ff..e0e783e8 100644 --- a/src/test/java/com/google/jenkins/plugins/computeengine/InstanceConfigurationTest.java +++ b/src/test/java/com/google/jenkins/plugins/computeengine/InstanceConfigurationTest.java @@ -212,7 +212,7 @@ public void testConfigRoundtrip() throws Exception { r.assertEqualBeans( want, got, - "namePrefix,region,zone,machineType,preemptible,windowsConfiguration,minCpuPlatform,startupScript,bootDiskType,bootDiskSourceImageName,bootDiskSourceImageProject,bootDiskSizeGb,acceleratorConfiguration,networkConfiguration,externalAddress,networkTags,serviceAccountEmail"); + "namePrefix,region,zone,machineType,preemptible,windowsConfiguration,minCpuPlatform,startupScript,bootDiskType,bootDiskSourceImageName,bootDiskSourceImageProject,bootDiskSizeGb,acceleratorConfiguration,networkConfiguration,externalAddress,networkTags,serviceAccountEmail,enableSecureBoot"); } @Test @@ -339,7 +339,8 @@ public static InstanceConfiguration.Builder instanceConfigurationBuilder() { .acceleratorConfiguration(new AcceleratorConfiguration(ACCELERATOR_NAME, ACCELERATOR_COUNT)) .runAsUser(RUN_AS_USER) .oneShot(false) - .template(null); + .template(null) + .enableSecureBoot(true); } @Test diff --git a/src/test/java/com/google/jenkins/plugins/computeengine/integration/ITUtil.java b/src/test/java/com/google/jenkins/plugins/computeengine/integration/ITUtil.java index 96595b34..71e48df0 100644 --- a/src/test/java/com/google/jenkins/plugins/computeengine/integration/ITUtil.java +++ b/src/test/java/com/google/jenkins/plugins/computeengine/integration/ITUtil.java @@ -129,6 +129,7 @@ class ITUtil { String.format("%s@%s.iam.gserviceaccount.com", System.getenv("GOOGLE_SA_NAME"), PROJECT_ID); private static final String RETENTION_TIME_MINUTES_STR = ""; private static final String LAUNCH_TIMEOUT_SECONDS_STR = ""; + private static final boolean ENABLE_SECURE_BOOT = true; static final int SNAPSHOT_TIMEOUT = windows ? 600 : 300; private static final GoogleKeyPair SSH_KEY = GoogleKeyPair.generate(RUN_AS_USER); static final String SSH_PRIVATE_KEY = SSH_KEY.getPrivateKey(); @@ -318,7 +319,8 @@ static InstanceConfiguration.Builder instanceConfigurationBuilder() { .acceleratorConfiguration(new AcceleratorConfiguration(ACCELERATOR_NAME, ACCELERATOR_COUNT)) .runAsUser(RUN_AS_USER) .startupScript(STARTUP_SCRIPT) - .javaExecPath("java -Dhudson.remoting.Launcher.pingIntervalSec=-1"); + .javaExecPath("java -Dhudson.remoting.Launcher.pingIntervalSec=-1") + .enableSecureBoot(ENABLE_SECURE_BOOT); } /* diff --git a/src/test/resources/com/google/jenkins/plugins/computeengine/configuration-as-code.yml b/src/test/resources/com/google/jenkins/plugins/computeengine/configuration-as-code.yml index d4f07156..bdab34bd 100644 --- a/src/test/resources/com/google/jenkins/plugins/computeengine/configuration-as-code.yml +++ b/src/test/resources/com/google/jenkins/plugins/computeengine/configuration-as-code.yml @@ -40,3 +40,4 @@ jenkins: bootDiskSizeGbStr: 50 bootDiskAutoDelete: true serviceAccountEmail: 'jenkins-test@gce-jenkins-ops.iam.gserviceaccount.com' + enableSecureBoot: true diff --git a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-it.yml b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-it.yml index 31c51150..75419de2 100644 --- a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-it.yml +++ b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-it.yml @@ -38,3 +38,4 @@ jenkins: bootDiskSizeGbStr: 10 bootDiskAutoDelete: true serviceAccountEmail: "${env.GOOGLE_SA_NAME}@${env.GOOGLE_PROJECT_ID}.iam.gserviceaccount.com" + enableSecureBoot: true diff --git a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-non-standard-java-it.yml b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-non-standard-java-it.yml index d13b6c65..81eec057 100644 --- a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-non-standard-java-it.yml +++ b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-non-standard-java-it.yml @@ -38,3 +38,4 @@ jenkins: bootDiskSizeGbStr: 10 bootDiskAutoDelete: true serviceAccountEmail: "${env.GOOGLE_SA_NAME}@${env.GOOGLE_PROJECT_ID}.iam.gserviceaccount.com" + enableSecureBoot: true diff --git a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-windows-it.yml b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-windows-it.yml index a4fcb5dd..ea63ef3e 100644 --- a/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-windows-it.yml +++ b/src/test/resources/com/google/jenkins/plugins/computeengine/integration/configuration-as-code-windows-it.yml @@ -40,6 +40,7 @@ jenkins: bootDiskSizeGbStr: 50 bootDiskAutoDelete: true serviceAccountEmail: "${env.GOOGLE_SA_NAME}@${env.GOOGLE_PROJECT_ID}.iam.gserviceaccount.com" + enableSecureBoot: true credentials: system: domainCredentials: