Skip to content

Commit

Permalink
Add fake-ipa
Browse files Browse the repository at this point in the history
Signed-off-by: Mohammed Boukhalfa <[email protected]>
  • Loading branch information
mboukhalfa committed Jul 22, 2024
1 parent a6127bf commit df4ddcf
Show file tree
Hide file tree
Showing 30 changed files with 2,582 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
__pycache__/
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
9 changes: 9 additions & 0 deletions fake-ipa/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ARG BASE_IMAGE=python:3.9-slim
FROM $BASE_IMAGE
ENV PBR_VERSION=1.0.0
COPY . /root/fake-ipa/
WORKDIR /root/fake-ipa/
ENV CONFIG ${CONFIG:-/root/fake-ipa/conf.py}
RUN pip install -r requirements.txt
RUN python3 setup.py install
CMD fake-ipa --config $CONFIG
48 changes: 48 additions & 0 deletions fake-ipa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Fake ironic python agent

Fake ipa is a tool to help test ironic communication with IPA.

Fake ipa simulate the IPA by:

- Running an API server with the needed real IPA endpoint.
- Send back fake inspection data when requested.
- lookup the node and save tokens.
- Heartbeating to ironic API with several threads looping over
a queue of fake agents.
- Faking the sync/async commands needed by ironic to inspect,
clean and provision a node.

## Run Fake ipa with ironic

### Requirements

Machine: `4c / 16gb / 100gb`
OS: `CentOS9-20220330`

### Test fake ipa

1. clone the env scripts `cd` inside `fake-ipa/Run-env` folder
2. check configs in `config.py`
3. run init `./Init-environment.sh`
4. to just rebuild fake-ipa from the local repo run `./rebuild-fipa.sh`

### Use ironic with fake-ipa

At this step there will be an ironic environment using fake-ipa,
by default there will be two nodes created on ironic you can list them with:
`baremetal node list`

To manage the a node using the ironicclient:
`baremetal node manage <node-name>`

To inspect use: `baremetal node inspect <node-name>`
then you can provide and deploy image on the node with:

```bash
baremetal node provide <node-name>
baremetal node deploy <node-name>
```

### Clean

To clean the env `./clean.sh`
99 changes: 99 additions & 0 deletions fake-ipa/Run-env/01-vm-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
set -e
#install kvm for minikube
dnf -y install qemu-kvm libvirt virt-install net-tools podman firewalld
systemctl enable --now libvirtd
systemctl start firewalld
systemctl enable firewalld
# create provisioning network
cat <<EOF >provisioning.xml
<network
xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'>
<dnsmasq:options>
<!-- Risk reduction for CVE-2020-25684, CVE-2020-25685, and CVE-2020-25686. See: https://access.redhat.com/security/vulnerabilities/RHSB-2021-001 -->
<dnsmasq:option value="cache-size=0"/>
</dnsmasq:options>
<name>provisioning</name>
<bridge name='provisioning'/>
<forward mode='bridge'></forward>
</network>
EOF

cat <<EOF >baremetal.xml
<network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'>
<name>baremetal</name>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='baremetal' stp='on' delay='0'/>
<domain name='ostest.test.metalkube.org' localOnly='yes'/>
<dns>
<forwarder domain='apps.ostest.test.metalkube.org' addr='127.0.0.1'/>
</dns>
<ip address='192.168.111.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.111.20' end='192.168.111.60'/>
<host mac='00:5c:52:31:3b:9c' name='node-0' ip='192.168.111.20'>
<lease expiry='60' unit='minutes'/>
</host>
<host mac='00:5c:52:31:3b:ad' name='node-1' ip='192.168.111.21'>
<lease expiry='60' unit='minutes'/>
</host>
</dhcp>
</ip>
<dnsmasq:options>
<dnsmasq:option value='cache-size=0'/>
</dnsmasq:options>
</network>
EOF
# define networks
virsh net-define baremetal.xml
virsh net-start baremetal
virsh net-autostart baremetal

virsh net-define provisioning.xml
virsh net-start provisioning
virsh net-autostart provisioning
tee -a /etc/NetworkManager/system-connections/provisioning.nmconnection <<EOF
[connection]
id=provisioning
type=bridge
interface-name=provisioning
[bridge]
stp=false
[ipv4]
address1=172.22.0.1/24
method=manual
[ipv6]
addr-gen-mode=eui64
method=disabled
EOF

chmod 600 /etc/NetworkManager/system-connections/provisioning.nmconnection
nmcli con load /etc/NetworkManager/system-connections/provisioning.nmconnection
nmcli con up provisioning

tee /etc/NetworkManager/system-connections/baremetal.nmconnection <<EOF
[connection]
id=baremetal
type=bridge
interface-name=baremetal
autoconnect=true
[bridge]
stp=false
[ipv6]
addr-gen-mode=stable-privacy
method=ignore
EOF

chmod 600 /etc/NetworkManager/system-connections/baremetal.nmconnection
nmcli con load /etc/NetworkManager/system-connections/baremetal.nmconnection
nmcli con up baremetal

# install minikube
curl -LO https://storage.googleapis.com/minikube/releases/v1.25.2/minikube-linux-amd64
install minikube-linux-amd64 /usr/local/bin/minikube
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
14 changes: 14 additions & 0 deletions fake-ipa/Run-env/02-configure-minikube.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set -e
minikube config set driver kvm2
minikube config set memory 4096
sudo usermod --append --groups libvirt "$(whoami)"
while /bin/true; do
minikube_error=0
minikube start --insecure-registry 172.22.0.1:5000 || minikube_error=1
if [[ $minikube_error -eq 0 ]]; then
break
fi
sudo su -l -c 'minikube delete --all --purge' "${USER}"
sudo ip link delete virbr0
done
minikube stop
70 changes: 70 additions & 0 deletions fake-ipa/Run-env/03-images-and-run-local-services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Set variables
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
REGISTRY_NAME="registry"
REGISTRY_PORT="5000"
IMAGE_NAMES=(
# "quay.io/metal3-io/sushy-tools"
"quay.io/metal3-io/ironic-client"
)

# Attach provisioning and baremetal network interfaces to minikube domain
virsh attach-interface --domain minikube --model virtio --source provisioning --type network --config
virsh attach-interface --domain minikube --model virtio --source baremetal --type network --config
podman pod create -n infra-pod || true
podman pod create -n ironic-pod || true
# Start podman registry if it's not already running
if ! podman ps | grep -q "$REGISTRY_NAME"; then
podman run -d -p "$REGISTRY_PORT":"$REGISTRY_PORT" --name "$REGISTRY_NAME" docker.io/library/registry:2.7.1
fi

# Pull images, tag to local registry, and push to registry
for NAME in "${IMAGE_NAMES[@]}"; do
# Pull and tag the image
podman pull "$NAME"
podman tag "$NAME" 127.0.0.1:"$REGISTRY_PORT"/localimages/"${NAME##*/}"
# Push the image to the local registry
podman push --tls-verify=false 127.0.0.1:5000/localimages/"${NAME##*/}"
done

./build-sushy-tools-and-fake-ipa-images.sh
# Set configuration options
cp ../conf.py "$SCRIPT_DIR/tmp/sushy-tools/conf.py"

# Create an htpasswd file
cat <<'EOF' >"$SCRIPT_DIR/tmp/sushy-tools/htpasswd"
admin:$2b$12$/dVOBNatORwKpF.ss99KB.vESjfyONOxyH.UgRwNyZi1Xs/W2pGVS
EOF
# Create directories
DIRECTORIES=(
"/opt/metal3-dev-env/ironic/virtualbmc"
"/opt/metal3-dev-env/ironic/virtualbmc/sushy-tools"
"/opt/metal3-dev-env/ironic/html/images"
)
for DIR in "${DIRECTORIES[@]}"; do
mkdir -p "$DIR"
chmod -R 755 "$DIR"
done

# Run httpd container
podman run -d --net host --name httpd-infra \
--pod infra-pod \
-v /opt/metal3-dev-env/ironic:/shared \
-e PROVISIONING_INTERFACE=provisioning \
-e LISTEN_ALL_INTERFACES=false \
--entrypoint /bin/runhttpd \
quay.io/metal3-io/ironic:latest

# Generate ssh keys to use for virtual power and add them to authorized_keys
sudo ssh-keygen -f /root/.ssh/id_rsa_virt_power -P "" -q -y
sudo cat /root/.ssh/id_rsa_virt_power.pub | sudo tee -a /root/.ssh/authorized_keys

# Create and start a container for sushy-tools
podman run -d --net host --name sushy-tools --pod infra-pod \
-v "$SCRIPT_DIR/tmp/sushy-tools:/root/sushy" \
-v /root/.ssh:/root/ssh \
127.0.0.1:5000/localimages/sushy-tools

# Create and start a container for fake-ipa
podman run -d --net host --name fake-ipa --pod infra-pod \
-v /root/.ssh:/root/ssh \
127.0.0.1:5000/localimages/fake-ipa
16 changes: 16 additions & 0 deletions fake-ipa/Run-env/04-start-minikube.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
set -e

# Start Minikube with insecure registry flag
minikube start --insecure-registry 172.22.0.1:5000

# SSH into the Minikube VM and execute the following commands
sudo su -l -c "minikube ssh sudo brctl addbr ironicendpoint" "${USER}"
sudo su -l -c "minikube ssh sudo ip link set ironicendpoint up" "${USER}"
sudo su -l -c "minikube ssh sudo brctl addif ironicendpoint eth2" "${USER}"
sudo su -l -c "minikube ssh sudo ip addr add 172.22.0.2/24 dev ironicendpoint" "${USER}"

# Firewall rules
for i in 8000 80 9999 6385 5050 6180 53 5000; do sudo firewall-cmd --zone=public --add-port=${i}/tcp; done
for i in 8000 80 9999 6385 5050 6180 53 5000; do sudo firewall-cmd --zone=libvirt --add-port=${i}/tcp; done
for i in 69 547 546 68 67 5353 6230 6231 6232 6233 6234 6235; do sudo firewall-cmd --zone=libvirt --add-port=${i}/udp; done
sudo firewall-cmd --zone=libvirt --add-port=8000/tcp
96 changes: 96 additions & 0 deletions fake-ipa/Run-env/05-apply-manifests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
set -e
# Apply ironic
# Clone bmo
if [ ! -d "baremetal-operator/" ] ; then
git clone "https://github.com/metal3-io/baremetal-operator.git"
fi

cd baremetal-operator/

# Ironic config file
cat <<'EOF' >ironic-deployment/default/ironic_bmo_configmap.env
HTTP_PORT=6180
PROVISIONING_IP=172.22.0.2
DEPLOY_KERNEL_URL=http://172.22.0.2:6180/images/ironic-python-agent.kernel
DEPLOY_RAMDISK_URL=http://172.22.0.2:6180/images/ironic-python-agent.initramfs
IRONIC_ENDPOINT=https://172.22.0.2:6385/v1/
CACHEURL=http://172.22.0.2/images
IRONIC_FAST_TRACK=true
IRONIC_KERNEL_PARAMS=console=ttyS0
IRONIC_INSPECTOR_VLAN_INTERFACES=all
PROVISIONING_CIDR=172.22.0.1/24
PROVISIONING_INTERFACE=ironicendpoint
DHCP_RANGE=172.22.0.10,172.22.0.100
IRONIC_INSPECTOR_ENDPOINT=http://172.22.0.2:5050/v1/
RESTART_CONTAINER_CERTIFICATE_UPDATED="false"
IRONIC_RAMDISK_SSH_KEY=ssh-rsa
IRONIC_USE_MARIADB=false
USE_IRONIC_INSPECTOR=true
EOF

# Apply default ironic manifest without tls or authentication for simplicity
# kubectl apply -k config/namespace/
# kubectl apply -k ironic-deployment/default
cd ..
# Building from ironic manifest to use an old ironic version
# The current fake IPA is configured to work with separated
# inspector the new version when inspector and ironic mereged
# seems to require the TLS
kubectl apply -f ironic.yaml -n baremetal-operator-system

kubectl -n baremetal-operator-system wait --for=condition=available deployment/baremetal-operator-ironic --timeout=300s

cat <<'EOF' >ironicclient.sh
#!/bin/bash
DIR="$(dirname "$(readlink -f "$0")")"
if [ -d "${PWD}/_clouds_yaml" ]; then
MOUNTDIR="${PWD}/_clouds_yaml"
else
echo "cannot find _clouds_yaml"
exit 1
fi
if [ "$1" == "baremetal" ] ; then
shift 1
fi
# shellcheck disable=SC2086
sudo podman run --net=host --tls-verify=false \
-v "${MOUNTDIR}:/etc/openstack" --rm \
-e OS_CLOUD="${OS_CLOUD:-metal3}" 127.0.0.1:5000/localimages/ironic-client "$@"
EOF
pwd
mkdir _clouds_yaml

cat <<'EOF' >_clouds_yaml/clouds.yaml
clouds:
metal3:
auth_type: none
baremetal_endpoint_override: http://172.22.0.2:6385
baremetal_introspection_endpoint_override: http://172.22.0.2:5050
EOF
sudo chmod a+x ironicclient.sh
sudo ln -sf "$PWD/ironicclient.sh" "/usr/local/bin/baremetal"

# Create ironic node
sudo touch /opt/metal3-dev-env/ironic/html/images/image.qcow2

baremetal node create --driver redfish --driver-info \
redfish_address=http://192.168.111.1:8000 --driver-info \
redfish_system_id=/redfish/v1/Systems/27946b59-9e44-4fa7-8e91-f3527a1ef094 --driver-info \
redfish_username=admin --driver-info redfish_password=password \
--name default-node-1

baremetal node set default-node-1 --driver-info deploy_kernel="http://172.22.0.2:6180/images/ironic-python-agent.kernel" --driver-info deploy_ramdisk="http://172.22.0.2:6180/images/ironic-python-agent.initramfs"
baremetal node set default-node-1 --instance-info image_source=http://172.22.0.1/images/image.qcow2 --instance-info image_checksum=http://172.22.0.1/images/image.qcow2

baremetal node create --driver redfish --driver-info \
redfish_address=http://192.168.111.1:8000 --driver-info \
redfish_system_id=/redfish/v1/Systems/27946b59-9e44-4fa7-8e91-f3527a1ef095 --driver-info \
redfish_username=admin --driver-info redfish_password=password \
--name default-node-2

baremetal node set default-node-2 --driver-info deploy_kernel="http://172.22.0.2:6180/images/ironic-python-agent.kernel" --driver-info deploy_ramdisk="http://172.22.0.2:6180/images/ironic-python-agent.initramfs"
baremetal node set default-node-2 --instance-info image_source=http://172.22.0.1/images/image.qcow2 --instance-info image_checksum=http://172.22.0.1/images/image.qcow2
6 changes: 6 additions & 0 deletions fake-ipa/Run-env/Init-environment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set -e
sudo ./01-vm-setup.sh
./02-configure-minikube.sh
sudo ./03-images-and-run-local-services.sh
./04-start-minikube.sh
./05-apply-manifests.sh
Loading

0 comments on commit df4ddcf

Please sign in to comment.