linode_api4-python icon indicating copy to clipboard operation
linode_api4-python copied to clipboard

Cannot update Domain type from master to slave

Open stvnjacobs opened this issue 4 years ago • 1 comments

Existing domains can be updated from a type master to type slave through the API. Through trial and error, I learned that it also requires master_ips to be popluated, but as long as it is provided, it works.

$ curl -s \
    -H "Authorization: Bearer ${LINODE_TOKEN}" \
    https://api.linode.com/v4/domains/1404371 | jq
{
  "id": 1404371,
  "type": "master",
  "domain": "sjacobs.local",
  "tags": [],
  "group": "",
  "status": "active",
  "description": "",
  "soa_email": "[email protected]",
  "retry_sec": 0,
  "master_ips": [],
  "axfr_ips": [],
  "expire_sec": 0,
  "refresh_sec": 0,
  "ttl_sec": 0,
  "created": "2020-07-25T02:38:49",
  "updated": "2020-09-18T17:56:10"
}
$ curl -s -X PUT \
    -H "content-type: application/json" \
    -H "Authorization: Bearer ${LINODE_TOKEN}" \
    -d '{"id": 1404371, "type": "slave", "domain": "sjacobs.local", "master_ips": ["127.0.0.1"]}' \
    https://api.linode.com/v4/domains/1404371 | jq
{
  "id": 1404371,
  "type": "slave",
  "domain": "sjacobs.local",
  "tags": [],
  "group": "",
  "status": "active",
  "description": "",
  "soa_email": "[email protected]",
  "retry_sec": 0,
  "master_ips": [
    "127.0.0.1"
  ],
  "axfr_ips": [],
  "expire_sec": 0,
  "refresh_sec": 0,
  "ttl_sec": 0,
  "created": "2020-07-25T02:38:49",
  "updated": "2021-07-22T18:30:52"
}

When the same operation trying through the Python library, this fails.

>>> d = Domain(client, 1404371)
>>> d.domain
'sjacobs.local'
>>> d.type
'master'
>>> d.type = 'slave'
>>> d.master_ips = ['127.0.0.1']
>>> d.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sjacobs/Code/foo/venv/lib/python3.9/site-packages/linode_api4/objects/base.py", line 156, in save
    resp = self._client.put(type(self).api_endpoint, model=self,
  File "/home/sjacobs/Code/foo/venv/lib/python3.9/site-packages/linode_api4/linode_client.py", line 1323, in put
    return self._api_call(*args, method=self.session.put, **kwargs)
  File "/home/sjacobs/Code/foo/venv/lib/python3.9/site-packages/linode_api4/linode_client.py", line 1286, in _api_call
    raise ApiError(error_msg, status=response.status_code, json=j)
linode_api4.errors.ApiError: 400: Length must be 1-50 characters;

Stats:

$ pip freeze | grep linode
linode-api4==5.2.0

$ python --version
Python 3.9.2

stvnjacobs avatar Jul 22 '21 18:07 stvnjacobs

For the purposes of debugging, it might help to see the JSON the API returned that generated that error:

In [15]: try:
    ...:     d.save()
    ...: except Exception as e:
    ...:     err = e
    ...:

In [16]: err
Out[16]: linode_api4.errors.ApiError('400: Length must be 1-50 characters; ')

In [17]: err.json
Out[17]: {'errors': [{'reason': 'Length must be 1-50 characters', 'field': 'group'}]}

It looks like when we called d.save(), it also attempted to save the empty string for the group field:

In [18]: d.group
Out[18]: ''

You can just populate that as whatever and it should work:

In [19]: d.group = "whatever"

In [20]: d.save()
Out[20]: True

In [21]: d.type
Out[21]: 'slave'

However, it would be nice if it wasn't necessary; I'll see what I do can.

Dorthu avatar Oct 19 '21 15:10 Dorthu