@@ -1613,3 +1613,240 @@ func TestCSVCopyWatchingAllNamespaces(t *testing.T) {
1613
1613
})
1614
1614
require .NoError (t , err )
1615
1615
}
1616
+
1617
+ func TestOperatorGroupInsufficientPermissionsResolveViaRBAC (t * testing.T ) {
1618
+ defer cleaner .NotifyTestComplete (t , true )
1619
+
1620
+ log := func (s string ) {
1621
+ t .Logf ("%s: %s" , time .Now ().Format ("15:04:05.9999" ), s )
1622
+ }
1623
+
1624
+ c := newKubeClient (t )
1625
+ crc := newCRClient (t )
1626
+ csvName := genName ("another-csv-" )
1627
+
1628
+ newNamespaceName := genName (testNamespace + "-" )
1629
+
1630
+ _ , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (& corev1.Namespace {
1631
+ ObjectMeta : metav1.ObjectMeta {
1632
+ Name : newNamespaceName ,
1633
+ },
1634
+ })
1635
+ require .NoError (t , err )
1636
+ defer func () {
1637
+ err = c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (newNamespaceName , & metav1.DeleteOptions {})
1638
+ require .NoError (t , err )
1639
+ }()
1640
+
1641
+ log ("Creating CRD" )
1642
+ mainCRDPlural := genName ("opgroup" )
1643
+ mainCRD := newCRD (mainCRDPlural )
1644
+ cleanupCRD , err := createCRD (c , mainCRD )
1645
+ require .NoError (t , err )
1646
+ defer cleanupCRD ()
1647
+
1648
+ log ("Creating operator group" )
1649
+ serviceAccountName := genName ("nginx-sa" )
1650
+ // intentionally creating an operator group without a service account already existing
1651
+ operatorGroup := v1.OperatorGroup {
1652
+ ObjectMeta : metav1.ObjectMeta {
1653
+ Name : genName ("e2e-operator-group-" ),
1654
+ Namespace : newNamespaceName ,
1655
+ },
1656
+ Spec : v1.OperatorGroupSpec {
1657
+ ServiceAccountName : serviceAccountName ,
1658
+ TargetNamespaces : []string {newNamespaceName },
1659
+ },
1660
+ }
1661
+ _ , err = crc .OperatorsV1 ().OperatorGroups (newNamespaceName ).Create (& operatorGroup )
1662
+ require .NoError (t , err )
1663
+
1664
+ log ("Creating CSV" )
1665
+
1666
+ // Create a new NamedInstallStrategy
1667
+ deploymentName := genName ("operator-deployment" )
1668
+ namedStrategy := newNginxInstallStrategy (deploymentName , nil , nil )
1669
+
1670
+ aCSV := newCSV (csvName , newNamespaceName , "" , semver .MustParse ("0.0.0" ), []apiextensions.CustomResourceDefinition {mainCRD }, nil , namedStrategy )
1671
+ createdCSV , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Create (& aCSV )
1672
+ require .NoError (t , err )
1673
+
1674
+ serviceAccount := & corev1.ServiceAccount {
1675
+ ObjectMeta : metav1.ObjectMeta {
1676
+ Namespace : newNamespaceName ,
1677
+ Name : serviceAccountName ,
1678
+ },
1679
+ }
1680
+ ownerutil .AddNonBlockingOwner (serviceAccount , createdCSV )
1681
+ err = ownerutil .AddOwnerLabels (serviceAccount , createdCSV )
1682
+ require .NoError (t , err )
1683
+
1684
+ _ , err = c .CreateServiceAccount (serviceAccount )
1685
+ require .NoError (t , err )
1686
+
1687
+ log ("wait for CSV to fail" )
1688
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
1689
+ fetched , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Get (createdCSV .GetName (), metav1.GetOptions {})
1690
+ if err != nil {
1691
+ return false , err
1692
+ }
1693
+ log (fmt .Sprintf ("%s (%s): %s" , fetched .Status .Phase , fetched .Status .Reason , fetched .Status .Message ))
1694
+ return csvFailedChecker (fetched ), nil
1695
+ })
1696
+ require .NoError (t , err )
1697
+
1698
+ // now add cluster admin permissions to service account
1699
+ role := & rbacv1.Role {
1700
+ ObjectMeta : metav1.ObjectMeta {
1701
+ Namespace : newNamespaceName ,
1702
+ Name : serviceAccountName + "-role" ,
1703
+ },
1704
+ Rules : []rbacv1.PolicyRule {
1705
+ {
1706
+ Verbs : []string {"*" },
1707
+ APIGroups : []string {"*" },
1708
+ Resources : []string {"*" },
1709
+ },
1710
+ },
1711
+ }
1712
+ ownerutil .AddNonBlockingOwner (role , createdCSV )
1713
+ err = ownerutil .AddOwnerLabels (role , createdCSV )
1714
+ require .NoError (t , err )
1715
+
1716
+ roleBinding := & rbacv1.RoleBinding {
1717
+ ObjectMeta : metav1.ObjectMeta {
1718
+ Namespace : newNamespaceName ,
1719
+ Name : serviceAccountName + "-rb" ,
1720
+ },
1721
+ Subjects : []rbacv1.Subject {
1722
+ {
1723
+ Kind : "ServiceAccount" ,
1724
+ Name : serviceAccountName ,
1725
+ Namespace : newNamespaceName ,
1726
+ },
1727
+ },
1728
+ RoleRef : rbacv1.RoleRef {
1729
+ Kind : "Role" ,
1730
+ Name : role .GetName (),
1731
+ },
1732
+ }
1733
+ ownerutil .AddNonBlockingOwner (roleBinding , createdCSV )
1734
+ err = ownerutil .AddOwnerLabels (roleBinding , createdCSV )
1735
+ require .NoError (t , err )
1736
+
1737
+ _ , err = c .CreateRole (role )
1738
+ require .NoError (t , err )
1739
+ _ , err = c .CreateRoleBinding (roleBinding )
1740
+ require .NoError (t , err )
1741
+
1742
+ log ("wait for CSV to succeeed" )
1743
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
1744
+ fetched , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Get (createdCSV .GetName (), metav1.GetOptions {})
1745
+ if err != nil {
1746
+ return false , err
1747
+ }
1748
+ log (fmt .Sprintf ("%s (%s): %s" , fetched .Status .Phase , fetched .Status .Reason , fetched .Status .Message ))
1749
+ return csvSucceededChecker (fetched ), nil
1750
+ })
1751
+ require .NoError (t , err )
1752
+ }
1753
+
1754
+ func TestOperatorGroupInsufficientPermissionsResolveViaServiceAccountRemoval (t * testing.T ) {
1755
+ defer cleaner .NotifyTestComplete (t , true )
1756
+
1757
+ log := func (s string ) {
1758
+ t .Logf ("%s: %s" , time .Now ().Format ("15:04:05.9999" ), s )
1759
+ }
1760
+
1761
+ c := newKubeClient (t )
1762
+ crc := newCRClient (t )
1763
+ csvName := genName ("another-csv-" )
1764
+
1765
+ newNamespaceName := genName (testNamespace + "-" )
1766
+
1767
+ _ , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (& corev1.Namespace {
1768
+ ObjectMeta : metav1.ObjectMeta {
1769
+ Name : newNamespaceName ,
1770
+ },
1771
+ })
1772
+ require .NoError (t , err )
1773
+ defer func () {
1774
+ err = c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (newNamespaceName , & metav1.DeleteOptions {})
1775
+ require .NoError (t , err )
1776
+ }()
1777
+
1778
+ log ("Creating CRD" )
1779
+ mainCRDPlural := genName ("opgroup" )
1780
+ mainCRD := newCRD (mainCRDPlural )
1781
+ cleanupCRD , err := createCRD (c , mainCRD )
1782
+ require .NoError (t , err )
1783
+ defer cleanupCRD ()
1784
+
1785
+ log ("Creating operator group" )
1786
+ serviceAccountName := genName ("nginx-sa" )
1787
+ // intentionally creating an operator group without a service account already existing
1788
+ operatorGroup := v1.OperatorGroup {
1789
+ ObjectMeta : metav1.ObjectMeta {
1790
+ Name : genName ("e2e-operator-group-" ),
1791
+ Namespace : newNamespaceName ,
1792
+ },
1793
+ Spec : v1.OperatorGroupSpec {
1794
+ ServiceAccountName : serviceAccountName ,
1795
+ TargetNamespaces : []string {newNamespaceName },
1796
+ },
1797
+ }
1798
+ _ , err = crc .OperatorsV1 ().OperatorGroups (newNamespaceName ).Create (& operatorGroup )
1799
+ require .NoError (t , err )
1800
+
1801
+ log ("Creating CSV" )
1802
+
1803
+ // Create a new NamedInstallStrategy
1804
+ deploymentName := genName ("operator-deployment" )
1805
+ namedStrategy := newNginxInstallStrategy (deploymentName , nil , nil )
1806
+
1807
+ aCSV := newCSV (csvName , newNamespaceName , "" , semver .MustParse ("0.0.0" ), []apiextensions.CustomResourceDefinition {mainCRD }, nil , namedStrategy )
1808
+ createdCSV , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Create (& aCSV )
1809
+ require .NoError (t , err )
1810
+
1811
+ serviceAccount := & corev1.ServiceAccount {
1812
+ ObjectMeta : metav1.ObjectMeta {
1813
+ Namespace : newNamespaceName ,
1814
+ Name : serviceAccountName ,
1815
+ },
1816
+ }
1817
+ ownerutil .AddNonBlockingOwner (serviceAccount , createdCSV )
1818
+ err = ownerutil .AddOwnerLabels (serviceAccount , createdCSV )
1819
+ require .NoError (t , err )
1820
+
1821
+ _ , err = c .CreateServiceAccount (serviceAccount )
1822
+ require .NoError (t , err )
1823
+
1824
+ log ("wait for CSV to fail" )
1825
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
1826
+ fetched , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Get (createdCSV .GetName (), metav1.GetOptions {})
1827
+ if err != nil {
1828
+ return false , err
1829
+ }
1830
+ log (fmt .Sprintf ("%s (%s): %s" , fetched .Status .Phase , fetched .Status .Reason , fetched .Status .Message ))
1831
+ return csvFailedChecker (fetched ), nil
1832
+ })
1833
+ require .NoError (t , err )
1834
+
1835
+ // now remove operator group specified service account
1836
+ createdOpGroup , err := crc .OperatorsV1 ().OperatorGroups (newNamespaceName ).Get (operatorGroup .GetName (), metav1.GetOptions {})
1837
+ require .NoError (t , err )
1838
+ createdOpGroup .Spec .ServiceAccountName = ""
1839
+ _ , err = crc .OperatorsV1 ().OperatorGroups (newNamespaceName ).Update (createdOpGroup )
1840
+ require .NoError (t , err )
1841
+
1842
+ log ("wait for CSV to succeeed" )
1843
+ err = wait .Poll (pollInterval , pollDuration , func () (bool , error ) {
1844
+ fetched , err := crc .OperatorsV1alpha1 ().ClusterServiceVersions (newNamespaceName ).Get (createdCSV .GetName (), metav1.GetOptions {})
1845
+ if err != nil {
1846
+ return false , err
1847
+ }
1848
+ log (fmt .Sprintf ("%s (%s): %s" , fetched .Status .Phase , fetched .Status .Reason , fetched .Status .Message ))
1849
+ return csvSucceededChecker (fetched ), nil
1850
+ })
1851
+ require .NoError (t , err )
1852
+ }
0 commit comments