Provisioning: Extract to apps submodule (#109074)
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
// File types used from classic provisioning
|
||||
// +enum
|
||||
type ClassicFileType string
|
||||
|
||||
const (
|
||||
// Dashboard JSON
|
||||
ClassicDashboard ClassicFileType = "dashboard"
|
||||
|
||||
// Datasource definitions
|
||||
// eg: https://github.com/grafana/grafana/blob/v11.3.1/conf/provisioning/datasources/sample.yaml
|
||||
ClassicDatasources ClassicFileType = "datasources"
|
||||
|
||||
// Alert configuration
|
||||
// https://github.com/grafana/grafana/blob/v11.3.1/conf/provisioning/alerting/sample.yaml
|
||||
ClassicAlerting ClassicFileType = "alerting"
|
||||
|
||||
// Access control
|
||||
// https://github.com/grafana/grafana/blob/v11.3.1/conf/provisioning/access-control/sample.yaml
|
||||
ClassicAccessControl ClassicFileType = "access-control"
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=provisioning.grafana.app
|
||||
|
||||
package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
@@ -1,249 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// The repository name and type are stored as labels
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type Job struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec JobSpec `json:"spec,omitempty"`
|
||||
Status JobStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type JobList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Job `json:"items"`
|
||||
}
|
||||
|
||||
// +enum
|
||||
type JobAction string
|
||||
|
||||
const (
|
||||
// JobActionPull replicates the remote branch in the local copy of the repository.
|
||||
JobActionPull JobAction = "pull"
|
||||
|
||||
// JobActionPush replicates the local copy of the repository in the remote branch.
|
||||
JobActionPush JobAction = "push"
|
||||
|
||||
// JobActionPullRequest adds additional useful information to a PR, such as comments with preview links and rendered images.
|
||||
JobActionPullRequest JobAction = "pr"
|
||||
|
||||
// JobActionMigrate acts like JobActionExport, then JobActionPull. It also tries to preserve the history.
|
||||
JobActionMigrate JobAction = "migrate"
|
||||
|
||||
// JobActionDelete deletes files in the remote repository
|
||||
JobActionDelete JobAction = "delete"
|
||||
|
||||
// JobActionMove moves files in the remote repository
|
||||
JobActionMove JobAction = "move"
|
||||
)
|
||||
|
||||
// +enum
|
||||
type JobState string
|
||||
|
||||
const (
|
||||
// Job has been submitted, but not processed yet
|
||||
JobStatePending JobState = "pending"
|
||||
|
||||
// The job is running
|
||||
JobStateWorking JobState = "working"
|
||||
|
||||
// Finished with success
|
||||
JobStateSuccess JobState = "success"
|
||||
|
||||
// Finished with errors
|
||||
JobStateError JobState = "error"
|
||||
|
||||
// Finished with some non-critical errors
|
||||
JobStateWarning JobState = "warning"
|
||||
)
|
||||
|
||||
func (j JobState) Finished() bool {
|
||||
return j == JobStateSuccess || j == JobStateError || j == JobStateWarning
|
||||
}
|
||||
|
||||
type JobSpec struct {
|
||||
Action JobAction `json:"action,omitempty"`
|
||||
|
||||
// The the repository reference (for now also in labels)
|
||||
// This value is required, but will be popuplated from the job making the request
|
||||
Repository string `json:"repository,omitempty"`
|
||||
|
||||
// Pull request options
|
||||
PullRequest *PullRequestJobOptions `json:"pr,omitempty"`
|
||||
|
||||
// Required when the action is `push`
|
||||
Push *ExportJobOptions `json:"push,omitempty"`
|
||||
|
||||
// Required when the action is `pull`
|
||||
Pull *SyncJobOptions `json:"pull,omitempty"`
|
||||
|
||||
// Required when the action is `migrate`
|
||||
Migrate *MigrateJobOptions `json:"migrate,omitempty"`
|
||||
|
||||
// Delete when the action is `delete`
|
||||
Delete *DeleteJobOptions `json:"delete,omitempty"`
|
||||
|
||||
// Move when the action is `move`
|
||||
Move *MoveJobOptions `json:"move,omitempty"`
|
||||
}
|
||||
|
||||
type PullRequestJobOptions struct {
|
||||
// The branch of commit hash
|
||||
Ref string `json:"ref,omitempty"`
|
||||
|
||||
// Pull request number (when appropriate)
|
||||
PR int `json:"pr,omitempty"`
|
||||
|
||||
// The specific commit hash that triggered this notice
|
||||
Hash string `json:"hash,omitempty"`
|
||||
|
||||
// URL to the originator (eg, PR URL)
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type SyncJobOptions struct {
|
||||
// Incremental synchronization for versioned repositories
|
||||
Incremental bool `json:"incremental"`
|
||||
}
|
||||
|
||||
type ExportJobOptions struct {
|
||||
// Message to use when committing the changes in a single commit
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// The source folder (or empty) to export
|
||||
Folder string `json:"folder,omitempty"`
|
||||
|
||||
// FIXME: we should validate this in admission hooks
|
||||
// Target branch for export (only git)
|
||||
Branch string `json:"branch,omitempty"`
|
||||
|
||||
// FIXME: we should validate this in admission hooks
|
||||
// Prefix in target file system
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
type MigrateJobOptions struct {
|
||||
// Preserve history (if possible)
|
||||
History bool `json:"history,omitempty"`
|
||||
|
||||
// Message to use when committing the changes in a single commit
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type DeleteJobOptions struct {
|
||||
// Ref to the branch or commit hash to delete from
|
||||
Ref string `json:"ref,omitempty"`
|
||||
// Paths to be deleted. Examples:
|
||||
// - dashboard.json (for a file)
|
||||
// - a/b/c/other-dashboard.json (for a file)
|
||||
// - nested/deep/ (for a directory)
|
||||
// FIXME: we should validate this in admission hooks
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
|
||||
// Resources to delete
|
||||
// This option has been created because currently the frontend does not use
|
||||
// standarized app platform APIs. For performance and API consistency reasons, the preferred option
|
||||
// is it to use the paths.
|
||||
Resources []ResourceRef `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceRef struct {
|
||||
// Name is the name of the resource, such as a dashboard UID.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Kind is the type of resource, for example, "Dashboard".
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Group is the group of the resource, such as "dashboard.grafana.app".
|
||||
Group string `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type MoveJobOptions struct {
|
||||
// Ref to the branch or commit hash that should move
|
||||
Ref string `json:"ref,omitempty"`
|
||||
// Paths to be deleted. Examples:
|
||||
// - dashboard.json (for a file)
|
||||
// - a/b/c/other-dashboard.json (for a file)
|
||||
// - nested/deep/ (for a directory)
|
||||
// FIXME: we should validate this in admission hooks
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
|
||||
// Destination path for the move (e.g. "new-location/")
|
||||
TargetPath string `json:"targetPath,omitempty"`
|
||||
|
||||
// Resources to move
|
||||
// This option has been created because currently the frontend does not use
|
||||
// standarized app platform APIs. For performance and API consistency reasons, the preferred option
|
||||
// is it to use the paths.
|
||||
Resources []ResourceRef `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// The job status
|
||||
type JobStatus struct {
|
||||
State JobState `json:"state,omitempty"`
|
||||
Started int64 `json:"started,omitempty"`
|
||||
Finished int64 `json:"finished,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
|
||||
// Optional value 0-100 that can be set while running
|
||||
Progress float64 `json:"progress,omitempty"`
|
||||
|
||||
// Summary of processed actions
|
||||
Summary []*JobResourceSummary `json:"summary,omitempty"`
|
||||
}
|
||||
|
||||
// Convert a JOB to a
|
||||
func (in JobStatus) ToSyncStatus(jobId string) SyncStatus {
|
||||
return SyncStatus{
|
||||
JobID: jobId,
|
||||
State: in.State,
|
||||
Started: in.Started,
|
||||
Finished: in.Finished,
|
||||
Message: in.Errors,
|
||||
}
|
||||
}
|
||||
|
||||
type JobResourceSummary struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
Total int64 `json:"total,omitempty"` // the count (if known)
|
||||
|
||||
Create int64 `json:"create,omitempty"`
|
||||
Update int64 `json:"update,omitempty"`
|
||||
Delete int64 `json:"delete,omitempty"`
|
||||
Write int64 `json:"write,omitempty"` // Create or update (export)
|
||||
Error int64 `json:"error,omitempty"` // The error count
|
||||
|
||||
// No action required (useful for sync)
|
||||
Noop int64 `json:"noop,omitempty"`
|
||||
|
||||
// Report errors for this resource type
|
||||
// This may not be an exhaustive list and recommend looking at the logs for more info
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type WebhookResponse struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// HTTP Status code
|
||||
// 200 implies that the payload was understood but nothing is required
|
||||
// 202 implies that an async job has been scheduled to handle the request
|
||||
Code int `json:"code,omitempty"`
|
||||
|
||||
// Optional message
|
||||
Message string `json:"added,omitempty"`
|
||||
|
||||
// Jobs to be processed
|
||||
// When the response is 202 (Accepted) the queued jobs will be returned
|
||||
Job *JobSpec `json:"job,omitempty"`
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
GROUP = "provisioning.grafana.app"
|
||||
VERSION = "v0alpha1"
|
||||
APIVERSION = GROUP + "/" + VERSION
|
||||
)
|
||||
|
||||
var RepositoryResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
|
||||
"repositories", "repository", "Repositories",
|
||||
func() runtime.Object { return &Repository{} }, // newObj
|
||||
func() runtime.Object { return &RepositoryList{} }, // newList
|
||||
utils.TableColumns{ // Returned by `kubectl get`. Doesn't affect disk storage.
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Created At", Type: "date"},
|
||||
{Name: "Title", Type: "string"},
|
||||
{Name: "Type", Type: "string"},
|
||||
{Name: "Target", Type: "string"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*Repository)
|
||||
if !ok {
|
||||
return nil, errors.New("expected Repository")
|
||||
}
|
||||
|
||||
var target string
|
||||
switch m.Spec.Type {
|
||||
case LocalRepositoryType:
|
||||
target = m.Spec.Local.Path
|
||||
case GitHubRepositoryType:
|
||||
target = m.Spec.GitHub.URL
|
||||
case GitRepositoryType:
|
||||
target = m.Spec.Git.URL
|
||||
case BitbucketRepositoryType:
|
||||
target = m.Spec.Bitbucket.URL
|
||||
case GitLabRepositoryType:
|
||||
target = m.Spec.GitLab.URL
|
||||
}
|
||||
|
||||
return []interface{}{
|
||||
m.Name, // may our may not be nice to read
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
m.Spec.Title, // explicitly configured title that can change
|
||||
m.Spec.Type,
|
||||
target,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
|
||||
var JobResourceInfo = utils.NewResourceInfo(GROUP, VERSION,
|
||||
"jobs", "job", "Job",
|
||||
func() runtime.Object { return &Job{} }, // newObj
|
||||
func() runtime.Object { return &JobList{} }, // newList
|
||||
utils.TableColumns{ // Returned by `kubectl get`. Doesn't affect disk storage.
|
||||
Definition: []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name"},
|
||||
{Name: "Created At", Type: "date"},
|
||||
{Name: "Action", Type: "string"},
|
||||
{Name: "State", Type: "string"},
|
||||
{Name: "Message", Type: "string"},
|
||||
},
|
||||
Reader: func(obj any) ([]interface{}, error) {
|
||||
m, ok := obj.(*Job)
|
||||
if !ok {
|
||||
return nil, errors.New("expected Job")
|
||||
}
|
||||
|
||||
return []interface{}{
|
||||
m.Name, // may our may not be nice to read
|
||||
m.CreationTimestamp.UTC().Format(time.RFC3339),
|
||||
m.Spec.Action,
|
||||
m.Status.State,
|
||||
m.Status.Message,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION}
|
||||
InternalGroupVersion = schema.GroupVersion{Group: GROUP, Version: runtime.APIVersionInternal}
|
||||
|
||||
// SchemaBuilder is used by standard codegen
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(func(s *runtime.Scheme) error {
|
||||
err := AddKnownTypes(SchemeGroupVersion, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metav1.AddToGroupVersion(s, SchemeGroupVersion)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(gv,
|
||||
&Repository{},
|
||||
&RepositoryList{},
|
||||
&WebhookResponse{},
|
||||
&ResourceWrapper{},
|
||||
&FileList{},
|
||||
&HistoryList{},
|
||||
&TestResults{},
|
||||
&ResourceList{},
|
||||
&ResourceStats{},
|
||||
&Job{},
|
||||
&JobList{},
|
||||
&RefList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Summary shows a view of the configuration that is sanitized and is OK for logged in users to see
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type RepositoryViewList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// The backend is using legacy storage
|
||||
// FIXME: Not sure where this should be exposed... but we need it somewhere
|
||||
// The UI should force the onboarding workflow when this is true
|
||||
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
|
||||
Items []RepositoryView `json:"items"`
|
||||
}
|
||||
|
||||
type RepositoryView struct {
|
||||
// The k8s name for this repository
|
||||
Name string `json:"name"`
|
||||
|
||||
// Repository display
|
||||
Title string `json:"title"`
|
||||
|
||||
// The repository type
|
||||
Type RepositoryType `json:"type"`
|
||||
|
||||
// When syncing, where values are saved
|
||||
Target SyncTargetType `json:"target"`
|
||||
|
||||
// For git, this is the target branch
|
||||
Branch string `json:"branch,omitempty"`
|
||||
|
||||
// The supported workflows
|
||||
Workflows []Workflow `json:"workflows"`
|
||||
}
|
||||
@@ -1,525 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
// When this code is changed, make sure to update the code generation.
|
||||
// As of writing, this can be done via the hack dir in the root of the repo: ./hack/update-codegen.sh provisioning
|
||||
// If you've opened the generated files in this dir at some point in VSCode, you may also have to re-open them to clear errors.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type Repository struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec RepositorySpec `json:"spec,omitempty"`
|
||||
Status RepositoryStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type LocalRepositoryConfig struct {
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// Workflow used for changes in the repository.
|
||||
// +enum
|
||||
type Workflow string
|
||||
|
||||
const (
|
||||
// WriteWorkflow allows a user to write directly to the repository
|
||||
WriteWorkflow Workflow = "write"
|
||||
// BranchWorkflow creates a branch for changes
|
||||
BranchWorkflow Workflow = "branch"
|
||||
)
|
||||
|
||||
type GitHubRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://github.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"`
|
||||
|
||||
// Whether we should show dashboard previews for pull requests.
|
||||
// By default, this is false (i.e. we will not create previews).
|
||||
GenerateDashboardPreviews bool `json:"generateDashboardPreviews,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 GitRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://github.com/example/test.git`).
|
||||
URL string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser string `json:"tokenUser,omitempty"`
|
||||
// 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 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"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser string `json:"tokenUser,omitempty"`
|
||||
// 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
|
||||
// +enum
|
||||
type RepositoryType string
|
||||
|
||||
// RepositoryType values
|
||||
const (
|
||||
LocalRepositoryType RepositoryType = "local"
|
||||
GitHubRepositoryType RepositoryType = "github"
|
||||
GitRepositoryType RepositoryType = "git"
|
||||
BitbucketRepositoryType RepositoryType = "bitbucket"
|
||||
GitLabRepositoryType RepositoryType = "gitlab"
|
||||
)
|
||||
|
||||
// IsGit returns true if the repository type is git or github
|
||||
func (r RepositoryType) IsGit() bool {
|
||||
return r == GitRepositoryType || r == GitHubRepositoryType || r == BitbucketRepositoryType || r == GitLabRepositoryType
|
||||
}
|
||||
|
||||
type RepositorySpec struct {
|
||||
// The repository display name (shown in the UI)
|
||||
Title string `json:"title"`
|
||||
|
||||
// Repository description
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// 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 []Workflow `json:"workflows"`
|
||||
|
||||
// Sync settings -- how values are pulled from the repository into grafana
|
||||
Sync SyncOptions `json:"sync"`
|
||||
|
||||
// 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 local | github.
|
||||
Local *LocalRepositoryConfig `json:"local,omitempty"`
|
||||
|
||||
// The repository on GitHub.
|
||||
// Mutually exclusive with local | github | git.
|
||||
GitHub *GitHubRepositoryConfig `json:"github,omitempty"`
|
||||
|
||||
// The repository on Git.
|
||||
// Mutually exclusive with local | github | git.
|
||||
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
|
||||
// +enum
|
||||
type SyncTargetType string
|
||||
|
||||
// RepositoryType values
|
||||
const (
|
||||
// Resources are saved in the global context
|
||||
// Only one repository may specify the `instance` target
|
||||
// When this exists, the UI will promote writing to the instance repo
|
||||
// rather than the grafana database (where possible)
|
||||
SyncTargetTypeInstance SyncTargetType = "instance"
|
||||
|
||||
// Resources will be saved into a folder managed by this repository
|
||||
// It will contain a copy of everything from the remote
|
||||
// The folder k8s name will be the same as the repository k8s name
|
||||
SyncTargetTypeFolder SyncTargetType = "folder"
|
||||
)
|
||||
|
||||
type SyncOptions struct {
|
||||
// Enabled must be saved as true before any sync job will run
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
// Where values should be saved
|
||||
Target SyncTargetType `json:"target"`
|
||||
|
||||
// Shared folder target
|
||||
// The value is a reference to the Kubernetes metadata name of the folder in the same namespace
|
||||
// Folder string `json:"folder,omitempty"`
|
||||
|
||||
// When non-zero, the sync will run periodically
|
||||
IntervalSeconds int64 `json:"intervalSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// The status of a Repository.
|
||||
// This is expected never to be created by a kubectl call or similar, and is expected to rarely (if ever) be edited manually.
|
||||
// As such, it is also a little less well structured than the spec, such as conditional-but-ever-present fields.
|
||||
type RepositoryStatus struct {
|
||||
// The generation of the spec last time reconciliation ran
|
||||
ObservedGeneration int64 `json:"observedGeneration"`
|
||||
|
||||
// This will get updated with the current health status (and updated periodically)
|
||||
Health HealthStatus `json:"health"`
|
||||
|
||||
// Sync information with the last sync information
|
||||
Sync SyncStatus `json:"sync"`
|
||||
|
||||
// The object count when sync last ran
|
||||
// +listType=atomic
|
||||
Stats []ResourceCount `json:"stats,omitempty"`
|
||||
|
||||
// Webhook Information (if applicable)
|
||||
Webhook *WebhookStatus `json:"webhook"`
|
||||
}
|
||||
|
||||
type HealthStatus struct {
|
||||
// When not healthy, requests will not be executed
|
||||
Healthy bool `json:"healthy"`
|
||||
|
||||
// When the health was checked last time
|
||||
Checked int64 `json:"checked,omitempty"`
|
||||
|
||||
// Summary messages (can be shown to users)
|
||||
// Will only be populated when not healthy
|
||||
// +listType=atomic
|
||||
Message []string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type SyncStatus struct {
|
||||
// pending, running, success, error
|
||||
State JobState `json:"state"`
|
||||
|
||||
// The ID for the job that ran this sync
|
||||
JobID string `json:"job,omitempty"`
|
||||
|
||||
// When the sync job started
|
||||
Started int64 `json:"started,omitempty"`
|
||||
|
||||
// When the sync job finished
|
||||
Finished int64 `json:"finished,omitempty"`
|
||||
|
||||
// When the next sync check is scheduled
|
||||
Scheduled int64 `json:"scheduled,omitempty"`
|
||||
|
||||
// Summary messages (will be shown to users)
|
||||
// +listType=atomic
|
||||
Message []string `json:"message"`
|
||||
|
||||
// The repository ref when the last successful sync ran
|
||||
LastRef string `json:"lastRef,omitempty"`
|
||||
|
||||
// Incremental synchronization for versioned repositories
|
||||
Incremental bool `json:"incremental,omitempty"`
|
||||
}
|
||||
|
||||
type WebhookStatus struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Secret string `json:"secret,omitempty"`
|
||||
EncryptedSecret []byte `json:"encryptedSecret,omitempty"`
|
||||
SubscribedEvents []string `json:"subscribedEvents,omitempty"`
|
||||
LastEvent int64 `json:"lastEvent,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type RepositoryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +listType=atomic
|
||||
Items []Repository `json:"items"`
|
||||
}
|
||||
|
||||
// The kubernetes action required when loading a given resource
|
||||
// +enum
|
||||
type ResourceAction string
|
||||
|
||||
// ResourceAction values
|
||||
const (
|
||||
ResourceActionCreate ResourceAction = "create"
|
||||
ResourceActionUpdate ResourceAction = "update"
|
||||
ResourceActionDelete ResourceAction = "delete"
|
||||
ResourceActionMove ResourceAction = "move"
|
||||
)
|
||||
|
||||
// This is a container type for any resource type
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ResourceWrapper struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// Path to the remote file
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
// The request ref (or branch if exists)
|
||||
Ref string `json:"ref,omitempty"`
|
||||
|
||||
// The repo hash value
|
||||
Hash string `json:"hash,omitempty"`
|
||||
|
||||
// Basic repository info
|
||||
Repository ResourceRepositoryInfo `json:"repository"`
|
||||
|
||||
// Typed links for this file (only supported by external systems, github etc)
|
||||
URLs *ResourceURLs `json:"urls,omitempty"`
|
||||
|
||||
// The modified time in the remote file system
|
||||
Timestamp *metav1.Time `json:"timestamp,omitempty"`
|
||||
|
||||
// Different flavors of the same object
|
||||
Resource ResourceObjects `json:"resource"`
|
||||
|
||||
// If errors exist, show them here
|
||||
// +listType=atomic
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceType struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
|
||||
// For non-k8s native formats, what did this start as
|
||||
Classic ClassicFileType `json:"classic,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceObjects struct {
|
||||
// The identified type for this object
|
||||
Type ResourceType `json:"type"`
|
||||
|
||||
// The resource from the repository with all modifications applied
|
||||
// eg, the name, folder etc will all be applied to this object
|
||||
File common.Unstructured `json:"file,omitempty"`
|
||||
|
||||
// The same value, currently saved in the grafana database
|
||||
Existing common.Unstructured `json:"existing,omitempty"`
|
||||
|
||||
// The action required/used for dryRun
|
||||
Action ResourceAction `json:"action,omitempty"`
|
||||
|
||||
// The value returned from a dryRun request
|
||||
DryRun common.Unstructured `json:"dryRun,omitempty"`
|
||||
|
||||
// For write events, this will return the value that was added or updated
|
||||
Upsert common.Unstructured `json:"upsert,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceRepositoryInfo struct {
|
||||
// The repository type
|
||||
Type RepositoryType `json:"type"`
|
||||
|
||||
// The display name for this repository
|
||||
Title string `json:"title"`
|
||||
|
||||
// The namespace this belongs to
|
||||
Namespace string `json:"namespace"`
|
||||
|
||||
// The name (identifier)
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ResourceURLs struct {
|
||||
// A URL pointing to the this file in the repository
|
||||
SourceURL string `json:"sourceURL,omitempty"`
|
||||
|
||||
// A URL pointing to the repository this lives in
|
||||
RepositoryURL string `json:"repositoryURL,omitempty"`
|
||||
|
||||
// A URL that will create a new pull requeset for this branch
|
||||
NewPullRequestURL string `json:"newPullRequestURL,omitempty"`
|
||||
|
||||
// Compare this version to the target branch
|
||||
CompareURL string `json:"compareURL,omitempty"`
|
||||
}
|
||||
|
||||
// Information we can get just from the file listing
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type FileList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +listType=atomic
|
||||
Items []FileItem `json:"items"`
|
||||
}
|
||||
|
||||
type FileItem struct {
|
||||
Path string `json:"path"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
Modified int64 `json:"modified,omitempty"`
|
||||
Author string `json:"author,omitempty"`
|
||||
}
|
||||
|
||||
// Information we can get just from the file listing
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ResourceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +listType=atomic
|
||||
Items []ResourceListItem `json:"items"`
|
||||
}
|
||||
|
||||
type ResourceListItem struct {
|
||||
Path string `json:"path"`
|
||||
Group string `json:"group"`
|
||||
Resource string `json:"resource"`
|
||||
Name string `json:"name"` // the k8s identifier
|
||||
Hash string `json:"hash"`
|
||||
Time int64 `json:"time,omitempty"`
|
||||
|
||||
Title string `json:"title,omitempty"`
|
||||
Folder string `json:"folder,omitempty"`
|
||||
}
|
||||
|
||||
// Information we can get just from the file listing
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type ResourceStats struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Stats across all unified storage
|
||||
// When legacy storage is still used, this will offer a shim
|
||||
// +listType=atomic
|
||||
Instance []ResourceCount `json:"instance,omitempty"`
|
||||
|
||||
// Stats for each manager
|
||||
// +listType=atomic
|
||||
Managed []ManagerStats `json:"managed,omitempty"`
|
||||
}
|
||||
|
||||
type ManagerStats struct {
|
||||
// Manager kind
|
||||
Kind utils.ManagerKind `json:"kind,omitempty"`
|
||||
|
||||
// Manager identity
|
||||
Identity string `json:"id,omitempty"`
|
||||
|
||||
// stats
|
||||
Stats []ResourceCount `json:"stats"`
|
||||
}
|
||||
|
||||
type ResourceCount struct {
|
||||
Group string `json:"group"`
|
||||
Resource string `json:"resource"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// HistoryList is a list of versions of a resource
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type TestResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// HTTP status code
|
||||
Code int `json:"code"`
|
||||
|
||||
// Is the connection healthy
|
||||
Success bool `json:"success"`
|
||||
|
||||
// Field related errors
|
||||
Errors []ErrorDetails `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
type ErrorDetails struct {
|
||||
Type metav1.CauseType `json:"type"`
|
||||
Field string `json:"field,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
}
|
||||
|
||||
// HistoryList is a list of versions of a resource
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type HistoryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +listType=atomic
|
||||
Items []HistoryItem `json:"items"`
|
||||
}
|
||||
|
||||
type Author struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatarURL,omitempty"`
|
||||
}
|
||||
|
||||
type HistoryItem struct {
|
||||
Ref string `json:"ref"`
|
||||
Message string `json:"message"`
|
||||
// +listType=atomic
|
||||
Authors []Author `json:"authors"`
|
||||
CreatedAt int64 `json:"createdAt"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type RefList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +listType=atomic
|
||||
Items []RefItem `json:"items"`
|
||||
}
|
||||
|
||||
type RefItem struct {
|
||||
// The name of the reference (branch or tag)
|
||||
Name string `json:"name"`
|
||||
// The SHA hash of the commit this ref points to
|
||||
Hash string `json:"hash,omitempty"`
|
||||
// The URL to the reference (branch or tag)
|
||||
RefURL string `json:"refURL,omitempty"`
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package v0alpha1_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
|
||||
)
|
||||
|
||||
func TestRepositoryType_IsGit(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repoType v0alpha1.RepositoryType
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "git",
|
||||
repoType: v0alpha1.GitRepositoryType,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
repoType: v0alpha1.GitHubRepositoryType,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "bitbucket",
|
||||
repoType: v0alpha1.BitbucketRepositoryType,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "gitlab",
|
||||
repoType: v0alpha1.GitLabRepositoryType,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "local",
|
||||
repoType: v0alpha1.LocalRepositoryType,
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := tt.repoType.IsGit()
|
||||
if got != tt.want {
|
||||
t.Errorf("IsGit() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,DeleteJobOptions,Paths
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,DeleteJobOptions,Resources
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,FileList,Items
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,HistoryList,Items
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobResourceSummary,Errors
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobStatus,Errors
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobStatus,Summary
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ManagerStats,Stats
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,MoveJobOptions,Paths
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,MoveJobOptions,Resources
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RefList,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,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,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,WebhookStatus,SubscribedEvents
|
||||
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,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,SyncStatus,JobID
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,WebhookResponse,Message
|
||||
Reference in New Issue
Block a user