logging: integrate new IAM

Signed-off-by: huanggze <loganhuang@yunify.com>
This commit is contained in:
huanggze
2020-05-21 11:16:49 +08:00
parent 48db63b91f
commit 9b6f38d857
36 changed files with 1735 additions and 813 deletions

View File

@@ -19,6 +19,7 @@ package tenant
import (
"fmt"
"io"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -28,9 +29,9 @@ import (
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
eventsv1alpha1 "kubesphere.io/kubesphere/pkg/api/events/v1alpha1"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/api/logging/v1alpha2"
clusterv1alpha1 "kubesphere.io/kubesphere/pkg/apis/cluster/v1alpha1"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizer"
"kubesphere.io/kubesphere/pkg/apiserver/authorization/authorizerfactory"
@@ -39,9 +40,11 @@ import (
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/events"
"kubesphere.io/kubesphere/pkg/models/iam/am"
"kubesphere.io/kubesphere/pkg/models/logging"
resources "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
resourcesv1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events"
loggingclient "kubesphere.io/kubesphere/pkg/simple/client/logging"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
"strings"
"time"
@@ -58,6 +61,8 @@ type Interface interface {
ListWorkspaceClusters(workspace string) (*api.ListResult, error)
Events(user user.Info, queryParam *eventsv1alpha1.Query) (*eventsv1alpha1.APIResponse, error)
QueryLogs(user user.Info, query *loggingv1alpha2.Query) (*loggingv1alpha2.APIResponse, error)
ExportLogs(user user.Info, query *loggingv1alpha2.Query, writer io.Writer) error
}
type tenantOperator struct {
@@ -67,9 +72,10 @@ type tenantOperator struct {
ksclient kubesphere.Interface
resourceGetter *resourcesv1alpha3.ResourceGetter
events events.Interface
lo logging.LoggingOperator
}
func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient eventsclient.Client) Interface {
func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient eventsclient.Client, loggingClient loggingclient.Interface) Interface {
amOperator := am.NewReadOnlyOperator(informers)
authorizer := authorizerfactory.NewRBACAuthorizer(amOperator)
return &tenantOperator{
@@ -79,6 +85,7 @@ func New(informers informers.InformerFactory, k8sclient kubernetes.Interface, ks
k8sclient: k8sclient,
ksclient: ksclient,
events: events.NewEventsOperator(evtsClient),
lo: logging.NewLoggingOperator(loggingClient),
}
}
@@ -407,6 +414,129 @@ func (t *tenantOperator) Events(user user.Info, queryParam *eventsv1alpha1.Query
})
}
func (t *tenantOperator) QueryLogs(user user.Info, query *loggingv1alpha2.Query) (*loggingv1alpha2.APIResponse, error) {
iNamespaces, err := t.listIntersectedNamespaces(user,
stringutils.Split(query.WorkspaceFilter, ","),
stringutils.Split(query.WorkspaceSearch, ","),
stringutils.Split(query.NamespaceFilter, ","),
stringutils.Split(query.NamespaceSearch, ","))
if err != nil {
klog.Error(err)
return nil, err
}
namespaceCreateTimeMap := make(map[string]time.Time)
for _, ns := range iNamespaces {
podLogs := authorizer.AttributesRecord{
User: user,
Verb: "get",
APIGroup: "",
APIVersion: "v1",
Namespace: ns.Name,
Resource: "pods",
Subresource: "log",
ResourceRequest: true,
}
decision, _, err := t.authorizer.Authorize(podLogs)
if err != nil {
klog.Error(err)
return nil, err
}
if decision == authorizer.DecisionAllow {
namespaceCreateTimeMap[ns.Name] = ns.CreationTimestamp.Time
}
}
sf := loggingclient.SearchFilter{
NamespaceFilter: namespaceCreateTimeMap,
WorkloadSearch: stringutils.Split(query.WorkloadSearch, ","),
WorkloadFilter: stringutils.Split(query.WorkloadFilter, ","),
PodSearch: stringutils.Split(query.PodSearch, ","),
PodFilter: stringutils.Split(query.PodFilter, ","),
ContainerSearch: stringutils.Split(query.ContainerSearch, ","),
ContainerFilter: stringutils.Split(query.ContainerFilter, ","),
LogSearch: stringutils.Split(query.LogSearch, ","),
Starttime: query.StartTime,
Endtime: query.EndTime,
}
var ar loggingv1alpha2.APIResponse
switch query.Operation {
case loggingv1alpha2.OperationStatistics:
if len(namespaceCreateTimeMap) == 0 {
ar.Statistics = &loggingclient.Statistics{}
} else {
ar, err = t.lo.GetCurrentStats(sf)
}
case loggingv1alpha2.OperationHistogram:
if len(namespaceCreateTimeMap) == 0 {
ar.Histogram = &loggingclient.Histogram{}
} else {
ar, err = t.lo.CountLogsByInterval(sf, query.Interval)
}
default:
if len(namespaceCreateTimeMap) == 0 {
ar.Logs = &loggingclient.Logs{}
} else {
ar, err = t.lo.SearchLogs(sf, query.From, query.Size, query.Sort)
}
}
return &ar, err
}
func (t *tenantOperator) ExportLogs(user user.Info, query *loggingv1alpha2.Query, writer io.Writer) error {
iNamespaces, err := t.listIntersectedNamespaces(user,
stringutils.Split(query.WorkspaceFilter, ","),
stringutils.Split(query.WorkspaceSearch, ","),
stringutils.Split(query.NamespaceFilter, ","),
stringutils.Split(query.NamespaceSearch, ","))
if err != nil {
klog.Error(err)
return err
}
namespaceCreateTimeMap := make(map[string]time.Time)
for _, ns := range iNamespaces {
podLogs := authorizer.AttributesRecord{
User: user,
Verb: "get",
APIGroup: "",
APIVersion: "v1",
Namespace: ns.Name,
Resource: "pods",
Subresource: "log",
ResourceRequest: true,
}
decision, _, err := t.authorizer.Authorize(podLogs)
if err != nil {
klog.Error(err)
return err
}
if decision == authorizer.DecisionAllow {
namespaceCreateTimeMap[ns.Name] = ns.CreationTimestamp.Time
}
}
sf := loggingclient.SearchFilter{
NamespaceFilter: namespaceCreateTimeMap,
WorkloadSearch: stringutils.Split(query.WorkloadSearch, ","),
WorkloadFilter: stringutils.Split(query.WorkloadFilter, ","),
PodSearch: stringutils.Split(query.PodSearch, ","),
PodFilter: stringutils.Split(query.PodFilter, ","),
ContainerSearch: stringutils.Split(query.ContainerSearch, ","),
ContainerFilter: stringutils.Split(query.ContainerFilter, ","),
LogSearch: stringutils.Split(query.LogSearch, ","),
Starttime: query.StartTime,
Endtime: query.EndTime,
}
if len(namespaceCreateTimeMap) == 0 {
return nil
} else {
return t.lo.ExportLogs(sf, writer)
}
}
func contains(objects []runtime.Object, object runtime.Object) bool {
for _, item := range objects {
if item == object {

View File

@@ -330,5 +330,5 @@ func prepare() Interface {
RoleBindings().Informer().GetIndexer().Add(roleBinding)
}
return New(fakeInformerFactory, nil, nil, nil)
return New(fakeInformerFactory, nil, nil, nil, nil)
}