Skip to content

Commit 4be4783

Browse files
committed
feat: Parse YAML parameters sequentially.
Signed-off-by: joyceliu <joyceliu@yunify.com>
1 parent dc87174 commit 4be4783

25 files changed

+1159
-502
lines changed

.golangci.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ linters:
6969
- nakedret
7070
- nestif
7171
# - nilerr
72-
- nilnil
73-
- nlreturn
72+
# - nilnil
73+
# - nlreturn
7474
- noctx
7575
- nolintlint
7676
- nonamedreturns
@@ -459,7 +459,7 @@ linters-settings:
459459
# # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-map-style
460460
- name: enforce-map-style
461461
severity: warning
462-
disabled: false
462+
disabled: true
463463
exclude: [""]
464464
arguments:
465465
- "make"
@@ -473,7 +473,7 @@ linters-settings:
473473
# # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-slice-style
474474
- name: enforce-slice-style
475475
severity: warning
476-
disabled: false
476+
disabled: true
477477
exclude: [""]
478478
arguments:
479479
- "make"

api/project/v1/base.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ limitations under the License.
1616

1717
package v1
1818

19+
import "gopkg.in/yaml.v3"
20+
1921
// Base defined in project.
2022
type Base struct {
2123
Name string `yaml:"name,omitempty"`
@@ -26,7 +28,7 @@ type Base struct {
2628
RemoteUser string `yaml:"remote_user,omitempty"`
2729

2830
// variables
29-
Vars map[string]any `yaml:"vars,omitempty"`
31+
Vars yaml.Node `yaml:"vars,omitempty"`
3032

3133
// module default params
3234
//ModuleDefaults []map[string]map[string]any `yaml:"module_defaults,omitempty"`

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ require (
1717
github.com/spf13/pflag v1.0.5
1818
github.com/stretchr/testify v1.9.0
1919
golang.org/x/crypto v0.31.0
20-
gopkg.in/yaml.v2 v2.4.0
2120
gopkg.in/yaml.v3 v3.0.1
2221
k8s.io/api v0.31.3
2322
k8s.io/apimachinery v0.31.3
@@ -146,6 +145,7 @@ require (
146145
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
147146
gopkg.in/inf.v0 v0.9.1 // indirect
148147
gopkg.in/warnings.v0 v0.1.2 // indirect
148+
gopkg.in/yaml.v2 v2.4.0 // indirect
149149
k8s.io/apiextensions-apiserver v0.31.3 // indirect
150150
k8s.io/cluster-bootstrap v0.31.3 // indirect
151151
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect

pkg/converter/converter.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"strconv"
2222
"strings"
2323

24+
"gopkg.in/yaml.v3"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2526
"k8s.io/apimachinery/pkg/runtime"
2627
"k8s.io/apimachinery/pkg/util/json"
@@ -149,3 +150,19 @@ func ConvertKKClusterToInventoryHost(kkcluster *capkkinfrav1beta1.KKCluster) (kk
149150

150151
return inventoryHosts, nil
151152
}
153+
154+
// ConvertMap2Node converts a map[string]any to a yaml.Node by first marshaling to YAML bytes
155+
// then unmarshaling into a Node. This allows working with the YAML node structure directly.
156+
func ConvertMap2Node(m map[string]any) (yaml.Node, error) {
157+
data, err := yaml.Marshal(m)
158+
if err != nil {
159+
return yaml.Node{}, errors.Wrap(err, "failed to marshal map to yaml")
160+
}
161+
var node yaml.Node
162+
err = yaml.Unmarshal(data, &node)
163+
if err != nil {
164+
return yaml.Node{}, errors.Wrap(err, "failed to unmarshal yaml to node")
165+
}
166+
167+
return node, nil
168+
}

pkg/converter/converter_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,51 @@ func TestConvertKKClusterToInventoryHost(t *testing.T) {
170170
})
171171
}
172172
}
173+
174+
func TestConvertMap2Node(t *testing.T) {
175+
testcases := []struct {
176+
name string
177+
input map[string]any
178+
wantErr bool
179+
}{
180+
{
181+
name: "simple map",
182+
input: map[string]any{
183+
"key1": "value1",
184+
"key2": 123,
185+
"key3": true,
186+
},
187+
},
188+
{
189+
name: "nested map",
190+
input: map[string]any{
191+
"outer": map[string]any{
192+
"inner": "value",
193+
},
194+
"array": []any{"a", "b", "c"},
195+
},
196+
},
197+
{
198+
name: "empty map",
199+
input: map[string]any{},
200+
},
201+
}
202+
203+
for _, tc := range testcases {
204+
t.Run(tc.name, func(t *testing.T) {
205+
node, err := ConvertMap2Node(tc.input)
206+
if err != nil {
207+
t.Fatal(err)
208+
}
209+
assert.NotNil(t, node)
210+
211+
// Convert back to map to verify roundtrip
212+
var result map[string]any
213+
err = node.Decode(&result)
214+
if err != nil {
215+
t.Fatal(err)
216+
}
217+
assert.Equal(t, tc.input, result)
218+
})
219+
}
220+
}

pkg/executor/executor_test.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,55 @@ import (
88
kkcorev1alpha1 "github.com/kubesphere/kubekey/api/core/v1alpha1"
99
corev1 "k8s.io/api/core/v1"
1010
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/runtime"
1112
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1213

1314
_const "github.com/kubesphere/kubekey/v4/pkg/const"
1415
"github.com/kubesphere/kubekey/v4/pkg/variable"
1516
"github.com/kubesphere/kubekey/v4/pkg/variable/source"
1617
)
1718

18-
func newTestOption() (*option, error) {
19+
func newTestOption(hosts []string) (*option, error) {
1920
var err error
21+
// convert host to InventoryHost
22+
inventoryHost := make(kkcorev1.InventoryHost)
23+
for _, h := range hosts {
24+
inventoryHost[h] = runtime.RawExtension{}
25+
}
26+
client := fake.NewClientBuilder().WithScheme(_const.Scheme).WithStatusSubresource(&kkcorev1.Playbook{}, &kkcorev1alpha1.Task{}).Build()
27+
inventory := &kkcorev1.Inventory{
28+
TypeMeta: metav1.TypeMeta{},
29+
ObjectMeta: metav1.ObjectMeta{
30+
GenerateName: "test-",
31+
Namespace: corev1.NamespaceDefault,
32+
},
33+
Spec: kkcorev1.InventorySpec{
34+
Hosts: inventoryHost,
35+
},
36+
}
37+
if err := client.Create(context.TODO(), inventory); err != nil {
38+
return nil, err
39+
}
2040

2141
o := &option{
22-
client: fake.NewClientBuilder().WithScheme(_const.Scheme).WithStatusSubresource(&kkcorev1.Playbook{}, &kkcorev1alpha1.Task{}).Build(),
42+
client: client,
2343
playbook: &kkcorev1.Playbook{
2444
TypeMeta: metav1.TypeMeta{},
2545
ObjectMeta: metav1.ObjectMeta{
26-
Name: "test",
27-
Namespace: corev1.NamespaceDefault,
46+
GenerateName: "test-",
47+
Namespace: corev1.NamespaceDefault,
2848
},
2949
Spec: kkcorev1.PlaybookSpec{
3050
InventoryRef: &corev1.ObjectReference{
31-
Name: "test",
32-
Namespace: corev1.NamespaceDefault,
51+
Name: inventory.Name,
52+
Namespace: inventory.Namespace,
3353
},
3454
},
3555
Status: kkcorev1.PlaybookStatus{},
3656
},
3757
logOutput: os.Stdout,
3858
}
3959

40-
if err := o.client.Create(context.TODO(), &kkcorev1.Inventory{
41-
TypeMeta: metav1.TypeMeta{},
42-
ObjectMeta: metav1.ObjectMeta{
43-
Name: "test",
44-
Namespace: corev1.NamespaceDefault,
45-
},
46-
Spec: kkcorev1.InventorySpec{},
47-
}); err != nil {
48-
return nil, err
49-
}
50-
5160
o.variable, err = variable.New(context.TODO(), o.client, *o.playbook, source.MemorySource)
5261
if err != nil {
5362
return nil, err

0 commit comments

Comments
 (0)