From 725d2b6a8fd7733afcbc6822723f4c7e171bcd7f Mon Sep 17 00:00:00 2001 From: Jefftree Date: Mon, 13 Jan 2020 21:23:39 -0800 Subject: [PATCH 1/4] Network Proxy: GRPC + HTTP Connect with UDS --- .../addons/konnectivity-agent/daemonset.yaml | 9 +- cluster/gce/gci/configure-helper.sh | 41 +++--- cluster/gce/gci/configure-kubeapiserver.sh | 9 ++ .../gce/manifests/konnectivity-server.yaml | 25 ++-- cluster/gce/manifests/kube-apiserver.manifest | 4 +- .../apiserver/pkg/apis/apiserver/types.go | 83 ++++++++--- .../pkg/apis/apiserver/v1alpha1/types.go | 73 +++++++--- .../v1alpha1/zz_generated.conversion.go | 126 +++++++++++++--- .../v1alpha1/zz_generated.deepcopy.go | 79 ++++++++-- .../apis/apiserver/zz_generated.deepcopy.go | 79 ++++++++-- .../apiserver/pkg/server/egressselector/BUILD | 2 + .../pkg/server/egressselector/config.go | 136 +++++++++++------- .../pkg/server/egressselector/config_test.go | 65 +++++---- .../server/egressselector/egress_selector.go | 129 ++++++++++++----- .../egressselector/egress_selector_test.go | 24 +--- 15 files changed, 641 insertions(+), 243 deletions(-) diff --git a/cluster/gce/addons/konnectivity-agent/daemonset.yaml b/cluster/gce/addons/konnectivity-agent/daemonset.yaml index ee770cc8683..5ea16d44bef 100644 --- a/cluster/gce/addons/konnectivity-agent/daemonset.yaml +++ b/cluster/gce/addons/konnectivity-agent/daemonset.yaml @@ -28,14 +28,12 @@ spec: hostPath: path: /etc/srv/kubernetes/pki/konnectivity-agent containers: - - image: gcr.io/google-containers/proxy-agent:v0.0.3 + - image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent:v0.0.4 name: konnectivity-agent command: ["/proxy-agent"] args: [ "--logtostderr=true", - "--ca-cert=/etc/srv/kubernetes/pki/konnectivity-agent/ca.crt", - "--agent-cert=/etc/srv/kubernetes/pki/konnectivity-agent/client.crt", - "--agent-key=/etc/srv/kubernetes/pki/konnectivity-agent/client.key", + "--ca-cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", "--proxy-server-host=__APISERVER_IP__", "--proxy-server-port=8132" ] @@ -59,6 +57,3 @@ spec: path: /healthz initialDelaySeconds: 15 timeoutSeconds: 15 - volumeMounts: - - name: pki - mountPath: /etc/srv/kubernetes/pki/konnectivity-agent diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 481eb6b5b9d..d7af6d34f25 100644 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -807,18 +807,16 @@ kind: EgressSelectorConfiguration egressSelections: - name: cluster connection: - type: http-connect - httpConnect: - url: https://127.0.0.1:8131 - caBundle: /etc/srv/kubernetes/pki/konnectivity-server/ca.crt - clientKey: /etc/srv/kubernetes/pki/konnectivity-server/client.key - clientCert: /etc/srv/kubernetes/pki/konnectivity-server/client.crt + proxyProtocol: HTTPConnect + transport: + uds: + udsName: /etc/srv/kubernetes/konnectivity/konnectivity-server.socket - name: master connection: - type: direct + proxyProtocol: Direct - name: etcd connection: - type: direct + proxyProtocol: Direct EOF fi @@ -1645,9 +1643,8 @@ function start-etcd-servers { # Replaces the variables in the konnectivity-server manifest file with the real values, and then # copy the file to the manifest dir -# $1: value for variable "server_port" -# $2: value for variable "agent_port" -# $3: value for bariable "admin_port" +# $1: value for variable "agent_port" +# $2: value for bariable "admin_port" function prepare-konnectivity-server-manifest { local -r temp_file="/tmp/konnectivity-server.yaml" params=() @@ -1655,24 +1652,20 @@ function prepare-konnectivity-server-manifest { params+=("--log-file=/var/log/konnectivity-server.log") params+=("--logtostderr=false") params+=("--log-file-max-size=0") - params+=("--server-ca-cert=${KONNECTIVITY_SERVER_CA_CERT_PATH}") - params+=("--server-cert=${KONNECTIVITY_SERVER_CERT_PATH}") - params+=("--server-key=${KONNECTIVITY_SERVER_KEY_PATH}") - params+=("--cluster-ca-cert=${KONNECTIVITY_AGENT_CA_CERT_PATH}") - params+=("--cluster-cert=${KONNECTIVITY_AGENT_CERT_PATH}") - params+=("--cluster-key=${KONNECTIVITY_AGENT_KEY_PATH}") + params+=("--uds-name=/etc/srv/kubernetes/konnectivity/konnectivity-server.socket") + params+=("--cluster-cert=/etc/srv/kubernetes/pki/apiserver.crt") + params+=("--cluster-key=/etc/srv/kubernetes/pki/apiserver.key") params+=("--mode=http-connect") - params+=("--server-port=$1") - params+=("--agent-port=$2") - params+=("--admin-port=$3") + params+=("--server-port=0") + params+=("--agent-port=$1") + params+=("--admin-port=$2") konnectivity_args="" for param in "${params[@]}"; do konnectivity_args+=", \"${param}\"" done sed -i -e "s@{{ *konnectivity_args *}}@${konnectivity_args}@g" "${temp_file}" - sed -i -e "s@{{ *server_port *}}@$1@g" "${temp_file}" - sed -i -e "s@{{ *agent_port *}}@$2@g" "${temp_file}" - sed -i -e "s@{{ *admin_port *}}@$3@g" "${temp_file}" + sed -i -e "s@{{ *agent_port *}}@$1@g" "${temp_file}" + sed -i -e "s@{{ *admin_port *}}@$2@g" "${temp_file}" sed -i -e "s@{{ *liveness_probe_initial_delay *}}@30@g" "${temp_file}" mv "${temp_file}" /etc/kubernetes/manifests } @@ -1683,7 +1676,7 @@ function prepare-konnectivity-server-manifest { function start-konnectivity-server { echo "Start konnectivity server pods" prepare-log-file /var/log/konnectivity-server.log - prepare-konnectivity-server-manifest "8131" "8132" "8133" + prepare-konnectivity-server-manifest "8132" "8133" } # Calculates the following variables based on env variables, which will be used diff --git a/cluster/gce/gci/configure-kubeapiserver.sh b/cluster/gce/gci/configure-kubeapiserver.sh index 44a0dcc3502..0e787c43cc8 100644 --- a/cluster/gce/gci/configure-kubeapiserver.sh +++ b/cluster/gce/gci/configure-kubeapiserver.sh @@ -324,11 +324,18 @@ function start-kube-apiserver { local csc_config_mount="" local csc_config_volume="" + local default_konnectivity_socket_vol="" + local default_konnectivity_socket_mnt="" if [[ "${ENABLE_EGRESS_VIA_KONNECTIVITY_SERVICE:-false}" == "true" ]]; then # Create the EgressSelectorConfiguration yaml file to control the Egress Selector. csc_config_mount="{\"name\": \"cscconfigmount\",\"mountPath\": \"/etc/srv/kubernetes/egress_selector_configuration.yaml\", \"readOnly\": false}," csc_config_volume="{\"name\": \"cscconfigmount\",\"hostPath\": {\"path\": \"/etc/srv/kubernetes/egress_selector_configuration.yaml\", \"type\": \"FileOrCreate\"}}," params+=" --egress-selector-config-file=/etc/srv/kubernetes/egress_selector_configuration.yaml" + + # UDS socket for communication between apiserver and konnectivity-server + local default_konnectivity_socket_path="/etc/srv/kubernetes/konnectivity" + default_konnectivity_socket_vol="{ \"name\": \"konnectivity-socket\", \"hostPath\": {\"path\": \"${default_konnectivity_socket_path}\", \"type\": \"DirectoryOrCreate\"}}," + default_konnectivity_socket_mnt="{ \"name\": \"konnectivity-socket\", \"mountPath\": \"${default_konnectivity_socket_path}\", \"readOnly\": false}," fi local container_env="" @@ -377,6 +384,8 @@ function start-kube-apiserver { sed -i -e "s@{{audit_webhook_config_volume}}@${audit_webhook_config_volume}@g" "${src_file}" sed -i -e "s@{{webhook_exec_auth_plugin_mount}}@${webhook_exec_auth_plugin_mount}@g" "${src_file}" sed -i -e "s@{{webhook_exec_auth_plugin_volume}}@${webhook_exec_auth_plugin_volume}@g" "${src_file}" + sed -i -e "s@{{konnectivity_socket_mount}}@${default_konnectivity_socket_mnt}@g" "${src_file}" + sed -i -e "s@{{konnectivity_socket_volume}}@${default_konnectivity_socket_vol}@g" "${src_file}" cp "${src_file}" "${ETC_MANIFESTS:-/etc/kubernetes/manifests}" } diff --git a/cluster/gce/manifests/konnectivity-server.yaml b/cluster/gce/manifests/konnectivity-server.yaml index 26be55cfd3c..6b78653add7 100644 --- a/cluster/gce/manifests/konnectivity-server.yaml +++ b/cluster/gce/manifests/konnectivity-server.yaml @@ -11,7 +11,7 @@ spec: hostNetwork: true containers: - name: konnectivity-server-container - image: gcr.io/google-containers/proxy-server:v0.0.3 + image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-server:v0.0.4 resources: requests: cpu: 25m @@ -25,9 +25,6 @@ spec: initialDelaySeconds: {{ liveness_probe_initial_delay }} timeoutSeconds: 60 ports: - - name: serverport - containerPort: {{ server_port }} - hostPort: {{ server_port }} - name: agentport containerPort: {{ agent_port }} hostPort: {{ agent_port }} @@ -38,21 +35,21 @@ spec: - name: varlogkonnectivityserver mountPath: /var/log/konnectivity-server.log readOnly: false - - name: pkiserver - mountPath: /etc/srv/kubernetes/pki/konnectivity-server - readOnly: true - - name: pkiagent - mountPath: /etc/srv/kubernetes/pki/konnectivity-agent + - name: pki + mountPath: /etc/srv/kubernetes/pki readOnly: true + - name: konnectivity-uds + mountPath: /etc/srv/kubernetes/konnectivity + readOnly: false volumes: - name: varlogkonnectivityserver hostPath: path: /var/log/konnectivity-server.log type: FileOrCreate - - name: pkiserver + - name: pki hostPath: - path: /etc/srv/kubernetes/pki/konnectivity-server - - name: pkiagent + path: /etc/srv/kubernetes/pki + - name: konnectivity-uds hostPath: - path: /etc/srv/kubernetes/pki/konnectivity-agent - + path: /etc/srv/kubernetes/konnectivity + type: DirectoryOrCreate diff --git a/cluster/gce/manifests/kube-apiserver.manifest b/cluster/gce/manifests/kube-apiserver.manifest index 6f126db1b7c..34de7e4016f 100644 --- a/cluster/gce/manifests/kube-apiserver.manifest +++ b/cluster/gce/manifests/kube-apiserver.manifest @@ -66,7 +66,8 @@ {{csc_config_mount}} {{audit_policy_config_mount}} {{audit_webhook_config_mount}} - {{webhook_exec_auth_plugin_mount}} + {{webhook_exec_auth_plugin_mount}} + {{konnectivity_socket_mount}} { "name": "srvkube", "mountPath": "/etc/srv/kubernetes", "readOnly": true}, @@ -108,6 +109,7 @@ {{audit_policy_config_volume}} {{audit_webhook_config_volume}} {{webhook_exec_auth_plugin_volume}} + {{konnectivity_socket_volume}} { "name": "srvkube", "hostPath": { "path": "/etc/srv/kubernetes"} diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go index d21e7d631d7..d6fe4e9931b 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -71,29 +71,80 @@ type EgressSelection struct { // Connection provides the configuration for a single egress selection client. type Connection struct { - // Type is the type of connection used to connect from client to konnectivity server. - // Currently supported values are "http-connect" and "direct". - Type string + // Protocol is the protocol used to connect from client to the konnectivity server. + ProxyProtocol ProtocolType - // httpConnect is the config needed to use http-connect to the konnectivity server. + // Transport defines the transport configurations we use to dial to the konnectivity server + // This is required if ProxyProtocol is HTTPConnect or GRPC // +optional - HTTPConnect *HTTPConnectConfig + Transport *Transport } -type HTTPConnectConfig struct { +// ProtocolType is a set of valid values for Connection.ProtocolType +type ProtocolType string + +// Valid types for ProtocolType for konnectivity server +const ( + // Use HTTPConnect to connect to konnectivity server + ProtocolHTTPConnect ProtocolType = "HTTPConnect" + // Use grpc to connect to konnectivity server + ProtocolGRPC ProtocolType = "GRPC" + // Connect directly (skip konnectivity server) + ProtocolDirect ProtocolType = "Direct" +) + +// Transport defines the transport configurations we use to dial to the konnectivity server +type Transport struct { + // TCP is the TCP configuration for communicating with the konnectivity server via TCP + // Requires at least one of TCP or UDS to be set + // +optional + TCP *TCPTransport + + // UDS is the UDS configuration for communicating with the konnectivity server via UDS + // Requires at least one of TCP or UDS to be set + // +optional + UDS *UDSTransport +} + +// TCPTransport provides the information to connect to konnectivity server via TCP +type TCPTransport struct { // URL is the location of the konnectivity server to connect to. // As an example it might be "https://127.0.0.1:8131" URL string - // CABundle is the file location of the CA to be used to determine trust with the konnectivity server. + // TLSConfig is the config needed to use TLS when connecting to konnectivity server // +optional - CABundle string - - // ClientKey is the file location of the client key to be used in mtls handshakes with the konnectivity server. - // +optional - ClientKey string - - // ClientCert is the file location of the client certificate to be used in mtls handshakes with the konnectivity server. - // +optional - ClientCert string + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` +} + +// UDSTransport provides the information to connect to konnectivity server via UDS +type UDSTransport struct { + // UDSName is the name of the unix domain socket to connect to konnectivity server + // This does not use a unix:// prefix. (Eg: /etc/srv/kubernetes/konnectivity/konnectivity-server.socket) + UDSName string +} + +// TLSConfig provides the authentication information to connect to konnectivity server +// Only used with TCPTransport +type TLSConfig struct { + // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol + // Misconfiguration will cause an error + // +optional + CABundle string `json:"caBundle,omitempty"` + + // clientKey is the file location of the client key to authenticate with the konnectivity server + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol + // Misconfiguration will cause an error + // +optional + ClientKey string `json:"clientKey,omitempty"` + + // clientCert is the file location of the client certificate to authenticate with the konnectivity server + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol + // Misconfiguration will cause an error + // +optional + ClientCert string `json:"clientCert,omitempty"` } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index 10034d7c340..e561017e215 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -71,39 +71,78 @@ type EgressSelection struct { // Connection provides the configuration for a single egress selection client. type Connection struct { - // type is the type of connection used to connect from client to network/konnectivity server. - // Currently supported values are "http-connect" and "direct". - Type string `json:"type"` + // Protocol is the protocol used to connect from client to the konnectivity server. + ProxyProtocol ProtocolType `json:"proxyProtocol,omitempty"` - // httpConnect is the config needed to use http-connect to the konnectivity server. - // Absence when the type is "http-connect" will cause an error - // Presence when the type is "direct" will also cause an error + // Transport defines the transport configurations we use to dial to the konnectivity server + // This is required if ProxyProtocol is HTTPConnect or GRPC // +optional - HTTPConnect *HTTPConnectConfig `json:"httpConnect,omitempty"` + Transport *Transport `json:"transport,omitempty"` } -type HTTPConnectConfig struct { - // url is the location of the proxy server to connect to. - // As an example it might be "https://127.0.0.1:8131" - URL string `json:"url"` +// ProtocolType is a set of valid values for Connection.ProtocolType +type ProtocolType string +// Valid types for ProtocolType for konnectivity server +const ( + // Use HTTPConnect to connect to konnectivity server + ProtocolHTTPConnect ProtocolType = "HTTPConnect" + // Use grpc to connect to konnectivity server + ProtocolGRPC ProtocolType = "GRPC" + // Connect directly (skip konnectivity server) + ProtocolDirect ProtocolType = "Direct" +) + +// Transport defines the transport configurations we use to dial to the konnectivity server +type Transport struct { + // TCP is the TCP configuration for communicating with the konnectivity server via TCP + // Requires at least one of TCP or UDS to be set + // +optional + TCP *TCPTransport `json:"tcp,omitempty"` + + // UDS is the UDS configuration for communicating with the konnectivity server via UDS + // Requires at least one of TCP or UDS to be set + // +optional + UDS *UDSTransport `json:"uds,omitempty"` +} + +// TCPTransport provides the information to connect to konnectivity server via TCP +type TCPTransport struct { + // URL is the location of the konnectivity server to connect to. + // As an example it might be "https://127.0.0.1:8131" + URL string + + // TLSConfig is the config needed to use TLS when connecting to konnectivity server + // +optional + TLSConfig *TLSConfig +} + +// UDSTransport provides the information to connect to konnectivity server via UDS +type UDSTransport struct { + // UDSName is the name of the unix domain socket to connect to konnectivity server + UDSName string +} + +// TLSConfig provides the authentication information to connect to konnectivity server +// Only used with TCPTransport +type TLSConfig struct { // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. - // Must be absent/empty http-connect using the plain http - // Must be configured for http-connect using the https protocol + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional CABundle string `json:"caBundle,omitempty"` // clientKey is the file location of the client key to be used in mtls handshakes with the konnectivity server. - // Must be absent/empty http-connect using the plain http - // Must be configured for http-connect using the https protocol + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional ClientKey string `json:"clientKey,omitempty"` // clientCert is the file location of the client certificate to be used in mtls handshakes with the konnectivity server. - // Must be absent/empty http-connect using the plain http - // Must be configured for http-connect using the https protocol + // Must be absent/empty HTTPConnect using the plain http + // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional ClientCert string `json:"clientCert,omitempty"` diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go index 80352f02e91..9174b16df70 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go @@ -85,13 +85,43 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*HTTPConnectConfig)(nil), (*apiserver.HTTPConnectConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha1_HTTPConnectConfig_To_apiserver_HTTPConnectConfig(a.(*HTTPConnectConfig), b.(*apiserver.HTTPConnectConfig), scope) + if err := s.AddGeneratedConversionFunc((*TCPTransport)(nil), (*apiserver.TCPTransport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_TCPTransport_To_apiserver_TCPTransport(a.(*TCPTransport), b.(*apiserver.TCPTransport), scope) }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*apiserver.HTTPConnectConfig)(nil), (*HTTPConnectConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_apiserver_HTTPConnectConfig_To_v1alpha1_HTTPConnectConfig(a.(*apiserver.HTTPConnectConfig), b.(*HTTPConnectConfig), scope) + if err := s.AddGeneratedConversionFunc((*apiserver.TCPTransport)(nil), (*TCPTransport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_TCPTransport_To_v1alpha1_TCPTransport(a.(*apiserver.TCPTransport), b.(*TCPTransport), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*TLSConfig)(nil), (*apiserver.TLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_TLSConfig_To_apiserver_TLSConfig(a.(*TLSConfig), b.(*apiserver.TLSConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiserver.TLSConfig)(nil), (*TLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(a.(*apiserver.TLSConfig), b.(*TLSConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Transport)(nil), (*apiserver.Transport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Transport_To_apiserver_Transport(a.(*Transport), b.(*apiserver.Transport), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiserver.Transport)(nil), (*Transport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_Transport_To_v1alpha1_Transport(a.(*apiserver.Transport), b.(*Transport), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*UDSTransport)(nil), (*apiserver.UDSTransport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_UDSTransport_To_apiserver_UDSTransport(a.(*UDSTransport), b.(*apiserver.UDSTransport), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiserver.UDSTransport)(nil), (*UDSTransport)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_UDSTransport_To_v1alpha1_UDSTransport(a.(*apiserver.UDSTransport), b.(*UDSTransport), scope) }); err != nil { return err } @@ -143,8 +173,8 @@ func Convert_apiserver_AdmissionPluginConfiguration_To_v1alpha1_AdmissionPluginC } func autoConvert_v1alpha1_Connection_To_apiserver_Connection(in *Connection, out *apiserver.Connection, s conversion.Scope) error { - out.Type = in.Type - out.HTTPConnect = (*apiserver.HTTPConnectConfig)(unsafe.Pointer(in.HTTPConnect)) + out.ProxyProtocol = apiserver.ProtocolType(in.ProxyProtocol) + out.Transport = (*apiserver.Transport)(unsafe.Pointer(in.Transport)) return nil } @@ -154,8 +184,8 @@ func Convert_v1alpha1_Connection_To_apiserver_Connection(in *Connection, out *ap } func autoConvert_apiserver_Connection_To_v1alpha1_Connection(in *apiserver.Connection, out *Connection, s conversion.Scope) error { - out.Type = in.Type - out.HTTPConnect = (*HTTPConnectConfig)(unsafe.Pointer(in.HTTPConnect)) + out.ProxyProtocol = ProtocolType(in.ProxyProtocol) + out.Transport = (*Transport)(unsafe.Pointer(in.Transport)) return nil } @@ -210,28 +240,90 @@ func Convert_apiserver_EgressSelectorConfiguration_To_v1alpha1_EgressSelectorCon return autoConvert_apiserver_EgressSelectorConfiguration_To_v1alpha1_EgressSelectorConfiguration(in, out, s) } -func autoConvert_v1alpha1_HTTPConnectConfig_To_apiserver_HTTPConnectConfig(in *HTTPConnectConfig, out *apiserver.HTTPConnectConfig, s conversion.Scope) error { +func autoConvert_v1alpha1_TCPTransport_To_apiserver_TCPTransport(in *TCPTransport, out *apiserver.TCPTransport, s conversion.Scope) error { out.URL = in.URL + out.TLSConfig = (*apiserver.TLSConfig)(unsafe.Pointer(in.TLSConfig)) + return nil +} + +// Convert_v1alpha1_TCPTransport_To_apiserver_TCPTransport is an autogenerated conversion function. +func Convert_v1alpha1_TCPTransport_To_apiserver_TCPTransport(in *TCPTransport, out *apiserver.TCPTransport, s conversion.Scope) error { + return autoConvert_v1alpha1_TCPTransport_To_apiserver_TCPTransport(in, out, s) +} + +func autoConvert_apiserver_TCPTransport_To_v1alpha1_TCPTransport(in *apiserver.TCPTransport, out *TCPTransport, s conversion.Scope) error { + out.URL = in.URL + out.TLSConfig = (*TLSConfig)(unsafe.Pointer(in.TLSConfig)) + return nil +} + +// Convert_apiserver_TCPTransport_To_v1alpha1_TCPTransport is an autogenerated conversion function. +func Convert_apiserver_TCPTransport_To_v1alpha1_TCPTransport(in *apiserver.TCPTransport, out *TCPTransport, s conversion.Scope) error { + return autoConvert_apiserver_TCPTransport_To_v1alpha1_TCPTransport(in, out, s) +} + +func autoConvert_v1alpha1_TLSConfig_To_apiserver_TLSConfig(in *TLSConfig, out *apiserver.TLSConfig, s conversion.Scope) error { out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert return nil } -// Convert_v1alpha1_HTTPConnectConfig_To_apiserver_HTTPConnectConfig is an autogenerated conversion function. -func Convert_v1alpha1_HTTPConnectConfig_To_apiserver_HTTPConnectConfig(in *HTTPConnectConfig, out *apiserver.HTTPConnectConfig, s conversion.Scope) error { - return autoConvert_v1alpha1_HTTPConnectConfig_To_apiserver_HTTPConnectConfig(in, out, s) +// Convert_v1alpha1_TLSConfig_To_apiserver_TLSConfig is an autogenerated conversion function. +func Convert_v1alpha1_TLSConfig_To_apiserver_TLSConfig(in *TLSConfig, out *apiserver.TLSConfig, s conversion.Scope) error { + return autoConvert_v1alpha1_TLSConfig_To_apiserver_TLSConfig(in, out, s) } -func autoConvert_apiserver_HTTPConnectConfig_To_v1alpha1_HTTPConnectConfig(in *apiserver.HTTPConnectConfig, out *HTTPConnectConfig, s conversion.Scope) error { - out.URL = in.URL +func autoConvert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in *apiserver.TLSConfig, out *TLSConfig, s conversion.Scope) error { out.CABundle = in.CABundle out.ClientKey = in.ClientKey out.ClientCert = in.ClientCert return nil } -// Convert_apiserver_HTTPConnectConfig_To_v1alpha1_HTTPConnectConfig is an autogenerated conversion function. -func Convert_apiserver_HTTPConnectConfig_To_v1alpha1_HTTPConnectConfig(in *apiserver.HTTPConnectConfig, out *HTTPConnectConfig, s conversion.Scope) error { - return autoConvert_apiserver_HTTPConnectConfig_To_v1alpha1_HTTPConnectConfig(in, out, s) +// Convert_apiserver_TLSConfig_To_v1alpha1_TLSConfig is an autogenerated conversion function. +func Convert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in *apiserver.TLSConfig, out *TLSConfig, s conversion.Scope) error { + return autoConvert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in, out, s) +} + +func autoConvert_v1alpha1_Transport_To_apiserver_Transport(in *Transport, out *apiserver.Transport, s conversion.Scope) error { + out.TCP = (*apiserver.TCPTransport)(unsafe.Pointer(in.TCP)) + out.UDS = (*apiserver.UDSTransport)(unsafe.Pointer(in.UDS)) + return nil +} + +// Convert_v1alpha1_Transport_To_apiserver_Transport is an autogenerated conversion function. +func Convert_v1alpha1_Transport_To_apiserver_Transport(in *Transport, out *apiserver.Transport, s conversion.Scope) error { + return autoConvert_v1alpha1_Transport_To_apiserver_Transport(in, out, s) +} + +func autoConvert_apiserver_Transport_To_v1alpha1_Transport(in *apiserver.Transport, out *Transport, s conversion.Scope) error { + out.TCP = (*TCPTransport)(unsafe.Pointer(in.TCP)) + out.UDS = (*UDSTransport)(unsafe.Pointer(in.UDS)) + return nil +} + +// Convert_apiserver_Transport_To_v1alpha1_Transport is an autogenerated conversion function. +func Convert_apiserver_Transport_To_v1alpha1_Transport(in *apiserver.Transport, out *Transport, s conversion.Scope) error { + return autoConvert_apiserver_Transport_To_v1alpha1_Transport(in, out, s) +} + +func autoConvert_v1alpha1_UDSTransport_To_apiserver_UDSTransport(in *UDSTransport, out *apiserver.UDSTransport, s conversion.Scope) error { + out.UDSName = in.UDSName + return nil +} + +// Convert_v1alpha1_UDSTransport_To_apiserver_UDSTransport is an autogenerated conversion function. +func Convert_v1alpha1_UDSTransport_To_apiserver_UDSTransport(in *UDSTransport, out *apiserver.UDSTransport, s conversion.Scope) error { + return autoConvert_v1alpha1_UDSTransport_To_apiserver_UDSTransport(in, out, s) +} + +func autoConvert_apiserver_UDSTransport_To_v1alpha1_UDSTransport(in *apiserver.UDSTransport, out *UDSTransport, s conversion.Scope) error { + out.UDSName = in.UDSName + return nil +} + +// Convert_apiserver_UDSTransport_To_v1alpha1_UDSTransport is an autogenerated conversion function. +func Convert_apiserver_UDSTransport_To_v1alpha1_UDSTransport(in *apiserver.UDSTransport, out *UDSTransport, s conversion.Scope) error { + return autoConvert_apiserver_UDSTransport_To_v1alpha1_UDSTransport(in, out, s) } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go index e8d6086798b..4498e408f0b 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go @@ -80,10 +80,10 @@ func (in *AdmissionPluginConfiguration) DeepCopy() *AdmissionPluginConfiguration // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Connection) DeepCopyInto(out *Connection) { *out = *in - if in.HTTPConnect != nil { - in, out := &in.HTTPConnect, &out.HTTPConnect - *out = new(HTTPConnectConfig) - **out = **in + if in.Transport != nil { + in, out := &in.Transport, &out.Transport + *out = new(Transport) + (*in).DeepCopyInto(*out) } return } @@ -148,17 +148,80 @@ func (in *EgressSelectorConfiguration) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HTTPConnectConfig) DeepCopyInto(out *HTTPConnectConfig) { +func (in *TCPTransport) DeepCopyInto(out *TCPTransport) { + *out = *in + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPTransport. +func (in *TCPTransport) DeepCopy() *TCPTransport { + if in == nil { + return nil + } + out := new(TCPTransport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPConnectConfig. -func (in *HTTPConnectConfig) DeepCopy() *HTTPConnectConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. +func (in *TLSConfig) DeepCopy() *TLSConfig { if in == nil { return nil } - out := new(HTTPConnectConfig) + out := new(TLSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Transport) DeepCopyInto(out *Transport) { + *out = *in + if in.TCP != nil { + in, out := &in.TCP, &out.TCP + *out = new(TCPTransport) + (*in).DeepCopyInto(*out) + } + if in.UDS != nil { + in, out := &in.UDS, &out.UDS + *out = new(UDSTransport) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Transport. +func (in *Transport) DeepCopy() *Transport { + if in == nil { + return nil + } + out := new(Transport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UDSTransport) DeepCopyInto(out *UDSTransport) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDSTransport. +func (in *UDSTransport) DeepCopy() *UDSTransport { + if in == nil { + return nil + } + out := new(UDSTransport) in.DeepCopyInto(out) return out } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go index 3159f7c1a34..622f1b5dc83 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go @@ -80,10 +80,10 @@ func (in *AdmissionPluginConfiguration) DeepCopy() *AdmissionPluginConfiguration // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Connection) DeepCopyInto(out *Connection) { *out = *in - if in.HTTPConnect != nil { - in, out := &in.HTTPConnect, &out.HTTPConnect - *out = new(HTTPConnectConfig) - **out = **in + if in.Transport != nil { + in, out := &in.Transport, &out.Transport + *out = new(Transport) + (*in).DeepCopyInto(*out) } return } @@ -148,17 +148,80 @@ func (in *EgressSelectorConfiguration) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HTTPConnectConfig) DeepCopyInto(out *HTTPConnectConfig) { +func (in *TCPTransport) DeepCopyInto(out *TCPTransport) { + *out = *in + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPTransport. +func (in *TCPTransport) DeepCopy() *TCPTransport { + if in == nil { + return nil + } + out := new(TCPTransport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPConnectConfig. -func (in *HTTPConnectConfig) DeepCopy() *HTTPConnectConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. +func (in *TLSConfig) DeepCopy() *TLSConfig { if in == nil { return nil } - out := new(HTTPConnectConfig) + out := new(TLSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Transport) DeepCopyInto(out *Transport) { + *out = *in + if in.TCP != nil { + in, out := &in.TCP, &out.TCP + *out = new(TCPTransport) + (*in).DeepCopyInto(*out) + } + if in.UDS != nil { + in, out := &in.UDS, &out.UDS + *out = new(UDSTransport) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Transport. +func (in *Transport) DeepCopy() *Transport { + if in == nil { + return nil + } + out := new(Transport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UDSTransport) DeepCopyInto(out *UDSTransport) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDSTransport. +func (in *UDSTransport) DeepCopy() *UDSTransport { + if in == nil { + return nil + } + out := new(UDSTransport) in.DeepCopyInto(out) return out } diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD index 7c0e2faad7d..beb7899b0df 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD @@ -16,8 +16,10 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/apis/apiserver:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/apiserver/install:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1:go_default_library", + "//vendor/google.golang.org/grpc:go_default_library", "//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/utils/path:go_default_library", + "//vendor/sigs.k8s.io/apiserver-network-proxy/pkg/agent/client:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go index 8cbbb3b014e..2cf06a4e0da 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go @@ -79,16 +79,38 @@ func ValidateEgressSelectorConfiguration(config *apiserver.EgressSelectorConfigu } for _, service := range config.EgressSelections { base := field.NewPath("service", "connection") - switch service.Connection.Type { - case "direct": + switch service.Connection.ProxyProtocol { + case apiserver.ProtocolDirect: allErrs = append(allErrs, validateDirectConnection(service.Connection, base)...) - case "http-connect": - allErrs = append(allErrs, validateHTTPConnection(service.Connection, base)...) + case apiserver.ProtocolHTTPConnect: + if service.Connection.Transport.TCP != nil && service.Connection.Transport.UDS != nil { + allErrs = append(allErrs, field.Invalid( + base.Child("tcp"), + service.Connection.Transport.TCP, + "TCP and UDS cannot both be set")) + } else if service.Connection.Transport.TCP == nil && service.Connection.Transport.UDS == nil { + allErrs = append(allErrs, field.Required( + base.Child("tcp"), + "One of TCP or UDS must be set")) + } else if service.Connection.Transport.TCP != nil { + allErrs = append(allErrs, validateTCPConnection(service.Connection, base)...) + } else if service.Connection.Transport.UDS != nil { + allErrs = append(allErrs, validateUDSConnection(service.Connection, base)...) + } + case apiserver.ProtocolGRPC: + if service.Connection.Transport.UDS != nil { + allErrs = append(allErrs, validateUDSConnection(service.Connection, base)...) + } else { + allErrs = append(allErrs, field.NotSupported( + base.Child("protocol"), + service.Connection.ProxyProtocol, + []string{"uds"})) + } default: allErrs = append(allErrs, field.NotSupported( - base.Child("type"), - service.Connection.Type, - []string{"direct", "http-connect"})) + base.Child("protocol"), + service.Connection.ProxyProtocol, + []string{"direct", "HTTPConnect", "grpc"})) } } @@ -96,80 +118,92 @@ func ValidateEgressSelectorConfiguration(config *apiserver.EgressSelectorConfigu } func validateDirectConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { - if connection.HTTPConnect != nil { + if connection.Transport != nil { return field.ErrorList{field.Invalid( - fldPath.Child("httpConnect"), + fldPath.Child("transport"), "direct", - "httpConnect config should be absent for direct connect"), + "Transport config should be absent for direct connect"), } } + return nil } -func validateHTTPConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { +func validateUDSConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if connection.HTTPConnect == nil { + if connection.Transport.UDS.UDSName == "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect"), + fldPath.Child("udsName"), "nil", - "httpConnect config should be present for http-connect")) - } else if strings.HasPrefix(connection.HTTPConnect.URL, "https://") { - if connection.HTTPConnect.CABundle == "" { + "UDSName should be present for UDS connections")) + } + return allErrs +} + +func validateTCPConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if connection.Transport.TCP.TLSConfig == nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig"), + "nil", + "TLSConfig config should be present for HTTPConnect via tcp")) + } else if strings.HasPrefix(connection.Transport.TCP.URL, "https://") { + if connection.Transport.TCP.TLSConfig.CABundle == "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "caBundle"), + fldPath.Child("tlsConfig", "caBundle"), "nil", - "http-connect via https requires caBundle")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.HTTPConnect.CABundle); exists == false || err != nil { + "HTTPConnect via https requires caBundle")) + } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.CABundle); exists == false || err != nil { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "caBundle"), - connection.HTTPConnect.CABundle, - "http-connect ca bundle does not exist")) + fldPath.Child("tlsConfig", "caBundle"), + connection.Transport.TCP.TLSConfig.CABundle, + "HTTPConnect ca bundle does not exist")) } - if connection.HTTPConnect.ClientCert == "" { + if connection.Transport.TCP.TLSConfig.ClientCert == "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientCert"), + fldPath.Child("tlsConfig", "clientCert"), "nil", - "http-connect via https requires clientCert")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.HTTPConnect.ClientCert); exists == false || err != nil { + "HTTPConnect via https requires clientCert")) + } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.ClientCert); exists == false || err != nil { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientCert"), - connection.HTTPConnect.ClientCert, - "http-connect client cert does not exist")) + fldPath.Child("tlsConfig", "clientCert"), + connection.Transport.TCP.TLSConfig.ClientCert, + "HTTPConnect client cert does not exist")) } - if connection.HTTPConnect.ClientKey == "" { + if connection.Transport.TCP.TLSConfig.ClientKey == "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientKey"), + fldPath.Child("tlsConfig", "clientKey"), "nil", - "http-connect via https requires clientKey")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.HTTPConnect.ClientKey); exists == false || err != nil { + "HTTPConnect via https requires clientKey")) + } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.ClientKey); exists == false || err != nil { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientKey"), - connection.HTTPConnect.ClientKey, - "http-connect client key does not exist")) + fldPath.Child("tlsConfig", "clientKey"), + connection.Transport.TCP.TLSConfig.ClientKey, + "HTTPConnect client key does not exist")) } - } else if strings.HasPrefix(connection.HTTPConnect.URL, "http://") { - if connection.HTTPConnect.CABundle != "" { + } else if strings.HasPrefix(connection.Transport.TCP.URL, "http://") { + if connection.Transport.TCP.TLSConfig.CABundle != "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "caBundle"), - connection.HTTPConnect.CABundle, - "http-connect via http does not support caBundle")) + fldPath.Child("tlsConfig", "caBundle"), + connection.Transport.TCP.TLSConfig.CABundle, + "HTTPConnect via http does not support caBundle")) } - if connection.HTTPConnect.ClientCert != "" { + if connection.Transport.TCP.TLSConfig.ClientCert != "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientCert"), - connection.HTTPConnect.ClientCert, - "http-connect via http does not support clientCert")) + fldPath.Child("tlsConfig", "clientCert"), + connection.Transport.TCP.TLSConfig.ClientCert, + "HTTPConnect via http does not support clientCert")) } - if connection.HTTPConnect.ClientKey != "" { + if connection.Transport.TCP.TLSConfig.ClientKey != "" { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "clientKey"), - connection.HTTPConnect.ClientKey, - "http-connect via http does not support clientKey")) + fldPath.Child("tlsConfig", "clientKey"), + connection.Transport.TCP.TLSConfig.ClientKey, + "HTTPConnect via http does not support clientKey")) } } else { allErrs = append(allErrs, field.Invalid( - fldPath.Child("httpConnect", "url"), - connection.HTTPConnect.URL, + fldPath.Child("url"), + connection.Transport.TCP.URL, "supported connection protocols are http:// and https://")) } return allErrs diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go index a524ebffae5..0f36bffbd8b 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go @@ -62,23 +62,27 @@ kind: EgressSelectorConfiguration egressSelections: - name: "cluster" connection: - type: "http-connect" - httpConnect: - url: "https://127.0.0.1:8131" - caBundle: "/etc/srv/kubernetes/pki/konnectivity-server/ca.crt" - clientKey: "/etc/srv/kubernetes/pki/konnectivity-server/client.key" - clientCert: "/etc/srv/kubernetes/pki/konnectivity-server/client.crt" + proxyProtocol: "HTTPConnect" + transport: + tcp: + url: "https://127.0.0.1:8131" + tlsConfig: + caBundle: "/etc/srv/kubernetes/pki/konnectivity-server/ca.crt" + clientKey: "/etc/srv/kubernetes/pki/konnectivity-server/client.key" + clientCert: "/etc/srv/kubernetes/pki/konnectivity-server/client.crt" - name: "master" connection: - type: "http-connect" - httpConnect: - url: "https://127.0.0.1:8132" - caBundle: "/etc/srv/kubernetes/pki/konnectivity-server-master/ca.crt" - clientKey: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.key" - clientCert: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.crt" + proxyProtocol: "HTTPConnect" + transport: + tcp: + url: "https://127.0.0.1:8132" + tlsConfig: + caBundle: "/etc/srv/kubernetes/pki/konnectivity-server-master/ca.crt" + clientKey: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.key" + clientCert: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.crt" - name: "etcd" connection: - type: "direct" + proxyProtocol: "Direct" `, expectedResult: &apiserver.EgressSelectorConfiguration{ TypeMeta: metav1.TypeMeta{ @@ -89,31 +93,40 @@ egressSelections: { Name: "cluster", Connection: apiserver.Connection{ - Type: "http-connect", - HTTPConnect: &apiserver.HTTPConnectConfig{ - URL: "https://127.0.0.1:8131", - CABundle: "/etc/srv/kubernetes/pki/konnectivity-server/ca.crt", - ClientKey: "/etc/srv/kubernetes/pki/konnectivity-server/client.key", - ClientCert: "/etc/srv/kubernetes/pki/konnectivity-server/client.crt", + ProxyProtocol: "HTTPConnect", + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "https://127.0.0.1:8131", + + TLSConfig: &apiserver.TLSConfig{ + CABundle: "/etc/srv/kubernetes/pki/konnectivity-server/ca.crt", + ClientKey: "/etc/srv/kubernetes/pki/konnectivity-server/client.key", + ClientCert: "/etc/srv/kubernetes/pki/konnectivity-server/client.crt", + }, + }, }, }, }, { Name: "master", Connection: apiserver.Connection{ - Type: "http-connect", - HTTPConnect: &apiserver.HTTPConnectConfig{ - URL: "https://127.0.0.1:8132", - CABundle: "/etc/srv/kubernetes/pki/konnectivity-server-master/ca.crt", - ClientKey: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.key", - ClientCert: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.crt", + ProxyProtocol: "HTTPConnect", + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "https://127.0.0.1:8132", + TLSConfig: &apiserver.TLSConfig{ + CABundle: "/etc/srv/kubernetes/pki/konnectivity-server-master/ca.crt", + ClientKey: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.key", + ClientCert: "/etc/srv/kubernetes/pki/konnectivity-server-master/client.crt", + }, + }, }, }, }, { Name: "etcd", Connection: apiserver.Connection{ - Type: "direct", + ProxyProtocol: "Direct", }, }, }, diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index d043e1392cd..919741d78d6 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -22,6 +22,7 @@ import ( "crypto/tls" "crypto/x509" "fmt" + "google.golang.org/grpc" "io/ioutil" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/apis/apiserver" @@ -29,6 +30,7 @@ import ( "net" "net/http" "net/url" + client "sigs.k8s.io/apiserver-network-proxy/pkg/agent/client" "strings" ) @@ -94,13 +96,40 @@ func lookupServiceName(name string) (EgressType, error) { return -1, fmt.Errorf("unrecognized service name %s", name) } -func createConnectDialer(connectConfig *apiserver.HTTPConnectConfig) (utilnet.DialFunc, error) { - clientCert := connectConfig.ClientCert - clientKey := connectConfig.ClientKey - caCert := connectConfig.CABundle - proxyURL, err := url.Parse(connectConfig.URL) +func tunnelHTTPConnect(proxyConn net.Conn, proxyAddress, addr string) (net.Conn, error) { + fmt.Fprintf(proxyConn, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", addr, "127.0.0.1") + br := bufio.NewReader(proxyConn) + res, err := http.ReadResponse(br, nil) if err != nil { - return nil, fmt.Errorf("invalid proxy server url %q: %v", connectConfig.URL, err) + proxyConn.Close() + return nil, fmt.Errorf("reading HTTP response from CONNECT to %s via proxy %s failed: %v", + addr, proxyAddress, err) + } + if res.StatusCode != 200 { + proxyConn.Close() + return nil, fmt.Errorf("proxy error from %s while dialing %s, code %d: %v", + proxyAddress, addr, res.StatusCode, res.Status) + } + + // It's safe to discard the bufio.Reader here and return the + // original TCP conn directly because we only use this for + // TLS, and in TLS the client speaks first, so we know there's + // no unbuffered data. But we can double-check. + if br.Buffered() > 0 { + proxyConn.Close() + return nil, fmt.Errorf("unexpected %d bytes of buffered data from CONNECT proxy %q", + br.Buffered(), proxyAddress) + } + return proxyConn, nil +} + +func createConnectTCPDialer(tcpTransport *apiserver.TCPTransport) (utilnet.DialFunc, error) { + clientCert := tcpTransport.TLSConfig.ClientCert + clientKey := tcpTransport.TLSConfig.ClientKey + caCert := tcpTransport.TLSConfig.CABundle + proxyURL, err := url.Parse(tcpTransport.URL) + if err != nil { + return nil, fmt.Errorf("invalid proxy server url %q: %v", tcpTransport.URL, err) } proxyAddress := proxyURL.Host @@ -128,30 +157,42 @@ func createConnectDialer(connectConfig *apiserver.HTTPConnectConfig) (utilnet.Di if err != nil { return nil, fmt.Errorf("dialing proxy %q failed: %v", proxyAddress, err) } - fmt.Fprintf(proxyConn, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", addr, "127.0.0.1") - br := bufio.NewReader(proxyConn) - res, err := http.ReadResponse(br, nil) + return tunnelHTTPConnect(proxyConn, proxyAddress, addr) + } + return contextDialer, nil +} + +func createConnectUDSDialer(udsName string) (utilnet.DialFunc, error) { + contextDialer := func(ctx context.Context, network, addr string) (net.Conn, error) { + proxyConn, err := net.Dial("unix", udsName) if err != nil { - proxyConn.Close() - return nil, fmt.Errorf("reading HTTP response from CONNECT to %s via proxy %s failed: %v", - addr, proxyAddress, err) + return nil, fmt.Errorf("dialing proxy %q failed: %v", udsName, err) } - if res.StatusCode != 200 { - proxyConn.Close() - return nil, fmt.Errorf("proxy error from %s while dialing %s, code %d: %v", - proxyAddress, addr, res.StatusCode, res.Status) + return tunnelHTTPConnect(proxyConn, udsName, addr) + } + return contextDialer, nil +} + +func createGRPCUDSDialer(udsName string) (utilnet.DialFunc, error) { + contextDialer := func(ctx context.Context, network, addr string) (net.Conn, error) { + + dialOption := grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { + c, err := net.Dial("unix", udsName) + if err != nil { + klog.Errorf("failed to create connection to uds name %s, error: %v", udsName, err) + } + return c, err + }) + + tunnel, err := client.CreateGrpcTunnel(udsName, dialOption, grpc.WithInsecure()) + if err != nil { + return nil, err } - // It's safe to discard the bufio.Reader here and return the - // original TCP conn directly because we only use this for - // TLS, and in TLS the client speaks first, so we know there's - // no unbuffered data. But we can double-check. - if br.Buffered() > 0 { - proxyConn.Close() - return nil, fmt.Errorf("unexpected %d bytes of buffered data from CONNECT proxy %q", - br.Buffered(), proxyAddress) + proxyConn, err := tunnel.Dial("tcp", addr) + if err != nil { + return nil, err } - klog.V(4).Infof("About to proxy request to %s over %s.", addr, proxyAddress) return proxyConn, nil } return contextDialer, nil @@ -172,17 +213,39 @@ func NewEgressSelector(config *apiserver.EgressSelectorConfiguration) (*EgressSe if err != nil { return nil, err } - switch service.Connection.Type { - case "http-connect": - contextDialer, err := createConnectDialer(service.Connection.HTTPConnect) - if err != nil { - return nil, fmt.Errorf("failed to create http-connect dialer: %v", err) + switch service.Connection.ProxyProtocol { + + case apiserver.ProtocolHTTPConnect: + if service.Connection.Transport.UDS != nil { + contextDialer, err := createConnectUDSDialer(service.Connection.Transport.UDS.UDSName) + if err != nil { + return nil, fmt.Errorf("failed to create HTTPConnect uds dialer: %v", err) + } + cs.egressToDialer[name] = contextDialer + } else if service.Connection.Transport.TCP != nil { + contextDialer, err := createConnectTCPDialer(service.Connection.Transport.TCP) + if err != nil { + return nil, fmt.Errorf("failed to create HTTPConnect dialer: %v", err) + } + cs.egressToDialer[name] = contextDialer + } else { + return nil, fmt.Errorf("Either TCP or UDP transport must be specified") } - cs.egressToDialer[name] = contextDialer - case "direct": + case apiserver.ProtocolGRPC: + if service.Connection.Transport.UDS != nil { + grpcContextDialer, err := createGRPCUDSDialer(service.Connection.Transport.UDS.UDSName) + if err != nil { + return nil, fmt.Errorf("failed to create grpc dialer: %v", err) + } + cs.egressToDialer[name] = grpcContextDialer + + } else { + return nil, fmt.Errorf("Either TCP or UDP transport must be specified") + } + case apiserver.ProtocolDirect: cs.egressToDialer[name] = directDialer default: - return nil, fmt.Errorf("unrecognized service connection type %q", service.Connection.Type) + return nil, fmt.Errorf("unrecognized service connection protocol %q", service.Connection.ProxyProtocol) } } return cs, nil diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector_test.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector_test.go index e24a5bdbb3b..dcd51906f02 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector_test.go @@ -53,37 +53,19 @@ func TestEgressSelector(t *testing.T) { { Name: "cluster", Connection: apiserver.Connection{ - Type: "direct", - HTTPConnect: &apiserver.HTTPConnectConfig{ - URL: "", - CABundle: "", - ClientKey: "", - ClientCert: "", - }, + ProxyProtocol: apiserver.ProtocolDirect, }, }, { Name: "master", Connection: apiserver.Connection{ - Type: "direct", - HTTPConnect: &apiserver.HTTPConnectConfig{ - URL: "", - CABundle: "", - ClientKey: "", - ClientCert: "", - }, + ProxyProtocol: apiserver.ProtocolDirect, }, }, { Name: "etcd", Connection: apiserver.Connection{ - Type: "direct", - HTTPConnect: &apiserver.HTTPConnectConfig{ - URL: "", - CABundle: "", - ClientKey: "", - ClientCert: "", - }, + ProxyProtocol: apiserver.ProtocolDirect, }, }, }, From 55b89a6451d253532ede0736d7bc8af62f396596 Mon Sep 17 00:00:00 2001 From: Jefftree Date: Mon, 3 Feb 2020 19:54:41 -0800 Subject: [PATCH 2/4] Support empty root CA for konnectivity --- .../apiserver/pkg/apis/apiserver/types.go | 13 +++++++------ .../pkg/apis/apiserver/v1alpha1/types.go | 10 +++++----- .../pkg/server/egressselector/config.go | 17 +++++++---------- .../server/egressselector/egress_selector.go | 18 +++++++++++------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go index d6fe4e9931b..f4d93d577f8 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -114,13 +114,13 @@ type TCPTransport struct { // TLSConfig is the config needed to use TLS when connecting to konnectivity server // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + TLSConfig *TLSConfig } // UDSTransport provides the information to connect to konnectivity server via UDS type UDSTransport struct { // UDSName is the name of the unix domain socket to connect to konnectivity server - // This does not use a unix:// prefix. (Eg: /etc/srv/kubernetes/konnectivity/konnectivity-server.socket) + // This does not use a unix:// prefix. (Eg: /etc/srv/kubernetes/konnectivity-server/konnectivity-server.socket) UDSName string } @@ -129,22 +129,23 @@ type UDSTransport struct { type TLSConfig struct { // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol + // If absent while using the HTTPConnect protocol with HTTPS + // default to system trust roots // Misconfiguration will cause an error // +optional - CABundle string `json:"caBundle,omitempty"` + CABundle string // clientKey is the file location of the client key to authenticate with the konnectivity server // Must be absent/empty HTTPConnect using the plain http // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional - ClientKey string `json:"clientKey,omitempty"` + ClientKey string // clientCert is the file location of the client certificate to authenticate with the konnectivity server // Must be absent/empty HTTPConnect using the plain http // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional - ClientCert string `json:"clientCert,omitempty"` + ClientCert string } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index e561017e215..2fdbcd06036 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -110,17 +110,17 @@ type Transport struct { type TCPTransport struct { // URL is the location of the konnectivity server to connect to. // As an example it might be "https://127.0.0.1:8131" - URL string + URL string `json:"url,omitempty"` // TLSConfig is the config needed to use TLS when connecting to konnectivity server // +optional - TLSConfig *TLSConfig + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` } // UDSTransport provides the information to connect to konnectivity server via UDS type UDSTransport struct { // UDSName is the name of the unix domain socket to connect to konnectivity server - UDSName string + UDSName string `json:"udsName,omitempty"` } // TLSConfig provides the authentication information to connect to konnectivity server @@ -128,14 +128,14 @@ type UDSTransport struct { type TLSConfig struct { // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol + // If absent while using the HTTPConnect protocol with HTTPS + // default to system trust roots // Misconfiguration will cause an error // +optional CABundle string `json:"caBundle,omitempty"` // clientKey is the file location of the client key to be used in mtls handshakes with the konnectivity server. // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol // Misconfiguration will cause an error // +optional ClientKey string `json:"clientKey,omitempty"` diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go index 2cf06a4e0da..77e45736373 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go @@ -148,16 +148,13 @@ func validateTCPConnection(connection apiserver.Connection, fldPath *field.Path) "nil", "TLSConfig config should be present for HTTPConnect via tcp")) } else if strings.HasPrefix(connection.Transport.TCP.URL, "https://") { - if connection.Transport.TCP.TLSConfig.CABundle == "" { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "caBundle"), - "nil", - "HTTPConnect via https requires caBundle")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.CABundle); exists == false || err != nil { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "caBundle"), - connection.Transport.TCP.TLSConfig.CABundle, - "HTTPConnect ca bundle does not exist")) + if connection.Transport.TCP.TLSConfig.CABundle != "" { + if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.CABundle); exists == false || err != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "caBundle"), + connection.Transport.TCP.TLSConfig.CABundle, + "HTTPConnect ca bundle does not exist")) + } } if connection.Transport.TCP.TLSConfig.ClientCert == "" { allErrs = append(allErrs, field.Invalid( diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index 919741d78d6..b528dd7ae23 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -138,13 +138,17 @@ func createConnectTCPDialer(tcpTransport *apiserver.TCPTransport) (utilnet.DialF return nil, fmt.Errorf("failed to read key pair %s & %s, got %v", clientCert, clientKey, err) } certPool := x509.NewCertPool() - certBytes, err := ioutil.ReadFile(caCert) - if err != nil { - return nil, fmt.Errorf("failed to read cert file %s, got %v", caCert, err) - } - ok := certPool.AppendCertsFromPEM(certBytes) - if !ok { - return nil, fmt.Errorf("failed to append CA cert to the cert pool") + if caCert != "" { + certBytes, err := ioutil.ReadFile(caCert) + if err != nil { + return nil, fmt.Errorf("failed to read cert file %s, got %v", caCert, err) + } + ok := certPool.AppendCertsFromPEM(certBytes) + if !ok { + return nil, fmt.Errorf("failed to append CA cert to the cert pool") + } + } else { + certPool = nil } contextDialer := func(ctx context.Context, network, addr string) (net.Conn, error) { klog.V(4).Infof("Sending request to %q.", addr) From 907ab25b6fc2d96b19fba1beae6ad3c749bc14e7 Mon Sep 17 00:00:00 2001 From: Jefftree Date: Wed, 12 Feb 2020 10:29:34 -0800 Subject: [PATCH 3/4] vendor network proxy client --- Godeps/LICENSES | 209 ++++++ go.mod | 1 + go.sum | 2 + .../src/k8s.io/apiextensions-apiserver/go.sum | 2 + staging/src/k8s.io/apiserver/go.mod | 1 + staging/src/k8s.io/apiserver/go.sum | 2 + .../apiserver/pkg/server/egressselector/BUILD | 2 +- .../server/egressselector/egress_selector.go | 2 +- staging/src/k8s.io/kube-aggregator/go.sum | 2 + .../src/k8s.io/legacy-cloud-providers/go.sum | 1 + staging/src/k8s.io/sample-apiserver/go.sum | 2 + vendor/BUILD | 2 + vendor/modules.txt | 3 + .../konnectivity-client/LICENSE | 201 ++++++ .../konnectivity-client/pkg/client/BUILD | 31 + .../konnectivity-client/pkg/client/client.go | 195 ++++++ .../konnectivity-client/pkg/client/conn.go | 141 ++++ .../konnectivity-client/proto/client/BUILD | 29 + .../proto/client/client.pb.go | 653 ++++++++++++++++++ .../proto/client/client.proto | 95 +++ 20 files changed, 1574 insertions(+), 2 deletions(-) create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/LICENSE create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/BUILD create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/BUILD create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go create mode 100644 vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto diff --git a/Godeps/LICENSES b/Godeps/LICENSES index db3a1057bd3..6df34592362 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -23322,6 +23322,215 @@ third-party archives. ================================================================================ +================================================================================ += vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client licensed under: = + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. + += vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/LICENSE e3fc50a88d0a364313df4b21ef20c29e +================================================================================ + + ================================================================================ = vendor/sigs.k8s.io/kustomize licensed under: = diff --git a/go.mod b/go.mod index 2ab72ed3c00..132ef934772 100644 --- a/go.mod +++ b/go.mod @@ -573,6 +573,7 @@ replace ( mvdan.cc/lint => mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 rsc.io/pdf => rsc.io/pdf v0.1.1 + sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 sigs.k8s.io/kustomize => sigs.k8s.io/kustomize v2.0.3+incompatible sigs.k8s.io/structured-merge-diff/v3 => sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.2.0 diff --git a/go.sum b/go.sum index ce074f593a0..a85692247fe 100644 --- a/go.sum +++ b/go.sum @@ -619,6 +619,8 @@ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIa mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 h1:bwop2S7kJYCtltbitSoLqQb8HdTxbcRAKqAGzcB4Lk8= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= diff --git a/staging/src/k8s.io/apiextensions-apiserver/go.sum b/staging/src/k8s.io/apiextensions-apiserver/go.sum index 0f8bd092f0a..786485aa53f 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/go.sum +++ b/staging/src/k8s.io/apiextensions-apiserver/go.sum @@ -430,6 +430,8 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 h1:bwop2S7kJYCtltbitSoLqQb8HdTxbcRAKqAGzcB4Lk8= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/staging/src/k8s.io/apiserver/go.mod b/staging/src/k8s.io/apiserver/go.mod index e2aa2c5d3f5..7f225359f9d 100644 --- a/staging/src/k8s.io/apiserver/go.mod +++ b/staging/src/k8s.io/apiserver/go.mod @@ -51,6 +51,7 @@ require ( k8s.io/klog v1.0.0 k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c sigs.k8s.io/yaml v1.2.0 ) diff --git a/staging/src/k8s.io/apiserver/go.sum b/staging/src/k8s.io/apiserver/go.sum index e0fa43b35c1..10d8515116d 100644 --- a/staging/src/k8s.io/apiserver/go.sum +++ b/staging/src/k8s.io/apiserver/go.sum @@ -346,6 +346,8 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 h1:bwop2S7kJYCtltbitSoLqQb8HdTxbcRAKqAGzcB4Lk8= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD index beb7899b0df..d52d6e7a6f2 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD @@ -19,7 +19,7 @@ go_library( "//vendor/google.golang.org/grpc:go_default_library", "//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/utils/path:go_default_library", - "//vendor/sigs.k8s.io/apiserver-network-proxy/pkg/agent/client:go_default_library", + "//vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client:go_default_library", "//vendor/sigs.k8s.io/yaml:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index b528dd7ae23..56d8fcc7a78 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -30,7 +30,7 @@ import ( "net" "net/http" "net/url" - client "sigs.k8s.io/apiserver-network-proxy/pkg/agent/client" + client "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client" "strings" ) diff --git a/staging/src/k8s.io/kube-aggregator/go.sum b/staging/src/k8s.io/kube-aggregator/go.sum index ec3aa4b4a81..d8ed09d5abc 100644 --- a/staging/src/k8s.io/kube-aggregator/go.sum +++ b/staging/src/k8s.io/kube-aggregator/go.sum @@ -367,6 +367,8 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 h1:bwop2S7kJYCtltbitSoLqQb8HdTxbcRAKqAGzcB4Lk8= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/staging/src/k8s.io/legacy-cloud-providers/go.sum b/staging/src/k8s.io/legacy-cloud-providers/go.sum index 9cfcf640349..7d560904f88 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/go.sum +++ b/staging/src/k8s.io/legacy-cloud-providers/go.sum @@ -350,6 +350,7 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/staging/src/k8s.io/sample-apiserver/go.sum b/staging/src/k8s.io/sample-apiserver/go.sum index 784ed008a22..c444aa9869b 100644 --- a/staging/src/k8s.io/sample-apiserver/go.sum +++ b/staging/src/k8s.io/sample-apiserver/go.sum @@ -364,6 +364,8 @@ k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDN k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg= k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 h1:bwop2S7kJYCtltbitSoLqQb8HdTxbcRAKqAGzcB4Lk8= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c h1:xQP7F7Lntt2dtYmg12WPQHObOrAyPHlMWP1JVSa79GM= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200207200219-5e70324e7c1c/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= diff --git a/vendor/BUILD b/vendor/BUILD index 678b9345f4c..8deab9211c2 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -506,6 +506,8 @@ filegroup( "//vendor/k8s.io/utils/pointer:all-srcs", "//vendor/k8s.io/utils/strings:all-srcs", "//vendor/k8s.io/utils/trace:all-srcs", + "//vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client:all-srcs", + "//vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client:all-srcs", "//vendor/sigs.k8s.io/kustomize/pkg/commands/build:all-srcs", "//vendor/sigs.k8s.io/kustomize/pkg/constants:all-srcs", "//vendor/sigs.k8s.io/kustomize/pkg/expansion:all-srcs", diff --git a/vendor/modules.txt b/vendor/modules.txt index 73be3bd93dd..c1f1ccb3c4c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1944,6 +1944,9 @@ k8s.io/utils/path k8s.io/utils/pointer k8s.io/utils/strings k8s.io/utils/trace +# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.5 +sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client +sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client # sigs.k8s.io/kustomize v2.0.3+incompatible => sigs.k8s.io/kustomize v2.0.3+incompatible sigs.k8s.io/kustomize/pkg/commands/build sigs.k8s.io/kustomize/pkg/constants diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/LICENSE b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/LICENSE new file mode 100644 index 00000000000..8dada3edaf5 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/BUILD b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/BUILD new file mode 100644 index 00000000000..35a4db1499b --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/BUILD @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "client.go", + "conn.go", + ], + importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client", + importpath = "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client", + visibility = ["//visibility:public"], + deps = [ + "//vendor/google.golang.org/grpc:go_default_library", + "//vendor/k8s.io/klog:go_default_library", + "//vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go new file mode 100644 index 00000000000..09f00f96564 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go @@ -0,0 +1,195 @@ +/* +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 client + +import ( + "context" + "errors" + "io" + "math/rand" + "net" + "sync" + "time" + + "google.golang.org/grpc" + "k8s.io/klog" + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" +) + +// Tunnel provides ability to dial a connection through a tunnel. +type Tunnel interface { + // Dial connects to the address on the named network, similar to + // what net.Dial does. The only supported protocol is tcp. + Dial(protocol, address string) (net.Conn, error) +} + +type dialResult struct { + err string + connid int64 +} + +// grpcTunnel implements Tunnel +type grpcTunnel struct { + stream client.ProxyService_ProxyClient + pendingDial map[int64]chan<- dialResult + conns map[int64]*conn + pendingDialLock sync.RWMutex + connsLock sync.RWMutex +} + +// CreateGrpcTunnel creates a Tunnel to dial to a remote server through a +// gRPC based proxy service. +func CreateGrpcTunnel(address string, opts ...grpc.DialOption) (Tunnel, error) { + c, err := grpc.Dial(address, opts...) + if err != nil { + return nil, err + } + + grpcClient := client.NewProxyServiceClient(c) + + stream, err := grpcClient.Proxy(context.Background()) + if err != nil { + return nil, err + } + + tunnel := &grpcTunnel{ + stream: stream, + pendingDial: make(map[int64]chan<- dialResult), + conns: make(map[int64]*conn), + } + + go tunnel.serve() + + return tunnel, nil +} + +func (t *grpcTunnel) serve() { + for { + pkt, err := t.stream.Recv() + if err == io.EOF { + return + } + if err != nil || pkt == nil { + klog.Warningf("stream read error: %v", err) + return + } + + klog.Infof("[tracing] recv packet %+v", pkt) + + switch pkt.Type { + case client.PacketType_DIAL_RSP: + resp := pkt.GetDialResponse() + t.pendingDialLock.RLock() + ch, ok := t.pendingDial[resp.Random] + t.pendingDialLock.RUnlock() + + if !ok { + klog.Warning("DialResp not recognized; dropped") + } else { + ch <- dialResult{ + err: resp.Error, + connid: resp.ConnectID, + } + } + case client.PacketType_DATA: + resp := pkt.GetData() + // TODO: flow control + t.connsLock.RLock() + conn, ok := t.conns[resp.ConnectID] + t.connsLock.RUnlock() + + if ok { + conn.readCh <- resp.Data + } else { + klog.Warningf("connection id %d not recognized", resp.ConnectID) + } + case client.PacketType_CLOSE_RSP: + resp := pkt.GetCloseResponse() + t.connsLock.RLock() + conn, ok := t.conns[resp.ConnectID] + t.connsLock.RUnlock() + + if ok { + close(conn.readCh) + conn.closeCh <- resp.Error + close(conn.closeCh) + t.connsLock.Lock() + delete(t.conns, resp.ConnectID) + t.connsLock.Unlock() + } else { + klog.Warningf("connection id %d not recognized", resp.ConnectID) + } + } + } +} + +// Dial connects to the address on the named network, similar to +// what net.Dial does. The only supported protocol is tcp. +func (t *grpcTunnel) Dial(protocol, address string) (net.Conn, error) { + if protocol != "tcp" { + return nil, errors.New("protocol not supported") + } + + random := rand.Int63() + resCh := make(chan dialResult) + t.pendingDialLock.Lock() + t.pendingDial[random] = resCh + t.pendingDialLock.Unlock() + defer func() { + t.pendingDialLock.Lock() + delete(t.pendingDial, random) + t.pendingDialLock.Unlock() + }() + + req := &client.Packet{ + Type: client.PacketType_DIAL_REQ, + Payload: &client.Packet_DialRequest{ + DialRequest: &client.DialRequest{ + Protocol: protocol, + Address: address, + Random: random, + }, + }, + } + klog.Infof("[tracing] send packet %+v", req) + + err := t.stream.Send(req) + if err != nil { + return nil, err + } + + klog.Info("DIAL_REQ sent to proxy server") + + c := &conn{stream: t.stream} + + select { + case res := <-resCh: + if res.err != "" { + return nil, errors.New(res.err) + } + c.connID = res.connid + c.readCh = make(chan []byte, 10) + c.closeCh = make(chan string) + t.connsLock.Lock() + t.conns[res.connid] = c + t.connsLock.Unlock() + case <-time.After(30 * time.Second): + return nil, errors.New("dial timeout") + } + + return c, nil +} diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go new file mode 100644 index 00000000000..22c25234cc2 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go @@ -0,0 +1,141 @@ +/* +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 client + +import ( + "errors" + "io" + "net" + "time" + + "k8s.io/klog" + "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" +) + +// CloseTimeout is the timeout to wait CLOSE_RSP packet after a +// successful delivery of CLOSE_REQ. +const CloseTimeout = 10 * time.Second + +// conn is an implementation of net.Conn, where the data is transported +// over an established tunnel defined by a gRPC service ProxyService. +type conn struct { + stream client.ProxyService_ProxyClient + connID int64 + readCh chan []byte + closeCh chan string + rdata []byte +} + +var _ net.Conn = &conn{} + +// Write sends the data thru the connection over proxy service +func (c *conn) Write(data []byte) (n int, err error) { + req := &client.Packet{ + Type: client.PacketType_DATA, + Payload: &client.Packet_Data{ + Data: &client.Data{ + ConnectID: c.connID, + Data: data, + }, + }, + } + + klog.Infof("[tracing] send req %+v", req) + + err = c.stream.Send(req) + if err != nil { + return 0, err + } + return len(data), err +} + +// Read receives data from the connection over proxy service +func (c *conn) Read(b []byte) (n int, err error) { + var data []byte + + if c.rdata != nil { + data = c.rdata + } else { + data = <-c.readCh + } + + if data == nil { + return 0, io.EOF + } + + if len(data) > len(b) { + copy(b, data[:len(b)]) + c.rdata = data[len(b):] + return len(b), nil + } + + c.rdata = nil + copy(b, data) + + return len(data), nil +} + +func (c *conn) LocalAddr() net.Addr { + return nil +} + +func (c *conn) RemoteAddr() net.Addr { + return nil +} + +func (c *conn) SetDeadline(t time.Time) error { + return errors.New("not implemented") +} + +func (c *conn) SetReadDeadline(t time.Time) error { + return errors.New("not implemented") +} + +func (c *conn) SetWriteDeadline(t time.Time) error { + return errors.New("not implemented") +} + +// Close closes the connection. It also sends CLOSE_REQ packet over +// proxy service to notify remote to drop the connection. +func (c *conn) Close() error { + klog.Info("conn.Close()") + req := &client.Packet{ + Type: client.PacketType_CLOSE_REQ, + Payload: &client.Packet_CloseRequest{ + CloseRequest: &client.CloseRequest{ + ConnectID: c.connID, + }, + }, + } + + klog.Infof("[tracing] send req %+v", req) + + if err := c.stream.Send(req); err != nil { + return err + } + + select { + case errMsg := <-c.closeCh: + if errMsg != "" { + return errors.New(errMsg) + } + return nil + case <-time.After(CloseTimeout): + } + + return errors.New("close timeout") +} diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/BUILD b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/BUILD new file mode 100644 index 00000000000..e42a33f0fb2 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/BUILD @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["client.pb.go"], + importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client", + importpath = "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/golang/protobuf/proto:go_default_library", + "//vendor/google.golang.org/grpc:go_default_library", + "//vendor/google.golang.org/grpc/codes:go_default_library", + "//vendor/google.golang.org/grpc/status:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go new file mode 100644 index 00000000000..107f2e546fe --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go @@ -0,0 +1,653 @@ +/* +Copyright 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. +*/ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: konnectivity-client/proto/client/client.proto + +package client + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type PacketType int32 + +const ( + PacketType_DIAL_REQ PacketType = 0 + PacketType_DIAL_RSP PacketType = 1 + PacketType_CLOSE_REQ PacketType = 2 + PacketType_CLOSE_RSP PacketType = 3 + PacketType_DATA PacketType = 4 +) + +var PacketType_name = map[int32]string{ + 0: "DIAL_REQ", + 1: "DIAL_RSP", + 2: "CLOSE_REQ", + 3: "CLOSE_RSP", + 4: "DATA", +} + +var PacketType_value = map[string]int32{ + "DIAL_REQ": 0, + "DIAL_RSP": 1, + "CLOSE_REQ": 2, + "CLOSE_RSP": 3, + "DATA": 4, +} + +func (x PacketType) String() string { + return proto.EnumName(PacketType_name, int32(x)) +} + +func (PacketType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{0} +} + +type Error int32 + +const ( + Error_EOF Error = 0 +) + +var Error_name = map[int32]string{ + 0: "EOF", +} + +var Error_value = map[string]int32{ + "EOF": 0, +} + +func (x Error) String() string { + return proto.EnumName(Error_name, int32(x)) +} + +func (Error) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{1} +} + +type Packet struct { + Type PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=PacketType" json:"type,omitempty"` + // Types that are valid to be assigned to Payload: + // *Packet_DialRequest + // *Packet_DialResponse + // *Packet_Data + // *Packet_CloseRequest + // *Packet_CloseResponse + Payload isPacket_Payload `protobuf_oneof:"payload"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Packet) Reset() { *m = Packet{} } +func (m *Packet) String() string { return proto.CompactTextString(m) } +func (*Packet) ProtoMessage() {} +func (*Packet) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{0} +} + +func (m *Packet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Packet.Unmarshal(m, b) +} +func (m *Packet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Packet.Marshal(b, m, deterministic) +} +func (m *Packet) XXX_Merge(src proto.Message) { + xxx_messageInfo_Packet.Merge(m, src) +} +func (m *Packet) XXX_Size() int { + return xxx_messageInfo_Packet.Size(m) +} +func (m *Packet) XXX_DiscardUnknown() { + xxx_messageInfo_Packet.DiscardUnknown(m) +} + +var xxx_messageInfo_Packet proto.InternalMessageInfo + +func (m *Packet) GetType() PacketType { + if m != nil { + return m.Type + } + return PacketType_DIAL_REQ +} + +type isPacket_Payload interface { + isPacket_Payload() +} + +type Packet_DialRequest struct { + DialRequest *DialRequest `protobuf:"bytes,2,opt,name=dialRequest,proto3,oneof"` +} + +type Packet_DialResponse struct { + DialResponse *DialResponse `protobuf:"bytes,3,opt,name=dialResponse,proto3,oneof"` +} + +type Packet_Data struct { + Data *Data `protobuf:"bytes,4,opt,name=data,proto3,oneof"` +} + +type Packet_CloseRequest struct { + CloseRequest *CloseRequest `protobuf:"bytes,5,opt,name=closeRequest,proto3,oneof"` +} + +type Packet_CloseResponse struct { + CloseResponse *CloseResponse `protobuf:"bytes,6,opt,name=closeResponse,proto3,oneof"` +} + +func (*Packet_DialRequest) isPacket_Payload() {} + +func (*Packet_DialResponse) isPacket_Payload() {} + +func (*Packet_Data) isPacket_Payload() {} + +func (*Packet_CloseRequest) isPacket_Payload() {} + +func (*Packet_CloseResponse) isPacket_Payload() {} + +func (m *Packet) GetPayload() isPacket_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (m *Packet) GetDialRequest() *DialRequest { + if x, ok := m.GetPayload().(*Packet_DialRequest); ok { + return x.DialRequest + } + return nil +} + +func (m *Packet) GetDialResponse() *DialResponse { + if x, ok := m.GetPayload().(*Packet_DialResponse); ok { + return x.DialResponse + } + return nil +} + +func (m *Packet) GetData() *Data { + if x, ok := m.GetPayload().(*Packet_Data); ok { + return x.Data + } + return nil +} + +func (m *Packet) GetCloseRequest() *CloseRequest { + if x, ok := m.GetPayload().(*Packet_CloseRequest); ok { + return x.CloseRequest + } + return nil +} + +func (m *Packet) GetCloseResponse() *CloseResponse { + if x, ok := m.GetPayload().(*Packet_CloseResponse); ok { + return x.CloseResponse + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Packet) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Packet_DialRequest)(nil), + (*Packet_DialResponse)(nil), + (*Packet_Data)(nil), + (*Packet_CloseRequest)(nil), + (*Packet_CloseResponse)(nil), + } +} + +type DialRequest struct { + // tcp or udp? + Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` + // node:port + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + // random id for client, maybe should be longer + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DialRequest) Reset() { *m = DialRequest{} } +func (m *DialRequest) String() string { return proto.CompactTextString(m) } +func (*DialRequest) ProtoMessage() {} +func (*DialRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{1} +} + +func (m *DialRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DialRequest.Unmarshal(m, b) +} +func (m *DialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DialRequest.Marshal(b, m, deterministic) +} +func (m *DialRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DialRequest.Merge(m, src) +} +func (m *DialRequest) XXX_Size() int { + return xxx_messageInfo_DialRequest.Size(m) +} +func (m *DialRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DialRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DialRequest proto.InternalMessageInfo + +func (m *DialRequest) GetProtocol() string { + if m != nil { + return m.Protocol + } + return "" +} + +func (m *DialRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *DialRequest) GetRandom() int64 { + if m != nil { + return m.Random + } + return 0 +} + +type DialResponse struct { + // error failed reason; enum? + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + // connectID indicates the identifier of the connection + ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` + // random copied from DialRequest + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DialResponse) Reset() { *m = DialResponse{} } +func (m *DialResponse) String() string { return proto.CompactTextString(m) } +func (*DialResponse) ProtoMessage() {} +func (*DialResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{2} +} + +func (m *DialResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DialResponse.Unmarshal(m, b) +} +func (m *DialResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DialResponse.Marshal(b, m, deterministic) +} +func (m *DialResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DialResponse.Merge(m, src) +} +func (m *DialResponse) XXX_Size() int { + return xxx_messageInfo_DialResponse.Size(m) +} +func (m *DialResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DialResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DialResponse proto.InternalMessageInfo + +func (m *DialResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func (m *DialResponse) GetConnectID() int64 { + if m != nil { + return m.ConnectID + } + return 0 +} + +func (m *DialResponse) GetRandom() int64 { + if m != nil { + return m.Random + } + return 0 +} + +type CloseRequest struct { + // connectID of the stream to close + ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CloseRequest) Reset() { *m = CloseRequest{} } +func (m *CloseRequest) String() string { return proto.CompactTextString(m) } +func (*CloseRequest) ProtoMessage() {} +func (*CloseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{3} +} + +func (m *CloseRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CloseRequest.Unmarshal(m, b) +} +func (m *CloseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CloseRequest.Marshal(b, m, deterministic) +} +func (m *CloseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CloseRequest.Merge(m, src) +} +func (m *CloseRequest) XXX_Size() int { + return xxx_messageInfo_CloseRequest.Size(m) +} +func (m *CloseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CloseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CloseRequest proto.InternalMessageInfo + +func (m *CloseRequest) GetConnectID() int64 { + if m != nil { + return m.ConnectID + } + return 0 +} + +type CloseResponse struct { + // error message + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + // connectID indicates the identifier of the connection + ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CloseResponse) Reset() { *m = CloseResponse{} } +func (m *CloseResponse) String() string { return proto.CompactTextString(m) } +func (*CloseResponse) ProtoMessage() {} +func (*CloseResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{4} +} + +func (m *CloseResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CloseResponse.Unmarshal(m, b) +} +func (m *CloseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CloseResponse.Marshal(b, m, deterministic) +} +func (m *CloseResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CloseResponse.Merge(m, src) +} +func (m *CloseResponse) XXX_Size() int { + return xxx_messageInfo_CloseResponse.Size(m) +} +func (m *CloseResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CloseResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CloseResponse proto.InternalMessageInfo + +func (m *CloseResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func (m *CloseResponse) GetConnectID() int64 { + if m != nil { + return m.ConnectID + } + return 0 +} + +type Data struct { + // connectID to connect to + ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` + // error message if error happens + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + // stream data + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Data) Reset() { *m = Data{} } +func (m *Data) String() string { return proto.CompactTextString(m) } +func (*Data) ProtoMessage() {} +func (*Data) Descriptor() ([]byte, []int) { + return fileDescriptor_fec4258d9ecd175d, []int{5} +} + +func (m *Data) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Data.Unmarshal(m, b) +} +func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Data.Marshal(b, m, deterministic) +} +func (m *Data) XXX_Merge(src proto.Message) { + xxx_messageInfo_Data.Merge(m, src) +} +func (m *Data) XXX_Size() int { + return xxx_messageInfo_Data.Size(m) +} +func (m *Data) XXX_DiscardUnknown() { + xxx_messageInfo_Data.DiscardUnknown(m) +} + +var xxx_messageInfo_Data proto.InternalMessageInfo + +func (m *Data) GetConnectID() int64 { + if m != nil { + return m.ConnectID + } + return 0 +} + +func (m *Data) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func (m *Data) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func init() { + proto.RegisterEnum("PacketType", PacketType_name, PacketType_value) + proto.RegisterEnum("Error", Error_name, Error_value) + proto.RegisterType((*Packet)(nil), "Packet") + proto.RegisterType((*DialRequest)(nil), "DialRequest") + proto.RegisterType((*DialResponse)(nil), "DialResponse") + proto.RegisterType((*CloseRequest)(nil), "CloseRequest") + proto.RegisterType((*CloseResponse)(nil), "CloseResponse") + proto.RegisterType((*Data)(nil), "Data") +} + +func init() { + proto.RegisterFile("konnectivity-client/proto/client/client.proto", fileDescriptor_fec4258d9ecd175d) +} + +var fileDescriptor_fec4258d9ecd175d = []byte{ + // 472 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xd1, 0x6e, 0x9b, 0x30, + 0x14, 0x85, 0x00, 0x49, 0xb8, 0x21, 0x15, 0xb2, 0xa6, 0x09, 0x75, 0x93, 0x5a, 0xf1, 0x14, 0x55, + 0x0b, 0x54, 0xa9, 0x34, 0xed, 0x35, 0x0d, 0xa9, 0x52, 0xa9, 0x5a, 0x99, 0xd3, 0xa7, 0xee, 0x61, + 0xf2, 0xc0, 0x9a, 0x50, 0x18, 0x66, 0xb6, 0x97, 0x8d, 0x0f, 0xda, 0x7f, 0x4e, 0x18, 0x52, 0xc8, + 0xa4, 0x6d, 0x52, 0x9f, 0xe0, 0x1c, 0xdf, 0x73, 0x7c, 0x7d, 0xae, 0x0d, 0xf3, 0x1d, 0x2b, 0x0a, + 0x9a, 0xc8, 0x6c, 0x9f, 0xc9, 0x6a, 0x9e, 0xe4, 0x19, 0x2d, 0x64, 0x58, 0x72, 0x26, 0x59, 0xd8, + 0x82, 0xe6, 0x13, 0x28, 0xce, 0xff, 0x35, 0x80, 0x61, 0x4c, 0x92, 0x1d, 0x95, 0xe8, 0x0c, 0x4c, + 0x59, 0x95, 0xd4, 0xd3, 0xcf, 0xf5, 0xd9, 0xc9, 0x62, 0x12, 0x34, 0xf4, 0x43, 0x55, 0x52, 0xac, + 0x16, 0xd0, 0x25, 0x4c, 0xd2, 0x8c, 0xe4, 0x98, 0x7e, 0xfb, 0x4e, 0x85, 0xf4, 0x06, 0xe7, 0xfa, + 0x6c, 0xb2, 0x70, 0x82, 0xa8, 0xe3, 0x36, 0x1a, 0xee, 0x97, 0xa0, 0x2b, 0x70, 0x1a, 0x28, 0x4a, + 0x56, 0x08, 0xea, 0x19, 0x4a, 0x32, 0x6d, 0x25, 0x0d, 0xb9, 0xd1, 0xf0, 0x51, 0x11, 0x7a, 0x05, + 0x66, 0x4a, 0x24, 0xf1, 0x4c, 0x55, 0x6c, 0x05, 0x11, 0x91, 0x64, 0xa3, 0x61, 0x45, 0xd6, 0x8e, + 0x49, 0xce, 0x04, 0x3d, 0x34, 0x61, 0xb5, 0x8e, 0xab, 0x1e, 0x59, 0x3b, 0xf6, 0x8b, 0xd0, 0x5b, + 0x98, 0xb6, 0xb8, 0xed, 0x63, 0xa8, 0x54, 0x27, 0x07, 0xd5, 0x53, 0x23, 0xc7, 0x65, 0xd7, 0x36, + 0x8c, 0x4a, 0x52, 0xe5, 0x8c, 0xa4, 0xfe, 0x47, 0x98, 0xf4, 0xce, 0x89, 0x4e, 0x61, 0xac, 0xf2, + 0x4b, 0x58, 0xae, 0xf2, 0xb2, 0xf1, 0x13, 0x46, 0x1e, 0x8c, 0x48, 0x9a, 0x72, 0x2a, 0x84, 0x8a, + 0xc8, 0xc6, 0x07, 0x88, 0x5e, 0xc2, 0x90, 0x93, 0x22, 0x65, 0x5f, 0x55, 0x10, 0x06, 0x6e, 0x91, + 0xff, 0x08, 0x4e, 0x3f, 0x11, 0xf4, 0x02, 0x2c, 0xca, 0x39, 0xe3, 0xad, 0x75, 0x03, 0xd0, 0x6b, + 0xb0, 0x93, 0x66, 0xb6, 0xb7, 0x91, 0x72, 0x36, 0x70, 0x47, 0xfc, 0xd5, 0xfb, 0x0d, 0x38, 0xfd, + 0x6c, 0x8e, 0x5d, 0xf4, 0x3f, 0x5c, 0xfc, 0x15, 0x4c, 0x8f, 0x32, 0x79, 0x4e, 0x2b, 0xfe, 0x7b, + 0x30, 0xeb, 0x99, 0xfd, 0x7b, 0xab, 0xce, 0x79, 0xd0, 0x77, 0x46, 0xed, 0xf0, 0xeb, 0x43, 0x38, + 0xcd, 0xcc, 0x2f, 0x62, 0x80, 0xee, 0x2e, 0x22, 0x07, 0xc6, 0xd1, 0xed, 0xf2, 0xee, 0x13, 0x5e, + 0x7f, 0x70, 0xb5, 0x0e, 0x6d, 0x63, 0x57, 0x47, 0x53, 0xb0, 0x57, 0x77, 0xf7, 0xdb, 0xb5, 0x5a, + 0x1c, 0xf4, 0xe0, 0x36, 0x76, 0x0d, 0x34, 0x06, 0x33, 0x5a, 0x3e, 0x2c, 0x5d, 0xf3, 0xc2, 0x05, + 0x6b, 0xad, 0xb6, 0x1b, 0x81, 0xb1, 0xbe, 0xbf, 0x71, 0xb5, 0x45, 0x08, 0x4e, 0xcc, 0xd9, 0xcf, + 0x6a, 0x4b, 0xf9, 0x3e, 0x4b, 0x28, 0x3a, 0x03, 0x4b, 0x61, 0x34, 0x6a, 0xdf, 0xc1, 0xe9, 0xe1, + 0xc7, 0xd7, 0x66, 0xfa, 0xa5, 0x7e, 0x7d, 0xf3, 0x18, 0x89, 0xec, 0x8b, 0x08, 0x76, 0xef, 0x44, + 0x90, 0xb1, 0x90, 0x94, 0x99, 0xa0, 0x7c, 0x4f, 0xf9, 0xbc, 0xa0, 0xf2, 0x07, 0xe3, 0xbb, 0x79, + 0x59, 0xcb, 0xc3, 0xff, 0xbd, 0xc6, 0xcf, 0x43, 0x85, 0xae, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x64, 0xe0, 0x62, 0xbe, 0xb8, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ProxyServiceClient is the client API for ProxyService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ProxyServiceClient interface { + Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) +} + +type proxyServiceClient struct { + cc *grpc.ClientConn +} + +func NewProxyServiceClient(cc *grpc.ClientConn) ProxyServiceClient { + return &proxyServiceClient{cc} +} + +func (c *proxyServiceClient) Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) { + stream, err := c.cc.NewStream(ctx, &_ProxyService_serviceDesc.Streams[0], "/ProxyService/Proxy", opts...) + if err != nil { + return nil, err + } + x := &proxyServiceProxyClient{stream} + return x, nil +} + +type ProxyService_ProxyClient interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ClientStream +} + +type proxyServiceProxyClient struct { + grpc.ClientStream +} + +func (x *proxyServiceProxyClient) Send(m *Packet) error { + return x.ClientStream.SendMsg(m) +} + +func (x *proxyServiceProxyClient) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ProxyServiceServer is the server API for ProxyService service. +type ProxyServiceServer interface { + Proxy(ProxyService_ProxyServer) error +} + +// UnimplementedProxyServiceServer can be embedded to have forward compatible implementations. +type UnimplementedProxyServiceServer struct { +} + +func (*UnimplementedProxyServiceServer) Proxy(srv ProxyService_ProxyServer) error { + return status.Errorf(codes.Unimplemented, "method Proxy not implemented") +} + +func RegisterProxyServiceServer(s *grpc.Server, srv ProxyServiceServer) { + s.RegisterService(&_ProxyService_serviceDesc, srv) +} + +func _ProxyService_Proxy_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ProxyServiceServer).Proxy(&proxyServiceProxyServer{stream}) +} + +type ProxyService_ProxyServer interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ServerStream +} + +type proxyServiceProxyServer struct { + grpc.ServerStream +} + +func (x *proxyServiceProxyServer) Send(m *Packet) error { + return x.ServerStream.SendMsg(m) +} + +func (x *proxyServiceProxyServer) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _ProxyService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ProxyService", + HandlerType: (*ProxyServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Proxy", + Handler: _ProxyService_Proxy_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "konnectivity-client/proto/client/client.proto", +} diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto new file mode 100644 index 00000000000..3aadac0642c --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto @@ -0,0 +1,95 @@ +// Copyright 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. + +syntax = "proto3"; + +// Retransmit? +// Sliding windows? + +option go_package = "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client"; + +service ProxyService { + rpc Proxy(stream Packet) returns (stream Packet) {} +} + +enum PacketType { + DIAL_REQ = 0; + DIAL_RSP = 1; + CLOSE_REQ = 2; + CLOSE_RSP = 3; + DATA = 4; +} + +enum Error { + EOF = 0; + // ... +} + +message Packet { + PacketType type = 1; + + oneof payload { + DialRequest dialRequest = 2; + DialResponse dialResponse = 3; + Data data = 4; + CloseRequest closeRequest = 5; + CloseResponse closeResponse = 6; + } +} + +message DialRequest { + // tcp or udp? + string protocol = 1; + + // node:port + string address = 2; + + // random id for client, maybe should be longer + int64 random = 3; +} + +message DialResponse { + // error failed reason; enum? + string error = 1; + + // connectID indicates the identifier of the connection + int64 connectID = 2; + + // random copied from DialRequest + int64 random = 3; +} + +message CloseRequest { + // connectID of the stream to close + int64 connectID = 1; +} + +message CloseResponse { + // error message + string error = 1; + + // connectID indicates the identifier of the connection + int64 connectID = 2; +} + +message Data { + // connectID to connect to + int64 connectID = 1; + + // error message if error happens + string error = 2; + + // stream data + bytes data = 3; +} From d798ccbba166449971c8579dce57870abec9131b Mon Sep 17 00:00:00 2001 From: Jefftree Date: Wed, 12 Feb 2020 10:57:21 -0800 Subject: [PATCH 4/4] Add tests for egress selector --- .../apiserver/pkg/apis/apiserver/types.go | 21 +- .../pkg/apis/apiserver/v1alpha1/types.go | 21 +- .../pkg/server/egressselector/config.go | 189 +++++++++------- .../pkg/server/egressselector/config_test.go | 203 ++++++++++++++++++ .../server/egressselector/egress_selector.go | 15 +- 5 files changed, 337 insertions(+), 112 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go index f4d93d577f8..4e414944129 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -74,8 +74,8 @@ type Connection struct { // Protocol is the protocol used to connect from client to the konnectivity server. ProxyProtocol ProtocolType - // Transport defines the transport configurations we use to dial to the konnectivity server - // This is required if ProxyProtocol is HTTPConnect or GRPC + // Transport defines the transport configurations we use to dial to the konnectivity server. + // This is required if ProxyProtocol is HTTPConnect or GRPC. // +optional Transport *Transport } @@ -96,6 +96,7 @@ const ( // Transport defines the transport configurations we use to dial to the konnectivity server type Transport struct { // TCP is the TCP configuration for communicating with the konnectivity server via TCP + // ProxyProtocol of GRPC is not supported with TCP transport at the moment // Requires at least one of TCP or UDS to be set // +optional TCP *TCPTransport @@ -128,24 +129,20 @@ type UDSTransport struct { // Only used with TCPTransport type TLSConfig struct { // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. - // Must be absent/empty HTTPConnect using the plain http - // If absent while using the HTTPConnect protocol with HTTPS - // default to system trust roots - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // If absent while TCPTransport.URL is prefixed with https://, default to system trust roots. // +optional CABundle string // clientKey is the file location of the client key to authenticate with the konnectivity server - // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientKey string // clientCert is the file location of the client certificate to authenticate with the konnectivity server - // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientCert string } diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index 2fdbcd06036..7b9aacae86f 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -74,8 +74,8 @@ type Connection struct { // Protocol is the protocol used to connect from client to the konnectivity server. ProxyProtocol ProtocolType `json:"proxyProtocol,omitempty"` - // Transport defines the transport configurations we use to dial to the konnectivity server - // This is required if ProxyProtocol is HTTPConnect or GRPC + // Transport defines the transport configurations we use to dial to the konnectivity server. + // This is required if ProxyProtocol is HTTPConnect or GRPC. // +optional Transport *Transport `json:"transport,omitempty"` } @@ -96,6 +96,7 @@ const ( // Transport defines the transport configurations we use to dial to the konnectivity server type Transport struct { // TCP is the TCP configuration for communicating with the konnectivity server via TCP + // ProxyProtocol of GRPC is not supported with TCP transport at the moment // Requires at least one of TCP or UDS to be set // +optional TCP *TCPTransport `json:"tcp,omitempty"` @@ -120,6 +121,7 @@ type TCPTransport struct { // UDSTransport provides the information to connect to konnectivity server via UDS type UDSTransport struct { // UDSName is the name of the unix domain socket to connect to konnectivity server + // This does not use a unix:// prefix. (Eg: /etc/srv/kubernetes/konnectivity-server/konnectivity-server.socket) UDSName string `json:"udsName,omitempty"` } @@ -127,23 +129,20 @@ type UDSTransport struct { // Only used with TCPTransport type TLSConfig struct { // caBundle is the file location of the CA to be used to determine trust with the konnectivity server. - // Must be absent/empty HTTPConnect using the plain http - // If absent while using the HTTPConnect protocol with HTTPS - // default to system trust roots - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // If absent while TCPTransport.URL is prefixed with https://, default to system trust roots. // +optional CABundle string `json:"caBundle,omitempty"` // clientKey is the file location of the client key to be used in mtls handshakes with the konnectivity server. - // Must be absent/empty HTTPConnect using the plain http - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientKey string `json:"clientKey,omitempty"` // clientCert is the file location of the client certificate to be used in mtls handshakes with the konnectivity server. - // Must be absent/empty HTTPConnect using the plain http - // Must be configured for HTTPConnect using the https protocol - // Misconfiguration will cause an error + // Must be absent/empty if TCPTransport.URL is prefixed with http:// + // Must be configured if TCPTransport.URL is prefixed with https:// // +optional ClientCert string `json:"clientCert,omitempty"` } diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go index 77e45736373..7c40154e6d5 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go @@ -78,42 +78,70 @@ func ValidateEgressSelectorConfiguration(config *apiserver.EgressSelectorConfigu return allErrs // Treating a nil configuration as valid } for _, service := range config.EgressSelections { - base := field.NewPath("service", "connection") + fldPath := field.NewPath("service", "connection") switch service.Connection.ProxyProtocol { case apiserver.ProtocolDirect: - allErrs = append(allErrs, validateDirectConnection(service.Connection, base)...) + allErrs = append(allErrs, validateDirectConnection(service.Connection, fldPath)...) case apiserver.ProtocolHTTPConnect: - if service.Connection.Transport.TCP != nil && service.Connection.Transport.UDS != nil { - allErrs = append(allErrs, field.Invalid( - base.Child("tcp"), - service.Connection.Transport.TCP, - "TCP and UDS cannot both be set")) - } else if service.Connection.Transport.TCP == nil && service.Connection.Transport.UDS == nil { - allErrs = append(allErrs, field.Required( - base.Child("tcp"), - "One of TCP or UDS must be set")) - } else if service.Connection.Transport.TCP != nil { - allErrs = append(allErrs, validateTCPConnection(service.Connection, base)...) - } else if service.Connection.Transport.UDS != nil { - allErrs = append(allErrs, validateUDSConnection(service.Connection, base)...) - } + allErrs = append(allErrs, validateHTTPConnectTransport(service.Connection.Transport, fldPath)...) case apiserver.ProtocolGRPC: - if service.Connection.Transport.UDS != nil { - allErrs = append(allErrs, validateUDSConnection(service.Connection, base)...) - } else { - allErrs = append(allErrs, field.NotSupported( - base.Child("protocol"), - service.Connection.ProxyProtocol, - []string{"uds"})) - } + allErrs = append(allErrs, validateGRPCTransport(service.Connection.Transport, fldPath)...) default: allErrs = append(allErrs, field.NotSupported( - base.Child("protocol"), + fldPath.Child("protocol"), service.Connection.ProxyProtocol, - []string{"direct", "HTTPConnect", "grpc"})) + []string{ + string(apiserver.ProtocolDirect), + string(apiserver.ProtocolHTTPConnect), + string(apiserver.ProtocolGRPC), + })) } } + return allErrs +} +func validateHTTPConnectTransport(transport *apiserver.Transport, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if transport == nil { + allErrs = append(allErrs, field.Required( + fldPath.Child("transport"), + "transport must be set for HTTPConnect")) + return allErrs + } + + if transport.TCP != nil && transport.UDS != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tcp"), + transport.TCP, + "TCP and UDS cannot both be set")) + } else if transport.TCP == nil && transport.UDS == nil { + allErrs = append(allErrs, field.Required( + fldPath.Child("tcp"), + "One of TCP or UDS must be set")) + } else if transport.TCP != nil { + allErrs = append(allErrs, validateTCPConnection(transport.TCP, fldPath)...) + } else if transport.UDS != nil { + allErrs = append(allErrs, validateUDSConnection(transport.UDS, fldPath)...) + } + return allErrs +} + +func validateGRPCTransport(transport *apiserver.Transport, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if transport == nil { + allErrs = append(allErrs, field.Required( + fldPath.Child("transport"), + "transport must be set for GRPC")) + return allErrs + } + + if transport.UDS != nil { + allErrs = append(allErrs, validateUDSConnection(transport.UDS, fldPath)...) + } else { + allErrs = append(allErrs, field.Required( + fldPath.Child("uds"), + "UDS must be set with GRPC")) + } return allErrs } @@ -129,9 +157,9 @@ func validateDirectConnection(connection apiserver.Connection, fldPath *field.Pa return nil } -func validateUDSConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { +func validateUDSConnection(udsConfig *apiserver.UDSTransport, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if connection.Transport.UDS.UDSName == "" { + if udsConfig.UDSName == "" { allErrs = append(allErrs, field.Invalid( fldPath.Child("udsName"), "nil", @@ -140,68 +168,65 @@ func validateUDSConnection(connection apiserver.Connection, fldPath *field.Path) return allErrs } -func validateTCPConnection(connection apiserver.Connection, fldPath *field.Path) field.ErrorList { +func validateTCPConnection(tcpConfig *apiserver.TCPTransport, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if connection.Transport.TCP.TLSConfig == nil { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig"), - "nil", - "TLSConfig config should be present for HTTPConnect via tcp")) - } else if strings.HasPrefix(connection.Transport.TCP.URL, "https://") { - if connection.Transport.TCP.TLSConfig.CABundle != "" { - if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.CABundle); exists == false || err != nil { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "caBundle"), - connection.Transport.TCP.TLSConfig.CABundle, - "HTTPConnect ca bundle does not exist")) - } - } - if connection.Transport.TCP.TLSConfig.ClientCert == "" { + + if strings.HasPrefix(tcpConfig.URL, "http://") { + if tcpConfig.TLSConfig != nil { allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientCert"), + fldPath.Child("tlsConfig"), "nil", - "HTTPConnect via https requires clientCert")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.ClientCert); exists == false || err != nil { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientCert"), - connection.Transport.TCP.TLSConfig.ClientCert, - "HTTPConnect client cert does not exist")) - } - if connection.Transport.TCP.TLSConfig.ClientKey == "" { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientKey"), - "nil", - "HTTPConnect via https requires clientKey")) - } else if exists, err := path.Exists(path.CheckFollowSymlink, connection.Transport.TCP.TLSConfig.ClientKey); exists == false || err != nil { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientKey"), - connection.Transport.TCP.TLSConfig.ClientKey, - "HTTPConnect client key does not exist")) - } - } else if strings.HasPrefix(connection.Transport.TCP.URL, "http://") { - if connection.Transport.TCP.TLSConfig.CABundle != "" { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "caBundle"), - connection.Transport.TCP.TLSConfig.CABundle, - "HTTPConnect via http does not support caBundle")) - } - if connection.Transport.TCP.TLSConfig.ClientCert != "" { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientCert"), - connection.Transport.TCP.TLSConfig.ClientCert, - "HTTPConnect via http does not support clientCert")) - } - if connection.Transport.TCP.TLSConfig.ClientKey != "" { - allErrs = append(allErrs, field.Invalid( - fldPath.Child("tlsConfig", "clientKey"), - connection.Transport.TCP.TLSConfig.ClientKey, - "HTTPConnect via http does not support clientKey")) + "TLSConfig config should not be present when using HTTP")) } + } else if strings.HasPrefix(tcpConfig.URL, "https://") { + return validateTLSConfig(tcpConfig.TLSConfig, fldPath) } else { allErrs = append(allErrs, field.Invalid( fldPath.Child("url"), - connection.Transport.TCP.URL, + tcpConfig.URL, "supported connection protocols are http:// and https://")) } return allErrs } + +func validateTLSConfig(tlsConfig *apiserver.TLSConfig, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if tlsConfig == nil { + allErrs = append(allErrs, field.Required( + fldPath.Child("tlsConfig"), + "TLSConfig must be present when using HTTPS")) + return allErrs + } + if tlsConfig.CABundle != "" { + if exists, err := path.Exists(path.CheckFollowSymlink, tlsConfig.CABundle); exists == false || err != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "caBundle"), + tlsConfig.CABundle, + "TLS config ca bundle does not exist")) + } + } + if tlsConfig.ClientCert == "" { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "clientCert"), + "nil", + "Using TLS requires clientCert")) + } else if exists, err := path.Exists(path.CheckFollowSymlink, tlsConfig.ClientCert); exists == false || err != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "clientCert"), + tlsConfig.ClientCert, + "TLS client cert does not exist")) + } + if tlsConfig.ClientKey == "" { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "clientKey"), + "nil", + "Using TLS requires requires clientKey")) + } else if exists, err := path.Exists(path.CheckFollowSymlink, tlsConfig.ClientKey); exists == false || err != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("tlsConfig", "clientKey"), + tlsConfig.ClientKey, + "TLS client key does not exist")) + } + return allErrs +} diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go index 0f36bffbd8b..87b8951d697 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go @@ -223,3 +223,206 @@ spec: }) } } + +func TestValidateEgressSelectorConfiguration(t *testing.T) { + testcases := []struct { + name string + expectError bool + contents *apiserver.EgressSelectorConfiguration + }{ + { + name: "direct-valid", + expectError: false, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "master", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolDirect, + }, + }, + }, + }, + }, + { + name: "direct-invalid-transport", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "master", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolDirect, + Transport: &apiserver.Transport{}, + }, + }, + }, + }, + }, + { + name: "httpconnect-no-https", + expectError: false, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolHTTPConnect, + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "http://127.0.0.1:8131", + }, + }, + }, + }, + }, + }, + }, + { + name: "httpconnect-https-no-cert-error", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolHTTPConnect, + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "https://127.0.0.1:8131", + }, + }, + }, + }, + }, + }, + }, + { + name: "httpconnect-tcp-uds-both-set", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolHTTPConnect, + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "http://127.0.0.1:8131", + }, + UDS: &apiserver.UDSTransport{ + UDSName: "/etc/srv/kubernetes/konnectivity/konnectivity-server.socket", + }, + }, + }, + }, + }, + }, + }, + { + name: "httpconnect-uds", + expectError: false, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolHTTPConnect, + Transport: &apiserver.Transport{ + UDS: &apiserver.UDSTransport{ + UDSName: "/etc/srv/kubernetes/konnectivity/konnectivity-server.socket", + }, + }, + }, + }, + }, + }, + }, + { + name: "grpc-https-invalid", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolGRPC, + Transport: &apiserver.Transport{ + TCP: &apiserver.TCPTransport{ + URL: "http://127.0.0.1:8131", + TLSConfig: &apiserver.TLSConfig{ + CABundle: "", + ClientKey: "", + ClientCert: "", + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "grpc-uds", + expectError: false, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "cluster", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolGRPC, + Transport: &apiserver.Transport{ + UDS: &apiserver.UDSTransport{ + UDSName: "/etc/srv/kubernetes/konnectivity/konnectivity-server.socket", + }, + }, + }, + }, + }, + }, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + errs := ValidateEgressSelectorConfiguration(tc.contents) + if tc.expectError == false && len(errs) != 0 { + t.Errorf("Calling ValidateEgressSelectorConfiguration expected no error, got %v", errs) + } else if tc.expectError == true && len(errs) == 0 { + t.Errorf("Calling ValidateEgressSelectorConfiguration expected error, got no error") + } + }) + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go index 56d8fcc7a78..d333debefbe 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/egress_selector.go @@ -148,6 +148,7 @@ func createConnectTCPDialer(tcpTransport *apiserver.TCPTransport) (utilnet.DialF return nil, fmt.Errorf("failed to append CA cert to the cert pool") } } else { + // Use host's root CA set instead of providing our own certPool = nil } contextDialer := func(ctx context.Context, network, addr string) (net.Conn, error) { @@ -166,13 +167,13 @@ func createConnectTCPDialer(tcpTransport *apiserver.TCPTransport) (utilnet.DialF return contextDialer, nil } -func createConnectUDSDialer(udsName string) (utilnet.DialFunc, error) { +func createConnectUDSDialer(udsConfig *apiserver.UDSTransport) (utilnet.DialFunc, error) { contextDialer := func(ctx context.Context, network, addr string) (net.Conn, error) { - proxyConn, err := net.Dial("unix", udsName) + proxyConn, err := net.Dial("unix", udsConfig.UDSName) if err != nil { - return nil, fmt.Errorf("dialing proxy %q failed: %v", udsName, err) + return nil, fmt.Errorf("dialing proxy %q failed: %v", udsConfig.UDSName, err) } - return tunnelHTTPConnect(proxyConn, udsName, addr) + return tunnelHTTPConnect(proxyConn, udsConfig.UDSName, addr) } return contextDialer, nil } @@ -221,7 +222,7 @@ func NewEgressSelector(config *apiserver.EgressSelectorConfiguration) (*EgressSe case apiserver.ProtocolHTTPConnect: if service.Connection.Transport.UDS != nil { - contextDialer, err := createConnectUDSDialer(service.Connection.Transport.UDS.UDSName) + contextDialer, err := createConnectUDSDialer(service.Connection.Transport.UDS) if err != nil { return nil, fmt.Errorf("failed to create HTTPConnect uds dialer: %v", err) } @@ -233,7 +234,7 @@ func NewEgressSelector(config *apiserver.EgressSelectorConfiguration) (*EgressSe } cs.egressToDialer[name] = contextDialer } else { - return nil, fmt.Errorf("Either TCP or UDP transport must be specified") + return nil, fmt.Errorf("Either a TCP or UDS transport must be specified") } case apiserver.ProtocolGRPC: if service.Connection.Transport.UDS != nil { @@ -244,7 +245,7 @@ func NewEgressSelector(config *apiserver.EgressSelectorConfiguration) (*EgressSe cs.egressToDialer[name] = grpcContextDialer } else { - return nil, fmt.Errorf("Either TCP or UDP transport must be specified") + return nil, fmt.Errorf("UDS transport must be specified for GRPC") } case apiserver.ProtocolDirect: cs.egressToDialer[name] = directDialer