Skip to content

Commit 21b0242

Browse files
committed
load nodes-config.yaml in the AddNodesConfig asset
1 parent 6372dde commit 21b0242

File tree

2 files changed

+124
-8
lines changed

2 files changed

+124
-8
lines changed

pkg/asset/agent/joiner/addnodesconfig.go

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,36 @@ import (
66
"os"
77
"path/filepath"
88

9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/util/validation/field"
11+
"sigs.k8s.io/yaml"
12+
913
"github.com/openshift/installer/pkg/asset"
14+
"github.com/openshift/installer/pkg/types/agent"
15+
"github.com/pkg/errors"
1016
)
1117

1218
const (
13-
addNodesParamsFile = ".addnodesparams"
19+
addNodesParamsFile = ".addnodesparams"
20+
nodesConfigFilename = "nodes-config.yaml"
1421
)
1522

1623
// AddNodesConfig is used to store the current configuration
1724
// for the command.
1825
type AddNodesConfig struct {
19-
File *asset.File
2026
Params Params
27+
Config Config
28+
}
29+
30+
var _ asset.WritableAsset = (*AddNodesConfig)(nil)
31+
32+
// Config defines the configuration for the nodes-config.yaml file
33+
// used by the add-nodes command.
34+
type Config struct {
35+
metav1.TypeMeta `json:",inline"`
36+
metav1.ObjectMeta `json:"metadata,omitempty"`
37+
38+
Hosts []agent.Host `json:"hosts,omitempty"`
2139
}
2240

2341
// Params is used to store the command line parameters.
@@ -53,15 +71,13 @@ func (*AddNodesConfig) Generate(dependencies asset.Parents) error {
5371
}
5472

5573
// Files returns the files generated by the asset.
56-
func (a *AddNodesConfig) Files() []*asset.File {
57-
if a.File != nil {
58-
return []*asset.File{a.File}
59-
}
74+
func (*AddNodesConfig) Files() []*asset.File {
6075
return []*asset.File{}
6176
}
6277

6378
// Load returns agent config asset from the disk.
6479
func (a *AddNodesConfig) Load(f asset.FileFetcher) (bool, error) {
80+
// Load params file.
6581
file, err := f.FetchByName(addNodesParamsFile)
6682
if err != nil {
6783
if os.IsNotExist(err) {
@@ -71,10 +87,44 @@ func (a *AddNodesConfig) Load(f asset.FileFetcher) (bool, error) {
7187
}
7288

7389
params := &Params{}
74-
if err := json.Unmarshal(file.Data, params); err != nil {
90+
if err = json.Unmarshal(file.Data, params); err != nil {
7591
return false, fmt.Errorf("failed to unmarshal %s: %w", addNodesParamsFile, err)
7692
}
77-
7893
a.Params = *params
94+
95+
// Load nodes-config.yaml file.
96+
file, err = f.FetchByName(nodesConfigFilename)
97+
if err != nil {
98+
return false, fmt.Errorf("failed to load %s file: %w", nodesConfigFilename, err)
99+
}
100+
101+
config := Config{}
102+
if err = yaml.Unmarshal(file.Data, &config); err != nil {
103+
return false, fmt.Errorf("failed to unmarshal %s: %w", nodesConfigFilename, err)
104+
}
105+
a.Config = config
106+
107+
err = a.finish()
108+
if err != nil {
109+
return false, err
110+
}
79111
return true, nil
80112
}
113+
114+
func (a *AddNodesConfig) finish() error {
115+
if err := a.validateHosts().ToAggregate(); err != nil {
116+
return errors.Wrapf(err, "invalid nodes configuration")
117+
}
118+
return nil
119+
}
120+
121+
func (a *AddNodesConfig) validateHosts() field.ErrorList {
122+
var allErrs field.ErrorList
123+
124+
if len(a.Config.Hosts) == 0 {
125+
fieldPath := field.NewPath("hosts")
126+
allErrs = append(allErrs, field.Required(fieldPath, "at least one host must be defined"))
127+
}
128+
129+
return allErrs
130+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package joiner
2+
3+
import (
4+
"testing"
5+
6+
"github.com/golang/mock/gomock"
7+
"github.com/openshift/installer/pkg/asset"
8+
"github.com/openshift/installer/pkg/asset/mock"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestAddNodesConfig_Load(t *testing.T) {
13+
cases := []struct {
14+
name string
15+
addNodesParamsData string
16+
nodesConfigData string
17+
expectedError string
18+
}{
19+
{
20+
name: "default",
21+
nodesConfigData: `hosts:
22+
- hostname: master-0
23+
interfaces:
24+
- name: eth0
25+
macAddress: 00:ef:29:72:b9:771`,
26+
},
27+
{
28+
name: "empty nodes-config.yaml",
29+
expectedError: "invalid nodes configuration: hosts: Required value: at least one host must be defined",
30+
},
31+
}
32+
for _, tc := range cases {
33+
t.Run(tc.name, func(t *testing.T) {
34+
mockCtrl := gomock.NewController(t)
35+
defer mockCtrl.Finish()
36+
37+
if tc.addNodesParamsData == "" {
38+
tc.addNodesParamsData = "{}"
39+
}
40+
41+
fileFetcher := mock.NewMockFileFetcher(mockCtrl)
42+
fileFetcher.EXPECT().FetchByName(addNodesParamsFile).
43+
Return(
44+
&asset.File{
45+
Filename: addNodesParamsFile,
46+
Data: []byte(tc.addNodesParamsData)},
47+
nil,
48+
)
49+
fileFetcher.EXPECT().FetchByName(nodesConfigFilename).
50+
Return(
51+
&asset.File{
52+
Filename: nodesConfigFilename,
53+
Data: []byte(tc.nodesConfigData)},
54+
nil,
55+
)
56+
57+
addNodesConfig := &AddNodesConfig{}
58+
_, err := addNodesConfig.Load(fileFetcher)
59+
if tc.expectedError != "" {
60+
assert.Equal(t, tc.expectedError, err.Error())
61+
} else {
62+
assert.NoError(t, err)
63+
}
64+
})
65+
}
66+
}

0 commit comments

Comments
 (0)