1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

baremetal: add NetworkConfig field and validation

Allow to specify desidered host networking settings yaml
compatible with NMState as a new install-config field.
Validation rule ensures that the string is at least a
valid generic yaml.
This commit is contained in:
Andrea Fasano
2021-09-13 07:01:38 -04:00
parent 8fc863d833
commit e367de337a
5 changed files with 56 additions and 0 deletions

View File

@@ -1448,6 +1448,8 @@ spec:
type: string
name:
type: string
networkConfig:
type: string
role:
type: string
rootDeviceHints:

View File

@@ -233,6 +233,7 @@ should be used to build the cluster. The number of assets must be at least great
| `bootMACAddress` | | The MAC address of the NIC the host will use to boot on the provisioning network. It must be unique. |
| `rootDeviceHints` | | How to choose the target disk for the OS during provisioning - for more details see [upstream docs](https://github.com/metal3-io/baremetal-operator/blob/master/docs/api.md). |
| `bootMode` | `UEFI` | Choose `legacy` (BIOS) or `UEFI` mode for booting. Use `UEFISecureBoot` to enable UEFI and secure boot on the server. Only some drivers support UEFI secure boot (notably, IPMI does not). |
| `networkConfig` | | Yaml string describing the desired host networking settings. Must be compatible with NMState (for more details see https://nmstate.io/) |
The `bmc` parameter for each host is a set of values for accessing the
baseboard management controller in the host.

View File

@@ -39,6 +39,7 @@ type Host struct {
HardwareProfile string `json:"hardwareProfile"`
RootDeviceHints *RootDeviceHints `json:"rootDeviceHints,omitempty"`
BootMode BootMode `json:"bootMode,omitempty"`
NetworkConfig string `json:"networkConfig,omitempty"`
}
// IsMaster checks if the current host is a master

View File

@@ -10,6 +10,7 @@ import (
"strings"
"github.com/apparentlymart/go-cidr/cidr"
"github.com/ghodss/yaml"
"github.com/go-playground/validator/v10"
"github.com/metal3-io/baremetal-operator/pkg/bmc"
"github.com/pkg/errors"
@@ -325,6 +326,18 @@ func validateHostsCount(hosts []*baremetal.Host, installConfig *types.InstallCon
return nil
}
// ensure that the NetworkConfig field contains a valid Yaml string
func validateNetworkConfig(hosts []*baremetal.Host, fldPath *field.Path) (errors field.ErrorList) {
for idx, host := range hosts {
networkConfig := make(map[string]interface{})
err := yaml.Unmarshal([]byte(host.NetworkConfig), &networkConfig)
if err != nil {
errors = append(errors, field.Invalid(fldPath.Index(idx).Child("networkConfig"), host.NetworkConfig, fmt.Sprintf("Not a valid yaml: %s", err.Error())))
}
}
return
}
// ensure that the bootMode field contains a valid value
func validateBootMode(hosts []*baremetal.Host, fldPath *field.Path) (errors field.ErrorList) {
for idx, host := range hosts {
@@ -404,6 +417,7 @@ func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field
allErrs = append(allErrs, validateHostsWithoutBMC(p.Hosts, fldPath)...)
allErrs = append(allErrs, validateBootMode(p.Hosts, fldPath.Child("Hosts"))...)
allErrs = append(allErrs, validateNetworkConfig(p.Hosts, fldPath.Child("Hosts"))...)
return allErrs
}

View File

@@ -262,6 +262,39 @@ func TestValidatePlatform(t *testing.T) {
platform: platform().ProvisioningNetwork("Invalid").build(),
expected: `Unsupported value: "Invalid": supported values: "Disabled", "Managed", "Unmanaged"`,
},
{
name: "networkConfig_invalid",
platform: platform().Hosts(host1().NetworkConfig("Not a valid yaml content")).build(),
expected: ".*Invalid value.*Not a valid yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map\\[string\\]interface \\{\\}",
},
{
name: "networkConfig_valid_yml",
platform: platform().Hosts(host1().NetworkConfig(`
interfaces:
- name: eth1
type: ethernet
state: up
- name: linux-br0
type: linux-bridge
state: up
bridge:
options:
group-forward-mask: 0
mac-ageing-time: 300
multicast-snooping: true
stp:
enabled: true
forward-delay: 15
hello-time: 2
max-age: 20
priority: 32768
port:
- name: eth1
stp-hairpin-mode: false
stp-path-cost: 100
stp-priority: 32`)).build(),
expected: "",
},
}
for _, tc := range cases {
@@ -731,6 +764,11 @@ func (hb *hostBuilder) Role(value string) *hostBuilder {
return hb
}
func (hb *hostBuilder) NetworkConfig(value string) *hostBuilder {
hb.Host.NetworkConfig = value
return hb
}
type platformBuilder struct {
baremetal.Platform
}