mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
config tree defaults to graph structure when ownerRefs available
This commit is contained in:
@@ -20,8 +20,9 @@ container names, etc.
|
|||||||
|
|
||||||
kustomize config tree supports printing arbitrary fields using the '--field' flag.
|
kustomize config tree supports printing arbitrary fields using the '--field' flag.
|
||||||
|
|
||||||
By default, kustomize config tree uses the directory structure for the tree structure, however when printing
|
By default, kustomize config tree uses Resource graph structure if any relationships between resources (ownerReferences)
|
||||||
from the cluster, the Resource graph structure may be used instead.
|
are detected, as is typically the case when printing from a cluster. Otherwise, directory graph structure is used. The
|
||||||
|
graph structure can also be selected explicitly using the '--graph-structure' flag.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
@@ -42,8 +43,7 @@ from the cluster, the Resource graph structure may be used instead.
|
|||||||
--field="status.conditions[type=Completed].status"
|
--field="status.conditions[type=Completed].status"
|
||||||
|
|
||||||
# print live Resources from a cluster using owners for graph structure
|
# print live Resources from a cluster using owners for graph structure
|
||||||
kubectl get all -o yaml | kustomize config tree --replicas --name --image \
|
kubectl get all -o yaml | kustomize config tree --replicas --name --image
|
||||||
--graph-structure=owners
|
|
||||||
|
|
||||||
# print live Resources with status condition fields
|
# print live Resources with status condition fields
|
||||||
kubectl get all -o yaml | kustomize config tree \
|
kubectl get all -o yaml | kustomize config tree \
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func GetTreeRunner(name string) *TreeRunner {
|
|||||||
"if true, include local-config in the output.")
|
"if true, include local-config in the output.")
|
||||||
c.Flags().BoolVar(&r.excludeNonLocal, "exclude-non-local", false,
|
c.Flags().BoolVar(&r.excludeNonLocal, "exclude-non-local", false,
|
||||||
"if true, exclude non-local-config in the output.")
|
"if true, exclude non-local-config in the output.")
|
||||||
c.Flags().StringVar(&r.structure, "graph-structure", "directory",
|
c.Flags().StringVar(&r.structure, "graph-structure", "",
|
||||||
"Graph structure to use for printing the tree. may be any of: "+
|
"Graph structure to use for printing the tree. may be any of: "+
|
||||||
strings.Join(kio.GraphStructures, ","))
|
strings.Join(kio.GraphStructures, ","))
|
||||||
|
|
||||||
|
|||||||
@@ -460,8 +460,9 @@ container names, etc.
|
|||||||
|
|
||||||
kustomize config tree supports printing arbitrary fields using the '--field' flag.
|
kustomize config tree supports printing arbitrary fields using the '--field' flag.
|
||||||
|
|
||||||
By default, kustomize config tree uses the directory structure for the tree structure, however when printing
|
By default, kustomize config tree uses Resource graph structure if any relationships between resources (ownerReferences)
|
||||||
from the cluster, the Resource graph structure may be used instead.
|
are detected, as is typically the case when printing from a cluster. Otherwise, directory graph structure is used. The
|
||||||
|
graph structure can also be selected explicitly using the '--graph-structure' flag.
|
||||||
`
|
`
|
||||||
var TreeExamples = `
|
var TreeExamples = `
|
||||||
# print Resources using directory structure
|
# print Resources using directory structure
|
||||||
@@ -481,8 +482,7 @@ var TreeExamples = `
|
|||||||
--field="status.conditions[type=Completed].status"
|
--field="status.conditions[type=Completed].status"
|
||||||
|
|
||||||
# print live Resources from a cluster using owners for graph structure
|
# print live Resources from a cluster using owners for graph structure
|
||||||
kubectl get all -o yaml | kustomize config tree --replicas --name --image \
|
kubectl get all -o yaml | kustomize config tree --replicas --name --image
|
||||||
--graph-structure=owners
|
|
||||||
|
|
||||||
# print live Resources with status condition fields
|
# print live Resources with status condition fields
|
||||||
kubectl get all -o yaml | kustomize config tree \
|
kubectl get all -o yaml | kustomize config tree \
|
||||||
|
|||||||
@@ -98,9 +98,15 @@ func (p TreeWriter) Write(nodes []*yaml.RNode) error {
|
|||||||
return p.packageStructure(nodes)
|
return p.packageStructure(nodes)
|
||||||
case TreeStructureGraph:
|
case TreeStructureGraph:
|
||||||
return p.graphStructure(nodes)
|
return p.graphStructure(nodes)
|
||||||
default:
|
|
||||||
return p.packageStructure(nodes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If any resource has an owner reference, default to the graph structure. Otherwise, use package structure.
|
||||||
|
for _, node := range nodes {
|
||||||
|
if owners, _ := node.Pipe(yaml.Lookup("metadata", "ownerReferences")); owners != nil {
|
||||||
|
return p.graphStructure(nodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p.packageStructure(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// node wraps a tree node, and any children nodes
|
// node wraps a tree node, and any children nodes
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrinter_Write(t *testing.T) {
|
func TestPrinter_Write_Package_Structure(t *testing.T) {
|
||||||
in := `kind: Deployment
|
in := `kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -66,7 +66,7 @@ spec:
|
|||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
err := Pipeline{
|
err := Pipeline{
|
||||||
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
Outputs: []Writer{TreeWriter{Writer: out}},
|
Outputs: []Writer{TreeWriter{Writer: out, Structure: TreeStructurePackage}},
|
||||||
}.Execute()
|
}.Execute()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -85,7 +85,7 @@ spec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrinter_Write_base(t *testing.T) {
|
func TestPrinter_Write_Package_Structure_base(t *testing.T) {
|
||||||
in := `kind: Deployment
|
in := `kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -139,7 +139,7 @@ spec:
|
|||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
err := Pipeline{
|
err := Pipeline{
|
||||||
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
Outputs: []Writer{TreeWriter{Writer: out}},
|
Outputs: []Writer{TreeWriter{Writer: out, Structure: TreeStructurePackage}},
|
||||||
}.Execute()
|
}.Execute()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -157,7 +157,7 @@ spec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrinter_Write_sort(t *testing.T) {
|
func TestPrinter_Write_Package_Structure_sort(t *testing.T) {
|
||||||
in := `apiVersion: extensions/v1
|
in := `apiVersion: extensions/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -255,7 +255,7 @@ spec:
|
|||||||
out := &bytes.Buffer{}
|
out := &bytes.Buffer{}
|
||||||
err := Pipeline{
|
err := Pipeline{
|
||||||
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
Outputs: []Writer{TreeWriter{Writer: out}},
|
Outputs: []Writer{TreeWriter{Writer: out, Structure: TreeStructurePackage}},
|
||||||
}.Execute()
|
}.Execute()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@@ -287,7 +287,7 @@ func TestPrinter_metaError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrinter_Write_owners(t *testing.T) {
|
func TestPrinter_Write_Graph_Structure(t *testing.T) {
|
||||||
in := `
|
in := `
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
@@ -384,3 +384,210 @@ metadata:
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrinter_Write_Structure_Defaulting_when_ownerRefs_present(t *testing.T) {
|
||||||
|
in := `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-0
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
name: cockroachdb
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-1
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
name: cockroachdb
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-2
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
name: cockroachdb
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.0
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
name: myapp
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
name: myapp
|
||||||
|
---
|
||||||
|
apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: myapp
|
||||||
|
name: myapp
|
||||||
|
namespace: myapp-staging
|
||||||
|
`
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
err := Pipeline{
|
||||||
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
|
Outputs: []Writer{TreeWriter{Writer: out}}, // Structure unspecified
|
||||||
|
}.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !assert.Equal(t, `.
|
||||||
|
└── [Resource] Application myapp-staging/myapp
|
||||||
|
├── [Resource] Service myapp-staging/cockroachdb
|
||||||
|
└── [Resource] StatefulSet myapp-staging/cockroachdb
|
||||||
|
├── [Resource] Pod myapp-staging/cockroachdb-0
|
||||||
|
├── [Resource] Pod myapp-staging/cockroachdb-1
|
||||||
|
└── [Resource] Pod myapp-staging/cockroachdb-2
|
||||||
|
`, out.String()) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrinter_Write_Structure_Defaulting_when_ownerRefs_absent(t *testing.T) {
|
||||||
|
in := `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-0
|
||||||
|
namespace: myapp-staging
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-1
|
||||||
|
namespace: myapp-staging
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb-2
|
||||||
|
namespace: myapp-staging
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.0
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
namespace: myapp-staging
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
containers:
|
||||||
|
- name: cockroachdb
|
||||||
|
image: cockraochdb:1.1.1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
namespace: myapp-staging
|
||||||
|
---
|
||||||
|
apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: myapp
|
||||||
|
name: myapp
|
||||||
|
namespace: myapp-staging
|
||||||
|
`
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
err := Pipeline{
|
||||||
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
|
Outputs: []Writer{TreeWriter{Writer: out}}, // Structure unspecified
|
||||||
|
}.Execute()
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !assert.Equal(t, `
|
||||||
|
└──
|
||||||
|
├── [.] Service myapp-staging/cockroachdb
|
||||||
|
├── [.] StatefulSet myapp-staging/cockroachdb
|
||||||
|
├── [.] Pod myapp-staging/cockroachdb-0
|
||||||
|
├── [.] Pod myapp-staging/cockroachdb-1
|
||||||
|
├── [.] Pod myapp-staging/cockroachdb-2
|
||||||
|
└── [.] Application myapp-staging/myapp
|
||||||
|
`, out.String()) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrinter_Write_error_when_owner_missing(t *testing.T) {
|
||||||
|
in := `
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: cockroachdb
|
||||||
|
namespace: myapp-staging
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
name: nginx
|
||||||
|
---
|
||||||
|
apiVersion: app.k8s.io/v1beta1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: myapp
|
||||||
|
name: myapp
|
||||||
|
namespace: myapp-staging
|
||||||
|
`
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
err := Pipeline{
|
||||||
|
Inputs: []Reader{&ByteReader{Reader: bytes.NewBufferString(in)}},
|
||||||
|
Outputs: []Writer{TreeWriter{Writer: out}},
|
||||||
|
}.Execute()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "owner 'Application myapp-staging/nginx' not found in input, but found as an owner of input objects", err.Error())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user