feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
257
pkg/simple/client/overview/metrics.go
Normal file
257
pkg/simple/client/overview/metrics.go
Normal file
@@ -0,0 +1,257 @@
|
||||
package overview
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
v12 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
|
||||
corev1alpha1 "kubesphere.io/api/core/v1alpha1"
|
||||
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
||||
tenantv1beta1 "kubesphere.io/api/tenant/v1beta1"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
)
|
||||
|
||||
type Counter interface {
|
||||
RegisterResource(options ...RegisterOption)
|
||||
GetMetrics(metricNames []string, namespace, workspace, prefix string) (*MetricResults, error)
|
||||
}
|
||||
|
||||
var _ Counter = &metricsCounter{}
|
||||
|
||||
type metricsCounter struct {
|
||||
registerTypeMap map[string]reflect.Type
|
||||
client client.Client
|
||||
}
|
||||
|
||||
func New(client client.Client) Counter {
|
||||
collector := &metricsCounter{
|
||||
registerTypeMap: make(map[string]reflect.Type),
|
||||
client: client,
|
||||
}
|
||||
|
||||
return collector
|
||||
}
|
||||
|
||||
func (r *metricsCounter) RegisterResource(options ...RegisterOption) {
|
||||
for _, o := range options {
|
||||
r.register(o)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *metricsCounter) register(option RegisterOption) {
|
||||
r.registerTypeMap[option.MetricsName] = reflect.TypeOf(option.Type)
|
||||
}
|
||||
|
||||
func (r *metricsCounter) GetMetrics(metricNames []string, namespace, workspace, prefix string) (*MetricResults, error) {
|
||||
result := &MetricResults{Results: make([]Metric, 0)}
|
||||
for _, n := range metricNames {
|
||||
metric, err := r.collect(n, prefix, namespace, workspace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.AddMetric(metric)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func CustomMetric(metricName, prefix string, count int) *Metric {
|
||||
return newMetric(metricName, prefix, count)
|
||||
}
|
||||
|
||||
func newMetric(metricName, prefix string, count int) *Metric {
|
||||
if prefix != "" {
|
||||
metricName = fmt.Sprintf("%s_%s", prefix, metricName)
|
||||
}
|
||||
metric := &Metric{
|
||||
MetricName: metricName,
|
||||
Data: MetricData{
|
||||
ResultType: "vector",
|
||||
Result: make([]MetricValue, 0),
|
||||
},
|
||||
}
|
||||
|
||||
value := MetricValue{
|
||||
Value: []interface{}{
|
||||
time.Now().Unix(),
|
||||
count,
|
||||
},
|
||||
}
|
||||
metric.Data.Result = append(metric.Data.Result, value)
|
||||
|
||||
return metric
|
||||
}
|
||||
|
||||
type RegisterOption struct {
|
||||
MetricsName string
|
||||
Type client.ObjectList
|
||||
}
|
||||
|
||||
func (r *metricsCounter) collect(metricName, prefix, namespace, workspace string) (*Metric, error) {
|
||||
t, exist := r.registerTypeMap[metricName]
|
||||
if !exist {
|
||||
return nil, errors.New("can not find metric type")
|
||||
}
|
||||
objVal := reflect.New(t.Elem())
|
||||
objList := objVal.Interface().(client.ObjectList)
|
||||
|
||||
opts := make([]client.ListOption, 0)
|
||||
if workspace != "" {
|
||||
opt := client.MatchingLabels(map[string]string{tenantv1beta1.WorkspaceLabel: workspace})
|
||||
opts = append(opts, opt)
|
||||
}
|
||||
if namespace != "" {
|
||||
opt := client.InNamespace(namespace)
|
||||
opts = append(opts, opt)
|
||||
}
|
||||
|
||||
err := r.client.List(context.Background(), objList, opts...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newMetric(metricName, prefix, meta.LenList(objList)), nil
|
||||
}
|
||||
|
||||
type MetricResults struct {
|
||||
Results []Metric `json:"results"`
|
||||
}
|
||||
|
||||
type Metric struct {
|
||||
MetricName string `json:"metric_name"`
|
||||
Data MetricData `json:"data"`
|
||||
}
|
||||
|
||||
type MetricData struct {
|
||||
ResultType string `json:"resultType"`
|
||||
Result []MetricValue `json:"result"`
|
||||
}
|
||||
|
||||
type MetricValue struct {
|
||||
Value []interface{} `json:"value"`
|
||||
}
|
||||
|
||||
func (r *MetricResults) AddMetric(metric *Metric) {
|
||||
r.Results = append(r.Results, *metric)
|
||||
}
|
||||
|
||||
func NewDefaultRegisterOptions(k8sVersion *semver.Version) []RegisterOption {
|
||||
options := []RegisterOption{
|
||||
{
|
||||
MetricsName: NamespaceCount,
|
||||
Type: &v12.NamespaceList{},
|
||||
},
|
||||
{
|
||||
MetricsName: WorkspaceCount,
|
||||
Type: &tenantv1beta1.WorkspaceTemplateList{},
|
||||
},
|
||||
{
|
||||
MetricsName: ClusterCount,
|
||||
Type: &clusterv1alpha1.ClusterList{},
|
||||
},
|
||||
{
|
||||
MetricsName: PodCount,
|
||||
Type: &v12.PodList{},
|
||||
},
|
||||
{
|
||||
MetricsName: DeploymentCount,
|
||||
Type: &appsv1.DeploymentList{},
|
||||
},
|
||||
{
|
||||
MetricsName: StatefulSetCount,
|
||||
Type: &appsv1.StatefulSetList{},
|
||||
},
|
||||
{
|
||||
MetricsName: DaemonSetCount,
|
||||
Type: &appsv1.DaemonSetList{},
|
||||
},
|
||||
{
|
||||
MetricsName: JobCount,
|
||||
Type: &batchv1.JobList{},
|
||||
},
|
||||
{
|
||||
MetricsName: ServiceCount,
|
||||
Type: &v12.ServiceList{},
|
||||
},
|
||||
{
|
||||
MetricsName: IngressCount,
|
||||
Type: &v1.IngressList{},
|
||||
},
|
||||
{
|
||||
MetricsName: PersistentVolumeCount,
|
||||
Type: &v12.PersistentVolumeList{},
|
||||
},
|
||||
{
|
||||
MetricsName: PersistentVolumeClaimCount,
|
||||
Type: &v12.PersistentVolumeClaimList{},
|
||||
},
|
||||
{
|
||||
MetricsName: GlobalRoleCount,
|
||||
Type: &iamv1beta1.GlobalRoleList{},
|
||||
},
|
||||
{
|
||||
MetricsName: WorkspaceRoleCount,
|
||||
Type: &iamv1beta1.WorkspaceRoleList{},
|
||||
},
|
||||
{
|
||||
MetricsName: RoleCount,
|
||||
Type: &iamv1beta1.RoleList{},
|
||||
},
|
||||
{
|
||||
MetricsName: ClusterRoleCount,
|
||||
Type: &iamv1beta1.ClusterRoleList{},
|
||||
},
|
||||
{
|
||||
MetricsName: UserCount,
|
||||
Type: &iamv1beta1.UserList{},
|
||||
},
|
||||
{
|
||||
MetricsName: GlobalRoleBindingCount,
|
||||
Type: &iamv1beta1.GlobalRoleBindingList{},
|
||||
},
|
||||
{
|
||||
MetricsName: ClusterRoleBindingCount,
|
||||
Type: &iamv1beta1.ClusterRoleBindingList{},
|
||||
},
|
||||
{
|
||||
MetricsName: RoleBindingCount,
|
||||
Type: &iamv1beta1.RoleBindingList{},
|
||||
},
|
||||
{
|
||||
MetricsName: WorkspaceRoleBindingCount,
|
||||
Type: &iamv1beta1.WorkspaceRoleBindingList{},
|
||||
},
|
||||
{
|
||||
MetricsName: ExtensionCount,
|
||||
Type: &corev1alpha1.ExtensionList{},
|
||||
},
|
||||
}
|
||||
|
||||
var cronJobType client.ObjectList
|
||||
if k8sutil.ServeBatchV1beta1(k8sVersion) {
|
||||
cronJobType = &batchv1beta1.CronJobList{}
|
||||
} else {
|
||||
cronJobType = &batchv1.CronJobList{}
|
||||
}
|
||||
options = append(options, RegisterOption{
|
||||
MetricsName: CronJobCount,
|
||||
Type: cronJobType,
|
||||
})
|
||||
|
||||
return options
|
||||
}
|
||||
Reference in New Issue
Block a user