@@ -2803,6 +2803,267 @@ var _ = Describe("Install Plan", func() {
2803
2803
Expect (ref .Kind ).To (Equal ("ConfigMap" ))
2804
2804
}
2805
2805
})
2806
+ It ("uses the OLM client when installing CRDs from a bundle" , func () {
2807
+ c := newKubeClient ()
2808
+ crc := newCRClient ()
2809
+
2810
+ By ("creating a scoped serviceaccount specifified in the operatorgroup" )
2811
+ ns , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (context .TODO (), & corev1.Namespace {
2812
+ ObjectMeta : metav1.ObjectMeta {
2813
+ Name : genName ("ns-" ),
2814
+ },
2815
+ }, metav1.CreateOptions {})
2816
+ Expect (err ).ToNot (HaveOccurred ())
2817
+ defer c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (context .TODO (), ns .GetName (), metav1.DeleteOptions {})
2818
+
2819
+ // create SA
2820
+ sa := & corev1.ServiceAccount {
2821
+ ObjectMeta : metav1.ObjectMeta {
2822
+ Name : genName ("sa-" ),
2823
+ Namespace : ns .GetName (),
2824
+ },
2825
+ }
2826
+ _ , err = c .KubernetesInterface ().CoreV1 ().ServiceAccounts (ns .GetName ()).Create (context .TODO (), sa , metav1.CreateOptions {})
2827
+ Expect (err ).ToNot (HaveOccurred ())
2828
+
2829
+ // create role that includes permission for installing the kiali operator, but not CRDs
2830
+ // see https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/scoped-operator-install.md
2831
+ role := & rbacv1.ClusterRole {
2832
+ ObjectMeta : metav1.ObjectMeta {
2833
+ Name : genName ("role-" ),
2834
+ },
2835
+ Rules : []rbacv1.PolicyRule {
2836
+ {
2837
+ APIGroups : []string {"operators.coreos.com" },
2838
+ Resources : []string {"subscriptions" , "clusterserviceversions" },
2839
+ Verbs : []string {"get" , "create" , "update" , "patch" },
2840
+ },
2841
+ {
2842
+ APIGroups : []string {"" },
2843
+ Resources : []string {"services" , "serviceaccounts" , "configmaps" , "endpoints" , "events" , "persistentvolumeclaims" , "pods" },
2844
+ Verbs : []string {"create" , "delete" , "get" , "list" , "update" , "patch" , "watch" },
2845
+ },
2846
+ {
2847
+ APIGroups : []string {"" },
2848
+ Resources : []string {"namespaces" , "nodes" , "pods/log" , "replicationcontrollers" },
2849
+ Verbs : []string {"list" , "get" , "patch" , "watch" },
2850
+ },
2851
+ {
2852
+ APIGroups : []string {"apps" },
2853
+ Resources : []string {"deployments" , "replicasets" , "statefulsets" },
2854
+ Verbs : []string {"list" , "watch" , "get" , "create" , "update" , "patch" , "delete" },
2855
+ },
2856
+ {
2857
+ APIGroups : []string {"monitoring.coreos.com" },
2858
+ Resources : []string {"servicemonitors" },
2859
+ Verbs : []string {"create" , "get" },
2860
+ },
2861
+ {
2862
+ APIGroups : []string {"apps" },
2863
+ Resources : []string {"deployments/finalizers" },
2864
+ ResourceNames : []string {"kiali-operator" },
2865
+ Verbs : []string {"update" },
2866
+ },
2867
+ {
2868
+ APIGroups : []string {"kiali.io" },
2869
+ Resources : []string {"*" },
2870
+ Verbs : []string {"*" },
2871
+ },
2872
+ {
2873
+ APIGroups : []string {"rbac.authorization.k8s.io" },
2874
+ Resources : []string {"*" },
2875
+ Verbs : []string {"*" },
2876
+ },
2877
+ {
2878
+ // ability to get and list CRDs, but not create CRDs
2879
+ APIGroups : []string {"apiextensions.k8s.io" },
2880
+ Resources : []string {"customresourcedefinitions" },
2881
+ Verbs : []string {"get" , "list" , "watch" },
2882
+ },
2883
+ {
2884
+ APIGroups : []string {"extensions" },
2885
+ Resources : []string {"*" },
2886
+ Verbs : []string {"*" },
2887
+ },
2888
+ {
2889
+ APIGroups : []string {"route.openshift.io" },
2890
+ Resources : []string {"routes" },
2891
+ Verbs : []string {"*" },
2892
+ },
2893
+ {
2894
+ APIGroups : []string {"oauth.openshift.io" },
2895
+ Resources : []string {"oauthclients" },
2896
+ Verbs : []string {"*" },
2897
+ },
2898
+ {
2899
+ APIGroups : []string {"monitoring.kiali.io" },
2900
+ Resources : []string {"monitoringdashboards" },
2901
+ Verbs : []string {"*" },
2902
+ },
2903
+ {
2904
+ APIGroups : []string {"autoscaling" },
2905
+ Resources : []string {"horizontalpodautoscalers" },
2906
+ Verbs : []string {"get" , "list" , "watch" },
2907
+ },
2908
+ {
2909
+ APIGroups : []string {"batch" },
2910
+ Resources : []string {"*" },
2911
+ Verbs : []string {"*" },
2912
+ },
2913
+ {
2914
+ APIGroups : []string {"config.istio.io" },
2915
+ Resources : []string {"*" },
2916
+ Verbs : []string {"*" },
2917
+ },
2918
+ {
2919
+ APIGroups : []string {"networking.istio.io" },
2920
+ Resources : []string {"*" },
2921
+ Verbs : []string {"*" },
2922
+ },
2923
+ {
2924
+ APIGroups : []string {"authentication.istio.io" },
2925
+ Resources : []string {"*" },
2926
+ Verbs : []string {"*" },
2927
+ },
2928
+ {
2929
+ APIGroups : []string {"rbac.istio.io" },
2930
+ Resources : []string {"*" },
2931
+ Verbs : []string {"*" },
2932
+ },
2933
+ {
2934
+ APIGroups : []string {"authentication.maistra.io" },
2935
+ Resources : []string {"servicemeshpolicies" },
2936
+ Verbs : []string {"*" },
2937
+ },
2938
+ {
2939
+ APIGroups : []string {"rbac.maistra.io" },
2940
+ Resources : []string {"servicemeshrbacconfigs" },
2941
+ Verbs : []string {"*" },
2942
+ },
2943
+ {
2944
+ APIGroups : []string {"apps.openshift.io" },
2945
+ Resources : []string {"deploymentconfigs" },
2946
+ Verbs : []string {"*" },
2947
+ },
2948
+ {
2949
+ APIGroups : []string {"project.openshift.io" },
2950
+ Resources : []string {"projects" },
2951
+ Verbs : []string {"get" },
2952
+ },
2953
+ {
2954
+ APIGroups : []string {"route.openshift.io" },
2955
+ Resources : []string {"routes" },
2956
+ Verbs : []string {"get" },
2957
+ },
2958
+ {
2959
+ APIGroups : []string {"monitoring.kiali.io" },
2960
+ Resources : []string {"monitoringdashboards" },
2961
+ Verbs : []string {"get" , "list" },
2962
+ },
2963
+ },
2964
+ }
2965
+
2966
+ _ , err = c .KubernetesInterface ().RbacV1 ().ClusterRoles ().Create (context .TODO (), role , metav1.CreateOptions {})
2967
+ Expect (err ).ToNot (HaveOccurred ())
2968
+
2969
+ // bind role to SA
2970
+ rb := & rbacv1.ClusterRoleBinding {
2971
+ ObjectMeta : metav1.ObjectMeta {
2972
+ Name : genName ("rb-" ),
2973
+ },
2974
+ RoleRef : rbacv1.RoleRef {
2975
+ Name : role .GetName (),
2976
+ Kind : "ClusterRole" ,
2977
+ APIGroup : "rbac.authorization.k8s.io" ,
2978
+ },
2979
+ Subjects : []rbacv1.Subject {
2980
+ {
2981
+ Kind : "ServiceAccount" ,
2982
+ Name : sa .GetName (),
2983
+ APIGroup : "" ,
2984
+ Namespace : sa .GetNamespace (),
2985
+ },
2986
+ },
2987
+ }
2988
+
2989
+ _ , err = c .KubernetesInterface ().RbacV1 ().ClusterRoleBindings ().Create (context .TODO (), rb , metav1.CreateOptions {})
2990
+ Expect (err ).ToNot (HaveOccurred ())
2991
+ defer c .KubernetesInterface ().RbacV1 ().ClusterRoles ().Delete (context .TODO (), role .GetName (), metav1.DeleteOptions {})
2992
+
2993
+ // create operator group referencing the SA
2994
+ og := & operatorsv1.OperatorGroup {
2995
+ ObjectMeta : metav1.ObjectMeta {
2996
+ Name : genName ("og-" ),
2997
+ Namespace : ns .GetName (),
2998
+ },
2999
+ Spec : operatorsv1.OperatorGroupSpec {
3000
+ ServiceAccountName : sa .GetName (),
3001
+ },
3002
+ }
3003
+ _ , err = crc .OperatorsV1 ().OperatorGroups (ns .GetName ()).Create (context .TODO (), og , metav1.CreateOptions {})
3004
+ Expect (err ).ToNot (HaveOccurred ())
3005
+
3006
+ By ("using the OLM client to install CRDs from the bundle and the scoped client for other resources" )
3007
+ // create catalog and subscription
3008
+ catsrc := & operatorsv1alpha1.CatalogSource {
3009
+ ObjectMeta : metav1.ObjectMeta {
3010
+ Name : genName ("kiali-" ),
3011
+ Namespace : ns .GetName (),
3012
+ Labels : map [string ]string {"olm.catalogSource" : "kaili-catalog" },
3013
+ },
3014
+ Spec : operatorsv1alpha1.CatalogSourceSpec {
3015
+ Image : "quay.io/olmtest/single-bundle-index:1.0.0" ,
3016
+ SourceType : operatorsv1alpha1 .SourceTypeGrpc ,
3017
+ },
3018
+ }
3019
+ catsrc , err = crc .OperatorsV1alpha1 ().CatalogSources (catsrc .GetNamespace ()).Create (context .TODO (), catsrc , metav1.CreateOptions {})
3020
+ Expect (err ).ToNot (HaveOccurred ())
3021
+ defer crc .OperatorsV1alpha1 ().CatalogSources (catsrc .GetNamespace ()).Delete (context .TODO (), catsrc .GetName (), metav1.DeleteOptions {})
3022
+
3023
+ // Wait for the CatalogSource to be ready
3024
+ catsrc , err = fetchCatalogSourceOnStatus (crc , catsrc .GetName (), catsrc .GetNamespace (), catalogSourceRegistryPodSynced )
3025
+ Expect (err ).ToNot (HaveOccurred ())
3026
+
3027
+ // Generate a Subscription
3028
+ subName := genName ("kiali-" )
3029
+ subCleanup := createSubscriptionForCatalog (crc , catsrc .GetNamespace (), subName , catsrc .GetName (), "kiali" , stableChannel , "" , operatorsv1alpha1 .ApprovalAutomatic )
3030
+ defer subCleanup ()
3031
+
3032
+ sub , err := fetchSubscription (crc , catsrc .GetNamespace (), subName , subscriptionHasInstallPlanChecker )
3033
+ Expect (err ).ToNot (HaveOccurred ())
3034
+
3035
+ // Wait for the expected InstallPlan's execution to succeed
3036
+ ipName := sub .Status .InstallPlanRef .Name
3037
+ ip , err := waitForInstallPlan (crc , ipName , sub .GetNamespace (), buildInstallPlanPhaseCheckFunc (operatorsv1alpha1 .InstallPlanPhaseFailed , operatorsv1alpha1 .InstallPlanPhaseComplete ))
3038
+ Expect (err ).ToNot (HaveOccurred ())
3039
+ Expect (operatorsv1alpha1 .InstallPlanPhaseComplete ).To (Equal (ip .Status .Phase ), "InstallPlan not complete" )
3040
+
3041
+ // ensure expected kiali CRDs are present on-cluster
3042
+ expectedCRDs := []metav1.GroupVersionKind {
3043
+ {
3044
+ Group : "kialis.kiali.io" ,
3045
+ Version : "v1alpha1" ,
3046
+ Kind : "CustomResourceDefinition" ,
3047
+ },
3048
+ {
3049
+ Group : "monitoringdashboards.monitoring.kiali.io" ,
3050
+ Version : "v1alpha1" ,
3051
+ Kind : "CustomResourceDefinition" ,
3052
+ },
3053
+ }
3054
+
3055
+ for _ , crd := range expectedCRDs {
3056
+ Eventually (func () error {
3057
+ defer Eventually (func () bool {
3058
+ err = c .ApiextensionsInterface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().Delete (context .TODO (), crd .Group , metav1.DeleteOptions {GracePeriodSeconds : new (int64 )})
3059
+ return k8serrors .IsNotFound (err )
3060
+ }).Should (BeTrue ())
3061
+
3062
+ _ , err = c .ApiextensionsInterface ().ApiextensionsV1beta1 ().CustomResourceDefinitions ().Get (context .TODO (), crd .Group , metav1.GetOptions {})
3063
+ return err
3064
+ }).ShouldNot (HaveOccurred ())
3065
+ }
3066
+ })
2806
3067
})
2807
3068
2808
3069
type checkInstallPlanFunc func (fip * operatorsv1alpha1.InstallPlan ) bool
0 commit comments