From 1ef2a894fc083141b8f52c027aa54a7d5306663d Mon Sep 17 00:00:00 2001 From: Troy Mohl Date: Mon, 16 Mar 2020 15:50:30 -0400 Subject: [PATCH] Add tag to prevent instance from being stopped --- .../hudson/plugins/ec2/AmazonEC2Cloud.java | 57 ++++++++++++++----- .../hudson/plugins/ec2/InstanceStopTimer.java | 2 +- .../ec2/AmazonEC2Cloud/config-entries.jelly | 5 +- ...gForEc2.html => help-nodeLabelForEc2.html} | 0 .../help-preventStopAwsTag.html | 2 + 5 files changed, 49 insertions(+), 17 deletions(-) rename src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/{help-nodeTagForEc2.html => help-nodeLabelForEc2.html} (100%) create mode 100644 src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-preventStopAwsTag.html diff --git a/src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java b/src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java index 34e4be2ca..0219b34f2 100644 --- a/src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java +++ b/src/main/java/hudson/plugins/ec2/AmazonEC2Cloud.java @@ -36,6 +36,7 @@ import com.amazonaws.services.ec2.model.Reservation; import com.amazonaws.services.ec2.model.StartInstancesRequest; import com.amazonaws.services.ec2.model.StopInstancesRequest; +import com.amazonaws.services.ec2.model.Tag; import com.google.common.annotations.VisibleForTesting; import hudson.Extension; import hudson.Util; @@ -63,7 +64,6 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -95,7 +95,9 @@ public class AmazonEC2Cloud extends EC2Cloud { private String instanceTagForJenkins; - private String nodeTagForEc2; + private String nodeLabelForEc2; + + private String preventStopAwsTag; private String maxIdleMinutes; @@ -186,23 +188,32 @@ public void setAltEC2Endpoint(String altEC2Endpoint) { this.altEC2Endpoint = altEC2Endpoint; } - public String getNodeTagForEc2() { - return nodeTagForEc2; + public String getNodeLabelForEc2() { + return nodeLabelForEc2; + } + + @DataBoundSetter + public void setNodeLabelForEc2(String nodeLabelForEc2 ) { + this.nodeLabelForEc2 = nodeLabelForEc2; + } + + public String getPreventStopAwsTag() { + return preventStopAwsTag; } @DataBoundSetter - public void setNodeTagForEc2(String nodeTagForEc2) { - this.nodeTagForEc2 = nodeTagForEc2; + public void setPreventStopAwsTag( String preventStopAwsTag ) { + this.preventStopAwsTag = preventStopAwsTag; } public boolean isEc2Node(Node node) { //If no label is specified then we check all nodes - if (nodeTagForEc2 == null || nodeTagForEc2.trim().length() == 0) { + if ( nodeLabelForEc2 == null || nodeLabelForEc2.trim().length() == 0) { return true; } for (LabelAtom label : node.getAssignedLabels()) { - if (label.getExpression().equalsIgnoreCase(nodeTagForEc2)) { + if (label.getExpression().equalsIgnoreCase( nodeLabelForEc2 )) { return true; } } @@ -281,13 +292,17 @@ public void stopNode(Node node) { final String instanceId = nodeInstance.getInstanceId(); - try { - StopInstancesRequest request = new StopInstancesRequest(); - request.setInstanceIds(Collections.singletonList(instanceId)); - connect().stopInstances(request); - LOGGER.log(Level.INFO, "Stopped instance: {0}", instanceId); - } catch (Exception e) { - LOGGER.log(Level.INFO, "Unable to stop instance: " + instanceId, e); + if (stopAllowed( nodeInstance )) { + try { + StopInstancesRequest request = new StopInstancesRequest(); + request.setInstanceIds( Collections.singletonList( instanceId ) ); + connect().stopInstances( request ); + LOGGER.log( Level.INFO, "Stopped instance: {0}", instanceId ); + } catch ( Exception e ) { + LOGGER.log( Level.INFO, "Unable to stop instance: " + instanceId, e ); + } + } else { + LOGGER.log( Level.FINEST, "Not allowed to stop node: {0}", instanceId); } } @@ -339,6 +354,18 @@ private Instance getInstance(List filters, InstanceStateName desiredStat return null; } + private boolean stopAllowed(Instance instance) { + List tags = instance.getTags(); + if (tags != null) { + for ( Tag tag : tags) { + if (tag.getKey().trim().equals( preventStopAwsTag )) { + return false; + } + } + } + return true; + } + @Extension public static class DescriptorImpl extends EC2Cloud.DescriptorImpl { diff --git a/src/main/java/hudson/plugins/ec2/InstanceStopTimer.java b/src/main/java/hudson/plugins/ec2/InstanceStopTimer.java index 96dd33ebe..d68eb45a8 100644 --- a/src/main/java/hudson/plugins/ec2/InstanceStopTimer.java +++ b/src/main/java/hudson/plugins/ec2/InstanceStopTimer.java @@ -79,7 +79,7 @@ private void stopNode(Node node) { continue; AmazonEC2Cloud ec2 = (AmazonEC2Cloud) cloud; if (ec2.isStartStopNodes() && ec2.isEc2Node(node)) { - LOGGER.log(Level.INFO, "Requesting stop on {0} of {1}", new Object[] {ec2.getCloudName(), node.getNodeName()}); + LOGGER.log(Level.FINE, "Requesting stop on {0} of {1}", new Object[] {ec2.getCloudName(), node.getNodeName()}); try { ec2.stopNode(node); } catch (Exception e) { diff --git a/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/config-entries.jelly b/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/config-entries.jelly index 7a3a97140..4a33ce909 100644 --- a/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/config-entries.jelly +++ b/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/config-entries.jelly @@ -55,12 +55,15 @@ THE SOFTWARE. - + + + + diff --git a/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-nodeTagForEc2.html b/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-nodeLabelForEc2.html similarity index 100% rename from src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-nodeTagForEc2.html rename to src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-nodeLabelForEc2.html diff --git a/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-preventStopAwsTag.html b/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-preventStopAwsTag.html new file mode 100644 index 000000000..a465ee3a7 --- /dev/null +++ b/src/main/resources/hudson/plugins/ec2/AmazonEC2Cloud/help-preventStopAwsTag.html @@ -0,0 +1,2 @@ +Marker tag used on EC2 instances that should not be stopped by this plugin. +Tag value is not checked as the presence of the tag is enough to prevent the plugin from stopping the instance. \ No newline at end of file