GithubHelp home page GithubHelp logo

f5-ansible-f5os's People

Contributors

urohit011 avatar wojtek0806 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

mvogel91

f5-ansible-f5os's Issues

f5os_lldp_config documentation not clear

Is your feature request related to a problem? Please describe.

The documentation is not clear on how to add multiple interfaces in the configuration. The documentation states it need to be a dictionary but it is unclear which format is expected for multiple interfaces.
The example also has unsupported parameters (max_core_size, exclude_cores) and for interfaces the parameter is enabled and enable.

Describe the solution you'd like

Update the documentation with correct examples and an example showing multiple interfaces.

Describe alternatives you've considered

n/a

Additional context

n/a

Add SNMPv2-MIB module to set sysContact

Is your feature request related to a problem? Please describe.

sysContact MIB entry is not exposed to be set via Ansible

Describe the solution you'd like

For a system onboarding it is required to set the SNMPv2-MIB sysContact, this should be exposed in a module - likely f5os_snmp

Describe alternatives you've considered

Setting via GUI/CLI/native API/URI module for Ansible

Additional context

This feature is required to onboard a major customer onto rSeries.

socket_path must be a value

COMPONENT NAME

f5networks.f5os.f5os_config_backup

Environment

ANSIBLE VERSION
ansible 6.7.0
ansible-core 2.13.13
F5OS VERSION
1.7.0-8741
CONFIGURATION
[defaults]
interpreter_python = /usr/bin/env python
forks = 10
host_key_checking = False
gathering = smart
error_on_undefined_vars = True
callbacks_enabled = timer, profile_roles, profile_tasks
retry_files_enabled = False
timeout = 120
OS / ENVIRONMENT
RHEL 7.9
SUMMARY

I m trying to play with this f5os module to backup and export my host configuration. I had an issue using API call and I saw that it was prefered to used ansible.
https://community.f5.com/discussions/technicalforum/f5os-api-for-downloading-files-not-working-as-expected/315598

So when I run my playbook i have error saying : socket_path must be a value

STEPS TO REPRODUCE
- name: Create backup config and import it to remote server
  vars:
    ansible_host: "{{ f5_backup_host }}"
    ansible_httpapi_password: "{{ f5_backup_password }}"
    ansible_httpapi_port: "8888" #i also tried 443
    ansible_network_os: f5networks.f5_bigip.bigip
    ansible_httpapi_use_ssl: yes
    ansible_httpapi_validate_certs: "{{ f5_backup_validate_certs }}"
  f5networks.f5os.f5os_config_backup:
    name: test_backup.xml
    state: absent
EXPECTED RESULTS

To delete test_backup.xml from f5os host

ACTUAL RESULTS
The full traceback is:
Traceback (most recent call last):
  File "/home/user/.ansible/tmp/ansible-tmp-1717688947.7444158-34053-207442020276603/AnsiballZ_f5os_config_backup.py", line 107, in <module>
    _ansiballz_main()
  File "/home/user/.ansible/tmp/ansible-tmp-1717688947.7444158-34053-207442020276603/AnsiballZ_f5os_config_backup.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/user/.ansible/tmp/ansible-tmp-1717688947.7444158-34053-207442020276603/AnsiballZ_f5os_config_backup.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_config_backup', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_config_backup', _modlib_path=modlib_path),
  File "/opt/rh/rh-python38/root/usr/lib64/python3.8/runpy.py", line 207, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/opt/rh/rh-python38/root/usr/lib64/python3.8/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/opt/rh/rh-python38/root/usr/lib64/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5networks.f5os.f5os_config_backup_payload_vbowxqpd/ansible_f5networks.f5os.f5os_config_backup_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_config_backup.py", line 441, in <module>
  File "/tmp/ansible_f5networks.f5os.f5os_config_backup_payload_vbowxqpd/ansible_f5networks.f5os.f5os_config_backup_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_config_backup.py", line 433, in main
  File "/tmp/ansible_f5networks.f5os.f5os_config_backup_payload_vbowxqpd/ansible_f5networks.f5os.f5os_config_backup_payload.zip/ansible/module_utils/connection.py", line 124, in __init__
AssertionError: socket_path must be a value

f5os_lldp_config fails to set system-name

COMPONENT NAME

f5os_lldp_config

Environment

ANSIBLE VERSION
ansible [core 2.17.1]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
F5OS VERSION
1.5.2-21056
CONFIGURATION
OS / ENVIRONMENT

N/A

SUMMARY

Running f5os_lldp_config requires the system config to already have a system name set in LLDP.
If the name is not set, the module fails. If the system-name pre-exists, the module runs fine.

STEPS TO REPRODUCE

Have a blank F5OS system with LLDP system-name not set.
Run a playbook.

    - name: Set LLDP
      f5os_lldp_config:
        system_name: "{{ inventory_hostname }}"
        enabled: true
EXPECTED RESULTS

Enables LLDP and sets the system name.

ACTUAL RESULTS
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_lldp_config', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_lldp_config', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py", line 726, in <module>
  File "/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py", line 719, in main
  File "/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py", line 450, in exec_module
  File "/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py", line 463, in present
  File "/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py", line 637, in exists
KeyError: 'system-name'
fatal: [10.170.9.37]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-46775i6oqwvh/ansible-tmp-1719219843.769013-4915-218168108677903/AnsiballZ_f5os_lldp_config.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_lldp_config', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_lldp_config', _modlib_path=modlib_path),\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py\", line 726, in <module>\n  File \"/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py\", line 719, in main\n  File \"/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py\", line 450, in exec_module\n  File \"/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py\", line 463, in present\n  File \"/tmp/ansible_f5os_lldp_config_payload_wt_ke_ah/ansible_f5os_lldp_config_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_lldp_config.py\", line 637, in exists\nKeyError: 'system-name'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

f5os_device_info NoneType base_registration_key - f5-system-licensing:licensing restconf response changed?

https://github.com/F5Networks/f5-ansible-f5os/blame/90d2520752c3deef0c3c24eb266347ccdd57af80/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py#L955

This line is giving the following error:
"/tmp/ansible_f5os_device_info_payload_eej88h_x/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 956, in base_registration_key
TypeError: 'NoneType' object is not subscriptable

When running:

    - name: "Collect F5OS facts"
      f5os_device_info:
        gather_subset:
          - all

Against a Base OS Version: 1.5.0-5781.
In this version the registration-key looks to be part of 'state' object and not 'config'

Possible Solution:

    @property
    def base_registration_key(self):
        return self._values['state']['registration-key']['base']
        #return self._values['config']['registration-key']['base']

    @property
    def dossier(self):
        return {}
        #return self._values['config']['dossier']

Same kind of issue happens for 'dossier' looks like the restconf response for url /restconf/data/openconfig-system:system/f5-system-licensing:licensing
Doesn't return 'dossier' anymore?

F5OS module, Task to change default partition password fails

COMPONENT NAME

Environment

ANSIBLE VERSION

F5OS VERSION

CONFIGURATION
OS / ENVIRONMENT
SUMMARY

name: Change Password on Partition
connection: httpapi
hosts: velos-partition[0]
collections:
f5networks.f5os
any_errors_fatal: true
vars:
ansible_user: "admin"
ansible_httpapi_password: "admin" # This is the default password for admin user on a partition
ansible_network_os: "f5networks.f5os.f5os"
ansible_httpapi_use_ssl: true
ansible_httpapi_use_proxy: false
ansible_httpapi_validate_certs: "no"
ansible_httpapi_port: 8888
ansible_command_timeout: 1800
persistent_log_messages: true

tasks:

  • name: pause for 30 seconds
    pause:
    seconds: 30

  • name: Change password on Demo partition
    velos_partition_change_password:
    user_name: "admin"
    old_password: "old_password" # for the very first time this will probably be admin
    new_password: "new_password"
    The above task to change VELOS default parition and password fails.
    Running F5OS_C 1.3.1
    TASK [Change password on Demo partition] *****************************************************************************
    task path: /Users/s.siddharth/test_with_anthony.yaml:66
    redirecting (type: connection) ansible.builtin.httpapi to ansible.netcommon.httpapi
    <10.144.140.123> ESTABLISH LOCAL CONNECTION FOR USER: s.siddharth
    <10.144.140.123> EXEC /bin/sh -c '( umask 77 && mkdir -p "echo /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh"&& mkdir "echo /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471" && echo ansible-tmp-1681852065.169584-76905-51035245995471="echo /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471" ) && sleep 0'
    Using module file /Users/s.siddharth/.ansible/collections/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py
    <10.144.140.123> PUT /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/tmp4lg34du2 TO /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py
    <10.144.140.123> EXEC /bin/sh -c 'chmod u+x /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/ /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py && sleep 0'
    <10.144.140.123> EXEC /bin/sh -c '/usr/local/Cellar/ansible/7.3.0/libexec/bin/python3.11 /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py && sleep 0'
    <10.144.140.123> EXEC /bin/sh -c 'rm -f -r /Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/ > /dev/null 2>&1 && sleep 0'
    The full traceback is:
    Traceback (most recent call last):
    File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 107, in
    ansiballz_main()
    File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 99, in ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
    File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.velos_partition_change_password', init_globals=dict(module_fqn='ansible_collections.f5networks.f5os.plugins.modules.velos_partition_change_password', modlib_path=modlib_path),
    File "", line 226, in run_module
    File "", line 98, in run_module_code
    File "", line 88, in run_code
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 227, in
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 220, in main
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 171, in exec_module
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 183, in execute
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 191, in change_password_on_device
    File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 26, in wrap
    File "/var/folders/9_/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 53, in post
    File "/var/folders/9_/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible/module_utils/connection.py", line 200, in rpc
    ansible.module_utils.connection.ConnectionError: {'ietf-restconf:errors': {'error': [{'error-type': 'application', 'error-tag': 'access-denied', 'error-message': 'access denied'}]}}
    fatal: [velos-partition-1]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 107, in \n ansiballz_main()\n File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 99, in ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File "/Users/s.siddharth/.ansible/tmp/ansible-local-76468r18chvoh/ansible-tmp-1681852065.169584-76905-51035245995471/AnsiballZ_velos_partition_change_password.py", line 47, in invoke_module\n runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.velos_partition_change_password', init_globals=dict(module_fqn='ansible_collections.f5networks.f5os.plugins.modules.velos_partition_change_password', modlib_path=modlib_path),\n File "", line 226, in run_module\n File "", line 98, in run_module_code\n File "", line 88, in run_code\n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 227, in \n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 220, in main\n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 171, in exec_module\n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 183, in execute\n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/velos_partition_change_password.py", line 191, in change_password_on_device\n File "/var/folders/9/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 26, in wrap\n File "/var/folders/9_/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 53, in post\n File "/var/folders/9_/zghqq6sx605cjnm2m35v8k0r0000gp/T/ansible_velos_partition_change_password_payload_hbyzb5ru/ansible_velos_partition_change_password_payload.zip/ansible/module_utils/connection.py", line 200, in rpc\nansible.module_utils.connection.ConnectionError: {'ietf-restconf:errors': {'error': [{'error-type': 'application', 'error-tag': 'access-denied', 'error-message': 'access denied'}]}}\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
    }

EXPECTED RESULTS
ACTUAL RESULTS

Add LAG information to f5os_device_info module

Is your feature request related to a problem? Please describe.

When using the f5os_lag module you have to specify all of the vlans you want assigned, adding a single to existing is not possible and using f5os_device_info doesn't list the existing LAGs vlan information.

Describe the solution you'd like

Under the interfaces subset add the currently configured vlans and possibly other config values like LAG members, type, speed, and so on.

Describe alternatives you've considered

Not using the F5OS module and making direct API calls

Enable SCP/SFTP for f5os_config_backup

Is your feature request related to a problem? Please describe.

Currently, only https transport is supported for exporting the configuration. SCP / SFTP are supported protocols on the API and should be included in the module.

Describe the solution you'd like

Successful configuration backup with file export to SCP / SFTP destination

Describe alternatives you've considered

N/A

Additional context

I was able to get SCP working locally by modifying the module with the following changes:

Add 'protocol': 'protocol', to api_map

api_map = {
'remote-host': 'remote_host',
'remote-port': 'remote_port',
'remote-file': 'remote_path',
'local-file': 'local_path',
'username': 'remote_user',
'password': 'remote_password',
}

Modify choices in ArgumentSpec to choices=['https','scp']

F5OS logging config

Is your feature request related to a problem? Please describe.

F5OS Ansible modules currently don't support configuration of logging settings for the F5OS system.

Describe the solution you'd like

There should be a module to update log settings via Ansible.

Describe alternatives you've considered

Drop out of Ansible and configure through API, CLI or GUI.

Additional context

My customer operates a large landscape of iSeries to be swapped by rSeries. A unified onboarding through Ansible would heavily reduce the efforts

Add SNMP v3 support

Is your feature request related to a problem? Please describe.

f5os_snmp does not allow to configure SNMPv3 users and targets

Describe the solution you'd like

f5os_snmp should allow to configure SNMPv3 users and targets

Describe alternatives you've considered

Configuration needs to happen via UI/CLI/native API/Ansible URI module

Additional context

This feature is required to onboard a major customer onto rSeries

Issue on login

COMPONENT NAME

f5networks.f5os.f5os_device_info

Environment

ansible_user: "{{ ansible_user }}"
ansible_httpapi_password: "{{ ansible_password }}"
ansible_network_os: f5networks.f5os.f5os
ansible_httpapi_use_ssl: true
ansible_httpapi_use_proxy: false
ansible_httpapi_validate_certs: false
ansible_httpapi_port: 8888
ansible_command_timeout: 1800
persistent_log_messages: true

ANSIBLE VERSION
ansible [core 2.13.6]
  config file = /spimi/NetDevOps/f5_utils/ansible/backup_f5/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.4 (default, Apr 14 2021, 10:57:48) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
  jinja version = 3.1.2
  libyaml = True
F5OS VERSION
1.3.2-13054
CONFIGURATION
OS / ENVIRONMENT

N/A

SUMMARY

When we try to connect to F5OS device goes in error

STEPS TO REPRODUCE
- name: Backup F5
  hosts: f5os
  connection: httpapi
  collections:
    - f5networks.f5os
  tasks:
    - name: Collect device information
      f5networks.f5os.f5os_device_info:
        gather_subset:
          - system-info
      environment:
        http_proxy: ""
        https_proxy: ""
EXPECTED RESULTS

Gathering data from F5

ACTUAL RESULTS
<IP> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', _modlib_path=modlib_path),
  File "/usr/local/lib/python3.9/runpy.py", line 210, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/local/lib/python3.9/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/local/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1523, in <module>
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1509, in main
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1408, in exec_module
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1442, in execute_managers
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1249, in exec_module
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1254, in _exec_module
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1282, in read_facts
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1312, in _read_component_facts
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1324, in read_components_from_device
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 26, in wrap
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 45, in get
  File "/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible/module_utils/connection.py", line 200, in __rpc__
ansible.module_utils.connection.ConnectionError: {'ietf-restconf:errors': {'error': [{'error-type': 'application', 'error-tag': 'invalid-value', 'error-message': 'uri keypath not found'}]}}
fatal: [device]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-10821gfx97vwk/ansible-tmp-1702399767.5647864-10870-152555949862923/AnsiballZ_f5os_device_info.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', _modlib_path=modlib_path),\n  File \"/usr/local/lib/python3.9/runpy.py\", line 210, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/local/lib/python3.9/runpy.py\", line 97, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/local/lib/python3.9/runpy.py\", line 87, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1523, in <module>\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1509, in main\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1408, in exec_module\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1442, in execute_managers\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1249, in exec_module\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1254, in _exec_module\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1282, in read_facts\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1312, in _read_component_facts\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1324, in read_components_from_device\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py\", line 26, in wrap\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py\", line 45, in get\n  File \"/tmp/ansible_f5networks.f5os.f5os_device_info_payload_rntd_kmr/ansible_f5networks.f5os.f5os_device_info_payload.zip/ansible/module_utils/connection.py\", line 200, in __rpc__\nansible.module_utils.connection.ConnectionError: {'ietf-restconf:errors': {'error': [{'error-type': 'application', 'error-tag': 'invalid-value', 'error-message': 'uri keypath not found'}]}}\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

F5OS remote system authentication

Is your feature request related to a problem? Please describe.

F5OS Ansible modules currently don't support configuration of remote authentication as in configuring the various authentication providers.

Describe the solution you'd like

If configuration would be split per protocol, RADIUS would be my highest priority, however the future state should allow to configure any remote authentication protocol.
The modules should also allow to define remote role assignment.

Describe alternatives you've considered

Drop out of Ansible and configure these through API, CLI or GUI.

Additional context

My customer operates a large landscape of iSeries to be swapped by rSeries. A unified onboarding through Ansible would heavily reduce the efforts

re-running f5os_ntp_server.py requires key-id to be set

COMPONENT NAME

f5os_ntp_server.py

Environment

ANSIBLE VERSION
# ansible --version
ansible [core 2.17.1]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
F5OS VERSION
1.5.2-21056
CONFIGURATION
OS / ENVIRONMENT

N/A

SUMMARY
STEPS TO REPRODUCE

Create NTP servers with address only.
Re-running the same playbook fails for missing key-id.

    - name: Create NTP servers
      f5os_ntp_server:
        server: "{{ item.address }}"
      with_items: "{{ env.ntp }}"
EXPECTED RESULTS

The object being identified as unchanged/ok.

ACTUAL RESULTS
TASK [Create NTP servers] ******************************************************************************************************************************************************************************************************
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 147, in compare
AttributeError: 'Difference' object has no attribute 'key_id'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_ntp_server', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_ntp_server', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 370, in <module>
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 363, in main
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 213, in exec_module
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 227, in present
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 244, in update
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 237, in should_update
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 185, in _update_changed_options
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 150, in compare
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 155, in __default
  File "/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py", line 113, in key_id
KeyError: 'f5-openconfig-system-ntp:key-id'
failed: [10.170.9.37] (item={'address': '1.2.3.4'}) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": {
        "address": "1.2.3.4"
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 147, in compare\nAttributeError: 'Difference' object has no attribute 'key_id'\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-34727a_1o4bn/ansible-tmp-1719218724.5681655-3710-170074854231225/AnsiballZ_f5os_ntp_server.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_ntp_server', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_ntp_server', _modlib_path=modlib_path),\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 370, in <module>\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 363, in main\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 213, in exec_module\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 227, in present\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 244, in update\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 237, in should_update\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 185, in _update_changed_options\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 150, in compare\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 155, in __default\n  File \"/tmp/ansible_f5os_ntp_server_payload_cn4q4x4k/ansible_f5os_ntp_server_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_ntp_server.py\", line 113, in key_id\nKeyError: 'f5-openconfig-system-ntp:key-id'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

Multiple issues in f5os_snmp

COMPONENT NAME

f5os_snmp

Environment

ANSIBLE VERSION
# ansible --version
ansible [core 2.17.1]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.4
  libyaml = True
F5OS VERSION
1.5.2-21056
CONFIGURATION
OS / ENVIRONMENT

N/A

SUMMARY
  1. v2c communities are not idempotent
  2. Targets can't be configured independently of communities in separate tasks
STEPS TO REPRODUCE
  1. Create SNMP v2c Community, rerun playbook
  tasks:
    - name: Create SNMP communities
      f5networks.f5os.f5os_snmp:
        snmp_community:
          - name: "{{ item.community.name }}"
            security_model: "{{ item.community.versions }}"
        snmp_target:
          - name: "{{ item.name }}"
            security_model: "{{ item.version }}"
            ipv4_address: "{{ item.ipv4_address }}"
            port: "{{ item.port }}"
            community: "{{ item.community.name }}"
      with_items: "{{ snmp.targets }}"
  1. Have 2 separate tasks for community and target
  tasks:
    - name: Create SNMP communities
      f5os_snmp:
        snmp_community:
          - name: "{{ item.name }}"
            security_model: "{{ item.version }}"
      with_items: "{{ snmp.communities }}"
      when: snmp is defined and snmp.communities is defined

    - name: Create SNMP targets
      f5os_snmp:
        snmp_target:
          - name: "{{ item.name }}"
            security_model: "{{ item.version }}"
            ipv4_address: "{{ item.ipv4_address }}"
            port: "{{ item.port }}"
            community: "{{ item.community }}"
      with_items: "{{ snmp.targets }}"
      when: snmp is defined and snmp.targets is defined
EXPECTED RESULTS
  1. Repeatedly pasting the same declaration for v2c communities results to ok/unchanged.
  2. Target hosts can be configured independently of communities
ACTUAL RESULTS
  1. Module fails with "TypeError: string indices must be integers"
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 565, in <module>
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 558, in main
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 350, in exec_module
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 364, in present
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 385, in update
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 461, in update_on_device
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/common.py", line 141, in api_params
  File "/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 228, in snmp_community
TypeError: string indices must be integers
failed: [10.170.9.37] (item={'name': 'target1', 'version': 'v2c', 'ipv4_address': '192.0.2.5', 'port': 1234, 'community': {'name': 'community1', 'versions': ['v2c']}}) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": {
        "community": {
            "name": "community1",
            "versions": [
                "v2c"
            ]
        },
        "ipv4_address": "192.0.2.5",
        "name": "target1",
        "port": 1234,
        "version": "v2c"
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-5213vva558b8/ansible-tmp-1719304746.3832297-5310-280915669646745/AnsiballZ_f5os_snmp.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', _modlib_path=modlib_path),\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 565, in <module>\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 558, in main\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 350, in exec_module\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 364, in present\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 385, in update\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 461, in update_on_device\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/common.py\", line 141, in api_params\n  File \"/tmp/ansible_f5networks.f5os.f5os_snmp_payload_u3i55mmt/ansible_f5networks.f5os.f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 228, in snmp_community\nTypeError: string indices must be integers\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}
  1. Module fails for "TypeError: 'NoneType' object is not iterable"
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 565, in <module>
  File "/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 558, in main
  File "/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 350, in exec_module
  File "/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 363, in present
  File "/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py", line 404, in exists
TypeError: 'NoneType' object is not iterable
failed: [10.170.9.37] (item={'name': 'target1', 'version': 'v1', 'ipv4_address': '192.0.2.5', 'port': 1234, 'community': {'name': 'community1', 'versions': ['v1']}}) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": {
        "community": {
            "name": "community1",
            "versions": [
                "v1"
            ]
        },
        "ipv4_address": "192.0.2.5",
        "name": "target1",
        "port": 1234,
        "version": "v1"
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-5090167lsjl6/ansible-tmp-1719304476.314065-5188-166467802791312/AnsiballZ_f5os_snmp.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_snmp', _modlib_path=modlib_path),\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 565, in <module>\n  File \"/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 558, in main\n  File \"/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 350, in exec_module\n  File \"/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 363, in present\n  File \"/tmp/ansible_f5os_snmp_payload_785p57gn/ansible_f5os_snmp_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_snmp.py\", line 404, in exists\nTypeError: 'NoneType' object is not iterable\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

Sending telemetry errors with f5os_device_info

COMPONENT NAME

f5os_device_info

Environment

ANSIBLE VERSION
2.13.5
F5OS VERSION
1.3.1
CONFIGURATION
OS / ENVIRONMENT

N/A

SUMMARY

In certain conditions when running f5os_device_info the F5Client class has no client kwarg and the module run fails with AttributeError

Should handle variable better on line 74, for example:

if client.plugin is not None and client.plugin.telemetry():
STEPS TO REPRODUCE
- hosts: all
  collections:
    - f5networks.f5os
  connection: httpapi
  vars:
    ansible_host: "lb.mydomain.com"
    ansible_user: "admin"
    ansible_httpapi_password: "secret"
    ansible_network_os: f5networks.f5os.f5os
    ansible_httpapi_use_ssl: yes
  tasks:
    - name: Collect all F5OS device information
      f5os_device_info:
        gather_subset:
          - all
EXPECTED RESULTS
ACTUAL RESULTS
TASK [Collect all F5OS device information] *********************************************************************************************************************************************************************************************************************
task path: *REDACTED*/f5os-info.yaml:21
redirecting (type: connection) ansible.builtin.httpapi to ansible.netcommon.httpapi
Loading collection ansible.netcommon from /var/opt/ansible/collections/ansible_collections/ansible/netcommon
<*REDACTED*> attempting to start connection
<*REDACTED*> using connection plugin ansible.netcommon.httpapi
Found ansible-connection at path /var/opt/ansible/venv/bin/ansible-connection
<*REDACTED*> found existing local domain socket, using it!
<*REDACTED*> updating play_context for connection
<*REDACTED*>
<*REDACTED*> local domain socket path is /root/.ansible/pc/a09fe927ba
<*REDACTED*> ESTABLISH LOCAL CONNECTION FOR USER: root
<*REDACTED*> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-4169668_lubgppz `"&& mkdir "` echo /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636 `" && echo ansible-tmp-1672334102.0005035-4169772-111621317794636="` echo /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636 `" ) && sleep 0'
Using module file /var/opt/ansible/collections/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py
<*REDACTED*> PUT /root/.ansible/tmp/ansible-local-4169668_lubgppz/tmpii7bl60d TO /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py
<*REDACTED*> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/ /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py && sleep 0'
<*REDACTED*> EXEC /bin/sh -c '/var/opt/ansible/venv/bin/python /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py && sleep 0'
<*REDACTED*> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 209, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1319, in <module>
  File "/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1305, in main
  File "/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py", line 1211, in exec_module
  File "/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py", line 74, in send_teem
AttributeError: 'NoneType' object has no attribute 'telemetry'
fatal: [m1e-pgc-lbhv-d01]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-local-4169668_lubgppz/ansible-tmp-1672334102.0005035-4169772-111621317794636/AnsiballZ_f5os_device_info.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', init_globals=dict(_module_fqn='ansible_collections.f5networks.f5os.plugins.modules.f5os_device_info', _modlib_path=modlib_path),\n  File \"/usr/lib/python3.10/runpy.py\", line 209, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1319, in <module>\n  File \"/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1305, in main\n  File \"/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/modules/f5os_device_info.py\", line 1211, in exec_module\n  File \"/tmp/ansible_f5os_device_info_payload_z_bkbvhx/ansible_f5os_device_info_payload.zip/ansible_collections/f5networks/f5os/plugins/module_utils/client.py\", line 74, in send_teem\nAttributeError: 'NoneType' object has no attribute 'telemetry'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.