2023-05-15 09:34:05 +00:00
package mutator
import (
"context"
2024-07-09 11:12:42 +00:00
"fmt"
2023-05-15 09:34:05 +00:00
2023-05-16 16:35:39 +00:00
"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config/variable"
2024-03-25 14:18:47 +00:00
"github.com/databricks/cli/libs/diag"
2024-07-09 11:12:42 +00:00
"github.com/databricks/cli/libs/dyn"
2023-09-11 08:18:43 +00:00
"github.com/databricks/cli/libs/env"
2023-05-15 09:34:05 +00:00
)
const bundleVarPrefix = "BUNDLE_VAR_"
type setVariables struct { }
func SetVariables ( ) bundle . Mutator {
return & setVariables { }
}
func ( m * setVariables ) Name ( ) string {
return "SetVariables"
}
2024-07-09 11:12:42 +00:00
func setVariable ( ctx context . Context , v dyn . Value , variable * variable . Variable , name string ) ( dyn . Value , error ) {
2023-05-15 09:34:05 +00:00
// case: variable already has value initialized, so skip
2024-07-09 11:12:42 +00:00
if variable . HasValue ( ) {
return v , nil
2023-05-15 09:34:05 +00:00
}
// case: read and set variable value from process environment
envVarName := bundleVarPrefix + name
2023-09-11 08:18:43 +00:00
if val , ok := env . Lookup ( ctx , envVarName ) ; ok {
2024-07-09 11:12:42 +00:00
if variable . IsComplex ( ) {
return dyn . InvalidValue , fmt . Errorf ( ` setting via environment variables (%s) is not supported for complex variable %s ` , envVarName , name )
2024-06-26 10:25:32 +00:00
}
2024-07-09 11:12:42 +00:00
v , err := dyn . Set ( v , "value" , dyn . V ( val ) )
2023-05-15 09:34:05 +00:00
if err != nil {
2024-07-09 11:12:42 +00:00
return dyn . InvalidValue , fmt . Errorf ( ` failed to assign value "%s" to variable %s from environment variable %s with error: %v ` , val , name , envVarName , err )
2023-05-15 09:34:05 +00:00
}
2024-07-09 11:12:42 +00:00
return v , nil
2023-05-15 09:34:05 +00:00
}
2024-06-19 08:03:06 +00:00
// case: Defined a variable for named lookup for a resource
// It will be resolved later in ResolveResourceReferences mutator
2024-07-09 11:12:42 +00:00
if variable . Lookup != nil {
return v , nil
2024-06-19 08:03:06 +00:00
}
2023-05-15 09:34:05 +00:00
// case: Set the variable to its default value
2024-07-09 11:12:42 +00:00
if variable . HasDefault ( ) {
vDefault , err := dyn . Get ( v , "default" )
2023-05-15 09:34:05 +00:00
if err != nil {
2024-07-09 11:12:42 +00:00
return dyn . InvalidValue , fmt . Errorf ( ` failed to get default value from config "%s" for variable %s with error: %v ` , variable . Default , name , err )
2023-05-15 09:34:05 +00:00
}
2024-07-09 11:12:42 +00:00
v , err := dyn . Set ( v , "value" , vDefault )
if err != nil {
return dyn . InvalidValue , fmt . Errorf ( ` failed to assign default value from config "%s" to variable %s with error: %v ` , variable . Default , name , err )
}
return v , nil
2023-05-15 09:34:05 +00:00
}
// We should have had a value to set for the variable at this point.
2024-07-09 11:12:42 +00:00
return dyn . InvalidValue , fmt . Errorf ( ` no value assigned to required variable %s. Assignment can be done through the "--var" flag or by setting the %s environment variable ` , name , bundleVarPrefix + name )
2023-05-15 09:34:05 +00:00
}
2024-03-25 14:18:47 +00:00
func ( m * setVariables ) Apply ( ctx context . Context , b * bundle . Bundle ) diag . Diagnostics {
2024-07-09 11:12:42 +00:00
err := b . Config . Mutate ( func ( v dyn . Value ) ( dyn . Value , error ) {
return dyn . Map ( v , "variables" , dyn . Foreach ( func ( p dyn . Path , variable dyn . Value ) ( dyn . Value , error ) {
name := p [ 1 ] . Key ( )
v , ok := b . Config . Variables [ name ]
if ! ok {
return dyn . InvalidValue , fmt . Errorf ( ` variable "%s" is not defined ` , name )
}
return setVariable ( ctx , variable , v , name )
} ) )
} )
return diag . FromErr ( err )
2023-05-15 09:34:05 +00:00
}