Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support --template-driver for docker_config (#332) #345

Merged
merged 10 commits into from
May 11, 2022

Conversation

sashajenner
Copy link
Contributor

SUMMARY

Adding template_driver option with one option 'golang'. Creates a dictionary templating or None as required by create_config (https://docker-py.readthedocs.io/en/stable/api.html#docker.api.config.ConfigApiMixin.create_config). This is to be used in conjunction with a template file specified in data.

Fixes #332.

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

Support --template-driver for docker_config

@github-actions
Copy link

github-actions bot commented May 3, 2022

Docs Build 📝

Thank you for contribution!✨

This PR has been merged and your docs changes will be incorporated when they are next published.

Copy link
Collaborator

@felixfontein felixfontein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! Please add a changelog fragment.

plugins/modules/docker_config.py Show resolved Hide resolved
plugins/modules/docker_config.py Outdated Show resolved Hide resolved
plugins/modules/docker_config.py Outdated Show resolved Hide resolved
plugins/modules/docker_config.py Outdated Show resolved Hide resolved
@felixfontein felixfontein added enhancement New feature or request docker-swarm Docker Swarm labels May 3, 2022
@sashajenner
Copy link
Contributor Author

Thank you for the detailed review. I have made updates as a result. Please let me know what you think of these changes.

@sashajenner
Copy link
Contributor Author

It is possible to add some integration tests for this new option. Let me know if you think this is necessary or not.

@felixfontein
Copy link
Collaborator

It is possible to add some integration tests for this new option. Let me know if you think this is necessary or not.

This is a good idea! At least for the platforms which use the lastest Docker SDK for Python, and a new enough Docker daemon :) You simply need to add one or more tasks to tests/integration/targets/docker_config/tasks/test_docker_config.yml for that. Look at https://github.com/ansible-collections/community.docker/blob/main/tests/integration/targets/docker_container/tasks/tests/options.yml#L1046-L1084 for an example of a test which only works for certain Docker daemon and Docker SDK for Python versions: it ignores failures for all tasks, and then checks whether it behaved correctly.

Copy link
Collaborator

@felixfontein felixfontein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think self.data_key needs to be updated when templating is used. I'm not sure what's the best way to do this. First you should probably add a method def _data_key_content(self): which is used in line 255 as self.data_key = hashlib.sha224(self._data_key_content()).hexdigest().

In that function, I would probably compile a configuration dictionary that's empty when template is not specified, and otherwise contains a key template_driver with the value of the template_driver option. If that config dict is empty, return data. Otherwise, return data + SALT + json(config_dict) (with sort_keys etc. so that JSON generation does not depend on platform), where SALT is a constant to be created containing a fixed but random string. (For example nu7Zook2bo4Ohyah1ieghae2ohpho7Haa1yeefieNgoo9ov3que3yaiKeing1poh.)

@felixfontein
Copy link
Collaborator

Hmm, it would probably be better if you could determine for an existing config which templating method is used. If that is doable, use that to fix idempotence and leave self.data_key alone.

@felixfontein
Copy link
Collaborator

You'll have to add the idempotence check in

self.results['config_id'] = config['ID']
self.results['config_name'] = config['Spec']['Name']
data_changed = False
attrs = config.get('Spec', {})
if attrs.get('Labels', {}).get('ansible_key'):
if attrs['Labels']['ansible_key'] != self.data_key:
data_changed = True
else:
if not self.force:
self.client.module.warn("'ansible_key' label not found. Config will not be changed unless the force parameter is set to 'yes'")
labels_changed = not compare_generic(self.labels, attrs.get('Labels'), 'allow_more_present', 'dict')
if self.rolling_versions:
self.version = self.get_version(config)
if data_changed or labels_changed or self.force:

@sashajenner
Copy link
Contributor Author

I think I've added an idempotency check now. It seems to work in testing. That is, when everything is the same but template_driver is modified, ansible says the task has changed.

However, I'm not confident in my solution. In particular, I'm not sure if I need to do a check as in

if attrs.get('Labels', {}).get('ansible_key'):
for template_driver as well.

attrs = config.get('Spec', {})
if attrs.get('Labels', {}).get('ansible_key'):
if attrs['Labels']['ansible_key'] != self.data_key:
data_changed = True
else:
if not self.force:
self.client.module.warn("'ansible_key' label not found. Config will not be changed unless the force parameter is set to 'yes'")
if attrs['Labels']['template_driver'] != self.template_driver:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should likely be something like:

Suggested change
if attrs['Labels']['template_driver'] != self.template_driver:
if attrs.get(...) != self.template_driver:

Unfortunately the API docs (https://docs.docker.com/engine/api/v1.41/#operation/ConfigInspect) do not give any hint how and where that information is available. Can you paste the output of something like docker config inspect ... for such a config?

In any case, this is one more reason why there should be tests for this in CI :)

Copy link
Contributor Author

@sashajenner sashajenner May 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this docker config task

- name: debug
  community.docker.docker_config:
    name: db_password
    data: opensesame!
    state: present
    template_driver: golang

the output of docker config inspect ... looks like this

[root@447f901529a4 /]# docker config inspect db_password
[
    {
        "ID": "ilwv23ojrt2ooisz06enkmovj",
        "Version": {
            "Index": 28681
        },
        "CreatedAt": "2022-05-11T01:45:58.5768652Z",
        "UpdatedAt": "2022-05-11T01:45:58.5768652Z",
        "Spec": {
            "Name": "db_password",
            "Labels": {
                "ansible_key": "4c8ed891d2bcad5bd4359a985e82349ec42e0c04be5511b0e53ac258"
            },
            "Data": "b3BlbnNlc2FtZSE=",
            "Templating": {
                "Name": "golang"
            }
        }
    }
]

Hence, I now access the attrs['Templating']['Name'] to get a config's template_driver. I have done some local testing and it seems to work. I will now work on adding integration tests.

@codecov
Copy link

codecov bot commented May 10, 2022

Codecov Report

Merging #345 (98b2270) into main (51d4c55) will decrease coverage by 0.02%.
The diff coverage is 100.00%.

❗ Current head 98b2270 differs from pull request most recent head 8cad235. Consider uploading reports for the commit 8cad235 to get more accurate results

@@            Coverage Diff             @@
##             main     #345      +/-   ##
==========================================
- Coverage   73.23%   73.21%   -0.03%     
==========================================
  Files          59       59              
  Lines        8167     8168       +1     
  Branches     1885     1885              
==========================================
- Hits         5981     5980       -1     
- Misses       1683     1685       +2     
  Partials      503      503              
Flag Coverage Δ
integration 72.86% <100.00%> (-0.06%) ⬇️
sanity 17.03% <0.00%> (-0.01%) ⬇️
stub 0.00% <0.00%> (ø)
units 27.58% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
plugins/modules/docker_swarm.py 81.81% <100.00%> (-0.73%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 51d4c55...8cad235. Read the comment docs.

Copy link
Collaborator

@felixfontein felixfontein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@felixfontein felixfontein merged commit c63ef41 into ansible-collections:main May 11, 2022
@felixfontein
Copy link
Collaborator

@sashajenner thanks for contributing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docker-swarm Docker Swarm enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support --template-driver for docker_config
2 participants