# Community.routeros.api\_modify: add support for containers

**URL:** <https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477>\
**Category:** Collection Development\
**Tags:** routeros\
**Created:** [September 12, 2024, 9:43pm UTC](https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477 "2024-09-12T21:43:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hirnpfirsich](https://avatars.discourse-cdn.com/v4/letter/h/a9adbd/32.png) [@hirnpfirsich](https://forum.ansible.com/u/hirnpfirsich)\
**Post date:** [September 12, 2024, 9:43pm UTC](https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477/1 "2024-09-12T21:43:33Z")

</div>

Hello everybody 🙂

I am currently in the process of writing support for the [`container` feature](https://help.mikrotik.com/docs/display/ROS/Container) in `routeros` for the `community.routeros.api_modify` module.

Implementing `/container/envs`, `/container/mounts` and `/container/config` was rather trivial. My [fork](https://github.com/ansible-collections/community.routeros/compare/main...hirnpfirsich:community.routeros:main) contains the changes.

Now I’ve got two problems when trying to support the `/container` path itself.

## problem #1: uncertain primary key situation

The primary key for an `container` entry is the `name` field.  
Unfortunately this field contains an automatically generated `uuid` that cannot be altered:

```auto
[admin@sax-hts1-gw-core01] /container> add remote-image=alpine:latest interface=container_test 
[admin@sax-hts1-gw-core01] /container> print detail 
 0 name="37ab9172-31eb-4fb2-ad55-414f4047a597" tag="alpine:latest" os="" arch="" interface=container_test mounts="" dns="" status=extracting 
[admin@sax-hts1-gw-core01] /container> set name=hello 0

```

My code for handling this endpoint is this:

```python
    ('container', ): APIData(
        versioned=[
            # available since 7.4beta4
            ('7.4', '>', VersionedAPIData(
                fully_understood=True,
                fields={
[...]
                    'name': KeyInfo(read_only=True),
[...]
                },
            )),
        ],
    ),

```

I explicitly did not define a `primary_key`. This seems to work fine with:

```yaml
     handle_absent_entries: remove
     handle_entries_content: remove_as_much_as_possible

```

but I am not sure if this is the correct way.

## problem #2: `remote-image | file -> tag`

When creating or manipulating an `container` one can set the image for it via `remote-image` (if the image should be pulled from a registry) or via `file` (if the image is a local `.tar` archive).

Whichever method is chosen afterwords the resolved image tag will be written into the read only attribute `tag` (as seen in the routeros cli example above).

The problem with this behaviour is that `community.routeros.api_modify` does not know that `remote-tag` (or `file`) sets `tag` and is therefore unable to detect changes.  
I have already tried to mark `tag` as `automatically_computed_by="remote-image"` but that did not do the trick.  
This is the relevant code snippet:

```python
    ('container', ): APIData(
        versioned=[
            # available since 7.4beta4
            ('7.4', '>', VersionedAPIData(
                fully_understood=True,
                fields={
[...]
                    'file': KeyInfo(write_only=True),
[...]
                    'remote-image': KeyInfo(write_only=True),
[...]
                    'tag': KeyInfo(read_only=True, automatically_computed_from='remote-image'),
[...]
                },
            )),
        ],
    ),

```

* * *

Could someone help me figure out how to correctly implement the `container` support for `community.routeros.api_modify` ?

I only found @felixfontein on the forums therefore you are the only maintainer I am tagging in the post.

Thanks you all so much for reading ! 🙂

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [September 13, 2024, 9:42pm UTC](https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477/2 "2024-09-13T21:42:25Z")

</div>

For your problem #1, not using a primary key and marking `name` as read-only looks like the best way forward.

For #2, `automatically_computed_from` currently doesn’t really do something at the moment (see for example [Correction and Bugfix for ip dhcp-server network by phox142 · Pull Request #156 · ansible-collections/community.routeros · GitHub](https://github.com/ansible-collections/community.routeros/pull/156)).

I’m currently wondering whether supporting `container` with the existing api\_modify module is a good idea, since that path seems to be pretty “special”. Maybe a more specialized module is needed for it? Or some more specific logic for paths like that (are there others?)?

---

<div class="post-metadata">

**Author:** ![hirnpfirsich](https://avatars.discourse-cdn.com/v4/letter/h/a9adbd/32.png) [@hirnpfirsich](https://forum.ansible.com/u/hirnpfirsich)\
**Post date:** [September 14, 2024, 12:29pm UTC](https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477/3 "2024-09-14T12:29:32Z")

</div>

Thank you for your response @felixfontein ! 🙂

Ok so `#1` is a non issue that’s nice.

> I’m currently wondering whether supporting `container` with the existing api\_modify module is a good idea, since that path seems to be pretty “special”. Maybe a more specialized module is needed for it? Or some more specific logic for paths like that (are there others?)?

I have no idea if there are other paths besides `/container` that behave “funny”. In my two year `routeros` experience I did not encountered anything like that but that obviously is not a conclusive answer.

Supporting `remote-image` is feasible - `file` is way more complicated/impossible?

We only need to teach `api_modify` that `remote-image` is `write_only` and sets `tag` implicitly. Therefore when `remote-image` does not match `tag` we have a `CHANGE`.

If the users sets `remote-image` to the correct `long-name` of an image this should work perfectly well. So if `remote-image` is `library/alpine:latest` tag will also be `library/alpine:latest`. Changing `remote-image` will then trigger the change on the device.  
Under this assumption a user setting `remote-image` to `alpine:latest` will have a bad time because the resulting `tag` will be `library/alpine:latest` therefore always registering a change. We could note this in the module documentation.

Handling `file` seems to be impossible though.  
The container engine in `routeros` needs to extract the image file to resolve the image name (aka `tag`). Therefore we have no way of telling `api_modify` that `superdopeimage.tar` is actually `alpine:latest` underneath. We would need to parse the image ourselfs to check if there is a change and that introduces a whole new class of problems.

* * *

**Long story short** : I would like to support `container` with `remote-image` in `api_modify`. And either explicitly not supporting `file` or supporting it without `CHANGE` detection.

I am more or less confident that I could build a special case in `api_modify` for that. On the other hand I am pretty certain that building a whole new module for this is out of my comfort zone.

Do I have your blessing for trying to introduce a new `field` in `KeyInfo()/APIData()` which represents this construct ?

Thank you so much and have a nice weekend @felixfontein ! 🙂

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [September 18, 2024, 4:17pm UTC](https://forum.ansible.com/t/community-routeros-api-modify-add-support-for-containers/8477/4 "2024-09-18T16:17:41Z")

</div>

It sounds to me like `automatically_computed_by` would be a good fit here, in a properly implemented way (that doesn’t exist yet). And for `remote-image`, a new option `create_only=True` (similar, but not identical to `write_only`) probably makes sense?

In any case, feel free to propose how this could be implemented, I’ll happily look at proposals / PRs.
