diff --git a/.github/workflows/release-blazar.yml b/.github/workflows/release-blazar.yml new file mode 100644 index 00000000..58b3d061 --- /dev/null +++ b/.github/workflows/release-blazar.yml @@ -0,0 +1,75 @@ +# +name: Create and publish the Blazar image + +# Configures this workflow to run every time a change is pushed to the branch called `release`. +on: + workflow_dispatch: + inputs: + imageTag: + description: 'Set tag for the image' + required: true + default: 'master-ubuntu_jammy' + type: choice + options: + - master-ubuntu_jammy + - 2023.1-ubuntu_jammy + - 2023.2-ubuntu_jammy + - 2024.1-ubuntu_jammy + pluginTag: + description: 'Set release used for the build environment' + required: true + default: 'master' + type: choice + options: + - "master" + - "2023.1" + - "2023.2" + - "2024.1" + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Dynamically set MY_DATE environment variable + run: echo "MY_DATE=$(date +%s)" >> $GITHUB_ENV + - name: Build and push Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: Containerfiles/Blazar-Containerfile + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/blazar:${{ github.event.inputs.imageTag }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/blazar:${{ github.event.inputs.imageTag }}-${{ env.MY_DATE }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + VERSION=${{ github.event.inputs.imageTag }} + PLUGIN_VERSION=${{ github.event.inputs.pluginTag }} diff --git a/.github/workflows/smoke-blazar.yml b/.github/workflows/smoke-blazar.yml new file mode 100644 index 00000000..2f4bae6e --- /dev/null +++ b/.github/workflows/smoke-blazar.yml @@ -0,0 +1,42 @@ +# +name: Run build check for the Blazar compatible image + +on: + pull_request: + paths: + - Containerfiles/Blazar-Containerfile + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: Containerfiles/Blazar-Containerfile + push: false + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/blazar:master-ubuntu_jammy + build-args: | + VERSION=master-ubuntu_jammy + PLUGIN_VERSION=master diff --git a/Containerfiles/Blazar-Containerfile b/Containerfiles/Blazar-Containerfile new file mode 100644 index 00000000..374feecb --- /dev/null +++ b/Containerfiles/Blazar-Containerfile @@ -0,0 +1,32 @@ +FROM --platform=linux/amd64 ubuntu:jammy + +ENV BLAZAR_HOME=/opt/ + +RUN apt-get update && apt-get install -y git build-essential libssl-dev libffi-dev \ + libxml2-dev libxslt1-dev libpq-dev \ + libmysqlclient-dev python3 python3-pip curl \ + vim python3-openstackclient; \ + rm -rf /var/lib/apt/lists/* + +RUN pip3 install pymysql + +RUN pip3 install --no-cache-dir --upgrade urllib3 chardet + +RUN pip3 install tox + +RUN mkdir -p $BLAZAR_HOME +WORKDIR $BLAZAR_HOME + +# Clone Blazar related repositories +RUN git clone -b stable/2024.1 https://opendev.org/openstack/blazar.git && \ + git clone -b stable/2024.1 https://opendev.org/openstack/python-blazarclient.git + +# Install dependencies and projects +RUN pip3 install --no-cache-dir ./blazar && \ + pip3 install --no-cache-dir ./python-blazarclient && \ + if [ ! -e /usr/local/bin/blazar-api ]; then \ + ln -s /opt/blazar/bin/blazar-api /usr/local/bin/blazar-api; \ + fi && \ + if [ ! -e /usr/local/bin/blazar-manager ]; then \ + ln -s /opt/blazar/bin/blazar-manager /usr/local/bin/blazar-manager; \ + fi diff --git a/Containerfiles/NovaEFI-Containerfile b/Containerfiles/NovaEFI-Containerfile index bc6c9544..89be2d85 100644 --- a/Containerfiles/NovaEFI-Containerfile +++ b/Containerfiles/NovaEFI-Containerfile @@ -7,6 +7,11 @@ if [ "${PLUGIN_VERSION}" != 'master' ]; then export PLUGIN_VERSION=stable/${PLUG . /var/lib/openstack/bin/activate; \ /var/lib/openstack/bin/pip install git+https://github.com/openstack/oslo.db@${PLUGIN_VERSION}#egg=oslo_db +RUN . /var/lib/openstack/bin/activate; \ + /var/lib/openstack/bin/pip install git+https://github.com/openstack/blazar-nova.git + +ENV PYTHONPATH="/var/lib/openstack/lib/python3.10/site-packages" + FROM openstackhelm/nova:${VERSION} COPY --from=build /var/lib/openstack/. /var/lib/openstack/ # Packages for the following features: diff --git a/docs/openstack-blazar.md b/docs/openstack-blazar.md new file mode 100644 index 00000000..6781e146 --- /dev/null +++ b/docs/openstack-blazar.md @@ -0,0 +1,35 @@ +# Deploy Blazar + + +### Create secrets + +``` shell +kubectl --namespace openstack \ + create secret generic blazar-rabbitmq-password \ + --type Opaque \ + --from-literal=username="blazar" \ + --from-literal=password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)" + +kubectl --namespace openstack \ + create secret generic blazar-secrets \ + --type Opaque \ + --from-literal=service-username="blazar" \ + --from-literal=service-password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)" \ + --from-literal=service-domain="service" \ + --from-literal=service-project="service" \ + --from-literal=service-project-domain="service" \ + --from-literal=db-endpoint="mariadb-cluster-primary.openstack.svc.cluster.local" \ + --from-literal=db-name="blazar" \ + --from-literal=db-username="blazar" \ + --from-literal=db-password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)" \ + --from-literal=secret-key="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)" \ + --from-literal=keystone-endpoint="$(kubectl --namespace openstack get secret keystone-keystone-admin -o jsonpath='{.data.OS_AUTH_URL}' | base64 -d)" \ + --from-literal=keystone-username="blazar" \ + --from-literal=default-region="RegionOne" +``` + +## Run the deployment + +``` shell +kubectl --namespace openstack apply -k /etc/genestack/kustomize/blazar/base +``` diff --git a/helm-configs.example/aio-example-openstack-overrides.yaml b/helm-configs.example/aio-example-openstack-overrides.yaml index 0d721b79..f4399644 100644 --- a/helm-configs.example/aio-example-openstack-overrides.yaml +++ b/helm-configs.example/aio-example-openstack-overrides.yaml @@ -37,14 +37,14 @@ images: cinder_storage_init: "docker.io/openstackhelm/ceph-config-helper:ubuntu_focal_18.2.0-1-20231013" cinder_backup: "docker.io/openstackhelm/cinder:2023.1-ubuntu_jammy" cinder_backup_storage_init: "docker.io/openstackhelm/ceph-config-helper:ubuntu_focal_18.2.0-1-20231013" - keystone_api: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" + keystone_api: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" keystone_bootstrap: "docker.io/openstackhelm/heat:2023.1-ubuntu_jammy" - keystone_credential_rotate: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_credential_setup: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_db_sync: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_domain_manage: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_fernet_rotate: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_fernet_setup: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" + keystone_credential_rotate: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_credential_setup: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_db_sync: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_domain_manage: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_fernet_rotate: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_fernet_setup: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" keystone_credential_cleanup: "docker.io/openstackhelm/heat:2023.1-ubuntu_jammy" libvirt: docker.io/openstackhelm/libvirt:2023.2-ubuntu_jammy # We want to use jammy. 2023.2 is the latest version that supports jammy. libvirt_exporter: vexxhost/libvirtd-exporter:latest @@ -77,7 +77,7 @@ images: nova_db_sync: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_novncproxy: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_novncproxy_assets: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" - nova_scheduler: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" + nova_scheduler: "ghcr.io/rackerlabs/genestack/nova-efi:2023.1-ubuntu_jammy" nova_spiceproxy: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_spiceproxy_assets: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_service_cleaner: "docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal" diff --git a/helm-configs.example/nova/nova-helm-overrides.yaml b/helm-configs.example/nova/nova-helm-overrides.yaml index d7dce3b3..46d703cc 100644 --- a/helm-configs.example/nova/nova-helm-overrides.yaml +++ b/helm-configs.example/nova/nova-helm-overrides.yaml @@ -1357,6 +1357,10 @@ conf: - api_database - cell0_database nova: + filter_scheduler: + enabled_filters: BlazarFilter + available_filters: nova.scheduler.filters.all_filters + available_filters: blazarnova.scheduler.filters.blazar_filter.BlazarFilter DEFAULT: # NOTE(cloudnull): the vif_plugging_* options are an implemntation detail of the nova container when running with OVN vif_plugging_is_fatal: true @@ -1436,7 +1440,7 @@ conf: rbd_secret_uuid: 457eb676-33da-42ec-9a8c-9293d545c337 disk_cachemodes: "network=writeback" hw_disk_discard: unmap - cpu_mode: host-model + cpu_mode: host-passthrough volume_use_multipath: false # Disabled because multipathd is not configured or running upgrade_levels: compute: auto diff --git a/helm-configs.example/prod-example-openstack-overrides.yaml b/helm-configs.example/prod-example-openstack-overrides.yaml index 603a5d3f..856b8e97 100644 --- a/helm-configs.example/prod-example-openstack-overrides.yaml +++ b/helm-configs.example/prod-example-openstack-overrides.yaml @@ -36,14 +36,14 @@ images: cinder_storage_init: "docker.io/openstackhelm/ceph-config-helper:ubuntu_focal_18.2.0-1-20231013" cinder_backup: "docker.io/openstackhelm/cinder:2023.1-ubuntu_jammy" cinder_backup_storage_init: "docker.io/openstackhelm/ceph-config-helper:ubuntu_focal_18.2.0-1-20231013" - keystone_api: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" + keystone_api: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" keystone_bootstrap: "docker.io/openstackhelm/heat:2023.1-ubuntu_jammy" - keystone_credential_rotate: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_credential_setup: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_db_sync: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_domain_manage: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_fernet_rotate: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" - keystone_fernet_setup: "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1720466623" + keystone_credential_rotate: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_credential_setup: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_db_sync: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_domain_manage: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_fernet_rotate: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" + keystone_fernet_setup: "ghcr.io/rackerlabs/genestack/keystone-rxt:2023.1-ubuntu_jammy" keystone_credential_cleanup: "docker.io/openstackhelm/heat:2023.1-ubuntu_jammy" libvirt: docker.io/openstackhelm/libvirt:2023.2-ubuntu_jammy # We want to use jammy. 2023.2 is the latest version that supports jammy. libvirt_exporter: vexxhost/libvirtd-exporter:latest @@ -76,7 +76,7 @@ images: nova_db_sync: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_novncproxy: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_novncproxy_assets: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" - nova_scheduler: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" + nova_scheduler: "ghcr.io/rackerlabs/genestack/nova-efi:2023.1-ubuntu_jammy" nova_spiceproxy: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_spiceproxy_assets: "docker.io/openstackhelm/nova:2023.1-ubuntu_jammy" nova_service_cleaner: "docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal" diff --git a/kustomize.example/blazar/aio/kustomization.yaml b/kustomize.example/blazar/aio/kustomization.yaml new file mode 100644 index 00000000..b82e5c83 --- /dev/null +++ b/kustomize.example/blazar/aio/kustomization.yaml @@ -0,0 +1,14 @@ +bases: + - ../base + +patches: + - target: + kind: HorizontalPodAutoscaler + name: blazar-api + patch: |- + - op: replace + path: /spec/minReplicas + value: 1 + - op: replace + path: /spec/maxReplicas + value: 1 diff --git a/kustomize.example/blazar/base/blazar-mariadb-database.yaml b/kustomize.example/blazar/base/blazar-mariadb-database.yaml new file mode 100644 index 00000000..2f40915b --- /dev/null +++ b/kustomize.example/blazar/base/blazar-mariadb-database.yaml @@ -0,0 +1,50 @@ +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: Database +metadata: + name: blazar + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + mariaDbRef: + name: mariadb-cluster + characterSet: utf8 + collate: utf8_general_ci + retryInterval: 5s +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: User +metadata: + name: blazar + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + mariaDbRef: + name: mariadb-cluster + passwordSecretKeyRef: + name: blazar-secrets + key: db-password + maxUserConnections: 0 + host: "%" + retryInterval: 5s +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: Grant +metadata: + name: blazar-grant + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + mariaDbRef: + name: mariadb-cluster + privileges: + - "ALL" + database: "blazar" + table: "*" + username: blazar + grantOption: true + host: "%" + retryInterval: 5s diff --git a/kustomize.example/blazar/base/blazar-rabbitmq-queue.yaml b/kustomize.example/blazar/base/blazar-rabbitmq-queue.yaml new file mode 100644 index 00000000..c19940a4 --- /dev/null +++ b/kustomize.example/blazar/base/blazar-rabbitmq-queue.yaml @@ -0,0 +1,67 @@ +--- +apiVersion: rabbitmq.com/v1beta1 +kind: User +metadata: + name: blazar + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + tags: + - management # available tags are 'management', 'policymaker', 'monitoring' and 'administrator' + - policymaker + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack + importCredentialsSecret: + name: blazar-rabbitmq-password +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Vhost +metadata: + name: blazar + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + name: "blazar" # vhost name; required and cannot be updated + defaultQueueType: quorum # default queue type for this vhost; require RabbitMQ version 3.11.12 or above + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Queue +metadata: + name: blazar-queue + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + name: blazar-qq # name of the queue + vhost: "blazar" # default to '/' if not provided + type: quorum # without providing a queue type, rabbitmq creates a classic queue + autoDelete: false + durable: true # seting 'durable' to false means this queue won't survive a server restart + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Permission +metadata: + name: blazar-permission + namespace: openstack + annotations: + helm.sh/resource-policy: keep +spec: + vhost: "blazar" # name of a vhost + userReference: + name: "blazar" # name of a user.rabbitmq.com in the same namespace; must specify either spec.userReference or spec.user + permissions: + write: ".*" + configure: ".*" + read: ".*" + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack diff --git a/kustomize.example/blazar/base/config-map.yaml b/kustomize.example/blazar/base/config-map.yaml new file mode 100644 index 00000000..cd2faeb2 --- /dev/null +++ b/kustomize.example/blazar/base/config-map.yaml @@ -0,0 +1,108 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: blazar-configmap + namespace: openstack +data: + blazar-conf-setup.sh: | + #!/bin/bash + cd /opt/blazar/ + tox -egenconfig + mv etc/blazar/blazar.conf.sample etc/blazar/blazar.conf + sed -i '/^\[keystone_authtoken\]/a \ + auth_url = '"${OS_AUTH_URL}"'\n\ + auth_uri = '"${OS_AUTH_URL}"'\n\ + www_authenticate_uri = '"${OS_AUTH_URL}"'\n\ + username = '"${SERVICE_USERNAME}"'\n\ + password = '"${SERVICE_PASSWORD}"'\n\ + user_domain_name = '"${SERVICE_DOMAIN}"'\n\ + project_name = '"${SERVICE_PROJECT}"'\n\ + project_domain_name = '"${SERVICE_PROJECT_DOMAIN}"'\n\ + ' etc/blazar/blazar.conf + + declare -a sed_commands=( + "s/^#*auth_type = .*/auth_type = password/" + "s/^#*auth_version = .*/auth_version = v${OS_IDENTITY_API_VERSION}/" + "s/^#*service_token_roles_required = .*/service_token_roles_required = true/" + "s/^#*service_token_roles = .*/service_token_roles = service/" + "s/^#*service_type = .*/service_type = reservation/" + "s/^#*region_name = .*/region_name = ${OS_REGION_NAME}/" + "s/^#*port = .*/port = 1234/" + "s/^#\(host = .*\)/\1/" + "s/^#*os_auth_host = .*/os_auth_host = keystone-api.openstack.svc.cluster.local/" + "s/^#*os_auth_port = .*/os_auth_port = 5000/" + "s/^#*os_auth_protocol = .*/os_auth_protocol = http/" + "s/^#*os_auth_version = .*/os_auth_version = v${OS_IDENTITY_API_VERSION}/" + "s/^#*os_admin_username = .*/os_admin_username = ${SERVICE_USERNAME}/" + "s/^#*os_admin_password = .*/os_admin_password = ${SERVICE_PASSWORD}/" + "s/^#*os_admin_project_name = .*/os_admin_project_name = ${SERVICE_PROJECT}/" + "s/^#*os_region_name = .*/os_region_name = ${OS_REGION_NAME}/" + "s/^#*os_admin_project_domain_name = .*/os_admin_project_domain_name = ${SERVICE_PROJECT_DOMAIN}/" + "s/^#*os_admin_user_domain_name = .*/os_admin_user_domain_name = ${SERVICE_DOMAIN}/" + "s|^#*transport_url = .*|transport_url = rabbit://${RABBIT_USERNAME}:${RABBIT_PASSWORD}@rabbitmq-server-0.rabbitmq-nodes.openstack.svc.cluster.local:5672,${RABBIT_USERNAME}:${RABBIT_PASSWORD}@rabbitmq-server-1.rabbitmq-nodes.openstack.svc.cluster.local:5672,${RABBIT_USERNAME}:${RABBIT_PASSWORD}@rabbitmq-server-2.rabbitmq-nodes.openstack.svc.cluster.local:5672/blazar|" + "s|^#*connection = .*|connection = mysql+pymysql://${DB_USERNAME}:${DB_PASSWORD}@${DB_ENDPOINT}:3306/blazar|" + "s|^#*slave_connection = .*|slave_connection = mysql+pymysql://${DB_USERNAME}:${DB_PASSWORD}@mariadb-cluster-secondary.openstack.svc.cluster.local:3306/blazar|" + "s/^#*max_retries = .*/max_retries = -1/" + "s/^#*max_pool_size = .*/max_pool_size = 20/" + "s/^#*max_overflow = .*/max_overflow = 0/" + "s/^#*plugins = .*/plugins = physical.host.plugin,virtual.instance.plugin/" + "s/^#*rpc_topic = .*/rpc_topic = blazar.manager/" + "s/^#*enable_proxy_headers_parsing = .*/enable_proxy_headers_parsing = true/" + "s/^#*rabbit_ha_queues = .*/rabbit_ha_queues = true/" + "s/^#driver = .*/driver = messagingv2/" + "s/^#*enable_v1_api = .*/enable_v1_api = false/" + ) + + for cmd in "${sed_commands[@]}"; do + sed -i "$cmd" etc/blazar/blazar.conf + done + + blazar-resource-create.sh: | + #!/bin/bash + + if openstack user list --project "service" --domain "service" | grep -q "\b${SERVICE_USERNAME}\b"; then + USER_ID=$(openstack user list --project "service" --domain "service" --long | grep "\b${SERVICE_USERNAME}\b" | awk '{print $2}') + else + USER_ID=$(openstack user create --project "service" --password "${SERVICE_PASSWORD}" --domain "service" --description "Service User for RegionOne/service/blazar" "${SERVICE_USERNAME}" -f value -c id) + fi + + service_exists() { + openstack service show blazar >/dev/null 2>&1 + } + + if ! service_exists "blazar"; then + openstack service create --name "blazar" --description "OpenStack Reservation Service" reservation + fi + SERVICE_ID=$(openstack service show -f value -c id blazar) + + + openstack role add --project "service" --user "${USER_ID}" admin + openstack aggregate show freepool >/dev/null 2>&1 || openstack aggregate create freepool + + for endpoint_type in internal admin public; do + if ! openstack endpoint list --service "$SERVICE_ID" --interface "$endpoint_type" | grep -q "blazar"; then + case "$endpoint_type" in + internal | admin) + openstack endpoint create --region "$OS_REGION_NAME" "$SERVICE_ID" "$endpoint_type" "http://blazar-api.openstack.svc.cluster.local:1234/" + ;; + public) + openstack endpoint create --region "$OS_REGION_NAME" "$SERVICE_ID" "$endpoint_type" "http://blazar.openstack.svc.cluster.local/" + ;; + esac + fi + done + + blazar-db-migrate.sh: | + #!/bin/bash + cd /opt/ + pip install SQLAlchemy==1.4.* + blazar-db-manage --config-file /opt/blazar/etc/blazar/blazar.conf upgrade head + + blazar-service-init.sh: | + #!/bin/bash + while true; do + /usr/local/bin/blazar-api --config-file /opt/blazar/etc/blazar/blazar.conf & + /usr/local/bin/blazar-manager --config-file /opt/blazar/etc/blazar/blazar.conf & + wait + sleep 10 # Adjust as needed + done diff --git a/kustomize.example/blazar/base/deployment.yaml b/kustomize.example/blazar/base/deployment.yaml new file mode 100644 index 00000000..9ef64d7d --- /dev/null +++ b/kustomize.example/blazar/base/deployment.yaml @@ -0,0 +1,252 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "blazar-api" + namespace: openstack + labels: + release_group: blazar + application: blazar + component: api +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 3 + selector: + matchLabels: + application: blazar + component: api + release_group: blazar + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + application: blazar + component: api + release_group: blazar + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: release_group + operator: In + values: + - blazar + - key: application + operator: In + values: + - blazar + - key: component + operator: In + values: + - server + topologyKey: kubernetes.io/hostname + weight: 10 + nodeSelector: + openstack-control-plane: enabled + terminationGracePeriodSeconds: 30 + volumes: + - name: pod-tmp + emptyDir: {} + - name: pod-etc-blazar + emptyDir: {} + - name: blazar-data + configMap: + name: "blazar-configmap" + defaultMode: 0555 + initContainers: + - name: init + image: "quay.io/airshipit/kubernetes-entrypoint:v1.0.0" + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: true + readOnlyRootFilesystem: false + runAsUser: 65534 + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: INTERFACE_NAME + value: eth0 + - name: PATH + value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/ + - name: DEPENDENCY_SERVICE + value: "" + - name: DEPENDENCY_JOBS + value: "" + - name: DEPENDENCY_DAEMONSET + value: "" + - name: DEPENDENCY_CONTAINER + value: "" + - name: DEPENDENCY_POD_JSON + value: "" + - name: DEPENDENCY_CUSTOM_RESOURCE + value: "" + command: + - kubernetes-entrypoint + volumeMounts: [] + containers: + - name: blazar-api + image: "ghcr.io/sowm9802/blazar:1.16" + imagePullPolicy: IfNotPresent + command: ["bash", "-c"] + args: + - | + /tmp/blazar-conf-setup.sh && + /tmp/blazar-resource-create.sh && + /tmp/blazar-db-migrate.sh && + /tmp/blazar-service-init.sh + volumeMounts: + - name: pod-tmp + mountPath: /tmp + - name: pod-etc-blazar + mountPath: /etc/blazar + readOnly: false + - name: blazar-data + mountPath: /tmp/blazar-conf-setup.sh + subPath: blazar-conf-setup.sh + readOnly: true + - name: blazar-data + mountPath: /tmp/blazar-resource-create.sh + subPath: blazar-resource-create.sh + readOnly: true + - name: blazar-data + mountPath: /tmp/blazar-db-migrate.sh + subPath: blazar-db-migrate.sh + readOnly: true + - name: blazar-data + mountPath: /tmp/blazar-service-init.sh + subPath: blazar-service-init.sh + readOnly: true + env: + - name: SERVICE_USERNAME + valueFrom: + secretKeyRef: + name: blazar-secrets + key: service-username + - name: SERVICE_PASSWORD + valueFrom: + secretKeyRef: + name: blazar-secrets + key: service-password + - name: SERVICE_DOMAIN + valueFrom: + secretKeyRef: + name: blazar-secrets + key: service-domain + - name: SERVICE_PROJECT + valueFrom: + secretKeyRef: + name: blazar-secrets + key: service-project + - name: SERVICE_PROJECT_DOMAIN + valueFrom: + secretKeyRef: + name: blazar-secrets + key: service-project-domain + - name: DB_ENDPOINT + valueFrom: + secretKeyRef: + name: blazar-secrets + key: db-endpoint + - name: DB_NAME + valueFrom: + secretKeyRef: + name: blazar-secrets + key: db-name + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: blazar-secrets + key: db-username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: blazar-secrets + key: db-password + - name: RABBIT_USERNAME + valueFrom: + secretKeyRef: + name: blazar-rabbitmq-password + key: username + - name: RABBIT_PASSWORD + valueFrom: + secretKeyRef: + name: blazar-rabbitmq-password + key: password + - name: BLAZAR_KEYSTONE_ENDPOINT + valueFrom: + secretKeyRef: + name: blazar-secrets + key: keystone-endpoint + - name: BLAZAR_DEFAULT_REGION + valueFrom: + secretKeyRef: + name: blazar-secrets + key: default-region + - name: OS_IDENTITY_API_VERSION + value: "3" + - name: OS_AUTH_URL + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_AUTH_URL + - name: OS_REGION_NAME + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_REGION_NAME + - name: OS_INTERFACE + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_INTERFACE + - name: OS_ENDPOINT_TYPE + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_INTERFACE + - name: OS_PROJECT_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_PROJECT_DOMAIN_NAME + - name: OS_PROJECT_NAME + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_PROJECT_NAME + - name: OS_USER_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_USER_DOMAIN_NAME + - name: OS_USERNAME + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_USERNAME + - name: OS_PASSWORD + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_PASSWORD + - name: OS_DEFAULT_DOMAIN + valueFrom: + secretKeyRef: + name: keystone-keystone-admin + key: OS_DEFAULT_DOMAIN diff --git a/kustomize.example/blazar/base/ingress.yaml b/kustomize.example/blazar/base/ingress.yaml new file mode 100644 index 00000000..feccc364 --- /dev/null +++ b/kustomize.example/blazar/base/ingress.yaml @@ -0,0 +1,43 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: blazar + namespace: openstack +spec: + ingressClassName: nginx + rules: + - host: blazar + http: + paths: + - backend: + service: + name: blazar-api + port: + name: b-api + path: / + pathType: ImplementationSpecific + - host: blazar.openstack + http: + paths: + - backend: + service: + name: blazar-api + port: + name: b-api + path: / + pathType: ImplementationSpecific + - host: blazar.openstack.svc.cluster.local + http: + paths: + - backend: + service: + name: blazar-api + port: + name: b-api + path: / + pathType: ImplementationSpecific +status: + loadBalancer: + ingress: + - ip: 172.31.1.181 + - ip: 172.31.1.26 diff --git a/kustomize.example/blazar/base/kustomization.yaml b/kustomize.example/blazar/base/kustomization.yaml new file mode 100644 index 00000000..d4466262 --- /dev/null +++ b/kustomize.example/blazar/base/kustomization.yaml @@ -0,0 +1,7 @@ +resources: + - blazar-mariadb-database.yaml + - blazar-rabbitmq-queue.yaml + - config-map.yaml + - deployment.yaml + - service.yaml + - ingress.yaml diff --git a/kustomize.example/blazar/base/service.yaml b/kustomize.example/blazar/base/service.yaml new file mode 100644 index 00000000..ca771d7c --- /dev/null +++ b/kustomize.example/blazar/base/service.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: Service +metadata: + name: blazar + namespace: openstack +spec: + selector: + app: ingress-api + ports: + - name: http + port: 80 + targetPort: 80 + - name: https + port: 443 + targetPort: 443 + sessionAffinity: None + type: ClusterIP + +--- + +apiVersion: v1 +kind: Service +metadata: + name: blazar-api + namespace: openstack +spec: + selector: + application: blazar + component: api + release_group: blazar + ports: + - name: b-api + port: 1234 + targetPort: 1234 + sessionAffinity: None + type: ClusterIP + diff --git a/kustomize.example/blazar/letsencrypt/kustomization.yaml b/kustomize.example/blazar/letsencrypt/kustomization.yaml new file mode 100644 index 00000000..8210772b --- /dev/null +++ b/kustomize.example/blazar/letsencrypt/kustomization.yaml @@ -0,0 +1,13 @@ +bases: + - ../base + +patches: + - target: + kind: Ingress + name: blazar-namespace-fqdn + patch: |- + - op: add + path: /metadata/annotations + value: + cert-manager.io/cluster-issuer: letsencrypt-prod + acme.cert-manager.io/http01-edit-in-place: "true"