diff --git a/pkg/apis/provisioning/v0alpha1/register.go b/pkg/apis/provisioning/v0alpha1/register.go index 68870ad9609..37cd02251b6 100644 --- a/pkg/apis/provisioning/v0alpha1/register.go +++ b/pkg/apis/provisioning/v0alpha1/register.go @@ -5,11 +5,11 @@ import ( "fmt" "time" - "github.com/grafana/grafana/pkg/apimachinery/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/klog/v2" + + "github.com/grafana/grafana/pkg/apimachinery/utils" ) const ( @@ -26,7 +26,7 @@ var RepositoryResourceInfo = utils.NewResourceInfo(GROUP, VERSION, Definition: []metav1.TableColumnDefinition{ {Name: "Name", Type: "string", Format: "name"}, {Name: "Created At", Type: "date"}, - // TODO: Add more here when we figure out the model... + {Name: "Title", Type: "string"}, {Name: "Type", Type: "string"}, {Name: "Target", Type: "string"}, }, @@ -36,28 +36,21 @@ var RepositoryResourceInfo = utils.NewResourceInfo(GROUP, VERSION, return nil, errors.New("expected Repository") } - var typ, target string - // TODO: Can probably make this prettier. Function on Repository maybe? - if !m.Spec.GitHub.IsEmpty() { - typ = "github" - // TODO: Enterprise GH?? - target = fmt.Sprintf("%s/%s", m.Spec.GitHub.Owner, m.Spec.GitHub.Repository) - } else if !m.Spec.Local.IsEmpty() { - typ = "local" + var target string + switch m.Spec.Type { + case LocalRepositoryType: target = m.Spec.Local.Path - } else if !m.Spec.S3.IsEmpty() { - typ = "s3" - // TODO: Can bucket URLs include sensitive info? + case S3RepositoryType: target = m.Spec.S3.Bucket - } else { - klog.InfoS("we have a repository with no known tabular converter", - "name", m.Name, "namespace", m.Namespace) + case GithubRepositoryType: + target = fmt.Sprintf("%s/%s", m.Spec.GitHub.Owner, m.Spec.GitHub.Repository) } return []interface{}{ - m.Name, + m.Name, // may our may not be nice to read m.CreationTimestamp.UTC().Format(time.RFC3339), - typ, + m.Spec.Title, // explicitly configured title that can change + m.Spec.Type, target, }, nil }, diff --git a/pkg/apis/provisioning/v0alpha1/types.go b/pkg/apis/provisioning/v0alpha1/types.go index d6b2e9204fa..0092e6bbe35 100644 --- a/pkg/apis/provisioning/v0alpha1/types.go +++ b/pkg/apis/provisioning/v0alpha1/types.go @@ -1,10 +1,6 @@ package v0alpha1 import ( - "encoding/json" - "errors" - "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -16,15 +12,12 @@ type Repository struct { Spec RepositorySpec `json:"spec,omitempty"` } -type LocalRepository struct { +type LocalRepositoryConfig struct { Path string `json:"path,omitempty"` } -func (r *LocalRepository) IsEmpty() bool { - return r == nil || r.Path == "" -} - -type S3Repository struct { +type S3RepositoryConfig struct { + Region string `json:"region,omitempty"` Bucket string `json:"bucket,omitempty"` // TODO: Add ACL? @@ -32,11 +25,7 @@ type S3Repository struct { // TODO: How do we define access? Secrets? } -func (r *S3Repository) IsEmpty() bool { - return r == nil || r.Bucket == "" -} - -type GitHubRepository struct { +type GitHubRepositoryConfig struct { // The owner of the repository (e.g. example in `example/test` or `https://github.com/example/test`). Owner string `json:"owner,omitempty"` // The name of the repository (e.g. test in `example/test` or `https://github.com/example/test`). @@ -56,50 +45,43 @@ type GitHubRepository struct { GenerateDashboardPreviews bool `json:"generateDashboardPreviews,omitempty"` } -func (r *GitHubRepository) IsEmpty() bool { - // we don't need to check options here, just the most important stuff to actually connect. - return r == nil || r.Owner == "" || r.Repository == "" -} +// RepositoryType defines the types of Repository +// +enum +type RepositoryType string + +// RepositoryType values +const ( + LocalRepositoryType RepositoryType = "local" + S3RepositoryType RepositoryType = "s3" + GithubRepositoryType RepositoryType = "github" +) type RepositorySpec struct { + // Describe the feature toggle + Title string `json:"title"` + + // Describe the feature toggle + Description string `json:"description,omitempty"` + // The folder that is backed by the repository. // The value is a reference to the Kubernetes metadata name of the folder in the same namespace. Folder string `json:"folder,omitempty"` + // The repository type. When selected oneOf the values below should be non-nil + Type RepositoryType `json:"type"` + // The repository on the local file system. // Mutually exclusive with s3 and github. - Local LocalRepository `json:"local,omitempty"` + Local *LocalRepositoryConfig `json:"local,omitempty"` + // The repository in an S3 bucket. // Mutually exclusive with local and github. - S3 S3Repository `json:"s3,omitempty"` + S3 *S3RepositoryConfig `json:"s3,omitempty"` + // The repository on GitHub. // Mutually exclusive with local and s3. // TODO: github or just 'git'?? - GitHub GitHubRepository `json:"github,omitempty"` -} - -func (s *RepositorySpec) UnmarshalJSON(data []byte) error { - type Alias RepositorySpec - real := struct { - *Alias `json:",inline"` - }{(*Alias)(s)} - - if err := json.Unmarshal(data, &real); err != nil { - return err - } - - nonEmpty := 0 - type IsEmptyer interface{ IsEmpty() bool } - for _, it := range []IsEmptyer{&real.GitHub, &real.S3, &real.Local} { - if !it.IsEmpty() { - nonEmpty++ - } - } - if nonEmpty != 1 { - return fmt.Errorf("%w (found %d)", errors.New("one (and exactly one) of github, s3, and local must be set"), nonEmpty) - } - - return nil + GitHub *GitHubRepositoryConfig `json:"github,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go b/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go index 38f7efd93f0..d5b5e5c69b7 100644 --- a/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go @@ -12,17 +12,17 @@ import ( ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GitHubRepository) DeepCopyInto(out *GitHubRepository) { +func (in *GitHubRepositoryConfig) DeepCopyInto(out *GitHubRepositoryConfig) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitHubRepository. -func (in *GitHubRepository) DeepCopy() *GitHubRepository { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitHubRepositoryConfig. +func (in *GitHubRepositoryConfig) DeepCopy() *GitHubRepositoryConfig { if in == nil { return nil } - out := new(GitHubRepository) + out := new(GitHubRepositoryConfig) in.DeepCopyInto(out) return out } @@ -53,17 +53,17 @@ func (in *HelloWorld) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LocalRepository) DeepCopyInto(out *LocalRepository) { +func (in *LocalRepositoryConfig) DeepCopyInto(out *LocalRepositoryConfig) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalRepository. -func (in *LocalRepository) DeepCopy() *LocalRepository { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalRepositoryConfig. +func (in *LocalRepositoryConfig) DeepCopy() *LocalRepositoryConfig { if in == nil { return nil } - out := new(LocalRepository) + out := new(LocalRepositoryConfig) in.DeepCopyInto(out) return out } @@ -73,7 +73,7 @@ func (in *Repository) DeepCopyInto(out *Repository) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) return } @@ -131,9 +131,21 @@ func (in *RepositoryList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) { *out = *in - out.Local = in.Local - out.S3 = in.S3 - out.GitHub = in.GitHub + if in.Local != nil { + in, out := &in.Local, &out.Local + *out = new(LocalRepositoryConfig) + **out = **in + } + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(S3RepositoryConfig) + **out = **in + } + if in.GitHub != nil { + in, out := &in.GitHub, &out.GitHub + *out = new(GitHubRepositoryConfig) + **out = **in + } return } @@ -148,17 +160,17 @@ func (in *RepositorySpec) DeepCopy() *RepositorySpec { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *S3Repository) DeepCopyInto(out *S3Repository) { +func (in *S3RepositoryConfig) DeepCopyInto(out *S3RepositoryConfig) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Repository. -func (in *S3Repository) DeepCopy() *S3Repository { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3RepositoryConfig. +func (in *S3RepositoryConfig) DeepCopy() *S3RepositoryConfig { if in == nil { return nil } - out := new(S3Repository) + out := new(S3RepositoryConfig) in.DeepCopyInto(out) return out } diff --git a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go index 3b7a45c47f1..3d90456db1d 100644 --- a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go +++ b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go @@ -14,17 +14,17 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepository": schema_pkg_apis_provisioning_v0alpha1_GitHubRepository(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HelloWorld": schema_pkg_apis_provisioning_v0alpha1_HelloWorld(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepository": schema_pkg_apis_provisioning_v0alpha1_LocalRepository(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Repository": schema_pkg_apis_provisioning_v0alpha1_Repository(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositoryList": schema_pkg_apis_provisioning_v0alpha1_RepositoryList(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositorySpec": schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref), - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3Repository": schema_pkg_apis_provisioning_v0alpha1_S3Repository(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HelloWorld": schema_pkg_apis_provisioning_v0alpha1_HelloWorld(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_LocalRepositoryConfig(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Repository": schema_pkg_apis_provisioning_v0alpha1_Repository(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositoryList": schema_pkg_apis_provisioning_v0alpha1_RepositoryList(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositorySpec": schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3RepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_S3RepositoryConfig(ref), } } -func schema_pkg_apis_provisioning_v0alpha1_GitHubRepository(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -96,7 +96,7 @@ func schema_pkg_apis_provisioning_v0alpha1_HelloWorld(ref common.ReferenceCallba } } -func schema_pkg_apis_provisioning_v0alpha1_LocalRepository(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_provisioning_v0alpha1_LocalRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -142,7 +142,8 @@ func schema_pkg_apis_provisioning_v0alpha1_Repository(ref common.ReferenceCallba }, "spec": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositorySpec"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.RepositorySpec"), }, }, }, @@ -206,6 +207,21 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref common.ReferenceCa SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Description: "Describe the feature toggle", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Describe the feature toggle", + Type: []string{"string"}, + Format: "", + }, + }, "folder": { SchemaProps: spec.SchemaProps{ Description: "The folder that is backed by the repository. The value is a reference to the Kubernetes metadata name of the folder in the same namespace.", @@ -213,41 +229,54 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref common.ReferenceCa Format: "", }, }, + "type": { + SchemaProps: spec.SchemaProps{ + Description: "The repository type. When selected oneOf the values below should be non-nil\n\nPossible enum values:\n - `\"github\"`\n - `\"local\"`\n - `\"s3\"`", + Default: "", + Type: []string{"string"}, + Format: "", + Enum: []interface{}{"github", "local", "s3"}, + }, + }, "local": { SchemaProps: spec.SchemaProps{ Description: "The repository on the local file system. Mutually exclusive with s3 and github.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepository"), + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig"), }, }, "s3": { SchemaProps: spec.SchemaProps{ Description: "The repository in an S3 bucket. Mutually exclusive with local and github.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3Repository"), + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3RepositoryConfig"), }, }, "github": { SchemaProps: spec.SchemaProps{ Description: "The repository on GitHub. Mutually exclusive with local and s3.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepository"), + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig"), }, }, }, + Required: []string{"title", "type"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepository", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepository", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3Repository"}, + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.S3RepositoryConfig"}, } } -func schema_pkg_apis_provisioning_v0alpha1_S3Repository(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_provisioning_v0alpha1_S3RepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ + "region": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, "bucket": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, diff --git a/pkg/registry/apis/provisioning/hello.go b/pkg/registry/apis/provisioning/hello.go index a3831f33869..842fd90e975 100644 --- a/pkg/registry/apis/provisioning/hello.go +++ b/pkg/registry/apis/provisioning/hello.go @@ -2,14 +2,19 @@ package provisioning import ( "context" + "fmt" "net/http" - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" + + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" ) -type helloWorldSubresource struct{} +type helloWorldSubresource struct { + getter rest.Getter +} func (*helloWorldSubresource) New() runtime.Object { // This is added as the "ResponseType" regardless what ProducesObject() returns @@ -42,13 +47,27 @@ func (*helloWorldSubresource) NewConnectOptions() (runtime.Object, bool, string) return nil, false, "" } -func (*helloWorldSubresource) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { +func (s *helloWorldSubresource) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { + obj, err := s.getter.Get(ctx, name, &v1.GetOptions{}) + if err != nil { + return nil, err + } + repo, ok := obj.(*v0alpha1.Repository) + if !ok { + return nil, fmt.Errorf("expected repository, but got %t", obj) + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { whom := r.URL.Query().Get("whom") if whom == "" { whom = "World" } + fmt.Printf("GOT: %s/%s\n", repo.Name, repo.Spec.Type) + fmt.Printf(" local: %+v\n", repo.Spec.Local) + fmt.Printf(" github: %+v\n", repo.Spec.GitHub) + fmt.Printf(" s3: %+v\n", repo.Spec.S3) + responder.Object(http.StatusOK, &v0alpha1.HelloWorld{Whom: whom}) }), nil } diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 4cbfa4c6cf4..d1a1fff1c53 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -3,10 +3,6 @@ package provisioning import ( "fmt" - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" - grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" - "github.com/grafana/grafana/pkg/services/apiserver/builder" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/prometheus/client_golang/prometheus" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -16,6 +12,11 @@ import ( "k8s.io/kube-openapi/pkg/common" "k8s.io/kube-openapi/pkg/spec3" "k8s.io/kube-openapi/pkg/validation/spec" + + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" + grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + "github.com/grafana/grafana/pkg/services/apiserver/builder" + "github.com/grafana/grafana/pkg/services/featuremgmt" ) var _ builder.APIGroupBuilder = (*ProvisioningAPIBuilder)(nil) @@ -70,7 +71,9 @@ func (b *ProvisioningAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserv return fmt.Errorf("failed to create repository storage: %w", err) } - helloWorld := &helloWorldSubresource{} + helloWorld := &helloWorldSubresource{ + getter: repositoryStorage, + } storage := map[string]rest.Storage{} storage[v0alpha1.RepositoryResourceInfo.StoragePath()] = repositoryStorage diff --git a/pkg/tests/apis/provisioning/provisioning_test.go b/pkg/tests/apis/provisioning/provisioning_test.go index 099af8429d4..89c4c12d1c9 100644 --- a/pkg/tests/apis/provisioning/provisioning_test.go +++ b/pkg/tests/apis/provisioning/provisioning_test.go @@ -40,7 +40,7 @@ func TestIntegrationProvisioning(t *testing.T) { v1Disco, err := json.MarshalIndent(resources, "", " ") require.NoError(t, err) - //fmt.Printf("%s", string(v1Disco)) + // fmt.Printf("%s", string(v1Disco)) require.JSONEq(t, `{ "kind": "APIResourceList", "apiVersion": "v1", @@ -85,23 +85,65 @@ func TestIntegrationProvisioning(t *testing.T) { }, }) createOptions := metav1.CreateOptions{FieldValidation: "Strict"} - r0, err := client.Resource.Create(ctx, + + // Load the samples + _, err := client.Resource.Create(ctx, helper.LoadYAMLOrJSONFile("testdata/local-devenv.yaml"), createOptions, ) + require.NoError(t, err) - require.NoError(t, err) - require.Equal(t, "devenv", r0.GetName()) - r1, err := client.Resource.Get(ctx, "devenv", metav1.GetOptions{}) - require.NoError(t, err) - require.Equal(t, - mustNestedString(r0.Object, "spec", "local", "path"), - mustNestedString(r1.Object, "spec", "local", "path"), + _, err = client.Resource.Create(ctx, + helper.LoadYAMLOrJSONFile("testdata/github-example.yaml"), + createOptions, ) - require.Equal(t, - "path/to/folder", // - mustNestedString(r1.Object, "spec", "local", "path"), + require.NoError(t, err) + + _, err = client.Resource.Create(ctx, + helper.LoadYAMLOrJSONFile("testdata/s3-example.yaml"), + createOptions, ) + require.NoError(t, err) + + samples, err := client.Resource.List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + found := map[string]any{} + for _, v := range samples.Items { + found[v.GetName()] = v.Object["spec"] + } + + js, _ := json.MarshalIndent(found, "", " ") + // fmt.Printf("%s", string(js)) + require.JSONEq(t, `{ + "github-example": { + "description": "load resources from github", + "github": { + "branchWorkflow": true, + "generateDashboardPreviews": true, + "owner": "grafana", + "repository": "git-ui-sync-demo" + }, + "title": "Github Example", + "type": "github" + }, + "local-devenv": { + "description": "load resources from grafana/grafana devenv folder", + "local": { + "path": "path/to/folder" + }, + "title": "Local devenv files", + "type": "local" + }, + "s3-example": { + "description": "load resources from an S3 bucket", + "s3": { + "bucket": "my-bucket", + "region": "us-west-1" + }, + "title": "S3 Example", + "type": "s3" + } + }`, string(js)) }) t.Run("basic helloworld subresource", func(t *testing.T) { @@ -115,7 +157,19 @@ func TestIntegrationProvisioning(t *testing.T) { }, }) + // Add it if this is the only test that ran + _, err := client.Resource.Update(ctx, + helper.LoadYAMLOrJSONFile("testdata/local-devenv.yaml"), + metav1.UpdateOptions{}, + ) + require.NoError(t, err) + + // "test" is Not found resp, err := client.Resource.Get(ctx, "test", metav1.GetOptions{}, "hello") + require.Error(t, err) // "test" not found + require.Nil(t, resp) // "test" not found + + resp, err = client.Resource.Get(ctx, "local-devenv", metav1.GetOptions{}, "hello") require.NoError(t, err) require.Equal(t, "World", diff --git a/pkg/tests/apis/provisioning/testdata/github-example.yaml b/pkg/tests/apis/provisioning/testdata/github-example.yaml new file mode 100644 index 00000000000..58aaba35a2f --- /dev/null +++ b/pkg/tests/apis/provisioning/testdata/github-example.yaml @@ -0,0 +1,13 @@ +apiVersion: provisioning.grafana.app/v0alpha1 +kind: Repository +metadata: + name: github-example +spec: + title: Github Example + description: load resources from github + type: github + github: + owner: grafana + repository: git-ui-sync-demo + branchWorkflow: true + generateDashboardPreviews: true \ No newline at end of file diff --git a/pkg/tests/apis/provisioning/testdata/local-devenv.yaml b/pkg/tests/apis/provisioning/testdata/local-devenv.yaml index 8a9c3c382be..02a896886a0 100644 --- a/pkg/tests/apis/provisioning/testdata/local-devenv.yaml +++ b/pkg/tests/apis/provisioning/testdata/local-devenv.yaml @@ -1,13 +1,10 @@ apiVersion: provisioning.grafana.app/v0alpha1 kind: Repository metadata: - name: devenv # anything is ok here... except yes or true -- they become boolean! + name: local-devenv spec: - # title: Local devenv - # description: files from devenv - folder: abc # do we create a file with k8s name abc??? - - # provider: local - + title: Local devenv files + description: load resources from grafana/grafana devenv folder + type: local local: path: path/to/folder diff --git a/pkg/tests/apis/provisioning/testdata/s3-example.yaml b/pkg/tests/apis/provisioning/testdata/s3-example.yaml new file mode 100644 index 00000000000..64dea4f61e4 --- /dev/null +++ b/pkg/tests/apis/provisioning/testdata/s3-example.yaml @@ -0,0 +1,11 @@ +apiVersion: provisioning.grafana.app/v0alpha1 +kind: Repository +metadata: + name: s3-example +spec: + title: S3 Example + description: load resources from an S3 bucket + type: s3 + s3: + region: us-west-1 + bucket: my-bucket