Skip to content

Commit bcadc0a

Browse files
committed
Add dynamic ranges to generated communication matrix
This PR is adding the following changes: As requested from the partenrs, the dynamic port ranges of the cluster (Linux dynamic\private ranges, kubelet node port dynamic range, host level services dynamic range), are added to the generated communication matrix in all of the supported formats. The dynamic ranges are extracted in the following ways: Node port dynamic range: we are looking for a custom defined range (network.Spec.ServiceNodePortRange), if there is no range set, we use a default static range (30000-32767) Linux dynamic\private range: we retrive the dynamic range by reading the host sysctl (/proc/sys/net/ipv4/ip_local_port_range). We also have added the option of using a custom entries file that include ranges, so partners will be able to add their own ranges if needed. The e2e tests have been modified the following: EPS vs SS: in the comparsion between the matrices, we also check if host level open ports (from ss matrix) which don't have an EPS are in the range specified in the generated commatrix. Doc vs EPS: in the comparison between the matrices, we also check if the ports in the generated commatrix which are not documented in the doc matrix, do appear in the doc ranges. The custom entries samples had been modified to also include ranges. commatrix.go file's unit tests had been modified to allow mocking of a debugpod in the tests. For that sense, we have added to the commatrixCreator struct a utils field similar to what's done in the ConnectionCheck struct.
1 parent 39f5f71 commit bcadc0a

File tree

11 files changed

+563
-174
lines changed

11 files changed

+563
-174
lines changed

cmd/generate/generate.go

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"path/filepath"
77
"slices"
88
"strings"
9-
"time"
10-
11-
"context"
129

1310
"github.com/openshift-kni/commatrix/pkg/client"
1411
commatrixcreator "github.com/openshift-kni/commatrix/pkg/commatrix-creator"
@@ -20,13 +17,9 @@ import (
2017
configv1 "github.com/openshift/api/config/v1"
2118
log "github.com/sirupsen/logrus"
2219
"github.com/spf13/cobra"
23-
corev1 "k8s.io/api/core/v1"
24-
apierrors "k8s.io/apimachinery/pkg/api/errors"
25-
"k8s.io/apimachinery/pkg/util/wait"
2620
"k8s.io/cli-runtime/pkg/genericclioptions"
2721
"k8s.io/cli-runtime/pkg/genericiooptions"
2822
"k8s.io/kubectl/pkg/util/templates"
29-
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
3023

3124
"github.com/openshift-kni/commatrix/pkg/types"
3225
)
@@ -261,7 +254,7 @@ func generateMatrix(o *GenerateOptions, controlPlaneTopology configv1.TopologyMo
261254
}
262255

263256
log.Debug("Creating communication matrix")
264-
commMatrix, err := commatrixcreator.New(epExporter, o.customEntriesPath, o.customEntriesFormat, platformType, controlPlaneTopology, ipv6Enabled)
257+
commMatrix, err := commatrixcreator.New(epExporter, o.customEntriesPath, o.customEntriesFormat, platformType, controlPlaneTopology, ipv6Enabled, o.utilsHelpers)
265258
if err != nil {
266259
return nil, err
267260
}
@@ -300,21 +293,6 @@ func generateSS(o *GenerateOptions) (*types.ComMatrix, error) {
300293
defer func() {
301294
if delErr := o.utilsHelpers.DeleteNamespace(consts.DefaultDebugNamespace); delErr != nil {
302295
log.Warnf("failed to delete namespace %s: %v", consts.DefaultDebugNamespace, delErr)
303-
return
304-
}
305-
if pollErr := wait.PollUntilContextTimeout(context.TODO(), time.Second, 2*time.Minute, true, func(ctx context.Context) (bool, error) {
306-
ns := &corev1.Namespace{}
307-
err := o.cs.Get(context.TODO(), ctrlclient.ObjectKey{Name: consts.DefaultDebugNamespace}, ns)
308-
if apierrors.IsNotFound(err) {
309-
return true, nil
310-
}
311-
if err != nil {
312-
log.Warningf("retrying due to error: %v", err)
313-
return false, nil // keep retrying
314-
}
315-
return false, nil
316-
}); pollErr != nil {
317-
log.Errorf("error while waiting for namespace %s deletion: %v", consts.DefaultDebugNamespace, pollErr)
318296
}
319297
}()
320298

pkg/commatrix-creator/commatrix.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99

1010
log "github.com/sirupsen/logrus"
1111

12+
dynamicranges "github.com/openshift-kni/commatrix/pkg/dynamic-ranges"
1213
"github.com/openshift-kni/commatrix/pkg/endpointslices"
1314
"github.com/openshift-kni/commatrix/pkg/mcp"
1415
"github.com/openshift-kni/commatrix/pkg/types"
16+
"github.com/openshift-kni/commatrix/pkg/utils"
1517
configv1 "github.com/openshift/api/config/v1"
1618
)
1719

@@ -22,16 +24,18 @@ type CommunicationMatrixCreator struct {
2224
platformType configv1.PlatformType
2325
controlPlaneTopology configv1.TopologyMode
2426
ipv6Enabled bool
27+
utilsHelpers utils.UtilsInterface
2528
}
2629

27-
func New(exporter *endpointslices.EndpointSlicesExporter, customEntriesPath string, customEntriesFormat string, platformType configv1.PlatformType, controlPlaneTopology configv1.TopologyMode, ipv6Enabled bool) (*CommunicationMatrixCreator, error) {
30+
func New(exporter *endpointslices.EndpointSlicesExporter, customEntriesPath string, customEntriesFormat string, platformType configv1.PlatformType, controlPlaneTopology configv1.TopologyMode, ipv6Enabled bool, utilsHelpers utils.UtilsInterface) (*CommunicationMatrixCreator, error) {
2831
return &CommunicationMatrixCreator{
2932
exporter: exporter,
3033
customEntriesPath: customEntriesPath,
3134
customEntriesFormat: customEntriesFormat,
3235
platformType: platformType,
3336
controlPlaneTopology: controlPlaneTopology,
3437
ipv6Enabled: ipv6Enabled,
38+
utilsHelpers: utilsHelpers,
3539
}, nil
3640
}
3741

@@ -74,23 +78,33 @@ func (cm *CommunicationMatrixCreator) CreateEndpointMatrix() (*types.ComMatrix,
7478
staticEntries = expandStaticEntriesByPool(staticEntries, PoolRolesForStaticEntriesExpansion)
7579
epSliceComDetails = append(epSliceComDetails, staticEntries...)
7680

81+
var customMatrix *types.ComMatrix
7782
if cm.customEntriesPath != "" {
7883
log.Debug("Loading custom entries from file")
79-
customComDetails, err := cm.GetComDetailsListFromFile()
84+
customMatrix, err = cm.GetComMatrixFromFile()
8085
if err != nil {
8186
log.Errorf("Failed adding custom entries: %s", err)
8287
return nil, fmt.Errorf("failed adding custom entries: %s", err)
8388
}
84-
epSliceComDetails = append(epSliceComDetails, customComDetails...)
89+
epSliceComDetails = append(epSliceComDetails, customMatrix.Ports...)
8590
}
8691

87-
commMatrix := &types.ComMatrix{Ports: epSliceComDetails}
92+
dynamicRanges, err := dynamicranges.GetDynamicRanges(cm.exporter, cm.utilsHelpers)
93+
if err != nil {
94+
log.Errorf("Failed to get dynamic ranges: %v", err)
95+
return nil, fmt.Errorf("failed to get dynamic ranges: %w", err)
96+
}
97+
if customMatrix != nil && len(customMatrix.DynamicRanges) > 0 {
98+
dynamicRanges = append(dynamicRanges, customMatrix.DynamicRanges...)
99+
}
100+
101+
commMatrix := &types.ComMatrix{Ports: epSliceComDetails, DynamicRanges: dynamicRanges}
88102
log.Debug("Sorting ComMatrix and removing duplicates")
89103
commMatrix.SortAndRemoveDuplicates()
90104
return commMatrix, nil
91105
}
92106

93-
func (cm *CommunicationMatrixCreator) GetComDetailsListFromFile() ([]types.ComDetails, error) {
107+
func (cm *CommunicationMatrixCreator) GetComMatrixFromFile() (*types.ComMatrix, error) {
94108
log.Debugf("Opening file %s", cm.customEntriesPath)
95109
f, err := os.Open(filepath.Clean(cm.customEntriesPath))
96110
if err != nil {
@@ -107,7 +121,7 @@ func (cm *CommunicationMatrixCreator) GetComDetailsListFromFile() ([]types.ComDe
107121
}
108122

109123
log.Debugf("Unmarshalling file content with format %s", cm.customEntriesFormat)
110-
res, err := types.ParseToComDetailsList(raw, cm.customEntriesFormat)
124+
res, err := types.ParseToComMatrix(raw, cm.customEntriesFormat)
111125
if err != nil {
112126
log.Errorf("Failed to unmarshal %s file: %v", cm.customEntriesFormat, err)
113127
return nil, fmt.Errorf("failed to unmarshal custom entries file: %v", err)

pkg/commatrix-creator/commatrix_test.go

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ import (
66

77
g "github.com/onsi/ginkgo/v2"
88
o "github.com/onsi/gomega"
9+
gomock "go.uber.org/mock/gomock"
910
corev1 "k8s.io/api/core/v1"
1011
discoveryv1 "k8s.io/api/discovery/v1"
1112
"k8s.io/apimachinery/pkg/runtime"
1213
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1314

1415
"github.com/openshift-kni/commatrix/pkg/client"
16+
"github.com/openshift-kni/commatrix/pkg/consts"
1517
"github.com/openshift-kni/commatrix/pkg/endpointslices"
1618
matrixdiff "github.com/openshift-kni/commatrix/pkg/matrix-diff"
1719
"github.com/openshift-kni/commatrix/pkg/types"
20+
mock_utils "github.com/openshift-kni/commatrix/pkg/utils/mock"
1821
configv1 "github.com/openshift/api/config/v1"
1922
machineconfigurationv1 "github.com/openshift/api/machineconfiguration/v1"
2023
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -67,6 +70,16 @@ var (
6770
Optional: false,
6871
},
6972
}
73+
exampleDynamicRanges = []types.DynamicRange{
74+
{
75+
Direction: "ingress",
76+
Protocol: "TCP",
77+
MinPort: 9000,
78+
MaxPort: 9999,
79+
Description: "example dynamic range",
80+
Optional: false,
81+
},
82+
}
7083
)
7184

7285
// Test resources.
@@ -289,56 +302,66 @@ var (
289302
},
290303
},
291304
}
305+
306+
testNetwork = &configv1.Network{
307+
ObjectMeta: metav1.ObjectMeta{
308+
Name: "cluster",
309+
},
310+
Spec: configv1.NetworkSpec{
311+
ServiceNodePortRange: "30000-32767",
312+
},
313+
}
292314
)
293315

294316
var _ = g.Describe("Commatrix creator pkg tests", func() {
295317
g.Context("Get Costume entries List From File", func() {
296318
for _, format := range []string{types.FormatCSV, types.FormatJSON, types.FormatYAML} {
297319
g.It(fmt.Sprintf("Should successfully extract ComDetails from a %s file", format), func() {
298320
g.By(fmt.Sprintf("Creating new communication matrix with %s static entries format", format))
299-
cm, err := New(nil, fmt.Sprintf("../../samples/custom-entries/example-custom-entries.%s", format), format, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false)
321+
cm, err := New(nil, fmt.Sprintf("../../samples/custom-entries/example-custom-entries.%s", format), format, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false, nil)
300322
o.Expect(err).ToNot(o.HaveOccurred())
301323

302-
g.By("Getting ComDetails List From File")
303-
gotComDetails, err := cm.GetComDetailsListFromFile()
324+
g.By("Getting ComMatrix From File")
325+
gotComMatrix, err := cm.GetComMatrixFromFile()
304326
o.Expect(err).ToNot(o.HaveOccurred())
305327

306-
g.By("Comparing gotten ComDetails to wanted ComDetials")
307-
o.Expect(gotComDetails).To(o.Equal(exampleComDetailsList))
328+
g.By("Comparing gotten ComMatrix.Ports to wanted ComDetials")
329+
o.Expect(gotComMatrix.Ports).To(o.Equal(exampleComDetailsList))
330+
o.Expect(gotComMatrix.DynamicRanges).To(o.Equal(exampleDynamicRanges))
308331
})
309332
}
310333

311334
g.It("Should return an error due to non-matched customEntriesPath and customEntriesFormat types", func() {
312335
g.By("Creating new communication matrix with non-matched customEntriesPath and customEntriesFormat")
313-
cm, err := New(nil, "../../samples/custom-entries/example-custom-entries.csv", types.FormatJSON, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false)
336+
cm, err := New(nil, "../../samples/custom-entries/example-custom-entries.csv", types.FormatJSON, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false, nil)
314337
o.Expect(err).ToNot(o.HaveOccurred())
315338

316-
g.By("Getting ComDetails List From File")
317-
gotComDetails, err := cm.GetComDetailsListFromFile()
339+
g.By("Getting ComMatrix From File")
340+
gotComMatrix, err := cm.GetComMatrixFromFile()
318341
o.Expect(err).To(o.HaveOccurred())
319342

320-
g.By("Comparing gotten ComDetails to empty ComDetials")
321-
o.Expect(gotComDetails).To(o.Equal(nilComDetailsList))
343+
g.By("Expecting nil ComMatrix on error")
344+
o.Expect(gotComMatrix).To(o.BeNil())
322345
})
323346

324347
g.It("Should return an error due to an invalid customEntriesFormat", func() {
325348
g.By("Creating new communication matrix with invalid customEntriesFormat")
326-
cm, err := New(nil, "../../samples/custom-entries/example-custom-entries.csv", types.FormatNFT, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false)
349+
cm, err := New(nil, "../../samples/custom-entries/example-custom-entries.csv", types.FormatNFT, configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false, nil)
327350
o.Expect(err).ToNot(o.HaveOccurred())
328351

329-
g.By("Getting ComDetails List From File")
330-
gotComDetails, err := cm.GetComDetailsListFromFile()
352+
g.By("Getting ComMatrix From File")
353+
gotComMatrix, err := cm.GetComMatrixFromFile()
331354
o.Expect(err).To(o.HaveOccurred())
332355

333-
g.By("Comparing gotten ComDetails to empty ComDetials")
334-
o.Expect(gotComDetails).To(o.Equal(nilComDetailsList))
356+
g.By("Expecting nil ComMatrix on error")
357+
o.Expect(gotComMatrix).To(o.BeNil())
335358
})
336359
})
337360

338361
g.Context("Get static entries from file", func() {
339362
g.It("Should successfully get static entries suitable to baremetal standard cluster", func() {
340363
g.By("Creating new communication matrix suitable to baremetal standard cluster")
341-
cm, err := New(nil, "", "", configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false)
364+
cm, err := New(nil, "", "", configv1.BareMetalPlatformType, configv1.HighlyAvailableTopologyMode, false, nil)
342365
o.Expect(err).ToNot(o.HaveOccurred())
343366

344367
g.By("Getting static entries comDetails of the created communication matrix")
@@ -353,7 +376,7 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
353376

354377
g.It("Should successfully get static entries suitable to baremetal SNO cluster", func() {
355378
g.By("Creating new communication matrix suitable to baremetal SNO cluster")
356-
cm, err := New(nil, "", "", configv1.BareMetalPlatformType, configv1.SingleReplicaTopologyMode, false)
379+
cm, err := New(nil, "", "", configv1.BareMetalPlatformType, configv1.SingleReplicaTopologyMode, false, nil)
357380
o.Expect(err).ToNot(o.HaveOccurred())
358381

359382
g.By("Getting static entries comDetails of the created communication matrix")
@@ -367,7 +390,7 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
367390

368391
g.It("Should return an error due to an invalid value for cluster environment", func() {
369392
g.By("Creating new communication matrix with an invalid value for cluster environment")
370-
cm, err := New(nil, "", "", "invalid", configv1.SingleReplicaTopologyMode, false)
393+
cm, err := New(nil, "", "", "invalid", configv1.SingleReplicaTopologyMode, false, nil)
371394
o.Expect(err).ToNot(o.HaveOccurred())
372395

373396
g.By("Getting static entries comDetails of the created communication matrix")
@@ -381,6 +404,9 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
381404
})
382405

383406
g.Context("Create EndpointSlice Matrix", func() {
407+
var ctrl *gomock.Controller
408+
var mockUtils *mock_utils.MockUtilsInterface
409+
384410
g.BeforeEach(func() {
385411
sch := runtime.NewScheme()
386412

@@ -390,9 +416,11 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
390416
o.Expect(err).NotTo(o.HaveOccurred())
391417
err = machineconfigurationv1.AddToScheme(sch)
392418
o.Expect(err).NotTo(o.HaveOccurred())
419+
err = configv1.AddToScheme(sch)
420+
o.Expect(err).NotTo(o.HaveOccurred())
393421

394-
fakeClient := fake.NewClientBuilder().WithScheme(sch).WithObjects(testNode, testNodeWorker, testPod, testService, testEndpointSlice, mcpWorker, mcpMaster).Build()
395-
fakeClientset := fakek.NewSimpleClientset()
422+
fakeClient := fake.NewClientBuilder().WithScheme(sch).WithObjects(testNode, testNodeWorker, testPod, testService, testEndpointSlice, mcpWorker, mcpMaster, testNetwork).Build()
423+
fakeClientset := fakek.NewSimpleClientset(testNode, testNodeWorker)
396424

397425
clientset := &client.ClientSet{
398426
Client: fakeClient,
@@ -401,11 +429,43 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
401429

402430
endpointSlices, err = endpointslices.New(clientset)
403431
o.Expect(err).ToNot(o.HaveOccurred())
432+
433+
// Set up mock utils to avoid pod creation in tests
434+
ctrl = gomock.NewController(g.GinkgoT())
435+
mockUtils = mock_utils.NewMockUtilsInterface(ctrl)
436+
437+
// Mock all the utils calls needed for getLinuxDynamicPrivateRange
438+
mockUtils.EXPECT().CreateNamespace(consts.DefaultDebugNamespace).Return(nil).AnyTimes()
439+
mockUtils.EXPECT().DeleteNamespace(consts.DefaultDebugNamespace).Return(nil).AnyTimes()
440+
441+
// Create a mock pod
442+
mockPod := &corev1.Pod{
443+
ObjectMeta: metav1.ObjectMeta{
444+
Name: "debug-pod",
445+
Namespace: consts.DefaultDebugNamespace,
446+
},
447+
Status: corev1.PodStatus{
448+
Phase: corev1.PodRunning,
449+
},
450+
}
451+
mockUtils.EXPECT().CreatePodOnNode(gomock.Any(), consts.DefaultDebugNamespace, gomock.Any(), gomock.Any()).Return(mockPod, nil).AnyTimes()
452+
mockUtils.EXPECT().DeletePod(mockPod).Return(nil).AnyTimes()
453+
mockUtils.EXPECT().WaitForPodStatus(consts.DefaultDebugNamespace, mockPod, corev1.PodRunning).Return(nil).AnyTimes()
454+
455+
// Mock the command output to return a default port range
456+
mockUtils.EXPECT().RunCommandOnPod(mockPod, gomock.Any()).Return([]byte("32768 60999\n"), nil).AnyTimes()
457+
})
458+
459+
g.AfterEach(func() {
460+
// Finish the controller
461+
if ctrl != nil {
462+
ctrl.Finish()
463+
}
404464
})
405465

406466
g.It("Should successfully create an endpoint matrix with custom entries", func() {
407467
g.By("Creating new communication matrix with static entries")
408-
commatrixCreator, err := New(endpointSlices, "../../samples/custom-entries/example-custom-entries.csv", types.FormatCSV, configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false)
468+
commatrixCreator, err := New(endpointSlices, "../../samples/custom-entries/example-custom-entries.csv", types.FormatCSV, configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false, mockUtils)
409469
o.Expect(err).ToNot(o.HaveOccurred())
410470
commatrix, err := commatrixCreator.CreateEndpointMatrix()
411471
o.Expect(err).ToNot(o.HaveOccurred())
@@ -429,7 +489,7 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
429489

430490
g.It("Should successfully create an endpoint matrix without custom entries", func() {
431491
g.By("Creating new communication matrix without static entries")
432-
commatrixCreator, err := New(endpointSlices, "", "", configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false)
492+
commatrixCreator, err := New(endpointSlices, "", "", configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false, mockUtils)
433493
o.Expect(err).ToNot(o.HaveOccurred())
434494
commatrix, err := commatrixCreator.CreateEndpointMatrix()
435495
o.Expect(err).ToNot(o.HaveOccurred())
@@ -449,7 +509,7 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
449509

450510
g.It("Should include IPv6 static entries when ipv6Enabled is true on Standard", func() {
451511
g.By("Creating communication matrix with ipv6Enabled=true for Standard")
452-
commatrixCreator, err := New(endpointSlices, "", "", configv1.AWSPlatformType, configv1.HighlyAvailableTopologyMode, true)
512+
commatrixCreator, err := New(endpointSlices, "", "", configv1.AWSPlatformType, configv1.HighlyAvailableTopologyMode, true, mockUtils)
453513
o.Expect(err).ToNot(o.HaveOccurred())
454514
commatrix, err := commatrixCreator.CreateEndpointMatrix()
455515
o.Expect(err).ToNot(o.HaveOccurred())
@@ -496,7 +556,7 @@ var _ = g.Describe("Commatrix creator pkg tests", func() {
496556
o.Expect(err).ToNot(o.HaveOccurred())
497557

498558
g.By("Creating endpoint matrix")
499-
commatrixCreator, err := New(localhostEndpointSlices, "", "", configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false)
559+
commatrixCreator, err := New(localhostEndpointSlices, "", "", configv1.AWSPlatformType, configv1.SingleReplicaTopologyMode, false, nil)
500560
o.Expect(err).ToNot(o.HaveOccurred())
501561
commatrix, err := commatrixCreator.CreateEndpointMatrix()
502562
o.Expect(err).ToNot(o.HaveOccurred())

0 commit comments

Comments
 (0)