Skip to content

Commit

Permalink
Basic validation for all resources
Browse files Browse the repository at this point in the history
  • Loading branch information
malcolmholmes committed Feb 7, 2024
1 parent b5149b5 commit 470b9ad
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 21 deletions.
3 changes: 0 additions & 3 deletions pkg/grafana/dashboard-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ func (h *DashboardHandler) Prepare(existing, resource grizzly.Resource) *grizzly
// Validate returns the uid of resource
func (h *DashboardHandler) Validate(resource grizzly.Resource) error {
uid, exist := resource.GetSpecString("uid")
if resource.Name() == "" {
return fmt.Errorf("name cannot be blank")
}
if resource.Name() != uid && exist {
return fmt.Errorf("uid '%s' and name '%s', don't match", uid, resource.Name())
}
Expand Down
46 changes: 30 additions & 16 deletions pkg/grafana/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,56 +83,70 @@ func TestDashboard(t *testing.T) {
_ = os.Unsetenv("GRAFANA_URL")

t.Run("Validate/Prepare", func(t *testing.T) {
grizzly.ConfigureProviderRegistry(
[]grizzly.Provider{
NewProvider(),
})

handler := DashboardHandler{}
tests := []struct {
Name string
Kind string
Resource grizzly.Resource
ValidateErrorString string
ExpectedUID string
}{
{
Name: "name and UID match",
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "name1", map[string]any{"uid": "name1"}),
ValidateErrorString: "",
ExpectedUID: "name1",
},
{
Name: "no UID provided",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "name1", map[string]any{}),
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "name1", map[string]any{"title": "something"}),
ValidateErrorString: "",
ExpectedUID: "name1",
},
{
Name: "name and UID differ",
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "name1", map[string]any{"uid": "name2"}),
ValidateErrorString: "uid 'name2' and name 'name1', don't match",
},
{
Name: "no name provided",
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "", map[string]any{"uid": "name1"}),
ValidateErrorString: "name cannot be blank",
ValidateErrorString: "Resource lacks name",
},
{
Name: "no spec provided",
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "name1", map[string]any{}),
ValidateErrorString: "Resource name1 lacks spec",
},
{
Name: "neither name nor UID provided",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "", map[string]any{}),
ValidateErrorString: "name cannot be blank",
Kind: "Dashboard",
Resource: grizzly.NewResource("apiVersion", "Dashboard", "", map[string]any{"title": "something"}),
ValidateErrorString: "Resource lacks name",
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
err := handler.Validate(test.Resource)
if err != nil {
if test.ValidateErrorString == "" {
require.NoError(t, err)
} else {
require.Contains(t, err.Error(), test.ValidateErrorString)
}
} else {
require.NoError(t, err)
newResource := handler.Prepare(nil, test.Resource)
uid, _ := handler.GetUID(*newResource)
require.Equal(t, uid, test.ExpectedUID)
err := test.Resource.Validate()
if test.ValidateErrorString != "" {
require.Error(t, err)
require.Contains(t, err.Error(), test.ValidateErrorString)
return
}
require.NoError(t, err)
newResource := handler.Prepare(nil, test.Resource)
uid, _ := handler.GetUID(*newResource)
require.Equal(t, uid, test.ExpectedUID)
})
}
})
Expand Down
31 changes: 31 additions & 0 deletions pkg/grizzly/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package grizzly
import (
"encoding/json"
"fmt"
"log"
"strings"

"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -82,6 +84,9 @@ func (r *Resource) HasMetadata(key string) bool {

func (r *Resource) GetMetadata(key string) string {
metadata := (*r)["metadata"].(map[string]interface{})
if _, ok := metadata[key]; !ok {
return ""
}
return metadata[key].(string)
}

Expand Down Expand Up @@ -153,6 +158,32 @@ func (r *Resource) JSON() (string, error) {
return string(j), nil
}

func (r *Resource) Validate() error {
handler, err := Registry.GetHandler(r.Kind())
if err != nil {
return err
}
missing := []string{}
if r.Name() == "" {
missing = append(missing, "name")
}
if r.Spec() == nil || len(r.Spec()) == 0 {
missing = append(missing, "spec")
}
jj, _ := r.JSON()

log.Printf("KIND: '%s' NAME: '%s' SPEC(%d)", r.Kind(), r.Name(), len(jj))
if len(missing) > 0 {
if r.Name() != "" {
return fmt.Errorf("Resource %s lacks %s", r.Name(), strings.Join(missing, ", "))
} else {
j, _ := r.JSON()
return fmt.Errorf("Resource lacks %s: %s", strings.Join(missing, ", "), j)
}
}
return handler.Validate(*r)
}

// Resources represents a set of resources
type Resources []Resource

Expand Down
3 changes: 1 addition & 2 deletions pkg/grizzly/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ func Apply(resources Resources) error {
if err != nil {
return err
}

err = handler.Validate(resource)
err = resource.Validate()
if err != nil {
return fmt.Errorf("resource %s is not valid: %v", resource.Key(), err)
}
Expand Down

0 comments on commit 470b9ad

Please sign in to comment.