Provisioning: Return available repository types in settings endpoint (#107977)
Actionlint / Lint GitHub Actions files (push) Waiting to run Details
Backend Code Checks / Validate Backend Configs (push) Waiting to run Details
Backend Unit Tests / Detect whether code changed (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (1/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (2/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (3/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (4/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (5/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (6/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (7/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (8/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (1/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (2/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (3/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (4/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (5/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (6/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (7/8) (push) Blocked by required conditions Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (8/8) (push) Blocked by required conditions Details
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions Details
CodeQL checks / Analyze (actions) (push) Waiting to run Details
CodeQL checks / Analyze (go) (push) Waiting to run Details
CodeQL checks / Analyze (javascript) (push) Waiting to run Details
Lint Frontend / Detect whether code changed (push) Waiting to run Details
Lint Frontend / Lint (push) Blocked by required conditions Details
Lint Frontend / Typecheck (push) Blocked by required conditions Details
Lint Frontend / Betterer (push) Blocked by required conditions Details
Verify i18n / verify-i18n (push) Waiting to run Details
End-to-end tests / Detect whether code changed (push) Waiting to run Details
End-to-end tests / Build & Package Grafana (push) Blocked by required conditions Details
End-to-end tests / Build E2E test runner (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/dashboards-suite, dashboards-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/panels-suite, panels-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/smoke-tests-suite, smoke-tests-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/various-suite, various-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/dashboards-suite, dashboards-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/panels-suite, panels-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/smoke-tests-suite, smoke-tests-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/various-suite, various-suite) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (1, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (2, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (3, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (4, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (5, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (6, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (7, 8) (push) Blocked by required conditions Details
End-to-end tests / Playwright E2E tests (${{ matrix.shard }}/${{ matrix.shardTotal }}) (8, 8) (push) Blocked by required conditions Details
End-to-end tests / All Playwright tests complete (push) Blocked by required conditions Details
End-to-end tests / A11y test (push) Blocked by required conditions Details
End-to-end tests / All E2E tests complete (push) Blocked by required conditions Details
Frontend tests / Detect whether code changed (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (1) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (2) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (3) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (4) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (5) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (6) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (7) (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (8) (push) Blocked by required conditions Details
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions Details
Integration Tests / Sqlite (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / All backend integration tests complete (push) Blocked by required conditions Details
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run Details
Build Release Packages / setup (push) Waiting to run Details
Build Release Packages / Dispatch grafana-enterprise build (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/amd64, darwin-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/arm64, darwin-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/amd64,deb:grafana:linux/amd64,rpm:grafana:linux/amd64,docker:grafana:linux/amd64,docker:grafana:linux/amd64:ubuntu,npm:grafana,storybook, linux-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v6,deb:grafana:linux/arm/v6, linux-armv6) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v7,deb:grafana:linux/arm/v7,docker:grafana:linux/arm/v7,docker:grafana:linux/arm/v7:ubuntu, linux-armv7) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm64,deb:grafana:linux/arm64,rpm:grafana:linux/arm64,docker:grafana:linux/arm64,docker:grafana:linux/arm64:ubuntu, linux-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/s390x,deb:grafana:linux/s390x,rpm:grafana:linux/s390x,docker:grafana:linux/s390x,docker:grafana:linux/s390x:ubuntu, linux-s390x) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/amd64,zip:grafana:windows/amd64,msi:grafana:windows/amd64, windows-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/arm64,zip:grafana:windows/arm64, windows-arm64) (push) Blocked by required conditions Details
Build Release Packages / Upload artifacts (push) Blocked by required conditions Details
Run dashboard schema v2 e2e / dashboard-schema-v2-e2e (push) Waiting to run Details
Shellcheck / Shellcheck scripts (push) Waiting to run Details
Swagger generated code / Verify committed API specs match (push) Waiting to run Details
Dispatch sync to mirror / dispatch-job (push) Waiting to run Details
golangci-lint / lint-go (push) Has been cancelled Details
Documentation / Build & Verify Docs (push) Has been cancelled Details
publish-technical-documentation-next / sync (push) Has been cancelled Details
trigger-dashboard-search-e2e / trigger-search-e2e (push) Has been cancelled Details
Trivy Scan / trivy-scan (push) Has been cancelled Details

* Add types for other repositories

* Inject the types from extras

* Fix go-lint

* Fix typecheck

* Add it to the tests

---------

Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com>
This commit is contained in:
Roberto Jiménez Sánchez 2025-07-12 00:07:04 +02:00 committed by GitHub
parent eab8c1db07
commit b49b103f42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 653 additions and 69 deletions

View File

@ -43,6 +43,10 @@ var RepositoryResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
target = m.Spec.GitHub.URL target = m.Spec.GitHub.URL
case GitRepositoryType: case GitRepositoryType:
target = m.Spec.Git.URL target = m.Spec.Git.URL
case BitbucketRepositoryType:
target = m.Spec.Bitbucket.URL
case GitLabRepositoryType:
target = m.Spec.GitLab.URL
} }
return []interface{}{ return []interface{}{

View File

@ -14,6 +14,9 @@ type RepositoryViewList struct {
// The UI should force the onboarding workflow when this is true // The UI should force the onboarding workflow when this is true
LegacyStorage bool `json:"legacyStorage,omitempty"` LegacyStorage bool `json:"legacyStorage,omitempty"`
// AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc)
AvailableRepositoryTypes []RepositoryType `json:"availableRepositoryTypes,omitempty"`
// +mapType=atomic // +mapType=atomic
Items []RepositoryView `json:"items"` Items []RepositoryView `json:"items"`
} }

View File

@ -77,6 +77,42 @@ type GitRepositoryConfig struct {
Path string `json:"path,omitempty"` Path string `json:"path,omitempty"`
} }
type BitbucketRepositoryConfig struct {
// The repository URL (e.g. `https://bitbucket.org/example/test`).
URL string `json:"url,omitempty"`
// The branch to use in the repository.
Branch string `json:"branch"`
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
Token string `json:"token,omitempty"`
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
// +listType=atomic
EncryptedToken []byte `json:"encryptedToken,omitempty"`
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
// This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed.
// The path is relative to the root of the repository, regardless of the leading slash.
//
// When specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.
Path string `json:"path,omitempty"`
}
type GitLabRepositoryConfig struct {
// The repository URL (e.g. `https://gitlab.com/example/test`).
URL string `json:"url,omitempty"`
// The branch to use in the repository.
Branch string `json:"branch"`
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
Token string `json:"token,omitempty"`
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
// +listType=atomic
EncryptedToken []byte `json:"encryptedToken,omitempty"`
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
// This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed.
// The path is relative to the root of the repository, regardless of the leading slash.
//
// When specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.
Path string `json:"path,omitempty"`
}
// RepositoryType defines the types of Repository // RepositoryType defines the types of Repository
// +enum // +enum
type RepositoryType string type RepositoryType string
@ -86,11 +122,13 @@ const (
LocalRepositoryType RepositoryType = "local" LocalRepositoryType RepositoryType = "local"
GitHubRepositoryType RepositoryType = "github" GitHubRepositoryType RepositoryType = "github"
GitRepositoryType RepositoryType = "git" GitRepositoryType RepositoryType = "git"
BitbucketRepositoryType RepositoryType = "bitbucket"
GitLabRepositoryType RepositoryType = "gitlab"
) )
// IsGit returns true if the repository type is git or github // IsGit returns true if the repository type is git or github
func (r RepositoryType) IsGit() bool { func (r RepositoryType) IsGit() bool {
return r == GitRepositoryType || r == GitHubRepositoryType return r == GitRepositoryType || r == GitHubRepositoryType || r == BitbucketRepositoryType || r == GitLabRepositoryType
} }
type RepositorySpec struct { type RepositorySpec struct {
@ -122,6 +160,14 @@ type RepositorySpec struct {
// The repository on Git. // The repository on Git.
// Mutually exclusive with local | github | git. // Mutually exclusive with local | github | git.
Git *GitRepositoryConfig `json:"git,omitempty"` Git *GitRepositoryConfig `json:"git,omitempty"`
// The repository on Bitbucket.
// Mutually exclusive with local | github | git.
Bitbucket *BitbucketRepositoryConfig `json:"bitbucket,omitempty"`
// The repository on GitLab.
// Mutually exclusive with local | github | git.
GitLab *GitLabRepositoryConfig `json:"gitlab,omitempty"`
} }
// SyncTargetType defines where we want all values to resolve // SyncTargetType defines where we want all values to resolve

View File

@ -22,6 +22,16 @@ func TestRepositoryType_IsGit(t *testing.T) {
repoType: v0alpha1.GitHubRepositoryType, repoType: v0alpha1.GitHubRepositoryType,
want: true, want: true,
}, },
{
name: "bitbucket",
repoType: v0alpha1.BitbucketRepositoryType,
want: true,
},
{
name: "gitlab",
repoType: v0alpha1.GitLabRepositoryType,
want: true,
},
{ {
name: "local", name: "local",
repoType: v0alpha1.LocalRepositoryType, repoType: v0alpha1.LocalRepositoryType,

View File

@ -27,6 +27,27 @@ func (in *Author) DeepCopy() *Author {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BitbucketRepositoryConfig) DeepCopyInto(out *BitbucketRepositoryConfig) {
*out = *in
if in.EncryptedToken != nil {
in, out := &in.EncryptedToken, &out.EncryptedToken
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BitbucketRepositoryConfig.
func (in *BitbucketRepositoryConfig) DeepCopy() *BitbucketRepositoryConfig {
if in == nil {
return nil
}
out := new(BitbucketRepositoryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ErrorDetails) DeepCopyInto(out *ErrorDetails) { func (in *ErrorDetails) DeepCopyInto(out *ErrorDetails) {
*out = *in *out = *in
@ -127,6 +148,27 @@ func (in *GitHubRepositoryConfig) DeepCopy() *GitHubRepositoryConfig {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitLabRepositoryConfig) DeepCopyInto(out *GitLabRepositoryConfig) {
*out = *in
if in.EncryptedToken != nil {
in, out := &in.EncryptedToken, &out.EncryptedToken
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitLabRepositoryConfig.
func (in *GitLabRepositoryConfig) DeepCopy() *GitLabRepositoryConfig {
if in == nil {
return nil
}
out := new(GitLabRepositoryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitRepositoryConfig) DeepCopyInto(out *GitRepositoryConfig) { func (in *GitRepositoryConfig) DeepCopyInto(out *GitRepositoryConfig) {
*out = *in *out = *in
@ -574,6 +616,16 @@ func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) {
*out = new(GitRepositoryConfig) *out = new(GitRepositoryConfig)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.Bitbucket != nil {
in, out := &in.Bitbucket, &out.Bitbucket
*out = new(BitbucketRepositoryConfig)
(*in).DeepCopyInto(*out)
}
if in.GitLab != nil {
in, out := &in.GitLab, &out.GitLab
*out = new(GitLabRepositoryConfig)
(*in).DeepCopyInto(*out)
}
return return
} }
@ -640,6 +692,11 @@ func (in *RepositoryView) DeepCopy() *RepositoryView {
func (in *RepositoryViewList) DeepCopyInto(out *RepositoryViewList) { func (in *RepositoryViewList) DeepCopyInto(out *RepositoryViewList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if in.AvailableRepositoryTypes != nil {
in, out := &in.AvailableRepositoryTypes, &out.AvailableRepositoryTypes
*out = make([]RepositoryType, len(*in))
copy(*out, *in)
}
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]RepositoryView, len(*in)) *out = make([]RepositoryView, len(*in))

View File

@ -15,11 +15,13 @@ import (
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{ return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Author": schema_pkg_apis_provisioning_v0alpha1_Author(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Author": schema_pkg_apis_provisioning_v0alpha1_Author(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ErrorDetails": schema_pkg_apis_provisioning_v0alpha1_ErrorDetails(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ErrorDetails": schema_pkg_apis_provisioning_v0alpha1_ErrorDetails(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ExportJobOptions": schema_pkg_apis_provisioning_v0alpha1_ExportJobOptions(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ExportJobOptions": schema_pkg_apis_provisioning_v0alpha1_ExportJobOptions(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.FileItem": schema_pkg_apis_provisioning_v0alpha1_FileItem(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.FileItem": schema_pkg_apis_provisioning_v0alpha1_FileItem(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.FileList": schema_pkg_apis_provisioning_v0alpha1_FileList(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.FileList": schema_pkg_apis_provisioning_v0alpha1_FileList(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.GitHubRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitLabRepositoryConfig(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HealthStatus": schema_pkg_apis_provisioning_v0alpha1_HealthStatus(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HealthStatus": schema_pkg_apis_provisioning_v0alpha1_HealthStatus(ref),
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HistoryItem": schema_pkg_apis_provisioning_v0alpha1_HistoryItem(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.HistoryItem": schema_pkg_apis_provisioning_v0alpha1_HistoryItem(ref),
@ -92,6 +94,60 @@ func schema_pkg_apis_provisioning_v0alpha1_Author(ref common.ReferenceCallback)
} }
} }
func schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"url": {
SchemaProps: spec.SchemaProps{
Description: "The repository URL (e.g. `https://bitbucket.org/example/test`).",
Type: []string{"string"},
Format: "",
},
},
"branch": {
SchemaProps: spec.SchemaProps{
Description: "The branch to use in the repository.",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"token": {
SchemaProps: spec.SchemaProps{
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
Type: []string{"string"},
Format: "",
},
},
"encryptedToken": {
VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{
"x-kubernetes-list-type": "atomic",
},
},
SchemaProps: spec.SchemaProps{
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
Type: []string{"string"},
Format: "byte",
},
},
"path": {
SchemaProps: spec.SchemaProps{
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"branch"},
},
},
}
}
func schema_pkg_apis_provisioning_v0alpha1_ErrorDetails(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_pkg_apis_provisioning_v0alpha1_ErrorDetails(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
@ -316,6 +372,60 @@ func schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref common.Ref
} }
} }
func schema_pkg_apis_provisioning_v0alpha1_GitLabRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"url": {
SchemaProps: spec.SchemaProps{
Description: "The repository URL (e.g. `https://gitlab.com/example/test`).",
Type: []string{"string"},
Format: "",
},
},
"branch": {
SchemaProps: spec.SchemaProps{
Description: "The branch to use in the repository.",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"token": {
SchemaProps: spec.SchemaProps{
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
Type: []string{"string"},
Format: "",
},
},
"encryptedToken": {
VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{
"x-kubernetes-list-type": "atomic",
},
},
SchemaProps: spec.SchemaProps{
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
Type: []string{"string"},
Format: "byte",
},
},
"path": {
SchemaProps: spec.SchemaProps{
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"branch"},
},
},
}
}
func schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { func schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{ return common.OpenAPIDefinition{
Schema: spec.Schema{ Schema: spec.Schema{
@ -1186,11 +1296,11 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref common.ReferenceCa
}, },
"type": { "type": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "The repository type. When selected oneOf the values below should be non-nil\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", Description: "The repository type. When selected oneOf the values below should be non-nil\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
Default: "", Default: "",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
Enum: []interface{}{"git", "github", "local"}, Enum: []interface{}{"bitbucket", "git", "github", "gitlab", "local"},
}, },
}, },
"local": { "local": {
@ -1211,12 +1321,24 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref common.ReferenceCa
Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig"), Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig"),
}, },
}, },
"bitbucket": {
SchemaProps: spec.SchemaProps{
Description: "The repository on Bitbucket. Mutually exclusive with local | github | git.",
Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig"),
},
},
"gitlab": {
SchemaProps: spec.SchemaProps{
Description: "The repository on GitLab. Mutually exclusive with local | github | git.",
Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig"),
},
},
}, },
Required: []string{"title", "workflows", "sync", "type"}, Required: []string{"title", "workflows", "sync", "type"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.SyncOptions"}, "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.SyncOptions"},
} }
} }
@ -1307,11 +1429,11 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositoryView(ref common.ReferenceCa
}, },
"type": { "type": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "The repository type\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", Description: "The repository type\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
Default: "", Default: "",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
Enum: []interface{}{"git", "github", "local"}, Enum: []interface{}{"bitbucket", "git", "github", "gitlab", "local"},
}, },
}, },
"target": { "target": {
@ -1381,6 +1503,22 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositoryViewList(ref common.Referen
Format: "", Format: "",
}, },
}, },
"availableRepositoryTypes": {
SchemaProps: spec.SchemaProps{
Description: "AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc)",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
Enum: []interface{}{"bitbucket", "git", "github", "gitlab", "local"},
},
},
},
},
},
"items": { "items": {
VendorExtensible: spec.VendorExtensible{ VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{ Extensions: spec.Extensions{
@ -1625,11 +1763,11 @@ func schema_pkg_apis_provisioning_v0alpha1_ResourceRepositoryInfo(ref common.Ref
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"type": { "type": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "The repository type\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", Description: "The repository type\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
Default: "", Default: "",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
Enum: []interface{}{"git", "github", "local"}, Enum: []interface{}{"bitbucket", "git", "github", "gitlab", "local"},
}, },
}, },
"title": { "title": {

View File

@ -8,6 +8,7 @@ API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provis
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryList,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryList,Items
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,Workflows API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,Workflows
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryView,Workflows API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryView,Workflows
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryViewList,AvailableRepositoryTypes
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryViewList,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryViewList,Items
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceList,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceList,Items
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,TestResults,Errors API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,TestResults,Errors
@ -15,6 +16,7 @@ API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provis
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobSpec,PullRequest API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobSpec,PullRequest
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ManagerStats,Identity API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ManagerStats,Identity
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,GitHub API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,GitHub
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,GitLab
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceWrapper,URLs API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceWrapper,URLs
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,SyncStatus,JobID API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,SyncStatus,JobID
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,WebhookResponse,Message API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,WebhookResponse,Message

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v0alpha1
// BitbucketRepositoryConfigApplyConfiguration represents a declarative configuration of the BitbucketRepositoryConfig type for use
// with apply.
type BitbucketRepositoryConfigApplyConfiguration struct {
URL *string `json:"url,omitempty"`
Branch *string `json:"branch,omitempty"`
Token *string `json:"token,omitempty"`
EncryptedToken []byte `json:"encryptedToken,omitempty"`
Path *string `json:"path,omitempty"`
}
// BitbucketRepositoryConfigApplyConfiguration constructs a declarative configuration of the BitbucketRepositoryConfig type for use with
// apply.
func BitbucketRepositoryConfig() *BitbucketRepositoryConfigApplyConfiguration {
return &BitbucketRepositoryConfigApplyConfiguration{}
}
// WithURL sets the URL field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the URL field is set to the value of the last call.
func (b *BitbucketRepositoryConfigApplyConfiguration) WithURL(value string) *BitbucketRepositoryConfigApplyConfiguration {
b.URL = &value
return b
}
// WithBranch sets the Branch field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Branch field is set to the value of the last call.
func (b *BitbucketRepositoryConfigApplyConfiguration) WithBranch(value string) *BitbucketRepositoryConfigApplyConfiguration {
b.Branch = &value
return b
}
// WithToken sets the Token field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Token field is set to the value of the last call.
func (b *BitbucketRepositoryConfigApplyConfiguration) WithToken(value string) *BitbucketRepositoryConfigApplyConfiguration {
b.Token = &value
return b
}
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
func (b *BitbucketRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *BitbucketRepositoryConfigApplyConfiguration {
for i := range values {
b.EncryptedToken = append(b.EncryptedToken, values[i])
}
return b
}
// WithPath sets the Path field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Path field is set to the value of the last call.
func (b *BitbucketRepositoryConfigApplyConfiguration) WithPath(value string) *BitbucketRepositoryConfigApplyConfiguration {
b.Path = &value
return b
}

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v0alpha1
// GitLabRepositoryConfigApplyConfiguration represents a declarative configuration of the GitLabRepositoryConfig type for use
// with apply.
type GitLabRepositoryConfigApplyConfiguration struct {
URL *string `json:"url,omitempty"`
Branch *string `json:"branch,omitempty"`
Token *string `json:"token,omitempty"`
EncryptedToken []byte `json:"encryptedToken,omitempty"`
Path *string `json:"path,omitempty"`
}
// GitLabRepositoryConfigApplyConfiguration constructs a declarative configuration of the GitLabRepositoryConfig type for use with
// apply.
func GitLabRepositoryConfig() *GitLabRepositoryConfigApplyConfiguration {
return &GitLabRepositoryConfigApplyConfiguration{}
}
// WithURL sets the URL field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the URL field is set to the value of the last call.
func (b *GitLabRepositoryConfigApplyConfiguration) WithURL(value string) *GitLabRepositoryConfigApplyConfiguration {
b.URL = &value
return b
}
// WithBranch sets the Branch field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Branch field is set to the value of the last call.
func (b *GitLabRepositoryConfigApplyConfiguration) WithBranch(value string) *GitLabRepositoryConfigApplyConfiguration {
b.Branch = &value
return b
}
// WithToken sets the Token field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Token field is set to the value of the last call.
func (b *GitLabRepositoryConfigApplyConfiguration) WithToken(value string) *GitLabRepositoryConfigApplyConfiguration {
b.Token = &value
return b
}
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
func (b *GitLabRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *GitLabRepositoryConfigApplyConfiguration {
for i := range values {
b.EncryptedToken = append(b.EncryptedToken, values[i])
}
return b
}
// WithPath sets the Path field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Path field is set to the value of the last call.
func (b *GitLabRepositoryConfigApplyConfiguration) WithPath(value string) *GitLabRepositoryConfigApplyConfiguration {
b.Path = &value
return b
}

View File

@ -19,6 +19,8 @@ type RepositorySpecApplyConfiguration struct {
Local *LocalRepositoryConfigApplyConfiguration `json:"local,omitempty"` Local *LocalRepositoryConfigApplyConfiguration `json:"local,omitempty"`
GitHub *GitHubRepositoryConfigApplyConfiguration `json:"github,omitempty"` GitHub *GitHubRepositoryConfigApplyConfiguration `json:"github,omitempty"`
Git *GitRepositoryConfigApplyConfiguration `json:"git,omitempty"` Git *GitRepositoryConfigApplyConfiguration `json:"git,omitempty"`
Bitbucket *BitbucketRepositoryConfigApplyConfiguration `json:"bitbucket,omitempty"`
GitLab *GitLabRepositoryConfigApplyConfiguration `json:"gitlab,omitempty"`
} }
// RepositorySpecApplyConfiguration constructs a declarative configuration of the RepositorySpec type for use with // RepositorySpecApplyConfiguration constructs a declarative configuration of the RepositorySpec type for use with
@ -92,3 +94,19 @@ func (b *RepositorySpecApplyConfiguration) WithGit(value *GitRepositoryConfigApp
b.Git = value b.Git = value
return b return b
} }
// WithBitbucket sets the Bitbucket field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Bitbucket field is set to the value of the last call.
func (b *RepositorySpecApplyConfiguration) WithBitbucket(value *BitbucketRepositoryConfigApplyConfiguration) *RepositorySpecApplyConfiguration {
b.Bitbucket = value
return b
}
// WithGitLab sets the GitLab field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the GitLab field is set to the value of the last call.
func (b *RepositorySpecApplyConfiguration) WithGitLab(value *GitLabRepositoryConfigApplyConfiguration) *RepositorySpecApplyConfiguration {
b.GitLab = value
return b
}

View File

@ -20,8 +20,12 @@ import (
func ForKind(kind schema.GroupVersionKind) interface{} { func ForKind(kind schema.GroupVersionKind) interface{} {
switch kind { switch kind {
// Group=provisioning.grafana.app, Version=v0alpha1 // Group=provisioning.grafana.app, Version=v0alpha1
case v0alpha1.SchemeGroupVersion.WithKind("BitbucketRepositoryConfig"):
return &provisioningv0alpha1.BitbucketRepositoryConfigApplyConfiguration{}
case v0alpha1.SchemeGroupVersion.WithKind("GitHubRepositoryConfig"): case v0alpha1.SchemeGroupVersion.WithKind("GitHubRepositoryConfig"):
return &provisioningv0alpha1.GitHubRepositoryConfigApplyConfiguration{} return &provisioningv0alpha1.GitHubRepositoryConfigApplyConfiguration{}
case v0alpha1.SchemeGroupVersion.WithKind("GitLabRepositoryConfig"):
return &provisioningv0alpha1.GitLabRepositoryConfigApplyConfiguration{}
case v0alpha1.SchemeGroupVersion.WithKind("GitRepositoryConfig"): case v0alpha1.SchemeGroupVersion.WithKind("GitRepositoryConfig"):
return &provisioningv0alpha1.GitRepositoryConfigApplyConfiguration{} return &provisioningv0alpha1.GitRepositoryConfigApplyConfiguration{}
case v0alpha1.SchemeGroupVersion.WithKind("HealthStatus"): case v0alpha1.SchemeGroupVersion.WithKind("HealthStatus"):

View File

@ -18,6 +18,7 @@ type Extra interface {
PostProcessOpenAPI(oas *spec3.OpenAPI) error PostProcessOpenAPI(oas *spec3.OpenAPI) error
GetJobWorkers() []jobs.Worker GetJobWorkers() []jobs.Worker
AsRepository(ctx context.Context, r *provisioning.Repository) (repository.Repository, error) AsRepository(ctx context.Context, r *provisioning.Repository) (repository.Repository, error)
RepositoryTypes() []provisioning.RepositoryType
} }
type ExtraBuilder func(b *APIBuilder) Extra type ExtraBuilder func(b *APIBuilder) Extra

View File

@ -2,6 +2,7 @@ package provisioning
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"path/filepath" "path/filepath"
@ -101,6 +102,7 @@ type APIBuilder struct {
statusPatcher *controller.RepositoryStatusPatcher statusPatcher *controller.RepositoryStatusPatcher
// Extras provides additional functionality to the API. // Extras provides additional functionality to the API.
extras []Extra extras []Extra
availableRepositoryTypes map[provisioning.RepositoryType]bool
} }
// NewAPIBuilder creates an API builder. // NewAPIBuilder creates an API builder.
@ -140,12 +142,23 @@ func NewAPIBuilder(
secrets: secrets, secrets: secrets,
access: access, access: access,
jobHistory: jobs.NewJobHistoryCache(), jobHistory: jobs.NewJobHistoryCache(),
availableRepositoryTypes: map[provisioning.RepositoryType]bool{
provisioning.LocalRepositoryType: true,
provisioning.GitHubRepositoryType: true,
},
} }
for _, builder := range extraBuilders { for _, builder := range extraBuilders {
b.extras = append(b.extras, builder(b)) b.extras = append(b.extras, builder(b))
} }
// Add the available repository types from the extras
for _, extra := range b.extras {
for _, t := range extra.RepositoryTypes() {
b.availableRepositoryTypes[t] = true
}
}
return b return b
} }
@ -1193,6 +1206,10 @@ func (b *APIBuilder) AsRepository(ctx context.Context, r *provisioning.Repositor
} }
switch r.Spec.Type { switch r.Spec.Type {
case provisioning.BitbucketRepositoryType:
return nil, errors.New("repository type bitbucket is not available")
case provisioning.GitLabRepositoryType:
return nil, errors.New("repository type gitlab is not available")
case provisioning.LocalRepositoryType: case provisioning.LocalRepositoryType:
return local.NewLocal(r, b.localFileResolver), nil return local.NewLocal(r, b.localFileResolver), nil
case provisioning.GitRepositoryType: case provisioning.GitRepositoryType:

View File

@ -156,11 +156,18 @@ func (b *APIBuilder) handleSettings(w http.ResponseWriter, r *http.Request) {
return return
} }
availableTypes := []provisioning.RepositoryType{}
for t := range b.availableRepositoryTypes {
availableTypes = append(availableTypes, t)
}
settings := provisioning.RepositoryViewList{ settings := provisioning.RepositoryViewList{
Items: make([]provisioning.RepositoryView, len(all)), Items: make([]provisioning.RepositoryView, len(all)),
// FIXME: this shouldn't be here in provisioning but at the dual writer or something about the storage // FIXME: this shouldn't be here in provisioning but at the dual writer or something about the storage
LegacyStorage: dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, b.storageStatus), LegacyStorage: dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, b.storageStatus),
AvailableRepositoryTypes: availableTypes,
} }
for i, val := range all { for i, val := range all {
branch := "" branch := ""
if val.Spec.GitHub != nil { if val.Spec.GitHub != nil {

View File

@ -220,3 +220,9 @@ func (e *WebhookExtra) AsRepository(ctx context.Context, r *provisioning.Reposit
return nil, nil return nil, nil
} }
func (e *WebhookExtra) RepositoryTypes() []provisioning.RepositoryType {
return []provisioning.RepositoryType{
provisioning.GitHubRepositoryType,
}
}

View File

@ -2572,6 +2572,37 @@
} }
} }
}, },
"com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.BitbucketRepositoryConfig": {
"type": "object",
"required": [
"branch"
],
"properties": {
"branch": {
"description": "The branch to use in the repository.",
"type": "string",
"default": ""
},
"encryptedToken": {
"description": "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
"type": "string",
"format": "byte",
"x-kubernetes-list-type": "atomic"
},
"path": {
"description": "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
"type": "string"
},
"token": {
"description": "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
"type": "string"
},
"url": {
"description": "The repository URL (e.g. `https://bitbucket.org/example/test`).",
"type": "string"
}
}
},
"com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ErrorDetails": { "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ErrorDetails": {
"type": "object", "type": "object",
"required": [ "required": [
@ -2695,6 +2726,37 @@
} }
} }
}, },
"com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.GitLabRepositoryConfig": {
"type": "object",
"required": [
"branch"
],
"properties": {
"branch": {
"description": "The branch to use in the repository.",
"type": "string",
"default": ""
},
"encryptedToken": {
"description": "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
"type": "string",
"format": "byte",
"x-kubernetes-list-type": "atomic"
},
"path": {
"description": "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
"type": "string"
},
"token": {
"description": "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
"type": "string"
},
"url": {
"description": "The repository URL (e.g. `https://gitlab.com/example/test`).",
"type": "string"
}
}
},
"com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.GitRepositoryConfig": { "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.GitRepositoryConfig": {
"type": "object", "type": "object",
"required": [ "required": [
@ -3271,6 +3333,14 @@
"type" "type"
], ],
"properties": { "properties": {
"bitbucket": {
"description": "The repository on Bitbucket. Mutually exclusive with local | github | git.",
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.BitbucketRepositoryConfig"
}
]
},
"description": { "description": {
"description": "Repository description", "description": "Repository description",
"type": "string" "type": "string"
@ -3291,6 +3361,14 @@
} }
] ]
}, },
"gitlab": {
"description": "The repository on GitLab. Mutually exclusive with local | github | git.",
"allOf": [
{
"$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.GitLabRepositoryConfig"
}
]
},
"local": { "local": {
"description": "The repository on the local file system. Mutually exclusive with local | github.", "description": "The repository on the local file system. Mutually exclusive with local | github.",
"allOf": [ "allOf": [
@ -3314,12 +3392,14 @@
"default": "" "default": ""
}, },
"type": { "type": {
"description": "The repository type. When selected oneOf the values below should be non-nil\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", "description": "The repository type. When selected oneOf the values below should be non-nil\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
"type": "string", "type": "string",
"default": "", "default": "",
"enum": [ "enum": [
"bitbucket",
"git", "git",
"github", "github",
"gitlab",
"local" "local"
] ]
}, },
@ -3428,12 +3508,14 @@
"default": "" "default": ""
}, },
"type": { "type": {
"description": "The repository type\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", "description": "The repository type\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
"type": "string", "type": "string",
"default": "", "default": "",
"enum": [ "enum": [
"bitbucket",
"git", "git",
"github", "github",
"gitlab",
"local" "local"
] ]
}, },
@ -3462,6 +3544,21 @@
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string" "type": "string"
}, },
"availableRepositoryTypes": {
"description": "AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc)",
"type": "array",
"items": {
"type": "string",
"default": "",
"enum": [
"bitbucket",
"git",
"github",
"gitlab",
"local"
]
}
},
"items": { "items": {
"type": "array", "type": "array",
"items": { "items": {
@ -3676,12 +3773,14 @@
"default": "" "default": ""
}, },
"type": { "type": {
"description": "The repository type\n\nPossible enum values:\n - `\"git\"`\n - `\"github\"`\n - `\"local\"`", "description": "The repository type\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"git\"`\n - `\"github\"`\n - `\"gitlab\"`\n - `\"local\"`",
"type": "string", "type": "string",
"default": "", "default": "",
"enum": [ "enum": [
"bitbucket",
"git", "git",
"github", "github",
"gitlab",
"local" "local"
] ]
} }

View File

@ -127,6 +127,10 @@ func TestIntegrationProvisioning_CreatingAndGetting(t *testing.T) {
err := rsp.Into(settings) err := rsp.Into(settings)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, settings.Items, len(inputFiles)) require.Len(t, settings.Items, len(inputFiles))
require.ElementsMatch(t, []provisioning.RepositoryType{
provisioning.LocalRepositoryType,
provisioning.GitHubRepositoryType,
}, settings.AvailableRepositoryTypes)
}) })
t.Run("Repositories are reported in stats", func(t *testing.T) { t.Run("Repositories are reported in stats", func(t *testing.T) {

View File

@ -851,6 +851,20 @@ export type JobList = {
kind?: string; kind?: string;
metadata?: ListMeta; metadata?: ListMeta;
}; };
export type BitbucketRepositoryConfig = {
/** The branch to use in the repository. */
branch: string;
/** Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted. */
encryptedToken?: string;
/** Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.
When specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found. */
path?: string;
/** Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again. */
token?: string;
/** The repository URL (e.g. `https://bitbucket.org/example/test`). */
url?: string;
};
export type GitRepositoryConfig = { export type GitRepositoryConfig = {
/** The branch to use in the repository. */ /** The branch to use in the repository. */
branch: string; branch: string;
@ -881,6 +895,20 @@ export type GitHubRepositoryConfig = {
/** The repository URL (e.g. `https://github.com/example/test`). */ /** The repository URL (e.g. `https://github.com/example/test`). */
url?: string; url?: string;
}; };
export type GitLabRepositoryConfig = {
/** The branch to use in the repository. */
branch: string;
/** Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted. */
encryptedToken?: string;
/** Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.
When specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found. */
path?: string;
/** Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again. */
token?: string;
/** The repository URL (e.g. `https://gitlab.com/example/test`). */
url?: string;
};
export type LocalRepositoryConfig = { export type LocalRepositoryConfig = {
path?: string; path?: string;
}; };
@ -897,12 +925,16 @@ export type SyncOptions = {
target: 'folder' | 'instance'; target: 'folder' | 'instance';
}; };
export type RepositorySpec = { export type RepositorySpec = {
/** The repository on Bitbucket. Mutually exclusive with local | github | git. */
bitbucket?: BitbucketRepositoryConfig;
/** Repository description */ /** Repository description */
description?: string; description?: string;
/** The repository on Git. Mutually exclusive with local | github | git. */ /** The repository on Git. Mutually exclusive with local | github | git. */
git?: GitRepositoryConfig; git?: GitRepositoryConfig;
/** The repository on GitHub. Mutually exclusive with local | github | git. */ /** The repository on GitHub. Mutually exclusive with local | github | git. */
github?: GitHubRepositoryConfig; github?: GitHubRepositoryConfig;
/** The repository on GitLab. Mutually exclusive with local | github | git. */
gitlab?: GitLabRepositoryConfig;
/** The repository on the local file system. Mutually exclusive with local | github. */ /** The repository on the local file system. Mutually exclusive with local | github. */
local?: LocalRepositoryConfig; local?: LocalRepositoryConfig;
/** Sync settings -- how values are pulled from the repository into grafana */ /** Sync settings -- how values are pulled from the repository into grafana */
@ -912,10 +944,12 @@ export type RepositorySpec = {
/** The repository type. When selected oneOf the values below should be non-nil /** The repository type. When selected oneOf the values below should be non-nil
Possible enum values: Possible enum values:
- `"bitbucket"`
- `"git"` - `"git"`
- `"github"` - `"github"`
- `"gitlab"`
- `"local"` */ - `"local"` */
type: 'git' | 'github' | 'local'; type: 'bitbucket' | 'git' | 'github' | 'gitlab' | 'local';
/** UI driven Workflow that allow changes to the contends of the repository. The order is relevant for defining the precedence of the workflows. When empty, the repository does not support any edits (eg, readonly) */ /** UI driven Workflow that allow changes to the contends of the repository. The order is relevant for defining the precedence of the workflows. When empty, the repository does not support any edits (eg, readonly) */
workflows: ('branch' | 'write')[]; workflows: ('branch' | 'write')[];
}; };
@ -1047,10 +1081,12 @@ export type ResourceRepositoryInfo = {
/** The repository type /** The repository type
Possible enum values: Possible enum values:
- `"bitbucket"`
- `"git"` - `"git"`
- `"github"` - `"github"`
- `"gitlab"`
- `"local"` */ - `"local"` */
type: 'git' | 'github' | 'local'; type: 'bitbucket' | 'git' | 'github' | 'gitlab' | 'local';
}; };
export type Unstructured = { export type Unstructured = {
[key: string]: any; [key: string]: any;
@ -1184,16 +1220,20 @@ export type RepositoryView = {
/** The repository type /** The repository type
Possible enum values: Possible enum values:
- `"bitbucket"`
- `"git"` - `"git"`
- `"github"` - `"github"`
- `"gitlab"`
- `"local"` */ - `"local"` */
type: 'git' | 'github' | 'local'; type: 'bitbucket' | 'git' | 'github' | 'gitlab' | 'local';
/** The supported workflows */ /** The supported workflows */
workflows: ('branch' | 'write')[]; workflows: ('branch' | 'write')[];
}; };
export type RepositoryViewList = { export type RepositoryViewList = {
/** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */
apiVersion?: string; apiVersion?: string;
/** AvailableRepositoryTypes is the list of repository types supported in this instance (e.g. git, bitbucket, github, etc) */
availableRepositoryTypes?: ('bitbucket' | 'git' | 'github' | 'gitlab' | 'local')[];
items: RepositoryView[]; items: RepositoryView[];
/** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */
kind?: string; kind?: string;

View File

@ -187,6 +187,7 @@ describe('BootstrapStep', () => {
settingsData: { settingsData: {
legacyStorage: true, legacyStorage: true,
items: [], items: [],
availableRepositoryTypes: [],
}, },
}); });
@ -239,6 +240,7 @@ describe('BootstrapStep', () => {
settingsData: { settingsData: {
legacyStorage: true, legacyStorage: true,
items: [], items: [],
availableRepositoryTypes: [],
}, },
}); });