Skip to content

Commit 50ec002

Browse files
committed
Merge pull request Netflix#227 from ebukoski/master
NoGeneratedAMIRule: Add a property to override owner email
2 parents 2469f40 + f8c743e commit 50ec002

3 files changed

Lines changed: 61 additions & 2 deletions

File tree

src/main/java/com/netflix/simianarmy/aws/janitor/rule/snapshot/NoGeneratedAMIRule.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public class NoGeneratedAMIRule implements Rule {
4444
/** The Constant LOGGER. */
4545
private static final Logger LOGGER = LoggerFactory.getLogger(NoGeneratedAMIRule.class);
4646

47+
private String ownerEmailOverride = null;
48+
4749
private static final String TERMINATION_REASON = "No AMI is generated for this snapshot";
4850

4951
private final MonkeyCalendar calendar;
@@ -67,14 +69,33 @@ public class NoGeneratedAMIRule implements Rule {
6769
* as cleanup candidate
6870
*/
6971
public NoGeneratedAMIRule(MonkeyCalendar calendar, int ageThreshold, int retentionDays) {
72+
this(calendar, ageThreshold, retentionDays, null);
73+
}
74+
75+
/**
76+
* Constructor.
77+
*
78+
* @param calendar
79+
* The calendar used to calculate the termination time
80+
* @param ageThreshold
81+
* The number of days that a snapshot is considered as cleanup candidate since it is created
82+
* @param retentionDays
83+
* The number of days that the volume is retained before being terminated after being marked
84+
* as cleanup candidate
85+
* @param ownerEmailOverride
86+
* If null, send notifications to the resource owner.
87+
* If not null, send notifications to the provided owner email address instead of the resource owner.
88+
*/
89+
public NoGeneratedAMIRule(MonkeyCalendar calendar, int ageThreshold, int retentionDays, String ownerEmailOverride) {
7090
Validate.notNull(calendar);
7191
Validate.isTrue(ageThreshold >= 0);
7292
Validate.isTrue(retentionDays >= 0);
7393
this.calendar = calendar;
7494
this.ageThreshold = ageThreshold;
7595
this.retentionDays = retentionDays;
96+
this.ownerEmailOverride = ownerEmailOverride;
7697
}
77-
98+
7899
@Override
79100
public boolean isValid(Resource resource) {
80101
Validate.notNull(resource);
@@ -96,6 +117,9 @@ public boolean isValid(Resource resource) {
96117
Date userSpecifiedDate = new Date(TERMINATION_DATE_FORMATTER.parseDateTime(janitorTag).getMillis());
97118
resource.setExpectedTerminationTime(userSpecifiedDate);
98119
resource.setTerminationReason(String.format("User specified termination date %s", janitorTag));
120+
if (ownerEmailOverride != null) {
121+
resource.setOwnerEmail(ownerEmailOverride);
122+
}
99123
return false;
100124
} catch (Exception e) {
101125
LOGGER.error(String.format("The janitor tag is not a user specified date: %s", janitorTag));
@@ -113,6 +137,9 @@ public boolean isValid(Resource resource) {
113137
DateTime launchTime = new DateTime(resource.getLaunchTime().getTime());
114138
DateTime now = new DateTime(calendar.now().getTimeInMillis());
115139
if (launchTime.plusDays(ageThreshold).isBefore(now)) {
140+
if (ownerEmailOverride != null) {
141+
resource.setOwnerEmail(ownerEmailOverride);
142+
}
116143
if (resource.getExpectedTerminationTime() == null) {
117144
Date terminationTime = calendar.getBusinessDay(new Date(now.getMillis()), retentionDays);
118145
resource.setExpectedTerminationTime(terminationTime);

src/main/java/com/netflix/simianarmy/basic/janitor/BasicJanitorMonkeyContext.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@ private EBSSnapshotJanitor getEBSSnapshotJanitor() {
293293
ruleEngine.addRule(new NoGeneratedAMIRule(monkeyCalendar,
294294
(int) configuration().getNumOrElse("simianarmy.janitor.rule.noGeneratedAMIRule.ageThreshold", 30),
295295
(int) configuration().getNumOrElse(
296-
"simianarmy.janitor.rule.noGeneratedAMIRule.retentionDays", 7)));
296+
"simianarmy.janitor.rule.noGeneratedAMIRule.retentionDays", 7),
297+
configuration().getStrOrElse(
298+
"simianarmy.janitor.rule.noGeneratedAMIRule.ownerEmail", null)));
297299
}
298300
if (configuration().getBoolOrElse("simianarmy.janitor.rule.untaggedRule.enabled", false)) {
299301
ruleEngine.addRule(new UntaggedRule(monkeyCalendar, getPropertySet("simianarmy.janitor.rule.untaggedRule.requiredTags"),

src/test/java/com/netflix/simianarmy/aws/janitor/rule/snapshot/TestNoGeneratedAMIRule.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,36 @@ public void testResourceWithExpectedTerminationTimeSet() {
162162
Assert.assertEquals(oldTermReason, resource.getTerminationReason());
163163
}
164164

165+
@Test
166+
public void testOldSnapshotWithoutAMIWithOwnerOverride() {
167+
int ageThreshold = 5;
168+
DateTime now = DateTime.now();
169+
Resource resource = new AWSResource().withId("snap123").withOwnerEmail("owner@netflix.com").withResourceType(AWSResourceType.EBS_SNAPSHOT)
170+
.withLaunchTime(new Date(now.minusDays(ageThreshold + 1).getMillis()));
171+
((AWSResource) resource).setAWSResourceState("completed");
172+
int retentionDays = 4;
173+
NoGeneratedAMIRule rule = new NoGeneratedAMIRule(new TestMonkeyCalendar(),
174+
ageThreshold, retentionDays, "new_owner@netflix.com");
175+
Assert.assertFalse(rule.isValid(resource));
176+
Assert.assertEquals(resource.getOwnerEmail(), "new_owner@netflix.com");
177+
TestUtils.verifyTerminationTimeRough(resource, retentionDays, now);
178+
}
179+
180+
@Test
181+
public void testOldSnapshotWithoutAMIWithoutOwnerOverride() {
182+
int ageThreshold = 5;
183+
DateTime now = DateTime.now();
184+
Resource resource = new AWSResource().withId("snap123").withOwnerEmail("owner@netflix.com").withResourceType(AWSResourceType.EBS_SNAPSHOT)
185+
.withLaunchTime(new Date(now.minusDays(ageThreshold + 1).getMillis()));
186+
((AWSResource) resource).setAWSResourceState("completed");
187+
int retentionDays = 4;
188+
NoGeneratedAMIRule rule = new NoGeneratedAMIRule(new TestMonkeyCalendar(),
189+
ageThreshold, retentionDays);
190+
Assert.assertFalse(rule.isValid(resource));
191+
Assert.assertEquals(resource.getOwnerEmail(), "owner@netflix.com");
192+
TestUtils.verifyTerminationTimeRough(resource, retentionDays, now);
193+
}
194+
165195
@Test(expectedExceptions = IllegalArgumentException.class)
166196
public void testNullResource() {
167197
NoGeneratedAMIRule rule = new NoGeneratedAMIRule(new TestMonkeyCalendar(), 5, 4);

0 commit comments

Comments
 (0)