|
|
@ -1,24 +1,22 @@
|
|
|
|
#!/usr/bin/python
|
|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
# (c) 2016, Hugh Ma <Hugh.Ma@flextronics.com>
|
|
|
|
# Copyright: (c) 2016, Hugh Ma <Hugh.Ma@flextronics.com>
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
|
|
'status': ['preview'],
|
|
|
|
'status': ['preview'],
|
|
|
|
'supported_by': 'community'}
|
|
|
|
'supported_by': 'community'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
---
|
|
|
|
---
|
|
|
|
module: stacki_host
|
|
|
|
module: stacki_host
|
|
|
|
short_description: Add or remove host to stacki front-end
|
|
|
|
short_description: Add or remove host to stacki front-end
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Use this module to add or remove hosts to a stacki front-end via API
|
|
|
|
- Use this module to add or remove hosts to a stacki front-end via API.
|
|
|
|
- U(https://github.com/StackIQ/stacki)
|
|
|
|
- U(https://github.com/StackIQ/stacki)
|
|
|
|
version_added: "2.3"
|
|
|
|
version_added: "2.3"
|
|
|
|
options:
|
|
|
|
options:
|
|
|
@ -43,21 +41,17 @@ options:
|
|
|
|
prim_intf_mac:
|
|
|
|
prim_intf_mac:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- MAC Address for the primary PXE boot network interface.
|
|
|
|
- MAC Address for the primary PXE boot network interface.
|
|
|
|
required: False
|
|
|
|
|
|
|
|
prim_intf_ip:
|
|
|
|
prim_intf_ip:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- IP Address for the primary network interface.
|
|
|
|
- IP Address for the primary network interface.
|
|
|
|
required: False
|
|
|
|
|
|
|
|
prim_intf:
|
|
|
|
prim_intf:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Name of the primary network interface.
|
|
|
|
- Name of the primary network interface.
|
|
|
|
required: False
|
|
|
|
|
|
|
|
force_install:
|
|
|
|
force_install:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Set value to True to force node into install state if it already exists in stacki.
|
|
|
|
- Set value to True to force node into install state if it already exists in stacki.
|
|
|
|
required: False
|
|
|
|
author:
|
|
|
|
|
|
|
|
- Hugh Ma <Hugh.Ma@flextronics.com>
|
|
|
|
author: "Hugh Ma <Hugh.Ma@flextronics.com>"
|
|
|
|
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
EXAMPLES = '''
|
|
|
|
EXAMPLES = '''
|
|
|
@ -161,7 +155,6 @@ class StackiHost(object):
|
|
|
|
'Content-type': 'application/json',
|
|
|
|
'Content-type': 'application/json',
|
|
|
|
'Cookie': login_req.headers.get('Set-Cookie')}
|
|
|
|
'Cookie': login_req.headers.get('Set-Cookie')}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def do_request(self, module, url, payload=None, headers=None, method=None):
|
|
|
|
def do_request(self, module, url, payload=None, headers=None, method=None):
|
|
|
|
res, info = fetch_url(module, url, data=payload, headers=headers, method=method)
|
|
|
|
res, info = fetch_url(module, url, data=payload, headers=headers, method=method)
|
|
|
|
|
|
|
|
|
|
|
@ -170,36 +163,25 @@ class StackiHost(object):
|
|
|
|
|
|
|
|
|
|
|
|
return res
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stack_check_host(self):
|
|
|
|
def stack_check_host(self):
|
|
|
|
|
|
|
|
res = self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "list host"}), headers=self.header, method="POST")
|
|
|
|
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():
|
|
|
|
if self.hostname in res.read():
|
|
|
|
return True
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stack_sync(self):
|
|
|
|
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 config"}),
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync host config"}), headers=self.header, method="POST")
|
|
|
|
headers=self.header, method="POST")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync host config"}),
|
|
|
|
|
|
|
|
headers=self.header, method="POST")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stack_force_install(self, result):
|
|
|
|
def stack_force_install(self, result):
|
|
|
|
|
|
|
|
|
|
|
|
data = dict()
|
|
|
|
data = dict()
|
|
|
|
changed = False
|
|
|
|
changed = False
|
|
|
|
|
|
|
|
|
|
|
|
data['cmd'] = "set host boot {0} action=install" \
|
|
|
|
data['cmd'] = "set host boot {0} action=install" \
|
|
|
|
.format(self.hostname)
|
|
|
|
.format(self.hostname)
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data),
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST")
|
|
|
|
headers=self.header, method="POST")
|
|
|
|
|
|
|
|
changed = True
|
|
|
|
changed = True
|
|
|
|
|
|
|
|
|
|
|
|
self.stack_sync()
|
|
|
|
self.stack_sync()
|
|
|
@ -208,29 +190,24 @@ class StackiHost(object):
|
|
|
|
result['stdout'] = "api call successful".rstrip("\r\n")
|
|
|
|
result['stdout'] = "api call successful".rstrip("\r\n")
|
|
|
|
|
|
|
|
|
|
|
|
def stack_add(self, result):
|
|
|
|
def stack_add(self, result):
|
|
|
|
|
|
|
|
|
|
|
|
data = dict()
|
|
|
|
data = dict()
|
|
|
|
changed = False
|
|
|
|
changed = False
|
|
|
|
|
|
|
|
|
|
|
|
data['cmd'] = "add host {0} rack={1} rank={2} appliance={3}"\
|
|
|
|
data['cmd'] = "add host {0} rack={1} rank={2} appliance={3}"\
|
|
|
|
.format(self.hostname, self.rack, self.rank, self.appliance)
|
|
|
|
.format(self.hostname, self.rack, self.rank, self.appliance)
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data),
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST")
|
|
|
|
headers=self.header, method="POST")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.stack_sync()
|
|
|
|
self.stack_sync()
|
|
|
|
|
|
|
|
|
|
|
|
result['changed'] = changed
|
|
|
|
result['changed'] = changed
|
|
|
|
result['stdout'] = "api call successful".rstrip("\r\n")
|
|
|
|
result['stdout'] = "api call successful".rstrip("\r\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stack_remove(self, result):
|
|
|
|
def stack_remove(self, result):
|
|
|
|
|
|
|
|
|
|
|
|
data = dict()
|
|
|
|
data = dict()
|
|
|
|
|
|
|
|
|
|
|
|
data['cmd'] = "remove host {0}"\
|
|
|
|
data['cmd'] = "remove host {0}"\
|
|
|
|
.format(self.hostname)
|
|
|
|
.format(self.hostname)
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data),
|
|
|
|
self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST")
|
|
|
|
headers=self.header, method="POST")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.stack_sync()
|
|
|
|
self.stack_sync()
|
|
|
|
|
|
|
|
|
|
|
@ -239,24 +216,23 @@ class StackiHost(object):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
def main():
|
|
|
|
|
|
|
|
|
|
|
|
module = AnsibleModule(
|
|
|
|
module = AnsibleModule(
|
|
|
|
argument_spec = dict(
|
|
|
|
argument_spec=dict(
|
|
|
|
state=dict(type='str', default='present', choices=['present', 'absent']),
|
|
|
|
state=dict(type='str', default='present', choices=['absent', 'present']),
|
|
|
|
name=dict(required=True, type='str'),
|
|
|
|
name=dict(type='str', required=True),
|
|
|
|
rack=dict(required=False, type='int', default=0),
|
|
|
|
rack=dict(type='int', default=0),
|
|
|
|
rank=dict(required=False, type='int', default=0),
|
|
|
|
rank=dict(type='int', default=0),
|
|
|
|
appliance=dict(required=False, type='str', default='backend'),
|
|
|
|
appliance=dict(type='str', default='backend'),
|
|
|
|
prim_intf=dict(required=False, type='str', default=None),
|
|
|
|
prim_intf=dict(type='str'),
|
|
|
|
prim_intf_ip=dict(required=False, type='str', default=None),
|
|
|
|
prim_intf_ip=dict(type='str'),
|
|
|
|
network=dict(required=False, type='str', default='private'),
|
|
|
|
network=dict(type='str', default='private'),
|
|
|
|
prim_intf_mac=dict(required=False, type='str', default=None),
|
|
|
|
prim_intf_mac=dict(type='str'),
|
|
|
|
stacki_user=dict(required=True, type='str', default=os.environ.get('stacki_user')),
|
|
|
|
stacki_user=dict(type='str', required=True, default=os.environ.get('stacki_user')),
|
|
|
|
stacki_password=dict(required=True, no_log=True, type='str', default=os.environ.get('stacki_password')),
|
|
|
|
stacki_password=dict(type='str', required=True, default=os.environ.get('stacki_password'), no_log=True),
|
|
|
|
stacki_endpoint=dict(required=True, type='str', default=os.environ.get('stacki_endpoint')),
|
|
|
|
stacki_endpoint=dict(type='str', required=True, default=os.environ.get('stacki_endpoint')),
|
|
|
|
force_install=dict(required=False, type='bool', default=False)
|
|
|
|
force_install=dict(type='bool', default=False),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
supports_check_mode=False
|
|
|
|
supports_check_mode=False,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
result = {'changed': False}
|
|
|
|
result = {'changed': False}
|
|
|
|