Skip to content

Commit 395500f

Browse files
authored
Merge pull request #46 from jeyrschabu/fixnotifications
refactor(notifications): Updating notifications
2 parents 1acc870 + 3e1a8bc commit 395500f

15 files changed

Lines changed: 77 additions & 106 deletions

File tree

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ It applies a set of rules to mark cleanup candidates. Once marked, a resource is
1010
```
1111
swabbie:
1212
taggingEnabled: false
13-
optOut:
14-
url: http://localhost:8088/
15-
defaultTtlDays: 14
13+
optOutBaseUrl: http://localhost:8088/
14+
spinnakerResourceSearchUrl: https://spinnaker/infrastructure?q=
1615
1716
agents:
1817
mark:
@@ -58,6 +57,12 @@ swabbie:
5857
dryRun: true
5958
retentionDays: 14
6059
notifyOwner: false
60+
exclusions:
61+
- type: Whitelist
62+
attributes:
63+
- key: application
64+
value:
65+
- appname
6166
6267
```
6368

swabbie-core/src/main/kotlin/com/netflix/spinnaker/config/SwabbieProperties.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties
2222
open class SwabbieProperties {
2323
var dryRun: Boolean = true
2424
var providers: List<CloudProviderConfiguration> = mutableListOf()
25+
var optOutBaseUrl: String = ""
26+
var spinnakerResourceSearchUrl: String = ""
2527
}
2628

2729
class CloudProviderConfiguration {
@@ -30,9 +32,11 @@ class CloudProviderConfiguration {
3032
var locations: List<String> = mutableListOf()
3133
var accounts: List<String> = mutableListOf()
3234
var resourceTypes: List<ResourceTypeConfiguration> = mutableListOf()
35+
var resourcesPerNotification: Int = 10
3336
override fun toString(): String {
34-
return "CloudProviderConfiguration(exclusions=$exclusions, name='$name', locations=$locations, accounts=$accounts, resourceTypes=$resourceTypes)"
37+
return "CloudProviderConfiguration(exclusions=$exclusions, name='$name', locations=$locations, accounts=$accounts, resourceTypes=$resourceTypes, resourcesPerNotification=$resourcesPerNotification)"
3538
}
39+
3640
}
3741

3842
class Exclusion {

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/AbstractResourceTypeHandler.kt

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,24 +181,32 @@ abstract class AbstractResourceTypeHandler<out T : Resource>(
181181
}
182182

183183
owners.let { ownersToResources ->
184-
val optOutUrl = "https://localhost:1000" //TODO: pass in configuration
185-
ownersToResources.forEach { ownerToResource ->
184+
ownersToResources.forEach { ownerToResources ->
186185
log.info("DryRun={}, shouldNotify={}, user={}, {} cleanup candidate(s)",
187-
workConfiguration.dryRun, workConfiguration.notifyOwner, ownerToResource.key, ownerToResource.value.size)
188-
if (workConfiguration.dryRun || !workConfiguration.notifyOwner) {
186+
workConfiguration.dryRun, workConfiguration.notificationConfiguration!!.notifyOwner, ownerToResources.key, ownerToResources.value.size)
187+
if (workConfiguration.dryRun || !workConfiguration.notificationConfiguration.notifyOwner) {
189188
log.info("Skipping notifications for {}", workConfiguration)
190189
} else {
191-
ownerToResource.value.let { resources ->
192-
val subject = NotificationMessage.subject(MessageType.EMAIL, clock, *resources.toTypedArray())
193-
val body = NotificationMessage.body(MessageType.EMAIL, clock, optOutUrl, *resources.toTypedArray())
194-
notifier.notify(ownerToResource.key, subject, body, EchoService.Notification.Type.EMAIL.name).let {
195-
log.info("Notification sent to {} for {}", ownerToResource.key, resources)
190+
ownerToResources.value.let { resources ->
191+
notifier.notify(
192+
recipient = ownerToResources.key,
193+
messageType = EchoService.Notification.Type.EMAIL.name,
194+
additionalContext = mapOf(
195+
"resourceOwner" to ownerToResources.key,
196+
"resources" to resources,
197+
"configuration" to workConfiguration,
198+
"resourceType" to workConfiguration.resourceType.formatted(),
199+
"spinnakerLink" to workConfiguration.notificationConfiguration.spinnakerResourceUrl,
200+
"optOutLink" to workConfiguration.notificationConfiguration.optOutUrl
201+
)
202+
).let {
203+
log.info("Notification sent to {} for {}", ownerToResources.key, resources)
196204
resources.forEach { resource ->
197205
val offsetStampSinceMarked: Long = ChronoUnit.MILLIS.between(Instant.ofEpochMilli(resource.createdTs!!), Instant.now(clock))
198206
resource.apply {
199-
projectedDeletionStamp = offsetStampSinceMarked + projectedDeletionStamp!!
207+
projectedDeletionStamp += offsetStampSinceMarked
200208
notificationInfo = NotificationInfo(
201-
recipient = ownerToResource.key,
209+
recipient = ownerToResources.key,
202210
notificationStamp = Instant.now(clock).toEpochMilli(),
203211
notificationType = EchoService.Notification.Type.EMAIL.name
204212
)

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/AgentRunner.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class LockEnabledAgentRunner(
3939
workConfiguration.takeIf {
4040
lock(agent, workConfiguration, acquire = true)
4141
}?.let {
42-
log.info("{} processing {}", agentName, workConfiguration)
42+
log.info("{} running with configuration {}", agentName, workConfiguration)
4343
agent.process(
4444
workConfiguration = workConfiguration,
4545
onCompleteCallback = {

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/WorkConfigurator.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.netflix.spinnaker.config.mergeExclusions
2121
import com.netflix.spinnaker.swabbie.exclusions.ExclusionPolicy
2222
import com.netflix.spinnaker.swabbie.model.Account
2323
import com.netflix.spinnaker.swabbie.model.EmptyAccount
24+
import com.netflix.spinnaker.swabbie.model.NotificationConfiguration
2425
import com.netflix.spinnaker.swabbie.model.WorkConfiguration
2526
import org.slf4j.Logger
2627
import org.slf4j.LoggerFactory
@@ -71,8 +72,13 @@ class WorkConfigurator(
7172
resourceType = resourceTypeConfiguration.name,
7273
retentionDays = resourceTypeConfiguration.retentionDays,
7374
exclusions = mergeExclusions(cloudProviderConfiguration.exclusions, resourceTypeConfiguration.exclusions),
74-
notifyOwner = resourceTypeConfiguration.notifyOwner,
75-
dryRun = if (swabbieProperties.dryRun) true else resourceTypeConfiguration.dryRun
75+
dryRun = if (swabbieProperties.dryRun) true else resourceTypeConfiguration.dryRun,
76+
notificationConfiguration = NotificationConfiguration(
77+
notifyOwner = resourceTypeConfiguration.notifyOwner,
78+
spinnakerResourceUrl = swabbieProperties.spinnakerResourceSearchUrl,
79+
optOutUrl = swabbieProperties.optOutBaseUrl,
80+
resourcesPerNotification = cloudProviderConfiguration.resourcesPerNotification
81+
)
7682
).let { configuration ->
7783
configuration.takeIf {
7884
!shouldExclude(account, it)

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/events/ResourceStateManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ class ResourceStateManager(
126126
}
127127

128128
internal fun MarkedResource.typeAndName(): String = this.resourceType.split("(?=[A-Z])".toRegex()).joinToString(" ") + ": " + this.name
129+
internal fun String.formatted(): String = this.split("(?=[A-Z])".toRegex()).joinToString(" ").toLowerCase()

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/model/WorkConfiguration.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,14 @@ data class WorkConfiguration(
2727
val retentionDays: Int,
2828
val exclusions: List<Exclusion>,
2929
val dryRun: Boolean = true,
30-
val notifyOwner: Boolean
30+
val notificationConfiguration: NotificationConfiguration? = EmptyNotificationConfiguration()
3131
)
32+
33+
open class NotificationConfiguration(
34+
val notifyOwner: Boolean,
35+
val optOutUrl: String,
36+
val resourcesPerNotification: Int,
37+
val spinnakerResourceUrl: String
38+
)
39+
40+
class EmptyNotificationConfiguration : NotificationConfiguration(false, "", 0, "")

swabbie-core/src/main/kotlin/com/netflix/spinnaker/swabbie/notificationMessages.kt

Lines changed: 0 additions & 61 deletions
This file was deleted.

swabbie-core/src/test/kotlin/com/netflix/spinnaker/swabbie/ResourceTypeHandlerTest.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,7 @@ object ResourceTypeHandlerTest {
286286
cloudProvider = TEST_RESOURCE_PROVIDER_TYPE,
287287
retentionDays = 14,
288288
dryRun = dryRun,
289-
exclusions = exclusions,
290-
notifyOwner = notifyOwner
289+
exclusions = exclusions
291290
)
292291

293292
class TestRule(

swabbie-echo/src/main/kotlin/com/netflix/spinnaker/swabbie/echo/EchoNotifier.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,16 @@ import org.springframework.stereotype.Component
2222
class EchoNotifier(
2323
private val echoService: EchoService
2424
) : Notifier {
25-
override fun notify(recipient: String, subject: String, body: String, messageType: String) {
25+
override fun notify(recipient: String, additionalContext: Map<String, Any>, messageType: String) {
2626
echoService.create(
2727
EchoService.Notification(
2828
notificationType = EchoService.Notification.Type.valueOf(messageType),
2929
to = listOf(recipient),
3030
cc = listOf(recipient),
3131
severity = NotificationSeverity.HIGH,
3232
source = EchoService.Notification.Source("swabbie"),
33-
additionalContext = mapOf(
34-
"subject" to subject,
35-
"body" to body
36-
)
33+
templateGroup = "swabbie",
34+
additionalContext = additionalContext
3735
)
3836
)
3937
}

0 commit comments

Comments
 (0)