Merge pull request #79423 from danwinship/agnhost-connect

Add new agnhost subcommand for a networking test
This commit is contained in:
Kubernetes Prow Robot 2019-07-11 14:33:46 -07:00 committed by GitHub
commit 25dc90aa8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 2 deletions

View File

@ -17,6 +17,7 @@ go_library(
importpath = "k8s.io/kubernetes/test/images/agnhost",
deps = [
"//test/images/agnhost/audit-proxy:go_default_library",
"//test/images/agnhost/connect:go_default_library",
"//test/images/agnhost/crd-conversion-webhook:go_default_library",
"//test/images/agnhost/dns:go_default_library",
"//test/images/agnhost/entrypoint-tester:go_default_library",
@ -51,6 +52,7 @@ filegroup(
srcs = [
":package-srcs",
"//test/images/agnhost/audit-proxy:all-srcs",
"//test/images/agnhost/connect:all-srcs",
"//test/images/agnhost/crd-conversion-webhook:all-srcs",
"//test/images/agnhost/dns:all-srcs",
"//test/images/agnhost/entrypoint-tester:all-srcs",

View File

@ -10,7 +10,7 @@ information could retrieved through other means. To combat those differences,
`agnhost` is an extendable CLI that behaves and outputs the same expected content,
no matter the underlying OS. The name itself reflects this idea, being a portmanteau
word of the words agnost and host.
word of the words agnostic and host.
The image was created for testing purposes, reducing the need for having different test
cases for the same tested behaviour.
@ -77,6 +77,29 @@ Usage:
```
### connect
Tries to open a TCP connection to the given host and port. On error it
prints an error message prefixed with a specific fixed string that
test cases can check for:
* `UNKNOWN` - Generic/unknown (non-network) error (eg, bad arguments)
* `TIMEOUT` - The connection attempt timed out
* `DNS` - An error in DNS resolution
* `REFUSED` - Connection refused
* `OTHER` - Other networking error (eg, "no route to host")
(Theoretically it would be nicer for it to distinguish these by exit
code, but it's much easier for test programs to compare strings in the
output than to check the exit code.)
Usage:
```console
kubectl exec test-agnost -- /agnost connect [--timeout=<duration>] <host>:<port>
```
### crd-conversion-webhook
The subcommand tests `CustomResourceConversionWebhook`. After deploying it to Kubernetes cluster,

View File

@ -1 +1 @@
2.2
2.4

View File

@ -23,6 +23,7 @@ import (
"k8s.io/klog"
"k8s.io/kubernetes/test/images/agnhost/audit-proxy"
"k8s.io/kubernetes/test/images/agnhost/connect"
"k8s.io/kubernetes/test/images/agnhost/crd-conversion-webhook"
"k8s.io/kubernetes/test/images/agnhost/dns"
"k8s.io/kubernetes/test/images/agnhost/entrypoint-tester"
@ -45,6 +46,7 @@ import (
func main() {
rootCmd := &cobra.Command{Use: "app"}
rootCmd.AddCommand(auditproxy.CmdAuditProxy)
rootCmd.AddCommand(connect.CmdConnect)
rootCmd.AddCommand(crdconvwebhook.CmdCrdConversionWebhook)
rootCmd.AddCommand(dns.CmdDNSSuffix)
rootCmd.AddCommand(dns.CmdDNSServerList)

View File

@ -0,0 +1,26 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["connect.go"],
importpath = "k8s.io/kubernetes/test/images/agnhost/connect",
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,83 @@
/*
Copyright 2019 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 connect
import (
"fmt"
"net"
"os"
"syscall"
"time"
"github.com/spf13/cobra"
)
// CmdConnect is used by agnhost Cobra.
var CmdConnect = &cobra.Command{
Use: "connect [host:port]",
Short: "Attempts a TCP connection and returns useful errors",
Long: `Tries to open a TCP connection to the given host and port. On error it prints an error message prefixed with a specific fixed string that test cases can check for:
* UNKNOWN - Generic/unknown (non-network) error (eg, bad arguments)
* TIMEOUT - The connection attempt timed out
* DNS - An error in DNS resolution
* REFUSED - Connection refused
* OTHER - Other networking error (eg, "no route to host")`,
Args: cobra.ExactArgs(1),
Run: main,
}
var timeout time.Duration
func init() {
CmdConnect.Flags().DurationVar(&timeout, "timeout", time.Duration(0), "Maximum time before returning an error")
}
func main(cmd *cobra.Command, args []string) {
dest := args[0]
// Redundantly parse and resolve the destination so we can return the correct
// errors if there's a problem.
if _, _, err := net.SplitHostPort(dest); err != nil {
fmt.Fprintf(os.Stderr, "UNKNOWN: %v\n", err)
os.Exit(1)
}
if _, err := net.ResolveTCPAddr("tcp", dest); err != nil {
fmt.Fprintf(os.Stderr, "DNS: %v\n", err)
os.Exit(1)
}
conn, err := net.DialTimeout("tcp", dest, timeout)
if err == nil {
conn.Close()
os.Exit(0)
}
if opErr, ok := err.(*net.OpError); ok {
if opErr.Timeout() {
fmt.Fprintf(os.Stderr, "TIMEOUT\n")
os.Exit(1)
} else if syscallErr, ok := opErr.Err.(*os.SyscallError); ok {
if syscallErr.Err == syscall.ECONNREFUSED {
fmt.Fprintf(os.Stderr, "REFUSED\n")
os.Exit(1)
}
}
}
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
os.Exit(1)
}