mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-30 09:51:23 +00:00
Reduce indirection.
This commit is contained in:
@@ -28,42 +28,37 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
)
|
||||
|
||||
func newResourceFromConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*resource.Resource, error) {
|
||||
corev1CM, err := makeConfigMap(l, cm)
|
||||
func newResourceFromConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*resource.Resource, error) {
|
||||
cm, err := makeConfigMap(l, cmArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := newUnstructuredFromObject(corev1CM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resource.NewResource(data, cm.Behavior), nil
|
||||
return resource.NewResourceWithBehavior(cm, resource.NewGenerationBehavior(cmArgs.Behavior))
|
||||
}
|
||||
|
||||
func makeConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*corev1.ConfigMap, error) {
|
||||
func makeConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*corev1.ConfigMap, error) {
|
||||
var envPairs, literalPairs, filePairs []kvPair
|
||||
var err error
|
||||
|
||||
corev1cm := &corev1.ConfigMap{}
|
||||
corev1cm.APIVersion = "v1"
|
||||
corev1cm.Kind = "ConfigMap"
|
||||
corev1cm.Name = cm.Name
|
||||
corev1cm.Data = map[string]string{}
|
||||
cm := &corev1.ConfigMap{}
|
||||
cm.APIVersion = "v1"
|
||||
cm.Kind = "ConfigMap"
|
||||
cm.Name = cmArgs.Name
|
||||
cm.Data = map[string]string{}
|
||||
|
||||
if cm.EnvSource != "" {
|
||||
envPairs, err = keyValuesFromEnvFile(l, cm.EnvSource)
|
||||
if cmArgs.EnvSource != "" {
|
||||
envPairs, err = keyValuesFromEnvFile(l, cmArgs.EnvSource)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading keys from env source file: %s %v", cm.EnvSource, err)
|
||||
return nil, fmt.Errorf("error reading keys from env source file: %s %v", cmArgs.EnvSource, err)
|
||||
}
|
||||
}
|
||||
|
||||
literalPairs, err = keyValuesFromLiteralSources(cm.LiteralSources)
|
||||
literalPairs, err = keyValuesFromLiteralSources(cmArgs.LiteralSources)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading key values from literal sources: %v", err)
|
||||
}
|
||||
|
||||
filePairs, err = keyValuesFromFileSources(l, cm.FileSources)
|
||||
filePairs, err = keyValuesFromFileSources(l, cmArgs.FileSources)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading key values from file sources: %v", err)
|
||||
}
|
||||
@@ -72,13 +67,13 @@ func makeConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*corev1.ConfigMap,
|
||||
|
||||
// merge key value pairs from all the sources
|
||||
for _, kv := range allPairs {
|
||||
err = addKV(corev1cm.Data, kv)
|
||||
err = addKV(cm.Data, kv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error adding key in configmap: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return corev1cm, nil
|
||||
return cm, nil
|
||||
}
|
||||
|
||||
func keyValuesFromEnvFile(l loader.Loader, path string) ([]kvPair, error) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package resmap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
@@ -30,7 +29,6 @@ import (
|
||||
"github.com/kubernetes-sigs/kustomize/pkg/loader"
|
||||
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
@@ -40,8 +38,8 @@ type ResMap map[resource.ResId]*resource.Resource
|
||||
// EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`.
|
||||
func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
||||
ids := []resource.ResId{}
|
||||
for gvkn := range m {
|
||||
ids = append(ids, gvkn)
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(IdSlice(ids))
|
||||
|
||||
@@ -49,7 +47,7 @@ func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
||||
var b []byte
|
||||
buf := bytes.NewBuffer(b)
|
||||
for _, id := range ids {
|
||||
obj := m[id].Unstruct()
|
||||
obj := m[id]
|
||||
out, err := yaml.Marshal(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -87,8 +85,8 @@ func (m1 ResMap) ErrorIfNotEqual(m2 ResMap) error {
|
||||
if !found {
|
||||
return fmt.Errorf("%#v doesn't exist in %#v", id, m2)
|
||||
}
|
||||
if !reflect.DeepEqual(obj1.Unstruct(), obj2.Unstruct()) {
|
||||
return fmt.Errorf("%#v doesn't match %#v", obj1.Unstruct(), obj2.Unstruct())
|
||||
if !reflect.DeepEqual(obj1, obj2) {
|
||||
return fmt.Errorf("%#v doesn't match %#v", obj1, obj2)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -153,11 +151,11 @@ func newResMapFromBytes(b []byte) (ResMap, error) {
|
||||
|
||||
result := ResMap{}
|
||||
for _, res := range resources {
|
||||
gvkn := res.Id()
|
||||
if _, found := result[gvkn]; found {
|
||||
return result, fmt.Errorf("GroupVersionKindName: %#v already exists b the map", gvkn)
|
||||
id := res.Id()
|
||||
if _, found := result[id]; found {
|
||||
return result, fmt.Errorf("GroupVersionKindName: %#v already exists b the map", id)
|
||||
}
|
||||
result[gvkn] = res
|
||||
result[id] = res
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -165,11 +163,11 @@ func newResMapFromBytes(b []byte) (ResMap, error) {
|
||||
func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, res := range resources {
|
||||
gvkn := res.Id()
|
||||
if _, found := result[gvkn]; found {
|
||||
return nil, fmt.Errorf("duplicated %#v is not allowed", gvkn)
|
||||
id := res.Id()
|
||||
if _, found := result[id]; found {
|
||||
return nil, fmt.Errorf("duplicated %#v is not allowed", id)
|
||||
}
|
||||
result[gvkn] = res
|
||||
result[id] = res
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -197,21 +195,17 @@ func newResourceSliceFromBytes(in []byte) ([]*resource.Resource, error) {
|
||||
func Merge(maps ...ResMap) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, m := range maps {
|
||||
for gvkn, obj := range m {
|
||||
if _, found := result[gvkn]; found {
|
||||
return nil, fmt.Errorf("there is already an entry: %q", gvkn)
|
||||
for id, obj := range m {
|
||||
if _, found := result[id]; found {
|
||||
return nil, fmt.Errorf("there is already an entry: %q", id)
|
||||
}
|
||||
result[gvkn] = obj
|
||||
result[id] = obj
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
const behaviorCreate = "create"
|
||||
const behaviorReplace = "replace"
|
||||
const behaviorMerge = "merge"
|
||||
|
||||
// MergeWithOverride merges the entries in the ResMap slice with Override.
|
||||
// If there is already an entry with the same Id , different actions are performed
|
||||
// according to value of behavior field:
|
||||
@@ -221,44 +215,30 @@ const behaviorMerge = "merge"
|
||||
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, m := range maps {
|
||||
for gvkn, resource := range m {
|
||||
if _, found := result[gvkn]; found {
|
||||
switch resource.Behavior() {
|
||||
case "", behaviorCreate:
|
||||
return nil, fmt.Errorf("Create an existing gvkn %#v is not allowed", gvkn)
|
||||
case behaviorReplace:
|
||||
glog.V(4).Infof("Replace object %v by %v", result[gvkn].Unstruct().Object, resource.Unstruct().Object)
|
||||
resource.Replace(result[gvkn])
|
||||
result[gvkn] = resource
|
||||
case behaviorMerge:
|
||||
glog.V(4).Infof("Merge object %v with %v", result[gvkn].Unstruct().Object, resource.Unstruct().Object)
|
||||
resource.Merge(result[gvkn])
|
||||
result[gvkn] = resource
|
||||
glog.V(4).Infof("The merged object is %v", result[gvkn].Unstruct().Object)
|
||||
for id, r := range m {
|
||||
if _, found := result[id]; found {
|
||||
switch r.Behavior() {
|
||||
case resource.BehaviorReplace:
|
||||
glog.V(4).Infof("Replace object %v by %v", result[id].Object, r.Object)
|
||||
r.Replace(result[id])
|
||||
result[id] = r
|
||||
case resource.BehaviorMerge:
|
||||
glog.V(4).Infof("Merge object %v with %v", result[id].Object, r.Object)
|
||||
r.Merge(result[id])
|
||||
result[id] = r
|
||||
glog.V(4).Infof("The merged object is %v", result[id].Object)
|
||||
default:
|
||||
return nil, fmt.Errorf("The behavior of %#v must be one of merge and replace since it already exists in the base", gvkn)
|
||||
return nil, fmt.Errorf("Id %#v exists; must merge or replace.", id)
|
||||
}
|
||||
} else {
|
||||
switch resource.Behavior() {
|
||||
case "", behaviorCreate:
|
||||
result[gvkn] = resource
|
||||
case behaviorMerge, behaviorReplace:
|
||||
return nil, fmt.Errorf("No merge or replace is allowed for non existing gvkn %#v", gvkn)
|
||||
switch r.Behavior() {
|
||||
case resource.BehaviorMerge, resource.BehaviorReplace:
|
||||
return nil, fmt.Errorf("Id %#v does not exist; cannot merge or replace.", id)
|
||||
default:
|
||||
return nil, fmt.Errorf("The behavior of %#v must be create since it doesn't exist", gvkn)
|
||||
result[id] = r
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func newUnstructuredFromObject(in runtime.Object) (*unstructured.Unstructured, error) {
|
||||
marshaled, err := json.Marshal(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out unstructured.Unstructured
|
||||
err = out.UnmarshalJSON(marshaled)
|
||||
return &out, err
|
||||
}
|
||||
|
||||
@@ -28,32 +28,34 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func newFromSecretGenerator(p string, s types.SecretArgs) (*resource.Resource, error) {
|
||||
corev1secret := &corev1.Secret{}
|
||||
corev1secret.APIVersion = "v1"
|
||||
corev1secret.Kind = "Secret"
|
||||
corev1secret.Name = s.Name
|
||||
corev1secret.Type = corev1.SecretType(s.Type)
|
||||
if corev1secret.Type == "" {
|
||||
corev1secret.Type = corev1.SecretTypeOpaque
|
||||
func newResourceFromSecretGenerator(p string, sArgs types.SecretArgs) (*resource.Resource, error) {
|
||||
s, err := makeSecret(p, sArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
corev1secret.Data = map[string][]byte{}
|
||||
return resource.NewResourceWithBehavior(
|
||||
s, resource.NewGenerationBehavior(sArgs.Behavior))
|
||||
}
|
||||
|
||||
for k, v := range s.Commands {
|
||||
func makeSecret(p string, sArgs types.SecretArgs) (*corev1.Secret, error) {
|
||||
s := &corev1.Secret{}
|
||||
s.APIVersion = "v1"
|
||||
s.Kind = "Secret"
|
||||
s.Name = sArgs.Name
|
||||
s.Type = corev1.SecretType(sArgs.Type)
|
||||
if s.Type == "" {
|
||||
s.Type = corev1.SecretTypeOpaque
|
||||
}
|
||||
s.Data = map[string][]byte{}
|
||||
|
||||
for k, v := range sArgs.Commands {
|
||||
out, err := createSecretKey(p, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
corev1secret.Data[k] = out
|
||||
s.Data[k] = out
|
||||
}
|
||||
|
||||
obj, err := newUnstructuredFromObject(corev1secret)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resource.NewResource(obj, s.Behavior), nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func createSecretKey(wd string, command string) ([]byte, error) {
|
||||
@@ -65,7 +67,6 @@ func createSecretKey(wd string, command string) ([]byte, error) {
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "sh", "-c", command)
|
||||
cmd.Dir = wd
|
||||
|
||||
return cmd.Output()
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ func createSecretKey(wd string, command string) ([]byte, error) {
|
||||
func NewResMapFromSecretArgs(p string, secretList []types.SecretArgs) (ResMap, error) {
|
||||
allResources := []*resource.Resource{}
|
||||
for _, secret := range secretList {
|
||||
res, err := newFromSecretGenerator(p, secret)
|
||||
res, err := newResourceFromSecretGenerator(p, secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ import (
|
||||
|
||||
var secret = schema.GroupVersionKind{Version: "v1", Kind: "Secret"}
|
||||
|
||||
func TestNewFromSecretGenerators(t *testing.T) {
|
||||
func TestNewResMapFromSecretArgs(t *testing.T) {
|
||||
secrets := []types.SecretArgs{
|
||||
{
|
||||
Name: "secret",
|
||||
Name: "apple",
|
||||
Commands: map[string]string{
|
||||
"DB_USERNAME": "printf admin",
|
||||
"DB_PASSWORD": "printf somepw",
|
||||
@@ -41,19 +41,20 @@ func TestNewFromSecretGenerators(t *testing.T) {
|
||||
Type: "Opaque",
|
||||
},
|
||||
}
|
||||
re, err := NewResMapFromSecretArgs(".", secrets)
|
||||
actual, err := NewResMapFromSecretArgs(".", secrets)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
expected := ResMap{
|
||||
resource.NewResId(secret, "secret"): resource.NewResource(
|
||||
resource.NewResId(secret, "apple"): resource.NewBehaviorlessResource(
|
||||
&unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Secret",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "secret",
|
||||
"name": "apple",
|
||||
"creationTimestamp": nil,
|
||||
},
|
||||
"type": string(corev1.SecretTypeOpaque),
|
||||
@@ -62,11 +63,9 @@ func TestNewFromSecretGenerators(t *testing.T) {
|
||||
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
|
||||
},
|
||||
},
|
||||
},
|
||||
""),
|
||||
}),
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(re, expected) {
|
||||
t.Fatalf("%#v\ndoesn't match expected:\n%#v", re, expected)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("%#v\ndoesn't match expected:\n%#v", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user