Skip to content

Instantly share code, notes, and snippets.

@dmc5179
Last active April 30, 2026 17:43
Show Gist options
  • Select an option

  • Save dmc5179/de79b49e9b36b1029cac3596ff823ad2 to your computer and use it in GitHub Desktop.

Select an option

Save dmc5179/de79b49e9b36b1029cac3596ff823ad2 to your computer and use it in GitHub Desktop.
Script to link OpenShift Node, Machine, and BareMetalHost Objects for agent based installations

Link Node to Bare Metal Host and Machine Object

  • Derived from the following access article

https://access.redhat.com/solutions/7130140#ocp_step_10

Set Variables needed to link

export NODE_NAME=""          # Node name from "oc get nodes"
export NEW_MACHINE_NAME=""   # Typically same as NODE_NAME
export BOOT_MAC=""           # MAC address of boot NICE
export BOOT_MODE=""          # UEFI vs legacy
export CLUSTER_NAME=$(oc get infrastructure cluster -o=jsonpath='{.status.infrastructureName}{"\n"}')
export ROLE="worker"         # master or worker

Create template files

  • Bare Metal Host Template
cat <<EOF > bare-metal-host-object.yaml
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: bmh-name
  namespace: openshift-machine-api
spec:
  automatedCleaningMode: metadata
  bootMACAddress: 00:00:00:00:00:00
  bootMode: legacy
  customDeploy:
    method: install_coreos
  externallyProvisioned: true
  online: true
  userData:
    name: worker-user-data-managed
    namespace: openshift-machine-api
EOF
  • Machine Template
cat <<EOF > machine-object.yaml
apiVersion: machine.openshift.io/v1beta1
kind: Machine
metadata:
  annotations:
    machine.openshift.io/instance-state: unmanaged
    metal3.io/BareMetalHost: openshift-machine-api/node-name
  finalizers:
    - machine.machine.openshift.io
  labels:
    machine.openshift.io/cluster-api-cluster: cluster-id
    machine.openshift.io/cluster-api-machine-role: worker
    machine.openshift.io/cluster-api-machine-type: worker
  name: node-name
  namespace: openshift-machine-api
spec:
  metadata: {}
  providerSpec:
    value:
      apiVersion: baremetal.cluster.k8s.io/v1alpha1
      customDeploy:
        method: install_coreos
      hostSelector: {}
      image:
        checksum: ''
        url: ''
      kind: BareMetalMachineProviderSpec
      metadata:
        creationTimestamp: null
      userData:
        name: worker-user-data-managed
EOF

Create Bare Metal Host Object

yq -y -i --arg val ${NODE_NAME} '.metadata.name = $val' bare-metal-host-object.yaml

yq -y -i --arg val ${BOOT_MAC} '.spec.bootMACAddress = $val' bare-metal-host-object.yaml

yq -y -i --arg val ${BOOT_MODE} '.spec.bootMode = $val' bare-metal-host-object.yaml

user_data="${ROLE}-user-data-managed"
yq -y -i --arg val ${user_data} '.spec.userData.name = $val' bare-metal-host-object.yaml

oc create -f bare-metal-host-object.yaml

Create Machine Object

bmh="openshift-machine-api/${NODE_NAME}"
yq -y -i --arg val ${bmh} '.metadata.annotations."metal3.io/BareMetalHost" = $val' machine-object.yaml

yq -y -i --arg val ${CLUSTER_NAME} '.metadata.labels."machine.openshift.io/cluster-api-cluster" = $val' machine-object.yaml

yq -y -i --arg val ${ROLE} '.metadata.labels."machine.openshift.io/cluster-api-machine-role" = $val' machine-object.yaml
yq -y -i --arg val ${ROLE} '.metadata.labels."machine.openshift.io/cluster-api-machine-type" = $val' machine-object.yaml

yq -y -i --arg val ${NODE_NAME} '.metadata.name = $val' machine-object.yaml

user_data="${ROLE}-user-data-managed"
yq -y -i --arg val ${user_data} '.spec.providerSpec.value.userData.name = $val' machine-object.yaml

oc create -f machine-object.yaml

Link the Node, Machine, and BareMetalHost

Define the BMH_UID by using the following command to extract it from the new node’s bmh

export BMH_UID=$(oc get -n openshift-machine-api bmh $NODE_NAME -ojson | jq -r .metadata.uid)
echo $BMH_UID

Patch consumerRef object into baremetal host

oc patch -n openshift-machine-api bmh $NODE_NAME --type merge --patch '{"spec":{"consumerRef":{"apiVersion":"machine.openshift.io/v1beta1","kind":"Machine","name":"'$NEW_MACHINE_NAME'","namespace":"openshift-machine-api"}}}'

Patch providerID into the new node

oc patch node $NODE_NAME --type merge --patch '{"spec":{"providerID":"baremetalhost:///openshift-machine-api/'$NODE_NAME'/'$BMH_UID'"}}'

Review the providerIDs

oc get node -l node-role.kubernetes.io/${ROLE} -ojson | jq -r '.items[] | .metadata.name + "  " + .spec.providerID'

Set bmh poweredOn (if necessary)

oc patch -n openshift-machine-api bmh $NODE_NAME --subresource status --type json -p '[{"op":"replace","path":"/status/poweredOn","value":true}]'

Review bmh poweredOn status

oc get bmh -n openshift-machine-api -ojson | jq -r '.items[] | .metadata.name + "   PoweredOn:" +  (.status.poweredOn | tostring)'

Review the bmh provisioning state

oc get bmh -n openshift-machine-api -ojson | jq -r '.items[] | .metadata.name + "   ProvsioningState:" +  .status.provisioning.state'

Change the provisioning state (if necessary)

oc patch -n openshift-machine-api bmh $NODE_NAME --subresource status --type json -p '[{"op":"replace","path":"/status/provisioning/state","value":"unmanaged"}]'

Set the machine provisioned state (if necessary)

oc  patch -n openshift-machine-api machines.machine.openshift.io $NEW_MACHINE_NAME -n openshift-machine-api --subresource status --type json -p '[{"op":"replace","path":"/status/phase","value":"Provisioned"}]'

Additonal Informational Commands

  • Generate the providerID lines for control plane nodes
oc get -n openshift-machine-api baremetalhost -l installer.openshift.io/role=control-plane -ojson | jq -r '.items[] | "baremetalhost:///openshift-machine-api/" + .metadata.name + "/" + .metadata.uid'
  • Identify the cluster
oc get machines.machine.openshift.io -n openshift-machine-api -l machine.openshift.io/cluster-api-machine-role=master  -L machine.openshift.io/cluster-api-cluster 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment