From 5904e2e9be3b747e0f906fce050ae583fc4d8341 Mon Sep 17 00:00:00 2001 From: Rao Yunkun Date: Mon, 19 Apr 2021 17:06:34 +0800 Subject: [PATCH] Remove metering ConfigMap dependency. Signed-off-by: Rao Yunkun --- pkg/apiserver/apiserver.go | 4 +- pkg/apiserver/config/config.go | 4 -- pkg/kapis/metering/v1alpha1/handler.go | 5 +- pkg/kapis/metering/v1alpha1/register.go | 5 +- pkg/kapis/monitoring/v1alpha3/handler.go | 20 ++++-- pkg/kapis/monitoring/v1alpha3/meter.go | 16 ++--- pkg/kapis/monitoring/v1alpha3/register.go | 2 +- pkg/kapis/tenant/v1alpha2/handler.go | 14 +++- pkg/kapis/tenant/v1alpha2/metering.go | 17 ++--- pkg/kapis/tenant/v1alpha2/register.go | 5 +- pkg/models/metering/type.go | 10 --- pkg/models/monitoring/monitoring.go | 13 ++-- pkg/models/monitoring/utils.go | 81 ++--------------------- pkg/models/tenant/metering.go | 23 ++++--- pkg/models/tenant/tenant.go | 13 ++-- pkg/simple/client/metering/options.go | 30 ++++++++- pkg/simple/client/monitoring/interface.go | 4 +- 17 files changed, 112 insertions(+), 154 deletions(-) diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 529af7cbd..c26670a63 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -220,14 +220,14 @@ func (s *APIServer) installKubeSphereAPIs() { urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config)) 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(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(openpitrixv2alpha1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions)) urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes())) urlruntime.Must(resourcesv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.InformerFactory, s.KubernetesClient.Master())) 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(clusterkapisv1alpha1.AddToContainer(s.container, s.InformerFactory.KubernetesSharedInformerFactory(), diff --git a/pkg/apiserver/config/config.go b/pkg/apiserver/config/config.go index d8e26ce2e..a4080d5ee 100644 --- a/pkg/apiserver/config/config.go +++ b/pkg/apiserver/config/config.go @@ -290,8 +290,4 @@ func (conf *Config) stripEmptyOptions() { if conf.KubeEdgeOptions != nil && conf.KubeEdgeOptions.Endpoint == "" { conf.KubeEdgeOptions = nil } - - if conf.MeteringOptions != nil && !conf.MeteringOptions.Enable { - conf.MeteringOptions = nil - } } diff --git a/pkg/kapis/metering/v1alpha1/handler.go b/pkg/kapis/metering/v1alpha1/handler.go index 544029e3f..8b24ff97d 100644 --- a/pkg/kapis/metering/v1alpha1/handler.go +++ b/pkg/kapis/metering/v1alpha1/handler.go @@ -26,6 +26,7 @@ import ( "kubesphere.io/kubesphere/pkg/informers" monitorhle "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) @@ -42,6 +43,6 @@ type meterHandler interface { 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 { - return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter) +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, meteringOptions) } diff --git a/pkg/kapis/metering/v1alpha1/register.go b/pkg/kapis/metering/v1alpha1/register.go index 9b0433964..745f1d87e 100644 --- a/pkg/kapis/metering/v1alpha1/register.go +++ b/pkg/kapis/metering/v1alpha1/register.go @@ -34,6 +34,7 @@ import ( monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" model "kubesphere.io/kubesphere/pkg/models/monitoring" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) @@ -44,10 +45,10 @@ const ( 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) - 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"). To(h.HandleClusterMeterQuery). diff --git a/pkg/kapis/monitoring/v1alpha3/handler.go b/pkg/kapis/monitoring/v1alpha3/handler.go index d8300a282..e7a7c1c40 100644 --- a/pkg/kapis/monitoring/v1alpha3/handler.go +++ b/pkg/kapis/monitoring/v1alpha3/handler.go @@ -33,25 +33,31 @@ import ( "kubesphere.io/kubesphere/pkg/informers" model "kubesphere.io/kubesphere/pkg/models/monitoring" resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) type handler struct { - k kubernetes.Interface - mo model.MonitoringOperator - opRelease openpitrix.ReleaseInterface + k kubernetes.Interface + mo model.MonitoringOperator + 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 if ksClient != nil { opRelease = openpitrix.NewOpenpitrixOperator(f, ksClient, nil) } + if meteringOptions == nil { + meteringOptions = &meteringclient.DefaultMeteringOption + } return &handler{ - k: k, - mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter), - opRelease: opRelease, + k: k, + mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter), + opRelease: opRelease, + meteringOptions: meteringOptions, } } diff --git a/pkg/kapis/monitoring/v1alpha3/meter.go b/pkg/kapis/monitoring/v1alpha3/meter.go index 7f390a79a..8895ab628 100644 --- a/pkg/kapis/monitoring/v1alpha3/meter.go +++ b/pkg/kapis/monitoring/v1alpha3/meter.go @@ -62,9 +62,9 @@ func (h handler) handleApplicationMetersQuery(meters []string, resp *restful.Res } 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 { - 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 { api.HandleBadRequest(resp, nil, err) @@ -119,9 +119,9 @@ func (h handler) handleServiceMetersQuery(meters []string, resp *restful.Respons } 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 { - 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 { api.HandleBadRequest(resp, nil, err) @@ -197,13 +197,13 @@ func (h handler) handleNamedMetersQuery(resp *restful.Response, q queryOptions) } 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 { api.HandleBadRequest(resp, nil, err) return } } 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 { api.HandleBadRequest(resp, nil, err) return @@ -434,9 +434,9 @@ func (h handler) handleOpenpitrixMetersQuery(meters []string, resp *restful.Resp } 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 { - 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 { api.HandleBadRequest(resp, nil, err) diff --git a/pkg/kapis/monitoring/v1alpha3/register.go b/pkg/kapis/monitoring/v1alpha3/register.go index 73f5514f8..fca39f2e2 100644 --- a/pkg/kapis/monitoring/v1alpha3/register.go +++ b/pkg/kapis/monitoring/v1alpha3/register.go @@ -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 { 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"). To(h.handleKubeSphereMetricsQuery). diff --git a/pkg/kapis/tenant/v1alpha2/handler.go b/pkg/kapis/tenant/v1alpha2/handler.go index 8c5b99774..540402abd 100644 --- a/pkg/kapis/tenant/v1alpha2/handler.go +++ b/pkg/kapis/tenant/v1alpha2/handler.go @@ -46,20 +46,28 @@ import ( "kubesphere.io/kubesphere/pkg/simple/client/auditing" "kubesphere.io/kubesphere/pkg/simple/client/events" "kubesphere.io/kubesphere/pkg/simple/client/logging" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) type tenantHandler struct { - tenant tenant.Interface + tenant tenant.Interface + meteringOptions *meteringclient.Options } func newTenantHandler(factory informers.InformerFactory, k8sclient kubernetes.Interface, ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client, auditingclient auditing.Client, 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{ - 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, } } diff --git a/pkg/kapis/tenant/v1alpha2/metering.go b/pkg/kapis/tenant/v1alpha2/metering.go index bca0b1b59..d507ac469 100644 --- a/pkg/kapis/tenant/v1alpha2/metering.go +++ b/pkg/kapis/tenant/v1alpha2/metering.go @@ -14,7 +14,6 @@ import ( "kubesphere.io/kubesphere/pkg/apiserver/request" monitoringv1alpha3 "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3" "kubesphere.io/kubesphere/pkg/models/metering" - "kubesphere.io/kubesphere/pkg/models/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) - res, err := h.tenant.Metering(u, q) + res, err := h.tenant.Metering(u, q, h.meteringOptions.Billing.PriceInfo) if err != nil { api.HandleBadRequest(resp, nil, err) return @@ -71,7 +70,7 @@ func (h *tenantHandler) QueryMeteringHierarchy(req *restful.Request, resp *restf q := meteringv1alpha1.ParseQueryParameter(req) 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 { api.HandleBadRequest(resp, nil, err) return @@ -83,17 +82,9 @@ func (h *tenantHandler) QueryMeteringHierarchy(req *restful.Request, resp *restf func (h *tenantHandler) HandlePriceInfoQuery(req *restful.Request, resp *restful.Response) { var priceResponse metering.PriceResponse - priceResponse.Init() - meterConfig, err := monitoring.LoadYaml() - if err != nil { - klog.Warning(err) - resp.WriteAsJson(priceResponse) - return - } - - priceInfo := meterConfig.GetPriceInfo() - priceResponse.RetentionDay = meterConfig.RetentionDay + priceInfo := h.meteringOptions.Billing.PriceInfo + priceResponse.RetentionDay = h.meteringOptions.RetentionDay priceResponse.Currency = priceInfo.CurrencyUnit priceResponse.CpuPerCorePerHour = priceInfo.CpuPerCorePerHour priceResponse.MemPerGigabytesPerHour = priceInfo.MemPerGigabytesPerHour diff --git a/pkg/kapis/tenant/v1alpha2/register.go b/pkg/kapis/tenant/v1alpha2/register.go index 755dd5849..82697cae3 100644 --- a/pkg/kapis/tenant/v1alpha2/register.go +++ b/pkg/kapis/tenant/v1alpha2/register.go @@ -48,6 +48,7 @@ import ( "kubesphere.io/kubesphere/pkg/simple/client/auditing" "kubesphere.io/kubesphere/pkg/simple/client/events" "kubesphere.io/kubesphere/pkg/simple/client/logging" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" 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, ksclient kubesphere.Interface, evtsClient events.Client, loggingClient logging.Client, 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} 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"). To(handler.ListClusters). diff --git a/pkg/models/metering/type.go b/pkg/models/metering/type.go index 511274056..3cb802897 100644 --- a/pkg/models/metering/type.go +++ b/pkg/models/metering/type.go @@ -14,16 +14,6 @@ type PriceResponse struct { 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 { CPUUsage float64 `json:"cpu_usage" description:"cpu_usage"` MemoryUsageWoCache float64 `json:"memory_usage_wo_cache" description:"memory_usage_wo_cache"` diff --git a/pkg/models/monitoring/monitoring.go b/pkg/models/monitoring/monitoring.go index bd90b316f..9ea32b13c 100644 --- a/pkg/models/monitoring/monitoring.go +++ b/pkg/models/monitoring/monitoring.go @@ -41,6 +41,7 @@ import ( resourcev1alpha3 "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource" "kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/params" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) @@ -57,8 +58,8 @@ type MonitoringOperator interface { GetWorkspaceStats(workspace string) Metrics // meter - GetNamedMetersOverTime(metrics []string, start, end time.Time, step time.Duration, opt monitoring.QueryOption) (Metrics, error) - GetNamedMeters(metrics []string, time time.Time, 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, priceInfo meteringclient.PriceInfo) (Metrics, error) GetAppWorkloads(ns string, apps []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 } -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 { klog.Warning("step should be longer than one hour") @@ -458,13 +459,13 @@ func (mo monitoringOperator) GetNamedMetersOverTime(meters []string, start, end sMap := generateScalingFactorMap(step) for i, _ := range ress { - ress[i].MetricData = updateMetricStatData(ress[i], sMap) + ress[i].MetricData = updateMetricStatData(ress[i], sMap, priceInfo) } 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) @@ -472,7 +473,7 @@ func (mo monitoringOperator) GetNamedMeters(meters []string, time time.Time, opt res := metersPerHour.Results[metricIndex] - metersPerHour.Results[metricIndex].MetricData = updateMetricStatData(res, nil) + metersPerHour.Results[metricIndex].MetricData = updateMetricStatData(res, nil, priceInfo) } return metersPerHour, nil diff --git a/pkg/models/monitoring/utils.go b/pkg/models/monitoring/utils.go index 450e600a8..5b369b0bd 100644 --- a/pkg/models/monitoring/utils.go +++ b/pkg/models/monitoring/utils.go @@ -3,12 +3,10 @@ package monitoring import ( "fmt" "math/big" - "os" - "path/filepath" - "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/klog" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "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, } -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 { var max *big.Float for i, p := range points { @@ -181,16 +129,6 @@ func getAvgPointValue(points []monitoring.Point) string { 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 { 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) if !ok { @@ -212,13 +150,6 @@ func getFeeWithMeterName(meterName string, sum string) string { return "" } - meterConfig, err := LoadYaml() - if err != nil { - klog.Error(err) - return "" - } - priceInfo := meterConfig.GetPriceInfo() - if resourceType, ok := MeterResourceMap[meterName]; !ok { klog.Errorf("invlaid meter %v", meterName) 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 metricData := metric.MetricData for index, metricValue := range metricData.MetricValues { @@ -293,14 +224,14 @@ func updateMetricStatData(metric monitoring.Metric, scalingMap map[string]float6 if metricData.MetricType == monitoring.MetricTypeMatrix { sum := getSumPointValue(metricData.MetricValues[index].Series) metricData.MetricValues[index].SumValue = sum - metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum) + metricData.MetricValues[index].Fee = getFeeWithMeterName(metricName, sum, priceInfo) } else { sum := getSumPointValue([]monitoring.Point{*metricValue.Sample}) 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) } diff --git a/pkg/models/tenant/metering.go b/pkg/models/tenant/metering.go index 8f4aa1886..25f2ab4dd 100644 --- a/pkg/models/tenant/metering.go +++ b/pkg/models/tenant/metering.go @@ -28,6 +28,7 @@ import ( monitoringmodel "kubesphere.io/kubesphere/pkg/models/monitoring" "kubesphere.io/kubesphere/pkg/models/openpitrix" "kubesphere.io/kubesphere/pkg/server/params" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" "kubesphere.io/kubesphere/pkg/simple/client/monitoring" ) @@ -538,7 +539,7 @@ func (t *tenantOperator) makeQueryOptions(user user.Info, q meteringv1alpha1.Que 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 for _, meter := range q.NamedMetrics { if !strings.HasPrefix(meter, monitoringmodel.MetricMeterPrefix) { @@ -559,20 +560,20 @@ func (t *tenantOperator) ProcessNamedMetersQuery(q QueryOptions) (metrics monito _, ok := q.Option.(monitoring.ApplicationsOption) if ok { - metrics, err = t.processApplicationMetersQuery(meters, q) + metrics, err = t.processApplicationMetersQuery(meters, q, priceInfo) return } _, ok = q.Option.(monitoring.ServicesOption) if ok { - metrics, err = t.processServiceMetersQuery(meters, q) + metrics, err = t.processServiceMetersQuery(meters, q, priceInfo) return } 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 { - metrics, err = t.mo.GetNamedMeters(meters, q.Time, q.Option) + metrics, err = t.mo.GetNamedMeters(meters, q.Time, q.Option, priceInfo) if q.shouldSort() { 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 } -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 current_res monitoringmodel.Metrics @@ -612,9 +613,9 @@ func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryO } 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 { - 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 { @@ -639,7 +640,7 @@ func (t *tenantOperator) processApplicationMetersQuery(meters []string, q QueryO 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 current_res monitoringmodel.Metrics @@ -659,9 +660,9 @@ func (t *tenantOperator) processServiceMetersQuery(meters []string, q QueryOptio } 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 { - 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 { diff --git a/pkg/models/tenant/tenant.go b/pkg/models/tenant/tenant.go index f4e1a502a..1b4b6c19a 100644 --- a/pkg/models/tenant/tenant.go +++ b/pkg/models/tenant/tenant.go @@ -63,6 +63,7 @@ import ( auditingclient "kubesphere.io/kubesphere/pkg/simple/client/auditing" eventsclient "kubesphere.io/kubesphere/pkg/simple/client/events" loggingclient "kubesphere.io/kubesphere/pkg/simple/client/logging" + meteringclient "kubesphere.io/kubesphere/pkg/simple/client/metering" monitoringclient "kubesphere.io/kubesphere/pkg/simple/client/monitoring" "kubesphere.io/kubesphere/pkg/utils/stringutils" ) @@ -90,8 +91,8 @@ type Interface interface { PatchNamespace(workspace string, namespace *corev1.Namespace) (*corev1.Namespace, error) PatchWorkspace(workspace string, data json.RawMessage) (*tenantv1alpha2.WorkspaceTemplate, error) ListClusters(info user.Info) (*api.ListResult, error) - Metering(user user.Info, queryParam *meteringv1alpha1.Query) (monitoring.Metrics, error) - MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query) (metering.ResourceStatistic, error) + Metering(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (monitoring.Metrics, error) + MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error) CreateWorkspaceResourceQuota(workspace string, resourceQuota *quotav1alpha2.ResourceQuota) (*quotav1alpha2.ResourceQuota, error) DeleteWorkspaceResourceQuota(workspace string, resourceQuotaName string) 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 @@ -999,13 +1000,13 @@ func (t *tenantOperator) Metering(user user.Info, query *meteringv1alpha1.Query) if err != nil { return } - metrics, err = t.ProcessNamedMetersQuery(opt) + metrics, err = t.ProcessNamedMetersQuery(opt, priceInfo) return } -func (t *tenantOperator) MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query) (metering.ResourceStatistic, error) { - res, err := t.Metering(user, queryParam) +func (t *tenantOperator) MeteringHierarchy(user user.Info, queryParam *meteringv1alpha1.Query, priceInfo meteringclient.PriceInfo) (metering.ResourceStatistic, error) { + res, err := t.Metering(user, queryParam, priceInfo) if err != nil { return metering.ResourceStatistic{}, err } diff --git a/pkg/simple/client/metering/options.go b/pkg/simple/client/metering/options.go index d95d9f619..0a76926ac 100644 --- a/pkg/simple/client/metering/options.go +++ b/pkg/simple/client/metering/options.go @@ -1,7 +1,35 @@ 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 { - 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 { diff --git a/pkg/simple/client/monitoring/interface.go b/pkg/simple/client/monitoring/interface.go index 1e82eb221..687761bd3 100644 --- a/pkg/simple/client/monitoring/interface.go +++ b/pkg/simple/client/monitoring/interface.go @@ -16,7 +16,9 @@ limitations under the License. package monitoring -import "time" +import ( + "time" +) type Interface interface { GetMetric(expr string, time time.Time) Metric