Provisioning: Require a name in the saved resource (#103309)

This commit is contained in:
Ryan McKinley
2025-04-03 18:58:05 +03:00
committed by GitHub
parent c7754d7065
commit c5d76a8bba
23 changed files with 609 additions and 264 deletions
@@ -12,6 +12,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/client-go/dynamic"
"github.com/grafana/grafana-app-sdk/logging"
@@ -60,7 +61,7 @@ type Parser struct {
urls repository.RepositoryWithURLs
// ResourceClients give access to k8s apis
clients *ResourceClients
clients ResourceClients
}
type ParsedResource struct {
@@ -105,9 +106,8 @@ type ParsedResource struct {
Errors []error
}
// FIXME: eliminate clients from parser
func (r *Parser) Clients() *ResourceClients {
// FIXME: eliminate clients from parser (but be careful that we can use the same cache/resolved GVK+GVR)
func (r *Parser) Clients() ResourceClients {
return r.clients
}
@@ -168,13 +168,14 @@ func (r *Parser) Parse(ctx context.Context, info *repository.FileInfo, validate
Checksum: info.Hash,
})
// Calculate name+folder from the file path
if info.Path != "" {
objName := FileNameFromHashedRepoPath(r.repo.Name, info.Path)
if obj.GetName() == "" {
obj.SetName(objName) // use the name saved in config
}
if obj.GetName() == "" && obj.GetGenerateName() == "" {
parsed.Errors = append(parsed.Errors,
field.Required(field.NewPath("name", "metadata", "name"),
"An explicit name must be saved in the resource (or generateName)"))
}
// Calculate folder identifier from the file path
if info.Path != "" {
dirPath := safepath.Dir(info.Path)
if dirPath != "" {
parsed.Meta.SetFolder(ParseFolder(dirPath, r.repo.Name).ID)
@@ -221,6 +222,12 @@ func (r *Parser) Parse(ctx context.Context, info *repository.FileInfo, validate
DryRun: []string{"All"},
})
}
// When the name is missing (and generateName is configured) use the value from DryRun
if obj.GetName() == "" && parsed.DryRunResponse != nil {
obj.SetName(parsed.DryRunResponse.GetName())
}
if err != nil {
parsed.Errors = append(parsed.Errors, err)
}
@@ -228,12 +235,13 @@ func (r *Parser) Parse(ctx context.Context, info *repository.FileInfo, validate
}
func (f *ParsedResource) ToSaveBytes() ([]byte, error) {
// TODO? should we use the dryRun (validated) version?
obj := make(map[string]any)
for k, v := range f.Obj.Object {
if k != "metadata" {
obj[k] = v
}
obj := f.Obj.DeepCopy().Object
delete(obj, "status")
name := f.Obj.GetName()
if name == "" {
delete(obj, "metadata")
} else {
obj["metadata"] = map[string]any{"name": name}
}
switch path.Ext(f.Info.Path) {