diff --git a/changelogs/fragments/2681-stacki-host-bugfix.yml b/changelogs/fragments/2681-stacki-host-bugfix.yml new file mode 100644 index 0000000000..3403bfbfbe --- /dev/null +++ b/changelogs/fragments/2681-stacki-host-bugfix.yml @@ -0,0 +1,4 @@ +bugfixes: + - stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681). +minor_changes: + - stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681). diff --git a/plugins/modules/remote_management/stacki/stacki_host.py b/plugins/modules/remote_management/stacki/stacki_host.py index 8bdc0f82f6..fda0c5d318 100644 --- a/plugins/modules/remote_management/stacki/stacki_host.py +++ b/plugins/modules/remote_management/stacki/stacki_host.py @@ -12,46 +12,48 @@ DOCUMENTATION = ''' module: stacki_host short_description: Add or remove host to stacki front-end description: - - Use this module to add or remove hosts to a stacki front-end via API. - - U(https://github.com/StackIQ/stacki) + - Use this module to add or remove hosts to a stacki front-end via API. + - Information on stacki can be found at U(https://github.com/StackIQ/stacki). options: name: description: - - Name of the host to be added to Stacki. + - Name of the host to be added to Stacki. required: True type: str stacki_user: description: - - Username for authenticating with Stacki API, but if not - specified, the environment variable C(stacki_user) is used instead. + - Username for authenticating with Stacki API, but if not specified, the environment variable C(stacki_user) is used instead. required: True type: str stacki_password: description: - - Password for authenticating with Stacki API, but if not + - Password for authenticating with Stacki API, but if not specified, the environment variable C(stacki_password) is used instead. required: True type: str stacki_endpoint: description: - - URL for the Stacki API Endpoint. + - URL for the Stacki API Endpoint. required: True type: str prim_intf_mac: description: - - MAC Address for the primary PXE boot network interface. + - MAC Address for the primary PXE boot network interface. + - Currently not used by the module. type: str prim_intf_ip: description: - - IP Address for the primary network interface. + - IP Address for the primary network interface. + - Currently not used by the module. type: str prim_intf: description: - - Name of the primary network interface. + - Name of the primary network interface. + - Currently not used by the module. type: str force_install: description: - - Set value to True to force node into install state if it already exists in stacki. + - Set value to C(true) to force node into install state if it already exists in stacki. type: bool default: no state: @@ -59,6 +61,30 @@ options: - Set value to the desired state for the specified host. type: str choices: [ absent, present ] + default: present + appliance: + description: + - Applicance to be used in host creation. + - Required if I(state) is C(present) and host does not yet exist. + type: str + default: backend + rack: + description: + - Rack to be used in host creation. + - Required if I(state) is C(present) and host does not yet exist. + type: int + rank: + description: + - Rank to be used in host creation. + - In Stacki terminology, the rank is the position of the machine in a rack. + - Required if I(state) is C(present) and host does not yet exist. + type: int + network: + description: + - Network to be configured in the host. + - Currently not used by the module. + type: str + default: private author: - Hugh Ma (@bbyhuy) ''' @@ -128,7 +154,7 @@ class StackiHost(object): 'PASSWORD': module.params['stacki_password']} # Get Initial CSRF - cred_a = self.do_request(self.module, self.endpoint, method="GET") + cred_a = self.do_request(self.endpoint, method="GET") cookie_a = cred_a.headers.get('Set-Cookie').split(';') init_csrftoken = None for c in cookie_a: @@ -145,8 +171,7 @@ class StackiHost(object): login_endpoint = self.endpoint + "/login" # Get Final CSRF and Session ID - login_req = self.do_request(self.module, login_endpoint, headers=header, - payload=urlencode(auth_creds), method='POST') + login_req = self.do_request(login_endpoint, headers=header, payload=urlencode(auth_creds), method='POST') cookie_f = login_req.headers.get('Set-Cookie').split(';') csrftoken = None @@ -163,8 +188,8 @@ class StackiHost(object): 'Content-type': 'application/json', 'Cookie': login_req.headers.get('Set-Cookie')} - def do_request(self, module, url, payload=None, headers=None, method=None): - res, info = fetch_url(module, url, data=payload, headers=headers, method=method) + def do_request(self, url, payload=None, headers=None, method=None): + res, info = fetch_url(self.module, url, data=payload, headers=headers, method=method) if info['status'] != 200: self.module.fail_json(changed=False, msg=info['msg']) @@ -172,24 +197,16 @@ class StackiHost(object): return res def stack_check_host(self): - res = self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "list host"}), headers=self.header, method="POST") - - if self.hostname in res.read(): - return True - else: - return False + res = self.do_request(self.endpoint, payload=json.dumps({"cmd": "list host"}), headers=self.header, method="POST") + return self.hostname in res.read() def stack_sync(self): - self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync config"}), headers=self.header, method="POST") - self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync host config"}), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps({"cmd": "sync config"}), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps({"cmd": "sync host config"}), headers=self.header, method="POST") def stack_force_install(self, result): - data = dict() - changed = False - - data['cmd'] = "set host boot {0} action=install" \ - .format(self.hostname) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + data = {'cmd': "set host boot {0} action=install".format(self.hostname)} + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") changed = True self.stack_sync() @@ -203,7 +220,7 @@ class StackiHost(object): data['cmd'] = "add host {0} rack={1} rank={2} appliance={3}"\ .format(self.hostname, self.rack, self.rank, self.appliance) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") self.stack_sync() @@ -215,7 +232,7 @@ class StackiHost(object): data['cmd'] = "remove host {0}"\ .format(self.hostname) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") self.stack_sync() @@ -258,8 +275,7 @@ def main(): .format(module.params['name']) # Otherwise, state is present, but host doesn't exists, require more params to add host elif module.params['state'] == 'present' and not host_exists: - for param in ['appliance', 'prim_intf', - 'prim_intf_ip', 'network', 'prim_intf_mac']: + for param in ['appliance', 'rack', 'rank', 'prim_intf', 'prim_intf_ip', 'network', 'prim_intf_mac']: if not module.params[param]: missing_params.append(param) if len(missing_params) > 0: # @FIXME replace with required_if diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 24caa4199d..d4ab945043 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -48,9 +48,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index b5f0a66859..9795211211 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -47,9 +47,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index bde8427875..efa12cda04 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -47,9 +47,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 569afe1207..e00cee8b52 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -38,9 +38,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/net_tools/nios/nios_a_record.py validate-modules:deprecation-mismatch plugins/modules/net_tools/nios/nios_a_record.py validate-modules:invalid-documentation plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:deprecation-mismatch