Skip to content

Commit

Permalink
Merge pull request slok#439 from slok/slok/refactor-cmd-gen
Browse files Browse the repository at this point in the history
  • Loading branch information
slok authored Nov 26, 2022
2 parents 2fbc8ed + 3a86cb4 commit 128115f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 38 deletions.
84 changes: 49 additions & 35 deletions cmd/sloth/commands/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ func (g generateCommand) Run(ctx context.Context, config RootConfig) error {
}
}

gen := generator{
logger: logger,
windowsRepo: windowsRepo,
disableRecordings: g.disableRecordings,
disableAlerts: g.disableAlerts,
disableOptimizedRules: g.disableOptimizedRules,
extraLabels: g.extraLabels,
}

for _, genTarget := range genTargets {
dataB := []byte(genTarget.SLOData)

Expand All @@ -249,7 +258,7 @@ func (g generateCommand) Run(ctx context.Context, config RootConfig) error {
return fmt.Errorf("tried loading raw prometheus SLOs spec, it couldn't: %w", err)
}

err = generatePrometheus(ctx, logger, windowsRepo, g.disableRecordings, g.disableAlerts, g.disableOptimizedRules, g.extraLabels, *slos, genTarget.Out)
err = gen.GeneratePrometheus(ctx, *slos, genTarget.Out)
if err != nil {
return fmt.Errorf("could not generate Prometheus format rules: %w", err)
}
Expand All @@ -260,7 +269,7 @@ func (g generateCommand) Run(ctx context.Context, config RootConfig) error {
return fmt.Errorf("tried loading Kubernetes prometheus SLOs spec, it couldn't: %w", err)
}

err = generateKubernetes(ctx, logger, windowsRepo, g.disableRecordings, g.disableAlerts, g.disableOptimizedRules, g.extraLabels, *sloGroup, genTarget.Out)
err = gen.GenerateKubernetes(ctx, *sloGroup, genTarget.Out)
if err != nil {
return fmt.Errorf("could not generate Kubernetes format rules: %w", err)
}
Expand All @@ -271,7 +280,7 @@ func (g generateCommand) Run(ctx context.Context, config RootConfig) error {
return fmt.Errorf("tried loading OpenSLO SLOs spec, it couldn't: %w", err)
}

err = generateOpenSLO(ctx, logger, windowsRepo, g.disableRecordings, g.disableAlerts, g.disableOptimizedRules, g.extraLabels, *slos, genTarget.Out)
err = gen.GenerateOpenSLO(ctx, *slos, genTarget.Out)
if err != nil {
return fmt.Errorf("could not generate OpenSLO format rules: %w", err)
}
Expand All @@ -284,22 +293,35 @@ func (g generateCommand) Run(ctx context.Context, config RootConfig) error {
return nil
}

// generatePrometheus generates the SLOs based on a raw regular Prometheus spec format input and
// outs a Prometheus raw yaml.
func generatePrometheus(ctx context.Context, logger log.Logger, windowsRepo alert.WindowsRepo, disableRecs, disableAlerts, disableOptimizedRules bool, extraLabels map[string]string, slos prometheus.SLOGroup, out io.Writer) error {
logger.Infof("Generating from Prometheus spec")
type generateTarget struct {
Out io.Writer
SLOData string
}

type generator struct {
logger log.Logger
windowsRepo alert.WindowsRepo
disableRecordings bool
disableAlerts bool
disableOptimizedRules bool
extraLabels map[string]string
}

// GeneratePrometheus generates the SLOs based on a raw regular Prometheus spec format input and outs a Prometheus raw yaml.
func (g generator) GeneratePrometheus(ctx context.Context, slos prometheus.SLOGroup, out io.Writer) error {
g.logger.Infof("Generating from Prometheus spec")
info := info.Info{
Version: info.Version,
Mode: info.ModeCLIGenPrometheus,
Spec: prometheusv1.Version,
}

result, err := generateRules(ctx, logger, info, windowsRepo, disableRecs, disableAlerts, disableOptimizedRules, extraLabels, slos)
result, err := g.generateRules(ctx, info, slos)
if err != nil {
return err
}

repo := prometheus.NewIOWriterGroupedRulesYAMLRepo(out, logger)
repo := prometheus.NewIOWriterGroupedRulesYAMLRepo(out, g.logger)
storageSLOs := make([]prometheus.StorageSLO, 0, len(result.PrometheusSLOs))
for _, s := range result.PrometheusSLOs {
storageSLOs = append(storageSLOs, prometheus.StorageSLO{
Expand All @@ -316,22 +338,21 @@ func generatePrometheus(ctx context.Context, logger log.Logger, windowsRepo aler
return nil
}

// generateKubernetes generates the SLOs based on a Kuberentes spec format input and
// outs a Kubernetes prometheus operator CRD yaml.
func generateKubernetes(ctx context.Context, logger log.Logger, windowsRepo alert.WindowsRepo, disableRecs, disableAlerts, disableOptimizedRules bool, extraLabels map[string]string, sloGroup k8sprometheus.SLOGroup, out io.Writer) error {
logger.Infof("Generating from Kubernetes Prometheus spec")
// generateKubernetes generates the SLOs based on a Kuberentes spec format input and outs a Kubernetes prometheus operator CRD yaml.
func (g generator) GenerateKubernetes(ctx context.Context, sloGroup k8sprometheus.SLOGroup, out io.Writer) error {
g.logger.Infof("Generating from Kubernetes Prometheus spec")

info := info.Info{
Version: info.Version,
Mode: info.ModeCLIGenKubernetes,
Spec: fmt.Sprintf("%s/%s", kubernetesv1.SchemeGroupVersion.Group, kubernetesv1.SchemeGroupVersion.Version),
}
result, err := generateRules(ctx, logger, info, windowsRepo, disableRecs, disableAlerts, disableOptimizedRules, extraLabels, sloGroup.SLOGroup)
result, err := g.generateRules(ctx, info, sloGroup.SLOGroup)
if err != nil {
return err
}

repo := k8sprometheus.NewIOWriterPrometheusOperatorYAMLRepo(out, logger)
repo := k8sprometheus.NewIOWriterPrometheusOperatorYAMLRepo(out, g.logger)
storageSLOs := make([]k8sprometheus.StorageSLO, 0, len(result.PrometheusSLOs))
for _, s := range result.PrometheusSLOs {
storageSLOs = append(storageSLOs, k8sprometheus.StorageSLO{
Expand All @@ -348,22 +369,21 @@ func generateKubernetes(ctx context.Context, logger log.Logger, windowsRepo aler
return nil
}

// generateOpenSLO generates the SLOs based on a OpenSLO spec format input and
// outs a Prometheus raw yaml.
func generateOpenSLO(ctx context.Context, logger log.Logger, windowsRepo alert.WindowsRepo, disableRecs, disableAlerts, disableOptimizedRules bool, extraLabels map[string]string, slos prometheus.SLOGroup, out io.Writer) error {
logger.Infof("Generating from OpenSLO spec")
// generateOpenSLO generates the SLOs based on a OpenSLO spec format input and outs a Prometheus raw yaml.
func (g generator) GenerateOpenSLO(ctx context.Context, slos prometheus.SLOGroup, out io.Writer) error {
g.logger.Infof("Generating from OpenSLO spec")
info := info.Info{
Version: info.Version,
Mode: info.ModeCLIGenOpenSLO,
Spec: openslov1alpha.APIVersion,
}

result, err := generateRules(ctx, logger, info, windowsRepo, disableRecs, disableAlerts, disableOptimizedRules, extraLabels, slos)
result, err := g.generateRules(ctx, info, slos)
if err != nil {
return err
}

repo := prometheus.NewIOWriterGroupedRulesYAMLRepo(out, logger)
repo := prometheus.NewIOWriterGroupedRulesYAMLRepo(out, g.logger)
storageSLOs := make([]prometheus.StorageSLO, 0, len(result.PrometheusSLOs))
for _, s := range result.PrometheusSLOs {
storageSLOs = append(storageSLOs, prometheus.StorageSLO{
Expand All @@ -380,41 +400,40 @@ func generateOpenSLO(ctx context.Context, logger log.Logger, windowsRepo alert.W
return nil
}

// generate is the main generator logic that all the spec types and storers share. Mainly
// has the logic of the generate app service.
func generateRules(ctx context.Context, logger log.Logger, info info.Info, windowsRepo alert.WindowsRepo, disableRecs, disableAlerts, disableOptimizedRules bool, extraLabels map[string]string, slos prometheus.SLOGroup) (*generate.Response, error) {
// generate is the main generator logic that all the spec types and storers share. Mainly has the logic of the generate app service.
func (g generator) generateRules(ctx context.Context, info info.Info, slos prometheus.SLOGroup) (*generate.Response, error) {
// Disable recording rules if required.
var sliRuleGen generate.SLIRecordingRulesGenerator = generate.NoopSLIRecordingRulesGenerator
var metaRuleGen generate.MetadataRecordingRulesGenerator = generate.NoopMetadataRecordingRulesGenerator
if !disableRecs {
if !g.disableRecordings {
// Disable optimized rules if required.
sliRuleGen = prometheus.OptimizedSLIRecordingRulesGenerator
if disableOptimizedRules {
if g.disableOptimizedRules {
sliRuleGen = prometheus.SLIRecordingRulesGenerator
}
metaRuleGen = prometheus.MetadataRecordingRulesGenerator
}

// Disable alert rules if required.
var alertRuleGen generate.SLOAlertRulesGenerator = generate.NoopSLOAlertRulesGenerator
if !disableAlerts {
if !g.disableAlerts {
alertRuleGen = prometheus.SLOAlertRulesGenerator
}

// Generate.
controller, err := generate.NewService(generate.ServiceConfig{
AlertGenerator: alert.NewGenerator(windowsRepo),
AlertGenerator: alert.NewGenerator(g.windowsRepo),
SLIRecordingRulesGenerator: sliRuleGen,
MetaRecordingRulesGenerator: metaRuleGen,
SLOAlertRulesGenerator: alertRuleGen,
Logger: logger,
Logger: g.logger,
})
if err != nil {
return nil, fmt.Errorf("could not create application service: %w", err)
}

result, err := controller.Generate(ctx, generate.Request{
ExtraLabels: extraLabels,
ExtraLabels: g.extraLabels,
Info: info,
SLOGroup: slos,
})
Expand All @@ -424,8 +443,3 @@ func generateRules(ctx context.Context, logger log.Logger, info info.Info, windo

return result, nil
}

type generateTarget struct {
Out io.Writer
SLOData string
}
12 changes: 9 additions & 3 deletions cmd/sloth/commands/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ func (v validateCommand) Run(ctx context.Context, config RootConfig) error {
// Split YAMLs in case we have multiple yaml files in a single file.
splittedSLOsData := splitYAML(slxData)

gen := generator{
logger: log.Noop,
windowsRepo: windowsRepo,
extraLabels: v.extraLabels,
}

// Prepare file validation result and start validation result for every SLO in the file.
// TODO(slok): Add service meta to validation.
validation := &fileValidation{File: input}
Expand All @@ -138,7 +144,7 @@ func (v validateCommand) Run(ctx context.Context, config RootConfig) error {
case promYAMLLoader.IsSpecType(ctx, dataB):
slos, promErr := promYAMLLoader.LoadSpec(ctx, dataB)
if promErr == nil {
err := generatePrometheus(ctx, log.Noop, windowsRepo, false, false, false, v.extraLabels, *slos, io.Discard)
err := gen.GeneratePrometheus(ctx, *slos, io.Discard)
if err != nil {
validation.Errs = []error{fmt.Errorf("Could not generate Prometheus format rules: %w", err)}
}
Expand All @@ -150,7 +156,7 @@ func (v validateCommand) Run(ctx context.Context, config RootConfig) error {
case kubeYAMLLoader.IsSpecType(ctx, dataB):
sloGroup, k8sErr := kubeYAMLLoader.LoadSpec(ctx, dataB)
if k8sErr == nil {
err := generateKubernetes(ctx, log.Noop, windowsRepo, false, false, false, v.extraLabels, *sloGroup, io.Discard)
err := gen.GenerateKubernetes(ctx, *sloGroup, io.Discard)
if err != nil {
validation.Errs = []error{fmt.Errorf("could not generate Kubernetes format rules: %w", err)}
}
Expand All @@ -162,7 +168,7 @@ func (v validateCommand) Run(ctx context.Context, config RootConfig) error {
case openSLOYAMLLoader.IsSpecType(ctx, dataB):
slos, openSLOErr := openSLOYAMLLoader.LoadSpec(ctx, dataB)
if openSLOErr == nil {
err := generateOpenSLO(ctx, log.Noop, windowsRepo, false, false, false, v.extraLabels, *slos, io.Discard)
err := gen.GenerateOpenSLO(ctx, *slos, io.Discard)
if err != nil {
validation.Errs = []error{fmt.Errorf("Could not generate OpenSLO format rules: %w", err)}
}
Expand Down

0 comments on commit 128115f

Please sign in to comment.