mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #2246 from lavalamp/fix2
Fix unversioned output being passed to -template
This commit is contained in:
commit
0ee7d5cc75
@ -92,7 +92,7 @@ function kube-up {
|
|||||||
local count="0"
|
local count="0"
|
||||||
until [[ "$count" == "1" ]]; do
|
until [[ "$count" == "1" ]]; do
|
||||||
local minions
|
local minions
|
||||||
minions=$("${KUBE_ROOT}/cluster/kubecfg.sh" -template '{{range.Items}}{{.Name}}:{{end}}' list minions)
|
minions=$("${KUBE_ROOT}/cluster/kubecfg.sh" -template '{{range.items}}{{.id}}:{{end}}' list minions)
|
||||||
count=$(echo $minions | grep -c "${MINION_NAMES[i]}") || {
|
count=$(echo $minions | grep -c "${MINION_NAMES[i]}") || {
|
||||||
printf "."
|
printf "."
|
||||||
sleep 2
|
sleep 2
|
||||||
|
@ -33,7 +33,7 @@ detect-master > /dev/null
|
|||||||
detect-minions > /dev/null
|
detect-minions > /dev/null
|
||||||
|
|
||||||
MINIONS_FILE=/tmp/minions
|
MINIONS_FILE=/tmp/minions
|
||||||
"${KUBE_ROOT}/cluster/kubecfg.sh" -template $'{{range.Items}}{{.Name}}\n{{end}}' list minions > ${MINIONS_FILE}
|
"${KUBE_ROOT}/cluster/kubecfg.sh" -template $'{{range.items}}{{.id}}\n{{end}}' list minions > ${MINIONS_FILE}
|
||||||
|
|
||||||
# On vSphere, use minion IPs as their names
|
# On vSphere, use minion IPs as their names
|
||||||
if [[ "${KUBERNETES_PROVIDER}" == "vsphere" ]]; then
|
if [[ "${KUBERNETES_PROVIDER}" == "vsphere" ]]; then
|
||||||
|
@ -26,7 +26,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
@ -324,14 +323,12 @@ func getPrinter() kubecfg.ResourcePrinter {
|
|||||||
} else {
|
} else {
|
||||||
data = []byte(*templateStr)
|
data = []byte(*templateStr)
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("output").Parse(string(data))
|
var err error
|
||||||
|
printer, err = kubecfg.NewTemplatePrinter(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Error parsing template %s, %v\n", string(data), err)
|
glog.Fatalf("Error '%v' parsing template:\n'%s'", err, string(data))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
printer = &kubecfg.TemplatePrinter{
|
|
||||||
Template: tmpl,
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
printer = humanReadablePrinter()
|
printer = humanReadablePrinter()
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ function teardown() {
|
|||||||
|
|
||||||
trap "teardown" EXIT
|
trap "teardown" EXIT
|
||||||
|
|
||||||
pod_id_list=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' -l replicationController=my-hostname list pods)
|
pod_id_list=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' -l replicationController=my-hostname list pods)
|
||||||
# Pod turn up on a clean cluster can take a while for the docker image pull.
|
# Pod turn up on a clean cluster can take a while for the docker image pull.
|
||||||
all_running=0
|
all_running=0
|
||||||
for i in $(seq 1 24); do
|
for i in $(seq 1 24); do
|
||||||
@ -45,7 +45,7 @@ for i in $(seq 1 24); do
|
|||||||
sleep 5
|
sleep 5
|
||||||
all_running=1
|
all_running=1
|
||||||
for id in $pod_id_list; do
|
for id in $pod_id_list; do
|
||||||
current_status=$($KUBECFG -template '{{.CurrentState.Status}}' get pods/$id) || true
|
current_status=$($KUBECFG -template '{{.currentState.status}}' get pods/$id) || true
|
||||||
if [[ "$current_status" != "Running" ]]; then
|
if [[ "$current_status" != "Running" ]]; then
|
||||||
all_running=0
|
all_running=0
|
||||||
break
|
break
|
||||||
@ -69,7 +69,7 @@ sleep 5
|
|||||||
|
|
||||||
# Verify that something is listening.
|
# Verify that something is listening.
|
||||||
for id in ${pod_id_list}; do
|
for id in ${pod_id_list}; do
|
||||||
ip=$($KUBECFG -template '{{.CurrentState.HostIP}}' get pods/$id)
|
ip=$($KUBECFG -template '{{.currentState.hostIP}}' get pods/$id)
|
||||||
echo "Trying to reach server that should be running at ${ip}:8080..."
|
echo "Trying to reach server that should be running at ${ip}:8080..."
|
||||||
ok=0
|
ok=0
|
||||||
for i in $(seq 1 5); do
|
for i in $(seq 1 5); do
|
||||||
|
@ -35,7 +35,7 @@ $KUBECFG -c "${GUESTBOOK}/redis-slave-controller.json" create /replicationContro
|
|||||||
|
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
POD_LIST_1=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' list pods)
|
POD_LIST_1=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' list pods)
|
||||||
echo "Pods running: ${POD_LIST_1}"
|
echo "Pods running: ${POD_LIST_1}"
|
||||||
|
|
||||||
$KUBECFG stop redisSlaveController
|
$KUBECFG stop redisSlaveController
|
||||||
@ -45,7 +45,7 @@ $KUBECFG rm redisSlaveController
|
|||||||
$KUBECFG delete services/redismaster
|
$KUBECFG delete services/redismaster
|
||||||
$KUBECFG delete pods/redis-master-2
|
$KUBECFG delete pods/redis-master-2
|
||||||
|
|
||||||
POD_LIST_2=$($KUBECFG '-template={{range.Items}}{{.Name}} {{end}}' list pods)
|
POD_LIST_2=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' list pods)
|
||||||
echo "Pods running after shutdown: ${POD_LIST_2}"
|
echo "Pods running after shutdown: ${POD_LIST_2}"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -69,7 +69,7 @@ function query_pods() {
|
|||||||
local i
|
local i
|
||||||
for i in $(seq 1 10); do
|
for i in $(seq 1 10); do
|
||||||
pods_unsorted=($(${KUBECFG} \
|
pods_unsorted=($(${KUBECFG} \
|
||||||
'-template={{range.Items}}{{.Name}} {{end}}' \
|
'-template={{range.items}}{{.id}} {{end}}' \
|
||||||
-l name="$1" list pods))
|
-l name="$1" list pods))
|
||||||
found="${#pods_unsorted[*]}"
|
found="${#pods_unsorted[*]}"
|
||||||
if [[ "${found}" == "$2" ]]; then
|
if [[ "${found}" == "$2" ]]; then
|
||||||
@ -103,7 +103,7 @@ function wait_for_pods() {
|
|||||||
echo "Waiting for ${pods_needed} pods to become 'running'"
|
echo "Waiting for ${pods_needed} pods to become 'running'"
|
||||||
pods_needed="$2"
|
pods_needed="$2"
|
||||||
for id in ${pods_sorted}; do
|
for id in ${pods_sorted}; do
|
||||||
status=$(${KUBECFG} -template '{{.CurrentState.Status}}' get "pods/${id}")
|
status=$(${KUBECFG} -template '{{.currentState.status}}' get "pods/${id}")
|
||||||
if [[ "${status}" == "Running" ]]; then
|
if [[ "${status}" == "Running" ]]; then
|
||||||
pods_needed=$((pods_needed-1))
|
pods_needed=$((pods_needed-1))
|
||||||
fi
|
fi
|
||||||
@ -213,9 +213,9 @@ svc1_pods=$(query_pods "${svc1_name}" "${svc1_count}")
|
|||||||
svc2_pods=$(query_pods "${svc2_name}" "${svc2_count}")
|
svc2_pods=$(query_pods "${svc2_name}" "${svc2_count}")
|
||||||
|
|
||||||
# Get the portal IPs.
|
# Get the portal IPs.
|
||||||
svc1_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc1_name}")
|
svc1_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc1_name}")
|
||||||
test -n "${svc1_ip}" || error "Service1 IP is blank"
|
test -n "${svc1_ip}" || error "Service1 IP is blank"
|
||||||
svc2_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc2_name}")
|
svc2_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc2_name}")
|
||||||
test -n "${svc2_ip}" || error "Service2 IP is blank"
|
test -n "${svc2_ip}" || error "Service2 IP is blank"
|
||||||
if [[ "${svc1_ip}" == "${svc2_ip}" ]]; then
|
if [[ "${svc1_ip}" == "${svc2_ip}" ]]; then
|
||||||
error "Portal IPs conflict: ${svc1_ip}"
|
error "Portal IPs conflict: ${svc1_ip}"
|
||||||
@ -272,7 +272,7 @@ wait_for_pods "${svc3_name}" "${svc3_count}"
|
|||||||
svc3_pods=$(query_pods "${svc3_name}" "${svc3_count}")
|
svc3_pods=$(query_pods "${svc3_name}" "${svc3_count}")
|
||||||
|
|
||||||
# Get the portal IP.
|
# Get the portal IP.
|
||||||
svc3_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc3_name}")
|
svc3_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc3_name}")
|
||||||
test -n "${svc3_ip}" || error "Service3 IP is blank"
|
test -n "${svc3_ip}" || error "Service3 IP is blank"
|
||||||
if [[ "${svc3_ip}" != "${svc1_ip}" ]]; then
|
if [[ "${svc3_ip}" != "${svc1_ip}" ]]; then
|
||||||
error "Portal IPs not resued: ${svc3_ip} != ${svc1_ip}"
|
error "Portal IPs not resued: ${svc3_ip} != ${svc1_ip}"
|
||||||
@ -325,7 +325,7 @@ wait_for_pods "${svc4_name}" "${svc4_count}"
|
|||||||
svc4_pods=$(query_pods "${svc4_name}" "${svc4_count}")
|
svc4_pods=$(query_pods "${svc4_name}" "${svc4_count}")
|
||||||
|
|
||||||
# Get the portal IP.
|
# Get the portal IP.
|
||||||
svc4_ip=$(${KUBECFG} -template '{{.PortalIP}}' get "services/${svc4_name}")
|
svc4_ip=$(${KUBECFG} -template '{{.portalIP}}' get "services/${svc4_name}")
|
||||||
test -n "${svc4_ip}" || error "Service4 IP is blank"
|
test -n "${svc4_ip}" || error "Service4 IP is blank"
|
||||||
if [[ "${svc4_ip}" == "${svc2_ip}" || "${svc4_ip}" == "${svc3_ip}" ]]; then
|
if [[ "${svc4_ip}" == "${svc2_ip}" || "${svc4_ip}" == "${svc3_ip}" ]]; then
|
||||||
error "Portal IPs conflict: ${svc4_ip}"
|
error "Portal IPs conflict: ${svc4_ip}"
|
||||||
|
@ -38,7 +38,7 @@ function validate() {
|
|||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
local pod_id_list
|
local pod_id_list
|
||||||
pod_id_list=($($KUBECFG -template='{{range.Items}}{{.Name}} {{end}}' -l name="${CONTROLLER_NAME}" list pods))
|
pod_id_list=($($KUBECFG -template='{{range.items}}{{.id}} {{end}}' -l name="${CONTROLLER_NAME}" list pods))
|
||||||
|
|
||||||
echo " ${#pod_id_list[@]} out of ${num_replicas} created"
|
echo " ${#pod_id_list[@]} out of ${num_replicas} created"
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ function validate() {
|
|||||||
# currently always set to a zero time.
|
# currently always set to a zero time.
|
||||||
#
|
#
|
||||||
# You can read about the syntax here: http://golang.org/pkg/text/template/
|
# You can read about the syntax here: http://golang.org/pkg/text/template/
|
||||||
template_string="{{and ((index .CurrentState.Info \"${CONTROLLER_NAME}\").State.Running) .CurrentState.Info.net.State.Running}}"
|
template_string="{{and ((index .currentState.info \"${CONTROLLER_NAME}\").state.running.startedAt) .currentState.info.net.state.running.startedAt}}"
|
||||||
current_status=$($KUBECFG -template="${template_string}" get "pods/$id") || {
|
current_status=$($KUBECFG -template="${template_string}" get "pods/$id") || {
|
||||||
if [[ $current_status =~ "pod \"${id}\" not found" ]]; then
|
if [[ $current_status =~ "pod \"${id}\" not found" ]]; then
|
||||||
echo " $id no longer exists"
|
echo " $id no longer exists"
|
||||||
@ -73,12 +73,12 @@ function validate() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "$current_status" != "{0001-01-01 00:00:00 +0000 UTC}" ]]; then
|
if [[ "$current_status" != "0001-01-01T00:00:00Z" ]]; then
|
||||||
echo " $id is created but not running"
|
echo " $id is created but not running"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
template_string="{{(index .CurrentState.Info \"${CONTROLLER_NAME}\").Image}}"
|
template_string="{{(index .currentState.info \"${CONTROLLER_NAME}\").image}}"
|
||||||
current_image=$($KUBECFG -template="${template_string}" get "pods/$id")
|
current_image=$($KUBECFG -template="${template_string}" get "pods/$id")
|
||||||
if [[ "$current_image" != "${DOCKER_HUB_USER}/update-demo:${container_image_version}" ]]; then
|
if [[ "$current_image" != "${DOCKER_HUB_USER}/update-demo:${container_image_version}" ]]; then
|
||||||
echo " ${id} is created but running wrong image"
|
echo " ${id} is created but running wrong image"
|
||||||
@ -86,7 +86,7 @@ function validate() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
host_ip=$($KUBECFG -template='{{.CurrentState.HostIP}}' get pods/$id)
|
host_ip=$($KUBECFG -template='{{.currentState.hostIP}}' get pods/$id)
|
||||||
curl -s --max-time 5 --fail http://${host_ip}:8080/data.json \
|
curl -s --max-time 5 --fail http://${host_ip}:8080/data.json \
|
||||||
| grep -q ${container_image_version} || {
|
| grep -q ${container_image_version} || {
|
||||||
echo " ${id} is running the right image but curl to contents failed or returned wrong info"
|
echo " ${id} is running the right image but curl to contents failed or returned wrong info"
|
||||||
|
21
hack/e2e.go
21
hack/e2e.go
@ -40,6 +40,9 @@ var (
|
|||||||
tests = flag.String("tests", "", "Run only tests in hack/e2e-suite matching this glob. Ignored if -test is set.")
|
tests = flag.String("tests", "", "Run only tests in hack/e2e-suite matching this glob. Ignored if -test is set.")
|
||||||
root = flag.String("root", absOrDie(filepath.Clean(filepath.Join(path.Base(os.Args[0]), ".."))), "Root directory of kubernetes repository.")
|
root = flag.String("root", absOrDie(filepath.Clean(filepath.Join(path.Base(os.Args[0]), ".."))), "Root directory of kubernetes repository.")
|
||||||
verbose = flag.Bool("v", false, "If true, print all command output.")
|
verbose = flag.Bool("v", false, "If true, print all command output.")
|
||||||
|
|
||||||
|
cfgCmd = flag.String("cfg", "", "If nonempty, pass this as an argument, and call kubecfg. Implies -v.")
|
||||||
|
ctlCmd = flag.String("ctl", "", "If nonempty, pass this as an argument, and call kubectl. Implies -v. (-test, -cfg, -ctl are mutually exclusive)")
|
||||||
)
|
)
|
||||||
|
|
||||||
var signals = make(chan os.Signal, 100)
|
var signals = make(chan os.Signal, 100)
|
||||||
@ -87,18 +90,24 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
failed, passed := []string{}, []string{}
|
failure := false
|
||||||
if *tests != "" {
|
switch {
|
||||||
failed, passed = Test()
|
case *cfgCmd != "":
|
||||||
|
failure = !runBash("'kubecfg "+*cfgCmd+"'", "$KUBECFG "+*cfgCmd)
|
||||||
|
case *ctlCmd != "":
|
||||||
|
failure = !runBash("'kubectl "+*ctlCmd+"'", "$KUBECFG "+*ctlCmd)
|
||||||
|
case *tests != "":
|
||||||
|
failed, passed := Test()
|
||||||
|
log.Printf("Passed tests: %v", passed)
|
||||||
|
log.Printf("Failed tests: %v", failed)
|
||||||
|
failure = len(failed) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if *down {
|
if *down {
|
||||||
TearDown()
|
TearDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Passed tests: %v", passed)
|
if failure {
|
||||||
log.Printf("Failed tests: %v", failed)
|
|
||||||
if len(failed) > 0 {
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,12 +100,12 @@ kube::log::status "Testing kubectl(pods)"
|
|||||||
"${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
"${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
||||||
"${kube_cmd[@]}" get pods "${kube_flags[@]}"
|
"${kube_cmd[@]}" get pods "${kube_flags[@]}"
|
||||||
"${kube_cmd[@]}" get pod redis-master-2 "${kube_flags[@]}"
|
"${kube_cmd[@]}" get pod redis-master-2 "${kube_flags[@]}"
|
||||||
[[ "$("${kube_cmd[@]}" get pod redis-master-2 -o template --output-version=v1beta1 -t '{{ .ID }}' "${kube_flags[@]}")" == "redis-master-2" ]]
|
[[ "$("${kube_cmd[@]}" get pod redis-master-2 -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master-2" ]]
|
||||||
output_pod=$("${kube_cmd[@]}" get pod redis-master-2 -o json --output-version=v1beta1 "${kube_flags[@]}")
|
output_pod=$("${kube_cmd[@]}" get pod redis-master-2 -o json --output-version=v1beta1 "${kube_flags[@]}")
|
||||||
"${kube_cmd[@]}" delete pod redis-master-2 "${kube_flags[@]}"
|
"${kube_cmd[@]}" delete pod redis-master-2 "${kube_flags[@]}"
|
||||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .Items }}' "${kube_flags[@]}") -eq 0 ]]
|
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 0 ]]
|
||||||
echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}"
|
echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}"
|
||||||
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .Items }}' "${kube_flags[@]}") -eq 1 ]]
|
[[ $("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}") -eq 1 ]]
|
||||||
"${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master-2"
|
"${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master-2"
|
||||||
"${kube_cmd[@]}" describe pod redis-master-2 "${kube_flags[@]}" | grep -q 'Name:.*redis-master-2'
|
"${kube_cmd[@]}" describe pod redis-master-2 "${kube_flags[@]}" | grep -q 'Name:.*redis-master-2'
|
||||||
"${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
"${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
||||||
|
@ -319,19 +319,32 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
|
|
||||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||||
type TemplatePrinter struct {
|
type TemplatePrinter struct {
|
||||||
Template *template.Template
|
template *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||||
|
t, err := template.New("output").Parse(string(tmpl))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &TemplatePrinter{t}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print parses the data as JSON, and re-formats it with the Go Template.
|
// Print parses the data as JSON, and re-formats it with the Go Template.
|
||||||
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
||||||
obj, err := latest.Codec.Decode(data)
|
obj := map[string]interface{}{}
|
||||||
|
err := json.Unmarshal(data, &obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return t.PrintObj(obj, w)
|
return t.template.Execute(w, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj formats the obj with the Go Template.
|
// PrintObj formats the obj with the Go Template.
|
||||||
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||||
return t.Template.Execute(w, obj)
|
data, err := latest.Codec.Encode(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.Print(data, w)
|
||||||
}
|
}
|
||||||
|
@ -161,3 +161,19 @@ func TestUnknownTypePrinting(t *testing.T) {
|
|||||||
t.Errorf("An error was expected from printing unknown type")
|
t.Errorf("An error was expected from printing unknown type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||||
|
// kind is always blank in memory and set on the wire
|
||||||
|
printer, err := NewTemplatePrinter([]byte(`{{.kind}}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tmpl fail: %v", err)
|
||||||
|
}
|
||||||
|
buffer := &bytes.Buffer{}
|
||||||
|
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("print fail: %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "Pod", string(buffer.Bytes()); e != a {
|
||||||
|
t.Errorf("Expected %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@ -45,35 +46,26 @@ func GetPrinter(format, templateFile string, defaultPrinter ResourcePrinter) (Re
|
|||||||
case "yaml":
|
case "yaml":
|
||||||
printer = &YAMLPrinter{}
|
printer = &YAMLPrinter{}
|
||||||
case "template":
|
case "template":
|
||||||
var data []byte
|
|
||||||
if len(templateFile) == 0 {
|
if len(templateFile) == 0 {
|
||||||
return nil, false, fmt.Errorf("template format specified but no template given")
|
return nil, false, fmt.Errorf("template format specified but no template given")
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("output").Parse(templateFile)
|
var err error
|
||||||
|
printer, err = NewTemplatePrinter([]byte(templateFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
return nil, false, fmt.Errorf("error parsing template %s, %v\n", templateFile, err)
|
||||||
}
|
|
||||||
printer = &TemplatePrinter{
|
|
||||||
Template: tmpl,
|
|
||||||
}
|
}
|
||||||
case "templatefile":
|
case "templatefile":
|
||||||
var data []byte
|
if len(templateFile) == 0 {
|
||||||
if len(templateFile) > 0 {
|
|
||||||
var err error
|
|
||||||
data, err = ioutil.ReadFile(templateFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, false, fmt.Errorf("templatefile format specified but no template file given")
|
return nil, false, fmt.Errorf("templatefile format specified but no template file given")
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("output").Parse(string(data))
|
data, err := ioutil.ReadFile(templateFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("error reading template %s, %v\n", templateFile, err)
|
||||||
|
}
|
||||||
|
printer, err = NewTemplatePrinter(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
return nil, false, fmt.Errorf("error parsing template %s, %v\n", string(data), err)
|
||||||
}
|
}
|
||||||
printer = &TemplatePrinter{
|
|
||||||
Template: tmpl,
|
|
||||||
}
|
|
||||||
case "":
|
case "":
|
||||||
printer = defaultPrinter
|
printer = defaultPrinter
|
||||||
versioned = false
|
versioned = false
|
||||||
@ -323,12 +315,29 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
|
|
||||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||||
type TemplatePrinter struct {
|
type TemplatePrinter struct {
|
||||||
Template *template.Template
|
template *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||||
|
t, err := template.New("output").Parse(string(tmpl))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &TemplatePrinter{t}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintObj formats the obj with the Go Template.
|
// PrintObj formats the obj with the Go Template.
|
||||||
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
func (t *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||||
return t.Template.Execute(w, obj)
|
data, err := latest.Codec.Encode(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
outObj := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal(data, &outObj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.template.Execute(w, outObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tabbedString(f func(*tabwriter.Writer) error) (string, error) {
|
func tabbedString(f func(*tabwriter.Writer) error) (string, error) {
|
||||||
|
@ -86,14 +86,17 @@ func TestPrintYAML(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintTemplate(t *testing.T) {
|
func TestPrintTemplate(t *testing.T) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
printer, versioned, err := GetPrinter("template", "{{ .Name }}", nil)
|
printer, versioned, err := GetPrinter("template", "{{.id}}", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %#v", err)
|
t.Fatalf("unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
if !versioned {
|
if !versioned {
|
||||||
t.Errorf("printer should be versioned")
|
t.Errorf("printer should be versioned")
|
||||||
}
|
}
|
||||||
printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
err = printer.PrintObj(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}, buf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %#v", err)
|
||||||
|
}
|
||||||
if buf.String() != "foo" {
|
if buf.String() != "foo" {
|
||||||
t.Errorf("unexpected output: %s", buf.String())
|
t.Errorf("unexpected output: %s", buf.String())
|
||||||
}
|
}
|
||||||
@ -204,3 +207,19 @@ func TestUnknownTypePrinting(t *testing.T) {
|
|||||||
t.Errorf("An error was expected from printing unknown type")
|
t.Errorf("An error was expected from printing unknown type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||||
|
// kind is always blank in memory and set on the wire
|
||||||
|
printer, err := NewTemplatePrinter([]byte(`{{.kind}}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tmpl fail: %v", err)
|
||||||
|
}
|
||||||
|
buffer := &bytes.Buffer{}
|
||||||
|
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("print fail: %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "Pod", string(buffer.Bytes()); e != a {
|
||||||
|
t.Errorf("Expected %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user