@@ -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
1218const (
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.
1825type 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.
6479func (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+ }
0 commit comments