Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate commatrix output files and fix review comments #2

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
3 changes: 3 additions & 0 deletions pkg/client/client.go → client/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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"
Expand All @@ -13,6 +14,7 @@ type ClientSet struct {
appsv1client.AppsV1Interface
discoveryv1client.DiscoveryV1Interface
runtimeclient.Client
configv1client.ConfigV1Interface
}

func New(kubeconfigPath string) (*ClientSet, error) {
Expand All @@ -25,6 +27,7 @@ func New(kubeconfigPath string) (*ClientSet, error) {
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 {
Expand Down
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)
}
}
67 changes: 50 additions & 17 deletions commatrix/commatrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,34 @@
"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

Check failure on line 15 in commatrix/commatrix.go

View workflow job for this annotation

GitHub Actions / unit-test

Comment should end in a period (godot)

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.
// Custom entries from a JSON file can be added to the matrix by setting `customEntriesPath`.
// 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 @@
}
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 @@
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
Loading