Skip to content

Commit 8159d0d

Browse files
committed
test(ci): add failing test assertion showing that operatorgroup
annotations on copied csvs will get overwritten to the wrong thing
1 parent d2c914c commit 8159d0d

File tree

1 file changed

+203
-1
lines changed

1 file changed

+203
-1
lines changed

test/e2e/operator_groups_e2e_test.go

Lines changed: 203 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ func TestOperatorGroupIntersection(t *testing.T) {
884884
// Generate operatorGroupD in namespaceD that selects namespace D and E
885885
// Generate csvD in namespaceD
886886
// 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
888888
// Wait for operatorGroupD to have providedAPI annotation with crdD's Kind.version.group
889889
// Generate operatorGroupA in namespaceA that selects AllNamespaces
890890
// Generate csvD in namespaceA
@@ -895,6 +895,8 @@ func TestOperatorGroupIntersection(t *testing.T) {
895895
// Wait for csvA to be successful
896896
// Ensure clusterroles created and aggregated for accessing provided APIs
897897
// 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
898900
// Wait for csvA to have a CSV with copied status in namespace C
899901
// Generate operatorGroupB in namespaceB that selects namespace C
900902
// Generate csvB in namespaceB that owns crdA
@@ -1091,6 +1093,26 @@ func TestOperatorGroupIntersection(t *testing.T) {
10911093
}
10921094
require.NoError(t, awaitAnnotations(t, q, map[string]string{v1.OperatorGroupProvidedAPIsAnnotationKey: kvgA}))
10931095

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+
10941116
// Await csvA's copy in namespaceC
10951117
_, err = awaitCSV(t, crc, nsC, csvA.GetName(), csvCopiedChecker)
10961118
require.NoError(t, err)
@@ -1849,3 +1871,183 @@ func TestOperatorGroupInsufficientPermissionsResolveViaServiceAccountRemoval(t *
18491871
})
18501872
require.NoError(t, err)
18511873
}
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

Comments
 (0)