Skip to content

Commit

Permalink
feat(schedule): deletion timestamp in schedule (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
emjburns authored Nov 7, 2018
1 parent 0477f21 commit e52eb9f
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.netflix.spinnaker.swabbie.aws.autoscalinggroups

import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.SwabbieProperties
import com.netflix.spinnaker.kork.core.RetrySupport
import com.netflix.spinnaker.moniker.frigga.FriggaReflectiveNamer
import com.netflix.spinnaker.swabbie.AbstractResourceTypeHandler
Expand Down Expand Up @@ -54,6 +55,7 @@ class AmazonAutoScalingGroupHandler(
applicationEventPublisher: ApplicationEventPublisher,
lockingService: Optional<LockingService>,
retrySupport: RetrySupport,
swabbieProperties: SwabbieProperties,
private val rules: List<Rule<AmazonAutoScalingGroup>>,
private val serverGroupProvider: ResourceProvider<AmazonAutoScalingGroup>,
private val orcaService: OrcaService,
Expand All @@ -71,7 +73,8 @@ class AmazonAutoScalingGroupHandler(
applicationEventPublisher,
lockingService,
retrySupport,
resourceUseTrackingRepository
resourceUseTrackingRepository,
swabbieProperties
) {

override fun softDeleteResources(markedResources: List<MarkedResource>, workConfiguration: WorkConfiguration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ class AmazonImageHandler(
applicationEventPublisher,
lockingService,
retrySupport,
resourceUseTrackingRepository
resourceUseTrackingRepository,
swabbieProperties
) {

override fun deleteResources(markedResources: List<MarkedResource>, workConfiguration: WorkConfiguration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.netflix.spinnaker.swabbie.aws.loadbalancers

import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.SwabbieProperties
import com.netflix.spinnaker.kork.core.RetrySupport
import com.netflix.spinnaker.moniker.frigga.FriggaReflectiveNamer
import com.netflix.spinnaker.swabbie.*
Expand Down Expand Up @@ -48,6 +49,7 @@ class AmazonLoadBalancerHandler(
applicationEventPublisher: ApplicationEventPublisher,
lockingService: Optional<LockingService>,
retrySupport: RetrySupport,
swabbieProperties: SwabbieProperties,
private val rules: List<Rule<AmazonElasticLoadBalancer>>,
private val loadBalancerProvider: ResourceProvider<AmazonElasticLoadBalancer>,
private val serverGroupProvider: ResourceProvider<AmazonAutoScalingGroup>,
Expand All @@ -66,7 +68,8 @@ class AmazonLoadBalancerHandler(
applicationEventPublisher,
lockingService,
retrySupport,
resourceUseTrackingRepository
resourceUseTrackingRepository,
swabbieProperties
) {
override fun deleteResources(
markedResources: List<MarkedResource>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.netflix.spinnaker.swabbie.aws.securitygroups

import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.SwabbieProperties
import com.netflix.spinnaker.kork.core.RetrySupport
import com.netflix.spinnaker.moniker.frigga.FriggaReflectiveNamer
import com.netflix.spinnaker.swabbie.*
Expand Down Expand Up @@ -46,6 +47,7 @@ class AmazonSecurityGroupHandler(
applicationEventPublisher: ApplicationEventPublisher,
lockingService: Optional<LockingService>,
retrySupport: RetrySupport,
swabbieProperties: SwabbieProperties,
private val rules: List<Rule<AmazonSecurityGroup>>,
private val securityGroupProvider: ResourceProvider<AmazonSecurityGroup>,
private val orcaService: OrcaService,
Expand All @@ -63,7 +65,8 @@ class AmazonSecurityGroupHandler(
applicationEventPublisher,
lockingService,
retrySupport,
resourceUseTrackingRepository
resourceUseTrackingRepository,
swabbieProperties
) {
override fun deleteResources(
markedResources: List<MarkedResource>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ object AmazonAutoScalingGroupHandlerTest {
retrySupport = RetrySupport(),
serverGroupProvider = serverGroupProvider,
orcaService = orcaService,
resourceUseTrackingRepository = resourceUseTrackingRepository
resourceUseTrackingRepository = resourceUseTrackingRepository,
swabbieProperties = SwabbieProperties().also { it.schedule.enabled = false }
)

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ package com.netflix.spinnaker.config
import com.netflix.spinnaker.swabbie.model.EmptyNotificationConfiguration
import com.netflix.spinnaker.swabbie.model.SoftDelete
import org.springframework.boot.context.properties.ConfigurationProperties
import java.time.DayOfWeek
import java.time.LocalTime
import java.time.ZoneId
import java.time.*

/**
* @param minImagesUsedByLC minimum number of images used by launch configurations that should be
Expand Down Expand Up @@ -207,6 +205,27 @@ class Schedule {
fun getZoneId(): ZoneId {
return ZoneId.of(defaultTimeZone)
}

/**
* Returns proposed timestamp or next time in window
*/
fun getNextTimeInWindow(proposedTimestamp: Long): Long {
return if (!enabled || getResolvedDays().isEmpty()) {
proposedTimestamp
} else {
var day = dayFromTimestamp(proposedTimestamp)
var incDays = 0
while (!getResolvedDays().contains(day)) {
day = day.plus(1)
incDays += 1
}
proposedTimestamp.plus(Duration.ofDays(incDays.toLong()).toMillis())
}
}

private fun dayFromTimestamp(timestamp: Long): DayOfWeek {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of(defaultTimeZone)).dayOfWeek
}
}

enum class ExclusionType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.netflix.spinnaker.swabbie

import com.google.common.collect.Lists
import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.SwabbieProperties
import com.netflix.spinnaker.kork.core.RetrySupport
import com.netflix.spinnaker.kork.lock.LockManager.LockOptions
import com.netflix.spinnaker.kork.web.exceptions.NotFoundException
Expand Down Expand Up @@ -61,7 +62,8 @@ abstract class AbstractResourceTypeHandler<T : Resource>(
private val applicationEventPublisher: ApplicationEventPublisher,
private val lockingService: Optional<LockingService>,
private val retrySupport: RetrySupport,
private val resourceUseTrackingRepository: ResourceUseTrackingRepository
private val resourceUseTrackingRepository: ResourceUseTrackingRepository,
private val swabbieProperties: SwabbieProperties
) : ResourceTypeHandler<T>, MetricsSupport(registry) {
protected val log: Logger = LoggerFactory.getLogger(javaClass)
private val resourceOwnerField: String = "swabbieResourceOwner"
Expand Down Expand Up @@ -382,16 +384,20 @@ abstract class AbstractResourceTypeHandler<T : Resource>(
}
}

private fun softDeletionTimestamp(workConfiguration: WorkConfiguration): Long =
(workConfiguration.retention + 1).days.fromNow.atStartOfDay(clock.zone).toInstant().toEpochMilli()
private fun softDeletionTimestamp(workConfiguration: WorkConfiguration): Long {
val daysInFuture = workConfiguration.retention + 1
val proposedTime = daysInFuture.days.fromNow.atStartOfDay(clock.zone).toInstant().toEpochMilli()
return swabbieProperties.schedule.getNextTimeInWindow(proposedTime)
}

private fun deletionTimestamp(workConfiguration: WorkConfiguration): Long {
if (!workConfiguration.softDelete.enabled) {
// soft deleting is not enabled, so our deletion time is the same as what our soft deletion time would be
return softDeletionTimestamp(workConfiguration)
}
return (workConfiguration.retention + workConfiguration.softDelete.waitingPeriodDays + 1)
.days.fromNow.atStartOfDay(clock.zone).toInstant().toEpochMilli()
val daysInFuture = workConfiguration.retention + workConfiguration.softDelete.waitingPeriodDays + 1
val proposedTime = daysInFuture.days.fromNow.atStartOfDay(clock.zone).toInstant().toEpochMilli()
return swabbieProperties.schedule.getNextTimeInWindow(proposedTime)
}

private fun printResult(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.netflix.spectator.api.Registry
import com.netflix.spinnaker.config.Attribute
import com.netflix.spinnaker.config.Exclusion
import com.netflix.spinnaker.config.ExclusionType
import com.netflix.spinnaker.config.SwabbieProperties
import com.netflix.spinnaker.kork.core.RetrySupport
import com.netflix.spinnaker.swabbie.events.Action
import com.netflix.spinnaker.swabbie.events.MarkResourceEvent
Expand Down Expand Up @@ -622,7 +623,8 @@ object ResourceTypeHandlerTest {
applicationEventPublisher,
lockingService,
retrySupport,
resourceUseTrackingRepository
resourceUseTrackingRepository,
SwabbieProperties()
) {
override fun deleteResources(
markedResources: List<MarkedResource>,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
*
* Copyright 2018 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

import com.natpryce.hamkrest.equalTo
import com.natpryce.hamkrest.should.shouldMatch
import com.netflix.spinnaker.config.Schedule
import org.junit.jupiter.api.Test
import java.time.Instant

object ScheduleTest {
private val subject = Schedule().also { it.enabled = true }

val mondayTimestamp = Instant.parse("2018-05-21T12:00:00Z")
val satTimestamp = Instant.parse("2018-05-26T12:00:00Z")
val followingMondayTimestamp = Instant.parse("2018-05-28T12:00:00Z")

@Test
fun `should return timestamp when day is in the schedule`() {
subject.getNextTimeInWindow(mondayTimestamp.toEpochMilli()) shouldMatch equalTo(mondayTimestamp.toEpochMilli())
}

@Test
fun `should return monday when saturday is the proposed timestamp`() {
subject.getNextTimeInWindow(satTimestamp.toEpochMilli()) shouldMatch equalTo(followingMondayTimestamp.toEpochMilli())
}
}

0 comments on commit e52eb9f

Please sign in to comment.