diff --git a/devstack/lib/heat b/devstack/lib/heat index 9dc35171..2d060fe8 100644 --- a/devstack/lib/heat +++ b/devstack/lib/heat @@ -106,9 +106,12 @@ function configure_heat { HEAT_API_PASTE_FILE=$HEAT_CONF_DIR/api-paste.ini cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE + # Get rabbitmq password + HEAT_RABBITMQ_PASSWORD=$(get_data_from_secret heat-rabbitmq openstack password) + HEAT_RABBITMQ_USERNAME=$(get_data_from_secret heat-rabbitmq openstack username) # common options - iniset_rpc_backend heat $HEAT_CONF + iniset_k8s_rpc_backend heat $HEAT_CONF DEFAULT "rabbit://$HEAT_RABBITMQ_USERNAME:$HEAT_RABBITMQ_PASSWORD@rabbitmq-heat:5672/" iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST/heat-api-cfn iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST/heat-api-cfn/v1/waitcondition diff --git a/openstack_operator/heat.py b/openstack_operator/heat.py index a254df0c..da9f60e2 100644 --- a/openstack_operator/heat.py +++ b/openstack_operator/heat.py @@ -46,6 +46,11 @@ def create_or_resume(name, spec, **_): utils.create_or_update('heat/cronjob-service-clean.yml.j2', name=name, spec=spec) + # deploy rabbitmq + if not utils.ensure_secret("openstack", "heat-rabbitmq"): + utils.create_or_update('heat/secret-rabbitmq.yml.j2', + password=utils.generate_password()) + utils.create_or_update('heat/rabbitmq.yml.j2') if "ingress" in spec: utils.create_or_update('heat/ingress.yml.j2', diff --git a/openstack_operator/objects.py b/openstack_operator/objects.py index e67a340b..feaaf173 100644 --- a/openstack_operator/objects.py +++ b/openstack_operator/objects.py @@ -60,6 +60,14 @@ class PodMonitor(NamespacedAPIObject): kind = "PodMonitor" +class Rabbitmq(NamespacedAPIObject): + """Rabbitmq Kubernetes object""" + + version = "infrastructure.vexxhost.cloud/v1alpha1" + endpoint = "rabbitmqs" + kind = "Rabbitmq" + + class PrometheusRule(NamespacedAPIObject): """PrometheusRule Kubernetes object""" @@ -92,7 +100,8 @@ MAPPING = { }, "infrastructure.vexxhost.cloud/v1alpha1": { "Mcrouter": Mcrouter, - "Memcached": Memcached + "Memcached": Memcached, + "Rabbitmq": Rabbitmq, }, "monitoring.coreos.com/v1": { "PodMonitor": PodMonitor, diff --git a/openstack_operator/templates/heat/rabbitmq.yml.j2 b/openstack_operator/templates/heat/rabbitmq.yml.j2 new file mode 100644 index 00000000..cbbb5d50 --- /dev/null +++ b/openstack_operator/templates/heat/rabbitmq.yml.j2 @@ -0,0 +1,30 @@ +--- +# Copyright 2020 VEXXHOST, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: infrastructure.vexxhost.cloud/v1alpha1 +kind: Rabbitmq +metadata: + name: heat + namespace: openstack +spec: + authSecret: heat-rabbitmq +{% if 'nodeSelector' in spec %} + nodeSelector: + {{ spec.nodeSelector | to_yaml | indent(4) }} +{% endif %} +{% if 'tolerations' in spec %} + tolerations: + {{ spec.tolerations | to_yaml | indent(4) }} +{% endif %} diff --git a/openstack_operator/templates/heat/secret-rabbitmq.yml.j2 b/openstack_operator/templates/heat/secret-rabbitmq.yml.j2 new file mode 100644 index 00000000..06945491 --- /dev/null +++ b/openstack_operator/templates/heat/secret-rabbitmq.yml.j2 @@ -0,0 +1,9 @@ + +apiVersion: v1 +metadata: + name: heat-rabbitmq + namespace: openstack +stringData: + username: heat + password: {{ password }} +kind: Secret diff --git a/openstack_operator/utils.py b/openstack_operator/utils.py index 1f6e3ffc..6a1ad6ab 100644 --- a/openstack_operator/utils.py +++ b/openstack_operator/utils.py @@ -205,6 +205,23 @@ def get_secret(namespace, name): } +def ensure_secret(namespace, name): + """Check if a secret exists + + This function return true when the specific secret exists while + return false when does not exist""" + + api = pykube.HTTPClient(pykube.KubeConfig.from_env()) + + try: + objects.Secret.objects(api).filter(namespace=namespace).get( + name=name + ) + return True + except pykube.exceptions.ObjectDoesNotExist: + return False + + def generate_hash(dictionary): """Generate a hash from a dictionary, return None if dictionary is empty""" if not dictionary: