Skip to content

Commit

Permalink
OCPBUGS-41834: Add agent installer checks for hosts interface table
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bfournie committed Sep 24, 2024
1 parent 30ba9c5 commit 4bafe2a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
24 changes: 24 additions & 0 deletions pkg/asset/agent/manifests/nmstateconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
14 changes: 11 additions & 3 deletions pkg/asset/agent/manifests/staticnetworkconfig/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -61,7 +62,7 @@ func (s *staticNetworkConfigGenerator) GenerateStaticNetworkConfigData(ctx conte
s.log.WithError(err).Errorf("Failed to decode static network config")
return nil, err
}
s.log.Infof("Start configuring static network for %d hosts", len(staticNetworkConfig))
s.log.Warnf("Start configuring static network for %d hosts", len(staticNetworkConfig))
filesList := []StaticNetworkConfigData{}
for i, hostConfig := range staticNetworkConfig {
hostFileList, err := s.generateHostStaticNetworkConfigData(ctx, hostConfig, fmt.Sprintf("host%d", i))
Expand Down Expand Up @@ -218,21 +219,28 @@ func (s *staticNetworkConfigGenerator) formatNMConnection(nmConnection string) (
// ValidateStaticConfigParams validates the NMState data in a HostStaticNetworkConfig.
func (s *staticNetworkConfigGenerator) ValidateStaticConfigParams(ctx context.Context, staticNetworkConfig []*models.HostStaticNetworkConfig) error {
var err *multierror.Error
s.log.Warnf("Validating StaticConfigParams")
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))
}
}
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)
Expand Down
33 changes: 33 additions & 0 deletions pkg/asset/agent/manifests/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down

0 comments on commit 4bafe2a

Please sign in to comment.