2017-06-02 20:14:27 +00:00
/ *
Copyright 2017 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2017-07-12 17:00:58 +00:00
package apimachinery
2017-06-02 20:14:27 +00:00
import (
"bytes"
2018-09-07 09:17:27 +00:00
"context"
2017-06-02 20:14:27 +00:00
"fmt"
"text/tabwriter"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
2018-02-05 03:38:39 +00:00
authorizationv1 "k8s.io/api/authorization/v1"
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
2017-06-02 20:14:27 +00:00
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2018-01-30 18:30:57 +00:00
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
2017-11-16 02:01:49 +00:00
"k8s.io/client-go/util/workqueue"
2018-02-05 03:38:39 +00:00
2018-09-21 05:06:51 +00:00
utilversion "k8s.io/apimachinery/pkg/util/version"
2018-09-21 06:03:05 +00:00
"k8s.io/kubernetes/pkg/printers"
2017-06-02 20:14:27 +00:00
"k8s.io/kubernetes/test/e2e/framework"
2017-08-29 08:32:08 +00:00
imageutils "k8s.io/kubernetes/test/utils/image"
2017-06-02 20:14:27 +00:00
)
2018-03-05 16:52:51 +00:00
var serverPrintVersion = utilversion . MustParseSemantic ( "v1.10.0" )
2017-07-12 17:00:58 +00:00
var _ = SIGDescribe ( "Servers with support for Table transformation" , func ( ) {
2017-06-02 20:14:27 +00:00
f := framework . NewDefaultFramework ( "tables" )
2018-03-05 16:52:51 +00:00
BeforeEach ( func ( ) {
framework . SkipUnlessServerVersionGTE ( serverPrintVersion , f . ClientSet . Discovery ( ) )
} )
2017-06-02 20:14:27 +00:00
It ( "should return pod details" , func ( ) {
ns := f . Namespace . Name
c := f . ClientSet
podName := "pod-1"
framework . Logf ( "Creating pod %s" , podName )
2017-10-25 15:54:32 +00:00
_ , err := c . CoreV1 ( ) . Pods ( ns ) . Create ( newTablePod ( podName ) )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to create pod %s in namespace: %s" , podName , ns )
2017-06-02 20:14:27 +00:00
2018-01-30 18:30:57 +00:00
table := & metav1beta1 . Table { }
err = c . CoreV1 ( ) . RESTClient ( ) . Get ( ) . Resource ( "pods" ) . Namespace ( ns ) . Name ( podName ) . SetHeader ( "Accept" , "application/json;as=Table;v=v1beta1;g=meta.k8s.io" ) . Do ( ) . Into ( table )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to get pod %s in Table form in namespace: %s" , podName , ns )
2017-06-02 20:14:27 +00:00
framework . Logf ( "Table: %#v" , table )
Expect ( len ( table . ColumnDefinitions ) ) . To ( BeNumerically ( ">" , 2 ) )
Expect ( len ( table . Rows ) ) . To ( Equal ( 1 ) )
Expect ( len ( table . Rows [ 0 ] . Cells ) ) . To ( Equal ( len ( table . ColumnDefinitions ) ) )
Expect ( table . ColumnDefinitions [ 0 ] . Name ) . To ( Equal ( "Name" ) )
Expect ( table . Rows [ 0 ] . Cells [ 0 ] ) . To ( Equal ( podName ) )
out := printTable ( table )
Expect ( out ) . To ( MatchRegexp ( "^NAME\\s" ) )
Expect ( out ) . To ( MatchRegexp ( "\npod-1\\s" ) )
framework . Logf ( "Table:\n%s" , out )
} )
2017-11-16 02:01:49 +00:00
It ( "should return chunks of table results for list calls" , func ( ) {
ns := f . Namespace . Name
c := f . ClientSet
client := c . CoreV1 ( ) . PodTemplates ( ns )
By ( "creating a large number of resources" )
2018-09-07 09:17:27 +00:00
workqueue . ParallelizeUntil ( context . TODO ( ) , 5 , 20 , func ( i int ) {
2017-11-16 02:01:49 +00:00
for tries := 3 ; tries >= 0 ; tries -- {
_ , err := client . Create ( & v1 . PodTemplate {
ObjectMeta : metav1 . ObjectMeta {
Name : fmt . Sprintf ( "template-%04d" , i ) ,
} ,
Template : v1 . PodTemplateSpec {
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container {
{ Name : "test" , Image : "test2" } ,
} ,
} ,
} ,
} )
if err == nil {
return
}
framework . Logf ( "Got an error creating template %d: %v" , i , err )
}
Fail ( "Unable to create template %d, exiting" , i )
} )
2018-01-30 18:30:57 +00:00
pagedTable := & metav1beta1 . Table { }
2017-11-16 02:01:49 +00:00
err := c . CoreV1 ( ) . RESTClient ( ) . Get ( ) . Namespace ( ns ) . Resource ( "podtemplates" ) .
VersionedParams ( & metav1 . ListOptions { Limit : 2 } , metav1 . ParameterCodec ) .
2018-01-30 18:30:57 +00:00
SetHeader ( "Accept" , "application/json;as=Table;v=v1beta1;g=meta.k8s.io" ) .
2017-11-16 02:01:49 +00:00
Do ( ) . Into ( pagedTable )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to get pod templates in Table form in namespace: %s" , ns )
2017-11-16 02:01:49 +00:00
Expect ( len ( pagedTable . Rows ) ) . To ( Equal ( 2 ) )
Expect ( pagedTable . ResourceVersion ) . ToNot ( Equal ( "" ) )
Expect ( pagedTable . SelfLink ) . ToNot ( Equal ( "" ) )
Expect ( pagedTable . Continue ) . ToNot ( Equal ( "" ) )
Expect ( pagedTable . Rows [ 0 ] . Cells [ 0 ] ) . To ( Equal ( "template-0000" ) )
Expect ( pagedTable . Rows [ 1 ] . Cells [ 0 ] ) . To ( Equal ( "template-0001" ) )
err = c . CoreV1 ( ) . RESTClient ( ) . Get ( ) . Namespace ( ns ) . Resource ( "podtemplates" ) .
VersionedParams ( & metav1 . ListOptions { Continue : pagedTable . Continue } , metav1 . ParameterCodec ) .
2018-01-30 18:30:57 +00:00
SetHeader ( "Accept" , "application/json;as=Table;v=v1beta1;g=meta.k8s.io" ) .
2017-11-16 02:01:49 +00:00
Do ( ) . Into ( pagedTable )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to get pod templates in Table form in namespace: %s" , ns )
2017-11-16 02:01:49 +00:00
Expect ( len ( pagedTable . Rows ) ) . To ( BeNumerically ( ">" , 0 ) )
Expect ( pagedTable . Rows [ 0 ] . Cells [ 0 ] ) . To ( Equal ( "template-0002" ) )
} )
2017-06-02 20:14:27 +00:00
It ( "should return generic metadata details across all namespaces for nodes" , func ( ) {
c := f . ClientSet
2018-01-30 18:30:57 +00:00
table := & metav1beta1 . Table { }
err := c . CoreV1 ( ) . RESTClient ( ) . Get ( ) . Resource ( "nodes" ) . SetHeader ( "Accept" , "application/json;as=Table;v=v1beta1;g=meta.k8s.io" ) . Do ( ) . Into ( table )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to get nodes in Table form across all namespaces" )
2017-06-02 20:14:27 +00:00
framework . Logf ( "Table: %#v" , table )
Expect ( len ( table . ColumnDefinitions ) ) . To ( BeNumerically ( ">=" , 2 ) )
Expect ( len ( table . Rows ) ) . To ( BeNumerically ( ">=" , 1 ) )
Expect ( len ( table . Rows [ 0 ] . Cells ) ) . To ( Equal ( len ( table . ColumnDefinitions ) ) )
Expect ( table . ColumnDefinitions [ 0 ] . Name ) . To ( Equal ( "Name" ) )
2017-11-16 02:01:49 +00:00
Expect ( table . ResourceVersion ) . ToNot ( Equal ( "" ) )
Expect ( table . SelfLink ) . ToNot ( Equal ( "" ) )
2017-06-02 20:14:27 +00:00
out := printTable ( table )
Expect ( out ) . To ( MatchRegexp ( "^NAME\\s" ) )
framework . Logf ( "Table:\n%s" , out )
} )
It ( "should return a 406 for a backend which does not implement metadata" , func ( ) {
c := f . ClientSet
2018-01-30 18:30:57 +00:00
table := & metav1beta1 . Table { }
2018-02-05 03:38:39 +00:00
sar := & authorizationv1 . SelfSubjectAccessReview {
Spec : authorizationv1 . SelfSubjectAccessReviewSpec {
NonResourceAttributes : & authorizationv1 . NonResourceAttributes {
Path : "/" ,
Verb : "get" ,
} ,
} ,
}
err := c . AuthorizationV1 ( ) . RESTClient ( ) . Post ( ) . Resource ( "selfsubjectaccessreviews" ) . SetHeader ( "Accept" , "application/json;as=Table;v=v1beta1;g=meta.k8s.io" ) . Body ( sar ) . Do ( ) . Into ( table )
2018-10-07 05:01:43 +00:00
Expect ( err ) . To ( HaveOccurred ( ) , "failed to return error when posting self subject access review: %+v, to a backend that does not implement metadata" , sar )
2017-06-02 20:14:27 +00:00
Expect ( err . ( errors . APIStatus ) . Status ( ) . Code ) . To ( Equal ( int32 ( 406 ) ) )
} )
} )
2018-01-30 18:30:57 +00:00
func printTable ( table * metav1beta1 . Table ) string {
2017-06-02 20:14:27 +00:00
buf := & bytes . Buffer { }
tw := tabwriter . NewWriter ( buf , 5 , 8 , 1 , ' ' , 0 )
err := printers . PrintTable ( table , tw , printers . PrintOptions { } )
2018-10-07 05:01:43 +00:00
Expect ( err ) . NotTo ( HaveOccurred ( ) , "failed to print table: %+v" , table )
2017-06-02 20:14:27 +00:00
tw . Flush ( )
return buf . String ( )
}
2017-07-12 17:00:58 +00:00
func newTablePod ( podName string ) * v1 . Pod {
2017-06-02 20:14:27 +00:00
containerName := fmt . Sprintf ( "%s-container" , podName )
port := 8080
pod := & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : podName ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container {
{
Name : containerName ,
2017-08-29 08:32:08 +00:00
Image : imageutils . GetE2EImage ( imageutils . Porter ) ,
2017-06-02 20:14:27 +00:00
Env : [ ] v1 . EnvVar { { Name : fmt . Sprintf ( "SERVE_PORT_%d" , port ) , Value : "foo" } } ,
Ports : [ ] v1 . ContainerPort { { ContainerPort : int32 ( port ) } } ,
} ,
} ,
RestartPolicy : v1 . RestartPolicyNever ,
} ,
}
return pod
}