Skip to content

Commit

Permalink
- keep it simple, remove the need for a basic rule
Browse files Browse the repository at this point in the history
- renamed TemporalThresholdRule to ExpiredResourceRule
- Updated to use a clock to determine if resource is expired
- clean up test
  • Loading branch information
jeyrschabu committed Oct 20, 2019
1 parent 2e5060f commit 1d46fcc
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 237 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2019 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.swabbie.aws

import com.netflix.spinnaker.swabbie.aws.model.AmazonResource
import com.netflix.spinnaker.swabbie.model.Result
import com.netflix.spinnaker.swabbie.model.Rule
import com.netflix.spinnaker.swabbie.model.Summary
import org.springframework.stereotype.Component
import java.time.Clock

/**
* This rule applies if this amazon resource has expired.
* A resource is expired if it's tagged with the following keys: ("expiration_time", "expires", "ttl")
* Acceptable tag value: a number followed by a prefix such as d (days), w (weeks), m (month), y (year)
* @see com.netflix.spinnaker.swabbie.tagging.TemporalTags.supportedTemporalTagValues
*/

@Component
class ExpiredResourceRule<T : AmazonResource>(
val clock: Clock
) : Rule<T> {
override fun apply(resource: T): Result {
if (resource.expired(clock)) {
return Result(
Summary(
description = "$${resource.resourceId} has expired. tags: ${resource.tags()}",
ruleName = javaClass.simpleName
)
)
}

return Result(null)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@ import com.netflix.spinnaker.swabbie.aws.model.AmazonResource
import com.netflix.spinnaker.swabbie.exclusions.Excludable
import com.netflix.spinnaker.swabbie.exclusions.ResourceExclusionPolicy
import org.springframework.stereotype.Component
import java.time.Clock

@Component
class AmazonTagExclusionPolicy : ResourceExclusionPolicy {
class AmazonTagExclusionPolicy(
val clock: Clock
) : ResourceExclusionPolicy {
override fun getType(): ExclusionType = ExclusionType.Tag
override fun apply(excludable: Excludable, exclusions: List<Exclusion>): String? {
if (excludable !is AmazonResource || excludable.tags().isNullOrEmpty()) {
return null
}

val tags = excludable.tags()!!
if (excludable.expired()) {
val temporalTag = tags.find { excludable.expired(it) }!!
if (excludable.expired(clock)) {
val temporalTag = tags.find { excludable.expired(it, clock) }!!
return patternMatchMessage(temporalTag.key, setOf(temporalTag.value as String))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2019 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.swabbie.aws

import com.netflix.spinnaker.kork.test.time.MutableClock
import com.netflix.spinnaker.swabbie.aws.autoscalinggroups.AmazonAutoScalingGroup
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import strikt.api.expectThat
import strikt.assertions.isNotNull
import strikt.assertions.isNull
import java.time.Duration
import java.time.Instant

object ExpiredResourceRuleTest {
private val clock = MutableClock()
private val subject = ExpiredResourceRule<AmazonAutoScalingGroup>(clock)
private val now = Instant.now(clock).toEpochMilli()
private val asg = AmazonAutoScalingGroup(
autoScalingGroupName = "testapp-v001",
instances = listOf(
mapOf("instanceId" to "i-01234")
),
loadBalancerNames = listOf(),
createdTime = now
)

@BeforeEach
fun setup() {
asg.set("tags", null)
}

@Test
fun `should not apply if resource is not tagged with a ttl`() {
expectThat(
subject.apply(asg).summary
).isNull()
}

@Test
fun `should not apply if resource is not expired`() {
val tags = listOf(
mapOf("ttl" to "4d")
)

asg.set("tags", tags)
expectThat(
subject.apply(asg).summary
).isNull()
}

@Test
fun `should apply if resource is expired`() {
val tags = listOf(
mapOf("ttl" to "2d")
)

asg.set("tags", tags)

clock.incrementBy(Duration.ofDays(3))
expectThat(
subject.apply(asg).summary
).isNotNull()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,23 @@ import com.natpryce.hamkrest.should.shouldMatch
import com.netflix.spinnaker.config.Attribute
import com.netflix.spinnaker.config.Exclusion
import com.netflix.spinnaker.config.ExclusionType
import com.netflix.spinnaker.kork.test.time.MutableClock
import com.netflix.spinnaker.swabbie.aws.model.AmazonResource
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.time.Duration
import java.time.Instant
import java.time.LocalDateTime

object AmazonTagExclusionPolicyTest {
private val clock = MutableClock()

@BeforeEach
fun setup() {
clock.instant(Instant.now())
}

private val subject = AmazonTagExclusionPolicy(clock)
@Test
fun `should exclude a resource with exclusion tag`() {
val exclusions = listOf(
Expand Down Expand Up @@ -60,7 +72,7 @@ object AmazonTagExclusionPolicyTest {
))

resources.filter {
AmazonTagExclusionPolicy().apply(it, exclusions) == null
subject.apply(it, exclusions) == null
}.let { filteredResources ->
filteredResources.size shouldMatch equalTo(1)
filteredResources.first().resourceId shouldMatch equalTo("2")
Expand All @@ -69,27 +81,30 @@ object AmazonTagExclusionPolicyTest {

@Test
fun `should exclude a resource based on temporal tags`() {
val tenDays = 10L
val now = LocalDateTime.now(clock)
val resources = listOf(
AwsTestResource(
id = "1",
creationDate = LocalDateTime.now().minusDays(tenDays).toString()
creationDate = now.toString()
).withDetail(
name = "tags",
value = listOf(
mapOf("expiration_time" to "${tenDays}d")
mapOf("expiration_time" to "10d")
)),
AwsTestResource(
id = "2",
creationDate = LocalDateTime.now().minusDays(tenDays).toString()
creationDate = now.toString()
).withDetail(
name = "tags",
value = listOf(
mapOf("expiration_time" to "${tenDays - 1}d")
mapOf("expiration_time" to "9d")
)
))

clock.incrementBy(Duration.ofDays(10))

resources.filter {
AmazonTagExclusionPolicy().apply(it, emptyList()) == null
subject.apply(it, emptyList()) == null
}.let { filteredResources ->
filteredResources.size shouldMatch equalTo(1)
filteredResources.first().resourceId shouldMatch equalTo("1")
Expand Down
1 change: 1 addition & 0 deletions swabbie-aws/swabbie-aws.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ dependencies {
implementation "com.fasterxml.jackson.module:jackson-module-kotlin"

testImplementation project(":swabbie-test")
testImplementation "com.netflix.spinnaker.kork:kork-test"
}
Loading

0 comments on commit 1d46fcc

Please sign in to comment.