VirtusLab / besom

Besom - a Pulumi SDK for Scala. Also, incidentally, a broom made of twigs tied round a stick. Brooms and besoms are used for protection, to ward off evil spirits, and cleansing of ritual spaces.
https://virtuslab.github.io/besom/
Apache License 2.0
114 stars 7 forks source link

Consider exposing `copy` for code generated Resource args #422

Closed pawelprazak closed 2 weeks ago

pawelprazak commented 3 months ago

As a user I expect to be able to do the following:

    val persistentVolumeLabels = Map("type" -> "local")
    val persistentVolumeTemplate = PersistentVolumeSpecArgs(
      storageClassName = "manual",
      capacity = Map("storage" -> "128Mi"),
      accessModes = List("ReadWriteOnce"),
      persistentVolumeReclaimPolicy = "Delete" // never do this in production
    )
    def createHostPathVolume(num: Int): Output[PersistentVolume] =
      PersistentVolume(
        s"redis-cluster-pv-$num-$name",
        PersistentVolumeArgs(
          metadata = ObjectMetaArgs(
            namespace = redisNamespace.metadata.name,
            labels = persistentVolumeLabels ++ labels,
            name = s"redis-cluster-pv-$num-$name"
          ),
          spec = persistentVolumeTemplate.copy(
            hostPath = HostPathVolumeSourceArgs(path = s"/tmp/redis/data-$num")
          )
        )
      )

but the PersistentVolumeSpecArgs constructor is private and by extension, its copy method.

This is easy to fix by generating an extension in codegen, e.g.:

case class Test private (a: String)
object Test:
  def apply(a: String): Test                 = Test(a)
  extension (test: Test) def copy(a: String) = test.copy(a = a)
Test("s").copy(a = "s")

The question is, is this a reasonable expectation, for the user to expect copy in this case @lbialy.

lbialy commented 2 months ago

if we can code-generate a copy method with Inputs this would solve the problem, I think

lbialy commented 2 months ago

it should be possible, we can assign existing Output[A] field to an Input[A] field 👍

kamilkloch commented 2 months ago

It would be great if besom allowed for tapir-like composability. In tapir, one often declares a "base" endpoint (say, with fixed security headers, error channel etc), which is then used as a base for the rest. In fact, we even use a hierarchyt of such base endpoints (e.g. baseEndpoint -> authenticatedEndpoint). In case of besom, one can imagine a similar use-case - e.g. containers sharing a particular provider, environment variables, memory settings etc. This base description could be then enriched/modified with custom values to obtain new outputs. Currently, to achieve this composability one has to wrap the instantiation of the resource into a helper method with all possible fields exposed as parameters.