Merge "Add Operations API docker swarm deployment"
diff --git a/docker/swarm/network/operations_api_backend.yml b/docker/swarm/network/operations_api_backend.yml
new file mode 100644
index 0000000..f23c239
--- /dev/null
+++ b/docker/swarm/network/operations_api_backend.yml
@@ -0,0 +1,10 @@
+parameters:
+  _param:
+    docker_operations_api_network_subnet: 10.80.0.0/24
+  docker:
+    client:
+      network:
+        operations_api_backend:
+          subnet: ${_param:docker_operations_api_network_subnet}
+          driver: overlay
+          attachable: true
diff --git a/docker/swarm/stack/operations_api.yml b/docker/swarm/stack/operations_api.yml
new file mode 100644
index 0000000..51cdeae
--- /dev/null
+++ b/docker/swarm/stack/operations_api.yml
@@ -0,0 +1,59 @@
+parameters:
+  _param:
+    docker_operations_api_replicas: 1
+    docker_image_operations_api: mirantis/python-operations-api:latest
+    operations_api_oidc_client_secrets: 'operations_api/config/client_secrets_docker.json'
+    operations_api_sqlalchemy_database_uri: 'cockroachdb://oapi@cockroach-ui:26257/oapi'
+    operations_api_sqlalchemy_echo: 'false'
+    operations_api_flask_debug: 'false'
+    operations_api_bind_host: 0.0.0.0
+    operations_api_bind_port: ${_param:haproxy_operations_api_bind_port}
+    docker_image_cockroachdb: cockroachdb/cockroach:latest
+  docker:
+    client:
+      stack:
+        operations_api:
+          service:
+            operations-api:
+              environment:
+                OAPI_OIDC_CLIENT_SECRETS: ${_param:operations_api_oidc_client_secrets}
+                OAPI_SQLALCHEMY_DATABASE_URI: ${_param:operations_api_sqlalchemy_database_uri}
+                OAPI_SQLALCHEMY_ECHO: ${_param:operations_api_sqlalchemy_echo}
+                OAPI_FLASK_DEBUG: ${_param:operations_api_flask_debug}
+                OAPI_FLASK_SECRET_KEY: ${_param:operations_api_flask_secret_key}
+                OAPI_FLASK_SERVER_HOST: ${_param:operations_api_bind_host}
+                OAPI_FLASK_SERVER_PORT: ${_param:operations_api_bind_port}
+              image: ${_param:docker_image_operations_api}
+              deploy:
+                replicas: ${_param:docker_operations_api_replicas}
+                restart_policy:
+                  condition: any
+              ports:
+                - ${_param:haproxy_operations_api_exposed_port}:${_param:haproxy_operations_api_bind_port}
+              volumes:
+                - /srv/volumes/operations_api/logs/:/var/log/operations_api
+            cockroach-ui:
+              image: ${_param:docker_image_cockroachdb}
+              ports:
+                - ${_param:haproxy_cockroachdb_ui_exposed_port}:${_param:haproxy_cockroachdb_ui_bind_port}
+              command: start --insecure
+            cockroach-db-1:
+              image: cockroachdb/cockroach
+              command: start --insecure --join=cockroach-ui
+              depends_on:
+                - cockroach-ui
+              volumes:
+                - /srv/volumes/cockroachdb/cockroach-db-1:/cockroach/cockroach-data
+            cockroach-init:
+              environment:
+                COCKROACH_HOST: cockroach-ui
+              image: atengler/cockroach
+              deploy:
+                restart_policy:
+                  condition: on-failure
+              depends_on:
+                - cockroach-db-1
+          network:
+            default:
+              external:
+                name: operations_api_backend
diff --git a/haproxy/proxy/listen/cicd/operations_api.yml b/haproxy/proxy/listen/cicd/operations_api.yml
new file mode 100644
index 0000000..14bb44a
--- /dev/null
+++ b/haproxy/proxy/listen/cicd/operations_api.yml
@@ -0,0 +1,76 @@
+parameters:
+  _param:
+    haproxy_operations_api_bind_host: ${_param:haproxy_bind_address}
+    haproxy_operations_api_bind_port: 8001
+    haproxy_operations_api_exposed_port: 18001
+    haproxy_cockroachdb_ui_bind_host: ${_param:haproxy_bind_address}
+    haproxy_cockroachdb_ui_bind_port: 8080
+    haproxy_cockroachdb_ui_exposed_port: 18080
+    haproxy_operations_api_ssl:
+      enabled: false
+    haproxy_cockroachdb_ui_ssl:
+      enabled: false
+  haproxy:
+    proxy:
+      listen:
+        operations_api:
+          mode: http
+          options:
+            - forwardfor
+            - httpchk GET /api/v1/
+            - httpclose
+            - httplog
+          balance: source
+          http_request:
+            - action: "add-header X-Forwarded-Proto https"
+              condition: "if { ssl_fc }"
+          sticks:
+          - http-check expect string 'API'
+          binds:
+            - address: ${_param:haproxy_operations_api_bind_host}
+              port: ${_param:haproxy_operations_api_bind_port}
+              ssl: ${_param:haproxy_operations_api_ssl}
+          servers:
+            - name: ${_param:cluster_node01_name}
+              host: ${_param:cluster_node01_address}
+              port: ${_param:haproxy_operations_api_exposed_port}
+              params: check
+            - name: ${_param:cluster_node02_name}
+              host: ${_param:cluster_node02_address}
+              port: ${_param:haproxy_operations_api_exposed_port}
+              params: backup check
+            - name: ${_param:cluster_node03_name}
+              host: ${_param:cluster_node03_address}
+              port: ${_param:haproxy_operations_api_exposed_port}
+              params: backup check
+        cockroachdb_ui:
+          mode: http
+          balance: source
+          options:
+            - forwardfor
+            - httpchk GET /#/overview/list
+            - httpclose
+            - httplog
+          balance: source
+          http_request:
+            - action: "add-header X-Forwarded-Proto https"
+              condition: "if { ssl_fc }"
+          sticks:
+          - http-check expect string 'CLUSTER OVERVIEW'
+          binds:
+            - address: ${_param:haproxy_cockroachdb_ui_bind_host}
+              port: ${_param:haproxy_cockroachdb_ui_bind_port}
+              ssl: ${_param:haproxy_cockroachdb_ui_ssl}
+          servers:
+            - name: ${_param:cluster_node01_name}
+              host: ${_param:cluster_node01_address}
+              port: ${_param:haproxy_cockroachdb_ui_exposed_port}
+              params: check
+            - name: ${_param:cluster_node02_name}
+              host: ${_param:cluster_node02_address}
+              port: ${_param:haproxy_cockroachdb_ui_exposed_port}
+              params: backup check
+            - name: ${_param:cluster_node03_name}
+              host: ${_param:cluster_node03_address}
+              port: ${_param:haproxy_cockroachdb_ui_exposed_port}
+              params: backup check