arensb / ansible-truenas Goto Github PK
View Code? Open in Web Editor NEWAnsible collection to manage TrueNAS
License: Apache License 2.0
Ansible collection to manage TrueNAS
License: Apache License 2.0
Invoking the module with invalid or not nonexistent pool name will cause the module to run into a syntax error and fail to report the underlying problem:
Traceback (most recent call last):
File "/tmp/ansible_arensb.truenas.pool_scrub_task_payload_qbsery8n/ansible_arensb.truenas.pool_scrub_task_payload.zip/ansible_collections/arensb/truenas/plugins/modules/pool_scrub_task.py", line 186, in main
AttributeError: 'AnsibleModule' object has no attribute 'json_fail'
During handling of the above exception, another exception occurred:
...
There is no attribute called json_fail
, the correct name is fail_json
.
We run TrueNAS-SCALE-22.12.2 and use ansible-truenas 1.4.4
To manage user works, until I try to manage sudo per user.
The yaml API on ansible-truenas site don't match what trusnas is doing.
ansible-truenas:
sudo enable bool
sudo_nopassword bool
sudo_commands array of commands
TrueNAS-SCALE-22.12.2 midcli
sudo_commands array of commands with password
sudo_commands_nopasswd array of commands with no password needed
How we would get this working?
a)Translate from ansible-truenas api to TrueNAS-SCALE api
b) change ansible-truenas api to TrueNAS-SCALE api
I can not get the right names for the iscsi and smb services. I managed to get the others:
However none of my ideas for smb or iscsi have worked:
I am using Truenas Scale 23.10.1.3
Due to the current limitations of the filesystem module, you can't set the ownership of a dataset to any non-root user.
This limitation means that if you want any NFS user to interact with the share as if they own it, you need to set 'mapall_user' to root on the NFS share. This has downsides in that we don't always want users of our nfs shares to be masquerading as root.
I've achieved this in the short term by using ansible.builtin.file
post-step, but it would be best to do this when the filesystem is created:
ansible.builtin.file:
path: /mnt/pool0/dataset
state: directory
recurse: yes
owner: myuser
group: mygroup
I can try and look into this myself when I have spare time, but my python skills are rusty.
Ran into the below issue when trying to create a password_disabled user on my Truenas box with smb shares.
It seems by default truenas creates users with smb enabled for user ease.
Reading through the source code for this module, it seems like we just need to add support for this by passing an smb value into the API request.
fatal: [192.168.1.100]: FAILED! => {"changed": false, "msg": "Error creating user dockyard: midclt exited with status 1: \"b'[EINVAL] user_create.password_disabled: Password authentication may not be disabled for SMB users.\\n'\""}
Currently working on a fix for this as I can see through the source code how this can be resolved.
The example code for configuring nfsv4 is throwing an error on TrueNAS Scale 23.10.2
- name: Enable NFSv4
arensb.truenas.nfs:
nfsv4: yes
Error
"module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1709435723.4626808-793846-169862083948011/AnsiballZ_nfs.py\", line 107, in <module>\r\n _ansiballz_main()\r\n File \"/root/.ansible/tmp/ansible-tmp-1709435723.4626808-793846-169862083948011/AnsiballZ_nfs.py\", line 99, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File \"/root/.ansible/tmp/ansible-tmp-1709435723.4626808-793846-169862083948011/AnsiballZ_nfs.py\", line 47, in invoke_module\r\n runpy.run_module(mod_name='ansible_collections.arensb.truenas.plugins.modules.nfs', init_globals=dict(_module_fqn='ansible_collections.arensb.truenas.plugins.modules.nfs', _modlib_path=modlib_path),\r\n File \"<frozen runpy>\", line 226, in run_module\r\n File \"<frozen runpy>\", line 98, in _run_module_code\r\n File \"<frozen runpy>\", line 88, in _run_code\r\n File \"/tmp/ansible_arensb.truenas.nfs_payload_c0ot8r0s/ansible_arensb.truenas.nfs_payload.zip/ansible_collections/arensb/truenas/plugins/modules/nfs.py\", line 112, in <module>\r\n File \"/tmp/ansible_arensb.truenas.nfs_payload_c0ot8r0s/ansible_arensb.truenas.nfs_payload.zip/ansible_collections/arensb/truenas/plugins/modules/nfs.py\", line 84, in main\r\nKeyError: 'v4'\r\n",
I'd like to add the ability to manage ssh host keys (e.g., ssh_host_rsa_key
and ssh_host_rsa_key.pub
) and especially host key certificates (e.g., ssh_host_rsa_key-cert.pub
), but I can't find the place in the web console to do so, nor have I found the documentation on how to do so.
The ssh.config
middleware call returns these keys and certs, but I don't know the best way to update them. By RTFSing, I've found a number of datastore
calls that can probably do the trick, but since I can't find documentation for this, I suspect this is not the recommended way of doing it.
the nfs module currently supports nfsv4
which sets v4
to a bool, but doesn't allow other parameters to be set
Would it be possible to add v4_v3owner
(also a bool) to that module such that it can be changed through ansible?
PS: I'm only interested in this v4_v3owner
, but other people may want to configure the other params as well
setup:
for some reason, it doesn't seem to start services I have defined
this is my roles/truenas/tasks/main.yml that I'm using
---
- name: Create an ordinary user and their group
arensb.truenas.user:
name: testuser
create_group: true
sudo_commands: ALL
password: "testpwd"
- name: Configure NFS exports
arensb.truenas.sharing_nfs:
enabled: true
name: media nfs share
path: /mnt/tank/data/media
maproot_user: testuser
maproot_group: testuser
- name: Enable NFSv4
arensb.truenas.nfs:
nfsv4: true
- name: Enable services
arensb.truenas.service:
name: "{{ item }}"
enabled: true
state: started
with_items:
- ssh
- nfs
The last step is to enable ssh and nfs. SSH is already started which allows ansible to run, but it doesn't enable it. Also it doesn't seem to enable and start the nfs service.
Running ansible-playbook -vvv playbooks/truenas.yml
gives me
<[email protected]> ESTABLISH SSH CONNECTION FOR USER: None
<[email protected]> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/paulo/.ansible/cp/e04ab7b04b"' [email protected] '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1691781720.9827127-9421-115081788509640/ /root/.ansible/tmp/ansible-tmp-1691781720.9827127-9421-115081788509640/AnsiballZ_service.py && sleep 0'"'"''
<[email protected]> (0, b'', b'')
<[email protected]> ESTABLISH SSH CONNECTION FOR USER: None
<[email protected]> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/paulo/.ansible/cp/e04ab7b04b"' -tt [email protected] '/bin/sh -c '"'"'/usr/local/bin/python3.9 /root/.ansible/tmp/ansible-tmp-1691781720.9827127-9421-115081788509640/AnsiballZ_service.py && sleep 0'"'"''
<[email protected]> (0, b'\r\n{"changed": false, "msg": "", "service_id": 11, "name": "ssh", "enabled": false, "state": "RUNNING", "pids": [1540], "invocation": {"module_args": {"name": "ssh", "enabled": true, "state": "started", "ha_propagate": null}}}\r\n', b'Shared connection to 192.168.122.100 closed.\r\n')
[email protected]> ESTABLISH SSH CONNECTION FOR USER: None
<[email protected]> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/paulo/.ansible/cp/e04ab7b04b"' [email protected] '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1691781720.9827127-9421-115081788509640/ > /dev/null 2>&1 && sleep 0'"'"''
<[email protected]> (0, b'', b'')
ok: [[email protected]] => (item=ssh) => {
"ansible_loop_var": "item",
"changed": false,
"enabled": false,
"invocation": {
"module_args": {
"enabled": true,
"ha_propagate": null,
"name": "ssh",
"state": "started"
}
},
"item": "ssh",
"msg": "",
"name": "ssh",
"pids": [
1540
],
"service_id": 11,
"state": "RUNNING"
}
...
...
<[email protected]> ESTABLISH SSH CONNECTION FOR USER: None
<[email protected]> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/paulo/.ansible/cp/e04ab7b04b"' -tt [email protected] '/bin/sh -c '"'"'/usr/local/bin/python3.9 /root/.ansible/tmp/ansible-tmp-1691781721.2552562-9421-21221030135877/AnsiballZ_service.py && sleep 0'"'"''
<[email protected]> (0, b'\r\n{"changed": false, "msg": "", "service_id": 9, "name": "nfs", "enabled": false, "state": "STOPPED", "pids": [], "invocation": {"module_args": {"name": "nfs", "enabled": true, "state": "started", "ha_propagate": null}}}\r\n', b'Shared connection to 192.168.122.100 closed.\r\n')
<[email protected]> ESTABLISH SSH CONNECTION FOR USER: None
<[email protected]> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o 'ControlPath="/home/paulo/.ansible/cp/e04ab7b04b"' [email protected] '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1691781721.2552562-9421-21221030135877/ > /dev/null 2>&1 && sleep 0'"'"''
<[email protected]> (0, b'', b'')
ok: [[email protected]] => (item=nfs) => {
"ansible_loop_var": "item",
"changed": false,
"enabled": false,
"invocation": {
"module_args": {
"enabled": true,
"ha_propagate": null,
"name": "nfs",
"state": "started"
}
},
"item": "nfs",
"msg": "",
"name": "nfs",
"pids": [],
"service_id": 9,
"state": "STOPPED"
}
Notice that ansible doesn't return errors, but returns state: STOPPED when it shouldn't
Example would be to export my MP3 directory ro to media players but rw to my desktop
- name: RO export for media players
arensb.truenas.sharing_nfs:
- name: MP3 ro export
path: /mnt/pool0/MP3
readonly: false
hosts:
- 192.168.1.8
- 192.168.1.9
- name: RW Export for my desktop
arensb.truenas.sharing_nfs:
- name: MP3 rw export
readonly: true
path: /mnt/pool0/MP3
hosts:
- 192.168.1.2
Only the second share will be created when you check the GUI on TrueNAS Scale.
Look like you're using "path" as the unique identified when it is possible to have mutiple exports with the same path.
Looks like an error in plugins/modules/sharing_nfs.py
Existing code
if readonly is not None and export_info['readonly'] != readonly:
arg['ro'] = readonly
Corrected code
if readonly is not None and export_info['ro'] != readonly:
arg['ro'] = readonly
Reference
smb defaults to true which conflicts with password_disabled. Ideally using password_disabled should require the smb parameter so that so we have to explicitly disable the value.
At present, there's no test suite, no CI/CD pipeline, no regression testing. If someone who knows more about CI/CD and testing than I do could add a test suite, with examples of how to add new tests, that would allow contributors to at least do some basic testing before trying code out on a live installation.
Hi @arensb thanks for sharing this ansible collection :)
I'd wondering if these things could be implemented
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.