Просмотр исходного кода

Merge pull request #126 from kubecost/AjayTripathy-ns-filters

add ns filtering
Ajay Tripathy 6 лет назад
Родитель
Сommit
af06934c2c
4 измененных файлов с 51 добавлено и 30 удалено
  1. 42 27
      costmodel/costmodel.go
  2. 1 0
      go.mod
  3. 3 0
      go.sum
  4. 5 3
      main.go

+ 42 - 27
costmodel/costmodel.go

@@ -39,26 +39,26 @@ const (
 )
 
 type CostData struct {
-	Name            string                       `json:"name"`
-	PodName         string                       `json:"podName"`
-	NodeName        string                       `json:"nodeName"`
-	NodeData        *costAnalyzerCloud.Node      `json:"node"`
-	Namespace       string                       `json:"namespace"`
-	Deployments     []string                     `json:"deployments"`
-	Services        []string                     `json:"services"`
-	Daemonsets      []string                     `json:"daemonsets"`
-	Statefulsets    []string                     `json:"statefulsets"`
-	Jobs            []string                     `json:"jobs"`
-	RAMReq          []*Vector                    `json:"ramreq"`
-	RAMUsed         []*Vector                    `json:"ramused"`
-	CPUReq          []*Vector                    `json:"cpureq"`
-	CPUUsed         []*Vector                    `json:"cpuused"`
-	RAMAllocation   []*Vector                    `json:"ramallocated"`
-	CPUAllocation   []*Vector                    `json:"cpuallocated"`
-	GPUReq          []*Vector                    `json:"gpureq"`
-	PVCData         []*PersistentVolumeClaimData `json:"pvcData"`
-	Labels          map[string]string            `json:"labels"`
-	NamespaceLabels map[string]string            `json:"namespaceLabels"`
+	Name            string                       `json:"name,omitempty"`
+	PodName         string                       `json:"podName,omitempty"`
+	NodeName        string                       `json:"nodeName,omitempty"`
+	NodeData        *costAnalyzerCloud.Node      `json:"node,omitempty"`
+	Namespace       string                       `json:"namespace,omitempty"`
+	Deployments     []string                     `json:"deployments,omitempty"`
+	Services        []string                     `json:"services,omitempty"`
+	Daemonsets      []string                     `json:"daemonsets,omitempty"`
+	Statefulsets    []string                     `json:"statefulsets,omitempty"`
+	Jobs            []string                     `json:"jobs,omitempty"`
+	RAMReq          []*Vector                    `json:"ramreq,omitempty"`
+	RAMUsed         []*Vector                    `json:"ramused,omitempty"`
+	CPUReq          []*Vector                    `json:"cpureq,omitempty"`
+	CPUUsed         []*Vector                    `json:"cpuused,omitempty"`
+	RAMAllocation   []*Vector                    `json:"ramallocated,omitempty"`
+	CPUAllocation   []*Vector                    `json:"cpuallocated,omitempty"`
+	GPUReq          []*Vector                    `json:"gpureq,omitempty"`
+	PVCData         []*PersistentVolumeClaimData `json:"pvcData,omitempty"`
+	Labels          map[string]string            `json:"labels,omitempty"`
+	NamespaceLabels map[string]string            `json:"namespaceLabels,omitempty"`
 }
 
 type Vector struct {
@@ -206,7 +206,7 @@ func getUptimeData(qr interface{}) ([]*Vector, bool, error) {
 	return jobData, kubecostMetrics, nil
 }
 
-func ComputeCostData(cli prometheusClient.Client, clientset kubernetes.Interface, cloud costAnalyzerCloud.Provider, window string, offset string) (map[string]*CostData, error) {
+func ComputeCostData(cli prometheusClient.Client, clientset kubernetes.Interface, cloud costAnalyzerCloud.Provider, window string, offset string, filterNamespace string) (map[string]*CostData, error) {
 	queryRAMRequests := fmt.Sprintf(queryRAMRequestsStr, window, offset, window, offset)
 	queryRAMUsage := fmt.Sprintf(queryRAMUsageStr, window, offset, window, offset)
 	queryCPURequests := fmt.Sprintf(queryCPURequestsStr, window, offset, window, offset)
@@ -445,9 +445,12 @@ func ComputeCostData(cli prometheusClient.Client, clientset kubernetes.Interface
 				}
 				costs.CPUAllocation = getContainerAllocation(costs.CPUReq, costs.CPUUsed)
 				costs.RAMAllocation = getContainerAllocation(costs.RAMReq, costs.RAMUsed)
-				containerNameCost[newKey] = costs
+				if filterNamespace == "" {
+					containerNameCost[newKey] = costs
+				} else if costs.Namespace == filterNamespace {
+					containerNameCost[newKey] = costs
+				}
 			}
-
 		} else {
 			// The container has been deleted. Not all information is sent to prometheus via ksm, so fill out what we can without k8s api
 			klog.V(4).Info("The container " + key + " has been deleted. Calculating allocation but resulting object will be missing data.")
@@ -505,7 +508,11 @@ func ComputeCostData(cli prometheusClient.Client, clientset kubernetes.Interface
 			}
 			costs.CPUAllocation = getContainerAllocation(costs.CPUReq, costs.CPUUsed)
 			costs.RAMAllocation = getContainerAllocation(costs.RAMReq, costs.RAMUsed)
-			containerNameCost[key] = costs
+			if filterNamespace == "" {
+				containerNameCost[key] = costs
+			} else if costs.Namespace == filterNamespace {
+				containerNameCost[key] = costs
+			}
 		}
 	}
 	err = findDeletedNodeInfo(cli, missingNodes, window)
@@ -885,7 +892,7 @@ func getPodDeployments(clientset kubernetes.Interface, podList *v1.PodList) (map
 }
 
 func ComputeCostDataRange(cli prometheusClient.Client, clientset kubernetes.Interface, cloud costAnalyzerCloud.Provider,
-	startString, endString, windowString string) (map[string]*CostData, error) {
+	startString, endString, windowString string, filterNamespace string) (map[string]*CostData, error) {
 	queryRAMRequests := fmt.Sprintf(queryRAMRequestsStr, windowString, "", windowString, "")
 	queryRAMUsage := fmt.Sprintf(queryRAMUsageStr, windowString, "", windowString, "")
 	queryCPURequests := fmt.Sprintf(queryCPURequestsStr, windowString, "", windowString, "")
@@ -1135,7 +1142,11 @@ func ComputeCostDataRange(cli prometheusClient.Client, clientset kubernetes.Inte
 				}
 				costs.CPUAllocation = getContainerAllocation(costs.CPUReq, costs.CPUUsed)
 				costs.RAMAllocation = getContainerAllocation(costs.RAMReq, costs.RAMUsed)
-				containerNameCost[newKey] = costs
+				if filterNamespace == "" {
+					containerNameCost[newKey] = costs
+				} else if costs.Namespace == filterNamespace {
+					containerNameCost[newKey] = costs
+				}
 			}
 
 		} else {
@@ -1192,7 +1203,11 @@ func ComputeCostDataRange(cli prometheusClient.Client, clientset kubernetes.Inte
 			}
 			costs.CPUAllocation = getContainerAllocation(costs.CPUReq, costs.CPUUsed)
 			costs.RAMAllocation = getContainerAllocation(costs.RAMReq, costs.RAMUsed)
-			containerNameCost[key] = costs
+			if filterNamespace == "" {
+				containerNameCost[key] = costs
+			} else if costs.Namespace == filterNamespace {
+				containerNameCost[key] = costs
+			}
 		}
 	}
 

+ 1 - 0
go.mod

@@ -24,6 +24,7 @@ require (
 	golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect
 	golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a
 	google.golang.org/api v0.4.0
+	gotest.tools v2.2.0+incompatible
 	k8s.io/api v0.0.0-20190404065945-709cf190c7b7
 	k8s.io/apimachinery v0.0.0-20190404065847-4a4abcd45006
 	k8s.io/client-go v0.0.0-20190404172613-2e1a3ed22ac5

+ 3 - 0
go.sum

@@ -117,6 +117,7 @@ github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -254,6 +255,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 5 - 3
main.go

@@ -127,12 +127,13 @@ func (a *Accesses) CostDataModel(w http.ResponseWriter, r *http.Request, ps http
 	window := r.URL.Query().Get("timeWindow")
 	offset := r.URL.Query().Get("offset")
 	fields := r.URL.Query().Get("filterFields")
+	namespace := r.URL.Query().Get("namespace")
 
 	if offset != "" {
 		offset = "offset " + offset
 	}
 
-	data, err := costModel.ComputeCostData(a.PrometheusClient, a.KubeClientSet, a.Cloud, window, offset)
+	data, err := costModel.ComputeCostData(a.PrometheusClient, a.KubeClientSet, a.Cloud, window, offset, namespace)
 	if fields != "" {
 		filteredData := filterFields(fields, data)
 		w.Write(wrapData(filteredData, err))
@@ -181,8 +182,9 @@ func (a *Accesses) CostDataModelRange(w http.ResponseWriter, r *http.Request, ps
 	end := r.URL.Query().Get("end")
 	window := r.URL.Query().Get("window")
 	fields := r.URL.Query().Get("filterFields")
+	namespace := r.URL.Query().Get("namespace")
 
-	data, err := costModel.ComputeCostDataRange(a.PrometheusClient, a.KubeClientSet, a.Cloud, start, end, window)
+	data, err := costModel.ComputeCostDataRange(a.PrometheusClient, a.KubeClientSet, a.Cloud, start, end, window, namespace)
 	if fields != "" {
 		filteredData := filterFields(fields, data)
 		w.Write(wrapData(filteredData, err))
@@ -299,7 +301,7 @@ func (a *Accesses) recordPrices() {
 	go func() {
 		for {
 			klog.V(3).Info("Recording prices...")
-			data, err := costModel.ComputeCostData(a.PrometheusClient, a.KubeClientSet, a.Cloud, "2m", "")
+			data, err := costModel.ComputeCostData(a.PrometheusClient, a.KubeClientSet, a.Cloud, "2m", "", "")
 			if err != nil {
 				klog.V(1).Info("Error in price recording: " + err.Error())
 				// zero the for loop so the time.Sleep will still work