Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DCPERF-747 Allow overriding the resource_owner label #27

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ Dropping a requirement of a major version of a dependency is a new contract.
## [Unreleased]
[Unreleased]: https://github.com/atlassian-labs/aws-resources/compare/release-1.17.0...master

### Added
- Add `Investment.Builder`
- Allow overriding the resource_owner label in `Investment.Builder`

### Changed
- Changed resource_owner default label to point to current Atlassian JPT maintainer

## [1.17.0] - 2024-06-14
[1.17.0]: https://github.com/atlassian-labs/aws-resources/compare/release-1.16.0...release-1.17.0

Expand Down
22 changes: 12 additions & 10 deletions src/main/kotlin/com/atlassian/performance/tools/aws/api/Aws.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,13 @@ class Aws private constructor(

private val shortTermStorage: ProvisionedStack by lazy {
StackFormula(
investment = Investment(
investment = Investment.Builder(
useCase = "Transport files necessary to run the tests",
reuseKey = { "jpt-short-term-storage" },
lifespan = Duration.ofDays(30),
disposable = false
),
lifespan = Duration.ofDays(30)
)
.disposable(false)
.reuseKey { "jpt-short-term-storage" }
.build(),
cloudformationTemplate = readResourceText("aws/short-term-storage.yaml"),
parameters = listOf(
Parameter().withParameterKey("PermissionBoundaryPolicyARN")
Expand All @@ -130,12 +131,13 @@ class Aws private constructor(

private val customDatasetStorage: ProvisionedStack by lazy {
StackFormula(
investment = Investment(
investment = Investment.Builder(
useCase = "Store custom datasets",
reuseKey = { "jpt-custom-datasets-storage" },
lifespan = Duration.ofDays(800),
disposable = false
),
lifespan = Duration.ofDays(800)
)
.disposable(false)
.reuseKey { "jpt-custom-datasets-storage" }
.build(),
cloudformationTemplate = readResourceText("aws/custom-datasets-storage.yaml"),
aws = this
).provision()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,39 @@ import com.amazonaws.services.ec2.model.Tag as Ec2Tag
* - value proposition
* - cost factors
* - accountability tracking
*
* @param useCase the value proposition for the investment
* @param lifespan pessimistic estimate of the duration of the investment, higher values mean higher cost
* @param disposable if true, then the investment can be cancelled even before [lifespan] and get its cost reduced
* @param reuseKey if a new investment would have the same reuse key as an existing investment, the old one can be
* reused, reducing the cost
*/
data class Investment(
data class Investment
private constructor(
private val useCase: String,
val lifespan: Duration,
private val disposable: Boolean = true,
val reuseKey: () -> String = { "jpt-${UUID.randomUUID()}" }
val reuseKey: () -> String = { "jpt-${UUID.randomUUID()}" },
private val resourceOwner: String = defaultResourceOwner
) {
/**
*
* @param useCase the value proposition for the investment
* @param lifespan pessimistic estimate of the duration of the investment, higher values mean higher cost
* @param disposable if true, then the investment can be cancelled even before [lifespan] and get its cost reduced
* @param reuseKey if a new investment would have the same reuse key as an existing investment, the old one can be
* reused, reducing the cost
*/
@Deprecated(
message = "Use Builder instead. Public constructor will be be removed in the next major version.",
replaceWith = ReplaceWith(
expression = "Investment.Builder(useCase = useCase, lifespan = lifespan)" +
".disposable(disposable)" +
".reuseKey(reuseKey)" +
".build()"
)
)
constructor(
useCase: String,
lifespan: Duration,
disposable: Boolean = true,
reuseKey: () -> String = { "jpt-${UUID.randomUUID()}" }
) : this(useCase, lifespan, disposable, reuseKey, defaultResourceOwner)

/**
* @return tags useful for tracking accountability of the investment
*/
Expand All @@ -37,7 +57,7 @@ data class Investment(
Tag("Name", "Jira Performance Tests"),
Tag("service_name", useCase),
Tag("business_unit", "Engineering-Server"),
Tag("resource_owner", "mgrzaslewicz")
Tag("resource_owner", resourceOwner)
)

/**
Expand Down Expand Up @@ -66,12 +86,55 @@ data class Investment(
}
}

/**
* Describes an investment:
* - value proposition
* - cost factors
* - accountability tracking
*
* @param useCase the value proposition for the investment
* @param lifespan pessimistic estimate of the duration of the investment, higher values mean higher cost
*/
class Builder(
private val useCase: String,
private val lifespan: Duration
) {
private var disposable: Boolean = true
private var reuseKey: () -> String = { "jpt-${UUID.randomUUID()}" }
private var resourceOwner: String = defaultResourceOwner

/**
* @param disposable if true, then the investment can be cancelled even before [lifespan] and get its cost reduced
*/
fun disposable(disposable: Boolean) = apply { this.disposable = disposable }
/**
* @param reuseKey if a new investment would have the same reuse key as an existing investment, the old one can be
* reused, reducing the cost
*/
fun reuseKey(reuseKey: () -> String) = apply { this.reuseKey = reuseKey }
/**
* @param resourceOwner AWS resource owner, defaults to current Atlassian JPT maintainer
*/
fun resourceOwner(resourceOwner: String) = apply { this.resourceOwner = resourceOwner }

fun build(): Investment {
return Investment(
useCase = useCase,
lifespan = lifespan,
disposable = disposable,
reuseKey = reuseKey,
resourceOwner = resourceOwner
)
}
}

companion object TagKeys {
const val lifespanKey = "lifespan"
private const val expiryKey = "expiry"
const val userKey = "os_user_name"
const val bambooBuildKey = "bamboo_result_key"
const val disposableKey = "disposable"
private const val defaultResourceOwner = "jforemski"

fun parseLifespan(
tags: List<Tag>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,12 @@ class SshAmiMod private constructor(

private val useCase = sshInstanceMod.useCase

private val amiInvestment = Investment(
useCase = useCase,
lifespan = amiLifespan
)
private val amiInvestment = Investment.Builder(useCase, amiLifespan).build()
private val expectedImageSavingTime = Duration.ofMinutes(6)
private val instanceInvestment = Investment(
private val instanceInvestment = Investment.Builder(
useCase = useCase,
lifespan = sshInstanceMod.expectedDuration + expectedImageSavingTime
)
).build()

/**
* If the [amiCache] finds an AMI matching [sshInstanceMod] and [amiProvider], it will be reused.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import java.util.*

class AwsIT {

private val investment = Investment(
private val investment = Investment.Builder(
useCase = "Test aws-resources library",
lifespan = Duration.ofMinutes(5),
disposable = true
lifespan = Duration.ofMinutes(5)
)
.disposable(true)
.build()
private val workspace = Files.createTempDirectory("AwsIT-")
private val awsPrefix = "aws-resources-test-"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class StackFormulaTest {
@Timeout(5, unit = SECONDS)
fun shouldNotHang() {
val formula = StackFormula(
investment = Investment(
investment = Investment.Builder(
useCase = "Unit test the StackFormula",
lifespan = Duration.ofMinutes(1)
),
lifespan = Duration.ofMinutes(1))
.build(),
aws = FakeAws.awsForUnitTests(
batchingCloudformationRefreshPeriod = Duration.ofMillis(100),
credentialsProvider = MissingCredentialsProvider()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SshAmiModIT {
val newImageId = sshAmiMod.provideAmiId(aws)

// then
val investment = Investment(echo.useCase, Duration.ofMinutes(10))
val investment = Investment.Builder(echo.useCase, Duration.ofMinutes(10)).build()
val prefix = investment.reuseKey()
val sshKey = SshKeyFormula(aws.ec2, createTempDirectory(prefix), prefix, investment.lifespan).provision()
aws.awaitingEc2.allocateInstance(investment, sshKey, vpcId = null) { launch ->
Expand Down
Loading