Skip to content

Commit

Permalink
Impersonate api call to grafana dashboard
Browse files Browse the repository at this point in the history
Signed-off-by: Tamal Saha <[email protected]>
  • Loading branch information
tamalsaha committed Nov 17, 2024
1 parent 8fb934b commit cd7f977
Show file tree
Hide file tree
Showing 53 changed files with 264 additions and 72 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ require (
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0
kmodules.xyz/apiversion v0.2.0
kmodules.xyz/authorizer v0.29.1
kmodules.xyz/client-go v0.30.37
kmodules.xyz/client-go v0.30.38-0.20241117075231-750051a8f0b9
kmodules.xyz/custom-resources v0.30.0
kmodules.xyz/go-containerregistry v0.0.12
kmodules.xyz/monitoring-agent-api v0.30.2
kmodules.xyz/offshoot-api v0.30.1
kmodules.xyz/resource-metadata v0.22.3-0.20241114091625-6c277c3fe863
kmodules.xyz/resource-metadata v0.22.3-0.20241117093124-a5b36fb25424
kmodules.xyz/resource-metrics v0.30.5
kmodules.xyz/resource-metrics/utils v0.30.4
kmodules.xyz/sets v0.29.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,8 @@ kmodules.xyz/apiversion v0.2.0 h1:vAQYqZFm4xu4pbB1cAdHbFEPES6EQkcR4wc06xdTOWk=
kmodules.xyz/apiversion v0.2.0/go.mod h1:oPX8g8LvlPdPX3Yc5YvCzJHQnw3YF/X4/jdW0b1am80=
kmodules.xyz/authorizer v0.29.1 h1:uByGGoryKbZcfiEAhjcK/Y345I9mygNQP7DVpkMbNQQ=
kmodules.xyz/authorizer v0.29.1/go.mod h1:kZRhclL8twzyt2bQuJQJbpYww2sc+qFr8I5PPoq/sWY=
kmodules.xyz/client-go v0.30.37 h1:hj4BMsNDgRVc2aDPB6Y3x5iCylXTZDZeQPJp/oA6lxs=
kmodules.xyz/client-go v0.30.37/go.mod h1:CAu+JlA8RVGtj6LQHu0Q1w2mnFUajuti49c7T1AvGdM=
kmodules.xyz/client-go v0.30.38-0.20241117075231-750051a8f0b9 h1:8qSZylUUBcY1rKlVLgm3mRjw3/mG8QT0tSuCCflmIeU=
kmodules.xyz/client-go v0.30.38-0.20241117075231-750051a8f0b9/go.mod h1:CAu+JlA8RVGtj6LQHu0Q1w2mnFUajuti49c7T1AvGdM=
kmodules.xyz/crd-schema-fuzz v0.29.1 h1:zJTlWYOrT5dsVVHW8HGcnR/vaWfxQfNh11QwTtkYpcs=
kmodules.xyz/crd-schema-fuzz v0.29.1/go.mod h1:n708z9YQqLMP2KNLQVgBcRJw1QpSWLvpNCEi+KJDOYE=
kmodules.xyz/custom-resources v0.30.0 h1:vR3CbseHMLwR4GvtcJJuRuwIV8voKqFqNii27rMcm1o=
Expand All @@ -939,8 +939,8 @@ kmodules.xyz/monitoring-agent-api v0.30.2 h1:sAgz5P5EXZqhlj1NzJ+QltAgeIx5bGSMj+a
kmodules.xyz/monitoring-agent-api v0.30.2/go.mod h1:BoZFPDDRB7J39CcUsSDlzgW8PQCwik4ILPleyUob+Mg=
kmodules.xyz/offshoot-api v0.30.1 h1:TrulAYO+oBsXe9sZZGTmNWIuI8qD2izMpgcTSPvgAmI=
kmodules.xyz/offshoot-api v0.30.1/go.mod h1:T3mpjR6fui0QzOcmQvIuANytW48fe9ytmy/1cgx6D4g=
kmodules.xyz/resource-metadata v0.22.3-0.20241114091625-6c277c3fe863 h1:dfsQYd8Uk8iQ/kcwddhL8GNXTN/i8e6UB3C4t0ArwyM=
kmodules.xyz/resource-metadata v0.22.3-0.20241114091625-6c277c3fe863/go.mod h1:G57v46vQOq5P1HIs9Rl7lJ5Y4dBcjJG5OyxApTdSyNs=
kmodules.xyz/resource-metadata v0.22.3-0.20241117093124-a5b36fb25424 h1:6qDtEIMVVt5xKLXnQIfyU49vxYRattFWPgA65umasc4=
kmodules.xyz/resource-metadata v0.22.3-0.20241117093124-a5b36fb25424/go.mod h1:NqGVv2kpYb6nA4i5jtDVGK5DHUVyw/eE2GtHa+1dWp4=
kmodules.xyz/resource-metrics v0.30.5 h1:ZhpGeR9DCz1HTrKUg/mWhr95wlFzCPRdgVAqwaggy1o=
kmodules.xyz/resource-metrics v0.30.5/go.mod h1:w9+rz7/s/kGP1GWzYSuRdCn+l7EwpesmESSEHkLBnIQ=
kmodules.xyz/resource-metrics/utils v0.30.4 h1:bJS/x0Qr7N1FFdxugFbzZ/Es6HVs4ptsFlhkmgj3jac=
Expand Down
10 changes: 5 additions & 5 deletions pkg/graph/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

func renderDashboard(kc client.Client, oc openvizcs.Interface, srcObj *unstructured.Unstructured) tableconvertor.DashboardRendererFunc {
func renderDashboard(ctx context.Context, kc client.Client, oc openvizcs.Interface, srcObj *unstructured.Unstructured) tableconvertor.DashboardRendererFunc {
return func(name string) (*uiapi.ResourceDashboard, string, error) {
rd, err := resourcedashboards.LoadByName(kc, name)
if err != nil {
Expand All @@ -52,15 +52,15 @@ func renderDashboard(kc client.Client, oc openvizcs.Interface, srcObj *unstructu
if len(rd.Spec.Dashboards) > 1 {
return nil, "", fmt.Errorf("multiple dashboards configured for %s", name)
}
dg, err := RenderDashboard(kc, oc, rd, srcObj, false)
dg, err := RenderDashboard(ctx, kc, oc, rd, srcObj, false)
if err != nil {
return nil, "", err
}
return rd, dg.Response.Dashboards[0].URL, nil
}
}

func RenderDashboard(kc client.Client, oc openvizcs.Interface, rd *uiapi.ResourceDashboard, src *unstructured.Unstructured, embeddedLink bool) (*openvizauipi.DashboardGroup, error) {
func RenderDashboard(ctx context.Context, kc client.Client, oc openvizcs.Interface, rd *uiapi.ResourceDashboard, src *unstructured.Unstructured, embeddedLink bool) (*openvizauipi.DashboardGroup, error) {
if rd.Spec.Provider != uiapi.DashboardProviderGrafana {
return nil, fmt.Errorf("dashboard %s uses unsupported provider %q", rd.Name, rd.Spec.Provider)
}
Expand All @@ -85,7 +85,7 @@ func RenderDashboard(kc client.Client, oc openvizcs.Interface, rd *uiapi.Resourc
result = strings.TrimSpace(result)
cond = strings.EqualFold(result, "true")
} else if d.If.Connected != nil {
_, targets, err := ExecRawQuery(kc, kmapi.NewObjectID(src).OID(), *d.If.Connected)
_, targets, err := ExecRawQuery(ctx, kc, kmapi.NewObjectID(src).OID(), *d.If.Connected)
if err != nil {
return nil, errors.Wrapf(err, "failed to check connection for dashboard with title %s", d.Title)
}
Expand Down Expand Up @@ -124,5 +124,5 @@ func RenderDashboard(kc client.Client, oc openvizcs.Interface, rd *uiapi.Resourc
}
dg.Request.Dashboards = append(dg.Request.Dashboards, out)
}
return oc.UiV1alpha1().DashboardGroups().Create(context.TODO(), dg, metav1.CreateOptions{})
return oc.UiV1alpha1().DashboardGroups().Create(ctx, dg, metav1.CreateOptions{})
}
2 changes: 1 addition & 1 deletion pkg/graph/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func LocatePods(ctx context.Context, kc client.Client, req *kmapi.ObjectInfo) ([
},
}

_, refs, err := ExecRawQuery(kc, src.OID(), target)
_, refs, err := ExecRawQuery(ctx, kc, src.OID(), target)
if err != nil {
return nil, err
}
Expand Down
54 changes: 30 additions & 24 deletions pkg/graph/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
)

func RenderLayout(
ctx context.Context,
kc client.Client,
oc openvizcs.Interface,
src kmapi.ObjectInfo,
Expand All @@ -57,7 +58,7 @@ func RenderLayout(
}
var srcObj unstructured.Unstructured
srcObj.SetGroupVersionKind(srcRID.GroupVersionKind())
err = kc.Get(context.TODO(), src.Ref.ObjectKey(), &srcObj)
err = kc.Get(ctx, src.Ref.ObjectKey(), &srcObj)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -118,14 +119,14 @@ func RenderLayout(
}

if layout.Spec.Header != nil && okToRender(layout.Spec.Header.Kind, renderBlocks) {
if bv, err := renderPageBlock(kc, oc, srcRID, &srcObj, layout.Spec.Header, convertToTable); err != nil {
if bv, err := renderPageBlock(ctx, kc, oc, srcRID, &srcObj, layout.Spec.Header, convertToTable); err != nil {
return nil, err
} else {
out.Header = bv
}
}
if layout.Spec.TabBar != nil && okToRender(layout.Spec.TabBar.Kind, renderBlocks) {
if bv, err := renderPageBlock(kc, oc, srcRID, &srcObj, layout.Spec.TabBar, convertToTable); err != nil {
if bv, err := renderPageBlock(ctx, kc, oc, srcRID, &srcObj, layout.Spec.TabBar, convertToTable); err != nil {
return nil, err
} else {
out.TabBar = bv
Expand All @@ -151,14 +152,14 @@ func RenderLayout(
Blocks: nil,
}
if sectionLayout.Info != nil && okToRender(sectionLayout.Info.Kind, renderBlocks) {
if bv, err := renderPageBlock(kc, oc, srcRID, &srcObj, sectionLayout.Info, convertToTable); err != nil {
if bv, err := renderPageBlock(ctx, kc, oc, srcRID, &srcObj, sectionLayout.Info, convertToTable); err != nil {
return nil, err
} else {
section.Info = bv
}
}
if sectionLayout.Insight != nil && okToRender(sectionLayout.Insight.Kind, renderBlocks) {
if bv, err := renderPageBlock(kc, oc, srcRID, &srcObj, sectionLayout.Insight, convertToTable); err != nil {
if bv, err := renderPageBlock(ctx, kc, oc, srcRID, &srcObj, sectionLayout.Insight, convertToTable); err != nil {
return nil, err
} else {
section.Insight = bv
Expand All @@ -168,7 +169,7 @@ func RenderLayout(
blocks := make([]rsapi.PageBlockView, 0, len(sectionLayout.Blocks))
for _, block := range sectionLayout.Blocks {
if okToRender(block.Kind, renderBlocks) {
if bv, err := renderPageBlock(kc, oc, srcRID, &srcObj, &block, convertToTable); err != nil {
if bv, err := renderPageBlock(ctx, kc, oc, srcRID, &srcObj, &block, convertToTable); err != nil {
return nil, err
} else {
blocks = append(blocks, *bv)
Expand All @@ -190,23 +191,23 @@ func okToRender(kind rsapi.TableKind, renderBlocks sets.Set[string]) bool {
return renderBlocks.Len() == 0 || renderBlocks.Has(string(kind))
}

func RenderPageBlock(kc client.Client, oc openvizcs.Interface, src kmapi.ObjectInfo, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
func RenderPageBlock(ctx context.Context, kc client.Client, oc openvizcs.Interface, src kmapi.ObjectInfo, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
srcRID, err := kmapi.ExtractResourceID(kc.RESTMapper(), src.Resource)
if err != nil {
return nil, errors.Wrap(err, "failed to detect src resource id")
}
var srcObj unstructured.Unstructured
srcObj.SetGroupVersionKind(srcRID.GroupVersionKind())
err = kc.Get(context.TODO(), src.Ref.ObjectKey(), &srcObj)
err = kc.Get(ctx, src.Ref.ObjectKey(), &srcObj)
if err != nil {
return nil, err
}

return renderPageBlock(kc, oc, srcRID, &srcObj, block, convertToTable)
return renderPageBlock(ctx, kc, oc, srcRID, &srcObj, block, convertToTable)
}

func renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.ResourceID, srcObj *unstructured.Unstructured, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
bv, err := _renderPageBlock(kc, oc, srcRID, srcObj, block, convertToTable)
func renderPageBlock(ctx context.Context, kc client.Client, oc openvizcs.Interface, srcRID *kmapi.ResourceID, srcObj *unstructured.Unstructured, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
bv, err := _renderPageBlock(ctx, kc, oc, srcRID, srcObj, block, convertToTable)
if err != nil {
bv.Result = rsapi.RenderResult{
Status: rsapi.RenderError,
Expand All @@ -220,7 +221,12 @@ func renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Res
return bv, nil
}

func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.ResourceID, srcObj *unstructured.Unstructured, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
func _renderPageBlock(ctx context.Context, kc client.Client, oc openvizcs.Interface, srcRID *kmapi.ResourceID, srcObj *unstructured.Unstructured, block *rsapi.PageBlockLayout, convertToTable bool) (*rsapi.PageBlockView, error) {
cc, err := getClient(ctx, kc, block.Impersonate)
if err != nil {
return nil, err
}

out := rsapi.PageBlockView{
Kind: block.Kind,
Name: block.Name,
Expand All @@ -231,11 +237,11 @@ func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Re
if block.Kind == rsapi.TableKindSelf || block.Kind == rsapi.TableKindSubTable {
out.Resource = srcRID
if convertToTable {
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(kc, oc, srcObj), RenderExec(nil, &srcGVR))
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(ctx, cc, oc, srcObj), RenderExec(nil, &srcGVR))
if err != nil {
return &out, err
}
table, err := converter.ConvertToTable(context.TODO(), srcObj)
table, err := converter.ConvertToTable(ctx, srcObj)
if err != nil {
return &out, err
}
Expand All @@ -248,7 +254,7 @@ func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Re
return &out, fmt.Errorf("unsupported table kind found in block %+v", block)
}

mapping, err := kc.RESTMapper().RESTMapping(schema.GroupKind{
mapping, err := cc.RESTMapper().RESTMapping(schema.GroupKind{
Group: block.Ref.Group,
Kind: block.Ref.Kind,
})
Expand Down Expand Up @@ -292,24 +298,24 @@ func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Re
// handle FalcoEvent list call
if vars[sharedapi.GraphQueryVarTargetGroup] == falco.GroupName &&
vars[sharedapi.GraphQueryVarTargetKind] == falcov1alpha1.ResourceKindFalcoEvent {
objs, err = listFalcoEvents(kc, block, srcID)
objs, err = listFalcoEvents(ctx, cc, block, srcID)
if err != nil {
return &out, err
}
} else {
objs, err = ExecGraphQLQuery(kc, q, vars)
objs, err = ExecGraphQLQuery(cc, q, vars)
if err != nil {
return &out, err
}
}

if convertToTable {
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(kc, oc, srcObj), RenderExec(&srcGVR, &mapping.Resource))
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(ctx, cc, oc, srcObj), RenderExec(&srcGVR, &mapping.Resource))
if err != nil {
return &out, err
}
list := &unstructured.UnstructuredList{Items: objs}
table, err := converter.ConvertToTable(context.TODO(), list)
table, err := converter.ConvertToTable(ctx, list)
if err != nil {
return &out, err
}
Expand All @@ -327,17 +333,17 @@ func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Re
}
u := unstructured.Unstructured{Object: obj}
u.SetGroupVersionKind(mapping.GroupVersionKind)
err = kc.Create(context.TODO(), &u)
err = cc.Create(ctx, &u)
if err != nil {
return &out, err
}

if convertToTable {
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(kc, oc, srcObj), RenderExec(&srcGVR, &mapping.Resource))
converter, err := tableconvertor.New(block.FieldPath, block.View.Columns, renderDashboard(ctx, cc, oc, srcObj), RenderExec(&srcGVR, &mapping.Resource))
if err != nil {
return &out, err
}
table, err := converter.ConvertToTable(context.TODO(), &u)
table, err := converter.ConvertToTable(ctx, &u)
if err != nil {
return &out, err
}
Expand All @@ -349,7 +355,7 @@ func _renderPageBlock(kc client.Client, oc openvizcs.Interface, srcRID *kmapi.Re
return &out, nil
}

func listFalcoEvents(kc client.Client, block *rsapi.PageBlockLayout, srcID *kmapi.ObjectID) ([]unstructured.Unstructured, error) {
func listFalcoEvents(ctx context.Context, kc client.Client, block *rsapi.PageBlockLayout, srcID *kmapi.ObjectID) ([]unstructured.Unstructured, error) {
var refs []kmapi.ObjectReference
var err error
if srcID.Kind == "Pod" {
Expand All @@ -376,7 +382,7 @@ func listFalcoEvents(kc client.Client, block *rsapi.PageBlockLayout, srcID *kmap

var list unstructured.UnstructuredList
list.SetGroupVersionKind(falcov1alpha1.SchemeGroupVersion.WithKind(falcov1alpha1.ResourceKindFalcoEvent))
err = kc.List(context.TODO(), &list, &client.ListOptions{LabelSelector: selector})
err = kc.List(ctx, &list, &client.ListOptions{LabelSelector: selector})
if meta.IsNoMatchError(err) {
return nil, err
} else if err == nil {
Expand Down
43 changes: 34 additions & 9 deletions pkg/graph/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
restclient "k8s.io/client-go/rest"
"k8s.io/klog/v2"
kmapi "kmodules.xyz/client-go/api/v1"
cu "kmodules.xyz/client-go/client"
meta_util "kmodules.xyz/client-go/meta"
sharedapi "kmodules.xyz/resource-metadata/apis/shared"
ksets "kmodules.xyz/sets"
Expand Down Expand Up @@ -247,8 +249,13 @@ func extractRefs(data map[string]interface{}, result ksets.ObjectReference) erro
return nil
}

func ExecRawQuery(kc client.Client, src kmapi.OID, target sharedapi.ResourceLocator) (*kmapi.ResourceID, []kmapi.ObjectReference, error) {
mapping, err := kc.RESTMapper().RESTMapping(schema.GroupKind{
func ExecRawQuery(ctx context.Context, kc client.Client, src kmapi.OID, target sharedapi.ResourceLocator) (*kmapi.ResourceID, []kmapi.ObjectReference, error) {
cc, err := getClient(ctx, kc, target.Impersonate)
if err != nil {
return nil, nil, err
}

mapping, err := cc.RESTMapper().RESTMapping(schema.GroupKind{
Group: target.Ref.Group,
Kind: target.Ref.Kind,
})
Expand All @@ -267,7 +274,7 @@ func ExecRawQuery(kc client.Client, src kmapi.OID, target sharedapi.ResourceLoca
return rid, result, err
}

obj, err := execRestQuery(kc, q, mapping.GroupVersionKind)
obj, err := execRestQuery(ctx, cc, q, mapping.GroupVersionKind)
if err != nil {
return nil, nil, err
}
Expand All @@ -278,8 +285,13 @@ func ExecRawQuery(kc client.Client, src kmapi.OID, target sharedapi.ResourceLoca
return rid, []kmapi.ObjectReference{ref}, nil
}

func ExecQuery(kc client.Client, src kmapi.OID, target sharedapi.ResourceLocator) (*kmapi.ResourceID, []unstructured.Unstructured, error) {
mapping, err := kc.RESTMapper().RESTMapping(schema.GroupKind{
func ExecQuery(ctx context.Context, kc client.Client, src kmapi.OID, target sharedapi.ResourceLocator) (*kmapi.ResourceID, []unstructured.Unstructured, error) {
cc, err := getClient(ctx, kc, target.Impersonate)
if err != nil {
return nil, nil, err
}

mapping, err := cc.RESTMapper().RESTMapping(schema.GroupKind{
Group: target.Ref.Group,
Kind: target.Ref.Kind,
})
Expand All @@ -294,28 +306,41 @@ func ExecQuery(kc client.Client, src kmapi.OID, target sharedapi.ResourceLocator
}

if target.Query.Type == sharedapi.GraphQLQuery {
result, err := ExecGraphQLQuery(kc, q, vars)
result, err := ExecGraphQLQuery(cc, q, vars)
return rid, result, err
}

obj, err := execRestQuery(kc, q, mapping.GroupVersionKind)
obj, err := execRestQuery(ctx, cc, q, mapping.GroupVersionKind)
if err != nil {
return rid, nil, err
}
return rid, []unstructured.Unstructured{*obj}, nil
}

func execRestQuery(kc client.Client, q string, gvk schema.GroupVersionKind) (*unstructured.Unstructured, error) {
func execRestQuery(ctx context.Context, kc client.Client, q string, gvk schema.GroupVersionKind) (*unstructured.Unstructured, error) {
var out unstructured.Unstructured
err := yaml.Unmarshal([]byte(q), &out)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal query %s", q)
}

out.SetGroupVersionKind(gvk)
err = kc.Create(context.TODO(), &out)
err = kc.Create(ctx, &out)
if err != nil {
return nil, err
}
return &out, nil
}

func getClient(ctx context.Context, kc client.Client, impersonate bool) (client.Client, error) {
u, found := request.UserFrom(ctx)

if !impersonate || !found {
return kc, nil
}

if rw, ok := kc.(*cu.DelegatingClient); ok {
return rw.Impersonate(u)
}
return nil, fmt.Errorf("can't impersonate client")
}
Loading

0 comments on commit cd7f977

Please sign in to comment.