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

OCPBUGS-41834: Add agent installer checks for hosts interface table

Add checks for the host interface table to validate:
- at least one entry is defined in the interface table when using
  network configuration
- the MAC addresses in the interface table are using the expected format
This commit is contained in:
Bob Fournier
2024-09-24 10:52:02 -04:00
parent 30ba9c57d5
commit df4120d95d
4 changed files with 67 additions and 3 deletions

2
go.mod
View File

@@ -48,6 +48,7 @@ require (
github.com/go-openapi/runtime v0.28.0
github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/swag v0.23.0
github.com/go-openapi/validate v0.24.0
github.com/go-playground/validator/v10 v10.19.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/mock v1.7.0-rc.1
@@ -185,7 +186,6 @@ require (
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect

View File

@@ -284,6 +284,30 @@ func TestNMStateConfig_Generate(t *testing.T) {
expectedConfig: nil,
expectedError: "failed to validate network yaml",
},
{
name: "invalid networkConfig, no interfaces in interface table",
dependencies: []asset.Asset{
&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
&joiner.ClusterInfo{},
getAgentHostsConfigNoInterfaces(),
getValidOptionalInstallConfig(),
},
requiresNmstatectl: true,
expectedConfig: nil,
expectedError: "at least one interface for host 0 must be provided",
},
{
name: "invalid networkConfig, invalid mac in interface table",
dependencies: []asset.Asset{
&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
&joiner.ClusterInfo{},
getAgentHostsConfigInvalidMac(),
getValidOptionalInstallConfig(),
},
requiresNmstatectl: true,
expectedConfig: nil,
expectedError: "MAC address 98-af-65-a5-8d-02 for host 0 is incorrectly formatted, use XX:XX:XX:XX:XX:XX format",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {

View File

@@ -10,6 +10,7 @@ import (
"sort"
"strings"
"github.com/go-openapi/validate"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -219,7 +220,7 @@ func (s *staticNetworkConfigGenerator) formatNMConnection(nmConnection string) (
func (s *staticNetworkConfigGenerator) ValidateStaticConfigParams(ctx context.Context, staticNetworkConfig []*models.HostStaticNetworkConfig) error {
var err *multierror.Error
for i, hostConfig := range staticNetworkConfig {
err = multierror.Append(err, s.validateMacInterfaceName(i, hostConfig.MacInterfaceMap))
err = multierror.Append(err, s.validateMacInterfaceTable(i, hostConfig.MacInterfaceMap))
if validateErr := s.ValidateNMStateYaml(ctx, hostConfig.NetworkYaml); validateErr != nil {
err = multierror.Append(err, fmt.Errorf("failed to validate network yaml for host %d, %w", i, validateErr))
}
@@ -227,12 +228,18 @@ func (s *staticNetworkConfigGenerator) ValidateStaticConfigParams(ctx context.Co
return err.ErrorOrNil()
}
func (s *staticNetworkConfigGenerator) validateMacInterfaceName(hostIdx int, macInterfaceMap models.MacInterfaceMap) error {
func (s *staticNetworkConfigGenerator) validateMacInterfaceTable(hostIdx int, macInterfaceMap models.MacInterfaceMap) error {
if len(macInterfaceMap) == 0 {
return fmt.Errorf("at least one interface for host %d must be provided", hostIdx)
}
interfaceCheck := make(map[string]struct{}, len(macInterfaceMap))
macCheck := make(map[string]struct{}, len(macInterfaceMap))
for _, macInterface := range macInterfaceMap {
interfaceCheck[macInterface.LogicalNicName] = struct{}{}
macCheck[macInterface.MacAddress] = struct{}{}
if err := validate.Pattern("mac_address", "body", macInterface.MacAddress, `^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$`); err != nil {
return fmt.Errorf("MAC address %s for host %d is incorrectly formatted, use XX:XX:XX:XX:XX:XX format", macInterface.MacAddress, hostIdx)
}
}
if len(interfaceCheck) < len(macInterfaceMap) || len(macCheck) < len(macInterfaceMap) {
return fmt.Errorf("MACs and Interfaces for host %d must be unique", hostIdx)

View File

@@ -450,6 +450,39 @@ func getAgentHostsWithBMCConfig() *agentconfig.AgentHosts {
}
}
func getAgentHostsConfigNoInterfaces() *agentconfig.AgentHosts {
return &agentconfig.AgentHosts{
Hosts: []agenttypes.Host{
{
Hostname: "control-0.example.org",
Interfaces: []*v1beta1.Interface{},
NetworkConfig: v1beta1.NetConfig{
Raw: unmarshalJSON([]byte(rawNMStateConfig)),
},
},
},
}
}
func getAgentHostsConfigInvalidMac() *agentconfig.AgentHosts {
return &agentconfig.AgentHosts{
Hosts: []agenttypes.Host{
{
Hostname: "control-0.example.org",
Interfaces: []*v1beta1.Interface{
{
Name: "enp2s0",
MacAddress: "98-af-65-a5-8d-02",
},
},
NetworkConfig: v1beta1.NetConfig{
Raw: unmarshalJSON([]byte(rawNMStateConfig)),
},
},
},
}
}
func getGoodACI() *hiveext.AgentClusterInstall {
goodACI := &hiveext.AgentClusterInstall{
TypeMeta: metav1.TypeMeta{