@@ -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"
@@ -1805,6 +1807,153 @@ var _ = Describe("OpenStackOperator controller", func() {
18051807 })
18061808 })
18071809
1810+ When ("A OpenStackControlplane instance is created" , func () {
1811+ BeforeEach (func () {
1812+ // NOTE(bogdando): DBs certs need to be created here as well, but those are already existing somehow
1813+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCertName ))
1814+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .RabbitMQCell1CertName ))
1815+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .MemcachedCertName ))
1816+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .OVNNorthdCertName ))
1817+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .OVNControllerCertName ))
1818+ DeferCleanup (k8sClient .Delete , ctx , th .CreateCertSecret (names .NeutronOVNCertName ))
1819+
1820+ DeferCleanup (k8sClient .Delete , ctx ,
1821+ th .CreateSecret (types.NamespacedName {Name : "openstack-config-secret" , Namespace : namespace }, map [string ][]byte {"secure.yaml" : []byte ("foo" )}))
1822+ DeferCleanup (k8sClient .Delete , ctx ,
1823+ th .CreateConfigMap (types.NamespacedName {Name : "openstack-config" , Namespace : namespace }, map [string ]interface {}{"clouds.yaml" : string ("foo" ), "OS_CLOUD" : "default" }))
1824+
1825+ spec := GetDefaultOpenStackControlPlaneSpec ()
1826+ // enable dependencies
1827+ spec ["nova" ] = map [string ]interface {}{
1828+ "enabled" : true ,
1829+ "template" : map [string ]interface {}{
1830+ "apiTimeout" : 60 ,
1831+ "cellTemplates" : map [string ]interface {}{
1832+ "cell0" : map [string ]interface {}{},
1833+ },
1834+ },
1835+ }
1836+ spec ["galera" ] = map [string ]interface {}{
1837+ "enabled" : true ,
1838+ }
1839+ spec ["memcached" ] = map [string ]interface {}{
1840+ "enabled" : true ,
1841+ "templates" : map [string ]interface {}{
1842+ "memcached" : map [string ]interface {}{
1843+ "replicas" : 1 ,
1844+ },
1845+ },
1846+ }
1847+ spec ["rabbitmq" ] = map [string ]interface {}{
1848+ "enabled" : true ,
1849+ "templates" : map [string ]interface {}{
1850+ "rabbitmq" : map [string ]interface {}{
1851+ "replicas" : 1 ,
1852+ },
1853+ },
1854+ }
1855+ spec ["keystone" ] = map [string ]interface {}{
1856+ "enabled" : true ,
1857+ }
1858+ spec ["glance" ] = map [string ]interface {}{
1859+ "enabled" : true ,
1860+ }
1861+ spec ["neutron" ] = map [string ]interface {}{
1862+ "enabled" : true ,
1863+ }
1864+ spec ["placement" ] = map [string ]interface {}{
1865+ "enabled" : true ,
1866+ "template" : map [string ]interface {}{
1867+ "apiTimeout" : 60 ,
1868+ },
1869+ }
1870+ // turn off unrelated to this test case services
1871+ spec ["horizon" ] = map [string ]interface {}{
1872+ "enabled" : false ,
1873+ }
1874+ spec ["cinder" ] = map [string ]interface {}{
1875+ "enabled" : false ,
1876+ }
1877+ spec ["swift" ] = map [string ]interface {}{
1878+ "enabled" : false ,
1879+ }
1880+ spec ["redis" ] = map [string ]interface {}{
1881+ "enabled" : false ,
1882+ }
1883+ spec ["ironic" ] = map [string ]interface {}{
1884+ "enabled" : false ,
1885+ }
1886+ spec ["designate" ] = map [string ]interface {}{
1887+ "enabled" : false ,
1888+ }
1889+ spec ["barbican" ] = map [string ]interface {}{
1890+ "enabled" : false ,
1891+ }
1892+ spec ["manila" ] = map [string ]interface {}{
1893+ "enabled" : false ,
1894+ }
1895+ spec ["heat" ] = map [string ]interface {}{
1896+ "enabled" : false ,
1897+ }
1898+ spec ["telemetry" ] = map [string ]interface {}{
1899+ "enabled" : false ,
1900+ }
1901+
1902+ Eventually (func (g Gomega ) {
1903+ g .Expect (CreateOpenStackControlPlane (names .OpenStackControlplaneName , spec )).Should (Not (BeNil ()))
1904+ keystoneAPI := keystone .GetKeystoneAPI (names .KeystoneAPIName )
1905+ g .Expect (keystoneAPI ).Should (Not (BeNil ()))
1906+ SimulateControlplaneReady ()
1907+ }, timeout , interval ).Should (Succeed ())
1908+
1909+ DeferCleanup (
1910+ th .DeleteInstance ,
1911+ GetOpenStackControlPlane (names .OpenStackControlplaneName ),
1912+ )
1913+
1914+ Eventually (func (g Gomega ) {
1915+ OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
1916+ OSCtlplane .Status .ObservedGeneration = OSCtlplane .Generation
1917+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneMemcachedReadyCondition , "Ready" )
1918+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneRabbitMQReadyCondition , "Ready" )
1919+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneNeutronReadyCondition , "Ready" )
1920+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlaneGlanceReadyCondition , "Ready" )
1921+ OSCtlplane .Status .Conditions .MarkTrue (corev1 .OpenStackControlPlanePlacementAPIReadyCondition , "Ready" )
1922+ g .Expect (k8sClient .Update (ctx , OSCtlplane )).Should (Succeed ())
1923+ th .Logger .Info ("Simulated nova dependencies ready" , "on" , names .OpenStackControlplaneName )
1924+ }, timeout , interval ).Should (Succeed ())
1925+
1926+ // nova to become ready
1927+ Eventually (func (g Gomega ) {
1928+ conditions := OpenStackControlPlaneConditionGetter (names .OpenStackControlplaneName )
1929+ g .Expect (conditions .Has (corev1 .OpenStackControlPlaneNovaReadyCondition )).To (BeTrue ())
1930+ }, timeout , interval ).Should (Succeed ())
1931+ })
1932+
1933+ It ("should have configured nova" , func () {
1934+ nova := & novav1.Nova {}
1935+ Eventually (func (g Gomega ) {
1936+ g .Expect (k8sClient .Get (ctx , names .NovaName , nova )).Should (Succeed ())
1937+ g .Expect (nova ).ShouldNot (BeNil ())
1938+ }, timeout , interval ).Should (Succeed ())
1939+ })
1940+
1941+ It ("should have configured nova from the service template" , func () {
1942+ OSCtlplane := GetOpenStackControlPlane (names .OpenStackControlplaneName )
1943+ Eventually (func (g Gomega ) {
1944+ OSCtlplane .Spec .Nova .Template .APIDatabaseInstance = "custom-db"
1945+ g .Expect (k8sClient .Update (ctx , OSCtlplane )).Should (Succeed ())
1946+ }, timeout , interval ).Should (Succeed ())
1947+
1948+ nova := & novav1.Nova {}
1949+ Eventually (func (g Gomega ) {
1950+ g .Expect (k8sClient .Get (ctx , names .NovaName , nova )).Should (Succeed ())
1951+ g .Expect (nova ).ShouldNot (BeNil ())
1952+ g .Expect (nova .Spec .APIDatabaseInstance ).Should (Equal ("custom-db" ))
1953+ }, timeout , interval ).Should (Succeed ())
1954+ })
1955+ })
1956+
18081957 When ("OpenStackControlplane instance is deleted" , func () {
18091958 BeforeEach (func () {
18101959 DeferCleanup (
0 commit comments