2016-10-26 22:54:24 +00:00
/ *
Copyright 2016 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2017-07-11 06:44:46 +00:00
package network
2016-10-26 22:54:24 +00:00
import (
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
2017-10-17 16:14:31 +00:00
networkingv1 "k8s.io/api/networking/v1"
2016-10-26 22:54:24 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/test/e2e/framework"
2017-06-09 23:20:42 +00:00
imageutils "k8s.io/kubernetes/test/utils/image"
2016-10-26 22:54:24 +00:00
"fmt"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
/ *
The following Network Policy tests verify that policy object definitions
are correctly enforced by a networking plugin . It accomplishes this by launching
a simple netcat server , and two clients with different
attributes . Each test case creates a network policy which should only allow
connections from one of the clients . The test then asserts that the clients
2017-06-09 23:20:42 +00:00
failed or successfully connected as expected .
2016-10-26 22:54:24 +00:00
* /
2017-07-24 09:43:54 +00:00
var _ = SIGDescribe ( "NetworkPolicy" , func ( ) {
2017-06-09 23:20:42 +00:00
var service * v1 . Service
var podServer * v1 . Pod
2016-10-26 22:54:24 +00:00
f := framework . NewDefaultFramework ( "network-policy" )
2017-06-09 23:20:42 +00:00
Context ( "NetworkPolicy between server and client" , func ( ) {
BeforeEach ( func ( ) {
By ( "Creating a simple server that serves on port 80 and 81." )
podServer , service = createServerPodAndService ( f , f . Namespace , "server" , [ ] int { 80 , 81 } )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
By ( "Waiting for pod ready" , func ( ) {
err := f . WaitForPodReady ( podServer . Name )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
} )
2017-05-30 15:26:52 +00:00
2017-06-09 23:20:42 +00:00
// Create pods, which should be able to communicate with the server on port 80 and 81.
By ( "Testing pods can connect to both ports when no policy is present." )
testCanConnect ( f , f . Namespace , "client-can-connect-80" , service , 80 )
testCanConnect ( f , f . Namespace , "client-can-connect-81" , service , 81 )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
AfterEach ( func ( ) {
cleanupServerPodAndService ( f , podServer , service )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
It ( "should support a 'default-deny' policy [Feature:NetworkPolicy]" , func ( ) {
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "deny-all" ,
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
PodSelector : metav1 . LabelSelector { } ,
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { } ,
2017-06-09 23:20:42 +00:00
} ,
}
2016-10-26 22:54:24 +00:00
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
// Create a pod with name 'client-cannot-connect', which will attempt to communicate with the server,
// but should not be able to now that isolation is on.
testCannotConnect ( f , f . Namespace , "client-cannot-connect" , service , 80 )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
It ( "should enforce policy based on PodSelector [Feature:NetworkPolicy]" , func ( ) {
By ( "Creating a network policy for the server which allows traffic from the pod 'client-a'." )
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-client-a-via-pod-selector" ,
2016-10-26 22:54:24 +00:00
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Apply this policy to the Server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
2016-10-26 22:54:24 +00:00
} ,
2017-06-09 23:20:42 +00:00
} ,
// Allow traffic only from client-a
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
From : [ ] networkingv1 . NetworkPolicyPeer { {
2017-06-09 23:20:42 +00:00
PodSelector : & metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : "client-a" ,
} ,
} ,
} } ,
2016-10-26 22:54:24 +00:00
} } ,
2017-06-09 23:20:42 +00:00
} ,
}
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Creating client-a which should be able to contact the server." , func ( ) {
testCanConnect ( f , f . Namespace , "client-a" , service , 80 )
} )
By ( "Creating client-b which should not be able to contact the server." , func ( ) {
testCannotConnect ( f , f . Namespace , "client-b" , service , 80 )
} )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
It ( "should enforce policy based on NamespaceSelector [Feature:NetworkPolicy]" , func ( ) {
nsA := f . Namespace
nsBName := f . BaseName + "-b"
// The CreateNamespace helper uses the input name as a Name Generator, so the namespace itself
// will have a different name than what we are setting as the value of ns-name.
// This is fine as long as we don't try to match the label as nsB.Name in our policy.
nsB , err := f . CreateNamespace ( nsBName , map [ string ] string {
"ns-name" : nsBName ,
} )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
// Create Server with Service in NS-B
framework . Logf ( "Waiting for server to come up." )
err = framework . WaitForPodRunningInNamespace ( f . ClientSet , podServer )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
// Create Policy for that service that allows traffic only via namespace B
By ( "Creating a network policy for the server which allows traffic from namespace-b." )
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-ns-b-via-namespace-selector" ,
2016-10-26 22:54:24 +00:00
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Apply to server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
} ,
} ,
// Allow traffic only from NS-B
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
From : [ ] networkingv1 . NetworkPolicyPeer { {
2017-06-09 23:20:42 +00:00
NamespaceSelector : & metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"ns-name" : nsBName ,
} ,
} ,
} } ,
2016-10-26 22:54:24 +00:00
} } ,
2017-06-09 23:20:42 +00:00
} ,
}
2017-10-17 16:14:31 +00:00
policy , err = f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( nsA . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
testCannotConnect ( f , nsA , "client-a" , service , 80 )
testCanConnect ( f , nsB , "client-b" , service , 80 )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
It ( "should enforce policy based on Ports [Feature:NetworkPolicy]" , func ( ) {
By ( "Creating a network policy for the Service which allows traffic only to one port." )
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-ingress-on-port-81" ,
2016-10-26 22:54:24 +00:00
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Apply to server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
} ,
2016-10-26 22:54:24 +00:00
} ,
2017-06-09 23:20:42 +00:00
// Allow traffic only to one port.
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
Ports : [ ] networkingv1 . NetworkPolicyPort { {
2017-06-09 23:20:42 +00:00
Port : & intstr . IntOrString { IntVal : 81 } ,
} } ,
2016-10-26 22:54:24 +00:00
} } ,
} ,
2017-06-09 23:20:42 +00:00
}
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Testing pods can connect only to the port allowed by the policy." )
testCannotConnect ( f , f . Namespace , "client-a" , service , 80 )
testCanConnect ( f , f . Namespace , "client-b" , service , 81 )
2016-10-26 22:54:24 +00:00
} )
2017-06-09 23:20:42 +00:00
It ( "should enforce multiple, stacked policies with overlapping podSelectors [Feature:NetworkPolicy]" , func ( ) {
By ( "Creating a network policy for the Service which allows traffic only to one port." )
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-ingress-on-port-80" ,
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Apply to server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
} ,
2016-10-26 22:54:24 +00:00
} ,
2017-06-09 23:20:42 +00:00
// Allow traffic only to one port.
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
Ports : [ ] networkingv1 . NetworkPolicyPort { {
2017-06-09 23:20:42 +00:00
Port : & intstr . IntOrString { IntVal : 80 } ,
} } ,
} } ,
2016-10-26 22:54:24 +00:00
} ,
2017-06-09 23:20:42 +00:00
}
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Creating a network policy for the Service which allows traffic only to another port." )
2017-10-17 16:14:31 +00:00
policy2 := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-ingress-on-port-81" ,
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Apply to server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
2016-10-26 22:54:24 +00:00
} ,
2017-06-09 23:20:42 +00:00
} ,
// Allow traffic only to one port.
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
Ports : [ ] networkingv1 . NetworkPolicyPort { {
2017-06-09 23:20:42 +00:00
Port : & intstr . IntOrString { IntVal : 81 } ,
} } ,
2016-10-26 22:54:24 +00:00
} } ,
2017-06-09 23:20:42 +00:00
} ,
}
2017-10-17 16:14:31 +00:00
policy2 , err = f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy2 )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy2 )
By ( "Testing pods can connect to both ports when both policies are present." )
testCanConnect ( f , f . Namespace , "client-a" , service , 80 )
testCanConnect ( f , f . Namespace , "client-b" , service , 81 )
} )
2016-10-26 22:54:24 +00:00
2017-06-09 23:20:42 +00:00
It ( "should support allow-all policy [Feature:NetworkPolicy]" , func ( ) {
By ( "Creating a network policy which allows all traffic." )
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-06-09 23:20:42 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-all" ,
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-06-09 23:20:42 +00:00
// Allow all traffic
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string { } ,
} ,
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { { } } ,
2017-06-09 23:20:42 +00:00
} ,
}
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-06-09 23:20:42 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Testing pods can connect to both ports when an 'allow-all' policy is present." )
testCanConnect ( f , f . Namespace , "client-a" , service , 80 )
testCanConnect ( f , f . Namespace , "client-b" , service , 81 )
} )
2017-10-11 22:54:08 +00:00
It ( "should allow ingress access on one named port [Feature:NetworkPolicy]" , func ( ) {
2017-10-17 16:14:31 +00:00
policy := & networkingv1 . NetworkPolicy {
2017-10-11 22:54:08 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-client-a-via-named-port-ingress-rule" ,
} ,
2017-10-17 16:14:31 +00:00
Spec : networkingv1 . NetworkPolicySpec {
2017-10-11 22:54:08 +00:00
// Apply this policy to the Server
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : podServer . Name ,
} ,
} ,
// Allow traffic to only one named port: "serve-80".
2017-10-17 16:14:31 +00:00
Ingress : [ ] networkingv1 . NetworkPolicyIngressRule { {
Ports : [ ] networkingv1 . NetworkPolicyPort { {
2017-10-11 22:54:08 +00:00
Port : & intstr . IntOrString { Type : intstr . String , StrVal : "serve-80" } ,
} } ,
} } ,
} ,
}
2017-10-17 16:14:31 +00:00
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
2017-10-11 22:54:08 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Creating client-a which should be able to contact the server." , func ( ) {
testCanConnect ( f , f . Namespace , "client-a" , service , 80 )
} )
By ( "Creating client-b which should not be able to contact the server on port 81." , func ( ) {
testCannotConnect ( f , f . Namespace , "client-b" , service , 81 )
} )
} )
2017-11-06 22:17:13 +00:00
It ( "should allow egress access on one named port [Feature:NetworkPolicy]" , func ( ) {
clientPodName := "client-a"
protocolUDP := v1 . ProtocolUDP
policy := & networkingv1 . NetworkPolicy {
ObjectMeta : metav1 . ObjectMeta {
Name : "allow-client-a-via-named-port-egress-rule" ,
} ,
Spec : networkingv1 . NetworkPolicySpec {
// Apply this policy to client-a
PodSelector : metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"pod-name" : clientPodName ,
} ,
} ,
// Allow traffic to only one named port: "serve-80".
Egress : [ ] networkingv1 . NetworkPolicyEgressRule { {
Ports : [ ] networkingv1 . NetworkPolicyPort {
{
Port : & intstr . IntOrString { Type : intstr . String , StrVal : "serve-80" } ,
} ,
// Allow DNS look-ups
{
Protocol : & protocolUDP ,
Port : & intstr . IntOrString { Type : intstr . Int , IntVal : 53 } ,
} ,
} ,
} } ,
} ,
}
policy , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . Create ( policy )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
defer cleanupNetworkPolicy ( f , policy )
By ( "Creating client-a which should be able to contact the server." , func ( ) {
testCanConnect ( f , f . Namespace , clientPodName , service , 80 )
} )
By ( "Creating client-a which should not be able to contact the server on port 81." , func ( ) {
testCannotConnect ( f , f . Namespace , clientPodName , service , 81 )
} )
} )
2016-10-26 22:54:24 +00:00
} )
} )
func testCanConnect ( f * framework . Framework , ns * v1 . Namespace , podName string , service * v1 . Service , targetPort int ) {
By ( fmt . Sprintf ( "Creating client pod %s that should successfully connect to %s." , podName , service . Name ) )
podClient := createNetworkClientPod ( f , ns , podName , service , targetPort )
defer func ( ) {
By ( fmt . Sprintf ( "Cleaning up the pod %s" , podName ) )
2017-10-17 16:14:31 +00:00
if err := f . ClientSet . CoreV1 ( ) . Pods ( ns . Name ) . Delete ( podClient . Name , nil ) ; err != nil {
2016-10-26 22:54:24 +00:00
framework . Failf ( "unable to cleanup pod %v: %v" , podClient . Name , err )
}
} ( )
framework . Logf ( "Waiting for %s to complete." , podClient . Name )
err := framework . WaitForPodNoLongerRunningInNamespace ( f . ClientSet , podClient . Name , ns . Name )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Pod did not finish as expected." )
framework . Logf ( "Waiting for %s to complete." , podClient . Name )
err = framework . WaitForPodSuccessInNamespace ( f . ClientSet , podClient . Name , ns . Name )
2017-06-09 23:20:42 +00:00
if err != nil {
// Collect pod logs when we see a failure.
logs , logErr := framework . GetPodLogs ( f . ClientSet , f . Namespace . Name , podName , fmt . Sprintf ( "%s-container" , podName ) )
if logErr != nil {
framework . Failf ( "Error getting container logs: %s" , logErr )
}
// Collect current NetworkPolicies applied in the test namespace.
2017-10-17 16:14:31 +00:00
policies , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . List ( metav1 . ListOptions { } )
2017-06-09 23:20:42 +00:00
if err != nil {
framework . Logf ( "error getting current NetworkPolicies for %s namespace: %s" , f . Namespace . Name , err )
}
// Collect the list of pods running in the test namespace.
podsInNS , err := framework . GetPodsInNamespace ( f . ClientSet , f . Namespace . Name , map [ string ] string { } )
if err != nil {
framework . Logf ( "error getting pods for %s namespace: %s" , f . Namespace . Name , err )
}
pods := [ ] string { }
for _ , p := range podsInNS {
pods = append ( pods , fmt . Sprintf ( "Pod: %s, Status: %s\n" , p . Name , p . Status . String ( ) ) )
}
framework . Failf ( "Pod %s should be able to connect to service %s, but was not able to connect.\nPod logs:\n%s\n\n Current NetworkPolicies:\n\t%v\n\n Pods:\n\t%v\n\n" , podName , service . Name , logs , policies . Items , pods )
// Dump debug information for the test namespace.
framework . DumpDebugInfo ( f . ClientSet , f . Namespace . Name )
}
2016-10-26 22:54:24 +00:00
}
func testCannotConnect ( f * framework . Framework , ns * v1 . Namespace , podName string , service * v1 . Service , targetPort int ) {
By ( fmt . Sprintf ( "Creating client pod %s that should not be able to connect to %s." , podName , service . Name ) )
podClient := createNetworkClientPod ( f , ns , podName , service , targetPort )
defer func ( ) {
By ( fmt . Sprintf ( "Cleaning up the pod %s" , podName ) )
2017-10-17 16:14:31 +00:00
if err := f . ClientSet . CoreV1 ( ) . Pods ( ns . Name ) . Delete ( podClient . Name , nil ) ; err != nil {
2016-10-26 22:54:24 +00:00
framework . Failf ( "unable to cleanup pod %v: %v" , podClient . Name , err )
}
} ( )
framework . Logf ( "Waiting for %s to complete." , podClient . Name )
err := framework . WaitForPodSuccessInNamespace ( f . ClientSet , podClient . Name , ns . Name )
2017-06-09 23:20:42 +00:00
// We expect an error here since it's a cannot connect test.
// Dump debug information if the error was nil.
if err == nil {
// Collect pod logs when we see a failure.
logs , logErr := framework . GetPodLogs ( f . ClientSet , f . Namespace . Name , podName , fmt . Sprintf ( "%s-container" , podName ) )
if logErr != nil {
framework . Failf ( "Error getting container logs: %s" , logErr )
}
// Collect current NetworkPolicies applied in the test namespace.
2017-10-17 16:14:31 +00:00
policies , err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( f . Namespace . Name ) . List ( metav1 . ListOptions { } )
2017-06-09 23:20:42 +00:00
if err != nil {
framework . Logf ( "error getting current NetworkPolicies for %s namespace: %s" , f . Namespace . Name , err )
}
// Collect the list of pods running in the test namespace.
podsInNS , err := framework . GetPodsInNamespace ( f . ClientSet , f . Namespace . Name , map [ string ] string { } )
if err != nil {
framework . Logf ( "error getting pods for %s namespace: %s" , f . Namespace . Name , err )
}
pods := [ ] string { }
for _ , p := range podsInNS {
pods = append ( pods , fmt . Sprintf ( "Pod: %s, Status: %s\n" , p . Name , p . Status . String ( ) ) )
}
framework . Failf ( "Pod %s should not be able to connect to service %s, but was able to connect.\nPod logs:\n%s\n\n Current NetworkPolicies:\n\t%v\n\n Pods:\n\t %v\n\n" , podName , service . Name , logs , policies . Items , pods )
// Dump debug information for the test namespace.
framework . DumpDebugInfo ( f . ClientSet , f . Namespace . Name )
}
2016-10-26 22:54:24 +00:00
}
// Create a server pod with a listening container for each port in ports[].
// Will also assign a pod label with key: "pod-name" and label set to the given podname for later use by the network
// policy.
func createServerPodAndService ( f * framework . Framework , namespace * v1 . Namespace , podName string , ports [ ] int ) ( * v1 . Pod , * v1 . Service ) {
// Because we have a variable amount of ports, we'll first loop through and generate our Containers for our pod,
// and ServicePorts.for our Service.
containers := [ ] v1 . Container { }
servicePorts := [ ] v1 . ServicePort { }
for _ , port := range ports {
// Build the containers for the server pod.
containers = append ( containers , v1 . Container {
Name : fmt . Sprintf ( "%s-container-%d" , podName , port ) ,
2017-06-09 23:20:42 +00:00
Image : imageutils . GetE2EImage ( imageutils . Porter ) ,
Env : [ ] v1 . EnvVar {
{
Name : fmt . Sprintf ( "SERVE_PORT_%d" , port ) ,
Value : "foo" ,
} ,
2016-10-26 22:54:24 +00:00
} ,
2017-10-11 22:54:08 +00:00
Ports : [ ] v1 . ContainerPort {
{
ContainerPort : int32 ( port ) ,
Name : fmt . Sprintf ( "serve-%d" , port ) ,
} ,
} ,
2017-06-09 23:20:42 +00:00
ReadinessProbe : & v1 . Probe {
Handler : v1 . Handler {
HTTPGet : & v1 . HTTPGetAction {
Path : "/" ,
Port : intstr . IntOrString {
IntVal : int32 ( port ) ,
} ,
Scheme : v1 . URISchemeHTTP ,
} ,
} ,
} ,
2016-10-26 22:54:24 +00:00
} )
// Build the Service Ports for the service.
servicePorts = append ( servicePorts , v1 . ServicePort {
Name : fmt . Sprintf ( "%s-%d" , podName , port ) ,
Port : int32 ( port ) ,
TargetPort : intstr . FromInt ( port ) ,
} )
}
By ( fmt . Sprintf ( "Creating a server pod %s in namespace %s" , podName , namespace . Name ) )
2017-10-17 16:14:31 +00:00
pod , err := f . ClientSet . CoreV1 ( ) . Pods ( namespace . Name ) . Create ( & v1 . Pod {
2016-10-26 22:54:24 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : podName ,
Labels : map [ string ] string {
"pod-name" : podName ,
} ,
} ,
Spec : v1 . PodSpec {
Containers : containers ,
RestartPolicy : v1 . RestartPolicyNever ,
} ,
} )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
framework . Logf ( "Created pod %v" , pod . ObjectMeta . Name )
svcName := fmt . Sprintf ( "svc-%s" , podName )
By ( fmt . Sprintf ( "Creating a service %s for pod %s in namespace %s" , svcName , podName , namespace . Name ) )
2017-10-17 16:14:31 +00:00
svc , err := f . ClientSet . CoreV1 ( ) . Services ( namespace . Name ) . Create ( & v1 . Service {
2016-10-26 22:54:24 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : svcName ,
} ,
Spec : v1 . ServiceSpec {
Ports : servicePorts ,
Selector : map [ string ] string {
"pod-name" : podName ,
} ,
} ,
} )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
framework . Logf ( "Created service %s" , svc . Name )
return pod , svc
}
2017-05-29 18:08:49 +00:00
func cleanupServerPodAndService ( f * framework . Framework , pod * v1 . Pod , service * v1 . Service ) {
By ( "Cleaning up the server." )
2017-10-17 16:14:31 +00:00
if err := f . ClientSet . CoreV1 ( ) . Pods ( pod . Namespace ) . Delete ( pod . Name , nil ) ; err != nil {
2017-05-29 18:08:49 +00:00
framework . Failf ( "unable to cleanup pod %v: %v" , pod . Name , err )
}
By ( "Cleaning up the server's service." )
2017-10-17 16:14:31 +00:00
if err := f . ClientSet . CoreV1 ( ) . Services ( service . Namespace ) . Delete ( service . Name , nil ) ; err != nil {
2017-05-29 18:08:49 +00:00
framework . Failf ( "unable to cleanup svc %v: %v" , service . Name , err )
}
}
2016-10-26 22:54:24 +00:00
// Create a client pod which will attempt a netcat to the provided service, on the specified port.
2017-06-09 23:20:42 +00:00
// This client will attempt a one-shot connection, then die, without restarting the pod.
2016-10-26 22:54:24 +00:00
// Test can then be asserted based on whether the pod quit with an error or not.
func createNetworkClientPod ( f * framework . Framework , namespace * v1 . Namespace , podName string , targetService * v1 . Service , targetPort int ) * v1 . Pod {
2017-10-17 16:14:31 +00:00
pod , err := f . ClientSet . CoreV1 ( ) . Pods ( namespace . Name ) . Create ( & v1 . Pod {
2016-10-26 22:54:24 +00:00
ObjectMeta : metav1 . ObjectMeta {
Name : podName ,
Labels : map [ string ] string {
"pod-name" : podName ,
} ,
} ,
Spec : v1 . PodSpec {
RestartPolicy : v1 . RestartPolicyNever ,
Containers : [ ] v1 . Container {
{
Name : fmt . Sprintf ( "%s-container" , podName ) ,
2018-08-07 01:18:35 +00:00
Image : imageutils . GetE2EImage ( imageutils . BusyBox ) ,
2016-10-26 22:54:24 +00:00
Args : [ ] string {
"/bin/sh" ,
"-c" ,
2018-10-08 22:17:10 +00:00
fmt . Sprintf ( "for i in $(seq 1 5); do curl -s -m 8 %s.%s:%d && exit 0 || sleep 1; done; exit 1" ,
2017-06-09 23:20:42 +00:00
targetService . Name , targetService . Namespace , targetPort ) ,
2016-10-26 22:54:24 +00:00
} ,
} ,
} ,
} ,
} )
Expect ( err ) . NotTo ( HaveOccurred ( ) )
2017-06-09 23:20:42 +00:00
2016-10-26 22:54:24 +00:00
return pod
}
2017-10-17 16:14:31 +00:00
func cleanupNetworkPolicy ( f * framework . Framework , policy * networkingv1 . NetworkPolicy ) {
2017-05-29 18:08:49 +00:00
By ( "Cleaning up the policy." )
2017-10-17 16:14:31 +00:00
if err := f . ClientSet . NetworkingV1 ( ) . NetworkPolicies ( policy . Namespace ) . Delete ( policy . Name , nil ) ; err != nil {
2017-05-29 18:08:49 +00:00
framework . Failf ( "unable to cleanup policy %v: %v" , policy . Name , err )
}
}