@@ -30,6 +30,7 @@ import (
3030
3131 k8s_corev1 "k8s.io/api/core/v1"
3232 k8s_errors "k8s.io/apimachinery/pkg/api/errors"
33+
3334 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3435 "k8s.io/apimachinery/pkg/types"
3536 "k8s.io/utils/ptr"
@@ -40,6 +41,7 @@ import (
4041 cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1"
4142 rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1"
4243 topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
44+
4345 "github.com/openstack-k8s-operators/lib-common/modules/certmanager"
4446 "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
4547 "github.com/openstack-k8s-operators/lib-common/modules/common/service"
@@ -1793,6 +1795,153 @@ var _ = Describe("OpenStackOperator controller", func() {
17931795 })
17941796 })
17951797
1798+ When ("A OpenStackControlplane instance is created" , func () {
1799+ BeforeEach (func () {
1800+ // NOTE(bogdando): DBs certs need to be created here as well, but those are already existing somehow
1801+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCertName ))
1802+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCell1CertName ))
1803+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .MemcachedCertName ))
1804+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .OVNNorthdCertName ))
1805+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .OVNControllerCertName ))
1806+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .NeutronOVNCertName ))
1807+
1808+ DeferCleanup (k8sClient .Delete , ctx ,
1809+ th .CreateSecret (types.NamespacedName {Name : "openstack-config-secret" , Namespace : namespace }, map [string ][]byte {"secure.yaml" : []byte ("foo" )}))
1810+ DeferCleanup (k8sClient .Delete , ctx ,
1811+ th .CreateConfigMap (types.NamespacedName {Name : "openstack-config" , Namespace : namespace }, map [string ]interface {}{"clouds.yaml" : string ("foo" ), "OS_CLOUD" : "default" }))
1812+
1813+ spec := GetDefaultOpenStackControlPlaneSpec ()
1814+ // enable dependencies
1815+ spec ["nova" ] = map [string ]interface {}{
1816+ "enabled" : true ,
1817+ "template" : map [string ]interface {}{
1818+ "apiTimeout" : 60 ,
1819+ "cellTemplates" : map [string ]interface {}{
1820+ "cell0" : map [string ]interface {}{},
1821+ },
1822+ },
1823+ }
1824+ spec ["galera" ] = map [string ]interface {}{
1825+ "enabled" : true ,
1826+ }
1827+ spec ["memcached" ] = map [string ]interface {}{
1828+ "enabled" : true ,
1829+ "templates" : map [string ]interface {}{
1830+ "memcached" : map [string ]interface {}{
1831+ "replicas" : 1 ,
1832+ },
1833+ },
1834+ }
1835+ spec ["rabbitmq" ] = map [string ]interface {}{
1836+ "enabled" : true ,
1837+ "templates" : map [string ]interface {}{
1838+ "rabbitmq" : map [string ]interface {}{
1839+ "replicas" : 1 ,
1840+ },
1841+ },
1842+ }
1843+ spec ["keystone" ] = map [string ]interface {}{
1844+ "enabled" : true ,
1845+ }
1846+ spec ["glance" ] = map [string ]interface {}{
1847+ "enabled" : true ,
1848+ }
1849+ spec ["neutron" ] = map [string ]interface {}{
1850+ "enabled" : true ,
1851+ }
1852+ spec ["placement" ] = map [string ]interface {}{
1853+ "enabled" : true ,
1854+ "template" : map [string ]interface {}{
1855+ "apiTimeout" : 60 ,
1856+ },
1857+ }
1858+ // turn off unrelated to this test case services
1859+ spec ["horizon" ] = map [string ]interface {}{
1860+ "enabled" : false ,
1861+ }
1862+ spec ["cinder" ] = map [string ]interface {}{
1863+ "enabled" : false ,
1864+ }
1865+ spec ["swift" ] = map [string ]interface {}{
1866+ "enabled" : false ,
1867+ }
1868+ spec ["redis" ] = map [string ]interface {}{
1869+ "enabled" : false ,
1870+ }
1871+ spec ["ironic" ] = map [string ]interface {}{
1872+ "enabled" : false ,
1873+ }
1874+ spec ["designate" ] = map [string ]interface {}{
1875+ "enabled" : false ,
1876+ }
1877+ spec ["barbican" ] = map [string ]interface {}{
1878+ "enabled" : false ,
1879+ }
1880+ spec ["manila" ] = map [string ]interface {}{
1881+ "enabled" : false ,
1882+ }
1883+ spec ["heat" ] = map [string ]interface {}{
1884+ "enabled" : false ,
1885+ }
1886+ spec ["telemetry" ] = map [string ]interface {}{
1887+ "enabled" : false ,
1888+ }
1889+
1890+ Eventually (func (g Gomega ) {
1891+ g .Expect (CreateOpenStackControlPlane (names .OpenStackControlplaneName , spec )).Should (Not (BeNil ()))
1892+ keystoneAPI := keystone .GetKeystoneAPI (names .KeystoneAPIName )
1893+ g .Expect (keystoneAPI ).Should (Not (BeNil ()))
1894+ SimulateControlplaneReady ()
1895+ }, timeout , interval ).Should (Succeed ())
1896+
1897+ DeferCleanup (
1898+ th .DeleteInstance ,
1899+ GetOpenStackControlPlane (names .OpenStackControlplaneName ),
1900+ )
1901+
1902+ Eventually (func (g Gomega ) {
1903+ OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
1904+ OSCtlplane .Status .ObservedGeneration = OSCtlplane .Generation
1905+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneMemcachedReadyCondition , "Ready" )
1906+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneRabbitMQReadyCondition , "Ready" )
1907+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneNeutronReadyCondition , "Ready" )
1908+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneGlanceReadyCondition , "Ready" )
1909+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlanePlacementAPIReadyCondition , "Ready" )
1910+ g .Expect (k8sClient .Update (ctx , OSCtlplane )).Should (Succeed ())
1911+ th .Logger .Info ("Simulated nova dependencies ready" , "on" , names .OpenStackControlplaneName )
1912+ }, timeout , interval ).Should (Succeed ())
1913+
1914+ // nova to become ready
1915+ Eventually (func (g Gomega ) {
1916+ conditions := OpenStackControlPlaneConditionGetter (names .OpenStackControlplaneName )
1917+ g .Expect (conditions .Has (corev1 .OpenStackControlPlaneNovaReadyCondition )).To (BeTrue ())
1918+ }, timeout , interval ).Should (Succeed ())
1919+ })
1920+
1921+ It ("should have configured nova" , func () {
1922+ nova := & novav1.Nova {}
1923+ Eventually (func (g Gomega ) {
1924+ g .Expect (k8sClient .Get (ctx , names .NovaName , nova )).Should (Succeed ())
1925+ g .Expect (nova ).ShouldNot (BeNil ())
1926+ }, timeout , interval ).Should (Succeed ())
1927+ })
1928+
1929+ It ("should have configured nova from the service template" , func () {
1930+ OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
1931+ Eventually (func (g Gomega ) {
1932+ OSCtlplane .Spec .Nova .Template .APIDatabaseInstance = "custom-db"
1933+ g .Expect (k8sClient .Update (ctx , OSCtlplane )).Should (Succeed ())
1934+ }, timeout , interval ).Should (Succeed ())
1935+
1936+ nova := & novav1.Nova {}
1937+ Eventually (func (g Gomega ) {
1938+ g .Expect (k8sClient .Get (ctx , names .NovaName , nova )).Should (Succeed ())
1939+ g .Expect (nova ).ShouldNot (BeNil ())
1940+ g .Expect (nova .Spec .APIDatabaseInstance ).Should (Equal ("custom-db" ))
1941+ }, timeout , interval ).Should (Succeed ())
1942+ })
1943+ })
1944+
17961945 When ("OpenStackControlplane instance is deleted" , func () {
17971946 BeforeEach (func () {
17981947 DeferCleanup (
0 commit comments