feat: switch openstack-helm-infra to atmosphere
diff --git a/atmosphere/flows.py b/atmosphere/flows.py
index 1f1b4bb..649e038 100644
--- a/atmosphere/flows.py
+++ b/atmosphere/flows.py
@@ -1,7 +1,7 @@
-from taskflow.patterns import graph_flow, linear_flow
+from taskflow.patterns import graph_flow
 
 from atmosphere.config import CONF
-from atmosphere.tasks import kubernetes, openstack_helm
+from atmosphere.tasks import flux, kubernetes, openstack_helm
 
 
 def generate_for_openstack_helm_chart(chart):
@@ -16,6 +16,14 @@
     return flow
 
 
-DEPLOY = linear_flow.Flow("deploy").add(
+DEPLOY = graph_flow.Flow("deploy").add(
+    flux.EnsureHelmRepositoryTask(
+        provides="openstack-helm-infra",
+        inject={
+            "namespace": "openstack",
+            "name": "openstack-helm-infra",
+            "url": "https://tarballs.opendev.org/openstack/openstack-helm-infra/",
+        },
+    ),
     generate_for_openstack_helm_chart("memcached"),
 )
diff --git a/atmosphere/tasks/flux.py b/atmosphere/tasks/flux.py
new file mode 100644
index 0000000..4fe9a2c
--- /dev/null
+++ b/atmosphere/tasks/flux.py
@@ -0,0 +1,43 @@
+import pykube
+from taskflow import task
+
+from atmosphere import clients, logger
+
+LOG = logger.get_logger()
+
+
+class HelmRepository(pykube.objects.NamespacedAPIObject):
+    version = "source.toolkit.fluxcd.io/v1beta2"
+    endpoint = "helmrepositories"
+    kind = "HelmRepository"
+
+
+class EnsureHelmRepositoryTask(task.Task):
+    def execute(self, namespace, name, url, *args, **kwargs):
+        log = LOG.bind(kind="HelmRelease", namespace=namespace, name=name)
+        api = clients.get_pykube_api()
+
+        log.debug("Ensuring HelmRepository")
+        repository = HelmRepository(
+            api,
+            {
+                "apiVersion": "source.toolkit.fluxcd.io/v1beta2",
+                "kind": "HelmRepository",
+                "metadata": {
+                    "name": name,
+                    "namespace": namespace,
+                },
+                "spec": {
+                    "interval": "1m",
+                    "url": url,
+                },
+            },
+        )
+
+        if not repository.exists():
+            log.debug("Resource does not exist, creating")
+            repository.create()
+        else:
+            repository.update()
+
+        log.info("Ensured resource")
diff --git a/roles/openstack_helm_infra_ceph_provisioners/meta/main.yml b/roles/openstack_helm_infra_ceph_provisioners/meta/main.yml
index f296bce..7d77a96 100644
--- a/roles/openstack_helm_infra_ceph_provisioners/meta/main.yml
+++ b/roles/openstack_helm_infra_ceph_provisioners/meta/main.yml
@@ -24,4 +24,5 @@
         - focal
 
 dependencies:
+  - role: atmosphere
   - role: ceph_csi_rbd
diff --git a/roles/openstack_helm_infra_ceph_provisioners/tasks/main.yml b/roles/openstack_helm_infra_ceph_provisioners/tasks/main.yml
index 817fa91..8a818eb 100644
--- a/roles/openstack_helm_infra_ceph_provisioners/tasks/main.yml
+++ b/roles/openstack_helm_infra_ceph_provisioners/tasks/main.yml
@@ -106,15 +106,6 @@
   kubernetes.core.k8s:
     state: present
     definition:
-      - apiVersion: source.toolkit.fluxcd.io/v1beta2
-        kind: HelmRepository
-        metadata:
-          name: openstack-helm-infra
-          namespace: openstack
-        spec:
-          interval: 60s
-          url: https://tarballs.opendev.org/openstack/openstack-helm-infra/
-
       - apiVersion: v1
         kind: Secret
         metadata:
diff --git a/roles/openstack_helm_infra_libvirt/meta/main.yml b/roles/openstack_helm_infra_libvirt/meta/main.yml
index fbb4bbf..d794993 100644
--- a/roles/openstack_helm_infra_libvirt/meta/main.yml
+++ b/roles/openstack_helm_infra_libvirt/meta/main.yml
@@ -22,3 +22,6 @@
     - name: Ubuntu
       versions:
         - focal
+
+dependencies:
+  - role: atmosphere
diff --git a/roles/openstack_helm_infra_libvirt/tasks/main.yml b/roles/openstack_helm_infra_libvirt/tasks/main.yml
index 594b4e1..e756335 100644
--- a/roles/openstack_helm_infra_libvirt/tasks/main.yml
+++ b/roles/openstack_helm_infra_libvirt/tasks/main.yml
@@ -24,15 +24,6 @@
   kubernetes.core.k8s:
     state: present
     definition:
-      - apiVersion: source.toolkit.fluxcd.io/v1beta2
-        kind: HelmRepository
-        metadata:
-          name: openstack-helm-infra
-          namespace: openstack
-        spec:
-          interval: 60s
-          url: https://tarballs.opendev.org/openstack/openstack-helm-infra/
-
       - apiVersion: v1
         kind: Secret
         metadata:
diff --git a/roles/openstack_helm_infra_memcached/tasks/main.yml b/roles/openstack_helm_infra_memcached/tasks/main.yml
index 379a472..6d7eafb 100644
--- a/roles/openstack_helm_infra_memcached/tasks/main.yml
+++ b/roles/openstack_helm_infra_memcached/tasks/main.yml
@@ -16,15 +16,6 @@
   kubernetes.core.k8s:
     state: present
     definition:
-      - apiVersion: source.toolkit.fluxcd.io/v1beta2
-        kind: HelmRepository
-        metadata:
-          name: openstack-helm-infra
-          namespace: openstack
-        spec:
-          interval: 60s
-          url: https://tarballs.opendev.org/openstack/openstack-helm-infra/
-
       - apiVersion: helm.toolkit.fluxcd.io/v2beta1
         kind: HelmRelease
         metadata:
diff --git a/roles/openstack_helm_infra_openvswitch/meta/main.yml b/roles/openstack_helm_infra_openvswitch/meta/main.yml
index bc3f67d..c3a069a 100644
--- a/roles/openstack_helm_infra_openvswitch/meta/main.yml
+++ b/roles/openstack_helm_infra_openvswitch/meta/main.yml
@@ -22,3 +22,6 @@
     - name: Ubuntu
       versions:
         - focal
+
+dependencies:
+  - role: atmosphere
diff --git a/roles/openstack_helm_infra_openvswitch/tasks/main.yml b/roles/openstack_helm_infra_openvswitch/tasks/main.yml
index 2e24498..11be0b7 100644
--- a/roles/openstack_helm_infra_openvswitch/tasks/main.yml
+++ b/roles/openstack_helm_infra_openvswitch/tasks/main.yml
@@ -24,15 +24,6 @@
   kubernetes.core.k8s:
     state: present
     definition:
-      - apiVersion: source.toolkit.fluxcd.io/v1beta2
-        kind: HelmRepository
-        metadata:
-          name: openstack-helm-infra
-          namespace: openstack
-        spec:
-          interval: 60s
-          url: https://tarballs.opendev.org/openstack/openstack-helm-infra/
-
       - apiVersion: v1
         kind: Secret
         metadata: