> For the complete documentation index, see [llms.txt](https://platform9.com/kb/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://platform9.com/kb/pmk/how-to/modify-metallb-addon-config-via-api.md).

# How To Add/Modify Existing MetalLB Configuration via API

## Problem

How To Add/Modify Existing MetalLB Configuration via API on a PMK cluster?

## Environment

* Platform9 Managed Kubernetes
* AddOn Operator v4.0.0 & MetalLB v0.9.7 and Above

## Procedure

Verify the *pf9-addon-operator* version on the cluster.

{% tabs %}
{% tab title="pf9-addon-operator Image" %}

```none
# kubectl describe deployment pf9-addon-operator -n pf9-addons | grep -i image
    Image:      platform9/pf9-addon-operator:5.0.0
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Info**

One can add/modify the set/existing MetalLB configuration as desired by following the steps below.

**Note:** For Cluster running *pf9-addon-operator* version below 4.0.0, set the *watch* attribute in the MetalLB ClusterAddOn object to *false* and then make changes to the MetalLB configmap directly so that the AddOn operator will not revert the changes made to the configmap. Note that the same will be overwritten post cluster upgrade.
{% endhint %}

1. Fetch the authentication TOKEN. [Keystone Identity API](https://platform9.com/docs/kubernetes/keystone-identity-api): This link describes the process for getting a Keystone authentication token in order to access the PMK REST API.
2. API to retrieve currently set MetalLB ClusterAddon object details.

```none
curl -X GET -H "X-Auth-Token: $TOKEN" https://<DU_FQDN>/qbert/v4/<PROJECT_ID>/sunpike/apis/sunpike.platform9.com/v1alpha2/namespaces/default/clusteraddons/<CLUSTER_UUID>-metallb
```

{% hint style="info" %}
**Info**

Replace the placeholders `<DU_FQDN>`, `<PROJECT_ID>` and the `<CLUSTER_UUID>` with their appropriate values.
{% endhint %}

* MetalLB ClusterAddon object here with single address pool range.

{% tabs %}
{% tab title="Example GET API" %}

```none
curl -X GET -H "X-Auth-Token: $TOKEN" https://cse.platform9.io/qbert/v4/b855dca4be144f089b68dcff7c39f820/sunpike/apis/sunpike.platform9.com/v1alpha2/namespaces/default/clusteraddons/8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1446  100  1446    0     0   1948      0 --:--:-- --:--:-- --:--:--  1972
{
  "kind": "ClusterAddon",
  "apiVersion": "sunpike.platform9.com/v1alpha2",
  "metadata": {
    "name": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb",
...
...
  "spec": {
    "clusterID": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7",
    "version": "0.10.2",
    "type": "metallb",
    "override": {
      "params": [
        {
          "name": "MetallbIpRange",
          "value": "10.128.147.247-10.128.147.249"
        }
      ]
    },
    "watch": true
  },
  "status": {
    "phase": "Installed",
    "healthy": true,
    "lastChecked": null
  }
}
```

{% endtab %}
{% endtabs %}

* Related Existing ConfigMap.

{% tabs %}
{% tab title="Example of Existing ConfigMap" %}

```none
$ kubectl describe configmap config -n metallb-system
Name:         config
Namespace:    metallb-system
Labels:       <none>
Annotations:  <none>

Data
====
config:
----
address-pools:
- name: default
  protocol: layer2
  addresses:
  - 10.128.147.247-10.128.147.249

Events:  <none>
```

{% endtab %}
{% endtabs %}

3. Create a new JSON spec for MetalLB.

{% hint style="info" %}
**Info**

Replace the values for `clusterID` & `sunpike.pf9.io/cluster` with required *CLUSTER\_UUID*.

The `name` attribute in the spec must be in the format *`CLUSTER_UUID-metallb`.*
{% endhint %}

{% tabs %}
{% tab title="Spec Example" %}

```none
# cat metallbaddon.json
{
  "apiVersion": "sunpike.platform9.com/v1alpha2",
  "kind": "ClusterAddon",
  "metadata": {
    "labels": {
      "sunpike.pf9.io/cluster": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7",
      "type": "metallb"
    },
    "name": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb",
    "namespace": "default"
  },
  "spec": {
    "clusterID": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7",
    "override": {
      "params": [
        {
          "name": "base64EncMetallbConfig",
          "value": "YWRkcmVzcy1wb29sczoKLSBuYW1lOiBkZWZhdWx0CiAgcHJvdG9jb2w6IGxheWVyMgogIGFkZHJlc3NlczoKICAgLSAxMC4xMjguMTQ3LjI0Ny0xMC4xMjguMTQ3LjI0OAotIG5hbWU6IHBvb2wKICBwcm90b2NvbDogbGF5ZXIyCiAgYWRkcmVzc2VzOgogICAtIDEwLjEyOC4xNDcuMjQ5LTEwLjEyOC4xNDcuMjUw"
        }
      ]
    },
    "type": "metallb",
    "version": "0.10.2",
    "watch": true
  }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Example Encoded string value for parameter base64EncMetallbConfig" %}

```none
YWRkcmVzcy1wb29sczoKLSBuYW1lOiBkZWZhdWx0CiAgcHJvdG9jb2w6IGxheWVyMgogIGFkZHJlc3NlczoKICAgLSAxMC4xMjguMTQ3LjI0Ny0xMC4xMjguMTQ3LjI0OAotIG5hbWU6IHBvb2wKICBwcm90b2NvbDogbGF5ZXIyCiAgYWRkcmVzc2VzOgogICAtIDEwLjEyOC4xNDcuMjQ5LTEwLjEyOC4xNDcuMjUw
```

{% endtab %}
{% endtabs %}

translates to

{% tabs %}
{% tab title="Example Decoded string value for base64EncMetallbConfig" %}

```none
address-pools:
- name: default
  protocol: layer2
  addresses:
   - 10.128.147.247-10.128.147.248
- name: pool
  protocol: layer2
  addresses:
   - 10.128.147.249-10.128.147.250
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Note**

In the above example, we are passing *`base64EncMetallbConfig`* string which includes Multiple Named Address Pools which have different IP allocations than the original `MetallbIpRange`.
{% endhint %}

4. Patching the existing MetalLB ClusterAddon object with the above-mentioned new JSON spec *metallbaddon.json*.

{% tabs %}
{% tab title="PATCH API" %}

```none
curl -X PATCH -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/merge-patch+json" -H "Accept: application/json" -d "@metallbaddon.json" https://<DU_FQDN>/qbert/v4/<PROJECT_ID>/sunpike/apis/sunpike.platform9.com/v1alpha2/namespaces/default/clusteraddons/<CLUSTER_UUID>-metallb
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Example Patch API" %}

```none
# curl -X PATCH -H "X-Auth-Token: $TOKEN" -H "Content-Type: application/merge-patch+json" -H "Accept: application/json" -d "@metallbaddon.json" https://cse.platform9.io/qbert/v4/b855dca4be144f089b68dcff7c39f820/sunpike/apis/sunpike.platform9.com/v1alpha2/namespaces/default/clusteraddons/8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb

...
```

{% endtab %}
{% endtabs %}

* Updated MetalLB ClusterAddon object

{% tabs %}
{% tab title="Example GET API Post Update" %}

```none
curl -X GET -H "X-Auth-Token: $TOKEN" https://cse.platform9.io/qbert/v4/b855dca4be144f089b68dcff7c39f820/sunpike/apis/sunpike.platform9.com/v1alpha2/namespaces/default/clusteraddons/8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb | jq

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1825  100  1825    0     0   2351      0 --:--:-- --:--:-- --:--:--  2382
{
  "kind": "ClusterAddon",
  "apiVersion": "sunpike.platform9.com/v1alpha2",
  "metadata": {
    "name": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7-metallb",
...
...
  "spec": {
    "clusterID": "8c3bd9bf-951d-4d60-88dc-aa42c4f548d7",
    "version": "0.10.2",
    "type": "metallb",
    "override": {
      "params": [
        {
          "name": "base64EncMetallbConfig",
          "value": "YWRkcmVzcy1wb29sczoKLSBuYW1lOiBkZWZhdWx0CiAgcHJvdG9jb2w6IGxheWVyMgogIGFkZHJlc3NlczoKICAgLSAxMC4xMjguMTQ3LjI0Ny0xMC4xMjguMTQ3LjI0OAotIG5hbWU6IHBvb2wKICBwcm90b2NvbDogbGF5ZXIyCiAgYWRkcmVzc2VzOgogICAtIDEwLjEyOC4xNDcuMjQ5LTEwLjEyOC4xNDcuMjUw"
        }
      ]
    },
    "watch": true
  },
  "status": {
    "phase": "Installed",
    "healthy": true,
    "lastChecked": null
  }
}
```

{% endtab %}
{% endtabs %}

* ConfigMap Updated After the PATCH Request.

{% tabs %}
{% tab title="Example of Updated ConfigMap" %}

```none
$ kubectl describe configmap config -n metallb-system
Name:         config
Namespace:    metallb-system
Labels:       <none>
Annotations:  <none>

Data
====
config:
----
address-pools:
- name: default
  protocol: layer2
  addresses:
   - 10.128.147.247-10.128.147.248
- name: pool
  protocol: layer2
  addresses:
   - 10.128.147.249-10.128.147.250

Events:  <none>
```

{% endtab %}
{% endtabs %}

## Additional Information

* Within PMK, currently while creating a cluster you can provide multiple address pools for MetalLB. \**Reference: \**[Create a cluster using auto-deploy or manual mode](https://platform9.com/docs/v5.2/qbert-v3/ref#postcreates-a-cluster-using-auto-deploy-or-manual-mode)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://platform9.com/kb/pmk/how-to/modify-metallb-addon-config-via-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
