mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
Merge pull request #3464 from smarterclayton/fix_invalid_json_in_services.sh
Fix e2e invalid JSON, ensure CLI communicates invalid JSON errors effectively
This commit is contained in:
commit
e14d5f3416
@ -87,9 +87,9 @@ function start_service() {
|
|||||||
"containerPort": 9376,
|
"containerPort": 9376,
|
||||||
"protocol": "TCP"
|
"protocol": "TCP"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
|
@ -531,9 +531,9 @@ func kubecfgArgs() string {
|
|||||||
// kubectl command (begining with a space).
|
// kubectl command (begining with a space).
|
||||||
func kubectlArgs() string {
|
func kubectlArgs() string {
|
||||||
if *checkVersionSkew {
|
if *checkVersionSkew {
|
||||||
return " --match-server-version"
|
return " --match-server-version --v=4"
|
||||||
}
|
}
|
||||||
return ""
|
return " --v=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
func bashWrap(cmd string) string {
|
func bashWrap(cmd string) string {
|
||||||
|
@ -115,6 +115,9 @@ for version in "${kube_api_versions[@]}"; do
|
|||||||
[ "$(kubectl get minions -t $'{{ .apiVersion }}' "${kube_flags[@]}")" == "${version}" ]
|
[ "$(kubectl get minions -t $'{{ .apiVersion }}' "${kube_flags[@]}")" == "${version}" ]
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# passing no arguments to create is an error
|
||||||
|
[ ! $(kubectl create) ]
|
||||||
|
|
||||||
kube::log::status "Testing kubectl(${version}:pods)"
|
kube::log::status "Testing kubectl(${version}:pods)"
|
||||||
kubectl get pods "${kube_flags[@]}"
|
kubectl get pods "${kube_flags[@]}"
|
||||||
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
|
||||||
@ -138,7 +141,17 @@ for version in "${kube_api_versions[@]}"; do
|
|||||||
output_service=$(kubectl get service frontend -o json --output-version=v1beta3 "${kube_flags[@]}")
|
output_service=$(kubectl get service frontend -o json --output-version=v1beta3 "${kube_flags[@]}")
|
||||||
kubectl delete service frontend "${kube_flags[@]}"
|
kubectl delete service frontend "${kube_flags[@]}"
|
||||||
echo "${output_service}" | kubectl create -f - "${kube_flags[@]}"
|
echo "${output_service}" | kubectl create -f - "${kube_flags[@]}"
|
||||||
|
kubectl create -f - "${kube_flags[@]}" << __EOF__
|
||||||
|
{
|
||||||
|
"kind": "Service",
|
||||||
|
"apiVersion": "v1beta1",
|
||||||
|
"id": "service-${version}-test",
|
||||||
|
"port": 80,
|
||||||
|
"protocol": "TCP"
|
||||||
|
}
|
||||||
|
__EOF__
|
||||||
kubectl get services "${kube_flags[@]}"
|
kubectl get services "${kube_flags[@]}"
|
||||||
|
kubectl get services "service-${version}-test" "${kube_flags[@]}"
|
||||||
kubectl delete service frontend "${kube_flags[@]}"
|
kubectl delete service frontend "${kube_flags[@]}"
|
||||||
|
|
||||||
kube::log::status "Testing kubectl(${version}:replicationcontrollers)"
|
kube::log::status "Testing kubectl(${version}:replicationcontrollers)"
|
||||||
|
@ -55,6 +55,7 @@ Examples:
|
|||||||
Flatten().
|
Flatten().
|
||||||
Do()
|
Do()
|
||||||
|
|
||||||
|
count := 0
|
||||||
err = r.Visit(func(info *resource.Info) error {
|
err = r.Visit(func(info *resource.Info) error {
|
||||||
data, err := info.Mapping.Codec.Encode(info.Object)
|
data, err := info.Mapping.Codec.Encode(info.Object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,11 +67,15 @@ Examples:
|
|||||||
if err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data); err != nil {
|
if err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
count++
|
||||||
// TODO: if generation of names added to server side, change this to use the server's name
|
// TODO: if generation of names added to server side, change this to use the server's name
|
||||||
fmt.Fprintf(out, "%s\n", info.Name)
|
fmt.Fprintf(out, "%s\n", info.Name)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
if count == 0 {
|
||||||
|
checkErr(fmt.Errorf("no objects passed to create"))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file to use to create the resource")
|
cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file to use to create the resource")
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -337,7 +338,10 @@ type StreamVisitor struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewStreamVisitor creates a visitor that will return resources that were encoded into the provided
|
// NewStreamVisitor creates a visitor that will return resources that were encoded into the provided
|
||||||
// stream. If ignoreErrors is set, unrecognized or invalid objects will be skipped and logged.
|
// stream. If ignoreErrors is set, unrecognized or invalid objects will be skipped and logged. An
|
||||||
|
// empty stream is treated as an error for now.
|
||||||
|
// TODO: convert ignoreErrors into a func(data, error, count) bool that consumers can use to decide
|
||||||
|
// what to do with ignored errors.
|
||||||
func NewStreamVisitor(r io.Reader, mapper *Mapper, source string, ignoreErrors bool) Visitor {
|
func NewStreamVisitor(r io.Reader, mapper *Mapper, source string, ignoreErrors bool) Visitor {
|
||||||
return &StreamVisitor{r, mapper, source, ignoreErrors}
|
return &StreamVisitor{r, mapper, source, ignoreErrors}
|
||||||
}
|
}
|
||||||
@ -353,10 +357,14 @@ func (v *StreamVisitor) Visit(fn VisitorFunc) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ext.RawJSON = bytes.TrimSpace(ext.RawJSON)
|
||||||
|
if len(ext.RawJSON) == 0 || bytes.Equal(ext.RawJSON, []byte("null")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
info, err := v.InfoForData(ext.RawJSON, v.Source)
|
info, err := v.InfoForData(ext.RawJSON, v.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if v.IgnoreErrors {
|
if v.IgnoreErrors {
|
||||||
glog.V(2).Infof("Unable to read item from stream %q: %v", err)
|
glog.Warningf("Could not read an encoded object from %s: %v", v.Source, err)
|
||||||
glog.V(4).Infof("Unreadable: %s", string(ext.RawJSON))
|
glog.V(4).Infof("Unreadable: %s", string(ext.RawJSON))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,6 @@ func guessJSONStream(r io.Reader, size int) (io.Reader, bool) {
|
|||||||
// Return true if the first non-whitespace bytes in buf is
|
// Return true if the first non-whitespace bytes in buf is
|
||||||
// prefix
|
// prefix
|
||||||
func hasPrefix(buf []byte, prefix []byte) bool {
|
func hasPrefix(buf []byte, prefix []byte) bool {
|
||||||
buf = bytes.TrimLeftFunc(buf, unicode.IsSpace)
|
trim := bytes.TrimLeftFunc(buf, unicode.IsSpace)
|
||||||
return bytes.HasPrefix(buf, prefix)
|
return bytes.HasPrefix(trim, prefix)
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,21 @@ func TestSplitYAMLDocument(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGuessJSON(t *testing.T) {
|
||||||
|
if r, isJSON := guessJSONStream(bytes.NewReader([]byte(" \n{}")), 100); !isJSON {
|
||||||
|
t.Fatalf("expected stream to be JSON")
|
||||||
|
} else {
|
||||||
|
b := make([]byte, 30)
|
||||||
|
n, err := r.Read(b)
|
||||||
|
if err != nil || n != 4 {
|
||||||
|
t.Fatalf("unexpected body: %d / %v", n, err)
|
||||||
|
}
|
||||||
|
if string(b[:n]) != " \n{}" {
|
||||||
|
t.Fatalf("unexpected body: %q", string(b[:n]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestScanYAML(t *testing.T) {
|
func TestScanYAML(t *testing.T) {
|
||||||
s := bufio.NewScanner(bytes.NewReader([]byte(`---
|
s := bufio.NewScanner(bytes.NewReader([]byte(`---
|
||||||
stuff: 1
|
stuff: 1
|
||||||
@ -130,7 +145,10 @@ func TestYAMLOrJSONDecoder(t *testing.T) {
|
|||||||
{" \na: b", 2, false, false, []generic{
|
{" \na: b", 2, false, false, []generic{
|
||||||
{"a": "b"},
|
{"a": "b"},
|
||||||
}},
|
}},
|
||||||
{` \n{"a": "b"}`, 2, false, true, []generic{
|
{" \n{\"a\": \"b\"}", 2, false, true, []generic{
|
||||||
|
{"a": "b"},
|
||||||
|
}},
|
||||||
|
{" \n{\"a\": \"b\"}", 3, true, false, []generic{
|
||||||
{"a": "b"},
|
{"a": "b"},
|
||||||
}},
|
}},
|
||||||
{` {"a":"b"}`, 100, true, false, []generic{
|
{` {"a":"b"}`, 100, true, false, []generic{
|
||||||
|
Loading…
Reference in New Issue
Block a user