139 lines
4.3 KiB
Go
139 lines
4.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/client-go/dynamic"
|
|
"k8s.io/client-go/kubernetes"
|
|
|
|
authlib "github.com/grafana/authlib/types"
|
|
collectionsV1 "github.com/grafana/grafana/apps/collections/pkg/apis/collections/v1alpha1"
|
|
dashboardsV1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
"github.com/grafana/grafana/pkg/services/apiserver"
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
)
|
|
|
|
//go:generate mockery --name K8sClients --structname MockK8sClients --inpackage --filename client_mock.go --with-expecter
|
|
type K8sClients interface {
|
|
GetDashboardID(c *contextmodel.ReqContext, uid string) (int64, response.Response)
|
|
GetStars(c *contextmodel.ReqContext) ([]string, error)
|
|
AddStar(c *contextmodel.ReqContext, uid string) error
|
|
RemoveStar(c *contextmodel.ReqContext, uid string) error
|
|
}
|
|
|
|
type k8sClients struct {
|
|
namespacer authlib.NamespaceFormatter
|
|
configProvider apiserver.DirectRestConfigProvider
|
|
}
|
|
|
|
var (
|
|
_ K8sClients = (*k8sClients)(nil)
|
|
)
|
|
|
|
// GetDashboardID implements the K8sClients interface.
|
|
func (k *k8sClients) GetDashboardID(c *contextmodel.ReqContext, uid string) (int64, response.Response) {
|
|
dyn, err := dynamic.NewForConfig(k.configProvider.GetDirectRestConfig(c))
|
|
if err != nil {
|
|
return 0, response.Error(http.StatusInternalServerError, "client config", err)
|
|
}
|
|
client := dyn.Resource(dashboardsV1.GroupVersion.WithResource(dashboardsV1.DASHBOARD_RESOURCE)).Namespace(k.namespacer(c.OrgID))
|
|
obj, err := client.Get(c.Req.Context(), uid, v1.GetOptions{})
|
|
if err != nil {
|
|
return 0, response.Error(http.StatusNotFound, "Dashboard not found", err)
|
|
}
|
|
dash, err := utils.MetaAccessor(obj)
|
|
if err != nil {
|
|
return 0, response.Error(http.StatusInternalServerError, "invalid object", err)
|
|
}
|
|
return dash.GetDeprecatedInternalID(), nil // nolint:staticcheck
|
|
}
|
|
|
|
// GetStars implements K8sClients.
|
|
func (k *k8sClients) GetStars(c *contextmodel.ReqContext) ([]string, error) {
|
|
dyn, err := dynamic.NewForConfig(k.configProvider.GetDirectRestConfig(c))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := dyn.Resource(collectionsV1.StarsResourceInfo.GroupVersionResource()).Namespace(k.namespacer(c.OrgID))
|
|
|
|
ctx := c.Req.Context()
|
|
user, err := identity.GetRequester(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
obj, _ := client.Get(ctx, "user-"+user.GetIdentifier(), v1.GetOptions{})
|
|
if obj != nil {
|
|
resources, ok, _ := unstructured.NestedSlice(obj.Object, "spec", "resource")
|
|
if ok && resources != nil {
|
|
for _, r := range resources {
|
|
tmp, ok := r.(map[string]any)
|
|
if ok {
|
|
g, _, _ := unstructured.NestedString(tmp, "group")
|
|
k, _, _ := unstructured.NestedString(tmp, "kind")
|
|
if k == "Dashboard" && g == dashboardsV1.APIGroup {
|
|
names, _, _ := unstructured.NestedStringSlice(tmp, "names")
|
|
return names, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return []string{}, nil
|
|
}
|
|
|
|
// AddStar implements K8sClients.
|
|
func (k *k8sClients) AddStar(c *contextmodel.ReqContext, uid string) error {
|
|
dyn, err := kubernetes.NewForConfig(k.configProvider.GetDirectRestConfig(c))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx := c.Req.Context()
|
|
user, err := identity.GetRequester(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ns := k.namespacer(c.OrgID)
|
|
|
|
client := dyn.RESTClient()
|
|
rsp := client.Put().AbsPath(
|
|
"apis", collectionsV1.APIGroup, collectionsV1.APIVersion, "namespaces", ns,
|
|
"stars", "user-"+user.GetIdentifier(),
|
|
"update", dashboardsV1.APIGroup, dashboardsV1.DashboardKind().Kind(), uid,
|
|
).Do(ctx)
|
|
|
|
return rsp.Error()
|
|
}
|
|
|
|
// RemoveStar implements K8sClients.
|
|
func (k *k8sClients) RemoveStar(c *contextmodel.ReqContext, uid string) error {
|
|
dyn, err := kubernetes.NewForConfig(k.configProvider.GetDirectRestConfig(c))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx := c.Req.Context()
|
|
user, err := identity.GetRequester(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ns := k.namespacer(c.OrgID)
|
|
|
|
client := dyn.RESTClient()
|
|
rsp := client.Delete().AbsPath(
|
|
"apis", collectionsV1.APIGroup, collectionsV1.APIVersion, "namespaces", ns,
|
|
"stars", "user-"+user.GetIdentifier(),
|
|
"update", dashboardsV1.APIGroup, dashboardsV1.DashboardKind().Kind(), uid,
|
|
).Do(ctx)
|
|
|
|
return rsp.Error()
|
|
}
|