Remove metering ConfigMap dependency.

Signed-off-by: Rao Yunkun <yunkunrao@yunify.com>
This commit is contained in:
Rao Yunkun
2021-04-19 17:06:34 +08:00
parent 37c53db57f
commit 5904e2e9be
17 changed files with 112 additions and 154 deletions

View File

@@ -220,14 +220,14 @@ func (s *APIServer) installKubeSphereAPIs() {
urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config)) urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config))
urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory, s.RuntimeCache)) urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory, s.RuntimeCache))
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.KubernetesClient.KubeSphere())) urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.KubernetesClient.KubeSphere()))
urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.RuntimeCache)) urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.RuntimeCache, s.Config.MeteringOptions))
urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions)) urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
urlruntime.Must(openpitrixv2alpha1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions)) urlruntime.Must(openpitrixv2alpha1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes())) urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory, urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory,
s.KubernetesClient.Master())) s.KubernetesClient.Master()))
urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(), urlruntime.Must(tenantv1alpha2.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.Kubernetes(),
s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache)) s.KubernetesClient.KubeSphere(), s.EventsClient, s.LoggingClient, s.AuditingClient, amOperator, rbacAuthorizer, s.MonitoringClient, s.RuntimeCache, s.Config.MeteringOptions))
urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.KubernetesClient.Config())) urlruntime.Must(terminalv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.KubernetesClient.Config()))
urlruntime.Must(clusterkapisv1alpha1.AddToContainer(s.container, urlruntime.Must(clusterkapisv1alpha1.AddToContainer(s.container,
s.InformerFactory.KubernetesSharedInformerFactory(), s.InformerFactory.KubernetesSharedInformerFactory(),

View File

@@ -290,8 +290,4 @@ func (conf *Config) stripEmptyOptions() {
if conf.KubeEdgeOptions != nil && conf.KubeEdgeOptions.Endpoint == "" { if conf.KubeEdgeOptions != nil && conf.KubeEdgeOptions.Endpoint == "" {
conf.KubeEdgeOptions = nil conf.KubeEdgeOptions = nil
} }
if conf.MeteringOptions != nil && !conf.MeteringOptions.Enable {
conf.MeteringOptions = nil
}
} }

View File

@@ -26,6 +26,7 @@ import (
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
monitorhle "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" monitorhle "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -42,6 +43,6 @@ type meterHandler interface {
HandlePVCMeterQuery(req *restful.Request, resp *restful.Response) HandlePVCMeterQuery(req *restful.Request, resp *restful.Response)
} }
func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter) meterHandler { func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options) meterHandler {
return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter) return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter, meteringOptions)
} }

View File

@@ -34,6 +34,7 @@ import (
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
model "kubesphere.io/kubesphere/pkg/models/monitoring" model "kubesphere.io/kubesphere/pkg/models/monitoring"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -44,10 +45,10 @@ const (
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha1"} var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha1"}
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, cache cache.Cache) error { func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, cache cache.Cache, meteringOptions *meteringclient.Options) error {
ws := runtime.NewWebService(GroupVersion) ws := runtime.NewWebService(GroupVersion)
h := newHandler(k8sClient, meteringClient, factory, ksClient, resourcev1alpha3.NewResourceGetter(factory, cache)) h := newHandler(k8sClient, meteringClient, factory, ksClient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions)
ws.Route(ws.GET("/cluster"). ws.Route(ws.GET("/cluster").
To(h.HandleClusterMeterQuery). To(h.HandleClusterMeterQuery).

View File

@@ -33,25 +33,31 @@ import (
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
model "kubesphere.io/kubesphere/pkg/models/monitoring" model "kubesphere.io/kubesphere/pkg/models/monitoring"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
type handler struct { type handler struct {
k kubernetes.Interface k kubernetes.Interface
mo model.MonitoringOperator mo model.MonitoringOperator
opRelease openpitrix.ReleaseInterface opRelease openpitrix.ReleaseInterface
meteringOptions *meteringclient.Options
} }
func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter) *handler { func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options) *handler {
var opRelease openpitrix.Interface var opRelease openpitrix.Interface
if ksClient != nil { if ksClient != nil {
opRelease = openpitrix.NewOpenpitrixOperator(f, ksClient, nil) opRelease = openpitrix.NewOpenpitrixOperator(f, ksClient, nil)
} }
if meteringOptions == nil {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &handler{ return &handler{
k: k, k: k,
mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter), mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter),
opRelease: opRelease, opRelease: opRelease,
meteringOptions: meteringOptions,
} }
} }

View File

@@ -62,9 +62,9 @@ func (h handler) handleApplicationMetersQuery(meters []string, resp *restful.Res
} }
if q.isRangeQuery() { if q.isRangeQuery() {
current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt) current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt, h.meteringOptions.Billing.PriceInfo)
} else { } else {
current_res, err = h.mo.GetNamedMeters(meters, q.time, opt) current_res, err = h.mo.GetNamedMeters(meters, q.time, opt, h.meteringOptions.Billing.PriceInfo)
} }
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
@@ -119,9 +119,9 @@ func (h handler) handleServiceMetersQuery(meters []string, resp *restful.Respons
} }
if q.isRangeQuery() { if q.isRangeQuery() {
current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt) current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt, h.meteringOptions.Billing.PriceInfo)
} else { } else {
current_res, err = h.mo.GetNamedMeters(meters, q.time, opt) current_res, err = h.mo.GetNamedMeters(meters, q.time, opt, h.meteringOptions.Billing.PriceInfo)
} }
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
@@ -197,13 +197,13 @@ func (h handler) handleNamedMetersQuery(resp *restful.Response, q queryOptions)
} }
if q.isRangeQuery() { if q.isRangeQuery() {
res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, q.option) res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, q.option, h.meteringOptions.Billing.PriceInfo)
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
return return
} }
} else { } else {
res, err = h.mo.GetNamedMeters(meters, q.time, q.option) res, err = h.mo.GetNamedMeters(meters, q.time, q.option, h.meteringOptions.Billing.PriceInfo)
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
return return
@@ -434,9 +434,9 @@ func (h handler) handleOpenpitrixMetersQuery(meters []string, resp *restful.Resp
} }
if q.isRangeQuery() { if q.isRangeQuery() {
current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt) current_res, err = h.mo.GetNamedMetersOverTime(meters, q.start, q.end, q.step, opt, h.meteringOptions.Billing.PriceInfo)
} else { } else {
current_res, err = h.mo.GetNamedMeters(meters, q.time, opt) current_res, err = h.mo.GetNamedMeters(meters, q.time, opt, h.meteringOptions.Billing.PriceInfo)
} }
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)

View File

@@ -44,7 +44,7 @@ var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha3"}
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface) error { func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface) error {
ws := runtime.NewWebService(GroupVersion) ws := runtime.NewWebService(GroupVersion)
h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, ksClient, nil) h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, ksClient, nil, nil)
ws.Route(ws.GET("/kubesphere"). ws.Route(ws.GET("/kubesphere").
To(h.handleKubeSphereMetricsQuery). To(h.handleKubeSphereMetricsQuery).

View File

@@ -46,20 +46,28 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/auditing" "kubesphere.io/kubesphere/pkg/simple/client/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/events" "kubesphere.io/kubesphere/pkg/simple/client/events"
"kubesphere.io/kubesphere/pkg/simple/client/logging" "kubesphere.io/kubesphere/pkg/simple/client/logging"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
type tenantHandler struct { type tenantHandler struct {
tenant tenant.Interface tenant tenant.Interface
meteringOptions *meteringclient.Options
} }
func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface,
evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client, evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client,
am am.AccessManagementInterface, authorizer authorizer.Authorizer, am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter) *tenantHandler { monitoringclient monitoringclient.Interface, resourceGetter *resourcev1alpha3.ResourceGetter,
meteringOptions *meteringclient.Options) *tenantHandler {
if meteringOptions == nil {
meteringOptions = &meteringclient.DefaultMeteringOption
}
return &tenantHandler{ return &tenantHandler{
tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourceGetter), tenant: tenant.New(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourceGetter),
meteringOptions: meteringOptions,
} }
} }

View File

@@ -14,7 +14,6 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/request" "kubesphere.io/kubesphere/pkg/apiserver/request"
monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
"kubesphere.io/kubesphere/pkg/models/metering" "kubesphere.io/kubesphere/pkg/models/metering"
"kubesphere.io/kubesphere/pkg/models/monitoring"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -30,7 +29,7 @@ func (h *tenantHandler) QueryMetering(req *restful.Request, resp *restful.Respon
q := meteringv1alpha1.ParseQueryParameter(req) q := meteringv1alpha1.ParseQueryParameter(req)
res, err := h.tenant.Metering(u, q) res, err := h.tenant.Metering(u, q, h.meteringOptions.Billing.PriceInfo)
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
return return
@@ -71,7 +70,7 @@ func (h *tenantHandler) QueryMeteringHierarchy(req *restful.Request, resp *restf
q := meteringv1alpha1.ParseQueryParameter(req) q := meteringv1alpha1.ParseQueryParameter(req)
q.Level = monitoringclient.LevelPod q.Level = monitoringclient.LevelPod
resourceStats, err := h.tenant.MeteringHierarchy(u, q) resourceStats, err := h.tenant.MeteringHierarchy(u, q, h.meteringOptions.Billing.PriceInfo)
if err != nil { if err != nil {
api.HandleBadRequest(resp, nil, err) api.HandleBadRequest(resp, nil, err)
return return
@@ -83,17 +82,9 @@ func (h *tenantHandler) QueryMeteringHierarchy(req *restful.Request, resp *restf
func (h *tenantHandler) HandlePriceInfoQuery(req *restful.Request, resp *restful.Response) { func (h *tenantHandler) HandlePriceInfoQuery(req *restful.Request, resp *restful.Response) {
var priceResponse metering.PriceResponse var priceResponse metering.PriceResponse
priceResponse.Init()
meterConfig, err := monitoring.LoadYaml() priceInfo := h.meteringOptions.Billing.PriceInfo
if err != nil { priceResponse.RetentionDay = h.meteringOptions.RetentionDay
klog.Warning(err)
resp.WriteAsJson(priceResponse)
return
}
priceInfo := meterConfig.GetPriceInfo()
priceResponse.RetentionDay = meterConfig.RetentionDay
priceResponse.Currency = priceInfo.CurrencyUnit priceResponse.Currency = priceInfo.CurrencyUnit
priceResponse.CpuPerCorePerHour = priceInfo.CpuPerCorePerHour priceResponse.CpuPerCorePerHour = priceInfo.CpuPerCorePerHour
priceResponse.MemPerGigabytesPerHour = priceInfo.MemPerGigabytesPerHour priceResponse.MemPerGigabytesPerHour = priceInfo.MemPerGigabytesPerHour

View File

@@ -48,6 +48,7 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/auditing" "kubesphere.io/kubesphere/pkg/simple/client/auditing"
"kubesphere.io/kubesphere/pkg/simple/client/events" "kubesphere.io/kubesphere/pkg/simple/client/events"
"kubesphere.io/kubesphere/pkg/simple/client/logging" "kubesphere.io/kubesphere/pkg/simple/client/logging"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -64,11 +65,11 @@ func Resource(resource string) schema.GroupResource {
func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface, func AddToContainer(c *restful.Container, factory informers.InformerFactory, k8sclient kubernetes.Interface,
ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client, ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client,
auditingclient auditing.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer, auditingclient auditing.Client, am am.AccessManagementInterface, authorizer authorizer.Authorizer,
monitoringclient monitoringclient.Interface, cache cache.Cache) error { monitoringclient monitoringclient.Interface, cache cache.Cache, meteringOptions *meteringclient.Options) error {
mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson} mimePatch := []string{restful.MIME_JSON, runtime.MimeMergePatchJson, runtime.MimeJsonPatchJson}
ws := runtime.NewWebService(GroupVersion) ws := runtime.NewWebService(GroupVersion)
handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache)) handler := newTenantHandler(factory, k8sclient, ksclient, evtsClient, loggingClient, auditingclient, am, authorizer, monitoringclient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions)
ws.Route(ws.GET("/clusters"). ws.Route(ws.GET("/clusters").
To(handler.ListClusters). To(handler.ListClusters).

View File

@@ -14,16 +14,6 @@ type PriceResponse struct {
PriceInfo `json:",inline"` PriceInfo `json:",inline"`
} }
// currently init method fill illegal value to hint that metering config file was not mounted yet
func (p *PriceInfo) Init() {
p.Currency = ""
p.CpuPerCorePerHour = -1
p.MemPerGigabytesPerHour = -1
p.IngressNetworkTrafficPerMegabytesPerHour = -1
p.EgressNetworkTrafficPerMegabytesPerHour = -1
p.PvcPerGigabytesPerHour = -1
}
type PodStatistic struct { type PodStatistic struct {
CPUUsage float64 `json:"cpu_usage" description:"cpu_usage"` CPUUsage float64 `json:"cpu_usage" description:"cpu_usage"`
MemoryUsageWoCache float64 `json:"memory_usage_wo_cache" description:"memory_usage_wo_cache"` MemoryUsageWoCache float64 `json:"memory_usage_wo_cache" description:"memory_usage_wo_cache"`

View File

@@ -41,6 +41,7 @@ import (
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params" "kubesphere.io/kubesphere/pkg/server/params"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -57,8 +58,8 @@ type MonitoringOperator interface {
GetWorkspaceStats(workspace string) Metrics GetWorkspaceStats(workspace string) Metrics
// meter // meter
GetNamedMetersOverTime(metrics []string, start, end time.Time, step time.Duration, opt monitoring.QueryOption) (Metrics, error) GetNamedMetersOverTime(metrics []string, start, end time.Time, step time.Duration, opt monitoring.QueryOption, priceInfo meteringclient.PriceInfo) (Metrics, error)
GetNamedMeters(metrics []string, time time.Time, opt monitoring.QueryOption) (Metrics, error) GetNamedMeters(metrics []string, time time.Time, opt monitoring.QueryOption, priceInfo meteringclient.PriceInfo) (Metrics, error)
GetAppWorkloads(ns string, apps []string) map[string][]string GetAppWorkloads(ns string, apps []string) map[string][]string
GetSerivePodsMap(ns string, services []string) map[string][]string GetSerivePodsMap(ns string, services []string) map[string][]string
} }
@@ -421,7 +422,7 @@ func generateScalingFactorMap(step time.Duration) map[string]float64 {
return scalingMap return scalingMap
} }
func (mo monitoringOperator) GetNamedMetersOverTime(meters []string, start, end time.Time, step time.Duration, opt monitoring.QueryOption) (metrics Metrics, err error) { func (mo monitoringOperator) GetNamedMetersOverTime(meters []string, start, end time.Time, step time.Duration, opt monitoring.QueryOption, priceInfo meteringclient.PriceInfo) (metrics Metrics, err error) {
if step.Hours() < 1 { if step.Hours() < 1 {
klog.Warning("step should be longer than one hour") klog.Warning("step should be longer than one hour")
@@ -458,13 +459,13 @@ func (mo monitoringOperator) GetNamedMetersOverTime(meters []string, start, end
sMap := generateScalingFactorMap(step) sMap := generateScalingFactorMap(step)
for i, _ := range ress { for i, _ := range ress {
ress[i].MetricData = updateMetricStatData(ress[i], sMap) ress[i].MetricData = updateMetricStatData(ress[i], sMap, priceInfo)
} }
return Metrics{Results: ress}, nil return Metrics{Results: ress}, nil
} }
func (mo monitoringOperator) GetNamedMeters(meters []string, time time.Time, opt monitoring.QueryOption) (Metrics, error) { func (mo monitoringOperator) GetNamedMeters(meters []string, time time.Time, opt monitoring.QueryOption, priceInfo meteringclient.PriceInfo) (Metrics, error) {
metersPerHour := mo.getNamedMetersWithHourInterval(meters, time, opt) metersPerHour := mo.getNamedMetersWithHourInterval(meters, time, opt)
@@ -472,7 +473,7 @@ func (mo monitoringOperator) GetNamedMeters(meters []string, time time.Time, opt
res := metersPerHour.Results[metricIndex] res := metersPerHour.Results[metricIndex]
metersPerHour.Results[metricIndex].MetricData = updateMetricStatData(res, nil) metersPerHour.Results[metricIndex].MetricData = updateMetricStatData(res, nil, priceInfo)
} }
return metersPerHour, nil return metersPerHour, nil

View File

@@ -3,12 +3,10 @@ package monitoring
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"os"
"path/filepath"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/klog" "k8s.io/klog"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -76,56 +74,6 @@ var MeterResourceMap = map[string]int{
"meter_pod_pvc_bytes_total": METER_RESOURCE_TYPE_PVC, "meter_pod_pvc_bytes_total": METER_RESOURCE_TYPE_PVC,
} }
type PriceInfo struct {
CpuPerCorePerHour float64 `json:"cpuPerCorePerHour" yaml:"cpuPerCorePerHour"`
MemPerGigabytesPerHour float64 `json:"memPerGigabytesPerHour" yaml:"memPerGigabytesPerHour"`
IngressNetworkTrafficPerMegabytesPerHour float64 `json:"ingressNetworkTrafficPerMegabytesPerHour" yaml:"ingressNetworkTrafficPerGiagabytesPerHour"`
EgressNetworkTrafficPerMegabytesPerHour float64 `json:"egressNetworkTrafficPerMegabytesPerHour" yaml:"egressNetworkTrafficPerGigabytesPerHour"`
PvcPerGigabytesPerHour float64 `json:"pvcPerGigabytesPerHour" yaml:"pvcPerGigabytesPerHour"`
CurrencyUnit string `json:"currencyUnit" yaml:"currencyUnit"`
}
type Billing struct {
PriceInfo PriceInfo `json:"priceInfo" yaml:"priceInfo"`
}
type MeterConfig struct {
RetentionDay string `json:"retentionDay" yaml:"retentionDay"`
Billing Billing `json:"billing" yaml:"billing"`
}
func (mc MeterConfig) GetPriceInfo() PriceInfo {
return mc.Billing.PriceInfo
}
func LoadYaml() (*MeterConfig, error) {
var meterConfig MeterConfig
var mf *os.File
var err error
if _, err := os.Stat(meteringConfigName); os.IsNotExist(err) {
mf, err = os.Open(filepath.Join(meteringConfigDir, meteringConfigName))
if err != nil {
klog.Error(err)
return nil, err
}
} else {
mf, err = os.Open(meteringConfigName)
if err != nil {
klog.Error(err)
return nil, err
}
}
if err = yaml.NewYAMLOrJSONDecoder(mf, 1024).Decode(&meterConfig); err != nil {
klog.Error(err)
return nil, err
}
return &meterConfig, nil
}
func getMaxPointValue(points []monitoring.Point) string { func getMaxPointValue(points []monitoring.Point) string {
var max *big.Float var max *big.Float
for i, p := range points { for i, p := range points {
@@ -181,16 +129,6 @@ func getAvgPointValue(points []monitoring.Point) string {
return fmt.Sprintf(generateFloatFormat(meteringDefaultPrecision), sum.Quo(sum, length)) return fmt.Sprintf(generateFloatFormat(meteringDefaultPrecision), sum.Quo(sum, length))
} }
func getCurrencyUnit() string {
meterConfig, err := LoadYaml()
if err != nil {
klog.Error(err)
return ""
}
return meterConfig.GetPriceInfo().CurrencyUnit
}
func generateFloatFormat(precision int) string { func generateFloatFormat(precision int) string {
return "%." + fmt.Sprintf("%d", precision) + "f" return "%." + fmt.Sprintf("%d", precision) + "f"
} }
@@ -204,7 +142,7 @@ func getResourceUnit(meterName string) string {
} }
} }
func getFeeWithMeterName(meterName string, sum string) string { func getFeeWithMeterName(meterName string, sum string, priceInfo meteringclient.PriceInfo) string {
s, ok := new(big.Float).SetString(sum) s, ok := new(big.Float).SetString(sum)
if !ok { if !ok {
@@ -212,13 +150,6 @@ func getFeeWithMeterName(meterName string, sum string) string {
return "" return ""
} }
meterConfig, err := LoadYaml()
if err != nil {
klog.Error(err)
return ""
}
priceInfo := meterConfig.GetPriceInfo()
if resourceType, ok := MeterResourceMap[meterName]; !ok { if resourceType, ok := MeterResourceMap[meterName]; !ok {
klog.Errorf("invlaid meter %v", meterName) klog.Errorf("invlaid meter %v", meterName)
return "" return ""
@@ -267,7 +198,7 @@ func getFeeWithMeterName(meterName string, sum string) string {
} }
} }
func updateMetricStatData(metric monitoring.Metric, scalingMap map[string]float64) monitoring.MetricData { func updateMetricStatData(metric monitoring.Metric, scalingMap map[string]float64, priceInfo meteringclient.PriceInfo) monitoring.MetricData {
metricName := metric.MetricName metricName := metric.MetricName
metricData := metric.MetricData metricData := metric.MetricData
for index, metricValue := range metricData.MetricValues { for index, metricValue := range metricData.MetricValues {
@@ -293,14 +224,14 @@ func updateMetricStatData(metric monitoring.Metric, scalingMap map[string]float6
if metricData.MetricType == monitoring.MetricTypeMatrix { if metricData.MetricType == monitoring.MetricTypeMatrix {
sum := getSumPointValue(metricData.MetricValues[index].Series) sum := getSumPointValue(metricData.MetricValues[index].Series)
metricData.MetricValues[index].SumValue = sum metricData.MetricValues[index].SumValue = sum
metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum) metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum, priceInfo)
} else { } else {
sum := getSumPointValue([]monitoring.Point{*metricValue.Sample}) sum := getSumPointValue([]monitoring.Point{*metricValue.Sample})
metricData.MetricValues[index].SumValue = sum metricData.MetricValues[index].SumValue = sum
metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum) metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum, priceInfo)
} }
metricData.MetricValues[index].CurrencyUnit = getCurrencyUnit() metricData.MetricValues[index].CurrencyUnit = priceInfo.CurrencyUnit
metricData.MetricValues[index].ResourceUnit = getResourceUnit(metricName) metricData.MetricValues[index].ResourceUnit = getResourceUnit(metricName)
} }

View File

@@ -28,6 +28,7 @@ import (
monitoringmodel "kubesphere.io/kubesphere/pkg/models/monitoring" monitoringmodel "kubesphere.io/kubesphere/pkg/models/monitoring"
"kubesphere.io/kubesphere/pkg/models/openpitrix" "kubesphere.io/kubesphere/pkg/models/openpitrix"
"kubesphere.io/kubesphere/pkg/server/params" "kubesphere.io/kubesphere/pkg/server/params"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
) )
@@ -538,7 +539,7 @@ func (t *tenantOperator) makeQueryOptions(user user.Info, q meteringv1alpha1.Que
return qo, nil return qo, nil
} }
func (t *tenantOperator) ProcessNamedMetersQuery(q QueryOptions) (metrics monitoringmodel.Metrics, err error) { func (t *tenantOperator) ProcessNamedMetersQuery(q QueryOptions, priceInfo meteringclient.PriceInfo) (metrics monitoringmodel.Metrics, err error) {
var meters []string var meters []string
for _, meter := range q.NamedMetrics { for _, meter := range q.NamedMetrics {
if !strings.HasPrefix(meter, monitoringmodel.MetricMeterPrefix) { if !strings.HasPrefix(meter, monitoringmodel.MetricMeterPrefix) {
@@ -559,20 +560,20 @@ func (t *tenantOperator) ProcessNamedMetersQuery(q QueryOptions) (metrics monito
_, ok := q.Option.(monitoring.ApplicationsOption) _, ok := q.Option.(monitoring.ApplicationsOption)
if ok { if ok {
metrics, err = t.processApplicationMetersQuery(meters, q) metrics, err = t.processApplicationMetersQuery(meters, q, priceInfo)
return return
} }
_, ok = q.Option.(monitoring.ServicesOption) _, ok = q.Option.(monitoring.ServicesOption)
if ok { if ok {
metrics, err = t.processServiceMetersQuery(meters, q) metrics, err = t.processServiceMetersQuery(meters, q, priceInfo)
return return
} }
if q.isRangeQuery() { if q.isRangeQuery() {
metrics, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, q.Option) metrics, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, q.Option, priceInfo)
} else { } else {
metrics, err = t.mo.GetNamedMeters(meters, q.Time, q.Option) metrics, err = t.mo.GetNamedMeters(meters, q.Time, q.Option, priceInfo)
if q.shouldSort() { if q.shouldSort() {
metrics = *metrics.Sort(q.Target, q.Order, q.Identifier).Page(q.Page, q.Limit) metrics = *metrics.Sort(q.Target, q.Order, q.Identifier).Page(q.Page, q.Limit)
} }
@@ -591,7 +592,7 @@ func getMetricPosMap(metrics []monitoring.Metric) map[string]int {
return metricMap return metricMap
} }
func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryOptions) (res monitoringmodel.Metrics, err error) { func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryOptions, priceInfo meteringclient.PriceInfo) (res monitoringmodel.Metrics, err error) {
var metricMap = make(map[string]int) var metricMap = make(map[string]int)
var current_res monitoringmodel.Metrics var current_res monitoringmodel.Metrics
@@ -612,9 +613,9 @@ func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryO
} }
if q.isRangeQuery() { if q.isRangeQuery() {
current_res, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, opt) current_res, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, opt, priceInfo)
} else { } else {
current_res, err = t.mo.GetNamedMeters(meters, q.Time, opt) current_res, err = t.mo.GetNamedMeters(meters, q.Time, opt, priceInfo)
} }
if res.Results == nil { if res.Results == nil {
@@ -639,7 +640,7 @@ func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryO
return return
} }
func (t *tenantOperator) processServiceMetersQuery(meters []string, q QueryOptions) (res monitoringmodel.Metrics, err error) { func (t *tenantOperator) processServiceMetersQuery(meters []string, q QueryOptions, priceInfo meteringclient.PriceInfo) (res monitoringmodel.Metrics, err error) {
var metricMap = make(map[string]int) var metricMap = make(map[string]int)
var current_res monitoringmodel.Metrics var current_res monitoringmodel.Metrics
@@ -659,9 +660,9 @@ func (t *tenantOperator) processServiceMetersQuery(meters []string, q QueryOptio
} }
if q.isRangeQuery() { if q.isRangeQuery() {
current_res, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, opt) current_res, err = t.mo.GetNamedMetersOverTime(meters, q.Start, q.End, q.Step, opt, priceInfo)
} else { } else {
current_res, err = t.mo.GetNamedMeters(meters, q.Time, opt) current_res, err = t.mo.GetNamedMeters(meters, q.Time, opt, priceInfo)
} }
if res.Results == nil { if res.Results == nil {

View File

@@ -63,6 +63,7 @@ import (
auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing" auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing"
eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events" eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events"
loggingclient "kubesphere.io/kubesphere/pkg/simple/client/logging" loggingclient "kubesphere.io/kubesphere/pkg/simple/client/logging"
meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering"
monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring"
"kubesphere.io/kubesphere/pkg/utils/stringutils" "kubesphere.io/kubesphere/pkg/utils/stringutils"
) )
@@ -90,8 +91,8 @@ type Interface interface {
PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error)
PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error) PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error)
ListClusters(info user.Info) (*api.ListResult, error) ListClusters(info user.Info) (*api.ListResult, error)
Metering(user user.Info, queryParam *meteringv1alpha1.Query) (monitoring.Metrics, error) Metering(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (monitoring.Metrics, error)
MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query) (metering.ResourceStatistic, error) MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error)
CreateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error) CreateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error)
DeleteWorkspaceResourceQuota(workspace string, resourceQuotaName string) error DeleteWorkspaceResourceQuota(workspace string, resourceQuotaName string) error
UpdateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error) UpdateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error)
@@ -991,7 +992,7 @@ func (t *tenantOperator) Auditing(user user.Info, queryParam *auditingv1alpha1.Q
}) })
} }
func (t *tenantOperator) Metering(user user.Info, query *meteringv1alpha1.Query) (metrics monitoring.Metrics, err error) { func (t *tenantOperator) Metering(user user.Info, query *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metrics monitoring.Metrics, err error) {
var opt QueryOptions var opt QueryOptions
@@ -999,13 +1000,13 @@ func (t *tenantOperator) Metering(user user.Info, query *meteringv1alpha1.Query)
if err != nil { if err != nil {
return return
} }
metrics, err = t.ProcessNamedMetersQuery(opt) metrics, err = t.ProcessNamedMetersQuery(opt, priceInfo)
return return
} }
func (t *tenantOperator) MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query) (metering.ResourceStatistic, error) { func (t *tenantOperator) MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error) {
res, err := t.Metering(user, queryParam) res, err := t.Metering(user, queryParam, priceInfo)
if err != nil { if err != nil {
return metering.ResourceStatistic{}, err return metering.ResourceStatistic{}, err
} }

View File

@@ -1,7 +1,35 @@
package metering package metering
type PriceInfo struct {
CpuPerCorePerHour float64 `json:"cpuPerCorePerHour" yaml:"cpuPerCorePerHour"`
MemPerGigabytesPerHour float64 `json:"memPerGigabytesPerHour" yaml:"memPerGigabytesPerHour"`
IngressNetworkTrafficPerMegabytesPerHour float64 `json:"ingressNetworkTrafficPerMegabytesPerHour" yaml:"ingressNetworkTrafficPerGiagabytesPerHour"`
EgressNetworkTrafficPerMegabytesPerHour float64 `json:"egressNetworkTrafficPerMegabytesPerHour" yaml:"egressNetworkTrafficPerGigabytesPerHour"`
PvcPerGigabytesPerHour float64 `json:"pvcPerGigabytesPerHour" yaml:"pvcPerGigabytesPerHour"`
CurrencyUnit string `json:"currencyUnit" yaml:"currencyUnit"`
}
type Billing struct {
PriceInfo PriceInfo `json:"priceInfo" yaml:"priceInfo"`
}
type Options struct { type Options struct {
Enable bool `json:"enable" yaml:"enable"` RetentionDay string `json:"retentionDay" yaml:"retentionDay"`
Billing Billing `json:"billing" yaml:"billing"`
}
var DefaultMeteringOption = Options{
RetentionDay: "7d",
Billing: Billing{
PriceInfo: PriceInfo{
CpuPerCorePerHour: 0,
MemPerGigabytesPerHour: 0,
IngressNetworkTrafficPerMegabytesPerHour: 0,
EgressNetworkTrafficPerMegabytesPerHour: 0,
PvcPerGigabytesPerHour: 0,
CurrencyUnit: "",
},
},
} }
func NewMeteringOptions() *Options { func NewMeteringOptions() *Options {

View File

@@ -16,7 +16,9 @@ limitations under the License.
package monitoring package monitoring
import "time" import (
"time"
)
type Interface interface { type Interface interface {
GetMetric(expr string, time time.Time) Metric GetMetric(expr string, time time.Time) Metric