diff --git a/cmd/kube-burner/kube-burner.go b/cmd/kube-burner/kube-burner.go index b83824768..c15c568d8 100644 --- a/cmd/kube-burner/kube-burner.go +++ b/cmd/kube-burner/kube-burner.go @@ -102,17 +102,26 @@ func initCmd() *cobra.Command { // We assume configFile is config.yml configFile = "config.yml" } - err = config.Parse(configFile, true) + configSpec, err := config.Parse(configFile, true) if err != nil { log.Fatal(err.Error()) } + if url == "" { + url = configSpec.GlobalConfig.PrometheusURL + } + if token == "" { + token = configSpec.GlobalConfig.BearerToken + } + if metricsProfile == "" { + metricsProfile = configSpec.GlobalConfig.MetricsProfile + } if url != "" { - prometheusClient, err = prometheus.NewPrometheusClient(url, token, username, password, uuid, skipTLSVerify, prometheusStep) + prometheusClient, err = prometheus.NewPrometheusClient(configSpec, url, token, username, password, uuid, skipTLSVerify, prometheusStep) if err != nil { log.Fatal(err) } // If indexer is enabled or writeTofile is enabled we read the profile - if config.ConfigSpec.GlobalConfig.IndexerConfig.Enabled || config.ConfigSpec.GlobalConfig.WriteToFile { + if configSpec.GlobalConfig.IndexerConfig.Enabled || configSpec.GlobalConfig.WriteToFile { if err := prometheusClient.ReadProfile(metricsProfile); err != nil { log.Fatal(err) } @@ -123,7 +132,7 @@ func initCmd() *cobra.Command { } } } - steps(uuid, prometheusClient, alertM) + steps(configSpec, uuid, prometheusClient, alertM) }, } cmd.Flags().StringVar(&uuid, "uuid", uid.NewV4().String(), "Benchmark UUID") @@ -151,7 +160,7 @@ func destroyCmd() *cobra.Command { Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { if configFile != "" { - err := config.Parse(configFile, false) + _, err := config.Parse(configFile, false) if err != nil { log.Fatal(err.Error()) } @@ -181,17 +190,17 @@ func indexCmd() *cobra.Command { Short: "Index kube-burner metrics", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - err := config.Parse(configFile, false) + configSpec, err := config.Parse(configFile, false) if err != nil { log.Fatal(err.Error()) } - if config.ConfigSpec.GlobalConfig.IndexerConfig.Enabled { - indexer, err = indexers.NewIndexer() + if configSpec.GlobalConfig.IndexerConfig.Enabled { + indexer, err = indexers.NewIndexer(configSpec) if err != nil { log.Fatal(err.Error()) } } - p, err := prometheus.NewPrometheusClient(url, token, username, password, uuid, skipTLSVerify, prometheusStep) + p, err := prometheus.NewPrometheusClient(configSpec, url, token, username, password, uuid, skipTLSVerify, prometheusStep) if err != nil { log.Fatal(err) } @@ -204,8 +213,8 @@ func indexCmd() *cobra.Command { if err := p.ScrapeMetrics(startTime, endTime, indexer, jobName); err != nil { log.Error(err) } - if config.ConfigSpec.GlobalConfig.WriteToFile && config.ConfigSpec.GlobalConfig.CreateTarball { - err = prometheus.CreateTarball(config.ConfigSpec.GlobalConfig.MetricsDirectory) + if configSpec.GlobalConfig.WriteToFile && configSpec.GlobalConfig.CreateTarball { + err = prometheus.CreateTarball(configSpec.GlobalConfig.MetricsDirectory) if err != nil { log.Fatal(err.Error()) } @@ -236,15 +245,15 @@ func importCmd() *cobra.Command { Use: "import", Short: "Import metrics tarball", Run: func(cmd *cobra.Command, args []string) { - err := config.Parse(configFile, false) + configSpec, err := config.Parse(configFile, false) if err != nil { log.Fatal(err.Error()) } - indexer, err := indexers.NewIndexer() + indexer, err := indexers.NewIndexer(configSpec) if err != nil { log.Fatal(err.Error()) } - err = prometheus.ImportTarball(tarball, config.ConfigSpec.GlobalConfig.IndexerConfig.DefaultIndex, indexer) + err = prometheus.ImportTarball(tarball, configSpec.GlobalConfig.IndexerConfig.DefaultIndex, indexer) if err != nil { log.Fatal(err.Error()) } @@ -268,7 +277,7 @@ func alertCmd() *cobra.Command { Short: "Evaluate alerts for the given time range", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - p, err := prometheus.NewPrometheusClient(url, token, username, password, uuid, skipTLSVerify, prometheusStep) + p, err := prometheus.NewPrometheusClient(config.Spec{}, url, token, username, password, uuid, skipTLSVerify, prometheusStep) if err != nil { log.Fatal(err) } @@ -297,13 +306,13 @@ func alertCmd() *cobra.Command { return cmd } -func steps(uuid string, p *prometheus.Prometheus, alertM *alerting.AlertManager) { +func steps(configSpec config.Spec, uuid string, p *prometheus.Prometheus, alertM *alerting.AlertManager) { var rc int var err error var measurementsWg sync.WaitGroup var indexer *indexers.Indexer - if config.ConfigSpec.GlobalConfig.IndexerConfig.Enabled { - indexer, err = indexers.NewIndexer() + if configSpec.GlobalConfig.IndexerConfig.Enabled { + indexer, err = indexers.NewIndexer(configSpec) if err != nil { log.Fatal(err.Error()) } @@ -312,8 +321,8 @@ func steps(uuid string, p *prometheus.Prometheus, alertM *alerting.AlertManager) if err != nil { log.Fatalf("Error creating k8s clientSet: %s", err) } - measurements.NewMeasurementFactory(restConfig, uuid, indexer) - jobList := burner.NewExecutorList(uuid) + measurements.NewMeasurementFactory(configSpec, restConfig, uuid, indexer) + jobList := burner.NewExecutorList(configSpec, uuid) // Iterate through job list for jobPosition, job := range jobList { if job.Config.PreLoadImages { @@ -358,10 +367,10 @@ func steps(uuid string, p *prometheus.Prometheus, alertM *alerting.AlertManager) elapsedTime := jobList[jobPosition].End.Sub(jobList[jobPosition].Start).Seconds() log.Infof("Job %s took %.2f seconds", job.Config.Name, elapsedTime) } - if config.ConfigSpec.GlobalConfig.IndexerConfig.Enabled { + if configSpec.GlobalConfig.IndexerConfig.Enabled { for _, job := range jobList { elapsedTime := job.End.Sub(job.Start).Seconds() - err := burner.IndexMetadataInfo(indexer, uuid, elapsedTime, job.Config, job.Start) + err := burner.IndexMetadataInfo(configSpec, indexer, uuid, elapsedTime, job.Config, job.Start) if err != nil { log.Errorf(err.Error()) } @@ -384,8 +393,8 @@ func steps(uuid string, p *prometheus.Prometheus, alertM *alerting.AlertManager) if err := p.ScrapeJobsMetrics(jobList, indexer); err != nil { log.Error(err.Error()) } - if config.ConfigSpec.GlobalConfig.WriteToFile && config.ConfigSpec.GlobalConfig.CreateTarball { - err = prometheus.CreateTarball(config.ConfigSpec.GlobalConfig.MetricsDirectory) + if configSpec.GlobalConfig.WriteToFile && configSpec.GlobalConfig.CreateTarball { + err = prometheus.CreateTarball(configSpec.GlobalConfig.MetricsDirectory) if err != nil { log.Error(err.Error()) } diff --git a/pkg/burner/job.go b/pkg/burner/job.go index 5c3b72deb..f1b84730b 100644 --- a/pkg/burner/job.go +++ b/pkg/burner/job.go @@ -68,7 +68,7 @@ var dynamicClient dynamic.Interface var RestConfig *rest.Config // NewExecutorList Returns a list of executors -func NewExecutorList(uuid string) []Executor { +func NewExecutorList(configSpec config.Spec, uuid string) []Executor { var err error var ex Executor var executorList []Executor @@ -76,7 +76,7 @@ func NewExecutorList(uuid string) []Executor { if err != nil { log.Fatalf("Error creating clientSet: %s", err) } - for _, job := range config.ConfigSpec.Jobs { + for _, job := range configSpec.Jobs { if job.JobType == config.CreationJob { ex = setupCreateJob(job) } else if job.JobType == config.DeletionJob { diff --git a/pkg/burner/metadata.go b/pkg/burner/metadata.go index 619f28fce..267ae892d 100644 --- a/pkg/burner/metadata.go +++ b/pkg/burner/metadata.go @@ -37,7 +37,7 @@ type metadata struct { const jobSummary = "jobSummary" // IndexMetadataInfo Generates and indexes a document with metadata information of the passed job -func IndexMetadataInfo(indexer *indexers.Indexer, uuid string, elapsedTime float64, jobConfig config.Job, timestamp time.Time) error { +func IndexMetadataInfo(configSpec config.Spec, indexer *indexers.Indexer, uuid string, elapsedTime float64, jobConfig config.Job, timestamp time.Time) error { metadataInfo := []interface{}{ metadata{ UUID: uuid, @@ -47,13 +47,13 @@ func IndexMetadataInfo(indexer *indexers.Indexer, uuid string, elapsedTime float Timestamp: timestamp, }, } - if config.ConfigSpec.GlobalConfig.WriteToFile { + if configSpec.GlobalConfig.WriteToFile { filename := fmt.Sprintf("%s-metadata.json", jobConfig.Name) - if config.ConfigSpec.GlobalConfig.MetricsDirectory != "" { - if err := os.MkdirAll(config.ConfigSpec.GlobalConfig.MetricsDirectory, 0744); err != nil { + if configSpec.GlobalConfig.MetricsDirectory != "" { + if err := os.MkdirAll(configSpec.GlobalConfig.MetricsDirectory, 0744); err != nil { return fmt.Errorf("Error creating metrics directory: %v: ", err) } - filename = path.Join(config.ConfigSpec.GlobalConfig.MetricsDirectory, filename) + filename = path.Join(configSpec.GlobalConfig.MetricsDirectory, filename) } log.Infof("Writing to: %s", filename) f, err := os.Create(filename) @@ -67,6 +67,6 @@ func IndexMetadataInfo(indexer *indexers.Indexer, uuid string, elapsedTime float } } log.Infof("Indexing metadata information for job: %s", jobConfig.Name) - (*indexer).Index(config.ConfigSpec.GlobalConfig.IndexerConfig.DefaultIndex, metadataInfo) + (*indexer).Index(configSpec.GlobalConfig.IndexerConfig.DefaultIndex, metadataInfo) return nil } diff --git a/pkg/config/config.go b/pkg/config/config.go index 85ca0e0c7..69a2bf1ce 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -38,7 +38,7 @@ import ( "k8s.io/client-go/tools/clientcmd" ) -var ConfigSpec Spec = Spec{ +var configSpec Spec = Spec{ GlobalConfig: GlobalConfig{ MetricsDirectory: "collected-metrics", RequestTimeout: 15 * time.Second, @@ -113,33 +113,33 @@ func (j *Job) UnmarshalYAML(unmarshal func(interface{}) error) error { } // Parse parses a configuration file -func Parse(c string, jobsRequired bool) error { +func Parse(c string, jobsRequired bool) (Spec, error) { f, err := util.ReadConfig(c) if err != nil { - return fmt.Errorf("Error reading configuration file %s: %s", c, err) + return configSpec, fmt.Errorf("Error reading configuration file %s: %s", c, err) } cfg, err := io.ReadAll(f) if err != nil { - return fmt.Errorf("Error reading configuration file %s: %s", c, err) + return configSpec, fmt.Errorf("Error reading configuration file %s: %s", c, err) } renderedCfg, err := renderConfig(cfg) if err != nil { - return err + return configSpec, err } cfgReader := bytes.NewReader(renderedCfg) yamlDec := yaml.NewDecoder(cfgReader) yamlDec.KnownFields(true) - if err = yamlDec.Decode(&ConfigSpec); err != nil { - return fmt.Errorf("Error decoding configuration file %s: %s", c, err) + if err = yamlDec.Decode(&configSpec); err != nil { + return configSpec, fmt.Errorf("Error decoding configuration file %s: %s", c, err) } if jobsRequired { - if len(ConfigSpec.Jobs) <= 0 { - return fmt.Errorf("No jobs found in the configuration file") + if len(configSpec.Jobs) <= 0 { + return configSpec, fmt.Errorf("No jobs found in the configuration file") } if err := validateDNS1123(); err != nil { - return err + return configSpec, err } - for _, job := range ConfigSpec.Jobs { + for _, job := range configSpec.Jobs { if len(job.Namespace) > 62 { log.Warnf("Namespace %s length has > 63 characters, truncating it", job.Namespace) job.Namespace = job.Namespace[:57] @@ -149,7 +149,7 @@ func Parse(c string, jobsRequired bool) error { } } } - return nil + return configSpec, nil } // FetchConfigMap Fetchs the specified configmap and looks for config.yml, metrics.yml and alerts.yml files @@ -187,7 +187,7 @@ func FetchConfigMap(configMap, namespace string) (string, string, error) { } func validateDNS1123() error { - for _, job := range ConfigSpec.Jobs { + for _, job := range configSpec.Jobs { if errs := validation.IsDNS1123Subdomain(job.Name); len(errs) > 0 { return fmt.Errorf("Job %s name validation error: %s", job.Name, fmt.Sprint(errs)) } @@ -215,7 +215,7 @@ func GetClientSet(QPS float32, burst int) (*kubernetes.Clientset, *rest.Config, return &kubernetes.Clientset{}, restConfig, err } restConfig.QPS, restConfig.Burst = QPS, burst - restConfig.Timeout = ConfigSpec.GlobalConfig.RequestTimeout + restConfig.Timeout = configSpec.GlobalConfig.RequestTimeout return kubernetes.NewForConfigOrDie(restConfig), restConfig, nil } diff --git a/pkg/config/types.go b/pkg/config/types.go index c420854a9..96e03c34c 100644 --- a/pkg/config/types.go +++ b/pkg/config/types.go @@ -71,6 +71,12 @@ type GlobalConfig struct { Measurements []mtypes.Measurement `yaml:"measurements"` // RequestTimeout of restclient RequestTimeout time.Duration `yaml:"requestTimeout"` + // PrometheusURL to interact with + PrometheusURL string `yaml:"prometheusURL"` + // BearerToken used to access prometheus + BearerToken string `yaml:"bearerToken"` + // MetricsProfile is the path to the metrics profile configuration + MetricsProfile string `yaml:"metricsProfile"` } // Object defines an object that kube-burner will create diff --git a/pkg/indexers/elastic.go b/pkg/indexers/elastic.go index 5ac3dffb9..6012e4ad7 100644 --- a/pkg/indexers/elastic.go +++ b/pkg/indexers/elastic.go @@ -45,8 +45,8 @@ func init() { indexerMap[elastic] = &Elastic{} } -func (esIndexer *Elastic) new() error { - esConfig := config.ConfigSpec.GlobalConfig.IndexerConfig +func (esIndexer *Elastic) new(configSpec config.Spec) error { + esConfig := configSpec.GlobalConfig.IndexerConfig cfg := elasticsearch.Config{ Addresses: esConfig.ESServers, Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: esConfig.InsecureSkipVerify}}, diff --git a/pkg/indexers/factory.go b/pkg/indexers/factory.go index 646e359f0..b7da200f8 100644 --- a/pkg/indexers/factory.go +++ b/pkg/indexers/factory.go @@ -22,19 +22,19 @@ import ( // Indexer indexer interface type Indexer interface { Index(string, []interface{}) - new() error + new(config.Spec) error } var indexerMap = make(map[string]Indexer) // NewIndexer creates a new Indexer with the specified IndexerConfig -func NewIndexer() (*Indexer, error) { +func NewIndexer(configSpec config.Spec) (*Indexer, error) { var indexer Indexer var exists bool - cfg := config.ConfigSpec.GlobalConfig.IndexerConfig + cfg := configSpec.GlobalConfig.IndexerConfig if indexer, exists = indexerMap[cfg.Type]; exists { log.Infof("📁 Creating indexer: %s", cfg.Type) - err := indexer.new() + err := indexer.new(configSpec) if err != nil { return &indexer, err } diff --git a/pkg/measurements/factory.go b/pkg/measurements/factory.go index 30624057f..62d3b08d7 100644 --- a/pkg/measurements/factory.go +++ b/pkg/measurements/factory.go @@ -43,10 +43,11 @@ type measurement interface { var factory measurementFactory var measurementMap = make(map[string]measurement) -var kubeburnerCfg *config.GlobalConfig = &config.ConfigSpec.GlobalConfig +var kubeburnerCfg *config.GlobalConfig // NewMeasurementFactory initializes the measurement facture -func NewMeasurementFactory(restConfig *rest.Config, uuid string, indexer *indexers.Indexer) { +func NewMeasurementFactory(configSpec config.Spec, restConfig *rest.Config, uuid string, indexer *indexers.Indexer) { + kubeburnerCfg = &configSpec.GlobalConfig log.Info("📈 Creating measurement factory") clientSet := kubernetes.NewForConfigOrDie(restConfig) factory = measurementFactory{ diff --git a/pkg/prometheus/prometheus.go b/pkg/prometheus/prometheus.go index 2e9aa6e46..3d5e211e4 100644 --- a/pkg/prometheus/prometheus.go +++ b/pkg/prometheus/prometheus.go @@ -48,10 +48,11 @@ func (bat authTransport) RoundTrip(req *http.Request) (*http.Response, error) { } // NewPrometheusClient creates a prometheus struct instance with the given parameters -func NewPrometheusClient(url, token, username, password, uuid string, tlsVerify bool, step time.Duration) (*Prometheus, error) { +func NewPrometheusClient(configSpec config.Spec, url, token, username, password, uuid string, tlsVerify bool, step time.Duration) (*Prometheus, error) { var p Prometheus = Prometheus{ - Step: step, - uuid: uuid, + Step: step, + uuid: uuid, + configSpec: configSpec, } log.Info("👽 Initializing prometheus client") @@ -149,14 +150,14 @@ func (p *Prometheus) ScrapeJobsMetrics(jobList []burner.Executor, indexer *index continue } } - if config.ConfigSpec.GlobalConfig.WriteToFile { + if p.configSpec.GlobalConfig.WriteToFile { filename := fmt.Sprintf("%s-%s.json", md.MetricName, p.uuid) - if config.ConfigSpec.GlobalConfig.MetricsDirectory != "" { - err = os.MkdirAll(config.ConfigSpec.GlobalConfig.MetricsDirectory, 0744) + if p.configSpec.GlobalConfig.MetricsDirectory != "" { + err = os.MkdirAll(p.configSpec.GlobalConfig.MetricsDirectory, 0744) if err != nil { return fmt.Errorf("Error creating metrics directory: %v: ", err) } - filename = path.Join(config.ConfigSpec.GlobalConfig.MetricsDirectory, filename) + filename = path.Join(p.configSpec.GlobalConfig.MetricsDirectory, filename) } log.Debugf("Writing to: %s", filename) f, err := os.Create(filename) @@ -171,8 +172,8 @@ func (p *Prometheus) ScrapeJobsMetrics(jobList []burner.Executor, indexer *index log.Errorf("JSON encoding error: %s", err) } } - if config.ConfigSpec.GlobalConfig.IndexerConfig.Enabled { - indexName := config.ConfigSpec.GlobalConfig.IndexerConfig.DefaultIndex + if p.configSpec.GlobalConfig.IndexerConfig.Enabled { + indexName := p.configSpec.GlobalConfig.IndexerConfig.DefaultIndex if md.IndexName != "" { indexName = strings.ToLower(md.IndexName) } diff --git a/pkg/prometheus/types.go b/pkg/prometheus/types.go index baf4bbdc3..5fc454ef7 100644 --- a/pkg/prometheus/types.go +++ b/pkg/prometheus/types.go @@ -18,6 +18,7 @@ import ( "net/http" "time" + "github.com/cloud-bulldozer/kube-burner/pkg/config" apiv1 "github.com/prometheus/client_golang/api/prometheus/v1" ) @@ -27,6 +28,7 @@ type Prometheus struct { MetricProfile metricProfile Step time.Duration uuid string + configSpec config.Spec } // This object implements RoundTripper