Skip to content

Commit 663f4df

Browse files
authored
Merge pull request #67 from Azure/swei/yamlvalueapplier
*: support YAML values applier
2 parents b18eae3 + 8837a12 commit 663f4df

File tree

6 files changed

+171
-6
lines changed

6 files changed

+171
-6
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
k8s.io/klog/v2 v2.100.1
1717
k8s.io/kubectl v0.28.4
1818
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
19+
sigs.k8s.io/yaml v1.4.0
1920
)
2021

2122
require (
@@ -143,5 +144,4 @@ require (
143144
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
144145
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
145146
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
146-
sigs.k8s.io/yaml v1.3.0 // indirect
147147
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,5 +529,5 @@ sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM
529529
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag=
530530
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
531531
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
532-
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
533-
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
532+
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
533+
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

helmcli/release.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"time"
88

9+
"gopkg.in/yaml.v2"
910
"helm.sh/helm/v3/pkg/action"
1011
"helm.sh/helm/v3/pkg/chart"
1112
"helm.sh/helm/v3/pkg/storage/driver"
@@ -40,6 +41,47 @@ func StringPathValuesApplier(values ...string) ValuesApplier {
4041
}
4142
}
4243

44+
func YAMLValuesApplier(yamlValues string) (ValuesApplier, error) {
45+
values := make(map[string]interface{})
46+
err := yaml.Unmarshal([]byte(yamlValues), &values)
47+
if err != nil {
48+
return nil, err
49+
}
50+
51+
return func(to map[string]interface{}) error {
52+
return applyValues(to, values)
53+
}, nil
54+
}
55+
56+
func applyValues(to, from map[string]interface{}) error {
57+
for k, v := range from {
58+
// If 'to' doesn't have key 'k'
59+
if _, checkKey := to[k]; !checkKey {
60+
to[k] = v
61+
continue
62+
}
63+
64+
// If 'to' has key 'k'
65+
switch v := v.(type) {
66+
case map[string]interface{}:
67+
// If 'v' is of type map[string]interface{}
68+
if toMap, checkKey := to[k].(map[string]interface{}); checkKey {
69+
if err := applyValues(toMap, v); err != nil {
70+
return err
71+
}
72+
} else {
73+
to[k] = v
74+
75+
}
76+
default:
77+
// If 'v' is not of type map[string]interface{}
78+
to[k] = v
79+
}
80+
81+
}
82+
return nil
83+
}
84+
4385
// ReleaseCli is a client to deploy helm chart with secret storage.
4486
type ReleaseCli struct {
4587
namespace string

helmcli/release_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package helmcli
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestApplyValues(t *testing.T) {
10+
for idx, tc := range []struct {
11+
from map[string]interface{}
12+
to map[string]interface{}
13+
expected map[string]interface{}
14+
}{
15+
{
16+
from: map[string]interface{}{
17+
"foo": "bar1",
18+
"baz": map[string]interface{}{
19+
"name": "alice",
20+
},
21+
},
22+
to: map[string]interface{}{
23+
"foo": "bar2",
24+
"baz": map[string]interface{}{
25+
"name": "bob",
26+
"age": "18",
27+
},
28+
},
29+
expected: map[string]interface{}{
30+
"foo": "bar1",
31+
"baz": map[string]interface{}{
32+
"name": "alice",
33+
"age": "18",
34+
},
35+
},
36+
},
37+
{
38+
from: map[string]interface{}{
39+
"foo": "bar1",
40+
"baz": "profile",
41+
},
42+
to: map[string]interface{}{
43+
"foo": "bar1",
44+
"baz": map[string]interface{}{
45+
"name": "alice",
46+
},
47+
},
48+
expected: map[string]interface{}{
49+
"foo": "bar1",
50+
"baz": "profile",
51+
},
52+
},
53+
{
54+
from: map[string]interface{}{
55+
"foo": "bar1",
56+
"baz": map[string]interface{}{
57+
"name": "alice",
58+
},
59+
},
60+
to: map[string]interface{}{
61+
"version": "alpha",
62+
},
63+
expected: map[string]interface{}{
64+
"foo": "bar1",
65+
"baz": map[string]interface{}{
66+
"name": "alice",
67+
},
68+
"version": "alpha",
69+
},
70+
},
71+
{
72+
from: map[string]interface{}{
73+
"baz": map[string]interface{}{
74+
"name": map[string]interface{}{
75+
"last": "unknown",
76+
"first": "bob",
77+
},
78+
},
79+
"version": "beta",
80+
},
81+
to: map[string]interface{}{
82+
"foo": "bar2",
83+
"baz": map[string]interface{}{
84+
"name": "bob",
85+
"age": "18",
86+
},
87+
},
88+
expected: map[string]interface{}{
89+
"foo": "bar2",
90+
"baz": map[string]interface{}{
91+
"name": map[string]interface{}{
92+
"last": "unknown",
93+
"first": "bob",
94+
},
95+
"age": "18",
96+
},
97+
"version": "beta",
98+
},
99+
},
100+
} {
101+
err := applyValues(tc.to, tc.from)
102+
assert.NoError(t, err, "#%v", idx)
103+
assert.Equal(t, tc.expected, tc.to, "#%v", idx)
104+
}
105+
}

virtualcluster/nodes_common.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55

66
"github.com/Azure/kperf/helmcli"
7+
"sigs.k8s.io/yaml"
78
)
89

910
var (
@@ -98,12 +99,25 @@ func WithNodepoolNodeControllerAffinity(nodeSelectors map[string][]string) Nodep
9899
// NOTE: Please align with ../manifests/virtualcluster/nodes/values.yaml
99100
//
100101
// TODO: Add YAML ValuesAppliers to support array type.
101-
func (cfg *nodepoolConfig) toHelmValuesAppliers(nodepoolName string) []helmcli.ValuesApplier {
102+
func (cfg *nodepoolConfig) toHelmValuesAppliers(nodepoolName string) ([]helmcli.ValuesApplier, error) {
102103
res := make([]string, 0, 4)
103104

104105
res = append(res, fmt.Sprintf("name=%s", nodepoolName))
105106
res = append(res, fmt.Sprintf("replicas=%d", cfg.count))
106107
res = append(res, fmt.Sprintf("cpu=%d", cfg.cpu))
107108
res = append(res, fmt.Sprintf("memory=%d", cfg.memory))
108-
return []helmcli.ValuesApplier{helmcli.StringPathValuesApplier(res...)}
109+
110+
stringPathApplier := helmcli.StringPathValuesApplier(res...)
111+
112+
// Marshal nodeSelectors to YAML
113+
nodeSelectorsYaml, err := yaml.Marshal(cfg.nodeSelectors)
114+
if err != nil {
115+
return nil, err
116+
}
117+
// Create YAML ValuesAppliers nodeSelectors
118+
nodeSelectorsApplier, err := helmcli.YAMLValuesApplier(string(nodeSelectorsYaml))
119+
if err != nil {
120+
return nil, err
121+
}
122+
return []helmcli.ValuesApplier{stringPathApplier, nodeSelectorsApplier}, nil
109123
}

virtualcluster/nodes_create.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,17 @@ func CreateNodepool(ctx context.Context, kubeconfigPath string, nodepoolName str
3939
return fmt.Errorf("failed to load virtual node chart: %w", err)
4040
}
4141

42+
cfgValues, err := cfg.toHelmValuesAppliers(nodepoolName)
43+
if err != nil {
44+
return fmt.Errorf("failed to convert to helm values: %w", err)
45+
}
4246
releaseCli, err := helmcli.NewReleaseCli(
4347
kubeconfigPath,
4448
virtualnodeReleaseNamespace,
4549
nodepoolName,
4650
ch,
4751
virtualnodeReleaseLabels,
48-
cfg.toHelmValuesAppliers(nodepoolName)...,
52+
cfgValues...,
4953
)
5054
if err != nil {
5155
return fmt.Errorf("failed to create helm release client: %w", err)

0 commit comments

Comments
 (0)