github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/metric_source.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package pkg 5 6 import ( 7 "context" 8 "encoding/json" 9 "fmt" 10 "net/http" 11 12 "github.com/verrazzano/verrazzano/pkg/constants" 13 vzconst "github.com/verrazzano/verrazzano/platform-operator/constants" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/client-go/kubernetes" 16 ) 17 18 // MetricSource implements an interface to interact with metrics sources 19 type MetricSource interface { 20 GetHost() string 21 GetTargets() ([]interface{}, error) 22 getKubeConfigPath() string 23 } 24 25 // metricSourceBase implements shared functions between metric sources 26 type metricSourceBase struct { 27 client *kubernetes.Clientset 28 kubeconfigPath string 29 } 30 31 // ThanosSource provides a struct to interact with the Thanos metric source 32 type ThanosSource struct { 33 metricSourceBase 34 } 35 36 // PrometheusSource provides a struct to interact with Prometheus metric source 37 type PrometheusSource struct { 38 metricSourceBase 39 } 40 41 var _ MetricSource = ThanosSource{} 42 var _ MetricSource = PrometheusSource{} 43 44 func newMetricsSourceBase(kubeconfigPath string) (metricSourceBase, error) { 45 cli, err := GetKubernetesClientsetForCluster(kubeconfigPath) 46 return metricSourceBase{ 47 kubeconfigPath: kubeconfigPath, 48 client: cli, 49 }, err 50 } 51 52 func NewThanosSource(kubeconfigPath string) (ThanosSource, error) { 53 msb, err := newMetricsSourceBase(kubeconfigPath) 54 return ThanosSource{metricSourceBase: msb}, err 55 } 56 57 func NewPrometheusSource(kubeconfigPath string) (PrometheusSource, error) { 58 msb, err := newMetricsSourceBase(kubeconfigPath) 59 return PrometheusSource{metricSourceBase: msb}, err 60 } 61 62 func (m metricSourceBase) getKubeConfigPath() string { 63 return m.kubeconfigPath 64 } 65 66 // getHostByName returns the hostname given the ingress name 67 func (m metricSourceBase) getHostByIngressName(name string) string { 68 ingress, err := m.client.NetworkingV1().Ingresses(constants.VerrazzanoSystemNamespace).Get(context.TODO(), name, metav1.GetOptions{}) 69 if err != nil { 70 Log(Error, fmt.Sprintf("Failed get Thanos Frontend Ingress %s from the cluster: %v", constants.ThanosQueryIngress, err)) 71 return "" 72 } 73 return ingress.Spec.Rules[0].Host 74 } 75 76 // GetHost returns the host for the Thanos ingress 77 func (t ThanosSource) GetHost() string { 78 return t.metricSourceBase.getHostByIngressName(constants.ThanosQueryIngress) 79 } 80 81 // GetHost returns the host for the Prometheus ingress 82 func (p PrometheusSource) GetHost() string { 83 return p.metricSourceBase.getHostByIngressName(vzconst.PrometheusIngress) 84 } 85 86 // getTargetsByHostAndPath returns an unstructred target interface given the host and the path 87 func (m metricSourceBase) getTargetsByHostAndPath(host, path string, jsonPath []string) ([]interface{}, error) { 88 metricsURL := fmt.Sprintf("https://%s%s", host, path) 89 password, err := GetVerrazzanoPasswordInCluster(m.kubeconfigPath) 90 if err != nil { 91 return nil, err 92 } 93 resp, err := GetWebPageWithBasicAuth(metricsURL, "", "verrazzano", password, m.kubeconfigPath) 94 if err != nil { 95 return nil, err 96 } 97 if resp.StatusCode != http.StatusOK { 98 return nil, fmt.Errorf("error retrieving targets %d", resp.StatusCode) 99 } 100 101 var result map[string]interface{} 102 err = json.Unmarshal(resp.Body, &result) 103 if err != nil { 104 return nil, err 105 } 106 queryStores, ok := Jq(result, jsonPath...).([]interface{}) 107 if !ok { 108 return nil, fmt.Errorf("error finding query store in the Thanos store list") 109 } 110 return queryStores, nil 111 } 112 113 // GetTargets returns the Thanos store targets 114 func (t ThanosSource) GetTargets() ([]interface{}, error) { 115 return t.metricSourceBase.getTargetsByHostAndPath(t.GetHost(), "/api/v1/stores", []string{"data", "query"}) 116 } 117 118 // GetTargets returns the Prometheus targets 119 func (p PrometheusSource) GetTargets() ([]interface{}, error) { 120 return p.metricSourceBase.getTargetsByHostAndPath(p.GetHost(), "/api/v1/targets", []string{"data", "activeTargets"}) 121 }