diff --git a/README.md b/README.md index e2583ddbd..7c346348c 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,4 @@ The following VAs are available. - [Network Functions Virtualization with SRIOV](examples/va/nfv/sriov/) - [Network Functions Virtualization with OvS DPDK](examples/va/nfv/ovs-dpdk/) - [Network Functions Virtualization with OvS DPDK & SRIOV](examples/va/nfv/ovs-dpdk-sriov/) [untested] +- [OpenStack on Highly Available OpenShift Cluster](examples/va/pidone/) diff --git a/automation/vars/pidone.yaml b/automation/vars/pidone.yaml new file mode 100644 index 000000000..023fcdfba --- /dev/null +++ b/automation/vars/pidone.yaml @@ -0,0 +1,66 @@ +--- +vas: + pidone: + stages: + - pre_stage_run: + - name: Apply taint on worker-3 + type: cr + definition: + spec: + taints: + - effect: NoSchedule + key: testOperator + value: 'true' + - effect: NoExecute + key: testOperator + value: 'true' + kind: Node + resource_name: worker-3 + state: patched + path: examples/va/pidone/nncp + wait_conditions: + - >- + oc -n openstack wait nncp + -l osp/nncm-config-type=standard + --for jsonpath='{.status.conditions[0].reason}'=SuccessfullyConfigured + --timeout=180s + values: + - name: network-values + src_file: values.yaml + build_output: nncp.yaml + + - path: examples/va/pidone + wait_conditions: + - >- + oc -n openstack wait osctlplane controlplane --for condition=Ready + --timeout=30m + values: + - name: network-values + src_file: nncp/values.yaml + - name: service-values + src_file: service-values.yaml + build_output: control-plane.yaml + + - path: examples/va/pidone/edpm/nodeset + wait_conditions: + - >- + oc -n openstack wait openstackdataplanenodeset + openstack-edpm + --for condition=SetupReady + --timeout=600s + values: + - name: edpm-nodeset-values + src_file: values.yaml + build_output: nodeset.yaml + + - path: examples/va/pidone/edpm/deployment + wait_conditions: + - >- + oc -n openstack wait openstackdataplanedeployment + edpm-deployment + --for condition=Ready + --timeout=40m + values: + - name: edpm-deployment-values + src_file: values.yaml + build_output: deployment.yaml diff --git a/examples/va/pidone/README.md b/examples/va/pidone/README.md new file mode 100644 index 000000000..4ed527227 --- /dev/null +++ b/examples/va/pidone/README.md @@ -0,0 +1,98 @@ +# OpenStack on Highly Available OpenShift Cluster + +This is a collection of CR templates that represent a validated Red Hat OpenStack Services on OpenShift deployment that has the following characteristics: + +- 3 masters plus 3 workers OpenShift cluster +- 1 worker dedicated to run testOperator taint-tolerant pods, see [test-operator](https://github.com/openstack-k8s-operators/test-operator) +- 3-replica Galera database +- 3-replica RabbitMQ +- OVN networking +- Network isolation over a single NIC +- 3 compute nodes +- Swift enabled and used as Glance backend + + +# Configuring networking and deploy the OpenStack control plane + +## Assumptions + +- A storage class called `local-storage` should already exist. + +## Initialize + +Switch to the "openstack" namespace +``` +oc project openstack +``` +Change to the pidone directory +``` +cd architecture/examples/va/pidone +``` +Edit the [nncp/values.yaml](nncp/values.yaml) and +[service-values.yaml](service-values.yaml) files to suit +your environment. +``` +vi nncp/values.yaml +vi service-values.yaml +``` + +## Apply node network configuration + +Generate the node network configuration +``` +kustomize build nncp > nncp.yaml +``` +Apply the NNCP CRs +``` +oc apply -f nncp.yaml +``` +Wait for NNCPs to be available +``` +oc wait nncp -l osp/nncm-config-type=standard --for jsonpath='{.status.conditions[0].reason}'=SuccessfullyConfigured --timeout=300s +``` + +## Apply networking and control-plane configuration + +Generate the control-plane and networking CRs. +``` +kustomize build > control-plane.yaml +``` +Apply the CRs +``` +oc apply -f control-plane.yaml +``` + +Wait for control plane to be available +``` +oc wait osctlplane controlplane --for condition=Ready --timeout=600s +``` + +## Apply dataplane nodeset and deployment configuration + +Generate the dataplane nodeset CR. +``` +kustomize build edpm/nodeset > nodeset.yaml +``` +Apply the CR +``` +oc apply -f nodeset.yaml +``` + +Wait for the nodeset to reach the SetupReady condition +``` +oc -n openstack wait openstackdataplanenodeset openstack-edpm --for condition=SetupReady --timeout=600s +``` + +Generate the dataplane deployment CR. +``` +kustomize build edpm/deployment > deployment.yaml +``` +Apply the CR +``` +oc apply -f deployment.yaml +``` + +Wait for the dataplanedeployment to reach the "Ready" condition +``` +oc -n openstack wait openstackdataplanedeployment edpm-deploymenti --for condition=Ready --timeout=40m +``` diff --git a/examples/va/pidone/edpm/deployment/kustomization.yaml b/examples/va/pidone/edpm/deployment/kustomization.yaml new file mode 100644 index 000000000..93508a262 --- /dev/null +++ b/examples/va/pidone/edpm/deployment/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +components: + - ../../../../../va/pidone/edpm/deployment + +resources: + - values.yaml diff --git a/examples/va/pidone/edpm/deployment/values.yaml b/examples/va/pidone/edpm/deployment/values.yaml new file mode 100644 index 000000000..e55b281f6 --- /dev/null +++ b/examples/va/pidone/edpm/deployment/values.yaml @@ -0,0 +1,12 @@ +# yamllint disable rule:line-length +# local-config: referenced, but not emitted by kustomize +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: edpm-deployment-values + annotations: + config.kubernetes.io/local-config: "true" +data: + deployment: + name: edpm-deployment diff --git a/examples/va/pidone/edpm/nodeset/kustomization.yaml b/examples/va/pidone/edpm/nodeset/kustomization.yaml new file mode 100644 index 000000000..5ef0d31ee --- /dev/null +++ b/examples/va/pidone/edpm/nodeset/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +components: + - ../../../../../va/pidone/edpm/nodeset + +resources: + - values.yaml diff --git a/examples/va/pidone/edpm/nodeset/values.yaml b/examples/va/pidone/edpm/nodeset/values.yaml new file mode 100644 index 000000000..6b1638213 --- /dev/null +++ b/examples/va/pidone/edpm/nodeset/values.yaml @@ -0,0 +1,172 @@ +# yamllint disable rule:line-length +# local-config: referenced, but not emitted by kustomize +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: edpm-nodeset-values + annotations: + config.kubernetes.io/local-config: "true" +data: + ssh_keys: + # Authorized keys that will have access to the dataplane computes via SSH + authorized: CHANGEME + # The private key that will have access to the dataplane computes via SSH + private: CHANGEME2 + # The public key that will have access to the dataplane computes via SSH + public: CHANGEME3 + nodeset: + ansible: + ansibleUser: cloud-admin + ansiblePort: 22 + ansibleVars: + timesync_ntp_servers: + - hostname: clock.redhat.com + # CHANGEME -- see https://access.redhat.com/solutions/253273 + # edpm_bootstrap_command: | + # subscription-manager register --username \ + # --password + # podman login -u -p registry.redhat.io + edpm_network_config_hide_sensitive_logs: false + edpm_network_config_os_net_config_mappings: + edpm-compute-0: + nic2: 6a:fe:54:3f:8a:02 # CHANGEME + edpm-compute-1: + nic2: 6b:fe:54:3f:8a:02 # CHANGEME + edpm-compute-2: + nic2: 6c:fe:54:3f:8a:02 # CHANGEME + edpm_network_config_template: | + --- + {% set mtu_list = [ctlplane_mtu] %} + {% for network in nodeset_networks %} + {{ mtu_list.append(lookup('vars', networks_lower[network] ~ '_mtu')) }} + {%- endfor %} + {% set min_viable_mtu = mtu_list | max %} + network_config: + - type: interface + name: nic1 + use_dhcp: true + mtu: {{ min_viable_mtu }} + - type: ovs_bridge + name: {{ neutron_physical_bridge_name }} + mtu: {{ min_viable_mtu }} + use_dhcp: false + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_cidr }} + routes: {{ ctlplane_host_routes }} + members: + - type: interface + name: nic2 + mtu: {{ min_viable_mtu }} + # force the MAC address of the bridge to this interface + primary: true + {% for network in nodeset_networks %} + - type: vlan + mtu: {{ lookup('vars', networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', networks_lower[network] ~ '_ip') }}/{{ lookup('vars', networks_lower[network] ~ '_cidr') }} + routes: {{ lookup('vars', networks_lower[network] ~ '_host_routes') }} + {% endfor %} + edpm_nodes_validation_validate_controllers_icmp: false + edpm_nodes_validation_validate_gateway_icmp: false + edpm_selinux_mode: enforcing + edpm_sshd_allowed_ranges: + - 192.168.122.0/24 + edpm_sshd_configure_firewall: true + enable_debug: false + gather_facts: false + neutron_physical_bridge_name: br-ex + neutron_public_interface_name: eth0 + service_net_map: + nova_api_network: internalapi + nova_libvirt_network: internalapi + storage_mtu: 9000 + storage_mgmt_mtu: 9000 + storage_mgmt_vlan_id: 23 + storage_mgmt_cidr: "24" + storage_mgmt_host_routes: [] + networks: + - defaultRoute: true + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + nodes: + edpm-compute-0: + ansible: + ansibleHost: 192.168.122.100 + hostName: edpm-compute-0 + networks: + - defaultRoute: true + fixedIP: 192.168.122.100 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + edpm-compute-1: + ansible: + ansibleHost: 192.168.122.101 + hostName: edpm-compute-1 + networks: + - defaultRoute: true + fixedIP: 192.168.122.101 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + edpm-compute-2: + ansible: + ansibleHost: 192.168.122.102 + hostName: edpm-compute-2 + networks: + - defaultRoute: true + fixedIP: 192.168.122.102 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + services: + - bootstrap + - configure-network + - validate-network + - install-os + - configure-os + - ssh-known-hosts + - run-os + - reboot-os + - install-certs + - ovn + - neutron-metadata + - libvirt + - nova + nova: + migration: + ssh_keys: + private: CHANGEME4 + public: CHANGEME5 diff --git a/examples/va/pidone/kustomization.yaml b/examples/va/pidone/kustomization.yaml new file mode 100644 index 000000000..01e1f9f6d --- /dev/null +++ b/examples/va/pidone/kustomization.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +components: + - ../../../va/pidone + +resources: + - nncp/values.yaml + - service-values.yaml diff --git a/examples/va/pidone/nncp/kustomization.yaml b/examples/va/pidone/nncp/kustomization.yaml new file mode 100644 index 000000000..a07606dac --- /dev/null +++ b/examples/va/pidone/nncp/kustomization.yaml @@ -0,0 +1,443 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +transformers: + # Set namespace to OpenStack on all namespaced objects without a namespace + - |- + apiVersion: builtin + kind: NamespaceTransformer + metadata: + name: _ignored_ + namespace: openstack + setRoleBindingSubjects: none + unsetOnly: true + fieldSpecs: + - path: metadata/name + kind: Namespace + create: true + +components: + - ../../../../lib/nncp + +resources: + - values.yaml + - ocp_pidone_nodes_nncp.yaml + +replacements: + # Static Node IPs: node-3 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_3.internalapi_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_3.tenant_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_3.ctlplane_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_3.storage_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.ip + + # Static Node IPs: node-4 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_4.internalapi_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_4.tenant_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_4.ctlplane_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_4.storage_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.ip + + # Static Node IPs: node-5 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_5.internalapi_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_5.tenant_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_5.ctlplane_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_5.storage_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.ip + + # Static Node IPs: node-6 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_6.internalapi_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_6.tenant_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_6.ctlplane_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.ip + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_6.storage_ip + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.ip + + + # prefix-length: node-3 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.ctlplane.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.internalapi.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.tenant.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storage.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.prefix-length + + # prefix-length: node-4 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.ctlplane.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.internalapi.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.tenant.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storage.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.prefix-length + + # prefix-length: node-5 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.ctlplane.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.internalapi.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.tenant.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storage.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.prefix-length + + # prefix-length: node-6 + - source: + kind: ConfigMap + name: network-values + fieldPath: data.ctlplane.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[type=linux-bridge].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.internalapi.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=internalapi].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.tenant.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=tenant].ipv4.address.0.prefix-length + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storage.prefix-length + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - spec.desiredState.interfaces.[name=storage].ipv4.address.0.prefix-length + + + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_3.name + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-3 + fieldPaths: + - metadata.name + - spec.nodeSelector.[kubernetes.io/hostname] + + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_4.name + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-4 + fieldPaths: + - metadata.name + - spec.nodeSelector.[kubernetes.io/hostname] + + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_5.name + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-5 + fieldPaths: + - metadata.name + - spec.nodeSelector.[kubernetes.io/hostname] + + - source: + kind: ConfigMap + name: network-values + fieldPath: data.node_6.name + targets: + - select: + kind: NodeNetworkConfigurationPolicy + name: node-6 + fieldPaths: + - metadata.name + - spec.nodeSelector.[kubernetes.io/hostname] + +patches: + - target: + kind: NodeNetworkConfigurationPolicy + name: master-0 + patch: |- + - op: add + path: /spec/nodeSelector/node-role.kubernetes.io~1master + value: "" + - op: remove + path: /spec/nodeSelector/node-role.kubernetes.io~1worker + + - target: + kind: NodeNetworkConfigurationPolicy + name: master-1 + patch: |- + - op: add + path: /spec/nodeSelector/node-role.kubernetes.io~1master + value: "" + - op: remove + path: /spec/nodeSelector/node-role.kubernetes.io~1worker + + - target: + kind: NodeNetworkConfigurationPolicy + name: master-2 + patch: |- + - op: add + path: /spec/nodeSelector/node-role.kubernetes.io~1master + value: "" + - op: remove + path: /spec/nodeSelector/node-role.kubernetes.io~1worker diff --git a/examples/va/pidone/nncp/ocp_pidone_nodes_nncp.yaml b/examples/va/pidone/nncp/ocp_pidone_nodes_nncp.yaml new file mode 100644 index 000000000..c73f57aa7 --- /dev/null +++ b/examples/va/pidone/nncp/ocp_pidone_nodes_nncp.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: nmstate.io/v1 +kind: NodeNetworkConfigurationPolicy +metadata: + name: node-3 + labels: + osp/nncm-config-type: standard +--- +apiVersion: nmstate.io/v1 +kind: NodeNetworkConfigurationPolicy +metadata: + name: node-4 + labels: + osp/nncm-config-type: standard +--- +apiVersion: nmstate.io/v1 +kind: NodeNetworkConfigurationPolicy +metadata: + name: node-5 + labels: + osp/nncm-config-type: standard +--- +apiVersion: nmstate.io/v1 +kind: NodeNetworkConfigurationPolicy +metadata: + name: node-6 + labels: + osp/nncm-config-type: standard diff --git a/examples/va/pidone/nncp/values.yaml b/examples/va/pidone/nncp/values.yaml new file mode 100644 index 000000000..bcc14d8ed --- /dev/null +++ b/examples/va/pidone/nncp/values.yaml @@ -0,0 +1,233 @@ +# local-config: referenced, but not emitted by kustomize +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: network-values + annotations: + config.kubernetes.io/local-config: "true" +data: + # nodes + node_0: + name: ostest-master-0 + internalapi_ip: 172.17.0.5 + tenant_ip: 172.19.0.5 + ctlplane_ip: 192.168.122.10 + storage_ip: 172.18.0.5 + node_1: + name: ostest-master-1 + internalapi_ip: 172.17.0.6 + tenant_ip: 172.19.0.6 + ctlplane_ip: 192.168.122.11 + storage_ip: 172.18.0.6 + node_2: + name: ostest-master-2 + internalapi_ip: 172.17.0.7 + tenant_ip: 172.19.0.7 + ctlplane_ip: 192.168.122.12 + storage_ip: 172.18.0.7 + node_3: + name: ostest-worker-0 + internalapi_ip: 172.17.0.8 + tenant_ip: 172.19.0.8 + ctlplane_ip: 192.168.122.13 + storage_ip: 172.18.0.8 + node_4: + name: ostest-worker-1 + internalapi_ip: 172.17.0.9 + tenant_ip: 172.19.0.9 + ctlplane_ip: 192.168.122.14 + storage_ip: 172.18.0.9 + node_5: + name: ostest-worker-2 + internalapi_ip: 172.17.0.10 + tenant_ip: 172.19.0.10 + ctlplane_ip: 192.168.122.15 + storage_ip: 172.18.0.10 + node_6: + name: ostest-worker-3 + internalapi_ip: 172.17.0.11 + tenant_ip: 172.19.0.11 + ctlplane_ip: 192.168.122.16 + storage_ip: 172.18.0.11 + + # networks + ctlplane: + dnsDomain: ctlplane.example.com + subnets: + - allocationRanges: + - end: 192.168.122.120 + start: 192.168.122.100 + - end: 192.168.122.200 + start: 192.168.122.150 + cidr: 192.168.122.0/24 + gateway: 192.168.122.1 + name: subnet1 + prefix-length: 24 + iface: enp6s0 + mtu: 9000 + lb_addresses: + - 192.168.122.80-192.168.122.90 + endpoint_annotations: + metallb.universe.tf/address-pool: ctlplane + metallb.universe.tf/allow-shared-ip: ctlplane + metallb.universe.tf/loadBalancerIPs: 192.168.122.80 + net-attach-def: | + { + "cniVersion": "0.3.1", + "name": "ctlplane", + "type": "macvlan", + "master": "ospbr", + "ipam": { + "type": "whereabouts", + "range": "192.168.122.0/24", + "range_start": "192.168.122.30", + "range_end": "192.168.122.70" + } + } + internalapi: + dnsDomain: internalapi.example.com + subnets: + - allocationRanges: + - end: 172.17.0.250 + start: 172.17.0.100 + cidr: 172.17.0.0/24 + name: subnet1 + vlan: 20 + mtu: 1500 + prefix-length: 24 + iface: internalapi + vlan: 20 + base_iface: enp6s0 + lb_addresses: + - 172.17.0.80-172.17.0.90 + endpoint_annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/allow-shared-ip: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.80 + net-attach-def: | + { + "cniVersion": "0.3.1", + "name": "internalapi", + "type": "macvlan", + "master": "internalapi", + "ipam": { + "type": "whereabouts", + "range": "172.17.0.0/24", + "range_start": "172.17.0.30", + "range_end": "172.17.0.70" + } + } + storage: + dnsDomain: storage.example.com + subnets: + - allocationRanges: + - end: 172.18.0.250 + start: 172.18.0.100 + cidr: 172.18.0.0/24 + name: subnet1 + vlan: 21 + mtu: 9000 + prefix-length: 24 + iface: storage + vlan: 21 + base_iface: enp6s0 + lb_addresses: + - 172.18.0.80-172.18.0.90 + net-attach-def: | + { + "cniVersion": "0.3.1", + "name": "storage", + "type": "macvlan", + "master": "storage", + "ipam": { + "type": "whereabouts", + "range": "172.18.0.0/24", + "range_start": "172.18.0.30", + "range_end": "172.18.0.70" + } + } + storagemgmt: # used on RHEL, not used on OpenShift + dnsDomain: storagemgmt.example.com + subnets: + - allocationRanges: + - end: 172.20.0.250 + start: 172.20.0.100 + cidr: 172.20.0.0/24 + name: subnet1 + vlan: 23 + mtu: 9000 + tenant: + dnsDomain: tenant.example.com + subnets: + - allocationRanges: + - end: 172.19.0.250 + start: 172.19.0.100 + cidr: 172.19.0.0/24 + name: subnet1 + vlan: 22 + mtu: 1500 + prefix-length: 24 + iface: tenant + vlan: 22 + base_iface: enp6s0 + lb_addresses: + - 172.19.0.80-172.19.0.90 + net-attach-def: | + { + "cniVersion": "0.3.1", + "name": "tenant", + "type": "macvlan", + "master": "tenant", + "ipam": { + "type": "whereabouts", + "range": "172.19.0.0/24", + "range_start": "172.19.0.30", + "range_end": "172.19.0.70" + } + } + external: + dnsDomain: external.example.com + subnets: + - allocationRanges: + - end: 10.0.0.250 + start: 10.0.0.100 + cidr: 10.0.0.0/24 + gateway: 10.0.0.1 + name: subnet1 + mtu: 1500 + datacentre: + net-attach-def: | + { + "cniVersion": "0.3.1", + "name": "datacentre", + "type": "bridge", + "bridge": "ospbr", + "ipam": {} + } + + dns-resolver: + config: + server: + - 192.168.122.1 + search: [] + options: + - key: server + values: + - 192.168.122.1 + + routes: + config: [] + + rabbitmq: + endpoint_annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.85 + rabbitmq-cell1: + endpoint_annotations: + metallb.universe.tf/address-pool: internalapi + metallb.universe.tf/loadBalancerIPs: 172.17.0.86 + + lbServiceType: LoadBalancer + storageClass: local-storage + bridgeName: ospbr diff --git a/examples/va/pidone/service-values.yaml b/examples/va/pidone/service-values.yaml new file mode 100644 index 000000000..529c6e09f --- /dev/null +++ b/examples/va/pidone/service-values.yaml @@ -0,0 +1,26 @@ +# local-config: referenced, but not emitted by kustomize +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: service-values + annotations: + config.kubernetes.io/local-config: "true" +data: + glance: + customServiceConfig: | + [DEFAULT] + enabled_backends = default_backend:swift + [glance_store] + default_backend = default_backend + [default_backend] + swift_store_create_container_on_put = True + swift_store_auth_version = 3 + swift_store_auth_address = {{ .KeystoneInternalURL }} + swift_store_endpoint_type = internalURL + swift_store_user = service:glance + swift_store_key = {{ .ServicePassword }} + default: + replicas: 1 + swift: + enabled: true diff --git a/examples/va/pidone/values.yaml b/examples/va/pidone/values.yaml new file mode 100644 index 000000000..6b1638213 --- /dev/null +++ b/examples/va/pidone/values.yaml @@ -0,0 +1,172 @@ +# yamllint disable rule:line-length +# local-config: referenced, but not emitted by kustomize +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: edpm-nodeset-values + annotations: + config.kubernetes.io/local-config: "true" +data: + ssh_keys: + # Authorized keys that will have access to the dataplane computes via SSH + authorized: CHANGEME + # The private key that will have access to the dataplane computes via SSH + private: CHANGEME2 + # The public key that will have access to the dataplane computes via SSH + public: CHANGEME3 + nodeset: + ansible: + ansibleUser: cloud-admin + ansiblePort: 22 + ansibleVars: + timesync_ntp_servers: + - hostname: clock.redhat.com + # CHANGEME -- see https://access.redhat.com/solutions/253273 + # edpm_bootstrap_command: | + # subscription-manager register --username \ + # --password + # podman login -u -p registry.redhat.io + edpm_network_config_hide_sensitive_logs: false + edpm_network_config_os_net_config_mappings: + edpm-compute-0: + nic2: 6a:fe:54:3f:8a:02 # CHANGEME + edpm-compute-1: + nic2: 6b:fe:54:3f:8a:02 # CHANGEME + edpm-compute-2: + nic2: 6c:fe:54:3f:8a:02 # CHANGEME + edpm_network_config_template: | + --- + {% set mtu_list = [ctlplane_mtu] %} + {% for network in nodeset_networks %} + {{ mtu_list.append(lookup('vars', networks_lower[network] ~ '_mtu')) }} + {%- endfor %} + {% set min_viable_mtu = mtu_list | max %} + network_config: + - type: interface + name: nic1 + use_dhcp: true + mtu: {{ min_viable_mtu }} + - type: ovs_bridge + name: {{ neutron_physical_bridge_name }} + mtu: {{ min_viable_mtu }} + use_dhcp: false + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_cidr }} + routes: {{ ctlplane_host_routes }} + members: + - type: interface + name: nic2 + mtu: {{ min_viable_mtu }} + # force the MAC address of the bridge to this interface + primary: true + {% for network in nodeset_networks %} + - type: vlan + mtu: {{ lookup('vars', networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', networks_lower[network] ~ '_ip') }}/{{ lookup('vars', networks_lower[network] ~ '_cidr') }} + routes: {{ lookup('vars', networks_lower[network] ~ '_host_routes') }} + {% endfor %} + edpm_nodes_validation_validate_controllers_icmp: false + edpm_nodes_validation_validate_gateway_icmp: false + edpm_selinux_mode: enforcing + edpm_sshd_allowed_ranges: + - 192.168.122.0/24 + edpm_sshd_configure_firewall: true + enable_debug: false + gather_facts: false + neutron_physical_bridge_name: br-ex + neutron_public_interface_name: eth0 + service_net_map: + nova_api_network: internalapi + nova_libvirt_network: internalapi + storage_mtu: 9000 + storage_mgmt_mtu: 9000 + storage_mgmt_vlan_id: 23 + storage_mgmt_cidr: "24" + storage_mgmt_host_routes: [] + networks: + - defaultRoute: true + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + nodes: + edpm-compute-0: + ansible: + ansibleHost: 192.168.122.100 + hostName: edpm-compute-0 + networks: + - defaultRoute: true + fixedIP: 192.168.122.100 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + edpm-compute-1: + ansible: + ansibleHost: 192.168.122.101 + hostName: edpm-compute-1 + networks: + - defaultRoute: true + fixedIP: 192.168.122.101 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + edpm-compute-2: + ansible: + ansibleHost: 192.168.122.102 + hostName: edpm-compute-2 + networks: + - defaultRoute: true + fixedIP: 192.168.122.102 + name: ctlplane + subnetName: subnet1 + - name: internalapi + subnetName: subnet1 + - name: storage + subnetName: subnet1 + - name: storagemgmt + subnetName: subnet1 + - name: tenant + subnetName: subnet1 + services: + - bootstrap + - configure-network + - validate-network + - install-os + - configure-os + - ssh-known-hosts + - run-os + - reboot-os + - install-certs + - ovn + - neutron-metadata + - libvirt + - nova + nova: + migration: + ssh_keys: + private: CHANGEME4 + public: CHANGEME5 diff --git a/va/pidone/README.md b/va/pidone/README.md new file mode 100644 index 000000000..7af2ee0ab --- /dev/null +++ b/va/pidone/README.md @@ -0,0 +1,11 @@ +# VA: PIDONE + +If you are looking for information on how to deploy the PIDONE VA, then +please see the +[PIDONE README in the examples directory](../../examples/va/pidone/README.md). + +This directory, `architecture/va/pidone/`, exists so that the +[kustomization.yaml](../../examples/va/pidone/kustomization.yaml) +in the examples directory for the PIDONE VA, reference it by path as a +component. Its contents are likely uninteresting unless you want to +understand how kustomize was implemented in this repository. diff --git a/va/pidone/edpm/deployment/kustomization.yaml b/va/pidone/edpm/deployment/kustomization.yaml new file mode 100644 index 000000000..227bcc100 --- /dev/null +++ b/va/pidone/edpm/deployment/kustomization.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +transformers: + # Set namespace to OpenStack on all namespaced objects without a namespace + - |- + apiVersion: builtin + kind: NamespaceTransformer + metadata: + name: _ignored_ + namespace: openstack + setRoleBindingSubjects: none + unsetOnly: true + fieldSpecs: + - path: metadata/name + kind: Namespace + create: true + +components: + - ../../../../lib/dataplane/deployment diff --git a/va/pidone/edpm/nodeset/kustomization.yaml b/va/pidone/edpm/nodeset/kustomization.yaml new file mode 100644 index 000000000..756f97a63 --- /dev/null +++ b/va/pidone/edpm/nodeset/kustomization.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +transformers: + - |- + apiVersion: builtin + kind: NamespaceTransformer + metadata: + name: _ignored_ + namespace: openstack + setRoleBindingSubjects: none + unsetOnly: true + fieldSpecs: + - path: metadata/name + kind: Namespace + create: true + +components: + - ../../../../lib/dataplane/nodeset diff --git a/va/pidone/kustomization.yaml b/va/pidone/kustomization.yaml new file mode 100644 index 000000000..540fe2c84 --- /dev/null +++ b/va/pidone/kustomization.yaml @@ -0,0 +1,105 @@ +--- +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +transformers: + # Set namespace to OpenStack on all namespaced objects without a namespace + - |- + apiVersion: builtin + kind: NamespaceTransformer + metadata: + name: _ignored_ + namespace: openstack + setRoleBindingSubjects: none + unsetOnly: true + fieldSpecs: + - path: metadata/name + kind: Namespace + create: true + +components: + - ../../lib/networking/metallb + - ../../lib/networking/netconfig + - ../../lib/networking/nad + - ../../lib/control-plane + +# Add storagemgmt network template, as it is needed for CephHCI +patches: + - target: + version: v1beta1 + kind: NetConfig + name: netconfig + patch: |- + - op: add + path: /spec/networks/- + value: + dnsDomain: _replaced_ + name: storagemgmt + subnets: + - _replaced_ + mtu: 1500 + +replacements: + - source: + kind: ConfigMap + name: service-values + fieldPath: data.glance.customServiceConfig + targets: + - select: + kind: OpenStackControlPlane + fieldPaths: + - spec.glance.template.customServiceConfig + options: + create: true + - source: + kind: ConfigMap + name: service-values + fieldPath: data.glance.default.replicas + targets: + - select: + kind: OpenStackControlPlane + fieldPaths: + - spec.glance.template.glanceAPIs.default.replicas + options: + create: true + - source: + kind: ConfigMap + name: service-values + fieldPath: data.swift.enabled + targets: + - select: + kind: OpenStackControlPlane + fieldPaths: + - spec.swift.enabled + options: + create: true + # NetConfig dnsDomain specific to this VA + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storagemgmt.dnsDomain + targets: + - select: + kind: NetConfig + fieldPaths: + - spec.networks.[name=storagemgmt].dnsDomain + # NetConfig MTU specific to this VA + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storagemgmt.mtu + targets: + - select: + kind: NetConfig + fieldPaths: + - spec.networks.[name=storagemgmt].mtu + # NetConfig subnets specific to this VA + - source: + kind: ConfigMap + name: network-values + fieldPath: data.storagemgmt.subnets + targets: + - select: + kind: NetConfig + fieldPaths: + - spec.networks.[name=storagemgmt].subnets diff --git a/va/pidone/namespace.yaml b/va/pidone/namespace.yaml new file mode 100644 index 000000000..60a6e8c42 --- /dev/null +++ b/va/pidone/namespace.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: builtin +kind: NamespaceTransformer +metadata: + name: _ignored_ + namespace: openstack +setRoleBindingSubjects: none +unsetOnly: true +fieldSpecs: + - path: metadata/name + kind: Namespace + create: true diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 520060a3f..5517f21ff 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -6,6 +6,7 @@ - rhoso-architecture-validate-hci - rhoso-architecture-validate-ovs-dpdk - rhoso-architecture-validate-ovs-dpdk-sriov + - rhoso-architecture-validate-pidone - rhoso-architecture-validate-sriov - rhoso-architecture-validate-uni01alpha - rhoso-architecture-validate-uni02beta diff --git a/zuul.d/validations.yaml b/zuul.d/validations.yaml index 3894e7e26..86335c9c9 100644 --- a/zuul.d/validations.yaml +++ b/zuul.d/validations.yaml @@ -48,6 +48,18 @@ parent: rhoso-architecture-base-job vars: cifmw_architecture_scenario: ovs-dpdk-sriov +- job: + files: + - examples/va/pidone + - examples/va/pidone/edpm/deployment + - examples/va/pidone/edpm/nodeset + - examples/va/pidone/nncp + - lib + - va/pidone + name: rhoso-architecture-validate-pidone + parent: rhoso-architecture-base-job + vars: + cifmw_architecture_scenario: pidone - job: files: - automation/mocks/sriov.yaml