mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 01:50:55 +00:00
Drain more code from kusttarget.
This commit is contained in:
@@ -50,7 +50,8 @@ type KustTarget struct {
|
|||||||
|
|
||||||
// NewKustTarget returns a new instance of KustTarget primed with a Loader.
|
// NewKustTarget returns a new instance of KustTarget primed with a Loader.
|
||||||
func NewKustTarget(
|
func NewKustTarget(
|
||||||
ldr ifc.Loader, fSys fs.FileSystem,
|
ldr ifc.Loader,
|
||||||
|
fSys fs.FileSystem,
|
||||||
rFactory *resmap.Factory,
|
rFactory *resmap.Factory,
|
||||||
tFactory transformer.Factory) (*KustTarget, error) {
|
tFactory transformer.Factory) (*KustTarget, error) {
|
||||||
content, err := loadKustFile(ldr)
|
content, err := loadKustFile(ldr)
|
||||||
@@ -80,6 +81,21 @@ func NewKustTarget(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
||||||
|
for _, kf := range []string{
|
||||||
|
constants.KustomizationFileName,
|
||||||
|
constants.SecondaryKustomizationFileName} {
|
||||||
|
content, err := ldr.Load(kf)
|
||||||
|
if err == nil {
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "no such file or directory") {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root())
|
||||||
|
}
|
||||||
|
|
||||||
func unmarshal(y []byte, o interface{}) error {
|
func unmarshal(y []byte, o interface{}) error {
|
||||||
j, err := yaml.YAMLToJSON(y)
|
j, err := yaml.YAMLToJSON(y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,47 +106,6 @@ func unmarshal(y []byte, o interface{}) error {
|
|||||||
return dec.Decode(o)
|
return dec.Decode(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(#6060) Maybe switch to the false path permanently
|
|
||||||
// (desired by #606), or expose this as a new customization
|
|
||||||
// directive.
|
|
||||||
const demandExplicitConfig = true
|
|
||||||
|
|
||||||
func makeTransformerConfig(
|
|
||||||
ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) {
|
|
||||||
if demandExplicitConfig {
|
|
||||||
return loadConfigFromDiskOrDefaults(ldr, paths)
|
|
||||||
}
|
|
||||||
return mergeCustomConfigWithDefaults(ldr, paths)
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadConfigFromDiskOrDefaults returns a TransformerConfig object
|
|
||||||
// built from either files or the hardcoded default configs.
|
|
||||||
// There's no merging, it's one or the other. This is preferred if one
|
|
||||||
// wants all configuration to be explicit in version control, as
|
|
||||||
// opposed to relying on a mix of files and hard coded config.
|
|
||||||
func loadConfigFromDiskOrDefaults(
|
|
||||||
ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) {
|
|
||||||
if paths == nil || len(paths) == 0 {
|
|
||||||
return config.NewFactory(nil).DefaultConfig(), nil
|
|
||||||
}
|
|
||||||
return config.NewFactory(ldr).FromFiles(paths)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mergeCustomConfigWithDefaults returns a merger of custom config,
|
|
||||||
// if any, with default config.
|
|
||||||
func mergeCustomConfigWithDefaults(
|
|
||||||
ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) {
|
|
||||||
t1 := config.NewFactory(nil).DefaultConfig()
|
|
||||||
if len(paths) == 0 {
|
|
||||||
return t1, nil
|
|
||||||
}
|
|
||||||
t2, err := config.NewFactory(ldr).FromFiles(paths)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return t1.Merge(t2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeCustomizedResMap creates a ResMap per kustomization instructions.
|
// MakeCustomizedResMap creates a ResMap per kustomization instructions.
|
||||||
// The Resources in the returned ResMap are fully customized.
|
// The Resources in the returned ResMap are fully customized.
|
||||||
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
||||||
@@ -186,7 +161,7 @@ func (kt *KustTarget) accumulateTarget() (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision"))
|
errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision"))
|
||||||
}
|
}
|
||||||
tConfig, err := makeTransformerConfig(
|
tConfig, err := config.MakeTransformerConfig(
|
||||||
kt.ldr, kt.kustomization.Configurations)
|
kt.ldr, kt.kustomization.Configurations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -199,7 +174,7 @@ func (kt *KustTarget) accumulateTarget() (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
errs.Append(errors.Wrap(err, "MergeVars"))
|
errs.Append(errors.Wrap(err, "MergeVars"))
|
||||||
}
|
}
|
||||||
crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds)
|
crdTc, err := config.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.Append(errors.Wrap(err, "LoadCRDs"))
|
errs.Append(errors.Wrap(err, "LoadCRDs"))
|
||||||
}
|
}
|
||||||
@@ -334,18 +309,3 @@ func (kt *KustTarget) newTransformer(
|
|||||||
r = append(r, t)
|
r = append(r, t)
|
||||||
return transformers.NewMultiTransformer(r), nil
|
return transformers.NewMultiTransformer(r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
|
||||||
for _, kf := range []string{
|
|
||||||
constants.KustomizationFileName,
|
|
||||||
constants.SecondaryKustomizationFileName} {
|
|
||||||
content, err := ldr.Load(kf)
|
|
||||||
if err == nil {
|
|
||||||
return content, nil
|
|
||||||
}
|
|
||||||
if !strings.Contains(err.Error(), "no such file or directory") {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import (
|
|||||||
|
|
||||||
func TestResolveVars(t *testing.T) {
|
func TestResolveVars(t *testing.T) {
|
||||||
ra := MakeEmptyAccumulator()
|
ra := MakeEmptyAccumulator()
|
||||||
err := ra.MergeConfig(config.NewFactory(nil).DefaultConfig())
|
err := ra.MergeConfig(config.MakeDefaultConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected err: %v", err)
|
t.Fatalf("unexpected err: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
// Annotation is to mark a field as annotations.
|
|
||||||
// "x-kubernetes-annotation": ""
|
|
||||||
const Annotation = "x-kubernetes-annotation"
|
|
||||||
|
|
||||||
// LabelSelector is to mark a field as LabelSelector
|
|
||||||
// "x-kubernetes-label-selector": ""
|
|
||||||
const LabelSelector = "x-kubernetes-label-selector"
|
|
||||||
|
|
||||||
// Identity is to mark a field as Identity
|
|
||||||
// "x-kubernetes-identity": ""
|
|
||||||
const Identity = "x-kubernetes-identity"
|
|
||||||
|
|
||||||
// Version marks the type version of an object ref field
|
|
||||||
// "x-kubernetes-object-ref-api-version": <apiVersion name>
|
|
||||||
const Version = "x-kubernetes-object-ref-api-version"
|
|
||||||
|
|
||||||
// Kind marks the type name of an object ref field
|
|
||||||
// "x-kubernetes-object-ref-kind": <kind name>
|
|
||||||
const Kind = "x-kubernetes-object-ref-kind"
|
|
||||||
|
|
||||||
// NameKey marks the field key that refers to an object of an object ref field
|
|
||||||
// "x-kubernetes-object-ref-name-key": "name"
|
|
||||||
// default is "name"
|
|
||||||
const NameKey = "x-kubernetes-object-ref-name-key"
|
|
||||||
@@ -21,7 +21,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
"sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Factory makes instances of TransformerConfig.
|
// Factory makes instances of TransformerConfig.
|
||||||
@@ -29,6 +28,48 @@ type Factory struct {
|
|||||||
ldr ifc.Loader
|
ldr ifc.Loader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(#6060) Maybe switch to the false path permanently
|
||||||
|
// (desired by #606), or expose this as a new customization
|
||||||
|
// directive.
|
||||||
|
const demandExplicitConfig = true
|
||||||
|
|
||||||
|
func MakeTransformerConfig(
|
||||||
|
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||||
|
if demandExplicitConfig {
|
||||||
|
return loadConfigFromDiskOrDefaults(ldr, paths)
|
||||||
|
}
|
||||||
|
return mergeCustomConfigWithDefaults(ldr, paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadConfigFromDiskOrDefaults returns a TransformerConfig object
|
||||||
|
// built from either files or the hardcoded default configs.
|
||||||
|
// There's no merging, it's one or the other. This is preferred
|
||||||
|
// if one wants all configuration to be explicit in version
|
||||||
|
// control, as opposed to relying on a mix of files and
|
||||||
|
// hard-coded config.
|
||||||
|
func loadConfigFromDiskOrDefaults(
|
||||||
|
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||||
|
if paths == nil || len(paths) == 0 {
|
||||||
|
return MakeDefaultConfig(), nil
|
||||||
|
}
|
||||||
|
return NewFactory(ldr).FromFiles(paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergeCustomConfigWithDefaults returns a merger of custom config,
|
||||||
|
// if any, with default config.
|
||||||
|
func mergeCustomConfigWithDefaults(
|
||||||
|
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||||
|
t1 := MakeDefaultConfig()
|
||||||
|
if len(paths) == 0 {
|
||||||
|
return t1, nil
|
||||||
|
}
|
||||||
|
t2, err := NewFactory(ldr).FromFiles(paths)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return t1.Merge(t2)
|
||||||
|
}
|
||||||
|
|
||||||
func NewFactory(l ifc.Loader) *Factory {
|
func NewFactory(l ifc.Loader) *Factory {
|
||||||
return &Factory{ldr: l}
|
return &Factory{ldr: l}
|
||||||
}
|
}
|
||||||
@@ -71,19 +112,3 @@ func makeTransformerConfigFromBytes(data []byte) (*TransformerConfig, error) {
|
|||||||
t.sortFields()
|
t.sortFields()
|
||||||
return &t, nil
|
return &t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmptyConfig returns an empty TransformerConfig object
|
|
||||||
func (tf *Factory) EmptyConfig() *TransformerConfig {
|
|
||||||
return &TransformerConfig{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultConfig returns a default TransformerConfig.
|
|
||||||
// This should never fail, hence the Fatal panic.
|
|
||||||
func (tf *Factory) DefaultConfig() *TransformerConfig {
|
|
||||||
c, err := makeTransformerConfigFromBytes(
|
|
||||||
defaultconfig.GetDefaultFieldSpecs())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Unable to make default transformconfig: %v", err)
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,21 +25,28 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMakeDefaultTransformerConfig(t *testing.T) {
|
func TestMakeDefaultConfig(t *testing.T) {
|
||||||
// Confirm default can be made without fatal error inside call.
|
// Confirm default can be made without fatal error inside call.
|
||||||
l, _, _ := makeFakeLoaderAndOutput()
|
_ = MakeDefaultConfig()
|
||||||
_ = NewFactory(l).DefaultConfig()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeFakeLoaderAndOutput() (ifc.Loader, *TransformerConfig, *TransformerConfig) {
|
func makeTestLoader(path, content string) ifc.Loader {
|
||||||
transformerConfig := `
|
fs := fs.MakeFakeFS()
|
||||||
|
fs.WriteFile(path, []byte(content))
|
||||||
|
return loader.NewFileLoaderAtRoot(fs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromFiles(t *testing.T) {
|
||||||
|
path := "/transformerconfig/test/config.yaml"
|
||||||
|
ldr := makeTestLoader(path, `
|
||||||
namePrefix:
|
namePrefix:
|
||||||
- path: nameprefix/path
|
- path: nameprefix/path
|
||||||
kind: SomeKind
|
kind: SomeKind
|
||||||
`
|
`)
|
||||||
fakeFS := fs.MakeFakeFS()
|
tcfg, err := NewFactory(ldr).FromFiles([]string{"transformerconfig/test/config.yaml"})
|
||||||
fakeFS.WriteFile("/transformerconfig/test/config.yaml", []byte(transformerConfig))
|
if err != nil {
|
||||||
ldr := loader.NewFileLoaderAtRoot(fakeFS)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
expected := &TransformerConfig{
|
expected := &TransformerConfig{
|
||||||
NamePrefix: []FieldSpec{
|
NamePrefix: []FieldSpec{
|
||||||
{
|
{
|
||||||
@@ -48,16 +55,6 @@ namePrefix:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return ldr, expected, NewFactory(ldr).DefaultConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMakeTransformerConfigFromFiles(t *testing.T) {
|
|
||||||
ldr, expected, _ := makeFakeLoaderAndOutput()
|
|
||||||
tcfg, err := NewFactory(ldr).FromFiles([]string{"transformerconfig/test/config.yaml"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(tcfg, expected) {
|
if !reflect.DeepEqual(tcfg, expected) {
|
||||||
t.Fatalf("expected %v\n but go6t %v\n", expected, tcfg)
|
t.Fatalf("expected %v\n but go6t %v\n", expected, tcfg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,29 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
"github.com/go-openapi/spec"
|
||||||
"k8s.io/kube-openapi/pkg/common"
|
"k8s.io/kube-openapi/pkg/common"
|
||||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadCRDs parse CRD schemas from paths into a TransformerConfig
|
type myProperties map[string]spec.Schema
|
||||||
func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) {
|
type nameToApiMap map[string]common.OpenAPIDefinition
|
||||||
tc := tf.EmptyConfig()
|
|
||||||
|
// LoadConfigFromCRDs parse CRD schemas from paths into a TransformerConfig
|
||||||
|
func LoadConfigFromCRDs(
|
||||||
|
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||||
|
tc := MakeEmptyConfig()
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
otherTc, err := tf.loadCRD(path)
|
content, err := ldr.Load(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m, err := makeNameToApiMap(content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
otherTc, err := makeConfigFromApiMap(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -41,28 +55,24 @@ func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) {
|
|||||||
return tc, nil
|
return tc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) {
|
func makeNameToApiMap(content []byte) (result nameToApiMap, err error) {
|
||||||
result := tf.EmptyConfig()
|
|
||||||
content, err := tf.loader().Load(path)
|
|
||||||
if err != nil {
|
|
||||||
return result, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var types map[string]common.OpenAPIDefinition
|
|
||||||
if content[0] == '{' {
|
if content[0] == '{' {
|
||||||
err = json.Unmarshal(content, &types)
|
err = json.Unmarshal(content, &result)
|
||||||
} else {
|
} else {
|
||||||
err = yaml.Unmarshal(content, &types)
|
err = yaml.Unmarshal(content, &result)
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
crds := getCRDs(types)
|
func makeConfigFromApiMap(m nameToApiMap) (*TransformerConfig, error) {
|
||||||
for crd, k := range crds {
|
result := MakeEmptyConfig()
|
||||||
tc := tf.EmptyConfig()
|
for name, api := range m {
|
||||||
err = loadCrdIntoConfig(
|
if !looksLikeAk8sType(api.Schema.SchemaProps.Properties) {
|
||||||
types, crd, crd, k, []string{}, tc)
|
continue
|
||||||
|
}
|
||||||
|
tc := MakeEmptyConfig()
|
||||||
|
err := loadCrdIntoConfig(
|
||||||
|
tc, makeGvkFromTypeName(name), m, name, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@@ -71,107 +81,120 @@ func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCRDs get all CRD types
|
// TODO: Get Group and Version for CRD from the
|
||||||
func getCRDs(types map[string]common.OpenAPIDefinition) map[string]gvk.Gvk {
|
// openAPI definition once
|
||||||
crds := map[string]gvk.Gvk{}
|
// "x-kubernetes-group-version-kind" is available in CRD
|
||||||
|
func makeGvkFromTypeName(n string) gvk.Gvk {
|
||||||
for typename, t := range types {
|
names := strings.Split(n, ".")
|
||||||
properties := t.Schema.SchemaProps.Properties
|
kind := names[len(names)-1]
|
||||||
_, foundKind := properties["kind"]
|
return gvk.Gvk{Kind: kind}
|
||||||
_, foundAPIVersion := properties["apiVersion"]
|
|
||||||
_, foundMetadata := properties["metadata"]
|
|
||||||
if foundKind && foundAPIVersion && foundMetadata {
|
|
||||||
// TODO: Get Group and Version for CRD from the openAPI definition once
|
|
||||||
// "x-kubernetes-group-version-kind" is available in CRD
|
|
||||||
kind := strings.Split(typename, ".")[len(strings.Split(typename, "."))-1]
|
|
||||||
crds[typename] = gvk.Gvk{Kind: kind}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return crds
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func looksLikeAk8sType(properties myProperties) bool {
|
||||||
|
_, ok := properties["kind"]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok = properties["apiVersion"]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok = properties["metadata"]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// "x-kubernetes-annotation": ""
|
||||||
|
xAnnotation = "x-kubernetes-annotation"
|
||||||
|
|
||||||
|
// "x-kubernetes-label-selector": ""
|
||||||
|
xLabelSelector = "x-kubernetes-label-selector"
|
||||||
|
|
||||||
|
// "x-kubernetes-identity": ""
|
||||||
|
xIdentity = "x-kubernetes-identity"
|
||||||
|
|
||||||
|
// "x-kubernetes-object-ref-api-version": <apiVersion name>
|
||||||
|
xVersion = "x-kubernetes-object-ref-api-version"
|
||||||
|
|
||||||
|
// "x-kubernetes-object-ref-kind": <kind name>
|
||||||
|
xKind = "x-kubernetes-object-ref-kind"
|
||||||
|
|
||||||
|
// "x-kubernetes-object-ref-name-key": "name"
|
||||||
|
// default is "name"
|
||||||
|
xNameKey = "x-kubernetes-object-ref-name-key"
|
||||||
|
)
|
||||||
|
|
||||||
// loadCrdIntoConfig loads a CRD spec into a TransformerConfig
|
// loadCrdIntoConfig loads a CRD spec into a TransformerConfig
|
||||||
func loadCrdIntoConfig(
|
func loadCrdIntoConfig(
|
||||||
types map[string]common.OpenAPIDefinition,
|
theConfig *TransformerConfig, theGvk gvk.Gvk, theMap nameToApiMap,
|
||||||
atype string, crd string, in gvk.Gvk,
|
typeName string, path []string) (err error) {
|
||||||
path []string, config *TransformerConfig) (err error) {
|
api, ok := theMap[typeName]
|
||||||
if _, ok := types[crd]; !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
for propName, property := range api.Schema.SchemaProps.Properties {
|
||||||
for propname, property := range types[atype].Schema.SchemaProps.Properties {
|
_, annotate := property.Extensions.GetString(xAnnotation)
|
||||||
_, annotate := property.Extensions.GetString(Annotation)
|
|
||||||
if annotate {
|
if annotate {
|
||||||
err = config.AddAnnotationFieldSpec(
|
err = theConfig.AddAnnotationFieldSpec(
|
||||||
FieldSpec{
|
makeFs(theGvk, append(path, propName)))
|
||||||
CreateIfNotPresent: false,
|
|
||||||
Gvk: in,
|
|
||||||
Path: strings.Join(append(path, propname), "/"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, label := property.Extensions.GetString(LabelSelector)
|
_, label := property.Extensions.GetString(xLabelSelector)
|
||||||
if label {
|
if label {
|
||||||
err = config.AddLabelFieldSpec(
|
err = theConfig.AddLabelFieldSpec(
|
||||||
FieldSpec{
|
makeFs(theGvk, append(path, propName)))
|
||||||
CreateIfNotPresent: false,
|
|
||||||
Gvk: in,
|
|
||||||
Path: strings.Join(append(path, propname), "/"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, identity := property.Extensions.GetString(Identity)
|
_, identity := property.Extensions.GetString(xIdentity)
|
||||||
if identity {
|
if identity {
|
||||||
err = config.AddPrefixFieldSpec(
|
err = theConfig.AddPrefixFieldSpec(
|
||||||
FieldSpec{
|
makeFs(theGvk, append(path, propName)))
|
||||||
CreateIfNotPresent: false,
|
|
||||||
Gvk: in,
|
|
||||||
Path: strings.Join(append(path, propname), "/"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
version, ok := property.Extensions.GetString(Version)
|
version, ok := property.Extensions.GetString(xVersion)
|
||||||
if ok {
|
if ok {
|
||||||
kind, ok := property.Extensions.GetString(Kind)
|
kind, ok := property.Extensions.GetString(xKind)
|
||||||
if ok {
|
if ok {
|
||||||
nameKey, ok := property.Extensions.GetString(NameKey)
|
nameKey, ok := property.Extensions.GetString(xNameKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
nameKey = "name"
|
nameKey = "name"
|
||||||
}
|
}
|
||||||
err = config.AddNamereferenceFieldSpec(NameBackReferences{
|
err = theConfig.AddNamereferenceFieldSpec(
|
||||||
Gvk: gvk.Gvk{Kind: kind, Version: version},
|
NameBackReferences{
|
||||||
FieldSpecs: []FieldSpec{
|
Gvk: gvk.Gvk{Kind: kind, Version: version},
|
||||||
{
|
FieldSpecs: []FieldSpec{
|
||||||
CreateIfNotPresent: false,
|
makeFs(theGvk, append(path, propName, nameKey))},
|
||||||
Gvk: in,
|
})
|
||||||
Path: strings.Join(append(path, propname, nameKey), "/"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if property.Ref.GetURL() != nil {
|
if property.Ref.GetURL() != nil {
|
||||||
loadCrdIntoConfig(
|
loadCrdIntoConfig(
|
||||||
types, property.Ref.String(), crd, in,
|
theConfig, theGvk, theMap,
|
||||||
append(path, propname), config)
|
property.Ref.String(), append(path, propName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeFs(in gvk.Gvk, path []string) FieldSpec {
|
||||||
|
return FieldSpec{
|
||||||
|
CreateIfNotPresent: false,
|
||||||
|
Gvk: in,
|
||||||
|
Path: strings.Join(path, "/"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -182,8 +182,7 @@ func TestLoadCRDs(t *testing.T) {
|
|||||||
NameReference: nbrs,
|
NameReference: nbrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
actualTc, err := NewFactory(makeLoader(t)).LoadCRDs(
|
actualTc, err := LoadConfigFromCRDs(makeLoader(t), []string{"crd.json"})
|
||||||
[]string{"crd.json"})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error:%v", err)
|
t.Fatalf("unexpected error:%v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TransformerConfig holds the data needed to perform transformations.
|
// TransformerConfig holds the data needed to perform transformations.
|
||||||
@@ -33,6 +36,21 @@ type TransformerConfig struct {
|
|||||||
VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeEmptyConfig returns an empty TransformerConfig object
|
||||||
|
func MakeEmptyConfig() *TransformerConfig {
|
||||||
|
return &TransformerConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeDefaultConfig returns a default TransformerConfig.
|
||||||
|
func MakeDefaultConfig() *TransformerConfig {
|
||||||
|
c, err := makeTransformerConfigFromBytes(
|
||||||
|
defaultconfig.GetDefaultFieldSpecs())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to make default transformconfig: %v", err)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// sortFields provides determinism in logging, tests, etc.
|
// sortFields provides determinism in logging, tests, etc.
|
||||||
func (t *TransformerConfig) sortFields() {
|
func (t *TransformerConfig) sortFields() {
|
||||||
sort.Sort(t.NamePrefix)
|
sort.Sort(t.NamePrefix)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ var crb = gvk.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Clus
|
|||||||
var sa = gvk.Gvk{Version: "v1", Kind: "ServiceAccount"}
|
var sa = gvk.Gvk{Version: "v1", Kind: "ServiceAccount"}
|
||||||
var ingress = gvk.Gvk{Kind: "Ingress"}
|
var ingress = gvk.Gvk{Kind: "Ingress"}
|
||||||
var rf = resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
var rf = resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
||||||
var defaultTransformerConfig = config.NewFactory(nil).DefaultConfig()
|
var defaultTransformerConfig = config.MakeDefaultConfig()
|
||||||
|
|
||||||
func TestLabelsRun(t *testing.T) {
|
func TestLabelsRun(t *testing.T) {
|
||||||
m := resmap.ResMap{
|
m := resmap.ResMap{
|
||||||
|
|||||||
Reference in New Issue
Block a user