Chapter 3. Integrating RHOSO networking services Important This feature is available in this release as a Technology Preview , and therefore is not fully supported by Red Hat. It should only be used for testing, and should not be deployed in a production environment. For more information about Technology Preview features, see Scope of Coverage Details . Red Hat only certifies Red Hat OpenStack Services on OpenShift (RHOSO) Networking drivers that are distributed by Red Hat. Conversely, Red Hat does not certify drivers that are distributed directly by the Partner. To integrate a Networking driver with RHOSO, you must perform the following actions: Build a neutron-api container with the Networking driver. Configure the Networking driver in the neutron-api component. Configure additional software dependencies, such as agents on the External DataPlane Nodes (EDPM), that are required by the driver. Access extra files that are required by the driver. 3.1. Configure the networking driver Red Hat OpenStack Services on OpenShift (RHOSO) uses OpenShift custom resource definitions (CRDs), which you deploy by using OpenStackControlPlane , OpenStackDataPlaneDeployment , and OpenStackDataPlaneNodeSet custom resources (CR). The OpenStackControlPlane CR includes specification templates that govern the openstack-neutron API service deployment, which include sections for configuring networking drivers. The OpenStackDataPlaneNodeSet CR includes specification templates that govern components that are deployed on the EDPM nodes. For information about configuring and deploying the openstack-neutron service, see the Configuring networking services guide . 3.2. Prepare neutron-api component with the new networking driver Red Hat OpenStack Services on OpenShift (RHOSO) openstack-neutron services execute in Linux containers that are built by Red Hat. These container images include the "in-tree" networking drivers such as ML2/OVN. You must prepare new container images to use Partner networking drivers. Partners must provide a container image that adds an additional layer on top of Red Hat's RHOSO container image. Partner container images for RHOSO are similar to a Partner's container images for director-based RHOSP. The purpose of providing a Partner container image is to provide software dependencies required by the Partner's driver. Partners are responsible for generating their container images, and the image has to go through the container image certification procedure before the Red Hat OpenStack certification. The container image certification is separate from Red Hat OpenStack certification and is a requirement for inclusion in the Red Hat Ecosystem Catalog . After a Partner's networking driver has passed Red Hat OpenStack Certification, the Partner is responsible for generating a certified container image for every subsequent minor update to the RHOSO release. For each minor RHOSO 18 update, Partners must generate an updated container image for the updated release, and publish the updated container image in the Red Hat Ecosystem Catalog. Container images for older RHOSO 18 minor updates must remain in the Red Hat Ecosystem Catalog. This ensures that customers that are not using the latest RHOSO release can still access the Partner's container image that was built for their RHOSO version. 3.2.1. Building partner container images for networking services A Partner must provide a Red Hat certified container image. A neutron-server service includes "in-tree" drivers for the OVN back end and many service plugins. Partners must provide a neutron-server container image to layer networking driver software on top of the RHOSO neutron-server container image. Note Depending on your plug-in or driver, you might also need to deploy additional services or agents on the data plane or the control plane nodes. For the control plane you can add a new OpenShift operator using operator-sdk , and for the data plane you can add a new OpenStackDataPlaneService . You can build the OpenStackDataPlaneService service on official Neutron agent images and edpm-ansible roles. You are responsible for the stability of the interface for new custom services. Procedure Create a Containerfile for generating the container image: The following example shows a sample Containerfile or Dockerfile for generating a neutron-server container image that includes external software dependencies that are required by a Partner's openstack-neutron driver. The example can be adapted to generate any other neutron-related container image that includes external software dependencies that are required by a Partner's openstack-neutron driver. 1 Use the FROM clause to specify the RHOSO base image, which in this example is the neutron-server service. The 18.0.1 tag specifies the release. To generate an image based on a specific minor release, modify the tag to specify that release, for example 18.0.0, or openstack-neutron-server-rhel9:*18.0.0*. For RHOSO 18 GA, use the URL: registry.redhat.io/rhoso/openstack-neutron-server-rhel9:18.0. 2 The labels in the sample Containerfile override the corresponding labels in the base image to uniquely identify the Partner's image. 3 You can install the software dependencies by this method, or the method at 4, 5, or 6. 4 You can install the software dependencies by this method, or the method at 3, 5, or 6. 5 You can install the software dependencies by this method, or the method at 3, 4, or 6. 6 You can install the software dependencies by this method, or the method at 3, 4, or 5. Build, tag, and upload the container image. You can use the podman build or buildah build commands to build the container image. For more information on how Partners chose a registry and provide an access token to the registry for the certification, see the Red Hat Software Certification Workflow Guide . Tag the image to match the corresponding RHOSO 18 base image. For example, when the base image is version 18.0.0, the Partner's image is also tagged as version 18.0.0. You can also use the above example procedure with the other neutron services. Ensure that you use the appropriate RHOSO openstack-neutron base image in place of the openstack-neutron-server base image. Certify and publish the container image: For information on how to certify the container image, see Red Hat Enterprise Linux Software Certification Policy Guide and Red Hat Software Certification Workflow Guide . You can publish container images in the Red Hat Ecosystem Catalog . 3.2.2. Maintain partner container images and image tags When a Partner certifies their networking solution that includes a container image, then the Partner is responsible for rebuilding that image every time the underlying Red Hat OpenStack Services on OpenShift (RHOSO) container image changes. The Partner must rebuild the container image: With every RHOSO maintenance release. When RHOSO container images are updated to address a CVE. For example, if a Partner certified their solution against RHOSO 18.0.1, the Partner must add two tags to the container image: 18.0.1 to indicate the specific release. 18.0 to indicate this is the latest version associated with RHOSO 18. When RHOSO 18.0.2 releases, the Partner must rebuild their image and update the images and tags: The tag for the new image is 18.0.2. The older 18.0.1 image must remain in the Red Hat Ecosystem Catalog. Partners must not remove old images. Remove the 18.0 tag from the older 18.0.1 image, and add it to the new 18.0.2 image. 3.2.3. Deploy partner container images With Red Hat OpenStack Services on OpenShift (RHOSO), you can use the OpenStackVersion custom resource definition (CRD) to override the container image for any service. In the following example, the CRD configures a custom image for the neutron-server to use the container image of a Partner named "PartnerX". 3.3. Set custom configuration for the networking driver You can use the OpenStackControlPlane custom resource definition (CRD) extraMounts feature to provide files to the openstack-neutron networking service. One example is if a Partner's openstack-neutron driver requires an additional configuration file containing authentication credentials to enable access to the Partner's back-end networking devices. You can store the contents of the file in a Kubernetes secret, which you can create from a YAML file: apiVersion: v1 kind: Secret metadata: name: cinder-volume-example-config 1 type: Opaque stringData: partner_config.ini: | 2 example_credentials=example 3 1 The secret name is arbitrary, but this example includes the networking service and the Partner's name. 2 The name of the file required by the example networking driver is partner_config.ini . 3 Example ini file data. The following example shows an extraMounts entry in the neutron section of the OpenStackControlPlane CR to mount the config.ini into the neutron-server pod. apiVersion: core.openstack.org/v1beta1 kind: OpenStackControlPlane metadata: name: openstack spec: neutron: template: databaseAccount: neutron databaseInstance: openstack memcachedInstance: memcached networkAttachments: - internalapi passwordSelectors: service: NeutronPassword rabbitMqClusterName: rabbitmq replicas: 1 secret: osp-secret serviceUser: neutron ml2MechanismDrivers: - partner-mech-driver 1 customServiceConfig: | 2 [example] foo=bar extraMounts: 3 - extraVol: - mounts: - name: partner-config mountPath: /etc/neutron/neutron.conf.d/partner_config.ini 4 subPath: partner_config.ini 5 readOnly: true volumes: - name: partner-config secret: secretName: neutron-server-partnerX-config 6 1 In a deployment where the Partner's networking driver integrates with the ML2 networking by using a custom mechanism driver, you can use this section to configure additional mechanism drivers. 2 Use this section to set the neutron-server configuration of the Partner driver. You can use this section to provide custom configuration in the CR. You should use secrets to provide information such as credentials. Note that secrets are stored unencrypted by default in the Kubernetes API server. For more information about Kubernetes secrets, see kubernetes documentation . 3 Use this section to set the extraMounts configuration for the neutron section of the OpenStackControlPlane . 4 Use this section to set the mount point where the partner_config.ini file appears in the neutron-server pod . 5 Use this section to set the subPath to specify the partner_config.ini filename. This is necessary to mount a single file in the /etc/neutron/neutron.conf.d directory. 6 The secretName value matches the name of the secret that you created previously. 3.4. Deploy the networking driver agent on the EDPM nodes If your networking solution requires a specific agent running on the External DataPlane Nodes (EDPM), you can deploy on such nodes by using a custom OpenStackDataPlaneService custom resource (CR) and adding the agent to the OpenStackDataPlaneNodeSet CR. If your networking solution requires a specific agent running on the Red Hat OpenShift Container Platform (RHOCP) nodes with the neutron-server , you can add a custom Kubernetes operator by using operator-sdk . Ensure that you provide specific custom resource definitions (CRDs) that are not integrated with the Red Hat OpenStack Services on OpenShift (RHOSO) openstack-operator for the new operator. 3.4.1. Building partner ansible-runner image You can build a Partner ansible-runner image so that you can streamline Ansible tasks that are required to install and configure the Networking agents. Procedure Create a Containerfile for generating the container image. The following example shows a sample Containerfile or Dockerfile for generating a ansibleee-runner container image that includes additional roles and playbooks that are required by a Partner's OpenStackDataPlaneService . 1 Add Partner's role to the container image. 2 Add the playbook to run the Partner's role to the container image. This step is optional. You can pass playbook content to the service directly in the OpenStackDataPlaneService file. For more information see, Customizing the data plane in Customizing the Red Hat OpenStack Services on OpenShift deployment . Build, tag, and upload the container image. You can use the podman build or buildah build commands to build the container image. For more information on how to choose a registry and provide an access token to the registry for the certification, see the Red Hat Software Certification Workflow Guide . Tag the image to match the corresponding RHOSO 18 base image. For example, when the base image is version 18.0, the Partner's image is also tagged as version 18.0. Certify and publish the container image: For information on how to certify the container image, see Red Hat Enterprise Linux Software Certification Policy Guide and Red Hat Software Certification Workflow Guide . You can publish container images in the Red Hat Ecosystem Catalog . 3.4.2. Deploy the partner solution on the EDPM nodes The following example shows a custom service definition (CRD) that you might use to deploy the Partner solution: 1 The name of the custom service, that is used in the OpenStackDataPlaneNodeSet CR to add the service to the service list. 2 The playbook that runs as part of the custom service deployment. It must be available in the custom ansibleee image. 3 The custom container image, that the ansible-runner execution environment uses to execute Ansible. For more information about how to define a custom service, see Customizing the data plane in Customizing the Red Hat OpenStack Services on OpenShift deployment . The following example shows how to enable a custom service in the EDPM NodeSet. To deploy a custom service on the EDPM nodes, you must include it in the services list in the OpenStackDataPlaneNodeSet CR: 1 The name of the service matches the service created previously. Add the service name in the order of execution relative to the other services. This example shows deploys the neutron-custom-partner-service after run-os and before the libvirt service. This order is important for dependencies because services are executed simply in the order from the list.

Commands:
FROM registry.redhat.io/rhoso/openstack-neutron-server-rhel9:18.0.1 1 LABEL name="rhoso18/openstack-neutron-server-partnerX-plugin" maintainer="maintainer@partnerX.com" vendor="PartnerX" summary="RHOSO 18.0 neutron-server PartnerX PluginY" description="RHOSO 18.0 neutron-server PartnerX PluginY" 2 Switch to root to install software dependencies USER root Enable a repo to install a package 3 COPY vendorX.repo /etc/yum.repos.d/vendorX.repo RUN dnf clean all && dnf install -y vendorX-plugin Install a package over the network 4 RUN dnf install -y http://vendorX.com/partnerX-plugin.rpm Install a local package 5 COPY partnerX-plugin.rpm /tmp RUN dnf install -y /tmp/partnerX-plugin.rpm && rm -f /tmp/partnerX-plugin.rpm Install a python package from PyPI 6 RUN curl -OL https://bootstrap.pypa.io/get-pip.py && python3 get-pip.py --no-setuptools --no-wheel && pip3 install partnerX-plugin && rm -f get-pip.py Add required license as text file(s) in /licenses directory (GPL, MIT, APACHE, Partner End User Agreement, etc) RUN mkdir /licenses COPY licensing.txt /licenses Switch to neutron user USER neutron
apiVersion: core.openstack.org/v1beta1 kind: OpenStackVersion metadata: name: openstack spec: customContainerImages: neutronAPIImage: registry.connect.redhat.com/partnerX/openstack-neutron-server-partnerX-plugin:18.0.1
apiVersion: v1 kind: Secret metadata: name: cinder-volume-example-config 1 type: Opaque stringData: partner_config.ini: | 2 example_credentials=example 3
apiVersion: core.openstack.org/v1beta1 kind: OpenStackControlPlane metadata: name: openstack spec: neutron: template: databaseAccount: neutron databaseInstance: openstack memcachedInstance: memcached networkAttachments: - internalapi passwordSelectors: service: NeutronPassword rabbitMqClusterName: rabbitmq replicas: 1 secret: osp-secret serviceUser: neutron ml2MechanismDrivers: - partner-mech-driver 1 customServiceConfig: | 2 [example] foo=bar extraMounts: 3 - extraVol: - mounts: - name: partner-config mountPath: /etc/neutron/neutron.conf.d/partner_config.ini 4 subPath: partner_config.ini 5 readOnly: true volumes: - name: partner-config secret: secretName: neutron-server-partnerX-config 6
FROM quay.io/openstack-k8s-operators/openstack-ansibleee-runner:latest COPY neutron_agent_partner_role /usr/share/ansible/roles/neutron_agent_partner_role 1 COPY playbooks/neutron_agent_partner.yaml /usr/share/ansible/collections/ansible_collections/osp/edpm/playbooks/ 2
apiVersion: dataplane.openstack.org/v1beta1 kind: OpenStackDataPlaneService metadata: name: neutron-custom-partner-service 1 spec: label: dataplane-deployment-neutron-custom-partner-service playbook: osp.edpm.neutron_agent_partner 2 openStackAnsibleEERunnerImage: openstack-ansibleee-partnerX-runner:latest 3
apiVersion: dataplane.openstack.org/v1beta1 kind: OpenStackDataPlaneNodeSet metadata: name: openstack-edpm spec: services: - download-cache - bootstrap - configure-network - validate-network - install-os - configure-os - run-os - neutron-custom-partner-service 1 - libvirt - nova nodes: edpm-compute: ansible: ansibleHost: 172.20.12.67 ansibleSSHPrivateKeySecret: dataplane-ansible-ssh-private-key-secret ansibleUser: cloud-admin ansibleVars: ansible_ssh_transfer_method: scp ctlplane_ip: 172.20.12.67 external_ip: 172.20.12.76 fqdn_internalapi: edpm-compute-1.example.com internalapi_ip: 172.17.0.101 storage_ip: 172.18.0.101 tenant_ip: 172.10.0.101 hostName: edpm-compute-0 networkConfig: {} nova: cellName: cell1 deploy: true novaInstance: nova