fix: use offline deploy for magnum
diff --git a/atmosphere/cmd/operator.py b/atmosphere/cmd/operator.py
index ca8aeb1..65ab3b3 100644
--- a/atmosphere/cmd/operator.py
+++ b/atmosphere/cmd/operator.py
@@ -1,45 +1 @@
-import kopf
-
-from atmosphere import clients
from atmosphere.operator import constants, controllers, utils # noqa: F401
-from atmosphere.operator.api import objects, types
-
-
-@kopf.on.create(
- constants.API_VERSION_ATMOSPHERE,
- constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-@kopf.on.resume(
- constants.API_VERSION_ATMOSPHERE,
- constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-def create_openstack_helm_rabbitmq_cluster(
- namespace: str, name: str, annotations: dict, labels: dict, spec: dict, **_
-):
- api = clients.get_pykube_api()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name=name,
- namespace=namespace,
- annotations=utils.filter_annotations(annotations),
- labels=labels,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(**spec),
- ).apply_rabbitmq_cluster()
-
-
-@kopf.on.delete(
- constants.API_VERSION_ATMOSPHERE,
- constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-def delete_openstack_helm_rabbitmq_cluster(namespace: str, name: str, spec: dict, **_):
- api = clients.get_pykube_api()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name=name,
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(**spec),
- ).delete_rabbitmq_cluster()
diff --git a/atmosphere/operator/api/objects.py b/atmosphere/operator/api/objects.py
index 0ef37b0..b16223c 100644
--- a/atmosphere/operator/api/objects.py
+++ b/atmosphere/operator/api/objects.py
@@ -3,7 +3,6 @@
import pykube
from pydantic import Field
-from atmosphere.operator import constants
from atmosphere.operator.api import mixins, types
# Kubernetes API
@@ -38,69 +37,3 @@
)
kind: str = Field("HelmRelease", const=True)
spec: types.HelmReleaseSpec
-
-
-class RabbitmqCluster(pykube.objects.NamespacedAPIObject, mixins.ServerSideApplyMixin):
- version = "rabbitmq.com/v1beta1"
- endpoint = "rabbitmqclusters"
- kind = "RabbitmqCluster"
-
-
-# Atmosphere
-
-
-class OpenstackHelmRabbitmqCluster(types.NamespacedKubernetesObject):
- endpoint: ClassVar[str] = "openstackhelmrabbitmqclusters"
-
- kind: str = Field(constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER, const=True)
- spec: types.OpenstackHelmRabbitmqClusterSpec
-
- def apply_rabbitmq_cluster(self):
- return RabbitmqCluster(
- self.api,
- {
- "apiVersion": RabbitmqCluster.version,
- "kind": RabbitmqCluster.kind,
- "metadata": {
- "name": f"rabbitmq-{self.metadata.name}",
- "namespace": self.metadata.namespace,
- "annotations": self.metadata.annotations,
- "labels": self.metadata.labels,
- },
- "spec": {
- "image": self.spec.image,
- "affinity": {
- "nodeAffinity": {
- "requiredDuringSchedulingIgnoredDuringExecution": {
- "nodeSelectorTerms": [
- {
- "matchExpressions": [
- {
- "key": "openstack-control-plane",
- "operator": "In",
- "values": ["enabled"],
- }
- ]
- }
- ]
- }
- }
- },
- "rabbitmq": {
- "additionalConfig": "vm_memory_high_watermark.relative = 0.9\n"
- },
- "resources": {
- "requests": {"cpu": "500m", "memory": "1Gi"},
- "limits": {"cpu": "1", "memory": "2Gi"},
- },
- "terminationGracePeriodSeconds": 15,
- },
- },
- ).apply()
-
- def delete_rabbitmq_cluster(self):
- rabbitmq_cluster = RabbitmqCluster.objects(
- self.api, namespace=self.metadata.namespace
- ).get_or_none(name=f"rabbitmq-{self.metadata.name}")
- if rabbitmq_cluster:
- rabbitmq_cluster.delete()
diff --git a/atmosphere/operator/api/types.py b/atmosphere/operator/api/types.py
index 1df4516..5aa7e84 100644
--- a/atmosphere/operator/api/types.py
+++ b/atmosphere/operator/api/types.py
@@ -170,10 +170,3 @@
class Config:
allow_population_by_field_name = True
-
-
-# Atmosphere
-
-
-class OpenstackHelmRabbitmqClusterSpec(pydantic.BaseModel):
- image: pydantic.constr(min_length=1)
diff --git a/atmosphere/operator/constants.py b/atmosphere/operator/constants.py
index 1766d9f..ba69c97 100644
--- a/atmosphere/operator/constants.py
+++ b/atmosphere/operator/constants.py
@@ -1,7 +1,5 @@
API_VERSION_ATMOSPHERE = "atmosphere.vexxhost.com/v1alpha1"
-KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER = "OpenstackHelmRabbitmqCluster"
-
IMAGE_LIST = {
"alertmanager": "quay.io/prometheus/alertmanager:v0.24.0",
"atmosphere": "quay.io/vexxhost/atmosphere:0.13.0", # x-release-please-version
diff --git a/atmosphere/operator/controllers/cloud.py b/atmosphere/operator/controllers/cloud.py
index a5f06ec..9181897 100644
--- a/atmosphere/operator/controllers/cloud.py
+++ b/atmosphere/operator/controllers/cloud.py
@@ -7,8 +7,8 @@
from atmosphere import clients, flows
from atmosphere.models import config
-from atmosphere.operator import tasks, utils
-from atmosphere.operator.api import Cloud, objects, types
+from atmosphere.operator import tasks
+from atmosphere.operator.api import Cloud
@kopf.on.resume(Cloud.version, Cloud.kind)
@@ -21,178 +21,13 @@
engine = flows.get_engine(cfg)
engine.run()
- flow = graph_flow.Flow("deploy").add(
- tasks.GenerateImageTagsConfigMap(provides="image_tags"),
- tasks.GenerateSecrets(provides="secrets"),
- )
+ flow = graph_flow.Flow("deploy")
if spec["magnum"].get("enabled", True):
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="magnum",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
flow.add(
tasks.InstallClusterApiTask(),
- tasks.GetChartValues(
- inject={
- "helm_repository": "openstack-helm",
- "helm_repository_url": "https://tarballs.opendev.org/openstack/openstack-helm/",
- "chart_name": "magnum",
- "chart_version": "0.2.8",
- },
- provides="magnum_chart_values",
- ),
- tasks.GenerateReleaseValues(
- inject={"chart_name": "magnum"},
- provides="magnum_release_values",
- ),
- tasks.GenerateMagnumChartValuesFrom(
- inject={"chart_name": "magnum"},
- provides="magnum_values_from",
- ),
- tasks.ApplyHelmReleaseTask(
- inject={
- "helm_repository": "openstack-helm",
- "chart_name": "magnum",
- "chart_version": "0.2.8",
- "release_name": "magnum",
- },
- rebind={
- "values": "magnum_release_values",
- "values_from": "magnum_values_from",
- },
- ),
)
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="keystone",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="barbican",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="glance",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="cinder",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="neutron",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="nova",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="octavia",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="senlin",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="designate",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
- objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="heat",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image=utils.get_image_ref(
- "rabbitmq_server", override_registry=spec["imageRepository"]
- ).string()
- ),
- ).apply()
-
engine = engines.load(
flow,
store={
diff --git a/atmosphere/operator/tasks.py b/atmosphere/operator/tasks.py
index c089e63..2c46dd0 100644
--- a/atmosphere/operator/tasks.py
+++ b/atmosphere/operator/tasks.py
@@ -1,48 +1,12 @@
import glob
-import json
-import logging
import os
import subprocess
-import mergedeep
import pkg_resources
-import pykube
-import yaml
-from oslo_utils import strutils
from taskflow import task
-from tenacity import retry, retry_if_result, stop_after_delay, wait_fixed
from atmosphere.operator import constants, utils
-LOG = logging.getLogger(__name__)
-
-
-class ApplyKubernetesObjectTask(task.Task):
- def generate_object(self, *args, **kwargs) -> pykube.objects.APIObject:
- raise NotImplementedError
-
- def wait_for_resource(self, resource: pykube.objects.APIObject):
- return resource
-
- def _apply(self, resource: pykube.objects.APIObject) -> pykube.objects.APIObject:
- resp = resource.api.patch(
- **resource.api_kwargs(
- headers={
- "Content-Type": "application/apply-patch+yaml",
- },
- params={
- "fieldManager": "atmosphere-operator",
- "force": True,
- },
- data=json.dumps(resource.obj),
- )
- )
-
- resource.api.raise_for_status(resp)
- resource.set_obj(resp.json())
-
- return self.wait_for_resource(resource)
-
class InstallClusterApiTask(task.Task):
def execute(self, spec: dict):
@@ -76,437 +40,3 @@
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
-
-
-class HelmRelease(pykube.objects.NamespacedAPIObject):
- version = "helm.toolkit.fluxcd.io/v2beta1"
- endpoint = "helmreleases"
- kind = "HelmRelease"
-
-
-class ApplyHelmReleaseTask(ApplyKubernetesObjectTask):
- def execute(
- self,
- api: pykube.HTTPClient,
- namespace: str,
- release_name: str,
- helm_repository: str,
- chart_name: str,
- chart_version: str,
- values: dict,
- values_from: list,
- ) -> HelmRelease:
- resource = HelmRelease(
- api,
- {
- "apiVersion": HelmRelease.version,
- "kind": HelmRelease.kind,
- "metadata": {
- "name": release_name,
- "namespace": namespace,
- },
- "spec": {
- "interval": "60s",
- "chart": {
- "spec": {
- "chart": chart_name,
- "version": chart_version,
- "sourceRef": {
- "kind": "HelmRepository",
- "name": helm_repository,
- },
- }
- },
- "install": {
- "crds": "CreateReplace",
- "disableWait": True,
- "remediation": {
- "retries": 3,
- },
- },
- "upgrade": {
- "crds": "CreateReplace",
- "disableWait": True,
- "remediation": {
- "retries": 3,
- },
- },
- "values": values,
- "valuesFrom": values_from,
- },
- },
- )
-
- return self._apply(resource)
-
- @retry(
- retry=retry_if_result(lambda f: f is False),
- stop=stop_after_delay(300),
- wait=wait_fixed(1),
- )
- def wait_for_resource(self, resource: HelmRelease, *args, **kwargs) -> bool:
- # TODO(mnaser): detect potential changes and wait
- resource.reload()
-
- conditions = {
- condition["type"]: strutils.bool_from_string(condition["status"])
- for condition in resource.obj["status"].get("conditions", [])
- }
-
- if not conditions.get("Ready", False) and conditions.get("Released", False):
- return False
- return resource
-
-
-class GenerateSecrets(ApplyKubernetesObjectTask):
- def execute(
- self, api: pykube.HTTPClient, namespace: str, name: str
- ) -> pykube.Secret:
- # TODO(mnaser): We should generate this if it's missing, but for now
- # assume that it exists.
- secret_name = f"{name}-secrets"
- return pykube.Secret.objects(api, namespace=namespace).get(name=secret_name)
-
-
-class GenerateImageTagsConfigMap(ApplyKubernetesObjectTask):
- def execute(
- self, api: pykube.HTTPClient, namespace: str, name: str, spec: dict
- ) -> pykube.ConfigMap:
- resource = pykube.ConfigMap(
- api,
- {
- "apiVersion": pykube.ConfigMap.version,
- "kind": pykube.ConfigMap.kind,
- "metadata": {
- "name": f"{name}-images",
- "namespace": namespace,
- },
- "data": {
- "values.yaml": yaml.dump(
- {
- "images": {
- "tags": {
- image_name: utils.get_image_ref(
- image_name,
- override_registry=spec["imageRepository"],
- ).string()
- for image_name in constants.IMAGE_LIST.keys()
- }
- }
- }
- )
- },
- },
- )
-
- return self._apply(resource)
-
-
-class GetChartValues(task.Task):
- def execute(
- self,
- helm_repository: str,
- helm_repository_url: str,
- chart_name: str,
- chart_version: str,
- ) -> dict:
- # TODO(mnaser): Once we move towards air-gapped deployments, we should
- # refactor this to pull from local OCI registry instead.
- subprocess.check_call(
- f"helm repo add --force-update {helm_repository} {helm_repository_url}",
- shell=True,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- subprocess.check_call(
- "helm repo update",
- shell=True,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- data = subprocess.check_output(
- f"helm show values {helm_repository}/{chart_name} --version {chart_version}",
- shell=True,
- )
- return yaml.safe_load(data)
-
-
-class GenerateReleaseValues(task.Task):
- def _generate_base(self, rabbitmq: str, spec: dict) -> dict:
- return {
- "endpoints": {
- "identity": {
- "auth": {
- "admin": {
- "username": f"admin-{spec['regionName']}",
- "region_name": spec["regionName"],
- },
- },
- },
- "oslo_db": {
- "hosts": {
- # TODO(mnaser): Move this into a dependency
- "default": "percona-xtradb-haproxy",
- },
- },
- "oslo_messaging": {
- "statefulset": None,
- "hosts": {
- # TODO(mnaser): handle scenario when those don't exist
- "default": rabbitmq,
- },
- },
- },
- }
-
- def _generate_magnum(self, spec: dict) -> dict:
- return {
- "endpoints": {
- "container_infra": {
- "host_fqdn_override": {
- "public": {"host": spec["magnum"]["endpoint"]}
- },
- "port": {"api": {"public": 443}},
- "scheme": {"public": "https"},
- },
- "identity": {
- "auth": {
- "magnum": {
- "username": f"magnum-{spec['regionName']}",
- "region_name": spec["regionName"],
- },
- "magnum_stack_user": {
- "username": f"magnum-domain-{spec['regionName']}",
- "region_name": spec["regionName"],
- },
- },
- },
- },
- "conf": {
- "magnum": {
- "DEFAULT": {"log_config_append": None},
- "barbican_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "cinder_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "cluster_template": {
- "kubernetes_allowed_network_drivers": "calico",
- "kubernetes_default_network_driver": "calico",
- },
- "conductor": {"workers": 4},
- "drivers": {
- "verify_ca": False,
- },
- "glance_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "heat_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "keystone_auth": {
- "auth_url": "http://keystone-api.openstack.svc.cluster.local:5000/v3",
- "user_domain_name": "service",
- "username": f"magnum-{spec['regionName']}",
- # NOTE(mnaser): Magnum does not allow changing the interface to internal
- # so we workaround with this for now.
- "insecure": True,
- },
- "keystone_authtoken": {
- # NOTE(mnaser): Magnum does not allow changing the interface to internal
- # so we workaround with this for now.
- "insecure": True,
- },
- "magnum_client": {"region_name": spec["regionName"]},
- "neutron_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "nova_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- "octavia_client": {
- "endpoint_type": "internalURL",
- "region_name": spec["regionName"],
- },
- }
- },
- "pod": {
- "replicas": {
- "api": 3,
- "conductor": 3,
- },
- },
- "manifests": {
- "ingress_api": False,
- "service_ingress_api": False,
- },
- }
-
- def execute(self, chart_name: str, spec: dict) -> dict:
- return mergedeep.merge(
- {},
- self._generate_base(f"rabbitmq-{chart_name}", spec),
- getattr(self, f"_generate_{chart_name}")(spec),
- spec[chart_name].get("overrides", {}),
- )
-
-
-class GenerateMagnumChartValuesFrom(task.Task):
- def execute(
- self,
- chart_name: str,
- image_tags: pykube.ConfigMap,
- secrets: pykube.Secret,
- ) -> dict:
- return [
- {
- "kind": pykube.ConfigMap.kind,
- "name": image_tags.name,
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "conf.magnum.keystone_auth.password",
- "valuesKey": "magnum-keystone-password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.oslo_cache.auth.memcache_secret_key",
- "valuesKey": "memcache-secret-key",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.identity.auth.admin.password",
- "valuesKey": "keystone-admin-password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.identity.auth.magnum.password",
- "valuesKey": "magnum-keystone-password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.identity.auth.magnum_stack_user.password",
- "valuesKey": "magnum-keystone-password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": "percona-xtradb",
- "targetPath": "endpoints.oslo_db.auth.admin.password",
- "valuesKey": "root",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.oslo_db.auth.magnum.password",
- "valuesKey": "magnum-database-password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": f"rabbitmq-{chart_name}-default-user",
- "targetPath": "endpoints.oslo_messaging.auth.admin.username",
- "valuesKey": "username",
- },
- {
- "kind": pykube.Secret.kind,
- "name": f"rabbitmq-{chart_name}-default-user",
- "targetPath": "endpoints.oslo_messaging.auth.admin.password",
- "valuesKey": "password",
- },
- {
- "kind": pykube.Secret.kind,
- "name": secrets.name,
- "targetPath": "endpoints.oslo_messaging.auth.magnum.password",
- "valuesKey": "magnum-rabbitmq-password",
- },
- ]
-
-
-class GenerateOpenStackHelmEndpoints(task.Task):
- SKIPPED_ENDPOINTS = (
- "cluster_domain_suffix",
- "local_image_registry",
- "oci_image_registry",
- "fluentd",
- )
-
- def __init__(
- self,
- repository_name: str,
- repository_url: str,
- chart_name: str,
- chart_version: str,
- *args,
- **kwargs,
- ):
- self._repository_name = repository_name
- self._repository_url = repository_url
- self._chart_name = chart_name
- self._chart_version = chart_version
-
- super().__init__(*args, **kwargs)
-
- def _get_values(self):
- # TODO(mnaser): Once we move towards air-gapped deployments, we should
- # refactor this to pull from local OCI registry instead.
- subprocess.check_call(
- f"helm repo add --force-update {self._repository_name} {self._repository_url}",
- shell=True,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- subprocess.check_call(
- "helm repo update",
- shell=True,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- data = subprocess.check_output(
- f"helm show values {self._repository_name}/{self._chart_name} --version {self._chart_version}",
- shell=True,
- )
- return yaml.safe_load(data)
-
- def _generate_oslo_messaging(self):
- return {
- "statefulset": None,
- "hosts": {
- "default": f"rabbitmq-{self._chart_name}",
- },
- }
-
- def _generate_orchestration(self):
- return {}
-
- def _generate_key_manager(self):
- return {}
-
- def _generate_oslo_db(self):
- return {"hosts": {"default": "percona-xtradb-haproxy"}}
-
- def _generate_identity(self):
- return {}
-
- def _generate_oslo_cache(self):
- # TODO: only generate if we're getting endpoints for memcached chart
- return {}
-
- def _generate_container_infra(self):
- return {}
-
- def execute(self, *args, **kwargs):
- endpoints = (
- self._get_values().get("endpoints", {}).keys() - self.SKIPPED_ENDPOINTS
- )
- return {"endpoints": {k: getattr(self, "_generate_" + k)() for k in endpoints}}
diff --git a/atmosphere/tests/unit/operator/test_objects.py b/atmosphere/tests/unit/operator/test_objects.py
index ad682e7..5434138 100644
--- a/atmosphere/tests/unit/operator/test_objects.py
+++ b/atmosphere/tests/unit/operator/test_objects.py
@@ -217,192 +217,3 @@
],
},
}
-
-
-class TestOpenstackHelmRabbitmqCluster:
- @given(st.builds(objects.OpenstackHelmRabbitmqCluster))
- def test_property(self, instance):
- assert isinstance(instance, objects.OpenstackHelmRabbitmqCluster)
- assert isinstance(instance.metadata, types.NamespacedObjectMeta)
- assert isinstance(instance.spec, types.OpenstackHelmRabbitmqClusterSpec)
-
- def test_apply(self, api, requests_mock):
- instance = objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="neutron",
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image="rabbitmq:3.8.9",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.PATCH,
- "https://localhost:9443/apis/atmosphere.vexxhost.com/v1alpha1/namespaces/default/openstackhelmrabbitmqclusters/neutron?fieldManager=atmosphere-operator&force=True", # noqa E501
- json={},
- )
-
- instance.apply()
-
- assert len(rsps.calls) == 1
- assert json.loads(rsps.calls[0].request.body) == {
- "apiVersion": "atmosphere.vexxhost.com/v1alpha1",
- "kind": "OpenstackHelmRabbitmqCluster",
- "metadata": {
- "name": "neutron",
- "namespace": "default",
- "labels": {
- "foo": "bar",
- },
- "annotations": {
- "annotate": "this",
- },
- },
- "spec": {
- "image": "rabbitmq:3.8.9",
- },
- }
-
- def test_apply_rabbitmq_cluster(self, api, requests_mock):
- instance = objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="neutron",
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image="rabbitmq:3.8.9",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.PATCH,
- "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron?fieldManager=atmosphere-operator&force=True", # noqa E501
- json={},
- )
-
- instance.apply_rabbitmq_cluster()
-
- assert len(rsps.calls) == 1
- assert json.loads(rsps.calls[0].request.body) == {
- "apiVersion": "rabbitmq.com/v1beta1",
- "kind": "RabbitmqCluster",
- "metadata": {
- "name": "rabbitmq-neutron",
- "namespace": "default",
- "annotations": {
- "annotate": "this",
- },
- "labels": {
- "foo": "bar",
- },
- },
- "spec": {
- "image": "rabbitmq:3.8.9",
- "affinity": {
- "nodeAffinity": {
- "requiredDuringSchedulingIgnoredDuringExecution": {
- "nodeSelectorTerms": [
- {
- "matchExpressions": [
- {
- "key": "openstack-control-plane",
- "operator": "In",
- "values": ["enabled"],
- }
- ]
- }
- ]
- }
- }
- },
- "rabbitmq": {
- "additionalConfig": "vm_memory_high_watermark.relative = 0.9\n"
- },
- "resources": {
- "requests": {"cpu": "500m", "memory": "1Gi"},
- "limits": {"cpu": "1", "memory": "2Gi"},
- },
- "terminationGracePeriodSeconds": 15,
- },
- }
-
- def test_delete_rabbitmq_cluster(self, api, requests_mock):
- instance = objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="neutron",
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image="rabbitmq:3.8.9",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.GET,
- "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
- json={
- "metadata": {
- "name": "rabbitmq-neutron",
- },
- },
- )
- rsps.add(
- responses.DELETE,
- "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
- )
-
- instance.delete_rabbitmq_cluster()
- assert len(rsps.calls) == 2
-
- def test_delete_missing_rabbitmq_cluster(self, api, requests_mock):
- instance = objects.OpenstackHelmRabbitmqCluster(
- api=api,
- metadata=types.NamespacedObjectMeta(
- name="neutron",
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmRabbitmqClusterSpec(
- image="rabbitmq:3.8.9",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.GET,
- "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
- status=404,
- )
-
- instance.delete_rabbitmq_cluster()
- assert len(rsps.calls) == 1
diff --git a/atmosphere/tests/unit/operator/test_types.py b/atmosphere/tests/unit/operator/test_types.py
index 246dc69..164ca6d 100644
--- a/atmosphere/tests/unit/operator/test_types.py
+++ b/atmosphere/tests/unit/operator/test_types.py
@@ -149,11 +149,3 @@
assert isinstance(instance.upgrade, types.HelmReleaseActionSpec)
assert isinstance(instance.values, dict)
assert isinstance(instance.values_from, list)
-
-
-class TestOpenstackHelmRabbitmqClusterSpec:
- @given(st.builds(types.OpenstackHelmRabbitmqClusterSpec))
- def test_property(self, instance):
- assert isinstance(instance, types.OpenstackHelmRabbitmqClusterSpec)
- assert isinstance(instance.image, str)
- assert instance.image != ""
diff --git a/molecule/default/group_vars/all/molecule.yml b/molecule/default/group_vars/all/molecule.yml
index 6fecc77..e1341f1 100644
--- a/molecule/default/group_vars/all/molecule.yml
+++ b/molecule/default/group_vars/all/molecule.yml
@@ -1,7 +1,8 @@
atmosphere_image: "{{ lookup('file', lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') + '/image') }}"
atmosphere_issuer_config:
- type: self-signed
+ # type: self-signed
+ email: mnaser@vexxhost.com
openstack_helm_glance_images:
- name: cirros
diff --git a/rabbitmq/README.md b/rabbitmq/README.md
new file mode 100644
index 0000000..4a53859
--- /dev/null
+++ b/rabbitmq/README.md
@@ -0,0 +1 @@
+# `rabbitmq`
diff --git a/rabbitmq/meta/main.yml b/rabbitmq/meta/main.yml
new file mode 100644
index 0000000..37118dc
--- /dev/null
+++ b/rabbitmq/meta/main.yml
@@ -0,0 +1,23 @@
+# Copyright (c) 2022 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.
+
+galaxy_info:
+ author: VEXXHOST, Inc.
+ description: Ansible role for RabbitMQ
+ license: Apache-2.0
+ min_ansible_version: 5.5.0
+ platforms:
+ - name: Ubuntu
+ versions:
+ - focal
diff --git a/rabbitmq/tasks/main.yml b/rabbitmq/tasks/main.yml
new file mode 100644
index 0000000..aed2e62
--- /dev/null
+++ b/rabbitmq/tasks/main.yml
@@ -0,0 +1,50 @@
+# Copyright (c) 2022 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.
+
+- name: Deploy cluster
+ kubernetes.core.k8s:
+ state: present
+ definition:
+ apiVersion: rabbitmq.com/v1beta1
+ kind: RabbitmqCluster
+ metadata:
+ name: "rabbitmq-{{ rabbitmq_cluster_name }}"
+ namespace: openstack
+ spec:
+ image: "{{ atmosphere_images['rabbitmq_server'] | docker_image('ref') }}"
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: openstack-control-plane
+ operator: In
+ values:
+ - enabled
+ rabbitmq:
+ additionalConfig: |
+ vm_memory_high_watermark.relative = 0.9
+ resources:
+ limits:
+ cpu: "1"
+ memory: 2Gi
+ requests:
+ cpu: 500m
+ memory: 1Gi
+ terminationGracePeriodSeconds: 15
+ wait: true
+ wait_timeout: 600
+ wait_condition:
+ type: ClusterAvailable
+ status: "True"
diff --git a/roles/atmosphere/templates/crds.yml b/roles/atmosphere/templates/crds.yml
index edc7e9f..2a31263 100644
--- a/roles/atmosphere/templates/crds.yml
+++ b/roles/atmosphere/templates/crds.yml
@@ -2,32 +2,6 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
- name: openstackhelmrabbitmqclusters.atmosphere.vexxhost.com
-spec:
- scope: Namespaced
- group: atmosphere.vexxhost.com
- names:
- kind: OpenstackHelmRabbitmqCluster
- plural: openstackhelmrabbitmqclusters
- singular: openstackhelmrabbitmqcluster
- versions:
- - name: v1alpha1
- served: true
- storage: true
- schema:
- openAPIV3Schema:
- type: object
- properties:
- spec:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- status:
- type: object
- x-kubernetes-preserve-unknown-fields: true
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
name: clouds.atmosphere.vexxhost.com
spec:
scope: Namespaced
diff --git a/roles/atmosphere/templates/resources.yml b/roles/atmosphere/templates/resources.yml
index bce31b0..c52dbc1 100644
--- a/roles/atmosphere/templates/resources.yml
+++ b/roles/atmosphere/templates/resources.yml
@@ -24,18 +24,6 @@
impliedRoleRef:
name: load-balancer-member
---
-apiVersion: v1
-kind: Secret
-metadata:
- name: atmosphere-secrets
- namespace: openstack
-stringData:
- keystone-admin-password: "{{ openstack_helm_endpoints_keystone_admin_password }}"
- magnum-database-password: "{{ openstack_helm_endpoints_magnum_mariadb_password }}"
- magnum-keystone-password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
- magnum-rabbitmq-password: "{{ openstack_helm_endpoints_magnum_rabbitmq_password }}"
- memcache-secret-key: "{{ openstack_helm_endpoints_memcached_secret_key }}"
----
apiVersion: atmosphere.vexxhost.com/v1alpha1
kind: Cloud
metadata:
diff --git a/roles/atmosphere/vars/main.yml b/roles/atmosphere/vars/main.yml
index 31b9832..85f1809 100644
--- a/roles/atmosphere/vars/main.yml
+++ b/roles/atmosphere/vars/main.yml
@@ -3,5 +3,3 @@
ingressClassName: "{{ openstack_helm_ingress_class_name | default('openstack') }}"
certManagerClusterIssuer: "{{ openstack_helm_ingress_cluster_issuer | default('atmosphere') }}"
regionName: "{{ openstack_helm_endpoints_region_name }}"
- magnum:
- endpoint: "{{ openstack_helm_endpoints_magnum_api_host }}"
diff --git a/roles/openstack_helm_barbican/tasks/main.yml b/roles/openstack_helm_barbican/tasks/main.yml
index a671853..0987b04 100644
--- a/roles/openstack_helm_barbican/tasks/main.yml
+++ b/roles/openstack_helm_barbican/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-barbican
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-barbican-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-barbican-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_cinder/tasks/main.yml b/roles/openstack_helm_cinder/tasks/main.yml
index 695987d..ab17686 100644
--- a/roles/openstack_helm_cinder/tasks/main.yml
+++ b/roles/openstack_helm_cinder/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-cinder
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-cinder-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-cinder-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_designate/tasks/main.yml b/roles/openstack_helm_designate/tasks/main.yml
index f189ede..fd2a06f 100644
--- a/roles/openstack_helm_designate/tasks/main.yml
+++ b/roles/openstack_helm_designate/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-designate
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-designate-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-designate-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_endpoints/tasks/main.yml b/roles/openstack_helm_endpoints/tasks/main.yml
index c8dc0b4..60cdfc7 100644
--- a/roles/openstack_helm_endpoints/tasks/main.yml
+++ b/roles/openstack_helm_endpoints/tasks/main.yml
@@ -19,6 +19,54 @@
when:
- openstack_helm_endpoints_list is not defined or openstack_helm_endpoints_list == None
+# NOTE(mnaser): Since we manage one-RabbitMQ per service, we create the RabbitMQ
+# cluster here and then append the necessary values to be used
+# inside the `oslo_messaging` section.
+- name: Configure "oslo.messaging"
+ when:
+ - '"oslo_messaging" in openstack_helm_endpoints_list'
+ block:
+ - name: Create RabbitMQ cluster
+ ansible.builtin.include_role:
+ name: rabbitmq
+ vars:
+ rabbitmq_cluster_name: "{{ openstack_helm_endpoints_chart }}"
+
+ - name: Grab RabbitMQ cluster secret
+ kubernetes.core.k8s_info:
+ api_version: v1
+ kind: Secret
+ name: "rabbitmq-{{ openstack_helm_endpoints_chart }}-default-user"
+ namespace: openstack
+ register: _openstack_helm_endpoints_rabbitmq_cluster_secret
+
+ - name: Cache fact with RabbitMQ cluster credentials
+ ansible.builtin.set_fact:
+ _openstack_helm_endpoints_rabbitmq_cluster_username: |-
+ {{ _openstack_helm_endpoints_rabbitmq_cluster_secret.resources[0]['data']['username'] | b64decode }}
+ _openstack_helm_endpoints_rabbitmq_cluster_password: |-
+ {{ _openstack_helm_endpoints_rabbitmq_cluster_secret.resources[0]['data']['password'] | b64decode }}
+
+# NOTE(mnaser): Since we deploy the database using the operator and we let it
+# generate the root password, we look it up if the fact has not
+# been cached from a previous run.
+- name: Configure "oslo.db"
+ when:
+ - '"oslo_db" in openstack_helm_endpoints_list'
+ - openstack_helm_endpoints_mariadb_admin_password is not defined
+ block:
+ - name: Grab Percona XtraDB cluster secret
+ kubernetes.core.k8s_info:
+ api_version: v1
+ kind: Secret
+ name: percona-xtradb
+ namespace: openstack
+ register: _openstack_helm_endpoints_oslo_db_secret
+
+ - name: Cache fact with Percona XtraDB password
+ ansible.builtin.set_fact:
+ openstack_helm_endpoints_mariadb_admin_password: "{{ _openstack_helm_endpoints_oslo_db_secret.resources[0]['data']['root'] | b64decode }}"
+
- name: Reset value for OpenStack_Helm endpoints
ansible.builtin.set_fact:
openstack_helm_endpoints: "{{ openstack_helm_endpoints_config }}"
diff --git a/roles/openstack_helm_endpoints/vars/main.yml b/roles/openstack_helm_endpoints/vars/main.yml
index 98bb122..391cdec 100644
--- a/roles/openstack_helm_endpoints/vars/main.yml
+++ b/roles/openstack_helm_endpoints/vars/main.yml
@@ -30,11 +30,24 @@
_openstack_helm_endpoints_oslo_db:
oslo_db:
+ auth:
+ admin:
+ password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
hosts:
default: percona-xtradb-haproxy
_openstack_helm_endpoints_oslo_messaging:
oslo_messaging:
+ auth:
+ user:
+ username: "{{ _openstack_helm_endpoints_rabbitmq_cluster_username }}"
+ password: "{{ _openstack_helm_endpoints_rabbitmq_cluster_password }}"
+ # NOTE(mnaser): The following is not actually used by the chart, however,
+ # since we are actually doing dynamic lookups to generate
+ # endpoints, we add it here.
+ admin:
+ username: "{{ _openstack_helm_endpoints_rabbitmq_cluster_username }}"
+ password: "{{ _openstack_helm_endpoints_rabbitmq_cluster_password }}"
statefulset: null
hosts:
default: "rabbitmq-{{ openstack_helm_endpoints_chart }}"
@@ -216,6 +229,8 @@
_openstack_helm_endpoints_oslo_db_api:
oslo_db_api:
auth:
+ admin:
+ password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
nova:
password: "{{ openstack_helm_endpoints_nova_mariadb_password }}"
hosts:
@@ -224,6 +239,8 @@
_openstack_helm_endpoints_oslo_db_cell0:
oslo_db_cell0:
auth:
+ admin:
+ password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
nova:
password: "{{ openstack_helm_endpoints_nova_mariadb_password }}"
hosts:
@@ -446,6 +463,10 @@
region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
username: "magnum-{{ openstack_helm_endpoints_magnum_region_name }}"
password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
+ magnum_stack_user:
+ region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
+ username: "magnum-domain-{{ openstack_helm_endpoints_magnum_region_name }}"
+ password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
container_infra:
scheme:
public: https
diff --git a/roles/openstack_helm_glance/tasks/main.yml b/roles/openstack_helm_glance/tasks/main.yml
index 6743778..9b2041c 100644
--- a/roles/openstack_helm_glance/tasks/main.yml
+++ b/roles/openstack_helm_glance/tasks/main.yml
@@ -77,18 +77,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-glance
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-glance-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-glance-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_heat/tasks/main.yml b/roles/openstack_helm_heat/tasks/main.yml
index d9ec7bd..ccb0ef7 100644
--- a/roles/openstack_helm_heat/tasks/main.yml
+++ b/roles/openstack_helm_heat/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-heat
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-heat-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-heat-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_horizon/tasks/main.yml b/roles/openstack_helm_horizon/tasks/main.yml
index 189099d..e10a794 100644
--- a/roles/openstack_helm_horizon/tasks/main.yml
+++ b/roles/openstack_helm_horizon/tasks/main.yml
@@ -52,10 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-horizon
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_keystone/tasks/main.yml b/roles/openstack_helm_keystone/tasks/main.yml
index 684399c..44d866f 100644
--- a/roles/openstack_helm_keystone/tasks/main.yml
+++ b/roles/openstack_helm_keystone/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-keystone
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-keystone-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-keystone-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_magnum/README.md b/roles/openstack_helm_magnum/README.md
new file mode 100644
index 0000000..d4cf7d3
--- /dev/null
+++ b/roles/openstack_helm_magnum/README.md
@@ -0,0 +1 @@
+# `openstack_helm_magnum`
diff --git a/roles/openstack_helm_magnum/defaults/main.yml b/roles/openstack_helm_magnum/defaults/main.yml
index d291f86..21650de 100644
--- a/roles/openstack_helm_magnum/defaults/main.yml
+++ b/roles/openstack_helm_magnum/defaults/main.yml
@@ -1,19 +1,25 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
-
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-# :local:
-
-
-# .. envvar:: openstack_helm_magnum_images [[[
+# Copyright (c) 2023 VEXXHOST, Inc.
#
-# List of images for magnum clusters
+# 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.
+
+openstack_helm_magnum_helm_release_name: magnum
+openstack_helm_magnum_helm_chart_path: "{{ role_path }}/../../charts/magnum/"
+openstack_helm_magnum_helm_chart_ref: /usr/local/src/magnum
+
+openstack_helm_magnum_helm_release_namespace: openstack
+openstack_helm_magnum_helm_values: {}
+
+# List of images to load into OpenStack for Magnum
openstack_helm_magnum_images:
- name: ubuntu-2004-v1.23.13
source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/
@@ -31,7 +37,5 @@
disk_format: qcow2
container_format: bare
- # ]]]
-
# List of annotations to apply to the Ingress
openstack_helm_magnum_ingress_annotations: {}
diff --git a/roles/openstack_helm_magnum/meta/main.yml b/roles/openstack_helm_magnum/meta/main.yml
index f639330..73d42b6 100644
--- a/roles/openstack_helm_magnum/meta/main.yml
+++ b/roles/openstack_helm_magnum/meta/main.yml
@@ -24,7 +24,11 @@
dependencies:
- role: defaults
- - role: openstacksdk
- - role: openstack_cli
- - role: openstack_helm_barbican
- - role: openstack_helm_octavia
+ - role: openstack_helm_endpoints
+ vars:
+ openstack_helm_endpoints_repo_name: openstack-helm
+ openstack_helm_endpoints_chart: magnum
+ - role: upload_helm_chart
+ vars:
+ upload_helm_chart_src: "{{ openstack_helm_magnum_helm_chart_path }}"
+ upload_helm_chart_dest: "{{ openstack_helm_magnum_helm_chart_ref }}"
diff --git a/roles/openstack_helm_magnum/tasks/main.yml b/roles/openstack_helm_magnum/tasks/main.yml
index 0d4204c..31df009 100644
--- a/roles/openstack_helm_magnum/tasks/main.yml
+++ b/roles/openstack_helm_magnum/tasks/main.yml
@@ -12,12 +12,40 @@
# License for the specific language governing permissions and limitations
# under the License.
-- name: Generate OpenStack-Helm endpoints
- ansible.builtin.include_role:
- name: openstack_helm_endpoints
- vars:
- openstack_helm_endpoints_repo_name: openstack-helm
- openstack_helm_endpoints_chart: magnum
+# NOTE(mnaser): We should get rid of this task eventually as it is suspending
+# the old HelmRelease and removing it to avoid uninstalling the
+# Helm chart.
+- name: Uninstall the legacy HelmRelease
+ run_once: true
+ block:
+ - name: Suspend the existing HelmRelease
+ kubernetes.core.k8s:
+ state: patched
+ api_version: helm.toolkit.fluxcd.io/v2beta1
+ kind: HelmRelease
+ name: "{{ openstack_helm_magnum_helm_release_name }}"
+ namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+ definition:
+ spec:
+ suspend: true
+
+ - name: Remove the existing HelmRelease
+ kubernetes.core.k8s:
+ state: absent
+ api_version: helm.toolkit.fluxcd.io/v2beta1
+ kind: HelmRelease
+ name: "{{ openstack_helm_magnum_helm_release_name }}"
+ namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+
+- name: Deploy Helm chart
+ run_once: true
+ kubernetes.core.helm:
+ name: "{{ openstack_helm_magnum_helm_release_name }}"
+ chart_ref: "{{ openstack_helm_magnum_helm_chart_ref }}"
+ release_namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+ create_namespace: true
+ kubeconfig: /etc/kubernetes/admin.conf
+ values: "{{ _openstack_helm_magnum_helm_values | combine(openstack_helm_magnum_helm_values, recursive=True) }}"
- name: Deploy Helm chart
kubernetes.core.k8s:
diff --git a/roles/openstack_helm_magnum/vars/main.yml b/roles/openstack_helm_magnum/vars/main.yml
new file mode 100644
index 0000000..b29e430
--- /dev/null
+++ b/roles/openstack_helm_magnum/vars/main.yml
@@ -0,0 +1,73 @@
+# Copyright (c) 2023 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.
+
+_openstack_helm_magnum_helm_values:
+ endpoints: "{{ openstack_helm_endpoints }}"
+ images:
+ pull_policy: Always
+ tags: "{{ atmosphere_images | openstack_helm_image_tags('magnum') }}"
+ conf:
+ magnum:
+ DEFAULT:
+ log_config_append: null
+ barbican_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_barbican_region_name }}"
+ cinder_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_cinder_region_name }}"
+ cluster_template:
+ kubernetes_allowed_network_drivers: calico
+ kubernetes_default_network_driver: calico
+ conductor:
+ workers: 4
+ drivers:
+ verify_ca: false
+ glance_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_glance_region_name }}"
+ heat_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_heat_region_name }}"
+ keystone_auth:
+ auth_url: http://keystone-api.openstack.svc.cluster.local:5000/v3
+ user_domain_name: service
+ username: "magnum-{{ openstack_helm_endpoints_magnum_region_name }}"
+ password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
+ # NOTE(mnaser): Magnum does not allow changing the interface to internal
+ # so we workaround with this for now.
+ insecure: true
+ keystone_authtoken:
+ # NOTE(mnaser): Magnum does not allow changing the interface to internal
+ # so we workaround with this for now.
+ insecure: true
+ magnum_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
+ neutron_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_neutron_region_name }}"
+ nova_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_nova_region_name }}"
+ octavia_client:
+ endpoint_type: internalURL
+ region_name: "{{ openstack_helm_endpoints_octavia_region_name }}"
+ pod:
+ replicas:
+ api: 3
+ conductor: 3
+ manifests:
+ ingress_api: false
+ service_ingress_api: false
diff --git a/roles/openstack_helm_neutron/tasks/main.yml b/roles/openstack_helm_neutron/tasks/main.yml
index 61d27be..47c1783 100644
--- a/roles/openstack_helm_neutron/tasks/main.yml
+++ b/roles/openstack_helm_neutron/tasks/main.yml
@@ -77,18 +77,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-neutron
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-neutron-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-neutron-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_nova/tasks/main.yml b/roles/openstack_helm_nova/tasks/main.yml
index 335b589..090fcf7 100644
--- a/roles/openstack_helm_nova/tasks/main.yml
+++ b/roles/openstack_helm_nova/tasks/main.yml
@@ -83,26 +83,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-nova
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db_api.auth.admin.password
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db_cell0.auth.admin.password
- - kind: Secret
- name: rabbitmq-nova-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-nova-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_octavia/tasks/main.yml b/roles/openstack_helm_octavia/tasks/main.yml
index 0d5f677..2047c27 100644
--- a/roles/openstack_helm_octavia/tasks/main.yml
+++ b/roles/openstack_helm_octavia/tasks/main.yml
@@ -233,18 +233,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-octavia
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-octavia-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-octavia-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_placement/tasks/main.yml b/roles/openstack_helm_placement/tasks/main.yml
index 020eb49..2407329 100644
--- a/roles/openstack_helm_placement/tasks/main.yml
+++ b/roles/openstack_helm_placement/tasks/main.yml
@@ -52,10 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-placement
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role:
diff --git a/roles/openstack_helm_senlin/tasks/main.yml b/roles/openstack_helm_senlin/tasks/main.yml
index 963fe2d..97b11d7 100644
--- a/roles/openstack_helm_senlin/tasks/main.yml
+++ b/roles/openstack_helm_senlin/tasks/main.yml
@@ -52,18 +52,6 @@
valuesFrom:
- kind: Secret
name: atmosphere-senlin
- - kind: Secret
- name: percona-xtradb
- valuesKey: root
- targetPath: endpoints.oslo_db.auth.admin.password
- - kind: Secret
- name: rabbitmq-senlin-default-user
- valuesKey: username
- targetPath: endpoints.oslo_messaging.auth.admin.username
- - kind: Secret
- name: rabbitmq-senlin-default-user
- valuesKey: password
- targetPath: endpoints.oslo_messaging.auth.admin.password
- name: Create Ingress
ansible.builtin.include_role: