Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into HEAD
Browse files Browse the repository at this point in the history
# Conflicts:
#	go.sum
#	internal/replay.go
  • Loading branch information
piotrkazulak committed Dec 6, 2024
2 parents 7dd9487 + ea7646e commit e8f7815
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ GOLANGCI_LINT_VERSION := v1.62.2
# renovate datasource=go depName=golang.org/x/vuln/cmd/govulncheck
GOVULNCHECK_VERSION := v1.1.3
# renovate datasource=go depName=golang.org/x/tools/cmd/goimports
GOIMPORTS_VERSION := v0.27.0
GOIMPORTS_VERSION := v0.28.0

# Check if the program is present in $PATH and install otherwise.
# ${1} - oneOf{binary,yarn}
Expand Down
1 change: 1 addition & 0 deletions cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ words:
- slos
- svcs
- tpng
- unmarshalling
- vuln
- vulns
- wrapf
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/schollz/progressbar/v3 v3.17.1
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.10.0
golang.org/x/sync v0.9.0
golang.org/x/sync v0.10.0
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
Expand Down
1 change: 1 addition & 0 deletions internal/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func (a ApplyCmd) runReplay(cmd *cobra.Command, objects []manifest.Object) error
return nil
}
replayCmd := ReplayCmd{client: a.client}
replayCmd.arePlaylistEnabled(cmd.Context())
replays := make([]ReplayConfig, 0, len(slos))
for _, slo := range slos {
replays = append(replays, ReplayConfig{
Expand Down
60 changes: 38 additions & 22 deletions internal/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ import (
)

type ReplayCmd struct {
client *sdk.Client
from flags.TimeValue
configPaths []string
sloName string
project string
deleteAll bool
client *sdk.Client
from flags.TimeValue
configPaths []string
sloName string
project string
deleteAll bool
playlistsAvailable bool
}

//go:embed replay_example.sh
Expand Down Expand Up @@ -79,6 +80,7 @@ func (r *ReplayCmd) Run(cmd *cobra.Command) error {
if r.client.Config.Project == "*" {
return errProjectWildcardIsNotAllowed
}
r.arePlaylistEnabled(cmd.Context())
replays, err := r.prepareConfigs()
if err != nil {
return err
Expand All @@ -92,9 +94,7 @@ func (r *ReplayCmd) RunReplays(cmd *cobra.Command, replays []ReplayConfig) (fail
return 0, err
}

arePlaylistEnabled := r.arePlaylistEnabled(cmd.Context())

if arePlaylistEnabled {
if r.playlistsAvailable {
cmd.Println(colorstring.Color("[yellow]- Your organization has access to Replay queues!"))
cmd.Println(colorstring.Color("[yellow]- To learn more about Replay queues, follow this link: " +
"https://docs.nobl9.com/replay-canary/ [reset]"))
Expand All @@ -107,7 +107,7 @@ func (r *ReplayCmd) RunReplays(cmd *cobra.Command, replays []ReplayConfig) (fail
i+1, len(replays), replay.SLO, replay.Project,
replay.From.Format(flags.TimeLayout), time.Now().In(replay.From.Location()).Format(flags.TimeLayout))))

if arePlaylistEnabled {
if r.playlistsAvailable {
cmd.Println("Replay is added to the queue...")
err = r.runReplay(cmd.Context(), replay)

Expand Down Expand Up @@ -137,7 +137,12 @@ func (r *ReplayCmd) RunReplays(cmd *cobra.Command, replays []ReplayConfig) (fail
return len(failedIndexes), nil
}

func (r *ReplayCmd) arePlaylistEnabled(ctx context.Context) bool {
type PlaylistConfiguration struct {
EnabledPlaylists bool `json:"enabledPlaylists"`
}

func (r *ReplayCmd) arePlaylistEnabled(ctx context.Context) {
r.playlistsAvailable = true
data, _, err := r.doRequest(
ctx,
http.MethodGet,
Expand All @@ -146,17 +151,13 @@ func (r *ReplayCmd) arePlaylistEnabled(ctx context.Context) bool {
nil,
nil)
if err != nil {
return true
fmt.Printf("error checking playlist availability: %v\n", err)
}
var pc PlaylistConfiguration
if err = json.Unmarshal(data, &pc); err != nil {
return true
fmt.Printf("error unmarshalling playlist configuration: %v\n", err)
}
return pc.EnabledPlaylists
}

type PlaylistConfiguration struct {
EnabledPlaylists bool `json:"enabledPlaylists"`
r.playlistsAvailable = pc.EnabledPlaylists
}

type ReplayConfig struct {
Expand Down Expand Up @@ -325,16 +326,28 @@ outer:
}

// Check Replay availability.
if err := r.checkReplayAvailability(ctx, replays); err != nil {
return err
}

return nil
}

func (r *ReplayCmd) checkReplayAvailability(ctx context.Context, replays []ReplayConfig) error {
notAvailable := make([]string, 0)
mu := sync.Mutex{}
eg, ctx := errgroup.WithContext(ctx)
eg.SetLimit(10)

for i := range replays {
eg.Go(func() error {
c := replays[i]
timeNow := time.Now()
tt := c.ToReplay(timeNow)
offset := i * int(averageReplayDuration.Minutes())
offset := 0
if !r.playlistsAvailable {
offset = i * int(averageReplayDuration.Minutes())
}
expectedDuration := offset + tt.Duration.Value
av, err := r.getReplayAvailability(ctx, c, tt.Duration.Unit, expectedDuration)
if err != nil {
Expand All @@ -343,6 +356,7 @@ outer:
}
if !av.Available {
mu.Lock()
defer mu.Unlock()
notAvailable = append(notAvailable,
fmt.Sprintf("['%s' SLO in '%s' Project] %s",
c.SLO, c.Project, r.replayUnavailabilityReasonExplanation(
Expand All @@ -351,18 +365,20 @@ outer:
time.Duration(expectedDuration)*time.Minute,
time.Duration(offset)*time.Minute,
timeNow)))
mu.Unlock()
}
return nil
})
}
if err = eg.Wait(); err != nil {

if err := eg.Wait(); err != nil {
return err
}

if len(notAvailable) > 0 {
return errors.Errorf("The following SLOs are not available for Replay: \n - %s",
strings.Join(notAvailable, "\n - "))
}

return nil
}

Expand Down Expand Up @@ -522,7 +538,7 @@ func (r *ReplayCmd) replayUnavailabilityReasonExplanation(
" + %dm (start offset to ensure Replay covers the desired time window) %s."+
" Edit the Data Source and run Replay once again.",
replay.metricSource.Name, replay.metricSource.Project, expectedDuration.String(),
timeNow.Format(flags.TimeLayout), r.from.Format(flags.TimeLayout), startOffsetMinutes, offsetNotice)
timeNow.Format(flags.TimeLayout), replay.From.Format(flags.TimeLayout), startOffsetMinutes, offsetNotice)
case sdkModels.ReplayConcurrentReplayRunsLimitExhausted:
return "You've exceeded the limit of concurrent Replay runs. Wait until the current Replay(s) are done."
case sdkModels.ReplayUnknownAgentVersion:
Expand Down

0 comments on commit e8f7815

Please sign in to comment.