fix: add ansible-based ingress
diff --git a/atmosphere/cmd/operator.py b/atmosphere/cmd/operator.py
index f1e931b..ca8aeb1 100644
--- a/atmosphere/cmd/operator.py
+++ b/atmosphere/cmd/operator.py
@@ -43,34 +43,3 @@
),
spec=types.OpenstackHelmRabbitmqClusterSpec(**spec),
).delete_rabbitmq_cluster()
-
-
-@kopf.on.create(constants.API_VERSION_ATMOSPHERE, constants.KIND_OPENSTACK_HELM_INGRESS)
-@kopf.on.resume(constants.API_VERSION_ATMOSPHERE, constants.KIND_OPENSTACK_HELM_INGRESS)
-def create_openstack_helm_ingress(
- namespace: str, name: str, annotations: dict, labels: dict, spec: dict, **_
-):
- api = clients.get_pykube_api()
- objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace=namespace,
- annotations=utils.filter_annotations(annotations),
- labels=labels,
- ),
- spec=types.OpenstackHelmIngressSpec(**spec),
- ).apply_ingress()
-
-
-@kopf.on.delete(constants.API_VERSION_ATMOSPHERE, constants.KIND_OPENSTACK_HELM_INGRESS)
-def delete_openstack_helm_ingress(namespace: str, name: str, spec: dict, **_):
- api = clients.get_pykube_api()
- objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace=namespace,
- ),
- spec=types.OpenstackHelmIngressSpec(**spec),
- ).delete_ingress()
diff --git a/atmosphere/operator/api/objects.py b/atmosphere/operator/api/objects.py
index d668b00..0ef37b0 100644
--- a/atmosphere/operator/api/objects.py
+++ b/atmosphere/operator/api/objects.py
@@ -104,130 +104,3 @@
).get_or_none(name=f"rabbitmq-{self.metadata.name}")
if rabbitmq_cluster:
rabbitmq_cluster.delete()
-
-
-class OpenstackHelmIngress(types.NamespacedKubernetesObject):
- endpoint: ClassVar[str] = "openstackhelmingresses"
-
- kind: str = Field(constants.KIND_OPENSTACK_HELM_INGRESS, const=True)
- metadata: types.OpenstackHelmIngressObjectMeta
- spec: types.OpenstackHelmIngressSpec
-
- ENDPOINT_TO_SERVICE_MAPPING: ClassVar[dict] = {
- types.OpenstackHelmIngressObjectMetaName.cloudformation: types.IngressServiceBackend(
- name="heat-cfn",
- port=types.ServiceBackendPort(number=8000),
- ),
- types.OpenstackHelmIngressObjectMetaName.clustering: types.IngressServiceBackend(
- name="senlin-api",
- port=types.ServiceBackendPort(number=8778),
- ),
- types.OpenstackHelmIngressObjectMetaName.compute: types.IngressServiceBackend(
- name="nova-api",
- port=types.ServiceBackendPort(number=8774),
- ),
- types.OpenstackHelmIngressObjectMetaName.compute_novnc_proxy: types.IngressServiceBackend(
- name="nova-novncproxy",
- port=types.ServiceBackendPort(number=6080),
- ),
- types.OpenstackHelmIngressObjectMetaName.container_infra: types.IngressServiceBackend(
- name="magnum-api",
- port=types.ServiceBackendPort(number=9511),
- ),
- types.OpenstackHelmIngressObjectMetaName.container_infra_registry: types.IngressServiceBackend(
- name="magnum-registry",
- port=types.ServiceBackendPort(number=5000),
- ),
- types.OpenstackHelmIngressObjectMetaName.dashboard: types.IngressServiceBackend(
- name="horizon-int",
- port=types.ServiceBackendPort(number=80),
- ),
- types.OpenstackHelmIngressObjectMetaName.identity: types.IngressServiceBackend(
- name="keystone-api",
- port=types.ServiceBackendPort(number=5000),
- ),
- types.OpenstackHelmIngressObjectMetaName.image: types.IngressServiceBackend(
- name="glance-api",
- port=types.ServiceBackendPort(number=9292),
- ),
- types.OpenstackHelmIngressObjectMetaName.key_manager: types.IngressServiceBackend(
- name="barbican-api",
- port=types.ServiceBackendPort(number=9311),
- ),
- types.OpenstackHelmIngressObjectMetaName.load_balancer: types.IngressServiceBackend(
- name="octavia-api",
- port=types.ServiceBackendPort(number=9876),
- ),
- types.OpenstackHelmIngressObjectMetaName.network: types.IngressServiceBackend(
- name="neutron-server",
- port=types.ServiceBackendPort(number=9696),
- ),
- types.OpenstackHelmIngressObjectMetaName.orchestration: types.IngressServiceBackend(
- name="heat-api",
- port=types.ServiceBackendPort(number=8004),
- ),
- types.OpenstackHelmIngressObjectMetaName.placement: types.IngressServiceBackend(
- name="placement-api",
- port=types.ServiceBackendPort(number=8778),
- ),
- types.OpenstackHelmIngressObjectMetaName.volumev3: types.IngressServiceBackend(
- name="cinder-api",
- port=types.ServiceBackendPort(number=8776),
- ),
- }
-
- @property
- def service(self):
- return self.ENDPOINT_TO_SERVICE_MAPPING[self.metadata.name]
-
- def apply_ingress(self) -> Ingress:
- return Ingress(
- self.api,
- {
- "apiVersion": Ingress.version,
- "kind": Ingress.kind,
- "metadata": {
- "name": self.metadata.name,
- "namespace": self.metadata.namespace,
- "labels": self.metadata.labels,
- "annotations": {
- **{
- "cert-manager.io/cluster-issuer": self.spec.clusterIssuer,
- },
- **self.metadata.annotations,
- },
- },
- "spec": {
- "ingressClassName": self.spec.ingressClassName,
- "rules": [
- {
- "host": self.spec.host,
- "http": {
- "paths": [
- {
- "path": "/",
- "pathType": "Prefix",
- "backend": {
- "service": self.service.dict(),
- },
- },
- ],
- },
- },
- ],
- "tls": [
- {
- "secretName": f"{self.service.name}-certs",
- "hosts": [self.spec.host],
- }
- ],
- },
- },
- ).apply()
-
- def delete_ingress(self) -> None:
- ingress = Ingress.objects(
- self.api, namespace=self.metadata.namespace
- ).get_or_none(name=self.metadata.name)
- if ingress:
- ingress.delete()
diff --git a/atmosphere/operator/api/types.py b/atmosphere/operator/api/types.py
index 1a44267..1df4516 100644
--- a/atmosphere/operator/api/types.py
+++ b/atmosphere/operator/api/types.py
@@ -177,31 +177,3 @@
class OpenstackHelmRabbitmqClusterSpec(pydantic.BaseModel):
image: pydantic.constr(min_length=1)
-
-
-class OpenstackHelmIngressObjectMetaName(str, Enum):
- cloudformation = "cloudformation"
- clustering = "clustering"
- compute = "compute"
- compute_novnc_proxy = "compute-novnc-proxy"
- container_infra = "container-infra"
- container_infra_registry = "container-infra-registry"
- dashboard = "dashboard"
- identity = "identity"
- image = "image"
- key_manager = "key-manager"
- load_balancer = "load-balancer"
- network = "network"
- orchestration = "orchestration"
- placement = "placement"
- volumev3 = "volumev3"
-
-
-class OpenstackHelmIngressObjectMeta(NamespacedObjectMeta):
- name: OpenstackHelmIngressObjectMetaName
-
-
-class OpenstackHelmIngressSpec(pydantic.BaseModel):
- clusterIssuer: pydantic.constr(min_length=1) = "atmosphere"
- ingressClassName: pydantic.constr(min_length=1) = "atmosphere"
- host: Hostname
diff --git a/atmosphere/operator/constants.py b/atmosphere/operator/constants.py
index 3fd102d..8aa2b71 100644
--- a/atmosphere/operator/constants.py
+++ b/atmosphere/operator/constants.py
@@ -1,7 +1,6 @@
API_VERSION_ATMOSPHERE = "atmosphere.vexxhost.com/v1alpha1"
KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER = "OpenstackHelmRabbitmqCluster"
-KIND_OPENSTACK_HELM_INGRESS = "OpenstackHelmIngress"
IMAGE_LIST = {
"alertmanager": "quay.io/prometheus/alertmanager:v0.24.0",
diff --git a/atmosphere/operator/controllers/cloud.py b/atmosphere/operator/controllers/cloud.py
index 0ea5dc2..a5f06ec 100644
--- a/atmosphere/operator/controllers/cloud.py
+++ b/atmosphere/operator/controllers/cloud.py
@@ -71,18 +71,6 @@
},
),
)
- objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name="container-infra",
- namespace=namespace,
- ),
- spec=types.OpenstackHelmIngressSpec(
- clusterIssuer=spec["certManagerClusterIssuer"],
- ingressClassName=spec["ingressClassName"],
- host=spec["magnum"]["endpoint"],
- ),
- ).apply()
objects.OpenstackHelmRabbitmqCluster(
api=api,
diff --git a/atmosphere/tests/unit/operator/test_objects.py b/atmosphere/tests/unit/operator/test_objects.py
index a2fbbcd..ad682e7 100644
--- a/atmosphere/tests/unit/operator/test_objects.py
+++ b/atmosphere/tests/unit/operator/test_objects.py
@@ -1,6 +1,5 @@
import json
-import pytest
import responses
from hypothesis import given
from hypothesis import provisional as prov
@@ -407,208 +406,3 @@
instance.delete_rabbitmq_cluster()
assert len(rsps.calls) == 1
-
-
-class TestOpenstackHelmIngress:
- @given(st.builds(objects.OpenstackHelmIngress))
- def test_property(self, instance):
- assert isinstance(instance, objects.OpenstackHelmIngress)
- assert isinstance(instance.metadata, types.OpenstackHelmIngressObjectMeta)
- assert isinstance(instance.spec, types.OpenstackHelmIngressSpec)
-
- def test_endpont_to_service_mapping_order(self):
- assert [*objects.OpenstackHelmIngress.ENDPOINT_TO_SERVICE_MAPPING] == sorted(
- [*objects.OpenstackHelmIngress.ENDPOINT_TO_SERVICE_MAPPING]
- )
-
- @pytest.mark.parametrize("name", types.OpenstackHelmIngressObjectMetaName)
- def test_service(self, name):
- instance = objects.OpenstackHelmIngress(
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace="default",
- ),
- spec=types.OpenstackHelmIngressSpec(
- host=f"{name}.example.com",
- ),
- )
-
- assert instance.service is not None
-
- @pytest.mark.parametrize("name", types.OpenstackHelmIngressObjectMetaName)
- def test_apply(self, api, requests_mock, name):
- instance = objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmIngressSpec(
- host=f"{name}.example.com",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.PATCH,
- f"https://localhost:9443/apis/atmosphere.vexxhost.com/v1alpha1/namespaces/default/openstackhelmingresses/{name}?fieldManager=atmosphere-operator&force=True", # noqa
- json={},
- )
-
- instance.apply()
-
- assert len(rsps.calls) == 1
- assert json.loads(rsps.calls[0].request.body) == {
- "apiVersion": "atmosphere.vexxhost.com/v1alpha1",
- "kind": "OpenstackHelmIngress",
- "metadata": {
- "name": name,
- "namespace": "default",
- "annotations": {
- "annotate": "this",
- },
- "labels": {
- "foo": "bar",
- },
- },
- "spec": {
- "host": f"{name}.example.com",
- "clusterIssuer": "atmosphere",
- "ingressClassName": "atmosphere",
- },
- }
-
- @pytest.mark.parametrize("name", types.OpenstackHelmIngressObjectMetaName)
- def test_apply_ingress(self, api, requests_mock, name):
- instance = objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace="default",
- annotations={
- "annotate": "this",
- },
- labels={
- "foo": "bar",
- },
- ),
- spec=types.OpenstackHelmIngressSpec(
- host=f"{name}.example.com",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.PATCH,
- f"https://localhost:9443/apis/networking.k8s.io/v1/namespaces/default/ingresses/{name}?fieldManager=atmosphere-operator&force=True", # noqa
- json={},
- )
-
- instance.apply_ingress()
-
- assert len(rsps.calls) == 1
- assert json.loads(rsps.calls[0].request.body) == {
- "apiVersion": "networking.k8s.io/v1",
- "kind": "Ingress",
- "metadata": {
- "name": name,
- "namespace": "default",
- "labels": {
- "foo": "bar",
- },
- "annotations": {
- "annotate": "this",
- "cert-manager.io/cluster-issuer": "atmosphere",
- },
- },
- "spec": {
- "ingressClassName": "atmosphere",
- "rules": [
- {
- "host": f"{name}.example.com",
- "http": {
- "paths": [
- {
- "path": "/",
- "pathType": "Prefix",
- "backend": {
- "service": {
- "name": instance.service.name,
- "port": {
- "number": instance.service.port.number,
- },
- },
- },
- },
- ],
- },
- },
- ],
- "tls": [
- {
- "secretName": f"{instance.service.name}-certs",
- "hosts": [f"{name}.example.com"],
- }
- ],
- },
- }
-
- @pytest.mark.parametrize("name", types.OpenstackHelmIngressObjectMetaName)
- def test_delete_ingress(self, api, requests_mock, name):
- instance = objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace="default",
- ),
- spec=types.OpenstackHelmIngressSpec(
- host=f"{name}.example.com",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.GET,
- f"https://localhost:9443/apis/networking.k8s.io/v1/namespaces/default/ingresses/{name}", # noqa
- json={
- "metadata": {
- "name": instance.metadata.name,
- },
- },
- )
- rsps.add(
- responses.DELETE,
- f"https://localhost:9443/apis/networking.k8s.io/v1/namespaces/default/ingresses/{name}", # noqa
- )
-
- instance.delete_ingress()
- assert len(rsps.calls) == 2
-
- @pytest.mark.parametrize("name", types.OpenstackHelmIngressObjectMetaName)
- def test_delete_missing_ingress(self, api, requests_mock, name):
- instance = objects.OpenstackHelmIngress(
- api=api,
- metadata=types.OpenstackHelmIngressObjectMeta(
- name=name,
- namespace="default",
- ),
- spec=types.OpenstackHelmIngressSpec(
- host=f"{name}.example.com",
- ),
- )
-
- with requests_mock as rsps:
- rsps.add(
- responses.GET,
- f"https://localhost:9443/apis/networking.k8s.io/v1/namespaces/default/ingresses/{name}", # noqa
- status=404,
- )
-
- instance.delete_ingress()
- assert len(rsps.calls) == 1
diff --git a/atmosphere/tests/unit/operator/test_types.py b/atmosphere/tests/unit/operator/test_types.py
index 8acf233..246dc69 100644
--- a/atmosphere/tests/unit/operator/test_types.py
+++ b/atmosphere/tests/unit/operator/test_types.py
@@ -157,26 +157,3 @@
assert isinstance(instance, types.OpenstackHelmRabbitmqClusterSpec)
assert isinstance(instance.image, str)
assert instance.image != ""
-
-
-class TestOpenstackHelmIngressObjectMetaName:
- def test_name_order(self):
- assert [*types.OpenstackHelmIngressObjectMetaName] == sorted(
- [*types.OpenstackHelmIngressObjectMetaName]
- )
-
-
-class TestOpenstackHelmIngressObjectMeta:
- @given(st.builds(types.OpenstackHelmIngressObjectMeta))
- def test_property(self, instance):
- assert isinstance(instance, types.OpenstackHelmIngressObjectMeta)
- assert isinstance(instance.name, types.OpenstackHelmIngressObjectMetaName)
-
-
-class TestOpenstackHelmIngressSpec:
- @given(st.builds(types.OpenstackHelmIngressSpec))
- def test_property(self, instance):
- assert isinstance(instance, types.OpenstackHelmIngressSpec)
- assert instance.clusterIssuer != ""
- assert instance.ingressClassName != ""
- assert instance.host != ""
diff --git a/roles/atmosphere/templates/crds.yml b/roles/atmosphere/templates/crds.yml
index db56695..edc7e9f 100644
--- a/roles/atmosphere/templates/crds.yml
+++ b/roles/atmosphere/templates/crds.yml
@@ -28,32 +28,6 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
- name: openstackhelmingresses.atmosphere.vexxhost.com
-spec:
- scope: Namespaced
- group: atmosphere.vexxhost.com
- names:
- kind: OpenstackHelmIngress
- plural: openstackhelmingresses
- singular: openstackhelmingress
- 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/openstack_helm_horizon/tasks/main.yml b/roles/openstack_helm_horizon/tasks/main.yml
index 460634a..424ea08 100644
--- a/roles/openstack_helm_horizon/tasks/main.yml
+++ b/roles/openstack_helm_horizon/tasks/main.yml
@@ -66,12 +66,3 @@
openstack_helm_ingress_service_name: horizon-int
openstack_helm_ingress_service_port: 80
openstack_helm_ingress_annotations: "{{ openstack_helm_horizon_ingress_annotations }}"
- # NOTE: Remove grafana path from horizon ingress till monasca realized
- # openstack_helm_ingress_paths:
- # - path: /grafana
- # pathType: Prefix
- # backend:
- # service:
- # name: grafana
- # port:
- # number: 80
diff --git a/roles/openstack_helm_ingress/defaults/main.yml b/roles/openstack_helm_ingress/defaults/main.yml
index 1ae03fe..9dacdb1 100644
--- a/roles/openstack_helm_ingress/defaults/main.yml
+++ b/roles/openstack_helm_ingress/defaults/main.yml
@@ -1,25 +1,21 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
+# Name of the OpenStack-Helm Ingress to create
+openstack_helm_ingress_name: "{{ openstack_helm_ingress_endpoint | replace('_', '-') }}"
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-# :local:
-
-
-# .. envvar:: openstack_helm_ingress_annotations [[[
-#
-# Additional annotations to include for Kubernetes ingress
+# List of annotations to apply to the Ingress
openstack_helm_ingress_annotations: {}
- # ]]]
-# .. envvar:: openstack_helm_ingress_paths [[[
-#
-# Additional paths to include for Kubernetes ingress
-openstack_helm_ingress_paths: []
+# Hostname to expose for the Ingress
+openstack_helm_ingress_host: "{{ openstack_helm_endpoints[openstack_helm_ingress_endpoint]['host_fqdn_override']['public']['host'] }}"
- # ]]]
+# Name of the "cert-manager" ClusterIssuer to use for TLS certificates
+openstack_helm_ingress_cluster_issuer: atmosphere
+
+# Name of the Ingress class to use for exposing the service.
+openstack_helm_ingress_class_name: openstack
+
+# Secret containing the TLS certificate to use for the Ingress, overriding this
+# value globally should allow to point towards a secret containing the custom
+# certificate.
+#
+# See: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
+openstack_helm_ingress_secret_name: "{{ openstack_helm_ingress_service_name }}-certs"
diff --git a/roles/openstack_helm_ingress/tasks/main.yml b/roles/openstack_helm_ingress/tasks/main.yml
index cf2b287..ae13029 100644
--- a/roles/openstack_helm_ingress/tasks/main.yml
+++ b/roles/openstack_helm_ingress/tasks/main.yml
@@ -12,17 +12,37 @@
# License for the specific language governing permissions and limitations
# under the License.
-- name: Create Ingress {{ openstack_helm_ingress_endpoint }}
+- name: Create Ingress {{ openstack_helm_ingress_name }}
kubernetes.core.k8s:
state: present
definition:
- apiVersion: atmosphere.vexxhost.com/v1alpha1
- kind: OpenstackHelmIngress
+ apiVersion: v1
+ kind: Ingress
metadata:
- name: "{{ openstack_helm_ingress_endpoint | replace('_', '-') }}"
+ name: "{{ openstack_helm_ingress_name }}"
namespace: openstack
- annotations: "{{ openstack_helm_ingress_annotations }}"
+ annotations: "{{ _openstack_helm_ingress_annotations | combine(openstack_helm_ingress_annotations, recursive=True) }}"
spec:
- clusterIssuer: "{{ openstack_helm_ingress_cluster_issuer | default('atmosphere') }}"
- ingressClassName: "{{ openstack_helm_ingress_class_name | default('openstack') }}"
- host: "{{ openstack_helm_endpoints[openstack_helm_ingress_endpoint]['host_fqdn_override']['public']['host'] }}"
+ ingressClassName: "{{ openstack_helm_ingress_class_name }}"
+ rules:
+ - host: "{{ openstack_helm_ingress_host }}"
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: "{{ openstack_helm_ingress_service_name }}"
+ port:
+ number: "{{ openstack_helm_ingress_service_port }}"
+ tls:
+ - secretName: "{{ openstack_helm_ingress_secret_name }}"
+ hosts:
+ - "{{ openstack_helm_ingress_host }}"
+ # NOTE(mnaser): The Atmosphere operator is so fast that the Ingress webhook
+ # is not up yet by the time we run this for the first time, so
+ # we retry until we let the operator handle creating the ingress.
+ retries: 60
+ delay: 5
+ register: _result
+ until: _result is not failed
diff --git a/roles/openstack_helm_ingress/vars/main.yml b/roles/openstack_helm_ingress/vars/main.yml
new file mode 100644
index 0000000..a1debf7
--- /dev/null
+++ b/roles/openstack_helm_ingress/vars/main.yml
@@ -0,0 +1,16 @@
+# 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.
+
+_openstack_helm_ingress_annotations:
+ cert-manager.io/cluster-issuer: "{{ openstack_helm_ingress_cluster_issuer }}"
diff --git a/roles/openstack_helm_magnum/defaults/main.yml b/roles/openstack_helm_magnum/defaults/main.yml
index b693bc7..d291f86 100644
--- a/roles/openstack_helm_magnum/defaults/main.yml
+++ b/roles/openstack_helm_magnum/defaults/main.yml
@@ -32,3 +32,6 @@
container_format: bare
# ]]]
+
+# List of annotations to apply to the Ingress
+openstack_helm_magnum_ingress_annotations: {}
diff --git a/roles/openstack_helm_magnum/tasks/main.yml b/roles/openstack_helm_magnum/tasks/main.yml
index 0ee4691..69e3819 100644
--- a/roles/openstack_helm_magnum/tasks/main.yml
+++ b/roles/openstack_helm_magnum/tasks/main.yml
@@ -322,6 +322,15 @@
nodeSelector:
openstack-control-plane: enabled
+- name: Create Ingress
+ ansible.builtin.include_role:
+ name: openstack_helm_ingress
+ vars:
+ openstack_helm_ingress_endpoint: container_infra
+ openstack_helm_ingress_service_name: magnum-api
+ openstack_helm_ingress_service_port: 9511
+ openstack_helm_ingress_annotations: "{{ openstack_helm_magnum_ingress_annotations }}"
+
- name: Create magnum registry Ingress
ansible.builtin.include_role:
name: openstack_helm_ingress