@@ -884,7 +884,7 @@ func TestOperatorGroupIntersection(t *testing.T) {
884
884
// Generate operatorGroupD in namespaceD that selects namespace D and E
885
885
// Generate csvD in namespaceD
886
886
// Wait for csvD to be successful
887
- // Wait for csvD to have a CSV with copied status in namespace D
887
+ // Wait for csvD to have a CSV with copied status in namespace E
888
888
// Wait for operatorGroupD to have providedAPI annotation with crdD's Kind.version.group
889
889
// Generate operatorGroupA in namespaceA that selects AllNamespaces
890
890
// Generate csvD in namespaceA
@@ -895,6 +895,8 @@ func TestOperatorGroupIntersection(t *testing.T) {
895
895
// Wait for csvA to be successful
896
896
// Ensure clusterroles created and aggregated for accessing provided APIs
897
897
// Wait for operatorGroupA to have providedAPI annotation with crdA's Kind.version.group in its providedAPIs annotation
898
+ // Wait for csvA to have a CSV with copied status in namespace D
899
+ // Ensure csvA retains the operatorgroup annotations for operatorgroupA
898
900
// Wait for csvA to have a CSV with copied status in namespace C
899
901
// Generate operatorGroupB in namespaceB that selects namespace C
900
902
// Generate csvB in namespaceB that owns crdA
@@ -1091,6 +1093,26 @@ func TestOperatorGroupIntersection(t *testing.T) {
1091
1093
}
1092
1094
require .NoError (t , awaitAnnotations (t , q , map [string ]string {v1 .OperatorGroupProvidedAPIsAnnotationKey : kvgA }))
1093
1095
1096
+ // Wait for csvA to have a CSV with copied status in namespace D
1097
+ csvAinNsD , err := awaitCSV (t , crc , nsD , csvA .GetName (), csvCopiedChecker )
1098
+ require .NoError (t , err )
1099
+
1100
+ // trigger a resync of operatorgropuD
1101
+ fetchedGroupD , err := crc .OperatorsV1 ().OperatorGroups (nsD ).Get (groupD .GetName (), metav1.GetOptions {})
1102
+ require .NoError (t , err )
1103
+
1104
+ fetchedGroupD .Annotations ["bump" ] = "update"
1105
+ _ , err = crc .OperatorsV1 ().OperatorGroups (nsD ).Update (fetchedGroupD )
1106
+ require .NoError (t , err )
1107
+
1108
+ // Ensure csvA retains the operatorgroup annotations for operatorgroupA
1109
+ csvAinNsD , err = awaitCSV (t , crc , nsD , csvA .GetName (), csvCopiedChecker )
1110
+ require .NoError (t , err )
1111
+
1112
+ require .Equal (t , groupA .GetName (), csvAinNsD .Annotations [v1 .OperatorGroupAnnotationKey ])
1113
+ require .Equal (t , nsA , csvAinNsD .Annotations [v1 .OperatorGroupNamespaceAnnotationKey ])
1114
+ require .Equal (t , nsA , csvAinNsD .Labels [v1alpha1 .CopiedLabelKey ])
1115
+
1094
1116
// Await csvA's copy in namespaceC
1095
1117
_ , err = awaitCSV (t , crc , nsC , csvA .GetName (), csvCopiedChecker )
1096
1118
require .NoError (t , err )
@@ -1849,3 +1871,183 @@ func TestOperatorGroupInsufficientPermissionsResolveViaServiceAccountRemoval(t *
1849
1871
})
1850
1872
require .NoError (t , err )
1851
1873
}
1874
+
1875
+ func TestCleanupCsvsWithBadOwnerOperatorGroups (t * testing.T ) {
1876
+ // Create namespace with specific label
1877
+ // Create CRD
1878
+ // Create CSV in operator namespace
1879
+ // Create operator group that watches namespace and uses specific label
1880
+ // Verify operator group status contains correct status
1881
+ // Verify csv in target namespace exists, has copied status, has annotations
1882
+ // Verify deployments have correct namespace annotation
1883
+ // (Verify that the operator can operate in the target namespace)
1884
+ // Update CSV to support no InstallModes
1885
+ // Verify the CSV transitions to FAILED
1886
+ // Verify the copied CSV transitions to FAILED
1887
+ // Delete CSV
1888
+ // Verify copied CVS is deleted
1889
+ defer cleaner .NotifyTestComplete (t , true )
1890
+
1891
+ log := func (s string ) {
1892
+ t .Logf ("%s: %s" , time .Now ().Format ("15:04:05.9999" ), s )
1893
+ }
1894
+
1895
+ c := newKubeClient (t )
1896
+ crc := newCRClient (t )
1897
+ csvName := genName ("another-csv-" ) // must be lowercase for DNS-1123 validation
1898
+
1899
+ opGroupNamespace := genName (testNamespace + "-" )
1900
+ matchingLabel := map [string ]string {"inGroup" : opGroupNamespace }
1901
+ otherNamespaceName := genName (opGroupNamespace + "-" )
1902
+ bothNamespaceNames := opGroupNamespace + "," + otherNamespaceName
1903
+
1904
+ _ , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (& corev1.Namespace {
1905
+ ObjectMeta : metav1.ObjectMeta {
1906
+ Name : opGroupNamespace ,
1907
+ Labels : matchingLabel ,
1908
+ },
1909
+ })
1910
+ require .NoError (t , err )
1911
+ defer func () {
1912
+ err = c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (opGroupNamespace , & metav1.DeleteOptions {})
1913
+ require .NoError (t , err )
1914
+ }()
1915
+
1916
+ otherNamespace := corev1.Namespace {
1917
+ ObjectMeta : metav1.ObjectMeta {
1918
+ Name : otherNamespaceName ,
1919
+ Labels : matchingLabel ,
1920
+ },
1921
+ }
1922
+ createdOtherNamespace , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (& otherNamespace )
1923
+ require .NoError (t , err )
1924
+ defer func () {
1925
+ err = c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (otherNamespaceName , & metav1.DeleteOptions {})
1926
+ require .NoError (t , err )
1927
+ }()
1928
+
1929
+ log ("Creating CRD" )
1930
+ mainCRDPlural := genName ("opgroup" )
1931
+ mainCRD := newCRD (mainCRDPlural )
1932
+ cleanupCRD , err := createCRD (c , mainCRD )
1933
+ require .NoError (t , err )
1934
+ defer cleanupCRD ()
1935
+
1936
+ log ("Creating operator group" )
1937
+ operatorGroup := v1.OperatorGroup {
1938
+ ObjectMeta : metav1.ObjectMeta {
1939
+ Name : genName ("e2e-operator-group-" ),
1940
+ Namespace : opGroupNamespace ,
1941
+ },
1942
+ Spec : v1.OperatorGroupSpec {
1943
+ Selector : & metav1.LabelSelector {
1944
+ MatchLabels : matchingLabel ,
1945
+ },
1946
+ },
1947
+ }
1948
+ _ , err = crc .OperatorsV1 ().OperatorGroups (opGroupNamespace ).Create (& operatorGroup )
1949
+ require .NoError (t , err )
1950
+ expectedOperatorGroupStatus := v1.OperatorGroupStatus {
1951
+ Namespaces : []string {opGroupNamespace , createdOtherNamespace .GetName ()},
1952
+ }
1953
+
1954
+ log ("Waiting on operator group to have correct status" )
1955
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
1956
+ fetched , fetchErr := crc .OperatorsV1 ().OperatorGroups (opGroupNamespace ).Get (operatorGroup .Name , metav1.GetOptions {})
1957
+ if fetchErr != nil {
1958
+ return false , fetchErr
1959
+ }
1960
+ if len (fetched .Status .Namespaces ) > 0 {
1961
+ require .ElementsMatch (t , expectedOperatorGroupStatus .Namespaces , fetched .Status .Namespaces , "have %#v" , fetched .Status .Namespaces )
1962
+ return true , nil
1963
+ }
1964
+ return false , nil
1965
+ })
1966
+ require .NoError (t , err )
1967
+
1968
+ log ("Creating CSV" )
1969
+
1970
+ // Generate permissions
1971
+ serviceAccountName := genName ("nginx-sa" )
1972
+ permissions := []v1alpha1.StrategyDeploymentPermissions {
1973
+ {
1974
+ ServiceAccountName : serviceAccountName ,
1975
+ Rules : []rbacv1.PolicyRule {
1976
+ {
1977
+ Verbs : []string {rbacv1 .VerbAll },
1978
+ APIGroups : []string {mainCRD .Spec .Group },
1979
+ Resources : []string {mainCRDPlural },
1980
+ },
1981
+ },
1982
+ },
1983
+ }
1984
+
1985
+ // Create a new NamedInstallStrategy
1986
+ deploymentName := genName ("operator-deployment" )
1987
+ namedStrategy := newNginxInstallStrategy (deploymentName , permissions , nil )
1988
+
1989
+ aCSV := newCSV (csvName , opGroupNamespace , "" , semver .MustParse ("0.0.0" ), []apiextensions.CustomResourceDefinition {mainCRD }, nil , namedStrategy )
1990
+ createdCSV , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (opGroupNamespace ).Create (& aCSV )
1991
+ require .NoError (t , err )
1992
+
1993
+ serviceAccount := & corev1.ServiceAccount {
1994
+ ObjectMeta : metav1.ObjectMeta {
1995
+ Namespace : opGroupNamespace ,
1996
+ Name : serviceAccountName ,
1997
+ },
1998
+ }
1999
+ ownerutil .AddNonBlockingOwner (serviceAccount , createdCSV )
2000
+ err = ownerutil .AddOwnerLabels (serviceAccount , createdCSV )
2001
+ require .NoError (t , err )
2002
+
2003
+ role := & rbacv1.Role {
2004
+ ObjectMeta : metav1.ObjectMeta {
2005
+ Namespace : opGroupNamespace ,
2006
+ Name : serviceAccountName + "-role" ,
2007
+ },
2008
+ Rules : permissions [0 ].Rules ,
2009
+ }
2010
+ ownerutil .AddNonBlockingOwner (role , createdCSV )
2011
+ err = ownerutil .AddOwnerLabels (role , createdCSV )
2012
+ require .NoError (t , err )
2013
+
2014
+ roleBinding := & rbacv1.RoleBinding {
2015
+ ObjectMeta : metav1.ObjectMeta {
2016
+ Namespace : opGroupNamespace ,
2017
+ Name : serviceAccountName + "-rb" ,
2018
+ },
2019
+ Subjects : []rbacv1.Subject {
2020
+ {
2021
+ Kind : "ServiceAccount" ,
2022
+ Name : serviceAccountName ,
2023
+ Namespace : opGroupNamespace ,
2024
+ },
2025
+ },
2026
+ RoleRef : rbacv1.RoleRef {
2027
+ Kind : "Role" ,
2028
+ Name : role .GetName (),
2029
+ },
2030
+ }
2031
+ ownerutil .AddNonBlockingOwner (roleBinding , createdCSV )
2032
+ err = ownerutil .AddOwnerLabels (roleBinding , createdCSV )
2033
+ require .NoError (t , err )
2034
+
2035
+ _ , err = c .CreateServiceAccount (serviceAccount )
2036
+ require .NoError (t , err )
2037
+ _ , err = c .CreateRole (role )
2038
+ require .NoError (t , err )
2039
+ _ , err = c .CreateRoleBinding (roleBinding )
2040
+ require .NoError (t , err )
2041
+
2042
+ log ("wait for CSV to succeed" )
2043
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
2044
+ fetched , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (opGroupNamespace ).Get (createdCSV .GetName (), metav1.GetOptions {})
2045
+ if err != nil {
2046
+ return false , err
2047
+ }
2048
+ log (fmt .Sprintf ("%s (%s): %s" , fetched .Status .Phase , fetched .Status .Reason , fetched .Status .Message ))
2049
+ return csvSucceededChecker (fetched ), nil
2050
+ })
2051
+ require .NoError (t , err )
2052
+ }
2053
+ }
0 commit comments