@@ -32,6 +32,22 @@ type cleanupFunc func()
3232
3333var immediateDeleteGracePeriod int64 = 0
3434
35+ func findLastEvent (events * corev1.EventList ) (event corev1.Event ) {
36+ var latestTime metav1.Time
37+ var latestInd int
38+ for i , item := range events .Items {
39+ if i != 0 {
40+ if latestTime .Before (& item .LastTimestamp ) {
41+ latestTime = item .LastTimestamp
42+ latestInd = i
43+ }
44+ } else {
45+ latestTime = item .LastTimestamp
46+ }
47+ }
48+ return events .Items [latestInd ]
49+ }
50+
3551func buildCSVCleanupFunc (t * testing.T , c operatorclient.ClientInterface , crc versioned.Interface , csv v1alpha1.ClusterServiceVersion , namespace string , deleteCRDs , deleteAPIServices bool ) cleanupFunc {
3652 return func () {
3753 require .NoError (t , crc .OperatorsV1alpha1 ().ClusterServiceVersions (namespace ).Delete (csv .GetName (), & metav1.DeleteOptions {}))
@@ -2703,4 +2719,221 @@ func TestUpdateCSVModifyDeploymentName(t *testing.T) {
27032719 require .NoError (t , err )
27042720}
27052721
2722+ func TestCreateCSVRequirementsEvents (t * testing.T ) {
2723+ defer cleaner .NotifyTestComplete (t , true )
2724+
2725+ c := newKubeClient (t )
2726+ crc := newCRClient (t )
2727+
2728+ sa := corev1.ServiceAccount {}
2729+ sa .SetName (genName ("sa-" ))
2730+ sa .SetNamespace (testNamespace )
2731+ _ , err := c .CreateServiceAccount (& sa )
2732+ require .NoError (t , err , "could not create ServiceAccount" )
2733+
2734+ permissions := []install.StrategyDeploymentPermissions {
2735+ {
2736+ ServiceAccountName : sa .GetName (),
2737+ Rules : []rbacv1.PolicyRule {
2738+ {
2739+ Verbs : []string {"create" },
2740+ APIGroups : []string {"" },
2741+ Resources : []string {"deployment" },
2742+ },
2743+ {
2744+ Verbs : []string {"delete" },
2745+ APIGroups : []string {"" },
2746+ Resources : []string {"deployment" },
2747+ },
2748+ },
2749+ },
2750+ }
2751+
2752+ clusterPermissions := []install.StrategyDeploymentPermissions {
2753+ {
2754+ ServiceAccountName : sa .GetName (),
2755+ Rules : []rbacv1.PolicyRule {
2756+ {
2757+ Verbs : []string {"get" },
2758+ APIGroups : []string {"" },
2759+ Resources : []string {"deployment" },
2760+ },
2761+ },
2762+ },
2763+ }
2764+
2765+ depName := genName ("dep-" )
2766+ csv := v1alpha1.ClusterServiceVersion {
2767+ TypeMeta : metav1.TypeMeta {
2768+ Kind : v1alpha1 .ClusterServiceVersionKind ,
2769+ APIVersion : v1alpha1 .ClusterServiceVersionAPIVersion ,
2770+ },
2771+ ObjectMeta : metav1.ObjectMeta {
2772+ Name : genName ("csv" ),
2773+ },
2774+ Spec : v1alpha1.ClusterServiceVersionSpec {
2775+ MinKubeVersion : "0.0.0" ,
2776+ InstallModes : []v1alpha1.InstallMode {
2777+ {
2778+ Type : v1alpha1 .InstallModeTypeOwnNamespace ,
2779+ Supported : true ,
2780+ },
2781+ {
2782+ Type : v1alpha1 .InstallModeTypeSingleNamespace ,
2783+ Supported : true ,
2784+ },
2785+ {
2786+ Type : v1alpha1 .InstallModeTypeMultiNamespace ,
2787+ Supported : true ,
2788+ },
2789+ {
2790+ Type : v1alpha1 .InstallModeTypeAllNamespaces ,
2791+ Supported : true ,
2792+ },
2793+ },
2794+ InstallStrategy : newNginxInstallStrategy (depName , permissions , clusterPermissions ),
2795+ // Cheating a little; this is an APIservice that will exist for the e2e tests
2796+ APIServiceDefinitions : v1alpha1.APIServiceDefinitions {
2797+ Required : []v1alpha1.APIServiceDescription {
2798+ {
2799+ Group : "packages.operators.coreos.com" ,
2800+ Version : "v1" ,
2801+ Kind : "PackageManifest" ,
2802+ DisplayName : "Package Manifest" ,
2803+ Description : "An apiservice that exists" ,
2804+ },
2805+ },
2806+ },
2807+ },
2808+ }
2809+
2810+ // Create Role/Cluster Roles and RoleBindings
2811+ role := rbacv1.Role {
2812+ Rules : []rbacv1.PolicyRule {
2813+ {
2814+ Verbs : []string {"create" },
2815+ APIGroups : []string {"" },
2816+ Resources : []string {"deployment" },
2817+ },
2818+ {
2819+ Verbs : []string {"delete" },
2820+ APIGroups : []string {"" },
2821+ Resources : []string {"deployment" },
2822+ },
2823+ },
2824+ }
2825+ role .SetName ("test-role" )
2826+ role .SetNamespace (testNamespace )
2827+ _ , err = c .CreateRole (& role )
2828+ require .NoError (t , err , "could not create Role" )
2829+
2830+ roleBinding := rbacv1.RoleBinding {
2831+ Subjects : []rbacv1.Subject {
2832+ {
2833+ Kind : "ServiceAccount" ,
2834+ APIGroup : "" ,
2835+ Name : sa .GetName (),
2836+ Namespace : sa .GetNamespace (),
2837+ },
2838+ },
2839+ RoleRef : rbacv1.RoleRef {
2840+ APIGroup : "rbac.authorization.k8s.io" ,
2841+ Kind : "Role" ,
2842+ Name : role .GetName (),
2843+ },
2844+ }
2845+ roleBinding .SetName (genName ("dep-" ))
2846+ roleBinding .SetNamespace (testNamespace )
2847+ _ , err = c .CreateRoleBinding (& roleBinding )
2848+ require .NoError (t , err , "could not create RoleBinding" )
2849+
2850+ clusterRole := rbacv1.ClusterRole {
2851+ Rules : []rbacv1.PolicyRule {
2852+ {
2853+ Verbs : []string {"get" },
2854+ APIGroups : []string {"" },
2855+ Resources : []string {"deployment" },
2856+ },
2857+ },
2858+ }
2859+ clusterRole .SetName (genName ("dep-" ))
2860+ _ , err = c .CreateClusterRole (& clusterRole )
2861+ require .NoError (t , err , "could not create ClusterRole" )
2862+
2863+ clusterRoleBinding := rbacv1.ClusterRoleBinding {
2864+ Subjects : []rbacv1.Subject {
2865+ {
2866+ Kind : "ServiceAccount" ,
2867+ APIGroup : "" ,
2868+ Name : sa .GetName (),
2869+ Namespace : sa .GetNamespace (),
2870+ },
2871+ },
2872+ RoleRef : rbacv1.RoleRef {
2873+ APIGroup : "rbac.authorization.k8s.io" ,
2874+ Kind : "ClusterRole" ,
2875+ Name : clusterRole .GetName (),
2876+ },
2877+ }
2878+ clusterRoleBinding .SetName (genName ("dep-" ))
2879+ _ , err = c .CreateClusterRoleBinding (& clusterRoleBinding )
2880+ require .NoError (t , err , "could not create ClusterRoleBinding" )
2881+
2882+ cleanupCSV , err := createCSV (t , c , crc , csv , testNamespace , false , false )
2883+ require .NoError (t , err )
2884+ defer cleanupCSV ()
2885+
2886+ _ , err = fetchCSV (t , crc , csv .Name , testNamespace , csvSucceededChecker )
2887+ require .NoError (t , err )
2888+
2889+ listOptions := metav1.ListOptions {
2890+ FieldSelector : "involvedObject.kind=ClusterServiceVersion" ,
2891+ }
2892+
2893+ // Get events from test namespace for CSV
2894+ eventsList , err := c .KubernetesInterface ().CoreV1 ().Events (testNamespace ).List (listOptions )
2895+ require .NoError (t , err )
2896+ latestEvent := findLastEvent (eventsList )
2897+ require .Equal (t , string (latestEvent .Reason ), "InstallSucceeded" )
2898+
2899+ // Edit role
2900+ updatedRole := rbacv1.Role {
2901+ Rules : []rbacv1.PolicyRule {
2902+ {
2903+ Verbs : []string {"create" },
2904+ APIGroups : []string {"" },
2905+ Resources : []string {"deployment" },
2906+ },
2907+ },
2908+ }
2909+ updatedRole .SetName ("test-role" )
2910+ updatedRole .SetNamespace (testNamespace )
2911+ _ , err = c .UpdateRole (& updatedRole )
2912+ require .NoError (t , err )
2913+
2914+ // Check CSV status
2915+ _ , err = fetchCSV (t , crc , csv .Name , testNamespace , csvPendingChecker )
2916+ require .NoError (t , err )
2917+
2918+ // Check event
2919+ eventsList , err = c .KubernetesInterface ().CoreV1 ().Events (testNamespace ).List (listOptions )
2920+ require .NoError (t , err )
2921+ latestEvent = findLastEvent (eventsList )
2922+ require .Equal (t , string (latestEvent .Reason ), "RequirementsNotMet" )
2923+
2924+ // Reverse the updated role
2925+ _ , err = c .UpdateRole (& role )
2926+ require .NoError (t , err )
2927+
2928+ // Check CSV status
2929+ _ , err = fetchCSV (t , crc , csv .Name , testNamespace , csvSucceededChecker )
2930+ require .NoError (t , err )
2931+
2932+ // Check event
2933+ eventsList , err = c .KubernetesInterface ().CoreV1 ().Events (testNamespace ).List (listOptions )
2934+ require .NoError (t , err )
2935+ latestEvent = findLastEvent (eventsList )
2936+ require .Equal (t , string (latestEvent .Reason ), "InstallSucceeded" )
2937+ }
2938+
27062939// TODO: test behavior when replaces field doesn't point to existing CSV
0 commit comments