alloy icon indicating copy to clipboard operation
alloy copied to clipboard

River: Identify correct behavior for attribute assignment and binary operation

Open rfratto opened this issue 2 years ago • 1 comments

In River, capsule values can opt-in to supporting conversion to and from other Go types. The most common case of this is rivertypes.OptionalSecret, which can be converted to a string if and only if the IsSecret flag is set to false.

This is exported by components such as local.file, where the sensitivity of the file is not known at compile time, so the user must specify it with an argument that controls the sensitivity of the export.

Normally, the fact that local.file exports a capsule is opaque to users, since attribute assignment supports automatic conversion.

However, grafana/agent#4036 noted that no conversion was happening for binary operators, making it impossible to concatenate the non-sensitive export of local.file to another string. grafana/agent#4288 introduced a temporary workaround for this fix, by hard-coding binary operations to unwrap rivertypes.OptionalSecret to a string if it was flagged as non-sensitive.

River is currently inconsistent with when (and to what extent) it automatically converts values:

  • When assigning a value to an attribute in a block (ATTRIBUTE = VALUE), VALUE may be converted in one of the following ways:
    • Capsules will be converted to another type if supported by the ConvertibleIntoCapsule (for converting a mistyped VALUE)/ConvertibleFromCapsule interface (for ATTRIBUTE to store a mistyped VALUE).
    • Capsules will be downcasted to a Go interface type if the type of ATTRIBUTE is a Go interface implemented by VALUE.
    • Number will be converted to string values.
    • String values will be converted to number values (if it can be parsed as a number).
  • No conversion is done for unary operations.
  • No conversion is done for binary operations.

We should identify a consistent behavior (consistent conversion rules, or never converting mistyped values) and implement it to help River be more consistent and predictable.

rfratto avatar Jun 29 '23 16:06 rfratto

Hi, I'm also facing this particular issue when I'm trying to use the function base64_decode() from Grafana Alloy standard library. The error I received is indicating that the input string I'm providing should be capsule, rather than an array or string.

The use case I have is passing a base64 encoded string as an argument from the client side river file to the remote module river file where the argument will be referenced as the password for the basic authentication of prometheus.remote_write component.

E.g. password = base64_decode("<base64_string>")

Can the team look into this? There is also no method for users to create a capsule type from a string, so we are hitting a dead end.

cheesengoon avatar Aug 16 '24 08:08 cheesengoon

@cheesengoon you can use the format function to convert it to a string: password = format("%s%", base64_decode("<base64_string>"))

we should probably change this because it is a bit tricky but the reason for this is that the decode method returns an array of bytes and the password expects either a capsule or a string that could be converted to a capsule. It does not convert a array of bytes to a capsule

wildum avatar Aug 28 '24 13:08 wildum