Skip to content

Commit

Permalink
Deprecate --directory/-d flag in favor of os.Stat (#259)
Browse files Browse the repository at this point in the history
* Deprecate --directory/-d flag in favor of os.Stat

* Add tests for grizzly.Pull
  • Loading branch information
joanlopez authored Oct 13, 2023
1 parent c023732 commit 39a906d
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 19 deletions.
4 changes: 4 additions & 0 deletions cmd/grr/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,13 @@ func providersCmd() *cli.Command {
}

func initialiseCmd(cmd *cli.Command, opts *grizzly.Opts) *cli.Command {
// Keep the old flags for backwards compatibility
cmd.Flags().BoolVarP(&opts.Directory, "directory", "d", false, "treat resource path as a directory")
cmd.Flags().MarkDeprecated("directory", "now it is inferred from the operating system")

cmd.Flags().StringSliceVarP(&opts.Targets, "target", "t", nil, "resources to target")
cmd.Flags().StringSliceVarP(&opts.JsonnetPaths, "jpath", "J", getDefaultJsonnetFolders(), "Specify an additional library search dir (right-most wins)")

return initialiseLogging(cmd, &opts.LoggingOpts)
}

Expand Down
4 changes: 2 additions & 2 deletions docs/content/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Grafana instances. To pull dashboards and folders from one instance to another
is as simple as:
```
$ export GRAFANA_URL=<...source Grafana URL...>
$ grr pull -d resources -t "Dashboard/*" -t "DashboardFolder/*"
$ grr pull resources -t "Dashboard/*" -t "DashboardFolder/*"
```
This asks Grizzly to pull all resources matching the `<kind>/<UID>` pattern for
dashboards and folders into a directory called `resources`.
Expand All @@ -28,7 +28,7 @@ dashboards and folders into a directory called `resources`.
To push them to a new Grafana instance:
```
$ export GRAFANA_URL=<...destination Grafana URL...>
$ grr apply -d resources
$ grr apply resources
```

## Jsonnet
Expand Down
5 changes: 3 additions & 2 deletions pkg/grafana/dashboards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ import (
"testing"

"github.com/grafana/grizzly/pkg/grizzly"
. "github.com/grafana/grizzly/pkg/internal/testutil"
"github.com/stretchr/testify/require"
)

func TestDashboard(t *testing.T) {
os.Setenv("GRAFANA_URL", getUrl())
os.Setenv("GRAFANA_URL", GetUrl())

grizzly.ConfigureProviderRegistry(
[]grizzly.Provider{
&Provider{},
})

ticker := pingService(getUrl())
ticker := PingService(GetUrl())
defer ticker.Stop()

t.Run("get remote dashboard - success", func(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions pkg/grafana/datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ import (
"testing"

"github.com/grafana/grizzly/pkg/grizzly"
. "github.com/grafana/grizzly/pkg/internal/testutil"
"github.com/stretchr/testify/require"
)

func TestDatasources(t *testing.T) {
os.Setenv("GRAFANA_URL", getUrl())
os.Setenv("GRAFANA_URL", GetUrl())

grizzly.ConfigureProviderRegistry(
[]grizzly.Provider{
&Provider{},
})

ticker := pingService(getUrl())
ticker := PingService(GetUrl())
defer ticker.Stop()

t.Run("get remote datasource - success", func(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions pkg/grafana/folders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"testing"

"github.com/grafana/grizzly/pkg/grizzly"
. "github.com/grafana/grizzly/pkg/internal/testutil"
"github.com/stretchr/testify/require"
)

func TestFolders(t *testing.T) {
os.Setenv("GRAFANA_URL", getUrl())
os.Setenv("GRAFANA_URL", GetUrl())

ticker := pingService(getUrl())
ticker := PingService(GetUrl())
defer ticker.Stop()

t.Run("get remote folder - success", func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ deleteDatasources:
orgId: 1

datasources:
- name: AppDynamics
- uid: 392IktgGk
name: AppDynamics
type: dlopes7-appdynamics-datasource
access: proxy
basicAuth: true
Expand Down
2 changes: 1 addition & 1 deletion pkg/grizzly/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type LoggingOpts struct {
// Opts contains options for most Grizzly commands
type Opts struct {
LoggingOpts
Directory bool
Directory bool // Deprecated: now is gathered with os.Stat(<resource-path>)
JsonnetPaths []string
Targets []string
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/grizzly/parsing.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,29 @@ import (
)

func Parse(resourcePath string, opts Opts) (Resources, error) {
if !(opts.Directory) {
stat, err := os.Stat(resourcePath)
if err != nil {
return nil, err
}

if !stat.IsDir() {
return ParseFile(opts, resourcePath)
}

var resources Resources
files, err := FindResourceFiles(resourcePath)
if err != nil {
return nil, err
}

for _, file := range files {
r, err := ParseFile(opts, file)
if err != nil {
return nil, err
}
resources = append(resources, r...)
}

return resources, nil
}

Expand Down
26 changes: 22 additions & 4 deletions pkg/grizzly/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,20 @@ func ListRemote(opts Opts) error {
return w.Flush()
}

// Pulls remote resources
// Pull pulls remote resources and stores them in the local file system.
// The given resourcePath must be a directory, where all resources will be stored.
func Pull(resourcePath string, opts Opts) error {
log.Infof("Pulling resources from %s", resourcePath)
isFile, err := isFile(resourcePath)
if err != nil {
return err
}

if !(opts.Directory) {
return fmt.Errorf("pull only works with -d option")
if isFile {
return fmt.Errorf("pull <resource-path> must be a directory")
}

log.Infof("Pulling resources to %s", resourcePath)

for name, handler := range Registry.Handlers {
if !Registry.HandlerMatchesTarget(handler, opts.Targets) {
notifier.Info(notifier.SimpleString(handler.Kind()), "skipped")
Expand Down Expand Up @@ -456,3 +462,15 @@ func Export(exportDir string, resources Resources) error {
}
return nil
}

func isFile(resourcePath string) (bool, error) {
stat, err := os.Stat(resourcePath)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

return !stat.IsDir(), nil
}
70 changes: 70 additions & 0 deletions pkg/grizzly/workflow_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package grizzly_test

import (
"os"
"path/filepath"
"testing"

"github.com/grafana/grizzly/pkg/grafana"
"github.com/grafana/grizzly/pkg/grizzly"
. "github.com/grafana/grizzly/pkg/internal/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestPull(t *testing.T) {
os.Setenv("GRAFANA_URL", GetUrl())

grizzly.ConfigureProviderRegistry(
[]grizzly.Provider{
&grafana.Provider{},
})

ticker := PingService(GetUrl())
defer ticker.Stop()

opts := grizzly.Opts{
Targets: []string{
"Datasource/392IktgGk",
},
}

t.Run("with existing file", func(t *testing.T) {
t.Parallel()

path := filepath.Join(t.TempDir(), filepath.Base(t.Name()))
f, err := os.Create(path)
require.NoError(t, err)
require.NoError(t, f.Close())

err = grizzly.Pull(path, opts)
assert.Error(t, err)
assert.ErrorContains(t, err, "pull <resource-path> must be a directory")
})

t.Run("with existing folder", func(t *testing.T) {
t.Parallel()

path := filepath.Join(t.TempDir(), filepath.Base(t.Name()))
err := os.MkdirAll(path, 0755)
require.NoError(t, err)

err = grizzly.Pull(path, opts)
assert.NoError(t, err)
assert.Equal(t, 1, numOfFiles(path))
})

t.Run("with non-existing folder", func(t *testing.T) {
t.Parallel()

path := filepath.Join(t.TempDir(), filepath.Base(t.Name()))
err := grizzly.Pull(path, opts)
assert.NoError(t, err)
assert.Equal(t, 1, numOfFiles(path))
})
}

func numOfFiles(path string) int {
files, _ := os.ReadDir(path)
return len(files)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package grafana
package testutil

import (
"fmt"
Expand All @@ -7,23 +7,23 @@ import (
"time"
)

func getUrl() string {
func GetUrl() string {
if os.Getenv("CI") != "" {
return "http://grizzly-grafana:3000/"
} else {
return "http://localhost:3000/"
}
}

func pingService(url string) *time.Ticker {
func PingService(url string) *time.Ticker {
ticker := time.NewTicker(1 * time.Second)
timeoutExceeded := time.After(120 * time.Second)

success := false
for !success {
select {
case <-timeoutExceeded:
panic("Unable to connect to grizzly-grafana:3000")
panic(fmt.Sprintf("Unable to connect to %s", url))

case <-ticker.C:
resp, _ := http.Get(url)
Expand Down

0 comments on commit 39a906d

Please sign in to comment.