update annotations

pull/101598/head
Ryan McKinley 5 months ago
parent e51c5796df
commit 0922a86c02
  1. 6
      pkg/registry/apis/provisioning/controller/finalizers.go
  2. 4
      pkg/registry/apis/provisioning/jobs/export/resources.go
  3. 9
      pkg/registry/apis/provisioning/jobs/migrate/resources.go
  4. 11
      pkg/registry/apis/provisioning/jobs/sync/worker.go
  5. 18
      pkg/registry/apis/provisioning/resources/parser.go
  6. 3
      pkg/registry/apis/provisioning/resources/tree.go
  7. 16
      public/app/features/apiserver/types.ts
  8. 16
      public/app/features/dashboard-scene/saving/provisioned/hooks.ts
  9. 8
      public/app/features/provisioning/dashboard.ts

@ -54,9 +54,9 @@ func (f *finalizer) process(ctx context.Context,
err := f.processExistingItems(ctx, repo.Config(),
func(client dynamic.ResourceInterface, item *provisioning.ResourceListItem) error {
_, err := client.Patch(ctx, item.Name, types.JSONPatchType, []byte(`[
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeyRepoName+`" },
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeyRepoPath+`" },
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeyRepoHash+`" }
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeyManagerKind+`" },
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeyManagerIdentity+`" },
{"op": "remove", "path": "/metadata/annotations/`+utils.AnnoKeySourcePath+`" }
]`), v1.PatchOptions{})
return err
})

@ -92,8 +92,8 @@ func (r *exportJob) write(ctx context.Context, obj *unstructured.Unstructured) j
}
name := meta.GetName()
repoName := meta.GetRepositoryName()
if repoName == r.target.Config().GetName() {
manager, _ := meta.GetManagerProperties()
if manager.Identity == r.target.Config().GetName() {
result.Action = repository.FileActionIgnored
return result
}

@ -48,8 +48,9 @@ func (r *resourceReader) Write(ctx context.Context, key *resource.ResourceKey, v
return fmt.Errorf("failed to unmarshal unstructured: %w", err)
}
// clear anything so it will get written
parsed.Meta.SetRepositoryInfo(nil)
// clear all manager fields so they are not exported
parsed.Meta.SetManagerProperties(utils.ManagerProperties{})
parsed.Meta.SetSourceProperties(utils.SourceProperties{})
if result := r.job.write(ctx, parsed.Obj); result.Error != nil {
r.job.progress.Record(ctx, result)
@ -134,8 +135,8 @@ func (j *migrationJob) write(ctx context.Context, obj *unstructured.Unstructured
}
name := meta.GetName()
repoName := meta.GetRepositoryName()
if repoName == j.target.Config().GetName() {
manager, _ := meta.GetManagerProperties()
if manager.Identity == j.target.Config().GetName() {
result.Action = repository.FileActionIgnored
return result
}

@ -538,7 +538,7 @@ func (r *syncJob) ensureFolderExists(ctx context.Context, folder resources.Folde
cfg := r.repository.Config()
obj, err := r.folders.Get(ctx, folder.ID, metav1.GetOptions{})
if err == nil {
current, ok := obj.GetAnnotations()[utils.AnnoKeyRepoName]
current, ok := obj.GetAnnotations()[utils.AnnoKeyManagerIdentity]
if !ok {
return fmt.Errorf("target folder is not managed by a repository")
}
@ -568,11 +568,12 @@ func (r *syncJob) ensureFolderExists(ctx context.Context, folder resources.Folde
if parent != "" {
meta.SetFolder(parent)
}
meta.SetRepositoryInfo(&utils.ResourceRepositoryInfo{
Name: cfg.GetName(),
meta.SetManagerProperties(utils.ManagerProperties{
Kind: utils.ManagerKindRepo,
Identity: cfg.GetName(),
})
meta.SetSourceProperties(utils.SourceProperties{
Path: folder.Path,
Hash: "", // FIXME: which hash?
Timestamp: nil, // ???&info.Modified.Time,
})
result := jobs.JobResourceResult{

@ -130,11 +130,14 @@ func (r *Parser) Parse(ctx context.Context, info *repository.FileInfo, validate
}
obj.SetNamespace(cfg.GetNamespace())
parsed.Meta.SetRepositoryInfo(&utils.ResourceRepositoryInfo{
Name: cfg.Name,
parsed.Meta.SetManagerProperties(utils.ManagerProperties{
Kind: utils.ManagerKindRepo,
Identity: cfg.Name,
})
parsed.Meta.SetSourceProperties(utils.SourceProperties{
Path: info.Path, // joinPathWithRef(info.Path, info.Ref),
Hash: info.Hash,
Timestamp: nil, // ???&info.Modified.Time,
Checksum: info.Hash,
TimestampMillis: asMillis(info.Modified),
})
// Calculate name+folder from the file path
@ -211,6 +214,13 @@ func (f *ParsedResource) ToSaveBytes() ([]byte, error) {
}
}
func asMillis(t *metav1.Time) int64 {
if t == nil || t.IsZero() {
return 0
}
return t.UnixMilli()
}
func (f *ParsedResource) AsResourceWrapper() *provisioning.ResourceWrapper {
info := f.Info
res := provisioning.ResourceObjects{

@ -104,7 +104,8 @@ func (t *FolderTree) AddUnstructured(item *unstructured.Unstructured, skipRepo s
if err != nil {
return fmt.Errorf("extract meta accessor: %w", err)
}
if meta.GetRepositoryName() == skipRepo {
manager, _ := meta.GetManagerProperties()
if manager.Identity == skipRepo {
return nil // skip it... already in tree?
}
folder := Folder{

@ -44,10 +44,10 @@ export const AnnoKeyMessage = 'grafana.app/message';
export const AnnoKeySlug = 'grafana.app/slug';
// Identify where values came from
export const AnnoKeyRepoName = 'grafana.app/repoName';
export const AnnoKeyRepoPath = 'grafana.app/repoPath';
export const AnnoKeyRepoHash = 'grafana.app/repoHash';
export const AnnoKeyRepoTimestamp = 'grafana.app/repoTimestamp';
export const AnnoKeyManagerKind = 'grafana.app/managerKind';
export const AnnoKeyManagerIdentity = 'grafana.app/managerIdentity';
export const AnnoKeySourcePath = 'grafana.app/sourcePath';
export const AnnoKeySourceChecksum = 'grafana.app/sourceChecksum';
export const AnnoKeySavedFromUI = 'grafana.app/saved-from-ui';
export const AnnoKeyDashboardNotFound = 'grafana.app/dashboard-not-found';
@ -66,10 +66,10 @@ type GrafanaAnnotations = {
[AnnoKeyFolder]?: string;
[AnnoKeySlug]?: string;
[AnnoKeyRepoName]?: string;
[AnnoKeyRepoPath]?: string;
[AnnoKeyRepoHash]?: string;
[AnnoKeyRepoTimestamp]?: string;
[AnnoKeyManagerKind]?: string;
[AnnoKeyManagerIdentity]?: string;
[AnnoKeySourcePath]?: string;
[AnnoKeySourceChecksum]?: string;
};
// Annotations provided by the front-end client

@ -1,7 +1,7 @@
import { Chance } from 'chance';
import { dateTime } from '@grafana/data';
import { AnnoKeyRepoName, AnnoKeyRepoPath } from 'app/features/apiserver/types';
import { AnnoKeyManagerKind, AnnoKeyManagerIdentity, AnnoKeySourcePath } from 'app/features/apiserver/types';
import { useGetResourceRepository } from 'app/features/provisioning/hooks';
import { DashboardMeta } from 'app/types';
@ -25,10 +25,12 @@ function generatePath(timestamp: string, pathFromAnnotation?: string, slug?: str
export function useDefaultValues({ meta, defaultTitle, defaultDescription }: UseDefaultValuesParams) {
const annotations = meta.k8s?.annotations;
const annoName = annotations?.[AnnoKeyRepoName];
const annoPath = annotations?.[AnnoKeyRepoPath];
const managerKind = annotations?.[AnnoKeyManagerKind];
const managerId = annotations?.[AnnoKeyManagerIdentity];
const sourcePath = annotations?.[AnnoKeySourcePath];
// Get config by resource name or folder UID for new resources
const repositoryConfig = useGetResourceRepository({ name: annoName, folderUid: meta.folderUid });
const repositoryConfig =
managerKind === 'repo' ? useGetResourceRepository({ name: managerId, folderUid: meta.folderUid }) : undefined;
const repository = repositoryConfig?.spec;
const random = Chance(1);
@ -37,8 +39,8 @@ export function useDefaultValues({ meta, defaultTitle, defaultDescription }: Use
return {
values: {
ref: `dashboard/${timestamp}`,
path: generatePath(timestamp, annoPath, meta.slug),
repo: annoName || repositoryConfig?.metadata?.name || '',
path: generatePath(timestamp, sourcePath, meta.slug),
repo: managerId || repositoryConfig?.metadata?.name || '',
comment: '',
folder: {
uid: meta.folderUid,
@ -48,7 +50,7 @@ export function useDefaultValues({ meta, defaultTitle, defaultDescription }: Use
description: defaultDescription ?? '',
workflow: getDefaultWorkflow(repository),
},
isNew: !annoName,
isNew: !managerId,
repositoryConfig: repository,
isGitHub: repository?.type === 'github',
};

@ -1,7 +1,7 @@
import { getBackendSrv } from '@grafana/runtime';
import { DashboardDTO } from 'app/types';
import { AnnoKeyRepoName, AnnoKeyRepoPath } from '../apiserver/types';
import { AnnoKeyManagerIdentity, AnnoKeySourcePath } from '../apiserver/types';
import { BASE_URL } from './api/baseAPI';
@ -32,10 +32,10 @@ export async function loadDashboardFromProvisioning(repo: string, path: string):
if (!anno) {
dryRun.metadata.annotations = anno = {};
}
anno[AnnoKeyRepoName] = repo;
anno[AnnoKeyRepoPath] = path;
anno[AnnoKeyManagerIdentity] = repo;
anno[AnnoKeySourcePath] = path;
if (ref) {
anno[AnnoKeyRepoPath] = path + '#' + ref;
anno[AnnoKeySourcePath] = path + '#' + ref;
}
return {

Loading…
Cancel
Save