Skip to content

Commit

Permalink
Generate commatrix output files and fix review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sabinaaledort committed Apr 17, 2024
1 parent 8253601 commit 9875b54
Show file tree
Hide file tree
Showing 21 changed files with 1,612 additions and 226 deletions.
20 changes: 20 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FORMAT ?= csv
CLUSTER_ENV ?= baremetal
DEST_DIR ?= .
DEPLOYMENT ?= mno
GO_SRC := cmd/main.go

EXECUTABLE := commatrix-gen

.DEFAULT_GOAL := run

build:
go build -o $(EXECUTABLE) $(GO_SRC)

# TODO: check if oc is installed
generate: build
mkdir -p $(DEST_DIR)/communication-matrix
./$(EXECUTABLE) -format=$(FORMAT) -env=$(CLUSTER_ENV) -destDir=$(DEST_DIR)/communication-matrix -deployment=$(DEPLOYMENT)

clean:
@rm -f $(EXECUTABLE)
38 changes: 38 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package client

import (
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
discoveryv1client "k8s.io/client-go/kubernetes/typed/discovery/v1"
"k8s.io/client-go/tools/clientcmd"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

type ClientSet struct {
corev1client.CoreV1Interface
appsv1client.AppsV1Interface
discoveryv1client.DiscoveryV1Interface
runtimeclient.Client
configv1client.ConfigV1Interface
}

func New(kubeconfigPath string) (*ClientSet, error) {
config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
if err != nil {
return nil, err
}

clientSet := &ClientSet{}
clientSet.CoreV1Interface = corev1client.NewForConfigOrDie(config)
clientSet.AppsV1Interface = appsv1client.NewForConfigOrDie(config)
clientSet.DiscoveryV1Interface = discoveryv1client.NewForConfigOrDie(config)
clientSet.ConfigV1Interface = configv1client.NewForConfigOrDie(config)

clientSet.Client, err = runtimeclient.New(config, runtimeclient.Options{})
if err != nil {
return nil, err
}

return clientSet, nil
}
170 changes: 170 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package main

import (
"context"
"flag"
"fmt"
"os"
"path"
"path/filepath"
"sync"

clientutil "github.com/openshift-kni/commatrix/client"
"github.com/openshift-kni/commatrix/commatrix"
"github.com/openshift-kni/commatrix/ss"
"github.com/openshift-kni/commatrix/types"
"golang.org/x/sync/errgroup"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
var (
destDir string
format string
envStr string
deploymentStr string
customEntriesPath string
printFn func(m types.ComMatrix) ([]byte, error)
)

flag.StringVar(&destDir, "destDir", "communication-matrix", "Output files dir")
flag.StringVar(&format, "format", "csv", "Desired format (json,yaml,csv)")
flag.StringVar(&envStr, "env", "baremetal", "Cluster environment (baremetal/aws)")
flag.StringVar(&deploymentStr, "deployment", "mno", "Deployment type (mno/sno)")
flag.StringVar(&customEntriesPath, "customEntriesPath", "", "Add custom entries from a JSON file to the matrix")

flag.Parse()

switch format {
case "json":
printFn = types.ToJSON
case "csv":
printFn = types.ToCSV
case "yaml":
printFn = types.ToYAML
default:
panic(fmt.Sprintf("invalid format: %s. Please specify json, csv, or yaml.", format))
}

kubeconfig, ok := os.LookupEnv("KUBECONFIG")
if !ok {
panic("must set the KUBECONFIG environment variable")
}

var env commatrix.Env
switch envStr {
case "baremetal":
env = commatrix.Baremetal
case "aws":
env = commatrix.AWS
default:
panic(fmt.Sprintf("invalid cluster environment: %s", envStr))
}

var deployment commatrix.Deployment
switch deploymentStr {
case "mno":
deployment = commatrix.MNO
case "sno":
deployment = commatrix.SNO
default:
panic(fmt.Sprintf("invalid deployment type: %s", deploymentStr))
}

mat, err := commatrix.New(kubeconfig, customEntriesPath, env, deployment)
if err != nil {
panic(fmt.Sprintf("failed to create the communication matrix: %s", err))
}

res, err := printFn(*mat)
if err != nil {
panic(err)
}

comMatrixFileName := filepath.Join(destDir, fmt.Sprintf("communication-matrix.%s", format))
err = os.WriteFile(comMatrixFileName, []byte(string(res)), 0644)
if err != nil {
panic(err)
}

cs, err := clientutil.New(kubeconfig)
if err != nil {
panic(err)
}

tcpFile, err := os.OpenFile(path.Join(destDir, "raw-ss-tcp"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer tcpFile.Close()

udpFile, err := os.OpenFile(path.Join(destDir, "raw-ss-udp"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
defer udpFile.Close()

nodesList, err := cs.CoreV1Interface.Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}

nodesComDetails := []types.ComDetails{}
nLock := &sync.Mutex{}
g := new(errgroup.Group)
for _, n := range nodesList.Items {
node := n
g.Go(func() error {
cds, err := ss.CreateComDetailsFromNode(cs, &node, tcpFile, udpFile)
if err != nil {
return err
}
nLock.Lock()
nodesComDetails = append(nodesComDetails, cds...)
nLock.Unlock()
return nil
})
}

err = g.Wait()
if err != nil {
panic(err)
}

cleanedComDetails := types.RemoveDups(nodesComDetails)
ssComMat := types.ComMatrix{Matrix: cleanedComDetails}

res, err = printFn(ssComMat)
if err != nil {
panic(err)
}

ssMatrixFileName := filepath.Join(destDir, fmt.Sprintf("ss-generated-matrix.%s", format))
err = os.WriteFile(ssMatrixFileName, []byte(string(res)), 0644)
if err != nil {
panic(err)
}

diff := ""
for _, cd := range mat.Matrix {
if ssComMat.Contains(cd) {
diff += fmt.Sprintf("%s\n", cd)
continue
}
diff += fmt.Sprintf("+ %s\n", cd)
}

for _, cd := range ssComMat.Matrix {
if !mat.Contains(cd) {
diff += fmt.Sprintf("- %s\n", cd)
continue
}
}

err = os.WriteFile(filepath.Join(destDir, "matrix-diff-ss"),
[]byte(diff),
0644)
if err != nil {
panic(err)
}
}
65 changes: 49 additions & 16 deletions commatrix/commatrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,34 @@ import (
"os"
"path/filepath"

"github.com/liornoy/node-comm-lib/pkg/client"
"github.com/liornoy/node-comm-lib/pkg/endpointslices"
"github.com/liornoy/node-comm-lib/pkg/types"
"github.com/openshift-kni/commatrix/client"
"github.com/openshift-kni/commatrix/endpointslices"
"github.com/openshift-kni/commatrix/types"
)

// TODO: add integration tests

type Env int

const (
Baremetal Env = iota
AWS
)

type Deployment int

const (
SNO Deployment = iota
MNO
)

// New initializes a ComMatrix using Kubernetes cluster data.
// It takes kubeconfigPath for cluster access to fetch EndpointSlice objects,
// detailing open ports for ingress traffic.
// customEntriesPath allows adding custom entries from a JSON file to the matrix.
// Returns a pointer to ComMatrix and error. Entries include traffic direction, protocol,
// port number, namespace, service name, pod, container, node role, and flow optionality for OpenShift.
func New(kubeconfigPath string, customEntriesPath string, e Env) (*types.ComMatrix, error) {
func New(kubeconfigPath string, customEntriesPath string, e Env, d Deployment) (*types.ComMatrix, error) {
res := make([]types.ComDetails, 0)

cs, err := client.New(kubeconfigPath)
Expand All @@ -44,7 +53,7 @@ func New(kubeconfigPath string, customEntriesPath string, e Env) (*types.ComMatr
}
res = append(res, epSliceComDetails...)

staticEntries, err := getStaticEntries(e)
staticEntries, err := getStaticEntries(e, d)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -83,32 +92,56 @@ func addFromFile(fp string) ([]types.ComDetails, error) {
return res, nil
}

func getStaticEntries(e Env) ([]types.ComDetails, error) {
var (
envComDetails []types.ComDetails
genericComDetails []types.ComDetails
)
func getStaticEntries(e Env, d Deployment) ([]types.ComDetails, error) {
comDetails := []types.ComDetails{}
add := []types.ComDetails{}

switch e {
case Baremetal:
err := json.Unmarshal([]byte(baremetalStaticEntries), &envComDetails)
err := json.Unmarshal([]byte(baremetalStaticEntriesMaster), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
if d == SNO {
break
}
err = json.Unmarshal([]byte(baremetalStaticEntriesWorker), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
case AWS:
err := json.Unmarshal([]byte(awsCloudStaticEntries), &envComDetails)
err := json.Unmarshal([]byte(awsCloudStaticEntriesMaster), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
if d == SNO {
break
}
err = json.Unmarshal([]byte(awsCloudStaticEntriesWorker), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
default:
return nil, fmt.Errorf("invalid value for cluster environment")
}

err := json.Unmarshal([]byte(generalStaticEntries), &genericComDetails)
err := json.Unmarshal([]byte(generalStaticEntriesMaster), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
if d == SNO {
return comDetails, nil
}

res := append(envComDetails, genericComDetails...)

return res, nil
err = json.Unmarshal([]byte(generalStaticEntriesWorker), &add)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal static entries: %v", err)
}
comDetails = append(comDetails, add...)
return comDetails, nil
}
Loading

0 comments on commit 9875b54

Please sign in to comment.