diff --git a/ansible/roles/octavia_preconf/templates/octavia_amphora_provider.yaml.j2 b/ansible/roles/octavia_preconf/templates/octavia_amphora_provider.yaml.j2 index 4c76181dd..dbd1e88dc 100644 --- a/ansible/roles/octavia_preconf/templates/octavia_amphora_provider.yaml.j2 +++ b/ansible/roles/octavia_preconf/templates/octavia_amphora_provider.yaml.j2 @@ -23,7 +23,13 @@ pod: subPath: client.key-and-cert.pem - name: pod-run-octavia mountPath: /var/run/octavia + - name: ovn-tls + mountPath: /etc/octavia/ovn + readOnly: true volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls - name: octavia-certs secret: secretName: octavia-certs @@ -47,7 +53,13 @@ pod: subPath: client.key-and-cert.pem - name: pod-run-octavia mountPath: /var/run/octavia + - name: ovn-tls + mountPath: /etc/octavia/ovn + readOnly: true volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls - name: octavia-certs secret: secretName: octavia-certs diff --git a/base-helm-configs/kube-ovn/kube-ovn-helm-overrides.yaml b/base-helm-configs/kube-ovn/kube-ovn-helm-overrides.yaml index 200bd321b..aceafdc9a 100644 --- a/base-helm-configs/kube-ovn/kube-ovn-helm-overrides.yaml +++ b/base-helm-configs/kube-ovn/kube-ovn-helm-overrides.yaml @@ -1,6 +1,7 @@ # Default values for kubeovn. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +--- global: registry: address: ghcr.io/rackerlabs/genestack-images @@ -26,7 +27,7 @@ MASTER_NODES_LABEL: "kube-ovn/role=master" networking: # NET_STACK defaults to ipv4 NET_STACK: ipv4 - ENABLE_SSL: false + ENABLE_SSL: true # network type could be geneve or vlan NETWORK_TYPE: geneve # tunnel type could be geneve, vxlan or stt @@ -38,13 +39,13 @@ networking: vlan: PROVIDER_NAME: "provider" VLAN_INTERFACE_NAME: "br-overlay" - #VLAN_NAME: "ovn-vlan" - #VLAN_ID: "100" + # VLAN_NAME: "ovn-vlan" + # VLAN_ID: "100" EXCHANGE_LINK_NAME: false ENABLE_EIP_SNAT: false DEFAULT_SUBNET: "ovn-default" DEFAULT_VPC: "ovn-cluster" - NODE_SUBNET: "join" #mesh network + NODE_SUBNET: "join" # mesh network ENABLE_ECMP: true ENABLE_METRICS: true # comma-separated string of nodelocal DNS ip addresses diff --git a/base-helm-configs/neutron/neutron-helm-overrides.yaml b/base-helm-configs/neutron/neutron-helm-overrides.yaml index f18d753f1..30ebe57ce 100644 --- a/base-helm-configs/neutron/neutron-helm-overrides.yaml +++ b/base-helm-configs/neutron/neutron-helm-overrides.yaml @@ -147,6 +147,27 @@ pod: timeout: 60 ironic_agent: timeout: 60 + mounts: + neutron_server: + neutron_server: + volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls + volumeMounts: + - name: ovn-tls + mountPath: /etc/neutron/ovn + readOnly: true + neutron_ovn_metadata_agent: + neutron_ovn_metadata_agent: + volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls + volumeMounts: + - name: ovn-tls + mountPath: /etc/neutron/ovn + readOnly: true conf: dhcp_agent: @@ -184,7 +205,7 @@ conf: agent_version: v2 driver: neutron_fwaas.services.firewall.service_drivers.ovn.firewall_l3_driver.OVNFwaasDriver # NOTE(cloudnull): in 2025.1 we can enable this - enabled: False + enabled: false agent: extensions: vpnaas,metadata availability_zone: az1 @@ -243,6 +264,13 @@ conf: metadata_workers: 2 ovs: ovsdb_connection: "tcp:127.0.0.1:6640" + ovn: + ovn_nb_private_key: /etc/neutron/ovn/key + ovn_nb_certificate: /etc/neutron/ovn/cert + ovn_nb_ca_cert: /etc/neutron/ovn/cacert + ovn_sb_private_key: /etc/neutron/ovn/key + ovn_sb_certificate: /etc/neutron/ovn/cert + ovn_sb_ca_cert: /etc/neutron/ovn/cacert ovn_vpn_agent: ovs: ovsdb_connection: "tcp:127.0.0.1:6640" @@ -269,6 +297,13 @@ conf: ovn_metadata_enabled: true ovn_nb_connection: "tcp:127.0.0.1:6641" ovn_sb_connection: "tcp:127.0.0.1:6642" + ovn_nb_private_key: "/etc/neutron/ovn/key" + ovn_nb_certificate: "/etc/neutron/ovn/cert" + ovn_nb_ca_cert: "/etc/neutron/ovn/cacert" + ovn_sb_private_key: "/etc/neutron/ovn/key" + ovn_sb_certificate: "/etc/neutron/ovn/cert" + ovn_sb_ca_cert: "/etc/neutron/ovn/cacert" + openvswitch_agent: agent: availability_zone: az1 diff --git a/base-helm-configs/octavia/octavia-helm-overrides.yaml b/base-helm-configs/octavia/octavia-helm-overrides.yaml index 22c8e0b0f..73f05c2c2 100644 --- a/base-helm-configs/octavia/octavia-helm-overrides.yaml +++ b/base-helm-configs/octavia/octavia-helm-overrides.yaml @@ -148,6 +148,14 @@ conf: ovn: ovn_nb_connection: "tcp:127.0.0.1:6641" ovn_sb_connection: "tcp:127.0.0.1:6642" + + ovn_nb_private_key: /etc/octavia/ovn/key + ovn_nb_certificate: /etc/octavia/ovn/cert + ovn_nb_ca_cert: /etc/octavia/ovn/cacert + + ovn_sb_private_key: /etc/octavia/ovn/key + ovn_sb_certificate: /etc/octavia/ovn/cert + ovn_sb_ca_cert: /etc/octavia/ovn/cacert service_auth: insecure: true task_flow: @@ -276,18 +284,30 @@ pod: init_container: null octavia_api: volumeMounts: + - name: ovn-tls + mountPath: /etc/octavia/ovn + readOnly: true - name: pod-run-octavia mountPath: /var/run/octavia volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls - name: pod-run-octavia emptyDir: {} octavia_worker: init_container: null octavia_worker: volumeMounts: + - name: ovn-tls + mountPath: /etc/octavia/ovn + readOnly: true - name: pod-run-octavia mountPath: /var/run/octavia volumes: + - name: ovn-tls + secret: + secretName: ovn-client-tls - name: pod-run-octavia emptyDir: {} octavia_driver_agent: diff --git a/base-kustomize/neutron/base/kustomization.yaml b/base-kustomize/neutron/base/kustomization.yaml index 98617a65a..542e56807 100644 --- a/base-kustomize/neutron/base/kustomization.yaml +++ b/base-kustomize/neutron/base/kustomization.yaml @@ -1,3 +1,4 @@ +--- sortOptions: order: fifo resources: @@ -8,6 +9,7 @@ resources: - policies.yaml patches: + - path: patch-ovn-tls-optional.yaml - target: kind: ConfigMap name: neutron-bin diff --git a/base-kustomize/neutron/base/patch-ovn-tls-optional.yaml b/base-kustomize/neutron/base/patch-ovn-tls-optional.yaml new file mode 100644 index 000000000..6fb2c63ba --- /dev/null +++ b/base-kustomize/neutron/base/patch-ovn-tls-optional.yaml @@ -0,0 +1,27 @@ +# I don't believe the OpenStack helm Neutron chart offers the ability to use +# optional volume mounts, and this secret may not exist on installations not +# using Kube-OVN's "control plane" TLS +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: neutron-ovn-metadata-agent-default +spec: + template: + spec: + volumes: + - name: ovn-tls + secret: + optional: true +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: neutron-server +spec: + template: + spec: + volumes: + - name: ovn-tls + secret: + optional: true diff --git a/base-kustomize/octavia/base/kustomization.yaml b/base-kustomize/octavia/base/kustomization.yaml index 16aaaceec..1704d3a06 100644 --- a/base-kustomize/octavia/base/kustomization.yaml +++ b/base-kustomize/octavia/base/kustomization.yaml @@ -20,6 +20,7 @@ resources: # To run the OVN driver, the octavia-api container must have an agent container within the same pod. patches: + - path: patch-ovn-tls-optional.yaml - target: kind: Secret name: octavia-etc diff --git a/base-kustomize/octavia/base/patch-ovn-tls-optional.yaml b/base-kustomize/octavia/base/patch-ovn-tls-optional.yaml new file mode 100644 index 000000000..1d48a73f7 --- /dev/null +++ b/base-kustomize/octavia/base/patch-ovn-tls-optional.yaml @@ -0,0 +1,27 @@ +# I don't believe the OpenStack helm Neutron chart offers the ability to use +# optional volume mounts, and this secret may not exist on installations not +# using Kube-OVN's "control plane" TLS +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: octavia-worker-default +spec: + template: + spec: + volumes: + - name: ovn-tls + secret: + optional: true +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: octavia-api +spec: + template: + spec: + volumes: + - name: ovn-tls + secret: + optional: true diff --git a/bin/create-secrets.sh b/bin/create-secrets.sh index b72e7e539..bcd0d3dd6 100755 --- a/bin/create-secrets.sh +++ b/bin/create-secrets.sh @@ -905,6 +905,24 @@ else echo "Note: ${SKYLINE_SECRETS_FILE} not found. Run create-skyline-secrets.sh to add skyline secrets." fi +# Check if kube-ovn-tls secret exists, and copy to openstack namespace if it does +if kubectl -n kube-system get secret kube-ovn-tls >/dev/null 2>&1 +then + cat <> $OUTPUT_FILE +--- +apiVersion: v1 +kind: Secret +metadata: + name: ovn-client-tls + namespace: openstack +type: Opaque +data: + cacert: $(kubectl -n kube-system get secret kube-ovn-tls -o jsonpath='{.data.cacert}') + cert: $(kubectl -n kube-system get secret kube-ovn-tls -o jsonpath='{.data.cert}') + key: $(kubectl -n kube-system get secret kube-ovn-tls -o jsonpath='{.data.key}') +EOF +fi + rm nova_ssh_key nova_ssh_key.pub rm manila_ssh_key manila_ssh_key.pub chmod 0640 ${OUTPUT_FILE} diff --git a/bin/install-neutron.sh b/bin/install-neutron.sh index 3595bc3d0..15bef2021 100755 --- a/bin/install-neutron.sh +++ b/bin/install-neutron.sh @@ -124,6 +124,28 @@ fi echo +# Set connection string based on whether we use Kube-OVN TLS +# Hyperconverged build tries to execute the install script without yq in the +# path +function installYq() { + export VERSION=v4.47.2 + export BINARY=yq_linux_amd64 + wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}.tar.gz -q -O - | tar xz && mv ${BINARY} /usr/local/bin/yq +} + +if ! yq --version 2> /dev/null; then + echo "yq is not installed. Attempting to install yq" + installYq +fi + +if helm -n kube-system get values kube-ovn \ + | yq -e '.networking.ENABLE_SSL == true' >/dev/null 2>&1 +then + CONNECTION_STRING="ssl" +else + CONNECTION_STRING="tcp" +fi + # Collect all --set arguments, executing commands and quoting safely # NOTE: This array contains OpenStack-specific secret retrievals and MUST be updated # with the necessary --set arguments for your target SERVICE_NAME_DEFAULT. @@ -143,10 +165,13 @@ set_args=( --set "conf.neutron.keystone_authtoken.memcache_secret_key=$(kubectl --namespace openstack get secret os-memcached -o jsonpath='{.data.memcache_secret_key}' | base64 -d)" --set "endpoints.oslo_messaging.auth.admin.password=$(kubectl --namespace openstack get secret rabbitmq-default-user -o jsonpath='{.data.password}' | base64 -d)" --set "endpoints.oslo_messaging.auth.neutron.password=$(kubectl --namespace openstack get secret neutron-rabbitmq-password -o jsonpath='{.data.password}' | base64 -d)" - --set "conf.neutron.ovn.ovn_nb_connection=tcp:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" - --set "conf.neutron.ovn.ovn_sb_connection=tcp:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" - --set "conf.plugins.ml2_conf.ovn.ovn_nb_connection=tcp:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" - --set "conf.plugins.ml2_conf.ovn.ovn_sb_connection=tcp:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.neutron.ovn.ovn_nb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.neutron.ovn.ovn_sb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.plugins.ml2_conf.ovn.ovn_nb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.plugins.ml2_conf.ovn.ovn_sb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.ovn_metadata_agent.ovn.ovn_nb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.ovn_metadata_agent.ovn.ovn_sb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + ) @@ -172,4 +197,4 @@ printf '%q ' "${helm_command[@]}" echo # Execute the command directly from the array -"${helm_command[@]}" \ No newline at end of file +"${helm_command[@]}" diff --git a/bin/install-octavia.sh b/bin/install-octavia.sh index bb08298e7..6b1bdb413 100755 --- a/bin/install-octavia.sh +++ b/bin/install-octavia.sh @@ -123,6 +123,28 @@ fi echo +# Set connection string based on whether we use Kube-OVN TLS +# Hyperconverged build tries to execute the install script without yq in the +# path +function installYq() { + export VERSION=v4.47.2 + export BINARY=yq_linux_amd64 + wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}.tar.gz -q -O - | tar xz && mv ${BINARY} /usr/local/bin/yq +} + +if ! yq --version 2> /dev/null; then + echo "yq is not installed. Attempting to install yq" + installYq +fi + +if helm -n kube-system get values kube-ovn \ + | yq -e '.networking.ENABLE_SSL == true' >/dev/null 2>&1 +then + CONNECTION_STRING="ssl" +else + CONNECTION_STRING="tcp" +fi + # Collect all --set arguments, executing commands and quoting safely # NOTE: This array contains OpenStack-specific secret retrievals and MUST be updated # with the necessary --set arguments for your target SERVICE_NAME_DEFAULT. @@ -148,8 +170,8 @@ set_args=( --set "conf.octavia.certificates.ca_private_key_passphrase=$(kubectl --namespace openstack get secret octavia-certificates -o jsonpath='{.data.password}' | base64 -d)" # OVN connections (dynamic clusterIP lookup) - --set "conf.octavia.ovn.ovn_nb_connection=tcp:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" - --set "conf.octavia.ovn.ovn_sb_connection=tcp:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.octavia.ovn.ovn_nb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" + --set "conf.octavia.ovn.ovn_sb_connection=$CONNECTION_STRING:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')" ) @@ -175,4 +197,4 @@ printf '%q ' "${helm_command[@]}" echo # Execute the command directly from the array -"${helm_command[@]}" \ No newline at end of file +"${helm_command[@]}"