k3s/vendor/sigs.k8s.io/kustomize/api/resource/factory.go

182 lines
4.9 KiB
Go
Raw Normal View History

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource
import (
"encoding/json"
"fmt"
"log"
"strings"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/kusterr"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/types"
)
// Factory makes instances of Resource.
type Factory struct {
kf ifc.KunstructuredFactory
}
// NewFactory makes an instance of Factory.
func NewFactory(kf ifc.KunstructuredFactory) *Factory {
return &Factory{kf: kf}
}
func (rf *Factory) Hasher() ifc.KunstructuredHasher {
return rf.kf.Hasher()
}
// FromMap returns a new instance of Resource.
func (rf *Factory) FromMap(m map[string]interface{}) *Resource {
return rf.makeOne(rf.kf.FromMap(m), nil)
}
// FromMapWithName returns a new instance with the given "original" name.
func (rf *Factory) FromMapWithName(n string, m map[string]interface{}) *Resource {
return rf.FromMapWithNamespaceAndName(resid.DefaultNamespace, n, m)
}
// FromMapWithNamespaceAndName returns a new instance with the given "original" namespace.
func (rf *Factory) FromMapWithNamespaceAndName(ns string, n string, m map[string]interface{}) *Resource {
return rf.makeOne(rf.kf.FromMap(m), nil).setPreviousNamespaceAndName(ns, n)
}
// FromMapAndOption returns a new instance of Resource with given options.
func (rf *Factory) FromMapAndOption(
m map[string]interface{}, args *types.GeneratorArgs) *Resource {
return rf.makeOne(rf.kf.FromMap(m), types.NewGenArgs(args))
}
// FromKunstructured returns a new instance of Resource.
func (rf *Factory) FromKunstructured(u ifc.Kunstructured) *Resource {
return rf.makeOne(u, nil)
}
// makeOne returns a new instance of Resource.
func (rf *Factory) makeOne(
u ifc.Kunstructured, o *types.GenArgs) *Resource {
if u == nil {
log.Fatal("unstruct ifc must not be null")
}
if o == nil {
o = types.NewGenArgs(nil)
}
r := &Resource{
kunStr: u,
options: o,
}
return r
}
// SliceFromPatches returns a slice of resources given a patch path
// slice from a kustomization file.
func (rf *Factory) SliceFromPatches(
ldr ifc.Loader, paths []types.PatchStrategicMerge) ([]*Resource, error) {
var result []*Resource
for _, path := range paths {
content, err := ldr.Load(string(path))
if err != nil {
return nil, err
}
res, err := rf.SliceFromBytes(content)
if err != nil {
return nil, kusterr.Handler(err, string(path))
}
result = append(result, res...)
}
return result, nil
}
// FromBytes unmarshalls bytes into one Resource.
func (rf *Factory) FromBytes(in []byte) (*Resource, error) {
result, err := rf.SliceFromBytes(in)
if err != nil {
return nil, err
}
if len(result) != 1 {
return nil, fmt.Errorf(
"expected 1 resource, found %d in %v", len(result), in)
}
return result[0], nil
}
// SliceFromBytes unmarshals bytes into a Resource slice.
func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) {
kunStructs, err := rf.kf.SliceFromBytes(in)
if err != nil {
return nil, err
}
var result []*Resource
for len(kunStructs) > 0 {
u := kunStructs[0]
kunStructs = kunStructs[1:]
if strings.HasSuffix(u.GetKind(), "List") {
m, err := u.Map()
if err != nil {
return nil, err
}
items := m["items"]
itemsSlice, ok := items.([]interface{})
if !ok {
if items == nil {
// an empty list
continue
}
return nil, fmt.Errorf("items in List is type %T, expected array", items)
}
for _, item := range itemsSlice {
itemJSON, err := json.Marshal(item)
if err != nil {
return nil, err
}
innerU, err := rf.kf.SliceFromBytes(itemJSON)
if err != nil {
return nil, err
}
// append innerU to kunStructs so nested Lists can be handled
kunStructs = append(kunStructs, innerU...)
}
} else {
result = append(result, rf.FromKunstructured(u))
}
}
return result, nil
}
// SliceFromBytesWithNames unmarshals bytes into a Resource slice with specified original
// name.
func (rf *Factory) SliceFromBytesWithNames(names []string, in []byte) ([]*Resource, error) {
result, err := rf.SliceFromBytes(in)
if err != nil {
return nil, err
}
if len(names) != len(result) {
return nil, fmt.Errorf("number of names doesn't match number of resources")
}
for i, res := range result {
res.setPreviousNamespaceAndName(resid.DefaultNamespace, names[i])
}
return result, nil
}
// MakeConfigMap makes an instance of Resource for ConfigMap
func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs) (*Resource, error) {
u, err := rf.kf.MakeConfigMap(kvLdr, args)
if err != nil {
return nil, err
}
return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil
}
// MakeSecret makes an instance of Resource for Secret
func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Resource, error) {
u, err := rf.kf.MakeSecret(kvLdr, args)
if err != nil {
return nil, err
}
return rf.makeOne(u, types.NewGenArgs(&args.GeneratorArgs)), nil
}