Thanks to visit codestin.com
Credit goes to github.com

Skip to content

aix_chsec module#49057

Closed
flynn1973 wants to merge 20 commits intoansible:develfrom
flynn1973:aix_chsec_added
Closed

aix_chsec module#49057
flynn1973 wants to merge 20 commits intoansible:develfrom
flynn1973:aix_chsec_added

Conversation

@flynn1973
Copy link

@flynn1973 flynn1973 commented Nov 23, 2018

SUMMARY

adds stanzas to aix config files using the chsec command.

ISSUE TYPE
  • New Module Pull Request
COMPONENT NAME

aix_chsec

ADDITIONAL INFORMATION

example plays:

- name: add ldap user stanza
  aix_chsec:
    path: /etc/security/user
    stanza: ldapuser
    options: SYSTEM=LDAP,registry=LDAP
    state: present
    mode: 0644

- name: change login times for user
  aix_chsec:
    path: /etc/security/user
    stanza: ldapuser
    options: logintimes=:0800-1700
    state: present

- name: remove registry option from stanza
  aix_chsec:
    path: /etc/security/user
    stanza: ldapuser
    options: SYSTEM=LDAP,registry=
    state: present

@ansibot
Copy link
Contributor

ansibot commented Nov 23, 2018

Hi @flynn1973, thank you for submitting this pull-request!

click here for bot help

@ansibot ansibot added affects_2.8 This issue/PR affects Ansible v2.8 community_review In order to be merged, this PR must follow the community review workflow. module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. new_contributor This PR is the first contribution by a new community member. new_module This PR includes a new module. new_plugin This PR includes a new plugin. support:community This issue/PR relates to code supported by the Ansible community. labels Nov 23, 2018
@ansibot

This comment has been minimized.

@ansibot ansibot added needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed community_review In order to be merged, this PR must follow the community review workflow. labels Nov 23, 2018
@flynn1973 flynn1973 closed this Nov 23, 2018
@flynn1973 flynn1973 reopened this Nov 23, 2018
@ansibot

This comment has been minimized.

@samdoran samdoran added the ci_verified Changes made in this PR are causing tests to fail. label Nov 27, 2018
@ansibot ansibot added the stale_ci This PR has been tested by CI more than one week ago. Close and re-open this PR to get it retested. label Dec 5, 2018
@dagwieers dagwieers added aix AIX community and removed aix AIX community labels Jan 8, 2019
Copy link
Contributor

@dagwieers dagwieers left a comment

Choose a reason for hiding this comment

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

LGTM, some cosmetic changes and an important fix to documentation.

options=dict(type='list', required=True),
state=dict(type='str', default='present', choices=['absent', 'present'])
),
supports_check_mode=False,
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if this module supported check-mode.

@dagwieers
Copy link
Contributor

dagwieers commented Jan 8, 2019

A few ideas to improve this module:

  • Add check-mode support
  • Make the module idempotent
  • Add a seealso: section pointing to official man chsec documentation or online docs
  • Add integration tests so future changes can be tested for correctness

@ansibot

This comment has been minimized.

@ansibot
Copy link
Contributor

ansibot commented Jan 9, 2019

@ansibot ansibot added test This PR relates to tests. and removed needs_triage Needs a first human triage before being processed. stale_ci This PR has been tested by CI more than one week ago. Close and re-open this PR to get it retested. labels Jan 9, 2019
@dagwieers
Copy link
Contributor

dagwieers commented Jan 9, 2019

@flynn1973 There is still a long list of issues to resolve before we can even start considering this module.

@ansibot ansibot removed the ci_verified Changes made in this PR are causing tests to fail. label Jan 9, 2019
@dagwieers
Copy link
Contributor

@flynn1973 I fixed all the open issues from CI. But we need to work on:

  • idempotency (not making changes when they are not needed)
  • check-mode support (act as if you're making a change without making the change)
  • integration tests (playbooks that use the module for making changes and testing if it behaves as expected)

@flynn1973
Copy link
Author

@dagwieers
ad idempotency: i am not aware of any option to the chsec command which allows pre checks. it is a fire and forget thing. same goes for the check mode support.

ad integration tests: i use this module on a daily basis and it works smoothly.

@molekuul
Copy link
Contributor

@dagwieers
ad idempotency: i am not aware of any option to the chsec command which allows pre checks. it is a fire and forget thing. same goes for the check mode support.

@flynn1973 there is also a command lssec. It lists attributes in the security stanza files.
You first check the value of each of the parameters in the stanza by the lssec command, and than change only those. which are different.

@ansibot
Copy link
Contributor

ansibot commented Jan 19, 2019

cc @bcoca
click here for bot help

@ansibot ansibot added stale_ci This PR has been tested by CI more than one week ago. Close and re-open this PR to get it retested. stale_review Updates were made after the last review and the last review is more than 7 days old. labels Jan 19, 2019
path: /etc/security/user
stanza: ldapuser
options:
- SYSTEM=LDAP
Copy link
Contributor

Choose a reason for hiding this comment

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

To me it seems more logical if the format is not a list, but a dictionary.

      options:
        SYSTEM: LDAP
        registry: LDAP
        logintimes: :0800-1700

The only reasons for using a list here, would be to ensure a specific order for processing, or to ensure that a specific key can be duplicate (so provided keys are not unique). But I don't think these are no applicable here.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you are worried about breaking backward compatibility with existing users, you can use type: raw and test if a string, a list or a dict was provided, and handle strings as key=val, use dicts as an iterable key: value store, and a list could contain either of those two.

And then only document/showcase the dicts syntax, and provide a deprecation message for people using a list or a string. Which could then be removed after 4 major releases (which is what we typically do).

module.fail_json(msg='Failed to run chsec command (present).', rc=rc, stdout=stdout, stderr=stderr)
else:
msg = 'stanza added'
changed = True
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no guarantee something was changed here. So this would mean the module can only either fail or report changes.

yield element

command = [chsec_command, '-f', filename, '-s', '%s' % stanza]
options = list(arguments_generator(options))
Copy link
Contributor

Choose a reason for hiding this comment

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

It's probably better to loop over the items and check the value before changing, so you can report back if there was a change or not.

@ansibot ansibot removed the stale_review Updates were made after the last review and the last review is more than 7 days old. label Jan 19, 2019
@ansibot
Copy link
Contributor

ansibot commented Jan 27, 2019

@dagwieers dagwieers removed the test This PR relates to tests. label Feb 4, 2019
@ansibot
Copy link
Contributor

ansibot commented Feb 4, 2019

@ansibot ansibot added the system System category label Feb 20, 2019
@ansibot
Copy link
Contributor

ansibot commented Jul 14, 2019

@d-little
Copy link
Contributor

I've written a proposal below for what I think the behaviour of the aix_chsec module should have, with a few open design questions. I'd like aix_chsec to be in 2.9, so am looking for responses!

SUMMARY

Below is a IBM AIX chsec module design proposal.

I've been trying to write a role to 'easily' wrap up the IBM AIX chsec command and make it idempotent. While I've got it (mostly) working here, I'd rather help to make a module to perform this work instead of maintaining such a clunky role.

COMPONENT NAME

aix_chsec

Idempotency

We can make the tool idempotent by first checking the output of lssec before making changes. It should be trivial to use this command in Python.

I'm achieving this in the ansible-role-aix-chsec using something similar to:

shell: >
  ( lssec -f '{{ file }}' -s '{{ stanza }}' -a '{{ key }}' | grep -q '{{ stanza }} {{ key }}={{ value }}' ) && echo nochange || chsec -f '{{ file }}' -s '{{ stanza }}' -a '{{ key }}={{ value }}'
Scope

This module could be part of a larger module to manage many types of AIX settings (aix_settings ?), or simply focus on the chsec command itself. For now we can focus on aix_chsec.

Potential Layout(s)
'Simple'

One example implementation with multiple key/value being set within a single files+stanza at a time:

- name: Name of Task
  aix_chsec:
    file: filename
    stanza: stanzaname
    attributes:
      key1: value1
      key2: value2
      keyN: valueN
    state: [ present, absent ]
    backup: bool (default no, timestamped backup before making changes.)

This would return Changed if any number of the above key/value pairs were changed. If none were changed it would be OK. Failure to change any key:value pair would consitute as a failure regardless of how many attributes were successfully set. In order to check for failure we need to re-check the lssec command after chsec is run; chsec will often return 0 even if nothing changed.

  • attributes can have an alias attrs
  • Attributes alternatives:
    • attributes: [ (key, value), (key, value), (key, value) ]
    • attributes: [ key: value, key2: value2 ]

Real world use:

  • Allow logins from 8:00 a.m. until 5:00 p.m. for all users
  • Change the CPU time limit of user joe AND chrlie to 1 hour (3600 seconds):
---
- hosts: targetserver
  gather_facts: no
  vars:
    example_chsec:
      - file: /etc/security/user
        stanza: default
        attrs:
          logintimes: ":0800-1700"
      - file: /etc/security/limits
        stanza: joe
        attrs: [ cpu: 3600 ]
      - file: /etc/security/limits
        stanza: charlie
        attrs:
          cpu: 3600
  remote_user: deploy
- tasks:
  name: Example chsec
    aix_chsec:
      file: "{{ item.file }}"
      stanza: "{{ item.stanza }}"
      attrs: "{{ item.attrs }}"
    loop:
      - "{{ example_chsec }}"

The example_chsec YAML above converts to the following JSON:

{
  "example_chsec": [
    {
      "file": "/etc/security/user",
      "stanza": "default",
      "attrs": {
        "logintimes": ":0800-1700"
      }
    },
    {
      "file": "/etc/security/limits",
      "stanza": "joe",
      "attrs": {
        "cpu": 3600
      }
    },
    {
      "file": "/etc/security/limits",
      "stanza": "charlie",
      "attrs": {
        "cpu": 3600,
        "file": -1
      }
    }
  ]
}
'Nested' Stanzas

We could 'nest' stanzas for a single file within a single module call. This makes configuration slightly more complicated, but can potentially reduce the amount of required tasks/YAML code. We can keep the stanza option available in addition to stanzas, mutually exclusive.

- name: Name of Task
  aix_chsec:
    file: filename
    stanzas:
      - stanza1:
          key1: value1
          key2: value2
          keyN: valueN
        state: [ present|absent ]
      - stanza2:
          key1: value1
          key2: value2
          keyN: valueN
        state: [ present|absent ]
    backup: bool (default no, timestamped backup before making changes.)

Real world use:

  • Allow logins from 8:00 a.m. until 5:00 p.m. for all users
  • Change the CPU time limit of user joe AND chrlie to 1 hour (3600 seconds):
---
- hosts: targetserver
  gather_facts: no
  vars:
    example_chsec:
      - file: /etc/security/user
        stanza: default
        attrs:
          logintimes: ":0800-1700"
      - file: /etc/security/limits
        stanzas:
        - joe:
            cpu: 3600
            file: -1
        - charlie:
            cpu: 3600
  remote_user: deploy
- tasks:
  name: Example chsec
    aix_chsec:
      file: "{{ item.file }}"
      stanza: "{{ item.stanza }}"
      attrs: "{{ item.attrs }}"
    loop:
      - "{{ example_chsec }}"

The example_chsec YAML above converts to the following JSON:

{
  "example_chsec": [
    {
      "file": "/etc/security/user",
      "stanza": "default",
      "attrs": {
        "logintimes": ":0800-1700"
      }
    },
    {
      "file": "/etc/security/limits",
      "stanzas": [
        {
          "joe": {
            "cpu": 3600,
            "file": -1
          }
        },
        {
          "charlie": {
            "cpu": 3600
          }
        }
      ]
    }
  ]
}
Open Questions
  • When setting multiple attributes per stanza, do we:
    • Run one chsec per attribute, or using a single chsec with multiple attributes
    • Fail as soon as one attribute fails, or try to set every attribute before failing the module?
      • ie: IF we're setting the ulimits file, count, and size; if file fails to set, do we continue to try count and size and then quit with failure, or quit at the point of failure?
  • Do we stick with one-stanza-per-file or allow many-stanzas-per-file?

module.fail_json(msg='Failed to run chsec command (absent).', rc=rc, stdout=stdout, stderr=stderr)
else:
msg = 'stanza removed'
changed = True
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless I am mistaken, this doesnt actually do anything. I do not believe it's possible to have an 'absent' flag to remove an entire stanza. chsec can only remove given attrs/options from a given stanza, it cannot remove the entire stanza.

This code block is just 'unsetting' all of the given attrs/options and ignoring the value assigned to them. These two YAML examples behave exactly the same way even though one has state=present and the other state=absent:

- name: Remove LDAP user stanzas
  aix_chsec:
    path: /etc/security/user
    stanza: ldapuser
    options: SYSTEM=LDAP,registry=LDAP
    state: absent
- name: Remove LDAP user stanzas
  aix_chsec:
    path: /etc/security/user
    stanza: ldapuser
    options: SYSTEM=,registry=
    state: present

HOWEVER, if there are other attrs set on that user stanza, the stanza will still exist. You need to specify every single user attr/option on that stanza to remove the stanza. Adding a 'true' state=absent will mean going through the given file, finding the stanza, getting all of the key:value pairs in that stanza, and then running chsec key=null to every one of those.

That's a loooot more work.

@d-little d-little mentioned this pull request Aug 20, 2019
@flynn1973
Copy link
Author

closed in favour of #60976

@flynn1973 flynn1973 closed this Sep 27, 2019
@ansible ansible locked and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

affects_2.8 This issue/PR affects Ansible v2.8 aix AIX community module This issue/PR relates to a module. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. new_contributor This PR is the first contribution by a new community member. new_module This PR includes a new module. new_plugin This PR includes a new plugin. stale_ci This PR has been tested by CI more than one week ago. Close and re-open this PR to get it retested. support:community This issue/PR relates to code supported by the Ansible community. system System category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants