mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #90797 from fedepaol/sctpconnectporter
Add SCTP support to agnhost connect / porter commands.
This commit is contained in:
commit
0072d8ae23
@ -88,7 +88,7 @@ Usage:
|
|||||||
|
|
||||||
### connect
|
### connect
|
||||||
|
|
||||||
Tries to open a TCP connection to the given host and port. On error it
|
Tries to open a TCP or SCTP connection to the given host and port. On error it
|
||||||
prints an error message prefixed with a specific fixed string that
|
prints an error message prefixed with a specific fixed string that
|
||||||
test cases can check for:
|
test cases can check for:
|
||||||
|
|
||||||
@ -105,9 +105,11 @@ output than to check the exit code.)
|
|||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
kubectl exec test-agnost -- /agnost connect [--timeout=<duration>] <host>:<port>
|
kubectl exec test-agnhost -- /agnhost connect [--timeout=<duration>] [--protocol=<protocol>] <host>:<port>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The optional `--protocol` parameter can be set to `sctp` to test SCTP
|
||||||
|
connections. The default value is `tcp`.
|
||||||
|
|
||||||
### crd-conversion-webhook
|
### crd-conversion-webhook
|
||||||
|
|
||||||
@ -543,10 +545,10 @@ Usage:
|
|||||||
|
|
||||||
### porter
|
### porter
|
||||||
|
|
||||||
Serves requested data on ports specified in ENV variables. For example, if the environment
|
Serves requested data on ports specified in environment variables of the form `SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN]`. eg:
|
||||||
variable `SERVE_PORT_9001` is set, then the subcommand will start serving on the port 9001.
|
- `SERVE_PORT_9001` - serve TCP connections on port 9001
|
||||||
Additionally, if the environment variable `SERVE_TLS_PORT_9002` is set, then the subcommand
|
- `SERVE_TLS_PORT_9002` - serve TLS-encrypted TCP connections on port 9002
|
||||||
will start a TLS server on that port.
|
- `SERVE_SCTP_PORT_9003` - serve SCTP connections on port 9003
|
||||||
|
|
||||||
The included `localhost.crt` is a PEM-encoded TLS cert with SAN IPs `127.0.0.1` and `[::1]`,
|
The included `localhost.crt` is a PEM-encoded TLS cert with SAN IPs `127.0.0.1` and `[::1]`,
|
||||||
expiring in January 2084, generated from `src/crypto/tls`:
|
expiring in January 2084, generated from `src/crypto/tls`:
|
||||||
|
@ -9,7 +9,10 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["connect.go"],
|
srcs = ["connect.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/agnhost/connect",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/connect",
|
||||||
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
|
deps = [
|
||||||
|
"//vendor/github.com/ishidawataru/sctp:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -23,14 +23,15 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ishidawataru/sctp"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CmdConnect is used by agnhost Cobra.
|
// CmdConnect is used by agnhost Cobra.
|
||||||
var CmdConnect = &cobra.Command{
|
var CmdConnect = &cobra.Command{
|
||||||
Use: "connect [host:port]",
|
Use: "connect [host:port]",
|
||||||
Short: "Attempts a TCP connection and returns useful errors",
|
Short: "Attempts a TCP or SCTP 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:
|
Long: `Tries to open a TCP or SCTP 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)
|
* UNKNOWN - Generic/unknown (non-network) error (eg, bad arguments)
|
||||||
* TIMEOUT - The connection attempt timed out
|
* TIMEOUT - The connection attempt timed out
|
||||||
@ -42,14 +43,27 @@ var CmdConnect = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var timeout time.Duration
|
var timeout time.Duration
|
||||||
|
var protocol string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
CmdConnect.Flags().DurationVar(&timeout, "timeout", time.Duration(0), "Maximum time before returning an error")
|
CmdConnect.Flags().DurationVar(&timeout, "timeout", time.Duration(0), "Maximum time before returning an error")
|
||||||
|
CmdConnect.Flags().StringVar(&protocol, "protocol", "tcp", "The protocol to use to perform the connection, can be tcp or sctp")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main(cmd *cobra.Command, args []string) {
|
func main(cmd *cobra.Command, args []string) {
|
||||||
dest := args[0]
|
dest := args[0]
|
||||||
|
switch protocol {
|
||||||
|
case "", "tcp":
|
||||||
|
connectTCP(dest, timeout)
|
||||||
|
case "sctp":
|
||||||
|
connectSCTP(dest, timeout)
|
||||||
|
default:
|
||||||
|
fmt.Fprint(os.Stderr, "Unsupported protocol\n", protocol)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectTCP(dest string, timeout time.Duration) {
|
||||||
// Redundantly parse and resolve the destination so we can return the correct
|
// Redundantly parse and resolve the destination so we can return the correct
|
||||||
// errors if there's a problem.
|
// errors if there's a problem.
|
||||||
if _, _, err := net.SplitHostPort(dest); err != nil {
|
if _, _, err := net.SplitHostPort(dest); err != nil {
|
||||||
@ -81,3 +95,33 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
|
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func connectSCTP(dest string, timeout time.Duration) {
|
||||||
|
addr, err := sctp.ResolveSCTPAddr("sctp", dest)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "DNS: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutCh := time.After(timeout)
|
||||||
|
errCh := make(chan (error))
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
conn, err := sctp.DialSCTP("sctp", nil, addr)
|
||||||
|
if err == nil {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
errCh <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err := <-errCh:
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "OTHER: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
case <-timeoutCh:
|
||||||
|
fmt.Fprint(os.Stderr, "TIMEOUT\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,7 +9,10 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["porter.go"],
|
srcs = ["porter.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/agnhost/porter",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/porter",
|
||||||
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
|
deps = [
|
||||||
|
"//vendor/github.com/ishidawataru/sctp:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -29,19 +29,24 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ishidawataru/sctp"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
const prefix = "SERVE_PORT_"
|
const tcpPrefix = "SERVE_PORT_"
|
||||||
|
const sctpPrefix = "SERVE_SCTP_PORT_"
|
||||||
const tlsPrefix = "SERVE_TLS_PORT_"
|
const tlsPrefix = "SERVE_TLS_PORT_"
|
||||||
|
|
||||||
// CmdPorter is used by agnhost Cobra.
|
// CmdPorter is used by agnhost Cobra.
|
||||||
var CmdPorter = &cobra.Command{
|
var CmdPorter = &cobra.Command{
|
||||||
Use: "porter",
|
Use: "porter",
|
||||||
Short: "Serves requested data on ports specified in ENV variables",
|
Short: "Serves requested data on ports specified in ENV variables",
|
||||||
Long: `Serves requested data on ports specified in ENV variables. For example, if the environment variable "SERVE_PORT_9001" is set, then the subcommand will start serving on the port 9001.
|
Long: `Serves requested data on ports specified in environment variables of the form SERVE_{PORT,TLS_PORT,SCTP_PORT}_[NNNN].
|
||||||
|
|
||||||
Additionally, if the environment variable "SERVE_TLS_PORT_9002" is set, then the subcommand will start a TLS server on that port.
|
eg:
|
||||||
|
* SERVE_PORT_9001 - serve TCP connections on port 9001
|
||||||
|
* SERVE_TLS_PORT_9002 - serve TLS-encrypted TCP connections on port 9002
|
||||||
|
* SERVE_SCTP_PORT_9003 - serve SCTP connections on port 9003
|
||||||
|
|
||||||
The included "localhost.crt" is a PEM-encoded TLS cert with SAN IPs "127.0.0.1" and "[::1]", expiring in January 2084, generated from "src/crypto/tls".
|
The included "localhost.crt" is a PEM-encoded TLS cert with SAN IPs "127.0.0.1" and "[::1]", expiring in January 2084, generated from "src/crypto/tls".
|
||||||
|
|
||||||
@ -58,11 +63,15 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
parts := strings.SplitN(vk, "=", 2)
|
parts := strings.SplitN(vk, "=", 2)
|
||||||
key := parts[0]
|
key := parts[0]
|
||||||
value := parts[1]
|
value := parts[1]
|
||||||
if strings.HasPrefix(key, prefix) {
|
|
||||||
port := strings.TrimPrefix(key, prefix)
|
switch {
|
||||||
|
case strings.HasPrefix(key, tcpPrefix):
|
||||||
|
port := strings.TrimPrefix(key, tcpPrefix)
|
||||||
go servePort(port, value)
|
go servePort(port, value)
|
||||||
}
|
case strings.HasPrefix(key, sctpPrefix):
|
||||||
if strings.HasPrefix(key, tlsPrefix) {
|
port := strings.TrimPrefix(key, sctpPrefix)
|
||||||
|
go serveSCTPPort(port, value)
|
||||||
|
case strings.HasPrefix(key, tlsPrefix):
|
||||||
port := strings.TrimPrefix(key, tlsPrefix)
|
port := strings.TrimPrefix(key, tlsPrefix)
|
||||||
go serveTLSPort(port, value)
|
go serveTLSPort(port, value)
|
||||||
}
|
}
|
||||||
@ -98,3 +107,38 @@ func serveTLSPort(port, value string) {
|
|||||||
}
|
}
|
||||||
log.Printf("tls server on port %q with certFile=%q, keyFile=%q failed: %v", port, certFile, keyFile, s.ListenAndServeTLS(certFile, keyFile))
|
log.Printf("tls server on port %q with certFile=%q, keyFile=%q failed: %v", port, certFile, keyFile, s.ListenAndServeTLS(certFile, keyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serveSCTPPort(port, value string) {
|
||||||
|
serverAddress, err := sctp.ResolveSCTPAddr("sctp", "0.0.0.0:"+port)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Sctp: failed to resolve address. error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listener, err := sctp.ListenSCTP("sctp", serverAddress)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to listen SCTP. error:", err)
|
||||||
|
}
|
||||||
|
log.Printf("Started SCTP server")
|
||||||
|
|
||||||
|
defer listener.Close()
|
||||||
|
defer func() {
|
||||||
|
log.Printf("SCTP server exited")
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := listener.AcceptSCTP()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to accept SCTP. error:", err)
|
||||||
|
}
|
||||||
|
go func(conn *sctp.SCTPConn) {
|
||||||
|
defer conn.Close()
|
||||||
|
log.Println("Sending response")
|
||||||
|
_, err = conn.Write([]byte(value))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to send response", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("Response sent")
|
||||||
|
}(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
linux/amd64=REGISTRY/agnhost:2.19-linux-amd64
|
linux/amd64=REGISTRY/agnhost:2.20-linux-amd64
|
||||||
linux/arm=REGISTRY/agnhost:2.19-linux-arm
|
linux/arm=REGISTRY/agnhost:2.20-linux-arm
|
||||||
linux/arm64=REGISTRY/agnhost:2.19-linux-arm64
|
linux/arm64=REGISTRY/agnhost:2.20-linux-arm64
|
||||||
linux/ppc64le=REGISTRY/agnhost:2.19-linux-ppc64le
|
linux/ppc64le=REGISTRY/agnhost:2.20-linux-ppc64le
|
||||||
linux/s390x=REGISTRY/agnhost:2.19-linux-s390x
|
linux/s390x=REGISTRY/agnhost:2.20-linux-s390x
|
||||||
windows/amd64/1809=REGISTRY/agnhost:2.19-windows-amd64-1809
|
windows/amd64/1809=REGISTRY/agnhost:2.20-windows-amd64-1809
|
||||||
windows/amd64/1903=REGISTRY/agnhost:2.19-windows-amd64-1903
|
windows/amd64/1903=REGISTRY/agnhost:2.20-windows-amd64-1903
|
||||||
windows/amd64/1909=REGISTRY/agnhost:2.19-windows-amd64-1909
|
windows/amd64/1909=REGISTRY/agnhost:2.20-windows-amd64-1909
|
||||||
|
@ -1 +1 @@
|
|||||||
1.2
|
1.3
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
linux/amd64=REGISTRY/agnhost:2.19-linux-amd64
|
linux/amd64=REGISTRY/agnhost:2.20-linux-amd64
|
||||||
linux/arm=REGISTRY/agnhost:2.19-linux-arm
|
linux/arm=REGISTRY/agnhost:2.20-linux-arm
|
||||||
linux/arm64=REGISTRY/agnhost:2.19-linux-arm64
|
linux/arm64=REGISTRY/agnhost:2.20-linux-arm64
|
||||||
linux/ppc64le=REGISTRY/agnhost:2.19-linux-ppc64le
|
linux/ppc64le=REGISTRY/agnhost:2.20-linux-ppc64le
|
||||||
linux/s390x=REGISTRY/agnhost:2.19-linux-s390x
|
linux/s390x=REGISTRY/agnhost:2.20-linux-s390x
|
||||||
windows/amd64/1809=REGISTRY/agnhost:2.19-windows-amd64-1809
|
windows/amd64/1809=REGISTRY/agnhost:2.20-windows-amd64-1809
|
||||||
windows/amd64/1903=REGISTRY/agnhost:2.19-windows-amd64-1903
|
windows/amd64/1903=REGISTRY/agnhost:2.20-windows-amd64-1903
|
||||||
windows/amd64/1909=REGISTRY/agnhost:2.19-windows-amd64-1909
|
windows/amd64/1909=REGISTRY/agnhost:2.20-windows-amd64-1909
|
||||||
|
@ -1 +1 @@
|
|||||||
1.2
|
1.3
|
||||||
|
Loading…
Reference in New Issue
Block a user