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

Aliases support #532

Merged
merged 1 commit into from
Jul 12, 2024
Merged
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
2 changes: 1 addition & 1 deletion besom-cfg/k8s/project.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

//> using dep com.lihaoyi::os-lib::0.9.3
//> using dep org.virtuslab::besom-cfg:0.2.0-SNAPSHOT
//> using dep org.virtuslab::besom-kubernetes:4.14.0-core.0.4-SNAPSHOT
//> using dep org.virtuslab::besom-kubernetes:4.15.0-core.0.4-SNAPSHOT
//> using dep com.lihaoyi::fansi::0.5.0
//> using dep com.lihaoyi::fastparse:3.1.0

Expand Down
48 changes: 48 additions & 0 deletions core/src/main/scala/besom/internal/ResourceAlias.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package besom.internal

/** Allows to specify details of parent of resource for alias.
*/
sealed trait ResourceAliasParent

/** Allows to specify urn of parent.
* @param urn
* of parent
*/
final case class ResourceAliasParentUrn(urn: String) extends ResourceAliasParent

/** Allows to indicate that resource previously had no parent. This property is ignored when set to false.
* @param noParent
* set to true when no parent
*/
final case class ResourceAliasNoParent(noParent: Boolean) extends ResourceAliasParent

/** The alias for a resource or component resource. It can be any combination of the old name, type, parent, stack, and/or project values.
* Alternatively, you can just specify the URN directly.
*/
sealed trait ResourceAlias

/** Allows to specify urn of resource.
* @param urn
* of resource
*/
final case class UrnResourceAlias(urn: String) extends ResourceAlias

/** Allows to specify any combination of old name, type, parent, stack, and/or project values.
* @param name
* of the old resource
* @param `type`
* of the old resource
* @param stack
* of the old resource
* @param project
* of the old resource
* @param parent
* of the old resource
*/
final case class SpecResourceAlias(
name: Option[String] = None,
`type`: Option[String] = None,
stack: Option[String] = None,
project: Option[String] = None,
parent: Option[ResourceAliasParent] = None
) extends ResourceAlias
37 changes: 28 additions & 9 deletions core/src/main/scala/besom/internal/ResourceOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
providerId: Option[String],
providerRefs: Map[String, String],
depUrns: AggregatedDependencyUrns,
aliases: List[String],
aliases: List[ResourceAlias],
options: ResolvedResourceOptions
)

Expand All @@ -349,9 +349,6 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
private[internal] def resolveDeletedWithUrn(options: ResolvedResourceOptions): Result[Option[URN]] =
options.deletedWith.map(_.urn.getValue).getOrElse(Result.pure(None))

private[internal] def resolveAliases(@unused resource: Resource): Result[List[String]] =
Result.pure(List.empty) // TODO aliases

private[internal] def resolveProviderRegistrationId(state: ResourceState): Result[Option[String]] =
state match
case prs: ProviderResourceState =>
Expand Down Expand Up @@ -388,10 +385,17 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
providerRefs <- resolveProviderReferences(state)
_ <- log.trace(s"Preparing inputs: resolved provider refs, aggregating dep URNs")
depUrns <- aggregateDependencyUrns(directDeps, serResult.propertyToDependentResources, ctx.resources)
_ <- log.trace(s"Preparing inputs: aggregated dep URNs, resolving aliases")
aliases <- resolveAliases(resource)
_ <- log.trace(s"Preparing inputs: resolved aliases, done")
yield PreparedInputs(serResult.serialized, parentUrnOpt, deletedWithUrnOpt, provIdOpt, providerRefs, depUrns, aliases, options)
yield PreparedInputs(
serResult.serialized,
parentUrnOpt,
deletedWithUrnOpt,
provIdOpt,
providerRefs,
depUrns,
options.aliases.toList,
options
)

private[internal] def executeReadResourceRequest[R <: Resource](
state: ResourceState,
Expand Down Expand Up @@ -471,8 +475,23 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
case CustomResolvedResourceOptions(_, _, _, _, importId) => importId.getOrElse("")
case _ => ""
,
aliases = inputs.aliases.map { alias =>
pulumirpc.alias.Alias(pulumirpc.alias.Alias.Alias.Urn(alias))
aliases = inputs.aliases.map {
case UrnResourceAlias(urn) => pulumirpc.alias.Alias(pulumirpc.alias.Alias.Alias.Urn(urn))
case SpecResourceAlias(name, resourceType, stack, project, parent) =>
pulumirpc.alias.Alias(
pulumirpc.alias.Alias.Alias.Spec(
pulumirpc.alias.Alias.Spec(
name = name.getOrElse(""),
`type` = resourceType.getOrElse(""),
stack = stack.getOrElse(""),
project = project.getOrElse(""),
parent = parent match
case Some(ResourceAliasParentUrn(urn)) => pulumirpc.alias.Alias.Spec.Parent.ParentUrn(urn)
case Some(ResourceAliasNoParent(noParent)) => pulumirpc.alias.Alias.Spec.Parent.NoParent(noParent)
case None => pulumirpc.alias.Alias.Spec.Parent.Empty
)
)
)
},
remote = remote,
customTimeouts = Some(
Expand Down
29 changes: 19 additions & 10 deletions core/src/main/scala/besom/internal/ResourceOptions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sealed trait ResolvedResourceOptions:
def version: Option[String]
def customTimeouts: Option[CustomTimeouts]
// def resourceTransformations: Iterable[ResourceTransformation], // TODO
// def aliases: Iterable[Output[Alias]], // TODO
def aliases: Iterable[ResourceAlias]
def urn: Option[URN]
def replaceOnChanges: Iterable[String]
def retainOnDelete: Boolean
Expand All @@ -47,7 +47,7 @@ case class CommonResolvedResourceOptions(
version: Option[String],
customTimeouts: Option[CustomTimeouts],
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Iterable[ResourceAlias],
urn: Option[URN],
replaceOnChanges: Iterable[String],
retainOnDelete: Boolean,
Expand Down Expand Up @@ -84,7 +84,7 @@ trait CommonResourceOptions:
def version: Output[Option[String]]
def customTimeouts: Output[Option[CustomTimeouts]]
// def resourceTransformations: Iterable[ResourceTransformation], // TODO
// def aliases: Iterable[Output[Alias]], // TODO
def aliases: Output[Iterable[ResourceAlias]]
// TODO this is only necessary for Resource deserialization, dependency resources and multi-language remote components
def urn: Output[Option[URN]]
def replaceOnChanges: Output[Iterable[String]]
Expand All @@ -103,6 +103,7 @@ extension (cro: CommonResourceOptions)
ignoreChanges <- cro.ignoreChanges.getData
version <- cro.version.getData
customTimeouts <- cro.customTimeouts.getData
aliases <- cro.aliases.getData
urn <- cro.urn.getData
replaceOnChanges <- cro.replaceOnChanges.getData
retainOnDelete <- cro.retainOnDelete.getData
Expand All @@ -116,6 +117,7 @@ extension (cro: CommonResourceOptions)
ignoreChanges = ignoreChanges.getValueOrElse(Iterable.empty),
version = version.getValueOrElse(None),
customTimeouts = customTimeouts.getValueOrElse(None),
aliases = aliases.getValueOrElse(Iterable.empty),
urn = urn.getValueOrElse(None),
replaceOnChanges = replaceOnChanges.getValueOrElse(Iterable.empty),
retainOnDelete = retainOnDelete.getValueOrElse(false),
Expand All @@ -131,7 +133,7 @@ final case class CommonResourceOptionsImpl(
version: Output[Option[String]],
customTimeouts: Output[Option[CustomTimeouts]],
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Output[Iterable[ResourceAlias]],
urn: Output[Option[URN]],
replaceOnChanges: Output[Iterable[String]],
retainOnDelete: Output[Boolean],
Expand Down Expand Up @@ -240,7 +242,7 @@ trait CustomResourceOptionsFactory:
provider: Input.Optional[ProviderResource] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -257,6 +259,7 @@ trait CustomResourceOptionsFactory:
version = version.asOptionOutput(),
provider = provider.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand All @@ -277,7 +280,7 @@ object CustomResourceOptions:
provider: Input.Optional[ProviderResource] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -293,6 +296,7 @@ object CustomResourceOptions:
ignoreChanges = ignoreChanges.asManyOutput(),
version = version.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand All @@ -306,6 +310,7 @@ object CustomResourceOptions:
additionalSecretOutputs = additionalSecretOutputs.asManyOutput(),
importId = importId.asOptionOutput()
)
end apply
end CustomResourceOptions

trait ComponentResourceOptionsFactory:
Expand All @@ -318,7 +323,7 @@ trait ComponentResourceOptionsFactory:
version: Input.Optional[NonEmptyString] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -332,6 +337,7 @@ trait ComponentResourceOptionsFactory:
ignoreChanges = ignoreChanges.asManyOutput(),
version = version.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand All @@ -349,7 +355,7 @@ object ComponentResourceOptions:
version: Input.Optional[NonEmptyString] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -363,6 +369,7 @@ object ComponentResourceOptions:
ignoreChanges = ignoreChanges.asManyOutput(),
version = version.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand All @@ -380,7 +387,7 @@ object StackReferenceResourceOptions:
version: Input.Optional[NonEmptyString] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -395,6 +402,7 @@ object StackReferenceResourceOptions:
ignoreChanges = ignoreChanges.asManyOutput(),
version = version.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand All @@ -412,7 +420,7 @@ trait StackReferenceResourceOptionsFactory:
version: Input.Optional[NonEmptyString] = None,
customTimeouts: Input.Optional[CustomTimeouts] = None,
// resourceTransformations: Iterable[ResourceTransformation], // TODO
// aliases: Iterable[Output[Alias]], // TODO
aliases: Input.OneOrIterable[ResourceAlias] = Iterable.empty,
urn: Input.Optional[URN] = None,
replaceOnChanges: Input.OneOrIterable[String] = Iterable.empty,
retainOnDelete: Input[Boolean] = false,
Expand All @@ -427,6 +435,7 @@ trait StackReferenceResourceOptionsFactory:
ignoreChanges = ignoreChanges.asManyOutput(),
version = version.asOptionOutput(),
customTimeouts = customTimeouts.asOptionOutput(),
aliases = aliases.asManyOutput(),
urn = urn.asOptionOutput(),
replaceOnChanges = replaceOnChanges.asManyOutput(),
retainOnDelete = retainOnDelete.asOutput(),
Expand Down
6 changes: 5 additions & 1 deletion integration-tests/CoreTests.test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@ class CoreTests extends munit.FunSuite {
)
},
teardown = pulumi.fixture.teardown
).test("random provider and memoization should work") { ctx =>
).test("random provider, memoization and aliases should work") { ctx =>
val result = pulumi.up(ctx.stackName).call(cwd = ctx.programDir, env = ctx.env)
val output = result.out.text()
assert(output.contains("randomString:"), s"Output:\n$output\n")

val previewResult = pulumi.preview(ctx.stackName).call(cwd = ctx.programDir, env = ctx.env + ("TEST_ALIAS" -> "true"))
val previewOutput = previewResult.out.text()
assert(previewOutput.contains("2 unchanged"), s"Output:\n$previewOutput\n")
}

FunFixture[pulumi.FixtureContext](
Expand Down
10 changes: 8 additions & 2 deletions integration-tests/resources/random-example/Main.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import besom.*
import besom.api.random.*
import besom.internal.SpecResourceAlias

@main
def main(): Unit = Pulumi.run {
val oldName = "random-string"
val newName = "random-string-2"

val testAlias = sys.env.getOrElse("TEST_ALIAS", "false").toBoolean

def strOutput = RandomString(
name = "random-string",
name = if (testAlias) newName else oldName,
args = RandomStringArgs(
length = 10
)
),
opts = opts(aliases = if (testAlias) List(SpecResourceAlias(name = Some(oldName))) else List.empty)
)

val str = strOutput
Expand Down
Loading