Remove package tree

This commit is contained in:
Jingfang Liu 2018-03-07 09:04:29 -08:00
parent 62ee664fbe
commit e069e421d0
16 changed files with 0 additions and 1039 deletions

View File

@ -1,55 +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 tree
import (
"path"
manifest "k8s.io/kubectl/pkg/apis/manifest/v1alpha1"
)
func adjustPathsForManifest(m *manifest.Manifest, pathToDir []string) {
m.Packages = adjustPaths(m.Packages, pathToDir)
m.Resources = adjustPaths(m.Resources, pathToDir)
m.Patches = adjustPaths(m.Patches, pathToDir)
m.Configmaps = adjustPathForConfigMaps(m.Configmaps, pathToDir)
}
func adjustPathForConfigMaps(cms []manifest.ConfigMap, prefix []string) []manifest.ConfigMap {
for i, cm := range cms {
if len(cm.FileSources) > 0 {
for j, fileSource := range cm.FileSources {
cms[i].FileSources[j] = adjustPath(fileSource, prefix)
}
}
if len(cm.EnvSource) > 0 {
cms[i].EnvSource = adjustPath(cm.EnvSource, prefix)
}
}
return cms
}
func adjustPath(original string, prefix []string) string {
return path.Join(append(prefix, original)...)
}
func adjustPaths(original []string, prefix []string) []string {
for i, filename := range original {
original[i] = adjustPath(filename, prefix)
}
return original
}

View File

@ -1,168 +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 tree
import (
"fmt"
"os"
"path/filepath"
manifest "k8s.io/kubectl/pkg/apis/manifest/v1alpha1"
cutil "k8s.io/kubectl/pkg/kinflate/configmapandsecret"
"k8s.io/kubectl/pkg/kinflate/types"
kutil "k8s.io/kubectl/pkg/kinflate/util"
)
// LoadManifestDataFromPath takes a path to a Kube-manifest.yaml or a dir that has a Kube-manifest.yaml.
// It returns a tree of ManifestData.
func (l *ManifestLoader) LoadManifestDataFromPath() (*ManifestData, error) {
m, err := l.loadManifestFileFromPath()
if err != nil {
return nil, err
}
return l.manifestToManifestData(m)
}
// loadManifestFileFromPath loads a manifest object from file.
func (l *ManifestLoader) loadManifestFileFromPath() (*manifest.Manifest, error) {
mLoader := ManifestLoader{FS: l.FS}
// Expand the initial directory or file path into the full manifest file path.
fullFilepath, err := mLoader.MakeValidManifestPath(l.InitialPath)
if err != nil {
return nil, err
}
l.fullFilePath = fullFilepath
m, err := mLoader.Read(fullFilepath)
if err != nil {
return nil, err
}
mLoader.Validate(m)
return m, err
}
// manifestToManifestData make a ManifestData given an Manifest object
func (l *ManifestLoader) manifestToManifestData(m *manifest.Manifest) (*ManifestData, error) {
mdata, err := l.loadManifestDataFromManifestFileAndResources(m)
if err != nil {
return nil, err
}
pkgs := []*ManifestData{}
for _, pkg := range m.Packages {
loader := &ManifestLoader{FS: l.FS, InitialPath: pkg}
pkgNode, err := loader.LoadManifestDataFromPath()
if err != nil {
return nil, err
}
pkgs = append(pkgs, pkgNode)
}
mdata.Packages = pkgs
return mdata, nil
}
func (l *ManifestLoader) loadManifestDataFromManifestFileAndResources(m *manifest.Manifest) (*ManifestData, error) {
mdata := &ManifestData{}
var err error
mdata.Name = m.Name
mdata.NamePrefix = NamePrefixType(m.NamePrefix)
mdata.ObjectLabels = m.ObjectLabels
mdata.ObjectAnnotations = m.ObjectAnnotations
res, err := l.loadKObjectFromPaths(m.Resources)
if err != nil {
errorMsg := fmt.Sprintf("Resource from Manifest (%s) couldn't be loaded properly.\n%v\n"+
"Please check the Resource subsection in (%s).", l.fullFilePath, err, l.fullFilePath)
return nil, fmt.Errorf(errorMsg)
}
mdata.Resources = ResourcesType(res)
pat, err := l.loadKObjectFromPaths(m.Patches)
if err != nil {
return nil, err
}
mdata.Patches = PatchesType(pat)
cms, err := cutil.MakeConfigMapsKObject(m.Configmaps)
if err != nil {
return nil, err
}
mdata.Configmaps = ConfigmapsType(cms)
sec, err := cutil.MakeSecretsKObject(m.SecretGenerators, l.fullFilePath)
if err != nil {
return nil, err
}
mdata.Secrets = SecretsType(sec)
return mdata, nil
}
func (l *ManifestLoader) loadKObjectFromPaths(paths []string) (types.KObject, error) {
res := types.KObject{}
for _, path := range paths {
err := l.loadKObjectFromPath(path, res)
if err != nil {
return nil, err
}
}
return res, nil
}
func (l *ManifestLoader) loadKObjectFromPath(path string, into types.KObject) error {
_, err := l.FS.Stat(path)
if err != nil {
return err
}
if into == nil {
return fmt.Errorf("cannot load object to an empty KObject")
}
var e error
filepath.Walk(path, func(filepath string, info os.FileInfo, err error) error {
if err != nil {
e = err
return err
}
// Skip all the dir
if info.IsDir() {
return nil
}
err = l.loadKObjectFromFile(filepath, into)
return nil
})
return e
}
func (l *ManifestLoader) loadKObjectFromFile(filename string, into types.KObject) error {
f, err := l.FS.Stat(filename)
if err != nil {
return err
}
if f.IsDir() {
return fmt.Errorf("%q is NOT expected to be an dir", filename)
}
content, err := l.FS.ReadFile(filename)
if err != nil {
return err
}
_, err = kutil.DecodeToKObject(content, into)
if err != nil {
return err
}
return nil
}

View File

@ -1,346 +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 tree
import (
"reflect"
"strings"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
manifest "k8s.io/kubectl/pkg/apis/manifest/v1alpha1"
"k8s.io/kubectl/pkg/kinflate/types"
"k8s.io/kubectl/pkg/kinflate/util/fs"
)
func makeMapOfConfigMap() types.KObject {
return types.KObject{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: {
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
"data": map[string]interface{}{
"foo": "bar",
},
},
},
}
}
func makeMapOfPod() types.KObject {
return makeMapOfPodWithImageName("nginx")
}
func makeMapOfPodWithImageName(imageName string) types.KObject {
return types.KObject{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "Pod"},
Name: "pod1",
}: {
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "pod1",
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": imageName,
},
},
},
},
},
}
}
func makeManifestData(name string) *ManifestData {
return &ManifestData{
Name: name,
Resources: ResourcesType(types.KObject{}),
Patches: PatchesType(types.KObject{}),
Configmaps: ConfigmapsType(types.KObject{}),
Secrets: SecretsType(types.KObject{}),
Packages: []*ManifestData{},
}
}
func TestFileToMap(t *testing.T) {
type testcase struct {
filename string
expected types.KObject
expectErr bool
errorStr string
}
testcases := []testcase{
{
filename: "testdata/valid/cm/configmap.yaml",
expected: types.KObject{
{
GVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
Name: "cm1",
}: {
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
"data": map[string]interface{}{
"foo": "bar",
},
},
},
},
expectErr: false,
},
{
filename: "testdata/valid/cm/",
expectErr: true,
errorStr: "NOT expected to be an dir",
},
{
filename: "does-not-exist",
expectErr: true,
errorStr: "no such file or directory",
},
}
// TODO: Convert to a fake filesystem instead of using test files.
loader := ManifestLoader{FS: fs.MakeRealFS()}
for _, tc := range testcases {
actual := types.KObject{}
err := loader.loadKObjectFromFile(tc.filename, actual)
if err == nil {
if tc.expectErr {
t.Errorf("filename: %q, expect an error containing %q, but didn't get an error", tc.filename, tc.errorStr)
}
if !reflect.DeepEqual(actual, tc.expected) {
t.Errorf("filename: %q, expect %v, but got %v", tc.filename, tc.expected, actual)
}
} else {
if tc.expectErr {
if !strings.Contains(err.Error(), tc.errorStr) {
t.Errorf("filename: %q, expect an error containing %q, but got %v", tc.filename, tc.errorStr, err)
}
} else {
t.Errorf("unexpected error: %v", err)
}
}
}
}
func TestPathToMap(t *testing.T) {
type testcase struct {
filename string
expected types.KObject
expectErr bool
errorStr string
}
expectedMap := makeMapOfConfigMap()
testcases := []testcase{
{
filename: "testdata/valid/cm/configmap.yaml",
expected: expectedMap,
expectErr: false,
},
{
filename: "testdata/valid/cm/",
expected: expectedMap,
expectErr: false,
},
{
filename: "does-not-exist",
expectErr: true,
errorStr: "no such file or directory",
},
}
// TODO: Convert to a fake filesystem instead of using test files.
loader := ManifestLoader{FS: fs.MakeRealFS()}
for _, tc := range testcases {
actual := types.KObject{}
err := loader.loadKObjectFromPath(tc.filename, actual)
if err == nil {
if tc.expectErr {
t.Errorf("filename: %q, expect an error containing %q, but didn't get an error", tc.filename, tc.errorStr)
}
if !reflect.DeepEqual(actual, tc.expected) {
t.Errorf("filename: %q, expect %v, but got %v", tc.filename, tc.expected, actual)
}
} else {
if tc.expectErr {
if !strings.Contains(err.Error(), tc.errorStr) {
t.Errorf("filename: %q, expect an error containing %q, but got %v", tc.filename, tc.errorStr, err)
}
} else {
t.Errorf("unexpected error: %v", err)
}
}
}
}
func TestPathsToMap(t *testing.T) {
type testcase struct {
filenames []string
expected types.KObject
expectErr bool
errorStr string
}
mapOfConfigMap := makeMapOfConfigMap()
mapOfPod := makeMapOfPod()
err := types.Merge(mapOfPod, mapOfConfigMap)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
mergedMap := mapOfPod
testcases := []testcase{
{
filenames: []string{"testdata/valid/cm/"},
expected: mapOfConfigMap,
expectErr: false,
},
{
filenames: []string{"testdata/valid/pod.yaml"},
expected: makeMapOfPod(),
expectErr: false,
},
{
filenames: []string{"testdata/valid/cm/", "testdata/valid/pod.yaml"},
expected: mergedMap,
expectErr: false,
},
{
filenames: []string{"does-not-exist"},
expectErr: true,
errorStr: "no such file or directory",
},
}
// TODO: Convert to a fake filesystem instead of using test files.
loader := ManifestLoader{FS: fs.MakeRealFS()}
for _, tc := range testcases {
actual, err := loader.loadKObjectFromPaths(tc.filenames)
if err == nil {
if tc.expectErr {
t.Errorf("filenames: %q, expect an error containing %q, but didn't get an error", tc.filenames, tc.errorStr)
}
if !reflect.DeepEqual(actual, tc.expected) {
t.Errorf("filenames: %q, expect %v, but got %v", tc.filenames, tc.expected, actual)
}
} else {
if tc.expectErr {
if !strings.Contains(err.Error(), tc.errorStr) {
t.Errorf("filenames: %q, expect an error containing %q, but got %v", tc.filenames, tc.errorStr, err)
}
} else {
t.Errorf("unexpected error: %v", err)
}
}
}
}
func TestManifestToManifestData(t *testing.T) {
mapOfConfigMap := makeMapOfConfigMap()
mapOfPod := makeMapOfPod()
err := types.Merge(mapOfPod, mapOfConfigMap)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
mergedMap := mapOfPod
m := &manifest.Manifest{
ObjectMeta: metav1.ObjectMeta{
Name: "test-manifest",
},
NamePrefix: "someprefix-",
ObjectLabels: map[string]string{
"foo": "bar",
},
ObjectAnnotations: map[string]string{
"note": "This is an annotation.",
},
Resources: []string{
"testdata/valid/cm/",
"testdata/valid/pod.yaml",
},
Patches: []string{
"testdata/valid/patch.yaml",
},
}
expectedMd := &ManifestData{
Name: "test-manifest",
NamePrefix: "someprefix-",
ObjectLabels: map[string]string{"foo": "bar"},
ObjectAnnotations: map[string]string{"note": "This is an annotation."},
Resources: ResourcesType(mergedMap),
Patches: PatchesType(makeMapOfPodWithImageName("nginx:latest")),
Configmaps: ConfigmapsType(types.KObject{}),
Secrets: SecretsType(types.KObject{}),
}
// TODO: Convert to a fake filesystem instead of using test files.
loader := ManifestLoader{FS: fs.MakeRealFS()}
actual, err := loader.loadManifestDataFromManifestFileAndResources(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(actual, expectedMd) {
t.Errorf("expect:\n%#v\nbut got:\n%#v", expectedMd, actual)
}
}
func TestLoadManifestDataFromPath(t *testing.T) {
grandparent := makeManifestData("grandparent")
parent1 := makeManifestData("parent1")
parent2 := makeManifestData("parent2")
child1 := makeManifestData("child1")
child2 := makeManifestData("child2")
grandparent.Packages = []*ManifestData{parent1, parent2}
parent1.Packages = []*ManifestData{child1}
parent2.Packages = []*ManifestData{child2}
loader := ManifestLoader{FS: fs.MakeRealFS(), InitialPath: "testdata/hierarchy"}
expected := grandparent
actual, err := loader.LoadManifestDataFromPath()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expect:\n%#v\nbut got:\n%#v", expected, actual)
}
}

View File

@ -1,63 +0,0 @@
/*
Copyright 2017 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 tree
import (
"k8s.io/kubectl/pkg/kinflate/transformers"
"k8s.io/kubectl/pkg/kinflate/types"
)
// DefaultTransformer generates the following transformers:
// 1) apply overlay
// 2) name prefix
// 3) apply labels
// 4) apply annotations
// 5) update name reference
func DefaultTransformer(m *ManifestData) (transformers.Transformer, error) {
ts := []transformers.Transformer{}
ot, err := transformers.NewOverlayTransformer(types.KObject(m.Patches))
if err != nil {
return nil, err
}
ts = append(ts, ot)
npt, err := transformers.NewDefaultingNamePrefixTransformer(string(m.NamePrefix))
if err != nil {
return nil, err
}
ts = append(ts, npt)
lt, err := transformers.NewDefaultingLabelsMapTransformer(m.ObjectLabels)
if err != nil {
return nil, err
}
ts = append(ts, lt)
at, err := transformers.NewDefaultingAnnotationsMapTransformer(m.ObjectAnnotations)
if err != nil {
return nil, err
}
ts = append(ts, at)
nrt, err := transformers.NewDefaultingNameReferenceTransformer()
if err != nil {
return nil, err
}
ts = append(ts, nrt)
return transformers.NewMultiTransformer(ts), nil
}

View File

@ -1,130 +0,0 @@
/*
Copyright 2017 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 tree
import (
"errors"
"fmt"
"path"
"strings"
"github.com/ghodss/yaml"
manifest "k8s.io/kubectl/pkg/apis/manifest/v1alpha1"
"k8s.io/kubectl/pkg/kinflate/constants"
"k8s.io/kubectl/pkg/kinflate/util/fs"
)
type ManifestLoader struct {
// Allows unit tests with fake filesystem.
FS fs.FileSystem
// Initial path to manifest directory or manifest filename.
InitialPath string
// Full expanded manifest file path.
fullFilePath string
}
// First pass to encapsulate fields for more informative error messages.
type ManifestErrors struct {
filepath string
errorMsg string
}
func (m *ManifestLoader) fs() fs.FileSystem {
if m.FS == nil {
m.FS = fs.MakeRealFS()
}
return m.FS
}
// makeValidManifestPath returns a path to a KubeManifest file known to exist.
// The argument is either the full path to the file itself, or a path to a directory
// that immediately contains the file. Anything else is an error.
func (m *ManifestLoader) MakeValidManifestPath(mPath string) (string, error) {
f, err := m.fs().Stat(mPath)
if err != nil {
errorMsg := fmt.Sprintf("Manifest (%s) missing\nRun `kinflate init` first", mPath)
return "", errors.New(errorMsg)
}
if f.IsDir() {
mPath = path.Join(mPath, constants.KubeManifestFileName)
_, err = m.fs().Stat(mPath)
if err != nil {
errorMsg := fmt.Sprintf("Manifest (%s) missing\nRun `kinflate init` first", mPath)
return "", errors.New(errorMsg)
}
} else {
if !strings.HasSuffix(mPath, constants.KubeManifestFileName) {
return "", fmt.Errorf("Manifest file (%s) should have %s suffix\n", mPath, constants.KubeManifestSuffix)
}
}
return mPath, nil
}
// Read loads a manifest file and parse it in to the Manifest object.
func (m *ManifestLoader) Read(filename string) (*manifest.Manifest, error) {
bytes, err := m.fs().ReadFile(filename)
if err != nil {
return nil, err
}
var manifest manifest.Manifest
err = yaml.Unmarshal(bytes, &manifest)
if err != nil {
return nil, err
}
dir, _ := path.Split(filename)
adjustPathsForManifest(&manifest, []string{dir})
return &manifest, err
}
// Write dumps the Manifest object into a file. If manifest is nil, an
// error is returned.
func (m *ManifestLoader) Write(filename string, manifest *manifest.Manifest) error {
if manifest == nil {
return errors.New("util: failed to write passed-in nil manifest")
}
bytes, err := yaml.Marshal(manifest)
if err != nil {
return err
}
return m.fs().WriteFile(filename, bytes)
}
// Read must have already been called and we have a loaded manifest
func (m *ManifestLoader) Validate(manifest *manifest.Manifest) []ManifestErrors {
//TODO: implement this function
//// validate Packages
//merrors := m.validatePackages(manifest.Packages)
//// validate Resources
//merrors = merrors + m.validateResources(manifest.Resources)
//
//// validate Patches
//merrors = append(merrors, m.validatePatches(manifest.Patches))
//
//// validate Configmaps
//merrors = append(merrors, m.validateConfigmaps(manifest.Configmaps))
//
//// validate GenericSecrets
//merrors = append(merrors, m.validateGenericSecrets(manifest.GenericSecrets))
//
//// validate TLSSecrets
//merrors = append(merrors, m.validateTLSSecrets(manifest.TLSSecrets))
return nil
}

View File

@ -1,86 +0,0 @@
/*
Copyright 2017 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 tree_test
import (
"reflect"
"testing"
"strings"
manifest "k8s.io/kubectl/pkg/apis/manifest/v1alpha1"
"k8s.io/kubectl/pkg/kinflate/tree"
"k8s.io/kubectl/pkg/kinflate/util/fs"
)
func TestManifestLoader(t *testing.T) {
manifest := &manifest.Manifest{
NamePrefix: "prefix",
}
loader := tree.ManifestLoader{FS: fs.MakeFakeFS()}
if err := loader.Write("Kube-manifest.yaml", manifest); err != nil {
t.Fatalf("Couldn't write manifest file: %v\n", err)
}
readManifest, err := loader.Read("Kube-manifest.yaml")
if err != nil {
t.Fatalf("Couldn't read manifest file: %v\n", err)
}
if !reflect.DeepEqual(manifest, readManifest) {
t.Fatal("Read manifest is different from written manifest")
}
}
func TestManifestLoaderEmptyFile(t *testing.T) {
manifest := &manifest.Manifest{
NamePrefix: "prefix",
}
loader := tree.ManifestLoader{}
if loader.Write("", manifest) == nil {
t.Fatalf("Write to empty filename should fail")
}
}
func TestLoadNotExist(t *testing.T) {
badSuffix := "foo.bar"
fakeFS := fs.MakeFakeFS()
fakeFS.Mkdir(".", 0644)
fakeFS.Create(badSuffix)
loader := tree.ManifestLoader{FS: fakeFS}
_, err := loader.MakeValidManifestPath("Kube-manifest.yaml")
if err == nil {
t.Fatalf("expect an error")
}
if !strings.Contains(err.Error(), "Run `kinflate init` first") {
t.Fatalf("expect an error contains %q, but got %v", "does not exist", err)
}
_, err = loader.MakeValidManifestPath(".")
if err == nil {
t.Fatalf("expect an error")
}
if !strings.Contains(err.Error(), "Run `kinflate init` first") {
t.Fatalf("expect an error contains %q, but got %v", "does not exist", err)
}
_, err = loader.MakeValidManifestPath(badSuffix)
if err == nil {
t.Fatalf("expect an error")
}
if !strings.Contains(err.Error(), "should have .yaml suffix") {
t.Fatalf("expect an error contains %q, but got %v", "does not exist", err)
}
}

View File

@ -1,128 +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 tree
import (
"fmt"
"k8s.io/kubectl/pkg/kinflate/transformers"
"k8s.io/kubectl/pkg/kinflate/types"
)
type NamePrefixType string
type ObjectLabelsType map[string]string
type ObjectAnnotationsType map[string]string
type ResourcesType types.KObject
type PatchesType types.KObject
type ConfigmapsType types.KObject
type SecretsType types.KObject
type PackagesType []*ManifestData
// ManifestData contains all the objects loaded from the filesystem according to
// the Manifest Object.
// Data in one node may refer to data in other nodes.
// The node is invalid if it requires data it cannot find.
// A node is either a base app, or a patch to the base, or a patch to a patch to the base, etc.
type ManifestData struct {
// Name of the manifest
Name string
NamePrefix NamePrefixType
ObjectLabels ObjectLabelsType
ObjectAnnotations ObjectAnnotationsType
Resources ResourcesType
Patches PatchesType
Configmaps ConfigmapsType
Secrets SecretsType
Packages PackagesType
}
func (md *ManifestData) allResources() error {
err := types.Merge(md.Resources, md.Configmaps)
if err != nil {
return err
}
return types.Merge(md.Resources, md.Secrets)
}
// ModeType is the option type for kinflate inflate
type ModeType string
const (
// ModeNormal means regular transformation.
ModeNormal ModeType = "normal_mode"
// ModeNoop means no transformation.
ModeNoop ModeType = "noop_mode"
)
func (md *ManifestData) preprocess(mode ModeType) error {
switch mode {
case ModeNormal:
return md.allResources()
case ModeNoop:
return nil
default:
return fmt.Errorf("unknown mode for inflate")
}
}
func (md *ManifestData) makeTransformer(mode ModeType) (transformers.Transformer, error) {
switch mode {
case ModeNormal:
return DefaultTransformer(md)
case ModeNoop:
return transformers.NewNoOpTransformer(), nil
default:
return transformers.NewNoOpTransformer(), fmt.Errorf("unknown mode for inflate")
}
}
// Inflate will recursively do the transformation on all the nodes below.
func (md *ManifestData) Inflate(mode ModeType) error {
for _, pkg := range md.Packages {
err := pkg.Inflate(ModeNormal)
if err != nil {
return err
}
}
for _, pkg := range md.Packages {
err := types.Merge(md.Resources, pkg.Resources)
if err != nil {
return err
}
}
err := md.preprocess(mode)
if err != nil {
return err
}
t, err := md.makeTransformer(mode)
if err != nil {
return err
}
return t.Transform(types.KObject(md.Resources))
}

View File

@ -1,7 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: grandparent
packages:
- parent1/
- parent2/

View File

@ -1,6 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: parent1
packages:
- child1/

View File

@ -1,4 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: child1

View File

@ -1,6 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: parent2
packages:
- child2/

View File

@ -1,4 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: child2

View File

@ -1,14 +0,0 @@
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: valid-app
namePrefix: someprefix-
objectLabels:
foo: bar
objectAnnotations:
baseAnno: This is an annotation.
resources:
- deployment.yaml
- cm/configmap.yaml
patches:
- patch.yaml

View File

@ -1,6 +0,0 @@
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
name: cm1

View File

@ -1,8 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: nginx
image: nginx:latest

View File

@ -1,8 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: nginx
image: nginx