mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Merge pull request #78390 from bclau/test-images/centralize-images-to-agnhost-part-2
Centralizes images into agnhost (part 2)
This commit is contained in:
commit
aa125b4dd5
@ -66,7 +66,7 @@ go_library(
|
|||||||
"//test/e2e/framework/providers/gce:go_default_library",
|
"//test/e2e/framework/providers/gce:go_default_library",
|
||||||
"//test/e2e/framework/ssh:go_default_library",
|
"//test/e2e/framework/ssh:go_default_library",
|
||||||
"//test/e2e/network/scale:go_default_library",
|
"//test/e2e/network/scale:go_default_library",
|
||||||
"//test/images/net/nat:go_default_library",
|
"//test/images/agnhost/net/nat:go_default_library",
|
||||||
"//test/utils:go_default_library",
|
"//test/utils:go_default_library",
|
||||||
"//test/utils/image:go_default_library",
|
"//test/utils/image:go_default_library",
|
||||||
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud:go_default_library",
|
"//vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud:go_default_library",
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
||||||
e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
|
e2essh "k8s.io/kubernetes/test/e2e/framework/ssh"
|
||||||
"k8s.io/kubernetes/test/images/net/nat"
|
"k8s.io/kubernetes/test/images/agnhost/net/nat"
|
||||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
|
@ -23,9 +23,6 @@ filegroup(
|
|||||||
"//test/images/logs-generator:all-srcs",
|
"//test/images/logs-generator:all-srcs",
|
||||||
"//test/images/metadata-concealment:all-srcs",
|
"//test/images/metadata-concealment:all-srcs",
|
||||||
"//test/images/mounttest:all-srcs",
|
"//test/images/mounttest:all-srcs",
|
||||||
"//test/images/net:all-srcs",
|
|
||||||
"//test/images/netexec:all-srcs",
|
|
||||||
"//test/images/nettest:all-srcs",
|
|
||||||
"//test/images/no-snat-test:all-srcs",
|
"//test/images/no-snat-test:all-srcs",
|
||||||
"//test/images/no-snat-test-proxy:all-srcs",
|
"//test/images/no-snat-test-proxy:all-srcs",
|
||||||
"//test/images/nonewprivs:all-srcs",
|
"//test/images/nonewprivs:all-srcs",
|
||||||
@ -39,7 +36,6 @@ filegroup(
|
|||||||
"//test/images/sample-device-plugin:all-srcs",
|
"//test/images/sample-device-plugin:all-srcs",
|
||||||
"//test/images/serve-hostname:all-srcs",
|
"//test/images/serve-hostname:all-srcs",
|
||||||
"//test/images/test-webserver:all-srcs",
|
"//test/images/test-webserver:all-srcs",
|
||||||
"//test/images/webhook:all-srcs",
|
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
5
test/images/agnhost/BASEIMAGE
Normal file
5
test/images/agnhost/BASEIMAGE
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
linux/amd64=alpine:3.6
|
||||||
|
linux/arm=arm32v6/alpine:3.6
|
||||||
|
linux/arm64=arm64v8/alpine:3.6
|
||||||
|
linux/ppc64le=ppc64le/alpine:3.6
|
||||||
|
linux/s390x=s390x/alpine:3.6
|
@ -21,7 +21,12 @@ go_library(
|
|||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/test/images/agnhost",
|
importpath = "k8s.io/kubernetes/test/images/agnhost",
|
||||||
deps = [
|
deps = [
|
||||||
|
"//test/images/agnhost/net:go_default_library",
|
||||||
|
"//test/images/agnhost/netexec:go_default_library",
|
||||||
|
"//test/images/agnhost/nettest:go_default_library",
|
||||||
|
"//test/images/agnhost/webhook:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,6 +39,12 @@ filegroup(
|
|||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "all-srcs",
|
name = "all-srcs",
|
||||||
srcs = [":package-srcs"],
|
srcs = [
|
||||||
|
":package-srcs",
|
||||||
|
"//test/images/agnhost/net:all-srcs",
|
||||||
|
"//test/images/agnhost/netexec:all-srcs",
|
||||||
|
"//test/images/agnhost/nettest:all-srcs",
|
||||||
|
"//test/images/agnhost/webhook:all-srcs",
|
||||||
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
@ -12,7 +12,22 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
FROM scratch
|
FROM BASEIMAGE
|
||||||
|
|
||||||
|
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
|
||||||
|
|
||||||
|
# from hostexec image
|
||||||
|
# install necessary packages:
|
||||||
|
# - curl, nc: used by a lot of e2e tests
|
||||||
|
# - iproute2: includes ss used in NodePort tests
|
||||||
|
RUN apk --update add curl netcat-openbsd iproute2 && rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
# PORT 8080 needed by: netexec, nettest
|
||||||
|
# PORT 8081 needed by: netexec
|
||||||
|
EXPOSE 8080 8081
|
||||||
|
|
||||||
|
# from netexec
|
||||||
|
RUN mkdir /uploads
|
||||||
|
|
||||||
ADD agnhost agnhost
|
ADD agnhost agnhost
|
||||||
ENTRYPOINT ["/agnhost"]
|
ENTRYPOINT ["/agnhost"]
|
||||||
|
@ -41,7 +41,7 @@ For example, let's consider the following `pod.yaml` file:
|
|||||||
containers:
|
containers:
|
||||||
- args:
|
- args:
|
||||||
- dns-suffix
|
- dns-suffix
|
||||||
image: gcr.io/kubernetes-e2e-test-images/agnhost:1.0
|
image: gcr.io/kubernetes-e2e-test-images/agnhost:2.1
|
||||||
name: agnhost
|
name: agnhost
|
||||||
dnsConfig:
|
dnsConfig:
|
||||||
nameservers:
|
nameservers:
|
||||||
@ -72,8 +72,125 @@ created with the `pause` argument instead, allowing us execute multiple commands
|
|||||||
kubectl exec test-agnhost -- /agnhost dns-server-list
|
kubectl exec test-agnhost -- /agnhost dns-server-list
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `agnhost` binary is a CLI with the following subcommands:
|
||||||
|
|
||||||
|
### net
|
||||||
|
|
||||||
|
The goal of this Go project is to consolidate all low-level
|
||||||
|
network testing "daemons" into one place. In network testing we
|
||||||
|
frequently have need of simple daemons (common/Runner) that perform
|
||||||
|
some "trivial" set of actions on a socket.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
* A package for each general area that is being tested, for example
|
||||||
|
`nat/` will contain Runners that test various NAT features.
|
||||||
|
* Every runner should be registered via `main.go:makeRunnerMap()`.
|
||||||
|
* Runners receive a JSON options structure as to their configuration. `Run()`
|
||||||
|
should return the disposition of the test.
|
||||||
|
|
||||||
|
Runners can be executed into two different ways, either through the
|
||||||
|
command-line or via an HTTP request:
|
||||||
|
|
||||||
|
Command-line:
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl exec test-agnhost -- /agnhost net --runner <runner> --options <json>
|
||||||
|
kubectl exec test-agnhost -- /agnhost net \
|
||||||
|
--runner nat-closewait-client \
|
||||||
|
--options '{"RemoteAddr":"127.0.0.1:9999"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP server:
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl exec test-agnhost -- /agnhost net --serve :8889
|
||||||
|
kubectl exec test-agnhost -- curl -v -X POST localhost:8889/run/nat-closewait-server \
|
||||||
|
-d '{"LocalAddr":"127.0.0.1:9999"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
[]()
|
||||||
|
|
||||||
|
### netexec
|
||||||
|
|
||||||
|
Starts a HTTP server on given TCP / UDP ports with the following endpoints:
|
||||||
|
|
||||||
|
- `/`: Returns the request's timestamp.
|
||||||
|
- `/clientip`: Returns the request's IP address.
|
||||||
|
- `/dial`: Creates a given number of requests to the given host and port using the given protocol,
|
||||||
|
and returns a JSON with the fields `responses` (successful request responses) and `errors` (
|
||||||
|
failed request responses). Returns `200 OK` status code if the last request succeeded,
|
||||||
|
`417 Expectation Failed` if it did not, or `400 Bad Request` if any of the endpoint's parameters
|
||||||
|
is invalid. The endpoint's parameters are:
|
||||||
|
- `host`: The host that will be dialed.
|
||||||
|
- `port`: The port that will be dialed.
|
||||||
|
- `request`: The HTTP endpoint or data to be sent through UDP. If not specified, it will result
|
||||||
|
in a `400 Bad Request` status code being returned.
|
||||||
|
- `protocol`: The protocol which will be used when making the request. Default value: `http`.
|
||||||
|
Acceptable values: `http`, `udp`.
|
||||||
|
- `tries`: The number of times the request will be performed. Default value: `1`.
|
||||||
|
- `/echo`: Returns the given `msg` (`/echo?msg=echoed_msg`)
|
||||||
|
- `/exit`: Closes the server with the given code (`/exit?code=some-code`). The `code`
|
||||||
|
is expected to be an integer [0-127] or empty; if it is not, it will return an error message.
|
||||||
|
- `/healthz`: Returns `200 OK` if the server is ready, `412 Status Precondition Failed`
|
||||||
|
otherwise. The server is considered not ready if the UDP server did not start yet or
|
||||||
|
it exited.
|
||||||
|
- `/hostname`: Returns the server's hostname.
|
||||||
|
- `/hostName`: Returns the server's hostname.
|
||||||
|
- `/shell`: Executes the given `shellCommand` or `cmd` (`/shell?cmd=some-command`) and
|
||||||
|
returns a JSON containing the fields `output` (command's output) and `error` (command's
|
||||||
|
error message). Returns `200 OK` if the command succeeded, `417 Expectation Failed` if not.
|
||||||
|
- `/shutdown`: Closes the server with the exit code 0.
|
||||||
|
- `/upload`: Accepts a file to be uploaded, writing it in the `/uploads` folder on the host.
|
||||||
|
Returns a JSON with the fields `output` (containing the file's name on the server) and
|
||||||
|
`error` containing any potential server side errors.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl exec test-agnhost -- /agnhost netexec [--http-port <http-port>] [--udp-port <udp-port>]
|
||||||
|
```
|
||||||
|
|
||||||
|
### nettest
|
||||||
|
|
||||||
|
A tiny web server for checking networking connectivity.
|
||||||
|
|
||||||
|
Will dial out to, and expect to hear from, every pod that is a member of the service
|
||||||
|
passed in the flag `--service`.
|
||||||
|
|
||||||
|
Will serve a webserver on given `--port`, and will create the following endpoints:
|
||||||
|
|
||||||
|
- `/read`: to see the current state, or `/quit` to shut down.
|
||||||
|
|
||||||
|
- `/status`: to see `pass/running/fail` determination. (literally, it will return
|
||||||
|
one of those words.)
|
||||||
|
|
||||||
|
- `/write`: is used by other network test pods to register connectivity.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl exec test-agnhost -- /agnhost nettest [--port <port>] [--peers <peers>] [--service <service>] [--namespace <namespace>] [--delay-shutdown <delay>]
|
||||||
|
```
|
||||||
|
|
||||||
|
### webhook (Kubernetes External Admission Webhook)
|
||||||
|
|
||||||
|
The subcommand tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
|
||||||
|
it to kubernetes cluster, administrator needs to create a ValidatingWebhookConfiguration
|
||||||
|
in kubernetes cluster to register remote webhook admission controllers.
|
||||||
|
|
||||||
|
TODO: add the reference when the document for admission webhook v1beta1 API is done.
|
||||||
|
|
||||||
|
Check the [MutatingAdmissionWebhook](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#mutatingwebhookconfiguration-v1beta1-admissionregistration-k8s-io) and [ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#validatingwebhookconfiguration-v1beta1-admissionregistration-k8s-io) documentations for more information about them.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
```console
|
||||||
|
kubectl exec test-agnhost -- /agnhost webhook [--tls-cert-file <key-file>] [--tls-private-key-file <cert-file>]
|
||||||
|
```
|
||||||
|
|
||||||
## Image
|
## Image
|
||||||
|
|
||||||
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:1.0` for Linux
|
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.1` for Linux
|
||||||
containers, and `e2eteam/agnhost:1.0` for Windows containers. In the future, the same
|
containers, and `e2eteam/agnhost:2.1` for Windows containers. In the future, the same
|
||||||
repository can be used for both OSes.
|
repository can be used for both OSes.
|
||||||
|
@ -1 +1 @@
|
|||||||
1.0
|
2.1
|
||||||
|
@ -17,7 +17,15 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/klog"
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/net"
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/netexec"
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/nettest"
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -58,5 +66,16 @@ func main() {
|
|||||||
rootCmd.AddCommand(cmdDNSServerList)
|
rootCmd.AddCommand(cmdDNSServerList)
|
||||||
rootCmd.AddCommand(cmdEtcHosts)
|
rootCmd.AddCommand(cmdEtcHosts)
|
||||||
rootCmd.AddCommand(cmdPause)
|
rootCmd.AddCommand(cmdPause)
|
||||||
|
|
||||||
|
rootCmd.AddCommand(net.CmdNet)
|
||||||
|
rootCmd.AddCommand(netexec.CmdNetexec)
|
||||||
|
rootCmd.AddCommand(nettest.CmdNettest)
|
||||||
|
rootCmd.AddCommand(webhook.CmdWebhook)
|
||||||
|
|
||||||
|
// NOTE(claudiub): Some tests are passing logging related flags, so we need to be able to
|
||||||
|
// accept them. This will also include them in the printed help.
|
||||||
|
loggingFlags := &flag.FlagSet{}
|
||||||
|
klog.InitFlags(loggingFlags)
|
||||||
|
rootCmd.PersistentFlags().AddGoFlagSet(loggingFlags)
|
||||||
rootCmd.Execute()
|
rootCmd.Execute()
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,17 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
|
|
||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_binary",
|
|
||||||
"go_library",
|
"go_library",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_binary(
|
|
||||||
name = "net",
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["main.go"],
|
srcs = ["main.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/net",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/net",
|
||||||
deps = [
|
deps = [
|
||||||
"//test/images/net/common:go_default_library",
|
"//test/images/agnhost/net/common:go_default_library",
|
||||||
"//test/images/net/nat:go_default_library",
|
"//test/images/agnhost/net/nat:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,8 +27,8 @@ filegroup(
|
|||||||
name = "all-srcs",
|
name = "all-srcs",
|
||||||
srcs = [
|
srcs = [
|
||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//test/images/net/common:all-srcs",
|
"//test/images/agnhost/net/common:all-srcs",
|
||||||
"//test/images/net/nat:all-srcs",
|
"//test/images/agnhost/net/nat:all-srcs",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
@ -8,7 +8,7 @@ load(
|
|||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["common.go"],
|
srcs = ["common.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/net/common",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/net/common",
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
@ -14,12 +14,11 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -27,8 +26,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/kubernetes/test/images/net/common"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/test/images/net/nat"
|
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/net/common"
|
||||||
|
"k8s.io/kubernetes/test/images/agnhost/net/nat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type runnerMap map[string]common.Runner
|
type runnerMap map[string]common.Runner
|
||||||
@ -49,8 +50,42 @@ type logOutput struct {
|
|||||||
b bytes.Buffer
|
b bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
// CmdNet is used by agnhost Cobra.
|
||||||
initFlags()
|
var CmdNet = &cobra.Command{
|
||||||
|
Use: "net",
|
||||||
|
Short: "Creates webserver or runner for various networking tests",
|
||||||
|
Long: `The subcommand will run the network tester in server mode if the "--serve" flag is given, and the runners are triggered through HTTP requests.
|
||||||
|
|
||||||
|
Alternatively, if the "--runner" flag is given, it will execute the given runner directly. Note that "--runner" and "--serve" flags cannot be given at the same time.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
agnhost net --runner nat-closewait-client --options '{"RemoteAddr":"127.0.0.1:9999"}'
|
||||||
|
|
||||||
|
agnhost net --serve :8889 && curl -v -X POST localhost:8889/run/nat-closewait-server -d '{"LocalAddr":"127.0.0.1:9999"}'
|
||||||
|
`,
|
||||||
|
Args: cobra.MaximumNArgs(0),
|
||||||
|
Run: main,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
legalRunners := ""
|
||||||
|
for k := range runners {
|
||||||
|
legalRunners += " " + k
|
||||||
|
}
|
||||||
|
CmdNet.Flags().StringVar(&flags.Serve, "serve", "",
|
||||||
|
"Address and port to bind to (e.g. 127.0.0.1:8080). Setting this will "+
|
||||||
|
"run the network tester in server mode runner are triggered through "+
|
||||||
|
"HTTP requests.")
|
||||||
|
CmdNet.Flags().StringVar(&flags.Runner, "runner", "", "Runner to execute (available:"+legalRunners+")")
|
||||||
|
CmdNet.Flags().StringVar(&flags.Options, "options", "", "JSON options to the Runner")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main(cmd *cobra.Command, args []string) {
|
||||||
|
if flags.Runner == "" && flags.Serve == "" {
|
||||||
|
log.Fatalf("Must set either --runner or --serve, see --help")
|
||||||
|
}
|
||||||
|
|
||||||
log.SetFlags(log.Flags() | log.Lshortfile)
|
log.SetFlags(log.Flags() | log.Lshortfile)
|
||||||
|
|
||||||
if flags.Serve == "" {
|
if flags.Serve == "" {
|
||||||
@ -70,29 +105,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initFlags() {
|
|
||||||
legalRunners := ""
|
|
||||||
for k := range runners {
|
|
||||||
legalRunners += " " + k
|
|
||||||
}
|
|
||||||
flag.StringVar(
|
|
||||||
&flags.Serve, "serve", "",
|
|
||||||
"Address and port to bind to (e.g. 127.0.0.1:8080). Setting this will "+
|
|
||||||
"run the network tester in server mode runner are triggered through "+
|
|
||||||
"HTTP requests.")
|
|
||||||
flag.StringVar(
|
|
||||||
&flags.Runner, "runner", "",
|
|
||||||
"Runner to execute (available:"+legalRunners+")")
|
|
||||||
flag.StringVar(
|
|
||||||
&flags.Options, "options", "",
|
|
||||||
"JSON options to the Runner")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if flags.Runner == "" && flags.Serve == "" {
|
|
||||||
log.Fatalf("Must set either -runner or -serve, see --help")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeRunnerMap() runnerMap {
|
func makeRunnerMap() runnerMap {
|
||||||
// runner name is <pkg>-<file>-<specific>.
|
// runner name is <pkg>-<file>-<specific>.
|
||||||
return runnerMap{
|
return runnerMap{
|
@ -8,8 +8,8 @@ load(
|
|||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["closewait.go"],
|
srcs = ["closewait.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/net/nat",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/net/nat",
|
||||||
deps = ["//test/images/net/common:go_default_library"],
|
deps = ["//test/images/agnhost/net/common:go_default_library"],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
@ -33,7 +33,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/test/images/net/common"
|
"k8s.io/kubernetes/test/images/agnhost/net/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// leakedConnection is a global variable that should leak the active
|
// leakedConnection is a global variable that should leak the active
|
@ -2,20 +2,17 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
|
|
||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_binary",
|
|
||||||
"go_library",
|
"go_library",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_binary(
|
|
||||||
name = "netexec",
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["netexec.go"],
|
srcs = ["netexec.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/netexec",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/netexec",
|
||||||
deps = ["//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library"],
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
@ -14,11 +14,10 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package netexec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -33,6 +32,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,6 +44,50 @@ var (
|
|||||||
serverReady = &atomicBool{0}
|
serverReady = &atomicBool{0}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CmdNetexec is used by agnhost Cobra.
|
||||||
|
var CmdNetexec = &cobra.Command{
|
||||||
|
Use: "netexec",
|
||||||
|
Short: "Creates a HTTP / UDP server with various endpoints",
|
||||||
|
Long: `Starts a HTTP server on given TCP / UDP ports with the following endpoints:
|
||||||
|
|
||||||
|
- /: Returns the request's timestamp.
|
||||||
|
- /clientip: Returns the request's IP address.
|
||||||
|
- /dial: Creates a given number of requests to the given host and port using the given protocol,
|
||||||
|
and returns a JSON with the fields "responses" (successful request responses) and "errors" (
|
||||||
|
failed request responses). Returns "200 OK" status code if the last request succeeded,
|
||||||
|
"417 Expectation Failed" if it did not, or "400 Bad Request" if any of the endpoint's parameters
|
||||||
|
is invalid. The endpoint's parameters are:
|
||||||
|
- "host": The host that will be dialed.
|
||||||
|
- "port": The port that will be dialed.
|
||||||
|
- "request": The HTTP endpoint or data to be sent through UDP. If not specified, it will result
|
||||||
|
in a "400 Bad Request" status code being returned.
|
||||||
|
- "protocol": The protocol which will be used when making the request. Default value: "http".
|
||||||
|
Acceptable values: "http", "udp".
|
||||||
|
- "tries": The number of times the request will be performed. Default value: "1".
|
||||||
|
- "/echo": Returns the given "msg" ("/echo?msg=echoed_msg")
|
||||||
|
- "/exit": Closes the server with the given code ("/exit?code=some-code"). The "code"
|
||||||
|
is expected to be an integer [0-127] or empty; if it is not, it will return an error message.
|
||||||
|
- "/healthz": Returns "200 OK" if the server is ready, "412 Status Precondition Failed"
|
||||||
|
otherwise. The server is considered not ready if the UDP server did not start yet or
|
||||||
|
it exited.
|
||||||
|
- "/hostname": Returns the server's hostname.
|
||||||
|
- "/hostName": Returns the server's hostname.
|
||||||
|
- "/shell": Executes the given "shellCommand" or "cmd" ("/shell?cmd=some-command") and
|
||||||
|
returns a JSON containing the fields "output" (command's output) and "error" (command's
|
||||||
|
error message). Returns "200 OK" if the command succeeded, "417 Expectation Failed" if not.
|
||||||
|
- "/shutdown": Closes the server with the exit code 0.
|
||||||
|
- "/upload": Accepts a file to be uploaded, writing it in the "/uploads" folder on the host.
|
||||||
|
Returns a JSON with the fields "output" (containing the file's name on the server) and
|
||||||
|
"error" containing any potential server side errors.`,
|
||||||
|
Args: cobra.MaximumNArgs(0),
|
||||||
|
Run: main,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
CmdNetexec.Flags().IntVar(&httpPort, "http-port", 8080, "HTTP Listen Port")
|
||||||
|
CmdNetexec.Flags().IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port")
|
||||||
|
}
|
||||||
|
|
||||||
// atomicBool uses load/store operations on an int32 to simulate an atomic boolean.
|
// atomicBool uses load/store operations on an int32 to simulate an atomic boolean.
|
||||||
type atomicBool struct {
|
type atomicBool struct {
|
||||||
v int32
|
v int32
|
||||||
@ -62,13 +107,7 @@ func (a *atomicBool) get() bool {
|
|||||||
return atomic.LoadInt32(&a.v) == 1
|
return atomic.LoadInt32(&a.v) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func main(cmd *cobra.Command, args []string) {
|
||||||
flag.IntVar(&httpPort, "http-port", 8080, "HTTP Listen Port")
|
|
||||||
flag.IntVar(&udpPort, "udp-port", 8081, "UDP Listen Port")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
go startUDPServer(udpPort)
|
go startUDPServer(udpPort)
|
||||||
startHTTPServer(httpPort)
|
startHTTPServer(httpPort)
|
||||||
}
|
}
|
@ -2,20 +2,20 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
|
|
||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_binary",
|
|
||||||
"go_library",
|
"go_library",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["nettest.go"],
|
srcs = ["nettest.go"],
|
||||||
importpath = "k8s.io/kubernetes/test/images/nettest",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/nettest",
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,8 +31,3 @@ filegroup(
|
|||||||
srcs = [":package-srcs"],
|
srcs = [":package-srcs"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_binary(
|
|
||||||
name = "nettest",
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
)
|
|
@ -27,12 +27,12 @@ limitations under the License.
|
|||||||
// return one of those words.)
|
// return one of those words.)
|
||||||
//
|
//
|
||||||
// /write is used by other network test pods to register connectivity.
|
// /write is used by other network test pods to register connectivity.
|
||||||
package main
|
|
||||||
|
package nettest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -44,6 +44,8 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/version"
|
"k8s.io/apimachinery/pkg/version"
|
||||||
@ -52,13 +54,42 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
port = flag.Int("port", 8080, "Port number to serve at.")
|
port int
|
||||||
peerCount = flag.Int("peers", 8, "Must find at least this many peers for the test to pass.")
|
peerCount int
|
||||||
service = flag.String("service", "nettest", "Service to find other network test pods in.")
|
service string
|
||||||
namespace = flag.String("namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
|
namespace string
|
||||||
delayShutdown = flag.Int("delay-shutdown", 0, "Number of seconds to delay shutdown when receiving SIGTERM.")
|
delayShutdown int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CmdNettest is used by agnhost Cobra.
|
||||||
|
var CmdNettest = &cobra.Command{
|
||||||
|
Use: "nettest",
|
||||||
|
Short: "Starts a tiny web server for checking networking connectivity",
|
||||||
|
Long: `Starts a web server for checking networking connectivity on the given "--port".
|
||||||
|
|
||||||
|
Will dial out to, and expect to hear from, every pod that is a member of the service
|
||||||
|
passed in the flag "--service".
|
||||||
|
|
||||||
|
The web server will have the following endpoints:
|
||||||
|
|
||||||
|
- "/read": to see the current state, or "/quit" to shut down.
|
||||||
|
|
||||||
|
- "/status": to see "pass/running/fail" determination. (literally, it will return
|
||||||
|
one of those words.)
|
||||||
|
|
||||||
|
- "/write": is used by other network test pods to register connectivity.`,
|
||||||
|
Args: cobra.MaximumNArgs(0),
|
||||||
|
Run: main,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
CmdNettest.Flags().IntVar(&port, "port", 8080, "Port number to serve at.")
|
||||||
|
CmdNettest.Flags().IntVar(&peerCount, "peers", 8, "Must find at least this many peers for the test to pass.")
|
||||||
|
CmdNettest.Flags().StringVar(&service, "service", "nettest", "Service to find other network test pods in.")
|
||||||
|
CmdNettest.Flags().StringVar(&namespace, "namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
|
||||||
|
CmdNettest.Flags().IntVar(&delayShutdown, "delay-shutdown", 0, "Number of seconds to delay shutdown when receiving SIGTERM.")
|
||||||
|
}
|
||||||
|
|
||||||
// State tracks the internal state of our little http server.
|
// State tracks the internal state of our little http server.
|
||||||
// It's returned verbatim over the /read endpoint.
|
// It's returned verbatim over the /read endpoint.
|
||||||
type State struct {
|
type State struct {
|
||||||
@ -85,7 +116,7 @@ func (s *State) doneContactingPeers() {
|
|||||||
func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
|
func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
if len(s.Sent) >= *peerCount && len(s.Received) >= *peerCount {
|
if len(s.Sent) >= peerCount && len(s.Received) >= peerCount {
|
||||||
fmt.Fprintf(w, "pass")
|
fmt.Fprintf(w, "pass")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -94,7 +125,7 @@ func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Logf can't be called while holding the lock, so defer using a goroutine
|
// Logf can't be called while holding the lock, so defer using a goroutine
|
||||||
go s.Logf("Declaring failure for %s/%s with %d sent and %d received and %d peers", *namespace, *service, len(s.Sent), len(s.Received), *peerCount)
|
go s.Logf("Declaring failure for %s/%s with %d sent and %d received and %d peers", namespace, service, len(s.Sent), len(s.Received), peerCount)
|
||||||
fmt.Fprintf(w, "fail")
|
fmt.Fprintf(w, "fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,10 +204,8 @@ var (
|
|||||||
state State
|
state State
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main(cmd *cobra.Command, args []string) {
|
||||||
flag.Parse()
|
if service == "" {
|
||||||
|
|
||||||
if *service == "" {
|
|
||||||
log.Fatal("Must provide -service flag.")
|
log.Fatal("Must provide -service flag.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,13 +214,13 @@ func main() {
|
|||||||
log.Fatalf("Error getting hostname: %v", err)
|
log.Fatalf("Error getting hostname: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *delayShutdown > 0 {
|
if delayShutdown > 0 {
|
||||||
termCh := make(chan os.Signal)
|
termCh := make(chan os.Signal)
|
||||||
signal.Notify(termCh, syscall.SIGTERM)
|
signal.Notify(termCh, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
<-termCh
|
<-termCh
|
||||||
log.Printf("Sleeping %d seconds before exit ...", *delayShutdown)
|
log.Printf("Sleeping %d seconds before exit ...", delayShutdown)
|
||||||
time.Sleep(time.Duration(*delayShutdown) * time.Second)
|
time.Sleep(time.Duration(delayShutdown) * time.Second)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -211,7 +240,7 @@ func main() {
|
|||||||
http.HandleFunc("/write", state.serveWrite)
|
http.HandleFunc("/write", state.serveWrite)
|
||||||
http.HandleFunc("/status", state.serveStatus)
|
http.HandleFunc("/status", state.serveStatus)
|
||||||
|
|
||||||
go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
|
go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
||||||
|
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
@ -226,14 +255,14 @@ func contactOthers(state *State) {
|
|||||||
// In large cluster getting all endpoints is pretty expensive.
|
// In large cluster getting all endpoints is pretty expensive.
|
||||||
// Thus, we will limit ourselves to send on average at most 10 such
|
// Thus, we will limit ourselves to send on average at most 10 such
|
||||||
// requests per second
|
// requests per second
|
||||||
if sleepTime < time.Duration(*peerCount/10)*time.Second {
|
if sleepTime < time.Duration(peerCount/10)*time.Second {
|
||||||
sleepTime = time.Duration(*peerCount/10) * time.Second
|
sleepTime = time.Duration(peerCount/10) * time.Second
|
||||||
}
|
}
|
||||||
timeout := 5 * time.Minute
|
timeout := 5 * time.Minute
|
||||||
// Similarly we need to bump timeout so that it is reasonable in large
|
// Similarly we need to bump timeout so that it is reasonable in large
|
||||||
// clusters.
|
// clusters.
|
||||||
if timeout < time.Duration(*peerCount)*time.Second {
|
if timeout < time.Duration(peerCount)*time.Second {
|
||||||
timeout = time.Duration(*peerCount) * time.Second
|
timeout = time.Duration(peerCount) * time.Second
|
||||||
}
|
}
|
||||||
defer state.doneContactingPeers()
|
defer state.doneContactingPeers()
|
||||||
|
|
||||||
@ -266,10 +295,10 @@ func contactOthers(state *State) {
|
|||||||
|
|
||||||
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepTime) {
|
for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepTime) {
|
||||||
eps := getWebserverEndpoints(client)
|
eps := getWebserverEndpoints(client)
|
||||||
if eps.Len() >= *peerCount {
|
if eps.Len() >= peerCount {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
state.Logf("%v/%v has %v endpoints (%v), which is less than %v as expected. Waiting for all endpoints to come up.", *namespace, *service, len(eps), eps.List(), *peerCount)
|
state.Logf("%v/%v has %v endpoints (%v), which is less than %v as expected. Waiting for all endpoints to come up.", namespace, service, len(eps), eps.List(), peerCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do this repeatedly, in case there's some propagation delay with getting
|
// Do this repeatedly, in case there's some propagation delay with getting
|
||||||
@ -286,10 +315,10 @@ func contactOthers(state *State) {
|
|||||||
|
|
||||||
//getWebserverEndpoints returns the webserver endpoints as a set of String, each in the format like "http://{ip}:{port}"
|
//getWebserverEndpoints returns the webserver endpoints as a set of String, each in the format like "http://{ip}:{port}"
|
||||||
func getWebserverEndpoints(client clientset.Interface) sets.String {
|
func getWebserverEndpoints(client clientset.Interface) sets.String {
|
||||||
endpoints, err := client.CoreV1().Endpoints(*namespace).Get(*service, v1.GetOptions{})
|
endpoints, err := client.CoreV1().Endpoints(namespace).Get(service, v1.GetOptions{})
|
||||||
eps := sets.String{}
|
eps := sets.String{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Logf("Unable to read the endpoints for %v/%v: %v.", *namespace, *service, err)
|
state.Logf("Unable to read the endpoints for %v/%v: %v.", namespace, service, err)
|
||||||
return eps
|
return eps
|
||||||
}
|
}
|
||||||
for _, ss := range endpoints.Subsets {
|
for _, ss := range endpoints.Subsets {
|
@ -1,4 +1,4 @@
|
|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
@ -14,8 +14,8 @@ go_library(
|
|||||||
"pods.go",
|
"pods.go",
|
||||||
"scheme.go",
|
"scheme.go",
|
||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/test/images/webhook",
|
importpath = "k8s.io/kubernetes/test/images/agnhost/webhook",
|
||||||
visibility = ["//visibility:private"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/admissionregistration/v1beta1:go_default_library",
|
||||||
@ -25,16 +25,11 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_binary(
|
|
||||||
name = "webhook",
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "package-srcs",
|
name = "package-srcs",
|
||||||
srcs = glob(["**"]),
|
srcs = glob(["**"]),
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/api/admission/v1beta1"
|
"k8s.io/api/admission/v1beta1"
|
@ -14,11 +14,10 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"flag"
|
|
||||||
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
@ -29,14 +28,6 @@ type Config struct {
|
|||||||
KeyFile string
|
KeyFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) addFlags() {
|
|
||||||
flag.StringVar(&c.CertFile, "tls-cert-file", c.CertFile, ""+
|
|
||||||
"File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+
|
|
||||||
"after server cert).")
|
|
||||||
flag.StringVar(&c.KeyFile, "tls-private-key-file", c.KeyFile, ""+
|
|
||||||
"File containing the default x509 private key matching --tls-cert-file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
func configTLS(config Config) *tls.Config {
|
func configTLS(config Config) *tls.Config {
|
||||||
sCert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
|
sCert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
|
||||||
if err != nil {
|
if err != nil {
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/api/admission/v1beta1"
|
"k8s.io/api/admission/v1beta1"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
@ -14,15 +14,16 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/api/admission/v1beta1"
|
"k8s.io/api/admission/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
@ -30,6 +31,29 @@ import (
|
|||||||
// https://github.com/mattbaird/jsonpatch
|
// https://github.com/mattbaird/jsonpatch
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
certFile string
|
||||||
|
keyFile string
|
||||||
|
)
|
||||||
|
|
||||||
|
// CmdWebhook is used by agnhost Cobra.
|
||||||
|
var CmdWebhook = &cobra.Command{
|
||||||
|
Use: "webhook",
|
||||||
|
Short: "Starts a HTTP server, useful for testing MutatingAdmissionWebhook and ValidatingAdmissionWebhook",
|
||||||
|
Long: `Starts a HTTP server, useful for testing MutatingAdmissionWebhook and ValidatingAdmissionWebhook.
|
||||||
|
After deploying it to Kubernetes cluster, the Administrator needs to create a ValidatingWebhookConfiguration
|
||||||
|
in the Kubernetes cluster to register remote webhook admission controllers.`,
|
||||||
|
Args: cobra.MaximumNArgs(0),
|
||||||
|
Run: main,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
CmdWebhook.Flags().StringVar(&certFile, "tls-cert-file", "",
|
||||||
|
"File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert).")
|
||||||
|
CmdWebhook.Flags().StringVar(&keyFile, "tls-private-key-file", "",
|
||||||
|
"File containing the default x509 private key matching --tls-cert-file.")
|
||||||
|
}
|
||||||
|
|
||||||
// toAdmissionResponse is a helper function to create an AdmissionResponse
|
// toAdmissionResponse is a helper function to create an AdmissionResponse
|
||||||
// with an embedded error
|
// with an embedded error
|
||||||
func toAdmissionResponse(err error) *v1beta1.AdmissionResponse {
|
func toAdmissionResponse(err error) *v1beta1.AdmissionResponse {
|
||||||
@ -135,11 +159,11 @@ func serveCRD(w http.ResponseWriter, r *http.Request) {
|
|||||||
serve(w, r, admitCRD)
|
serve(w, r, admitCRD)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main(cmd *cobra.Command, args []string) {
|
||||||
klog.InitFlags(nil)
|
config := Config{
|
||||||
var config Config
|
CertFile: certFile,
|
||||||
config.addFlags()
|
KeyFile: keyFile,
|
||||||
flag.Parse()
|
}
|
||||||
|
|
||||||
http.HandleFunc("/always-allow-delay-5s", serveAlwaysAllowDelayFiveSeconds)
|
http.HandleFunc("/always-allow-delay-5s", serveAlwaysAllowDelayFiveSeconds)
|
||||||
http.HandleFunc("/always-deny", serveAlwaysDeny)
|
http.HandleFunc("/always-deny", serveAlwaysDeny)
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
1
test/images/net/.gitignore
vendored
1
test/images/net/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/net
|
|
@ -1,5 +0,0 @@
|
|||||||
amd64=alpine:3.6
|
|
||||||
arm=arm32v6/alpine:3.6
|
|
||||||
arm64=arm64v8/alpine:3.6
|
|
||||||
ppc64le=ppc64le/alpine:3.6
|
|
||||||
s390x=s390x/alpine:3.6
|
|
@ -1,20 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
FROM BASEIMAGE
|
|
||||||
|
|
||||||
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
|
|
||||||
|
|
||||||
COPY net /net
|
|
||||||
RUN apk update && apk add curl
|
|
@ -1,25 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
SRCS=net
|
|
||||||
ARCH ?= amd64
|
|
||||||
TARGET ?= $(CURDIR)
|
|
||||||
GOLANG_VERSION ?= latest
|
|
||||||
SRC_DIR = $(notdir $(shell pwd))
|
|
||||||
export
|
|
||||||
|
|
||||||
bin:
|
|
||||||
../image-util.sh bin $(SRCS)
|
|
||||||
|
|
||||||
.PHONY: bin
|
|
@ -1,36 +0,0 @@
|
|||||||
# Overview
|
|
||||||
|
|
||||||
The goal of this Go project is to consolidate all low-level
|
|
||||||
network testing "daemons" into one place. In network testing we
|
|
||||||
frequently have need of simple daemons (common/Runner) that perform
|
|
||||||
some "trivial" set of actions on a socket.
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
* A package for each general area that is being tested, for example
|
|
||||||
`nat/` will contain Runners that test various NAT features.
|
|
||||||
* Every runner should be registered via `main.go:makeRunnerMap()`.
|
|
||||||
* Runners receive a JSON options structure as to their configuration. `Run()`
|
|
||||||
should return the disposition of the test.
|
|
||||||
|
|
||||||
Runners can be executed into two different ways, either through the
|
|
||||||
command-line or via an HTTP request:
|
|
||||||
|
|
||||||
## Command-line
|
|
||||||
|
|
||||||
````
|
|
||||||
$ ./net -runner <runner> -options <json>
|
|
||||||
./net \
|
|
||||||
-runner nat-closewait-client \
|
|
||||||
-options '{"RemoteAddr":"127.0.0.1:9999"}'
|
|
||||||
````
|
|
||||||
|
|
||||||
## HTTP server
|
|
||||||
````
|
|
||||||
$ ./net --serve :8889
|
|
||||||
$ curl -v -X POST localhost:8889/run/nat-closewait-server \
|
|
||||||
-d '{"LocalAddr":"127.0.0.1:9999"}'
|
|
||||||
````
|
|
||||||
|
|
||||||
|
|
||||||
[]()
|
|
@ -1 +0,0 @@
|
|||||||
1.0
|
|
1
test/images/netexec/.gitignore
vendored
1
test/images/netexec/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
netexec
|
|
@ -1,5 +0,0 @@
|
|||||||
amd64=busybox
|
|
||||||
arm=arm32v6/busybox
|
|
||||||
arm64=arm64v8/busybox
|
|
||||||
ppc64le=ppc64le/busybox
|
|
||||||
s390x=s390x/busybox
|
|
@ -1,25 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
FROM BASEIMAGE
|
|
||||||
|
|
||||||
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/
|
|
||||||
|
|
||||||
ADD netexec netexec
|
|
||||||
EXPOSE 8080
|
|
||||||
EXPOSE 8081
|
|
||||||
|
|
||||||
RUN mkdir /uploads
|
|
||||||
|
|
||||||
ENTRYPOINT ["/netexec"]
|
|
@ -1,25 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
SRCS=netexec
|
|
||||||
ARCH ?= amd64
|
|
||||||
TARGET ?= $(CURDIR)
|
|
||||||
GOLANG_VERSION ?= latest
|
|
||||||
SRC_DIR = $(notdir $(shell pwd))
|
|
||||||
export
|
|
||||||
|
|
||||||
bin:
|
|
||||||
../image-util.sh bin $(SRCS)
|
|
||||||
|
|
||||||
.PHONY: bin
|
|
@ -1 +0,0 @@
|
|||||||
1.1
|
|
@ -1,39 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: netexec
|
|
||||||
labels:
|
|
||||||
app: netexec
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: netexec
|
|
||||||
image: gcr.io/kubernetes-e2e-test-images/netexec-amd64:1.1
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
protocol: TCP
|
|
||||||
- containerPort: 8081
|
|
||||||
protocol: UDP
|
|
||||||
# give this pod the same liveness and readiness probe because
|
|
||||||
# we always want the kubelet to restart it if it becomes
|
|
||||||
# unready, and at the same time we want to observe readiness
|
|
||||||
# as a signal to start testing.
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 10
|
|
||||||
timeoutSeconds: 5
|
|
||||||
failureThreshold: 3
|
|
||||||
periodSeconds: 10
|
|
||||||
successThreshold: 1
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: 8080
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 10
|
|
||||||
timeoutSeconds: 5
|
|
||||||
failureThreshold: 3
|
|
||||||
periodSeconds: 10
|
|
||||||
successThreshold: 1
|
|
@ -1,18 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
FROM gcr.io/distroless/static:latest
|
|
||||||
COPY nettest /
|
|
||||||
EXPOSE 8080
|
|
||||||
ENTRYPOINT ["/nettest"]
|
|
@ -1,25 +0,0 @@
|
|||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
SRCS=nettest
|
|
||||||
ARCH ?= amd64
|
|
||||||
TARGET ?= $(CURDIR)
|
|
||||||
GOLANG_VERSION ?= latest
|
|
||||||
SRC_DIR = $(notdir $(shell pwd))
|
|
||||||
export
|
|
||||||
|
|
||||||
bin:
|
|
||||||
../image-util.sh bin $(SRCS)
|
|
||||||
|
|
||||||
.PHONY: bin
|
|
@ -1 +0,0 @@
|
|||||||
1.1
|
|
@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"kind": "ReplicationController",
|
|
||||||
"apiVersion": "v1",
|
|
||||||
"metadata": {
|
|
||||||
"name": "nettest-controller",
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"replicas": 2,
|
|
||||||
"selector": {
|
|
||||||
"name": "nettest"
|
|
||||||
},
|
|
||||||
"template": {
|
|
||||||
"metadata": {
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"containers": [
|
|
||||||
{
|
|
||||||
"name": "webserver",
|
|
||||||
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
|
|
||||||
"imagePullPolicy": "Always",
|
|
||||||
"args": [
|
|
||||||
"-service=nettest",
|
|
||||||
"-port=8080",
|
|
||||||
"-namespace=default",
|
|
||||||
"-peers=2"
|
|
||||||
],
|
|
||||||
"ports": [
|
|
||||||
{
|
|
||||||
"containerPort": 8080,
|
|
||||||
"protocol": "TCP"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"kind": "Service",
|
|
||||||
"apiVersion": "v1",
|
|
||||||
"metadata": {
|
|
||||||
"name": "nettest",
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"ports": [
|
|
||||||
{
|
|
||||||
"port": 8080,
|
|
||||||
"protocol": "TCP",
|
|
||||||
"targetPort": 8080
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"selector": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"kind": "Pod",
|
|
||||||
"apiVersion": "v1",
|
|
||||||
"metadata": {
|
|
||||||
"name": "slow-pod",
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"containers": [
|
|
||||||
{
|
|
||||||
"name": "webserver",
|
|
||||||
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
|
|
||||||
"args": [
|
|
||||||
"-service=nettest",
|
|
||||||
"-delay-shutdown=10"
|
|
||||||
],
|
|
||||||
"ports": [
|
|
||||||
{
|
|
||||||
"containerPort": 8080,
|
|
||||||
"protocol": "TCP"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"kind": "ReplicationController",
|
|
||||||
"apiVersion": "v1",
|
|
||||||
"metadata": {
|
|
||||||
"name": "slow-rc",
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"replicas": 8,
|
|
||||||
"selector": {
|
|
||||||
"name": "nettest"
|
|
||||||
},
|
|
||||||
"template": {
|
|
||||||
"metadata": {
|
|
||||||
"labels": {
|
|
||||||
"name": "nettest"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spec": {
|
|
||||||
"terminationGracePeriodSeconds": 5,
|
|
||||||
"containers": [
|
|
||||||
{
|
|
||||||
"name": "webserver",
|
|
||||||
"image": "gcr.io/kubernetes-e2e-test-images/nettest-amd64:1.0",
|
|
||||||
"args": [
|
|
||||||
"-service=nettest",
|
|
||||||
"-delay-shutdown=10"
|
|
||||||
],
|
|
||||||
"ports": [
|
|
||||||
{
|
|
||||||
"containerPort": 8080,
|
|
||||||
"protocol": "TCP"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
amd64=alpine:3.6
|
|
||||||
arm=arm32v6/alpine:3.6
|
|
||||||
arm64=arm64v8/alpine:3.6
|
|
||||||
ppc64le=ppc64le/alpine:3.6
|
|
@ -1,18 +0,0 @@
|
|||||||
# Copyright 2017 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.
|
|
||||||
|
|
||||||
FROM BASEIMAGE
|
|
||||||
|
|
||||||
ADD webhook /webhook
|
|
||||||
ENTRYPOINT ["/webhook"]
|
|
@ -1,25 +0,0 @@
|
|||||||
# Copyright 2017 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.
|
|
||||||
|
|
||||||
SRCS=webhook
|
|
||||||
ARCH ?= amd64
|
|
||||||
TARGET ?= $(CURDIR)
|
|
||||||
GOLANG_VERSION ?= latest
|
|
||||||
SRC_DIR = $(notdir $(shell pwd))
|
|
||||||
export
|
|
||||||
|
|
||||||
bin:
|
|
||||||
../image-util.sh bin $(SRCS)
|
|
||||||
|
|
||||||
.PHONY: bin
|
|
@ -1,13 +0,0 @@
|
|||||||
# Kubernetes External Admission Webhook Test Image
|
|
||||||
|
|
||||||
The image tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying
|
|
||||||
it to kubernetes cluster, administrator needs to create a ValidatingWebhookConfiguration
|
|
||||||
in kubernetes cluster to register remote webhook admission controllers.
|
|
||||||
|
|
||||||
TODO: add the reference when the document for admission webhook v1beta1 API is done.
|
|
||||||
|
|
||||||
## Build the code
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make build
|
|
||||||
```
|
|
@ -1 +0,0 @@
|
|||||||
1.15v1
|
|
Loading…
Reference in New Issue
Block a user