Skip to content

Commit

Permalink
Update Antrea Octant plugin to support latest Octant version
Browse files Browse the repository at this point in the history
We can now support Octant 0.24 (latest version). Older versions (up to
0.19) may be supported as well (not tested).

By updating the Octant module dependency to v0.24.0, we can also start
using the Octant Dashboard client to perform CRUD operations on Antrea
CRDs, thus ensuring that the plugin is always using the correct cluster
context (see #1519).

A few other notable things:
* We can remove replace directives in the plugin go.mod file (for now?)
  since K8s dependencies between Antrea and Octant are compatible.
* Octant now has a new logging mechanism for plugins but unfortunately
  it is still buggy so we are not updating our plugin to use it.
* The Dashboard client supports a link generator to easily generate
  links to resources
  (vmware-archive/octant#2276). Unfortunately I
  believe that in practice it would make our plugin code more
  complicated. We can revisit this in the future.

Fixes #1519
Fixes #2315
Fixes #2676

Signed-off-by: Antonin Bas <[email protected]>
  • Loading branch information
antoninbas committed Oct 30, 2021
1 parent ae2b53d commit d10e035
Show file tree
Hide file tree
Showing 6 changed files with 767 additions and 260 deletions.
12 changes: 6 additions & 6 deletions docs/octant-plugin-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,20 @@ detailed installation instructions.

You can follow the steps listed below to install octant and antrea-octant-plugin on linux.

1. Get and install Octant v0.16.1.
1. Get and install Octant v0.24.0.

Depending on your linux operating system, to install Octant v0.16.1, you can use either
Depending on your linux operating system, to install Octant v0.24.0, you can use either

```bash
wget https://github.com/vmware-tanzu/octant/releases/download/v0.16.1/octant_0.16.1_Linux-64bit.deb
dpkg -i octant_0.16.1_Linux-64bit.deb
wget https://github.com/vmware-tanzu/octant/releases/download/v0.24.0/octant_0.24.0_Linux-64bit.deb
dpkg -i octant_0.24.0_Linux-64bit.deb
```

or

```bash
wget https://github.com/vmware-tanzu/octant/releases/download/v0.16.1/octant_0.16.1_Linux-64bit.rpm
rpm -i octant_0.16.1_Linux-64bit.rpm
wget https://github.com/vmware-tanzu/octant/releases/download/v0.24.0/octant_0.24.0_Linux-64bit.rpm
rpm -i octant_0.24.0_Linux-64bit.rpm
```

2. Export your kubeconfig path (file location depends on your setup) to environment variable $KUBECONFIG,
Expand Down
62 changes: 53 additions & 9 deletions plugins/octant/cmd/antrea-octant-plugin/antrea_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ package main
import (
"context"
"log"
"sort"
"strconv"
"strings"

"github.com/vmware-tanzu/octant/pkg/plugin/service"
"github.com/vmware-tanzu/octant/pkg/store"
"github.com/vmware-tanzu/octant/pkg/view/component"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"

crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1"
)

const (
Expand Down Expand Up @@ -58,16 +62,36 @@ func (p *antreaOctantPlugin) agentHandler(request service.Request) (component.Co
}, nil
}

func listAntreaControllerInfos(ctx context.Context, client service.Dashboard, sortedByPodName bool) ([]crdv1beta1.AntreaControllerInfo, error) {
unstructuredList, err := client.List(ctx, store.Key{
APIVersion: "crd.antrea.io/v1beta1",
Kind: "AntreaControllerInfo",
})
if err != nil {
return nil, err
}
controllers := make([]crdv1beta1.AntreaControllerInfo, len(unstructuredList.Items))
for idx, unstructuredObj := range unstructuredList.Items {
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredObj.Object, &controllers[idx]); err != nil {
return nil, err
}
}
if sortedByPodName {
sort.Slice(controllers, func(p, q int) bool {
return controllers[p].PodRef.Name < controllers[q].PodRef.Name
})
}
return controllers, nil
}

// getControllerTable gets the table for displaying Controller information
func (p *antreaOctantPlugin) getControllerTable(request service.Request) *component.Table {
controllers, err := p.client.CrdV1beta1().AntreaControllerInfos().List(context.TODO(), metav1.ListOptions{
ResourceVersion: "0",
})
controllers, err := listAntreaControllerInfos(request.Context(), request.DashboardClient(), true)
if err != nil {
log.Fatalf("Failed to get AntreaControllerInfos %v", err)
}
controllerRows := make([]component.TableRow, 0)
for _, controller := range controllers.Items {
for _, controller := range controllers {
controllerRows = append(controllerRows, component.TableRow{
versionCol: component.NewText(controller.Version),
podCol: component.NewLink(controller.PodRef.Name, controller.PodRef.Name,
Expand All @@ -85,16 +109,36 @@ func (p *antreaOctantPlugin) getControllerTable(request service.Request) *compon
return component.NewTableWithRows(controllerTitle, "We couldn't find any Antrea controllers!", controllerCols, controllerRows)
}

func listAntreaAgentInfos(ctx context.Context, client service.Dashboard, sortedByPodName bool) ([]crdv1beta1.AntreaAgentInfo, error) {
unstructuredList, err := client.List(ctx, store.Key{
APIVersion: "crd.antrea.io/v1beta1",
Kind: "AntreaAgentInfo",
})
if err != nil {
return nil, err
}
agents := make([]crdv1beta1.AntreaAgentInfo, len(unstructuredList.Items))
for idx, unstructuredObj := range unstructuredList.Items {
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredObj.Object, &agents[idx]); err != nil {
return nil, err
}
}
if sortedByPodName {
sort.Slice(agents, func(p, q int) bool {
return agents[p].PodRef.Name < agents[q].PodRef.Name
})
}
return agents, nil
}

// getAgentTable gets the table for displaying Agent information.
func (p *antreaOctantPlugin) getAgentTable(request service.Request) *component.Table {
agents, err := p.client.CrdV1beta1().AntreaAgentInfos().List(context.TODO(), metav1.ListOptions{
ResourceVersion: "0",
})
agents, err := listAntreaAgentInfos(request.Context(), request.DashboardClient(), true)
if err != nil {
log.Fatalf("Failed to get AntreaAgentInfos %v", err)
}
agentRows := make([]component.TableRow, 0)
for _, agent := range agents.Items {
for _, agent := range agents {
agentRows = append(agentRows, component.TableRow{
versionCol: component.NewText(agent.Version),
podCol: component.NewLink(agent.PodRef.Name, agent.PodRef.Name,
Expand Down
37 changes: 12 additions & 25 deletions plugins/octant/cmd/antrea-octant-plugin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,27 @@ package main

import (
"log"
"os"
"path/filepath"
"sync"

"github.com/vmware-tanzu/octant/pkg/navigation"
"github.com/vmware-tanzu/octant/pkg/plugin"
"github.com/vmware-tanzu/octant/pkg/plugin/service"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd"

crdv1alpha1 "antrea.io/antrea/pkg/apis/crd/v1alpha1"
clientset "antrea.io/antrea/pkg/client/clientset/versioned"
)

var (
const (
title = "Antrea"
pluginName = "antrea-octant-plugin"
)

const (
title = "Antrea"
var (
logger = service.NewLoggerHelper()
)

type antreaOctantPlugin struct {
client *clientset.Clientset
// tfMutex protects the Traceflow state in case of multiple client
// tfmutex protects the Traceflow state in case of multiple client
// sessions concurrently accessing the Traceflow functionality of the
// Antrea plugin.
tfMutex sync.Mutex
Expand All @@ -49,23 +45,8 @@ type antreaOctantPlugin struct {
}

func newAntreaOctantPlugin() *antreaOctantPlugin {
kubeconfig := os.Getenv("KUBECONFIG")
if kubeconfig == "" {
kubeconfig = filepath.Join(os.Getenv("HOME"), ".kube", "config")
}
// Create a k8s client.
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
log.Fatalf("Failed to build kubeConfig %v", err)
}
client, err := clientset.NewForConfig(config)
if err != nil {
log.Fatalf("Failed to create K8s client for %s: %v", pluginName, err)
}

return &antreaOctantPlugin{
client: client,
graph: "",
graph: "",
lastTf: &crdv1alpha1.Traceflow{
ObjectMeta: metav1.ObjectMeta{Name: ""},
},
Expand Down Expand Up @@ -94,6 +75,12 @@ func main() {
log.Fatal(err)
}

// TODO: at the moment it seems that plugin logging is buggy, so this is
// the only use of the logger in our plugin so far.
// When it is fixed, we should replace all usage of the Go standard
// library log with this logger for easier debugging.
// See https://github.com/vmware-tanzu/octant/issues/3012
logger.Info("antrea-octant-plugin is starting")
log.Printf("antrea-octant-plugin is starting")
p.Serve()
}
Expand Down
Loading

0 comments on commit d10e035

Please sign in to comment.