Files
kustomize/pkg/resource/factory.go
jregan a7df00c07a Starting v3 release for plugin developers.
[doc]: https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher

Per this Go modules [doc] a repo or branch that's
already tagged v2 or higher should increment the major
version (e.g. go to v3) when releasing their first Go
module-based packages.

At the moment, the kustomize repo has these top level
packages in the sigs.k8s.io/kustomize module:

 - `cmd` - holds main program for kustomize

	 Conceivably someone can depend on this
	 package for integration tests.

 - `internal` - intentionally unreleased subpackages

 - `k8sdeps` - an adapter wrapping k8s dependencies

	 This exists only for use in pre-Go-modules kustomize-into-kubectl
	 integration and won't live much longer (as everything involved is
	 switching to Go modules).

 - `pkg` - kustomize packages for export

	 This should shrink in later versions, since
	 the surface area is too large, containing
	 sub-packages that should be in 'internal'.

 - `plugin` - holds main programs for plugins

This PR changes the top level go.mod file from

```
module sigs.k8s.io/kustomize
```

to

```
module sigs.k8s.io/kustomize/v3
```

and adjusts all import statements to
reflect the change.
2019-06-23 15:05:59 -07:00

175 lines
4.5 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource
import (
"encoding/json"
"fmt"
"log"
"strings"
"sigs.k8s.io/kustomize/v3/internal/kusterr"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
"sigs.k8s.io/kustomize/v3/pkg/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.makeOne(rf.kf.FromMap(m), nil).setOriginalName(n)
}
// FromMapWithNamespace returns a new instance with the given "original" namespace.
func (rf *Factory) FromMapWithNamespace(n string, m map[string]interface{}) *Resource {
return rf.makeOne(rf.kf.FromMap(m), nil).setOriginalNs(n)
}
// FromMapAndOption returns a new instance of Resource with given options.
func (rf *Factory) FromMapAndOption(
m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *Resource {
return rf.makeOne(rf.kf.FromMap(m), types.NewGenArgs(args, option))
}
// 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, nil)
}
r := &Resource{
Kunstructured: u,
options: o,
}
return r.setOriginalName(r.GetName()).setOriginalNs(r.GetNamespace())
}
// 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 unmarshals 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") {
items := u.Map()["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
}
// MakeConfigMap makes an instance of Resource for ConfigMap
func (rf *Factory) MakeConfigMap(
ldr ifc.Loader,
options *types.GeneratorOptions,
args *types.ConfigMapArgs) (*Resource, error) {
u, err := rf.kf.MakeConfigMap(ldr, options, args)
if err != nil {
return nil, err
}
return rf.makeOne(
u,
types.NewGenArgs(
&types.GeneratorArgs{Behavior: args.Behavior},
options)), nil
}
// MakeSecret makes an instance of Resource for Secret
func (rf *Factory) MakeSecret(
ldr ifc.Loader,
options *types.GeneratorOptions,
args *types.SecretArgs) (*Resource, error) {
u, err := rf.kf.MakeSecret(ldr, options, args)
if err != nil {
return nil, err
}
return rf.makeOne(
u,
types.NewGenArgs(
&types.GeneratorArgs{Behavior: args.Behavior},
options)), nil
}