diff --git a/modules/dagger/driver.go b/modules/dagger/driver.go index 9c738f0..3c96235 100644 --- a/modules/dagger/driver.go +++ b/modules/dagger/driver.go @@ -49,6 +49,8 @@ const ( const defaultKey = "default" +const daggerTaintKey = "dagger" + var defaultDriverConf = driverConf{ Namespace: map[string]string{ defaultKey: "dagger", @@ -104,6 +106,8 @@ type driverConf struct { // timeout value for a kube deployment run KubeDeployTimeout int `json:"kube_deploy_timeout_seconds"` + + NodeAffinityMatchExpressions kubernetes.NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` } type Output struct { @@ -218,6 +222,38 @@ func (dd *daggerDriver) getHelmRelease(res resource.Resource, conf Config, formatted := fmt.Sprintf("[%s]", strings.Join(programArgs, ",")) encodedProgramArgs := base64.StdEncoding.EncodeToString([]byte(formatted)) + tolerationKey := daggerTaintKey + tolerations := []map[string]any{} + + for _, t := range kubeOut.Tolerations[tolerationKey] { + tolerations = append(tolerations, map[string]any{ + "key": t.Key, + "value": t.Value, + "effect": t.Effect, + "operator": t.Operator, + }) + } + + requiredDuringSchedulingIgnoredDuringExecution := []kubernetes.Preference{} + preferredDuringSchedulingIgnoredDuringExecution := []kubernetes.WeightedPreference{} + + affinityKey := daggerTaintKey + if affinity, ok := kubeOut.Affinities[affinityKey]; ok { + requiredDuringSchedulingIgnoredDuringExecution = affinity.RequiredDuringSchedulingIgnoredDuringExecution + preferredDuringSchedulingIgnoredDuringExecution = affinity.PreferredDuringSchedulingIgnoredDuringExecution + } + + if dd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution != nil { + requiredDuringSchedulingIgnoredDuringExecution = dd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution + } + + if dd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution != nil { + preferredDuringSchedulingIgnoredDuringExecution = dd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution + } + + requiredDuringSchedulingIgnoredDuringExecutionInterface := kubernetes.PreferenceSliceToInterfaceSlice(requiredDuringSchedulingIgnoredDuringExecution) + preferredDuringSchedulingIgnoredDuringExecutionInterface := kubernetes.WeightedPreferencesToInterfaceSlice(preferredDuringSchedulingIgnoredDuringExecution) + rc.Values = map[string]any{ labelsConfKey: modules.CloneAndMergeMaps(deploymentLabels, entropyLabels), "image": imageRepository, @@ -250,6 +286,11 @@ func (dd *daggerDriver) getHelmRelease(res resource.Resource, conf Config, "dagger_k8s_ha_url": conf.DaggerK8sHAURL, "cloud_provider": conf.CloudProvider, "fs_oss_endpoint": conf.FSOSSEndpoint, + "tolerations": tolerations, + "nodeAffinityMatchExpressions": map[string]any{ + "requiredDuringSchedulingIgnoredDuringExecution": requiredDuringSchedulingIgnoredDuringExecutionInterface, + "preferredDuringSchedulingIgnoredDuringExecution": preferredDuringSchedulingIgnoredDuringExecutionInterface, + }, } return rc, nil diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 133c05e..de28b98 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -16,7 +16,6 @@ import ( "github.com/goto/entropy/pkg/errors" "github.com/goto/entropy/pkg/helm" "github.com/goto/entropy/pkg/kube" - "github.com/mitchellh/mapstructure" ) const ( @@ -351,8 +350,8 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, imageRepository = conf.ChartValues.ImageRepository } - requiredDuringSchedulingIgnoredDuringExecutionInterface := preferenceSliceToInterfaceSlice(requiredDuringSchedulingIgnoredDuringExecution) - preferredDuringSchedulingIgnoredDuringExecutionInterface := weightedPreferencesToInterfaceSlice(preferredDuringSchedulingIgnoredDuringExecution) + requiredDuringSchedulingIgnoredDuringExecutionInterface := kubernetes.PreferenceSliceToInterfaceSlice(requiredDuringSchedulingIgnoredDuringExecution) + preferredDuringSchedulingIgnoredDuringExecutionInterface := kubernetes.WeightedPreferencesToInterfaceSlice(preferredDuringSchedulingIgnoredDuringExecution) rc.Values = map[string]any{ labelsConfKey: modules.CloneAndMergeMaps(deploymentLabels, entropyLabels), @@ -518,47 +517,3 @@ func renderTplOfMapStringAny(labelsTpl map[string]any, labelsValues map[string]s return labelsTpl, nil } - -func preferenceSliceToInterfaceSlice(prefs []kubernetes.Preference) []map[string]interface{} { - result := make([]map[string]interface{}, len(prefs)) - - for i, pref := range prefs { - var prefMap map[string]interface{} - if err := mapstructure.Decode(pref, &prefMap); err != nil { - continue - } - - lowercaseMap := make(map[string]interface{}) - for k, v := range prefMap { - lowercaseMap[strings.ToLower(k)] = v - } - result[i] = lowercaseMap - } - - return result -} - -func weightedPreferencesToInterfaceSlice(weightedPrefs []kubernetes.WeightedPreference) []map[string]interface{} { - result := make([]map[string]interface{}, len(weightedPrefs)) - - for i, wp := range weightedPrefs { - var wpMap map[string]interface{} - if err := mapstructure.Decode(wp, &wpMap); err != nil { - continue - } - - lowercaseMap := make(map[string]interface{}) - for k, v := range wpMap { - // Special handling for the preference field - if k == "Preference" && v != nil { - // Convert the nested Preference slice - lowercaseMap["preference"] = preferenceSliceToInterfaceSlice(wp.Preference) - } else { - lowercaseMap[strings.ToLower(k)] = v - } - } - result[i] = lowercaseMap - } - - return result -} diff --git a/modules/kubernetes/output.go b/modules/kubernetes/output.go index 70d5cc4..7c43e42 100644 --- a/modules/kubernetes/output.go +++ b/modules/kubernetes/output.go @@ -2,10 +2,12 @@ package kubernetes import ( "encoding/json" + "strings" "k8s.io/apimachinery/pkg/version" "github.com/goto/entropy/pkg/kube" + "github.com/mitchellh/mapstructure" ) type Output struct { @@ -47,3 +49,47 @@ func (out Output) JSON() []byte { } return b } + +func PreferenceSliceToInterfaceSlice(prefs []Preference) []map[string]interface{} { + result := make([]map[string]interface{}, len(prefs)) + + for i, pref := range prefs { + var prefMap map[string]interface{} + if err := mapstructure.Decode(pref, &prefMap); err != nil { + continue + } + + lowercaseMap := make(map[string]interface{}) + for k, v := range prefMap { + lowercaseMap[strings.ToLower(k)] = v + } + result[i] = lowercaseMap + } + + return result +} + +func WeightedPreferencesToInterfaceSlice(weightedPrefs []WeightedPreference) []map[string]interface{} { + result := make([]map[string]interface{}, len(weightedPrefs)) + + for i, wp := range weightedPrefs { + var wpMap map[string]interface{} + if err := mapstructure.Decode(wp, &wpMap); err != nil { + continue + } + + lowercaseMap := make(map[string]interface{}) + for k, v := range wpMap { + // Special handling for the preference field + if k == "Preference" && v != nil { + // Convert the nested Preference slice + lowercaseMap["preference"] = PreferenceSliceToInterfaceSlice(wp.Preference) + } else { + lowercaseMap[strings.ToLower(k)] = v + } + } + result[i] = lowercaseMap + } + + return result +}