Skip to content
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 go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ require (
golang.org/x/oauth2 v0.36.0
golang.org/x/text v0.40.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20260630182238-925bb5da69e7
google.golang.org/grpc v1.82.0
google.golang.org/grpc v1.82.1
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
gopkg.in/yaml.v3 v3.0.1
k8s.io/klog/v2 v2.140.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3324,8 +3324,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU=
google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
48 changes: 32 additions & 16 deletions pkg/svc/installer/awslbcontroller/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/devantler-tech/ksail/v7/pkg/client/helm"
"github.com/devantler-tech/ksail/v7/pkg/svc/installer/internal/helmutil"
"k8s.io/apimachinery/pkg/util/validation"
"sigs.k8s.io/yaml"
)

const (
Expand Down Expand Up @@ -103,6 +104,11 @@ func NewInstaller(
}
}

valuesYAML, err := buildValuesYaml(clusterName, region, serviceAccountName, haEnabled)
if err != nil {
return nil, fmt.Errorf("build AWS load balancer controller Helm values: %w", err)
}

managed := len(ksailManaged) > 0 && ksailManaged[0]

return &Installer{
Expand Down Expand Up @@ -132,7 +138,7 @@ func NewInstaller(
ReleaseOwnershipLabel: releaseOwnershipValue,
},
Timeout: timeout,
ValuesYaml: buildValuesYaml(clusterName, region, serviceAccountName, haEnabled),
ValuesYaml: valuesYAML,
},
),
client: client,
Expand Down Expand Up @@ -259,29 +265,39 @@ func (i *Installer) Uninstall(ctx context.Context) error {
// disabled: it makes this controller the default for every new LoadBalancer
// Service, and during install its admitted-but-not-ready window rejects
// Services created by concurrently-installing components.
func buildValuesYaml(clusterName, region, serviceAccountName string, haEnabled bool) string {
parts := []string{
"clusterName: " + clusterName,
"enableServiceMutatorWebhook: false",
func buildValuesYaml(
clusterName, region, serviceAccountName string,
haEnabled bool,
) (string, error) {
type serviceAccountValues struct {
Create bool `json:"create"`
Name string `json:"name"`
}

if region != "" {
parts = append(parts, "region: "+region)
values := struct {
ClusterName string `json:"clusterName"`
EnableServiceMutatorWebhook bool `json:"enableServiceMutatorWebhook"`
Region string `json:"region,omitempty"`
ReplicaCount int `json:"replicaCount"`
ServiceAccount *serviceAccountValues `json:"serviceAccount,omitempty"`
}{
ClusterName: clusterName,
Region: region,
ReplicaCount: 1,
}

if serviceAccountName = strings.TrimSpace(serviceAccountName); serviceAccountName != "" {
// Quoted: DNS-1123 names like "123", "null", "true" or "on" are
// otherwise parsed as YAML numbers/nulls/booleans, not strings.
// Validation guarantees the name contains no quote or backslash.
parts = append(parts,
"serviceAccount:\n create: false\n name: \""+serviceAccountName+"\"")
values.ServiceAccount = &serviceAccountValues{Name: serviceAccountName}
}

if haEnabled {
parts = append(parts, "replicaCount: 2")
} else {
parts = append(parts, "replicaCount: 1")
values.ReplicaCount = 2
}

encoded, err := yaml.Marshal(values)
if err != nil {
return "", fmt.Errorf("marshal AWS load balancer controller Helm values: %w", err)
}

return strings.Join(parts, "\n")
return string(encoded), nil
}
24 changes: 22 additions & 2 deletions pkg/svc/installer/awslbcontroller/installer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"sigs.k8s.io/yaml"
)

type newInstallerCase struct {
Expand Down Expand Up @@ -452,15 +453,34 @@ func runBuildValuesCases(t *testing.T, tests []buildValuesCase) {
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()

got := awslbcontrollerinstaller.BuildValuesYamlForTest(
got, err := awslbcontrollerinstaller.BuildValuesYamlForTest(
testCase.clusterName, testCase.region, testCase.serviceAccount, testCase.haEnabled,
)

assert.Equal(t, testCase.want, got)
require.NoError(t, err)
assert.YAMLEq(t, testCase.want, got)
})
}
}

func TestBuildValuesYaml_EscapesUntrustedScalars(t *testing.T) {
t.Parallel()

clusterName := "prod-eks\nimage:\n repository: attacker/controller"
region := "eu-north-1\nserviceAccount:\n name: attacker"
values, err := awslbcontrollerinstaller.BuildValuesYamlForTest(clusterName, region, "", false)
require.NoError(t, err)

var parsed map[string]any
require.NoError(t, yaml.Unmarshal([]byte(values), &parsed))
assert.Equal(t, map[string]any{
"clusterName": clusterName,
"enableServiceMutatorWebhook": false,
"region": region,
"replicaCount": float64(1),
}, parsed)
}

func TestChartVersion(t *testing.T) {
t.Parallel()

Expand Down