Provisioning: Add resource types (#98727)

Co-authored-by: Mariell Hoversholm <mariell.hoversholm@grafana.com>
Co-authored-by: Roberto Jimenez Sanchez <roberto.jimenez@grafana.com>
This commit is contained in:
Ryan McKinley
2025-01-09 17:12:01 +03:00
committed by GitHub
co-authored by Mariell Hoversholm Roberto Jimenez Sanchez
parent 56be39ed4f
commit a84ab52cc7
38 changed files with 3882 additions and 11 deletions
+22
View File
@@ -0,0 +1,22 @@
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"
)
+6
View File
@@ -0,0 +1,6 @@
// +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"
+98
View File
@@ -0,0 +1,98 @@
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,omitempty"`
}
// +enum
type JobAction string
const (
// Update a pull request -- send preview images, links etc
JobActionPullRequest JobAction = "pr"
// Sync the remote branch with the grafana instance
JobActionSync JobAction = "sync"
// Export from grafana into the remote repository
JobActionExport JobAction = "export"
)
// +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"
)
func (j JobState) Finished() bool {
return j == JobStateSuccess || j == JobStateError
}
type JobSpec struct {
Action JobAction `json:"action"`
// The branch of commit hash
Ref string `json:"ref,omitempty"`
// Pull request number (when appropriate)
PR int `json:"pr,omitempty"`
Hash string `json:"hash,omitempty"` // used in PR code... not sure it is necessary
// URL to the originator (eg, PR URL)
URL string `json:"url,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"`
}
// +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"`
}
+129
View File
@@ -0,0 +1,129 @@
package v0alpha1
import (
"errors"
"fmt"
"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 S3RepositoryType:
target = m.Spec.S3.Bucket
case GitHubRepositoryType:
target = fmt.Sprintf("%s/%s", m.Spec.GitHub.Owner, m.Spec.GitHub.Repository)
}
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: "Repository", Type: "string"},
},
Reader: func(obj any) ([]interface{}, error) {
m, ok := obj.(*Job)
if !ok {
return nil, errors.New("expected Repository")
}
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.Labels["repository"],
}, 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{},
&HelloWorld{},
&WebhookResponse{},
&ResourceWrapper{},
&FileList{},
&HistoryList{},
&TestResults{},
&Job{},
&JobList{},
)
return nil
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
+338
View File
@@ -0,0 +1,338 @@
package v0alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
)
// 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"`
}
type S3RepositoryConfig struct {
Region string `json:"region,omitempty"`
Bucket string `json:"bucket,omitempty"`
// TODO: Add ACL?
// TODO: Encryption??
// TODO: How do we define access? Secrets?
}
type GitHubRepositoryConfig struct {
// The owner of the repository (e.g. example in `example/test` or `https://github.com/example/test`).
Owner string `json:"owner,omitempty"`
// The name of the repository (e.g. test in `example/test` or `https://github.com/example/test`).
Repository string `json:"repository,omitempty"`
// The branch to use in the repository.
// By default, this is the main branch.
Branch string `json:"branch,omitempty"`
// Token for accessing the repository.
// TODO: this should be part of secrets and a simple reference.
Token string `json:"token,omitempty"`
// TODO: Do we want an SSH url instead maybe?
// TODO: On-prem GitHub Enterprise support?
// Whether we should commit to change branches and use a Pull Request flow to achieve this.
// By default, this is false (i.e. we will commit straight to the main branch).
BranchWorkflow bool `json:"branchWorkflow,omitempty"`
// Whether we should show dashboard previews in the pull requests caused by the BranchWorkflow option.
// By default, this is false (i.e. we will not create previews).
// This option is a no-op if BranchWorkflow is `false` or default.
GenerateDashboardPreviews bool `json:"generateDashboardPreviews,omitempty"`
// PullRequestLinter enables the dashboard linter for this repository in Pull Requests
PullRequestLinter bool `json:"pullRequestLinter,omitempty"`
}
// RepositoryType defines the types of Repository
// +enum
type RepositoryType string
// RepositoryType values
const (
LocalRepositoryType RepositoryType = "local"
S3RepositoryType RepositoryType = "s3"
GitHubRepositoryType RepositoryType = "github"
)
type RepositorySpec struct {
// Describe the feature toggle
Title string `json:"title"`
// Describe the feature toggle
Description string `json:"description,omitempty"`
// The folder that is backed by the repository.
// The value is a reference to the Kubernetes metadata name of the folder in the same namespace.
Folder string `json:"folder,omitempty"`
// Should we prefer emitting YAML for this repository, e.g. upon export?
// Editing existing dashboards will continue to emit the file format used in the repository. (TODO: implement this)
// If you delete and then recreate a dashboard, it will switch to the preferred format.
PreferYAML bool `json:"preferYaml,omitempty"`
// Edit options within the repository
Editing EditingOptions `json:"editing"`
// The repository type. When selected oneOf the values below should be non-nil
Type RepositoryType `json:"type"`
// Linting enables linting for this repository
Linting bool `json:"linting,omitempty"`
// The repository on the local file system.
// Mutually exclusive with s3 and github.
Local *LocalRepositoryConfig `json:"local,omitempty"`
// The repository in an S3 bucket.
// Mutually exclusive with local and github.
S3 *S3RepositoryConfig `json:"s3,omitempty"`
// The repository on GitHub.
// Mutually exclusive with local and s3.
// TODO: github or just 'git'??
GitHub *GitHubRepositoryConfig `json:"github,omitempty"`
}
type EditingOptions struct {
// End users can create new files in the remote file system
Create bool `json:"create"`
// End users can update existing files in the remote file system
Update bool `json:"update"`
// End users can delete existing files in the remote file system
Delete bool `json:"delete"`
}
// 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"`
// 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 (will be shown to users)
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)
Message []string `json:"message,omitempty"`
// The repository hash when the last sync ran
Hash string `json:"hash,omitempty"`
}
type WebhookStatus struct {
ID int64 `json:"id,omitempty"`
URL string `json:"url,omitempty"`
Secret string `json:"secret,omitempty"`
SubscribedEvents []string `json:"subscribedEvents,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type RepositoryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Repository `json:"items,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type HelloWorld struct {
metav1.TypeMeta `json:",inline"`
Whom string `json:"whom,omitempty"`
}
// 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"
)
// 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 commit hash (if exists)
Ref string `json:"ref,omitempty"`
// The repo hash value
Hash string `json:"hash,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"`
// Lint results
Lint []LintIssue `json:"lint,omitempty"`
// If errors exist, show them here
Errors []string `json:"errors,omitempty"`
}
// The kubernetes action required when loading a given resource
// +enum
type LintSeverity string
// ResourceAction values
const (
LintSeverityExclude LintSeverity = "exclude"
LintSeverityQuiet LintSeverity = "quiet"
LintSeverityWarning LintSeverity = "warning"
LintSeverityError LintSeverity = "error"
LintSeverityFixed LintSeverity = "fixed"
)
type LintIssue struct {
Severity LintSeverity `json:"severity"`
Rule string `json:"rule"`
Message string `json:"message"`
}
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"`
}
// 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"`
// should be named "items", but avoid subresource error for now:
// kubernetes/kubernetes#126809
Items []FileItem `json:"files,omitempty"`
}
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"`
}
// 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"`
// Error descriptions
Errors []string `json:"errors,omitempty"`
// Optional details
Details *common.Unstructured `json:"details,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"`
// should be named "items", but avoid subresource error for now:
// kubernetes/kubernetes#126809
Items []HistoryItem `json:"items,omitempty"`
}
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"`
Authors []Author `json:"authors"`
CreatedAt int64 `json:"createdAt"`
}
@@ -0,0 +1,651 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
// SPDX-License-Identifier: AGPL-3.0-only
// Code generated by deepcopy-gen. DO NOT EDIT.
package v0alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Author) DeepCopyInto(out *Author) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Author.
func (in *Author) DeepCopy() *Author {
if in == nil {
return nil
}
out := new(Author)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *EditingOptions) DeepCopyInto(out *EditingOptions) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EditingOptions.
func (in *EditingOptions) DeepCopy() *EditingOptions {
if in == nil {
return nil
}
out := new(EditingOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FileItem) DeepCopyInto(out *FileItem) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FileItem.
func (in *FileItem) DeepCopy() *FileItem {
if in == nil {
return nil
}
out := new(FileItem)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FileList) DeepCopyInto(out *FileList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FileItem, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FileList.
func (in *FileList) DeepCopy() *FileList {
if in == nil {
return nil
}
out := new(FileList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FileList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitHubRepositoryConfig) DeepCopyInto(out *GitHubRepositoryConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitHubRepositoryConfig.
func (in *GitHubRepositoryConfig) DeepCopy() *GitHubRepositoryConfig {
if in == nil {
return nil
}
out := new(GitHubRepositoryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HealthStatus) DeepCopyInto(out *HealthStatus) {
*out = *in
if in.Message != nil {
in, out := &in.Message, &out.Message
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthStatus.
func (in *HealthStatus) DeepCopy() *HealthStatus {
if in == nil {
return nil
}
out := new(HealthStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelloWorld) DeepCopyInto(out *HelloWorld) {
*out = *in
out.TypeMeta = in.TypeMeta
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelloWorld.
func (in *HelloWorld) DeepCopy() *HelloWorld {
if in == nil {
return nil
}
out := new(HelloWorld)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HelloWorld) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HistoryItem) DeepCopyInto(out *HistoryItem) {
*out = *in
if in.Authors != nil {
in, out := &in.Authors, &out.Authors
*out = make([]Author, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HistoryItem.
func (in *HistoryItem) DeepCopy() *HistoryItem {
if in == nil {
return nil
}
out := new(HistoryItem)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HistoryList) DeepCopyInto(out *HistoryList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]HistoryItem, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HistoryList.
func (in *HistoryList) DeepCopy() *HistoryList {
if in == nil {
return nil
}
out := new(HistoryList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HistoryList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Job) DeepCopyInto(out *Job) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Job.
func (in *Job) DeepCopy() *Job {
if in == nil {
return nil
}
out := new(Job)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Job) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JobList) DeepCopyInto(out *JobList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Job, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobList.
func (in *JobList) DeepCopy() *JobList {
if in == nil {
return nil
}
out := new(JobList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *JobList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JobSpec) DeepCopyInto(out *JobSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobSpec.
func (in *JobSpec) DeepCopy() *JobSpec {
if in == nil {
return nil
}
out := new(JobSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JobStatus) DeepCopyInto(out *JobStatus) {
*out = *in
if in.Errors != nil {
in, out := &in.Errors, &out.Errors
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobStatus.
func (in *JobStatus) DeepCopy() *JobStatus {
if in == nil {
return nil
}
out := new(JobStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LintIssue) DeepCopyInto(out *LintIssue) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LintIssue.
func (in *LintIssue) DeepCopy() *LintIssue {
if in == nil {
return nil
}
out := new(LintIssue)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LocalRepositoryConfig) DeepCopyInto(out *LocalRepositoryConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalRepositoryConfig.
func (in *LocalRepositoryConfig) DeepCopy() *LocalRepositoryConfig {
if in == nil {
return nil
}
out := new(LocalRepositoryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Repository) DeepCopyInto(out *Repository) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repository.
func (in *Repository) DeepCopy() *Repository {
if in == nil {
return nil
}
out := new(Repository)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Repository) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RepositoryList) DeepCopyInto(out *RepositoryList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Repository, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryList.
func (in *RepositoryList) DeepCopy() *RepositoryList {
if in == nil {
return nil
}
out := new(RepositoryList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *RepositoryList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) {
*out = *in
out.Editing = in.Editing
if in.Local != nil {
in, out := &in.Local, &out.Local
*out = new(LocalRepositoryConfig)
**out = **in
}
if in.S3 != nil {
in, out := &in.S3, &out.S3
*out = new(S3RepositoryConfig)
**out = **in
}
if in.GitHub != nil {
in, out := &in.GitHub, &out.GitHub
*out = new(GitHubRepositoryConfig)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositorySpec.
func (in *RepositorySpec) DeepCopy() *RepositorySpec {
if in == nil {
return nil
}
out := new(RepositorySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RepositoryStatus) DeepCopyInto(out *RepositoryStatus) {
*out = *in
in.Health.DeepCopyInto(&out.Health)
in.Sync.DeepCopyInto(&out.Sync)
if in.Webhook != nil {
in, out := &in.Webhook, &out.Webhook
*out = new(WebhookStatus)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepositoryStatus.
func (in *RepositoryStatus) DeepCopy() *RepositoryStatus {
if in == nil {
return nil
}
out := new(RepositoryStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceObjects) DeepCopyInto(out *ResourceObjects) {
*out = *in
out.Type = in.Type
in.File.DeepCopyInto(&out.File)
in.Existing.DeepCopyInto(&out.Existing)
in.DryRun.DeepCopyInto(&out.DryRun)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceObjects.
func (in *ResourceObjects) DeepCopy() *ResourceObjects {
if in == nil {
return nil
}
out := new(ResourceObjects)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceType) DeepCopyInto(out *ResourceType) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceType.
func (in *ResourceType) DeepCopy() *ResourceType {
if in == nil {
return nil
}
out := new(ResourceType)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceWrapper) DeepCopyInto(out *ResourceWrapper) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Timestamp != nil {
in, out := &in.Timestamp, &out.Timestamp
*out = (*in).DeepCopy()
}
in.Resource.DeepCopyInto(&out.Resource)
if in.Lint != nil {
in, out := &in.Lint, &out.Lint
*out = make([]LintIssue, len(*in))
copy(*out, *in)
}
if in.Errors != nil {
in, out := &in.Errors, &out.Errors
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceWrapper.
func (in *ResourceWrapper) DeepCopy() *ResourceWrapper {
if in == nil {
return nil
}
out := new(ResourceWrapper)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ResourceWrapper) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *S3RepositoryConfig) DeepCopyInto(out *S3RepositoryConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3RepositoryConfig.
func (in *S3RepositoryConfig) DeepCopy() *S3RepositoryConfig {
if in == nil {
return nil
}
out := new(S3RepositoryConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SyncStatus) DeepCopyInto(out *SyncStatus) {
*out = *in
if in.Message != nil {
in, out := &in.Message, &out.Message
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncStatus.
func (in *SyncStatus) DeepCopy() *SyncStatus {
if in == nil {
return nil
}
out := new(SyncStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TestResults) DeepCopyInto(out *TestResults) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Errors != nil {
in, out := &in.Errors, &out.Errors
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Details != nil {
in, out := &in.Details, &out.Details
*out = (*in).DeepCopy()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestResults.
func (in *TestResults) DeepCopy() *TestResults {
if in == nil {
return nil
}
out := new(TestResults)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *TestResults) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookResponse) DeepCopyInto(out *WebhookResponse) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Job != nil {
in, out := &in.Job, &out.Job
*out = new(JobSpec)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookResponse.
func (in *WebhookResponse) DeepCopy() *WebhookResponse {
if in == nil {
return nil
}
out := new(WebhookResponse)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *WebhookResponse) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WebhookStatus) DeepCopyInto(out *WebhookStatus) {
*out = *in
if in.SubscribedEvents != nil {
in, out := &in.SubscribedEvents, &out.SubscribedEvents
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookStatus.
func (in *WebhookStatus) DeepCopy() *WebhookStatus {
if in == nil {
return nil
}
out := new(WebhookStatus)
in.DeepCopyInto(out)
return out
}
@@ -0,0 +1,19 @@
//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
@@ -0,0 +1,13 @@
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,HealthStatus,Message
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,HistoryItem,Authors
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,ResourceWrapper,Errors
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceWrapper,Lint
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,SyncStatus,Message
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,FileList,Items
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,PreferYAML
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