Relocating extras into lib/ansible/modules/ after merge

This commit is contained in:
James Cammarata 2016-12-08 00:36:57 -05:00 committed by Matt Clay
commit 011ea55a8f
596 changed files with 0 additions and 266 deletions

View file

@ -0,0 +1,249 @@
#!/usr/bin/python
# Copyright (c) 2015 VMware, Inc. All Rights Reserved.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vca_fw
short_description: add remove firewall rules in a gateway in a vca
description:
- Adds or removes firewall rules from a gateway in a vca environment
version_added: "2.0"
author: Peter Sprygada (@privateip)
options:
fw_rules:
description:
- A list of firewall rules to be added to the gateway, Please see examples on valid entries
required: True
default: false
extends_documentation_fragment: vca.documentation
'''
EXAMPLES = '''
#Add a set of firewall rules
- hosts: localhost
connection: local
tasks:
- vca_fw:
instance_id: 'b15ff1e5-1024-4f55-889f-ea0209726282'
vdc_name: 'benz_ansible'
state: 'absent'
fw_rules:
- description: "ben testing"
source_ip: "Any"
dest_ip: 192.0.2.23
- description: "ben testing 2"
source_ip: 192.0.2.50
source_port: "Any"
dest_port: "22"
dest_ip: 192.0.2.101
is_enable: "true"
enable_logging: "false"
protocol: "Tcp"
policy: "allow"
'''
try:
from pyvcloud.schema.vcd.v1_5.schemas.vcloud.networkType import FirewallRuleType
from pyvcloud.schema.vcd.v1_5.schemas.vcloud.networkType import ProtocolsType
except ImportError:
# normally set a flag here but it will be caught when testing for
# the existence of pyvcloud (see module_utils/vca.py). This just
# protects against generating an exception at runtime
pass
VALID_PROTO = ['Tcp', 'Udp', 'Icmp', 'Other', 'Any']
VALID_RULE_KEYS = ['policy', 'is_enable', 'enable_logging', 'description',
'dest_ip', 'dest_port', 'source_ip', 'source_port',
'protocol']
def protocol_to_tuple(protocol):
return (protocol.get_Tcp(),
protocol.get_Udp(),
protocol.get_Icmp(),
protocol.get_Other(),
protocol.get_Any())
def protocol_to_string(protocol):
protocol = protocol_to_tuple(protocol)
if protocol[0] is True:
return 'Tcp'
elif protocol[1] is True:
return 'Udp'
elif protocol[2] is True:
return 'Icmp'
elif protocol[3] is True:
return 'Other'
elif protocol[4] is True:
return 'Any'
def protocol_to_type(protocol):
try:
protocols = ProtocolsType()
setattr(protocols, protocol, True)
return protocols
except AttributeError:
raise VcaError("The value in protocol is not valid")
def validate_fw_rules(fw_rules):
for rule in fw_rules:
for k in rule.keys():
if k not in VALID_RULE_KEYS:
raise VcaError("%s is not a valid key in fw rules, please "
"check above.." % k, valid_keys=VALID_RULE_KEYS)
rule['dest_port'] = str(rule.get('dest_port', 'Any')).lower()
rule['dest_ip'] = rule.get('dest_ip', 'Any').lower()
rule['source_port'] = str(rule.get('source_port', 'Any')).lower()
rule['source_ip'] = rule.get('source_ip', 'Any').lower()
rule['protocol'] = rule.get('protocol', 'Any').lower()
rule['policy'] = rule.get('policy', 'allow').lower()
rule['is_enable'] = rule.get('is_enable', True)
rule['enable_logging'] = rule.get('enable_logging', False)
rule['description'] = rule.get('description', 'rule added by Ansible')
return fw_rules
def fw_rules_to_dict(rules):
fw_rules = list()
for rule in rules:
fw_rules.append(
dict(
dest_port=rule.get_DestinationPortRange().lower(),
dest_ip=rule.get_DestinationIp().lower().lower(),
source_port=rule.get_SourcePortRange().lower(),
source_ip=rule.get_SourceIp().lower(),
protocol=protocol_to_string(rule.get_Protocols()).lower(),
policy=rule.get_Policy().lower(),
is_enable=rule.get_IsEnabled(),
enable_logging=rule.get_EnableLogging(),
description=rule.get_Description()
)
)
return fw_rules
def create_fw_rule(is_enable, description, policy, protocol, dest_port,
dest_ip, source_port, source_ip, enable_logging):
return FirewallRuleType(IsEnabled=is_enable,
Description=description,
Policy=policy,
Protocols=protocol_to_type(protocol),
DestinationPortRange=dest_port,
DestinationIp=dest_ip,
SourcePortRange=source_port,
SourceIp=source_ip,
EnableLogging=enable_logging)
def main():
argument_spec = vca_argument_spec()
argument_spec.update(
dict(
fw_rules = dict(required=True, type='list'),
gateway_name = dict(default='gateway'),
state = dict(default='present', choices=['present', 'absent'])
)
)
module = AnsibleModule(argument_spec, supports_check_mode=True)
fw_rules = module.params.get('fw_rules')
gateway_name = module.params.get('gateway_name')
vdc_name = module.params['vdc_name']
vca = vca_login(module)
gateway = vca.get_gateway(vdc_name, gateway_name)
if not gateway:
module.fail_json(msg="Not able to find the gateway %s, please check "
"the gateway_name param" % gateway_name)
fwservice = gateway._getFirewallService()
rules = gateway.get_fw_rules()
current_rules = fw_rules_to_dict(rules)
try:
desired_rules = validate_fw_rules(fw_rules)
except VcaError as e:
module.fail_json(msg=e.message)
result = dict(changed=False)
result['current_rules'] = current_rules
result['desired_rules'] = desired_rules
updates = list()
additions = list()
deletions = list()
for (index, rule) in enumerate(desired_rules):
try:
if rule != current_rules[index]:
updates.append((index, rule))
except IndexError:
additions.append(rule)
eol = len(current_rules) > len(desired_rules)
if eol > 0:
for rule in current_rules[eos:]:
deletions.append(rule)
for rule in additions:
if not module.check_mode:
rule['protocol'] = rule['protocol'].capitalize()
gateway.add_fw_rule(**rule)
result['changed'] = True
for index, rule in updates:
if not module.check_mode:
rule = create_fw_rule(**rule)
fwservice.replace_FirewallRule_at(index, rule)
result['changed'] = True
keys = ['protocol', 'dest_port', 'dest_ip', 'source_port', 'source_ip']
for rule in deletions:
if not module.check_mode:
kwargs = dict([(k, v) for k, v in rule.items() if k in keys])
kwargs['protocol'] = protocol_to_string(kwargs['protocol'])
gateway.delete_fw_rule(**kwargs)
result['changed'] = True
if not module.check_mode and result['changed'] == True:
task = gateway.save_services_configuration()
if task:
vca.block_until_completed(task)
result['rules_updated'] = count=len(updates)
result['rules_added'] = count=len(additions)
result['rules_deleted'] = count=len(deletions)
return module.exit_json(**result)
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.vca import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,219 @@
#!/usr/bin/python
# Copyright (c) 2015 VMware, Inc. All Rights Reserved.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vca_nat
short_description: add remove nat rules in a gateway in a vca
description:
- Adds or removes nat rules from a gateway in a vca environment
version_added: "2.0"
author: Peter Sprygada (@privateip)
options:
purge_rules:
description:
- If set to true, it will delete all rules in the gateway that are not given as paramter to this module.
required: false
default: false
nat_rules:
description:
- A list of rules to be added to the gateway, Please see examples on valid entries
required: True
default: false
extends_documentation_fragment: vca.documentation
'''
EXAMPLES = '''
#An example for a source nat
- hosts: localhost
connection: local
tasks:
- vca_nat:
instance_id: 'b15ff1e5-1024-4f55-889f-ea0209726282'
vdc_name: 'benz_ansible'
state: 'present'
nat_rules:
- rule_type: SNAT
original_ip: 192.0.2.42
translated_ip: 203.0.113.23
#example for a DNAT
- hosts: localhost
connection: local
tasks:
- vca_nat:
instance_id: 'b15ff1e5-1024-4f55-889f-ea0209726282'
vdc_name: 'benz_ansible'
state: 'present'
nat_rules:
- rule_type: DNAT
original_ip: 203.0.113.23
original_port: 22
translated_ip: 192.0.2.42
translated_port: 22
'''
import time
import xmltodict
VALID_RULE_KEYS = ['rule_type', 'original_ip', 'original_port',
'translated_ip', 'translated_port', 'protocol']
def validate_nat_rules(nat_rules):
for rule in nat_rules:
if not isinstance(rule, dict):
raise VcaError("nat rules must be a list of dictionaries, "
"Please check", valid_keys=VALID_RULE_KEYS)
for k in rule.keys():
if k not in VALID_RULE_KEYS:
raise VcaError("%s is not a valid key in nat rules, please "
"check above.." % k, valid_keys=VALID_RULE_KEYS)
rule['original_port'] = str(rule.get('original_port', 'any')).lower()
rule['original_ip'] = rule.get('original_ip', 'any').lower()
rule['translated_ip'] = rule.get('translated_ip', 'any').lower()
rule['translated_port'] = str(rule.get('translated_port', 'any')).lower()
rule['protocol'] = rule.get('protocol', 'any').lower()
rule['rule_type'] = rule.get('rule_type', 'DNAT').lower()
return nat_rules
def nat_rules_to_dict(nat_rules):
result = []
for rule in nat_rules:
gw_rule = rule.get_GatewayNatRule()
result.append(
dict(
rule_type=rule.get_RuleType().lower(),
original_ip=gw_rule.get_OriginalIp().lower(),
original_port=(gw_rule.get_OriginalPort().lower() or 'any'),
translated_ip=gw_rule.get_TranslatedIp().lower(),
translated_port=(gw_rule.get_TranslatedPort().lower() or 'any'),
protocol=(gw_rule.get_Protocol().lower() or 'any')
)
)
return result
def rule_to_string(rule):
strings = list()
for key, value in rule.items():
strings.append('%s=%s' % (key, value))
return ', '.join(string)
def main():
argument_spec = vca_argument_spec()
argument_spec.update(
dict(
nat_rules = dict(type='list', default=[]),
gateway_name = dict(default='gateway'),
purge_rules = dict(default=False, type='bool'),
state = dict(default='present', choices=['present', 'absent'])
)
)
module = AnsibleModule(argument_spec, supports_check_mode=True)
vdc_name = module.params.get('vdc_name')
state = module.params['state']
nat_rules = module.params['nat_rules']
gateway_name = module.params['gateway_name']
purge_rules = module.params['purge_rules']
if not purge_rules and not nat_rules:
module.fail_json(msg='Must define purge_rules or nat_rules')
vca = vca_login(module)
gateway = vca.get_gateway(vdc_name, gateway_name)
if not gateway:
module.fail_json(msg="Not able to find the gateway %s, please check "
"the gateway_name param" % gateway_name)
try:
desired_rules = validate_nat_rules(nat_rules)
except VcaError as e:
module.fail_json(msg=e.message)
rules = gateway.get_nat_rules()
result = dict(changed=False, rules_purged=0)
deletions = 0
additions = 0
if purge_rules is True and len(rules) > 0:
result['rules_purged'] = len(rules)
deletions = result['rules_purged']
rules = list()
if not module.check_mode:
gateway.del_all_nat_rules()
task = gateway.save_services_configuration()
vca.block_until_completed(task)
rules = gateway.get_nat_rules()
result['changed'] = True
current_rules = nat_rules_to_dict(rules)
result['current_rules'] = current_rules
result['desired_rules'] = desired_rules
for rule in desired_rules:
if rule not in current_rules:
additions += 1
if not module.check_mode:
gateway.add_nat_rule(**rule)
result['changed'] = True
result['rules_added'] = additions
result['delete_rule'] = list()
result['delete_rule_rc'] = list()
for rule in current_rules:
if rule not in desired_rules:
deletions += 1
if not module.check_mode:
result['delete_rule'].append(rule)
rc = gateway.del_nat_rule(**rule)
result['delete_rule_rc'].append(rc)
result['changed'] = True
result['rules_deleted'] = deletions
if not module.check_mode and (additions > 0 or deletions > 0):
task = gateway.save_services_configuration()
vca.block_until_completed(task)
module.exit_json(**result)
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.vca import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,286 @@
#!/usr/bin/python
# Copyright (c) 2015 Ansible, Inc.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vca_vapp
short_description: Manages vCloud Air vApp instances.
description:
- This module will actively managed vCloud Air vApp instances. Instances
can be created and deleted as well as both deployed and undeployed.
version_added: "2.0"
author: Peter Sprygada (@privateip)
options:
vapp_name:
description:
- The name of the vCloud Air vApp instance
required: yes
template_name:
description:
- The name of the vApp template to use to create the vApp instance. If
the I(state) is not `absent` then the I(template_name) value must be
provided. The I(template_name) must be previously uploaded to the
catalog specified by I(catalog_name)
required: no
default: None
network_name:
description:
- The name of the network that should be attached to the virtual machine
in the vApp. The virtual network specified must already be created in
the vCloud Air VDC. If the I(state) is not 'absent' then the
I(network_name) argument must be provided.
required: no
default: None
network_mode:
description:
- Configures the mode of the network connection.
required: no
default: pool
choices: ['pool', 'dhcp', 'static']
vm_name:
description:
- The name of the virtual machine instance in the vApp to manage.
required: no
default: None
vm_cpus:
description:
- The number of vCPUs to configure for the VM in the vApp. If the
I(vm_name) argument is provided, then this becomes a per VM setting
otherwise it is applied to all VMs in the vApp.
required: no
default: None
vm_memory:
description:
- The amount of memory in MB to allocate to VMs in the vApp. If the
I(vm_name) argument is provided, then this becomes a per VM setting
otherise it is applied to all VMs in the vApp.
required: no
default: None
operation:
description:
- Specifies an operation to be performed on the vApp.
required: no
default: noop
choices: ['noop', 'poweron', 'poweroff', 'suspend', 'shutdown', 'reboot', 'reset']
state:
description:
- Configures the state of the vApp.
required: no
default: present
choices: ['present', 'absent', 'deployed', 'undeployed']
username:
description:
- The vCloud Air username to use during authentication
required: false
default: None
password:
description:
- The vCloud Air password to use during authentication
required: false
default: None
org:
description:
- The org to login to for creating vapp, mostly set when the service_type is vdc.
required: false
default: None
instance_id:
description:
- The instance id in a vchs environment to be used for creating the vapp
required: false
default: None
host:
description:
- The authentication host to be used when service type is vcd.
required: false
default: None
api_version:
description:
- The api version to be used with the vca
required: false
default: "5.7"
service_type:
description:
- The type of service we are authenticating against
required: false
default: vca
choices: [ "vca", "vchs", "vcd" ]
vdc_name:
description:
- The name of the virtual data center (VDC) where the vm should be created or contains the vAPP.
required: false
default: None
'''
EXAMPLES = '''
- name: Creates a new vApp in a VCA instance
vca_vapp:
vapp_name: tower
state=present
template_name='Ubuntu Server 12.04 LTS (amd64 20150127)'
vdc_name=VDC1
instance_id=<your instance id here>
username=<your username here>
password=<your password here>
'''
DEFAULT_VAPP_OPERATION = 'noop'
VAPP_STATUS = {
'Powered off': 'poweroff',
'Powered on': 'poweron',
'Suspended': 'suspend'
}
VAPP_STATES = ['present', 'absent', 'deployed', 'undeployed']
VAPP_OPERATIONS = ['poweron', 'poweroff', 'suspend', 'shutdown',
'reboot', 'reset', 'noop']
def get_instance(module):
vapp_name = module.params['vapp_name']
inst = dict(vapp_name=vapp_name, state='absent')
try:
vapp = module.get_vapp(vapp_name)
if vapp:
status = module.vca.get_status(vapp.me.get_status())
inst['status'] = VAPP_STATUS.get(status, 'unknown')
inst['state'] = 'deployed' if vapp.me.deployed else 'undeployed'
return inst
except VcaError:
return inst
def create(module):
vdc_name = module.params['vdc_name']
vapp_name = module.params['vapp_name']
template_name = module.params['template_name']
catalog_name = module.params['catalog_name']
network_name = module.params['network_name']
network_mode = module.params['network_mode']
vm_name = module.params['vm_name']
vm_cpus = module.params['vm_cpus']
vm_memory = module.params['vm_memory']
deploy = module.params['state'] == 'deploy'
poweron = module.params['operation'] == 'poweron'
task = module.vca.create_vapp(vdc_name, vapp_name, template_name,
catalog_name, network_name, network_mode,
vm_name, vm_cpus, vm_memory, deploy, poweron)
module.vca.block_until_completed(task)
def delete(module):
vdc_name = module.params['vdc_name']
vapp_name = module.params['vapp_name']
module.vca.delete_vapp(vdc_name, vapp_name)
def do_operation(module):
vapp_name = module.params['vapp_name']
operation = module.params['operation']
vm_name = module.params.get('vm_name')
vm = None
if vm_name:
vm = module.get_vm(vapp_name, vm_name)
if operation == 'poweron':
operation = 'powerOn'
elif operation == 'poweroff':
operation = 'powerOff'
cmd = 'power:%s' % operation
module.get_vapp(vapp_name).execute(cmd, 'post', targetVM=vm)
def set_state(module):
state = module.params['state']
vapp = module.get_vapp(module.params['vapp_name'])
if state == 'deployed':
action = module.params['operation'] == 'poweron'
if not vapp.deploy(action):
module.fail('unable to deploy vapp')
elif state == 'undeployed':
action = module.params['operation']
if action == 'poweroff':
action = 'powerOff'
elif action != 'suspend':
action = None
if not vapp.undeploy(action):
module.fail('unable to undeploy vapp')
def main():
argument_spec = dict(
vapp_name=dict(required=True),
vdc_name=dict(required=True),
template_name=dict(),
catalog_name=dict(default='Public Catalog'),
network_name=dict(),
network_mode=dict(default='pool', choices=['dhcp', 'static', 'pool']),
vm_name=dict(),
vm_cpus=dict(),
vm_memory=dict(),
operation=dict(default=DEFAULT_VAPP_OPERATION, choices=VAPP_OPERATIONS),
state=dict(default='present', choices=VAPP_STATES)
)
module = VcaAnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
state = module.params['state']
operation = module.params['operation']
instance = get_instance(module)
result = dict(changed=False)
if instance and state == 'absent':
if not module.check_mode:
delete(module)
result['changed'] = True
elif state != 'absent':
if instance['state'] == 'absent':
if not module.check_mode:
create(module)
result['changed'] = True
elif instance['state'] != state and state != 'present':
if not module.check_mode:
set_state(module)
result['changed'] = True
if operation != instance.get('status') and operation != 'noop':
if not module.check_mode:
do_operation(module)
result['changed'] = True
return module.exit(**result)
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.vca import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,255 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_cluster
short_description: Create VMware vSphere Cluster
description:
- Create VMware vSphere Cluster
version_added: 2.0
author: Joseph Callen (@jcpowermac)
notes:
requirements:
- Tested on ESXi 5.5
- PyVmomi installed
options:
datacenter_name:
description:
- The name of the datacenter the cluster will be created in.
required: True
cluster_name:
description:
- The name of the cluster that will be created
required: True
enable_ha:
description:
- If set to True will enable HA when the cluster is created.
required: False
default: False
enable_drs:
description:
- If set to True will enable DRS when the cluster is created.
required: False
default: False
enable_vsan:
description:
- If set to True will enable vSAN when the cluster is created.
required: False
default: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_cluster command from Ansible Playbooks
- name: Create Cluster
local_action: >
vmware_cluster
hostname="{{ ansible_ssh_host }}" username=root password=vmware
datacenter_name="datacenter"
cluster_name="cluster"
enable_ha=True
enable_drs=True
enable_vsan=True
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareCluster(object):
def __init__(self, module):
self.module = module
self.enable_ha = module.params['enable_ha']
self.enable_drs = module.params['enable_drs']
self.enable_vsan = module.params['enable_vsan']
self.cluster_name = module.params['cluster_name']
self.desired_state = module.params['state']
self.datacenter = None
self.cluster = None
self.content = connect_to_api(module)
self.datacenter_name = module.params['datacenter_name']
def process_state(self):
cluster_states = {
'absent': {
'present': self.state_destroy_cluster,
'absent': self.state_exit_unchanged,
},
'present': {
'update': self.state_update_cluster,
'present': self.state_exit_unchanged,
'absent': self.state_create_cluster,
}
}
current_state = self.check_cluster_configuration()
# Based on the desired_state and the current_state call
# the appropriate method from the dictionary
cluster_states[self.desired_state][current_state]()
def configure_ha(self):
das_config = vim.cluster.DasConfigInfo()
das_config.enabled = self.enable_ha
das_config.admissionControlPolicy = vim.cluster.FailoverLevelAdmissionControlPolicy()
das_config.admissionControlPolicy.failoverLevel = 2
return das_config
def configure_drs(self):
drs_config = vim.cluster.DrsConfigInfo()
drs_config.enabled = self.enable_drs
# Set to partially automated
drs_config.vmotionRate = 3
return drs_config
def configure_vsan(self):
vsan_config = vim.vsan.cluster.ConfigInfo()
vsan_config.enabled = self.enable_vsan
vsan_config.defaultConfig = vim.vsan.cluster.ConfigInfo.HostDefaultInfo()
vsan_config.defaultConfig.autoClaimStorage = False
return vsan_config
def state_create_cluster(self):
try:
cluster_config_spec = vim.cluster.ConfigSpecEx()
cluster_config_spec.dasConfig = self.configure_ha()
cluster_config_spec.drsConfig = self.configure_drs()
if self.enable_vsan:
cluster_config_spec.vsanConfig = self.configure_vsan()
if not self.module.check_mode:
self.datacenter.hostFolder.CreateClusterEx(self.cluster_name, cluster_config_spec)
self.module.exit_json(changed=True)
except vim.fault.DuplicateName:
self.module.fail_json(msg="A cluster with the name %s already exists" % self.cluster_name)
except vmodl.fault.InvalidArgument:
self.module.fail_json(msg="Cluster configuration specification parameter is invalid")
except vim.fault.InvalidName:
self.module.fail_json(msg="%s is an invalid name for a cluster" % self.cluster_name)
except vmodl.fault.NotSupported:
# This should never happen
self.module.fail_json(msg="Trying to create a cluster on an incorrect folder object")
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
# This should never happen either
self.module.fail_json(msg=method_fault.msg)
def state_destroy_cluster(self):
changed = True
result = None
try:
if not self.module.check_mode:
task = self.cluster.Destroy_Task()
changed, result = wait_for_task(task)
self.module.exit_json(changed=changed, result=result)
except vim.fault.VimFault as vim_fault:
self.module.fail_json(msg=vim_fault.msg)
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_update_cluster(self):
cluster_config_spec = vim.cluster.ConfigSpecEx()
changed = True
result = None
if self.cluster.configurationEx.dasConfig.enabled != self.enable_ha:
cluster_config_spec.dasConfig = self.configure_ha()
if self.cluster.configurationEx.drsConfig.enabled != self.enable_drs:
cluster_config_spec.drsConfig = self.configure_drs()
if self.cluster.configurationEx.vsanConfigInfo.enabled != self.enable_vsan:
cluster_config_spec.vsanConfig = self.configure_vsan()
try:
if not self.module.check_mode:
task = self.cluster.ReconfigureComputeResource_Task(cluster_config_spec, True)
changed, result = wait_for_task(task)
self.module.exit_json(changed=changed, result=result)
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except TaskError as task_e:
self.module.fail_json(msg=str(task_e))
def check_cluster_configuration(self):
try:
self.datacenter = find_datacenter_by_name(self.content, self.datacenter_name)
if self.datacenter is None:
self.module.fail_json(msg="Datacenter %s does not exist, "
"please create first with Ansible Module vmware_datacenter or manually."
% self.datacenter_name)
self.cluster = find_cluster_by_name_datacenter(self.datacenter, self.cluster_name)
if self.cluster is None:
return 'absent'
else:
desired_state = (self.enable_ha,
self.enable_drs,
self.enable_vsan)
current_state = (self.cluster.configurationEx.dasConfig.enabled,
self.cluster.configurationEx.drsConfig.enabled,
self.cluster.configurationEx.vsanConfigInfo.enabled)
if cmp(desired_state, current_state) != 0:
return 'update'
else:
return 'present'
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(datacenter_name=dict(required=True, type='str'),
cluster_name=dict(required=True, type='str'),
enable_ha=dict(default=False, required=False, type='bool'),
enable_drs=dict(default=False, required=False, type='bool'),
enable_vsan=dict(default=False, required=False, type='bool'),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_cluster = VMwareCluster(module)
vmware_cluster.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,164 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_datacenter
short_description: Manage VMware vSphere Datacenters
description:
- Manage VMware vSphere Datacenters
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Kamil Szczygiel (@kamsz)"
notes:
- Tested on vSphere 6.0
requirements:
- "python >= 2.6"
- PyVmomi
options:
hostname:
description:
- The hostname or IP address of the vSphere vCenter API server
required: True
username:
description:
- The username of the vSphere vCenter
required: True
aliases: ['user', 'admin']
password:
description:
- The password of the vSphere vCenter
required: True
aliases: ['pass', 'pwd']
datacenter_name:
description:
- The name of the datacenter the cluster will be created in.
required: True
state:
description:
- If the datacenter should be present or absent
choices: ['present', 'absent']
default: present
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_datacenter command from Ansible Playbooks
- name: Create Datacenter
local_action: >
vmware_datacenter
hostname="{{ ansible_ssh_host }}" username=root password=vmware
datacenter_name="datacenter" state=present
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def get_datacenter(context, module):
try:
datacenter_name = module.params.get('datacenter_name')
datacenter = find_datacenter_by_name(context, datacenter_name)
return datacenter
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
def create_datacenter(context, module):
datacenter_name = module.params.get('datacenter_name')
folder = context.rootFolder
try:
datacenter = get_datacenter(context, module)
changed = False
if not datacenter:
changed = True
if not module.check_mode:
folder.CreateDatacenter(name=datacenter_name)
module.exit_json(changed=changed)
except vim.fault.DuplicateName:
module.fail_json(msg="A datacenter with the name %s already exists" % datacenter_name)
except vim.fault.InvalidName:
module.fail_json(msg="%s is an invalid name for a cluster" % datacenter_name)
except vmodl.fault.NotSupported:
# This should never happen
module.fail_json(msg="Trying to create a datacenter on an incorrect folder object")
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
def destroy_datacenter(context, module):
result = None
try:
datacenter = get_datacenter(context, module)
changed = False
if datacenter:
changed = True
if not module.check_mode:
task = datacenter.Destroy_Task()
changed, result = wait_for_task(task)
module.exit_json(changed=changed, result=result)
except vim.fault.VimFault as vim_fault:
module.fail_json(msg=vim_fault.msg)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(
dict(
datacenter_name=dict(required=True, type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str')
)
)
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
context = connect_to_api(module)
state = module.params.get('state')
if state == 'present':
create_datacenter(context, module)
if state == 'absent':
destroy_datacenter(context, module)
from ansible.module_utils.basic import *
from ansible.module_utils.vmware import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,134 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_dns_config
short_description: Manage VMware ESXi DNS Configuration
description:
- Manage VMware ESXi DNS Configuration
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
change_hostname_to:
description:
- The hostname that an ESXi host should be changed to.
required: True
domainname:
description:
- The domain the ESXi host should be apart of.
required: True
dns_servers:
description:
- The DNS servers that the host should be configured to use.
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_dns_config command from Ansible Playbooks
- name: Configure ESXi hostname and DNS servers
local_action:
module: vmware_dns_config
hostname: esxi_hostname
username: root
password: your_password
change_hostname_to: esx01
domainname: foo.org
dns_servers:
- 8.8.8.8
- 8.8.4.4
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def configure_dns(host_system, hostname, domainname, dns_servers):
changed = False
host_config_manager = host_system.configManager
host_network_system = host_config_manager.networkSystem
config = host_network_system.dnsConfig
config.dhcp = False
if config.address != dns_servers:
config.address = dns_servers
changed = True
if config.domainName != domainname:
config.domainName = domainname
changed = True
if config.hostName != hostname:
config.hostName = hostname
changed = True
if changed:
host_network_system.UpdateDnsConfig(config)
return changed
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(change_hostname_to=dict(required=True, type='str'),
domainname=dict(required=True, type='str'),
dns_servers=dict(required=True, type='list')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
change_hostname_to = module.params['change_hostname_to']
domainname = module.params['domainname']
dns_servers = module.params['dns_servers']
try:
content = connect_to_api(module)
host = get_all_objs(content, [vim.HostSystem])
if not host:
module.fail_json(msg="Unable to locate Physical Host.")
host_system = host.keys()[0]
changed = configure_dns(host_system, change_hostname_to, domainname, dns_servers)
module.exit_json(changed=changed)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,253 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_dvs_host
short_description: Add or remove a host from distributed virtual switch
description:
- Add or remove a host from distributed virtual switch
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
esxi_hostname:
description:
- The ESXi hostname
required: True
switch_name:
description:
- The name of the Distributed vSwitch
required: True
vmnics:
description:
- The ESXi hosts vmnics to use with the Distributed vSwitch
required: True
state:
description:
- If the host should be present or absent attached to the vSwitch
choices: ['present', 'absent']
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_dvs_host command from Ansible Playbooks
- name: Add Host to dVS
local_action:
module: vmware_dvs_host
hostname: vcenter_ip_or_hostname
username: vcenter_username
password: vcenter_password
esxi_hostname: esxi_hostname_as_listed_in_vcenter
switch_name: dvSwitch
vmnics:
- vmnic0
- vmnic1
state: present
'''
try:
import collections
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareDvsHost(object):
def __init__(self, module):
self.module = module
self.dv_switch = None
self.uplink_portgroup = None
self.host = None
self.dv_switch = None
self.nic = None
self.content = connect_to_api(self.module)
self.state = self.module.params['state']
self.switch_name = self.module.params['switch_name']
self.esxi_hostname = self.module.params['esxi_hostname']
self.vmnics = self.module.params['vmnics']
def process_state(self):
try:
dvs_host_states = {
'absent': {
'present': self.state_destroy_dvs_host,
'absent': self.state_exit_unchanged,
},
'present': {
'update': self.state_update_dvs_host,
'present': self.state_exit_unchanged,
'absent': self.state_create_dvs_host,
}
}
dvs_host_states[self.state][self.check_dvs_host_state()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def find_dvspg_by_name(self):
portgroups = self.dv_switch.portgroup
for pg in portgroups:
if pg.name == self.portgroup_name:
return pg
return None
def find_dvs_uplink_pg(self):
# There should only always be a single uplink port group on
# a distributed virtual switch
if len(self.dv_switch.config.uplinkPortgroup):
return self.dv_switch.config.uplinkPortgroup[0]
else:
return None
# operation should be edit, add and remove
def modify_dvs_host(self, operation):
spec = vim.DistributedVirtualSwitch.ConfigSpec()
spec.configVersion = self.dv_switch.config.configVersion
spec.host = [vim.dvs.HostMember.ConfigSpec()]
spec.host[0].operation = operation
spec.host[0].host = self.host
if operation in ("edit", "add"):
spec.host[0].backing = vim.dvs.HostMember.PnicBacking()
count = 0
for nic in self.vmnics:
spec.host[0].backing.pnicSpec.append(vim.dvs.HostMember.PnicSpec())
spec.host[0].backing.pnicSpec[count].pnicDevice = nic
spec.host[0].backing.pnicSpec[count].uplinkPortgroupKey = self.uplink_portgroup.key
count += 1
task = self.dv_switch.ReconfigureDvs_Task(spec)
changed, result = wait_for_task(task)
return changed, result
def state_destroy_dvs_host(self):
operation = "remove"
changed = True
result = None
if not self.module.check_mode:
changed, result = self.modify_dvs_host(operation)
self.module.exit_json(changed=changed, result=str(result))
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_update_dvs_host(self):
operation = "edit"
changed = True
result = None
if not self.module.check_mode:
changed, result = self.modify_dvs_host(operation)
self.module.exit_json(changed=changed, result=str(result))
def state_create_dvs_host(self):
operation = "add"
changed = True
result = None
if not self.module.check_mode:
changed, result = self.modify_dvs_host(operation)
self.module.exit_json(changed=changed, result=str(result))
def find_host_attached_dvs(self):
for dvs_host_member in self.dv_switch.config.host:
if dvs_host_member.config.host.name == self.esxi_hostname:
return dvs_host_member.config.host
return None
def check_uplinks(self):
pnic_device = []
for dvs_host_member in self.dv_switch.config.host:
if dvs_host_member.config.host == self.host:
for pnicSpec in dvs_host_member.config.backing.pnicSpec:
pnic_device.append(pnicSpec.pnicDevice)
return collections.Counter(pnic_device) == collections.Counter(self.vmnics)
def check_dvs_host_state(self):
self.dv_switch = find_dvs_by_name(self.content, self.switch_name)
if self.dv_switch is None:
raise Exception("A distributed virtual switch %s does not exist" % self.switch_name)
self.uplink_portgroup = self.find_dvs_uplink_pg()
if self.uplink_portgroup is None:
raise Exception("An uplink portgroup does not exist on the distributed virtual switch %s"
% self.switch_name)
self.host = self.find_host_attached_dvs()
if self.host is None:
# We still need the HostSystem object to add the host
# to the distributed vswitch
self.host = find_hostsystem_by_name(self.content, self.esxi_hostname)
if self.host is None:
self.module.fail_json(msg="The esxi_hostname %s does not exist in vCenter" % self.esxi_hostname)
return 'absent'
else:
if self.check_uplinks():
return 'present'
else:
return 'update'
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(esxi_hostname=dict(required=True, type='str'),
switch_name=dict(required=True, type='str'),
vmnics=dict(required=True, type='list'),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_dvs_host = VMwareDvsHost(module)
vmware_dvs_host.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,202 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_dvs_portgroup
short_description: Create or remove a Distributed vSwitch portgroup
description:
- Create or remove a Distributed vSwitch portgroup
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
portgroup_name:
description:
- The name of the portgroup that is to be created or deleted
required: True
switch_name:
description:
- The name of the distributed vSwitch the port group should be created on.
required: True
vlan_id:
description:
- The VLAN ID that should be configured with the portgroup
required: True
num_ports:
description:
- The number of ports the portgroup should contain
required: True
portgroup_type:
description:
- See VMware KB 1022312 regarding portgroup types
required: True
choices:
- 'earlyBinding'
- 'lateBinding'
- 'ephemeral'
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: Create Management portgroup
local_action:
module: vmware_dvs_portgroup
hostname: vcenter_ip_or_hostname
username: vcenter_username
password: vcenter_password
portgroup_name: Management
switch_name: dvSwitch
vlan_id: 123
num_ports: 120
portgroup_type: earlyBinding
state: present
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareDvsPortgroup(object):
def __init__(self, module):
self.module = module
self.dvs_portgroup = None
self.switch_name = self.module.params['switch_name']
self.portgroup_name = self.module.params['portgroup_name']
self.vlan_id = self.module.params['vlan_id']
self.num_ports = self.module.params['num_ports']
self.portgroup_type = self.module.params['portgroup_type']
self.dv_switch = None
self.state = self.module.params['state']
self.content = connect_to_api(module)
def process_state(self):
try:
dvspg_states = {
'absent': {
'present': self.state_destroy_dvspg,
'absent': self.state_exit_unchanged,
},
'present': {
'update': self.state_update_dvspg,
'present': self.state_exit_unchanged,
'absent': self.state_create_dvspg,
}
}
dvspg_states[self.state][self.check_dvspg_state()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def create_port_group(self):
config = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()
config.name = self.portgroup_name
config.numPorts = self.num_ports
# vim.VMwareDVSPortSetting() does not exist in the pyvmomi documentation
# but this is the correct managed object type.
config.defaultPortConfig = vim.VMwareDVSPortSetting()
# vim.VmwareDistributedVirtualSwitchVlanIdSpec() does not exist in the
# pyvmomi documentation but this is the correct managed object type
config.defaultPortConfig.vlan = vim.VmwareDistributedVirtualSwitchVlanIdSpec()
config.defaultPortConfig.vlan.inherited = False
config.defaultPortConfig.vlan.vlanId = self.vlan_id
config.type = self.portgroup_type
spec = [config]
task = self.dv_switch.AddDVPortgroup_Task(spec)
changed, result = wait_for_task(task)
return changed, result
def state_destroy_dvspg(self):
changed = True
result = None
if not self.module.check_mode:
task = self.dvs_portgroup.Destroy_Task()
changed, result = wait_for_task(task)
self.module.exit_json(changed=changed, result=str(result))
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_update_dvspg(self):
self.module.exit_json(changed=False, msg="Currently not implemented.")
def state_create_dvspg(self):
changed = True
result = None
if not self.module.check_mode:
changed, result = self.create_port_group()
self.module.exit_json(changed=changed, result=str(result))
def check_dvspg_state(self):
self.dv_switch = find_dvs_by_name(self.content, self.switch_name)
if self.dv_switch is None:
raise Exception("A distributed virtual switch with name %s does not exist" % self.switch_name)
self.dvs_portgroup = find_dvspg_by_name(self.dv_switch, self.portgroup_name)
if self.dvs_portgroup is None:
return 'absent'
else:
return 'present'
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),
switch_name=dict(required=True, type='str'),
vlan_id=dict(required=True, type='int'),
num_ports=dict(required=True, type='int'),
portgroup_type=dict(required=True, choices=['earlyBinding', 'lateBinding', 'ephemeral'], type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_dvs_portgroup = VMwareDvsPortgroup(module)
vmware_dvs_portgroup.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,213 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_dvswitch
short_description: Create or remove a distributed vSwitch
description:
- Create or remove a distributed vSwitch
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
datacenter_name:
description:
- The name of the datacenter that will contain the dvSwitch
required: True
switch_name:
description:
- The name of the switch to create or remove
required: True
mtu:
description:
- The switch maximum transmission unit
required: True
uplink_quantity:
description:
- Quantity of uplink per ESXi host added to the switch
required: True
discovery_proto:
description:
- Link discovery protocol between Cisco and Link Layer discovery
choices:
- 'cdp'
- 'lldp'
required: True
discovery_operation:
description:
- Select the discovery operation
choices:
- 'both'
- 'none'
- 'advertise'
- 'listen'
state:
description:
- Create or remove dvSwitch
default: 'present'
choices:
- 'present'
- 'absent'
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: Create dvswitch
local_action:
module: vmware_dvswitch
hostname: vcenter_ip_or_hostname
username: vcenter_username
password: vcenter_password
datacenter_name: datacenter
switch_name: dvSwitch
mtu: 9000
uplink_quantity: 2
discovery_proto: lldp
discovery_operation: both
state: present
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareDVSwitch(object):
def __init__(self, module):
self.module = module
self.dvs = None
self.switch_name = self.module.params['switch_name']
self.datacenter_name = self.module.params['datacenter_name']
self.mtu = self.module.params['mtu']
self.uplink_quantity = self.module.params['uplink_quantity']
self.discovery_proto = self.module.params['discovery_proto']
self.discovery_operation = self.module.params['discovery_operation']
self.switch_name = self.module.params['switch_name']
self.state = self.module.params['state']
self.content = connect_to_api(module)
def process_state(self):
try:
dvs_states = {
'absent': {
'present': self.state_destroy_dvs,
'absent': self.state_exit_unchanged,
},
'present': {
'update': self.state_update_dvs,
'present': self.state_exit_unchanged,
'absent': self.state_create_dvs,
}
}
dvs_states[self.state][self.check_dvs_configuration()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def create_dvswitch(self, network_folder):
result = None
changed = False
spec = vim.DistributedVirtualSwitch.CreateSpec()
spec.configSpec = vim.dvs.VmwareDistributedVirtualSwitch.ConfigSpec()
spec.configSpec.uplinkPortPolicy = vim.DistributedVirtualSwitch.NameArrayUplinkPortPolicy()
spec.configSpec.linkDiscoveryProtocolConfig = vim.host.LinkDiscoveryProtocolConfig()
spec.configSpec.name = self.switch_name
spec.configSpec.maxMtu = self.mtu
spec.configSpec.linkDiscoveryProtocolConfig.protocol = self.discovery_proto
spec.configSpec.linkDiscoveryProtocolConfig.operation = self.discovery_operation
spec.productInfo = vim.dvs.ProductSpec()
spec.productInfo.name = "DVS"
spec.productInfo.vendor = "VMware"
for count in range(1, self.uplink_quantity+1):
spec.configSpec.uplinkPortPolicy.uplinkPortName.append("uplink%d" % count)
task = network_folder.CreateDVS_Task(spec)
changed, result = wait_for_task(task)
return changed, result
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_destroy_dvs(self):
task = self.dvs.Destroy_Task()
changed, result = wait_for_task(task)
self.module.exit_json(changed=changed, result=str(result))
def state_update_dvs(self):
self.module.exit_json(changed=False, msg="Currently not implemented.")
def state_create_dvs(self):
changed = True
result = None
if not self.module.check_mode:
dc = find_datacenter_by_name(self.content, self.datacenter_name)
changed, result = self.create_dvswitch(dc.networkFolder)
self.module.exit_json(changed=changed, result=str(result))
def check_dvs_configuration(self):
self.dvs = find_dvs_by_name(self.content, self.switch_name)
if self.dvs is None:
return 'absent'
else:
return 'present'
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(datacenter_name=dict(required=True, type='str'),
switch_name=dict(required=True, type='str'),
mtu=dict(required=True, type='int'),
uplink_quantity=dict(required=True, type='int'),
discovery_proto=dict(required=True, choices=['cdp', 'lldp'], type='str'),
discovery_operation=dict(required=True, choices=['both', 'none', 'advertise', 'listen'], type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_dvswitch = VMwareDVSwitch(module)
vmware_dvswitch.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,229 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_host
short_description: Add/remove ESXi host to/from vCenter
description:
- This module can be used to add/remove an ESXi host to/from vCenter
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
datacenter_name:
description:
- Name of the datacenter to add the host
required: True
cluster_name:
description:
- Name of the cluster to add the host
required: True
esxi_hostname:
description:
- ESXi hostname to manage
required: True
esxi_username:
description:
- ESXi username
required: True
esxi_password:
description:
- ESXi password
required: True
state:
description:
- Add or remove the host
default: 'present'
choices:
- 'present'
- 'absent'
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
Example from Ansible playbook
- name: Add ESXi Host to VCSA
local_action:
module: vmware_host
hostname: vcsa_host
username: vcsa_user
password: vcsa_pass
datacenter_name: datacenter_name
cluster_name: cluster_name
esxi_hostname: esxi_hostname
esxi_username: esxi_username
esxi_password: esxi_password
state: present
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareHost(object):
def __init__(self, module):
self.module = module
self.datacenter_name = module.params['datacenter_name']
self.cluster_name = module.params['cluster_name']
self.esxi_hostname = module.params['esxi_hostname']
self.esxi_username = module.params['esxi_username']
self.esxi_password = module.params['esxi_password']
self.state = module.params['state']
self.dc = None
self.cluster = None
self.host = None
self.content = connect_to_api(module)
def process_state(self):
try:
# Currently state_update_dvs is not implemented.
host_states = {
'absent': {
'present': self.state_remove_host,
'absent': self.state_exit_unchanged,
},
'present': {
'present': self.state_exit_unchanged,
'absent': self.state_add_host,
}
}
host_states[self.state][self.check_host_state()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def find_host_by_cluster_datacenter(self):
self.dc = find_datacenter_by_name(self.content, self.datacenter_name)
self.cluster = find_cluster_by_name_datacenter(self.dc, self.cluster_name)
for host in self.cluster.host:
if host.name == self.esxi_hostname:
return host, self.cluster
return None, self.cluster
def add_host_to_vcenter(self):
host_connect_spec = vim.host.ConnectSpec()
host_connect_spec.hostName = self.esxi_hostname
host_connect_spec.userName = self.esxi_username
host_connect_spec.password = self.esxi_password
host_connect_spec.force = True
host_connect_spec.sslThumbprint = ""
as_connected = True
esxi_license = None
resource_pool = None
try:
task = self.cluster.AddHost_Task(host_connect_spec, as_connected, resource_pool, esxi_license)
success, result = wait_for_task(task)
return success, result
except TaskError as add_task_error:
# This is almost certain to fail the first time.
# In order to get the sslThumbprint we first connect
# get the vim.fault.SSLVerifyFault then grab the sslThumbprint
# from that object.
#
# args is a tuple, selecting the first tuple
ssl_verify_fault = add_task_error.args[0]
host_connect_spec.sslThumbprint = ssl_verify_fault.thumbprint
task = self.cluster.AddHost_Task(host_connect_spec, as_connected, resource_pool, esxi_license)
success, result = wait_for_task(task)
return success, result
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_remove_host(self):
changed = True
result = None
if not self.module.check_mode:
if not self.host.runtime.inMaintenanceMode:
maintenance_mode_task = self.host.EnterMaintenanceMode_Task(300, True, None)
changed, result = wait_for_task(maintenance_mode_task)
if changed:
task = self.host.Destroy_Task()
changed, result = wait_for_task(task)
else:
raise Exception(result)
self.module.exit_json(changed=changed, result=str(result))
def state_update_host(self):
self.module.exit_json(changed=False, msg="Currently not implemented.")
def state_add_host(self):
changed = True
result = None
if not self.module.check_mode:
changed, result = self.add_host_to_vcenter()
self.module.exit_json(changed=changed, result=str(result))
def check_host_state(self):
self.host, self.cluster = self.find_host_by_cluster_datacenter()
if self.host is None:
return 'absent'
else:
return 'present'
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(datacenter_name=dict(required=True, type='str'),
cluster_name=dict(required=True, type='str'),
esxi_hostname=dict(required=True, type='str'),
esxi_username=dict(required=True, type='str'),
esxi_password=dict(required=True, type='str', no_log=True),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_host = VMwareHost(module)
vmware_host.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,195 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright IBM Corp. 2016
# Author(s): Andreas Nafpliotis <nafpliot@de.ibm.com>
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_local_user_manager
short_description: Manage local users on an ESXi host
description:
- Manage local users on an ESXi host
version_added: "2.2"
author: Andreas Nafpliotis
notes:
- Tested on ESXi 6.0
- Be sure that the ESXi user used for login, has the appropriate rights to create / delete / edit users
requirements:
- "python >= 2.6"
- PyVmomi installed
options:
local_user_name:
description:
- The local user name to be changed
required: True
local_user_password:
description:
- The password to be set
required: False
local_user_description:
description:
- Description for the user
required: False
state:
description:
- Indicate desired state of the user. If the user already exists when C(state=present), the user info is updated
choices: ['present', 'absent']
default: present
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_local_user_manager command from Ansible Playbooks
- name: Add local user to ESXi
local_action:
module: vmware_local_user_manager
hostname: esxi_hostname
username: root
password: vmware
local_user_name: foo
'''
RETURN = '''# '''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareLocalUserManager(object):
def __init__(self, module):
self.module = module
self.content = connect_to_api(self.module)
self.local_user_name = self.module.params['local_user_name']
self.local_user_password = self.module.params['local_user_password']
self.local_user_description = self.module.params['local_user_description']
self.state = self.module.params['state']
def process_state(self):
try:
local_account_manager_states = {
'absent': {
'present': self.state_remove_user,
'absent': self.state_exit_unchanged,
},
'present': {
'present': self.state_update_user,
'absent': self.state_create_user,
}
}
local_account_manager_states[self.state][self.check_local_user_manager_state()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def check_local_user_manager_state(self):
user_account = self.find_user_account()
if not user_account:
return 'absent'
else:
return 'present'
def find_user_account(self):
searchStr = self.local_user_name
exactMatch = True
findUsers = True
findGroups = False
user_account = self.content.userDirectory.RetrieveUserGroups(None, searchStr, None, None, exactMatch, findUsers, findGroups)
return user_account
def create_account_spec(self):
account_spec = vim.host.LocalAccountManager.AccountSpecification()
account_spec.id = self.local_user_name
account_spec.password = self.local_user_password
account_spec.description = self.local_user_description
return account_spec
def state_create_user(self):
account_spec = self.create_account_spec()
try:
task = self.content.accountManager.CreateUser(account_spec)
self.module.exit_json(changed=True)
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def state_update_user(self):
account_spec = self.create_account_spec()
try:
task = self.content.accountManager.UpdateUser(account_spec)
self.module.exit_json(changed=True)
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def state_remove_user(self):
try:
task = self.content.accountManager.RemoveUser(self.local_user_name)
self.module.exit_json(changed=True)
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(local_user_name=dict(required=True, type='str'),
local_user_password=dict(required=False, type='str', no_log=True),
local_user_description=dict(required=False, type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_local_user_manager = VMwareLocalUserManager(module)
vmware_local_user_manager.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,216 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, VMware, Inc.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_maintenancemode
short_description: Place a host into maintenance mode
description:
- Place an ESXI host into maintenance mode
- Support for VSAN compliant maintenance mode when selected
author: "Jay Jahns <jjahns@vmware.com>"
version_added: "2.1"
notes:
- Tested on vSphere 5.5 and 6.0
requirements:
- "python >= 2.6"
- PyVmomi
options:
esxi_hostname:
description:
- Name of the host as defined in vCenter
required: True
vsan_mode:
description:
- Specify which VSAN compliant mode to enter
choices:
- 'ensureObjectAccessibility'
- 'evacuateAllData'
- 'noAction'
required: False
evacuate:
description:
- If True, evacuate all powered off VMs
choices:
- True
- False
default: False
required: False
timeout:
description:
- Specify a timeout for the operation
required: False
default: 0
state:
description:
- Enter or exit maintenance mode
choices:
- present
- absent
default: present
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: Enter VSAN-Compliant Maintenance Mode
local_action:
module: vmware_maintenancemode
hostname: vc_host
username: vc_user
password: vc_pass
esxi_hostname: esxi.host.example
vsan: ensureObjectAccessibility
evacuate: yes
timeout: 3600
state: present
'''
RETURN = '''
hostsystem:
description: Name of vim reference
returned: always
type: string
sample: "'vim.HostSystem:host-236'"
hostname:
description: Name of host in vCenter
returned: always
type: string
sample: "esxi.local.domain"
status:
description: Action taken
return: always
type: string
sample: "ENTER"
'''
try:
from pyVmomi import vim
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def EnterMaintenanceMode(module, host):
if host.runtime.inMaintenanceMode:
module.exit_json(
changed=False,
hostsystem=str(host),
hostname=module.params['esxi_hostname'],
status='NO_ACTION',
msg='Host already in maintenance mode')
spec = vim.host.MaintenanceSpec()
if module.params['vsan']:
spec.vsanMode = vim.vsan.host.DecommissionMode()
spec.vsanMode.objectAction = module.params['vsan']
try:
task = host.EnterMaintenanceMode_Task(
module.params['timeout'],
module.params['evacuate'],
spec)
success, result = wait_for_task(task)
return dict(changed=success,
hostsystem=str(host),
hostname=module.params['esxi_hostname'],
status='ENTER',
msg='Host entered maintenance mode')
except TaskError:
module.fail_json(
msg='Host failed to enter maintenance mode')
def ExitMaintenanceMode(module, host):
if not host.runtime.inMaintenanceMode:
module.exit_json(
changed=False,
hostsystem=str(host),
hostname=module.params['esxi_hostname'],
status='NO_ACTION',
msg='Host not in maintenance mode')
try:
task = host.ExitMaintenanceMode_Task(
module.params['timeout'])
success, result = wait_for_task(task)
return dict(changed=success,
hostsystem=str(host),
hostname=module.params['esxi_hostname'],
status='EXIT',
msg='Host exited maintenance mode')
except TaskError:
module.fail_json(
msg='Host failed to exit maintenance mode')
def main():
spec = vmware_argument_spec()
spec.update(dict(
esxi_hostname=dict(required=True),
vsan=dict(required=False, choices=['ensureObjectAccessibility',
'evacuateAllData',
'noAction']),
evacuate=dict(required=False, type='bool', default=False),
timeout=dict(required=False, default=0, type='int'),
state=dict(required=False,
default='present',
choices=['present', 'absent'])))
module = AnsibleModule(argument_spec=spec)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
content = connect_to_api(module)
host = find_hostsystem_by_name(content, module.params['esxi_hostname'])
if not host:
module.fail_json(
msg='Host not found in vCenter')
if module.params['state'] == 'present':
result = EnterMaintenanceMode(module, host)
elif module.params['state'] == 'absent':
result = ExitMaintenanceMode(module, host)
module.exit_json(**result)
from ansible.module_utils.basic import *
from ansible.module_utils.vmware import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,200 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_migrate_vmk
short_description: Migrate a VMK interface from VSS to VDS
description:
- Migrate a VMK interface from VSS to VDS
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
esxi_hostname:
description:
- ESXi hostname to be managed
required: True
device:
description:
- VMK interface name
required: True
current_switch_name:
description:
- Switch VMK interface is currently on
required: True
current_portgroup_name:
description:
- Portgroup name VMK interface is currently on
required: True
migrate_switch_name:
description:
- Switch name to migrate VMK interface to
required: True
migrate_portgroup_name:
description:
- Portgroup name to migrate VMK interface to
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
Example from Ansible playbook
- name: Migrate Management vmk
local_action:
module: vmware_migrate_vmk
hostname: vcsa_host
username: vcsa_user
password: vcsa_pass
esxi_hostname: esxi_hostname
device: vmk1
current_switch_name: temp_vswitch
current_portgroup_name: esx-mgmt
migrate_switch_name: dvSwitch
migrate_portgroup_name: Management
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareMigrateVmk(object):
def __init__(self, module):
self.module = module
self.host_system = None
self.migrate_switch_name = self.module.params['migrate_switch_name']
self.migrate_portgroup_name = self.module.params['migrate_portgroup_name']
self.device = self.module.params['device']
self.esxi_hostname = self.module.params['esxi_hostname']
self.current_portgroup_name = self.module.params['current_portgroup_name']
self.current_switch_name = self.module.params['current_switch_name']
self.content = connect_to_api(module)
def process_state(self):
try:
vmk_migration_states = {
'migrate_vss_vds': self.state_migrate_vss_vds,
'migrate_vds_vss': self.state_migrate_vds_vss,
'migrated': self.state_exit_unchanged
}
vmk_migration_states[self.check_vmk_current_state()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_migrate_vds_vss(self):
self.module.exit_json(changed=False, msg="Currently Not Implemented")
def create_host_vnic_config(self, dv_switch_uuid, portgroup_key):
host_vnic_config = vim.host.VirtualNic.Config()
host_vnic_config.spec = vim.host.VirtualNic.Specification()
host_vnic_config.changeOperation = "edit"
host_vnic_config.device = self.device
host_vnic_config.portgroup = ""
host_vnic_config.spec.distributedVirtualPort = vim.dvs.PortConnection()
host_vnic_config.spec.distributedVirtualPort.switchUuid = dv_switch_uuid
host_vnic_config.spec.distributedVirtualPort.portgroupKey = portgroup_key
return host_vnic_config
def create_port_group_config(self):
port_group_config = vim.host.PortGroup.Config()
port_group_config.spec = vim.host.PortGroup.Specification()
port_group_config.changeOperation = "remove"
port_group_config.spec.name = self.current_portgroup_name
port_group_config.spec.vlanId = -1
port_group_config.spec.vswitchName = self.current_switch_name
port_group_config.spec.policy = vim.host.NetworkPolicy()
return port_group_config
def state_migrate_vss_vds(self):
host_network_system = self.host_system.configManager.networkSystem
dv_switch = find_dvs_by_name(self.content, self.migrate_switch_name)
pg = find_dvspg_by_name(dv_switch, self.migrate_portgroup_name)
config = vim.host.NetworkConfig()
config.portgroup = [self.create_port_group_config()]
config.vnic = [self.create_host_vnic_config(dv_switch.uuid, pg.key)]
host_network_system.UpdateNetworkConfig(config, "modify")
self.module.exit_json(changed=True)
def check_vmk_current_state(self):
self.host_system = find_hostsystem_by_name(self.content, self.esxi_hostname)
for vnic in self.host_system.configManager.networkSystem.networkInfo.vnic:
if vnic.device == self.device:
#self.vnic = vnic
if vnic.spec.distributedVirtualPort is None:
if vnic.portgroup == self.current_portgroup_name:
return "migrate_vss_vds"
else:
dvs = find_dvs_by_name(self.content, self.current_switch_name)
if dvs is None:
return "migrated"
if vnic.spec.distributedVirtualPort.switchUuid == dvs.uuid:
return "migrate_vds_vss"
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(esxi_hostname=dict(required=True, type='str'),
device=dict(required=True, type='str'),
current_switch_name=dict(required=True, type='str'),
current_portgroup_name=dict(required=True, type='str'),
migrate_switch_name=dict(required=True, type='str'),
migrate_portgroup_name=dict(required=True, type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
self.module.fail_json(msg='pyvmomi required for this module')
vmware_migrate_vmk = VMwareMigrateVmk(module)
vmware_migrate_vmk.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,167 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_portgroup
short_description: Create a VMware portgroup
description:
- Create a VMware portgroup
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
switch_name:
description:
- vSwitch to modify
required: True
portgroup_name:
description:
- Portgroup name to add
required: True
vlan_id:
description:
- VLAN ID to assign to portgroup
required: True
network_policy:
description:
- Network policy specifies layer 2 security settings for a
portgroup such as promiscuous mode, where guest adapter listens
to all the packets, MAC address changes and forged transmits.
Settings are promiscuous_mode, forged_transmits, mac_changes
required: False
version_added: "2.2"
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
Example from Ansible playbook
- name: Add Management Network VM Portgroup
local_action:
module: vmware_portgroup
hostname: esxi_hostname
username: esxi_username
password: esxi_password
switch_name: vswitch_name
portgroup_name: portgroup_name
vlan_id: vlan_id
- name: Add Portgroup with Promiscuous Mode Enabled
local_action:
module: vmware_portgroup
hostname: esxi_hostname
username: esxi_username
password: esxi_password
switch_name: vswitch_name
portgroup_name: portgroup_name
network_policy:
promiscuous_mode: True
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def create_network_policy(promiscuous_mode, forged_transmits, mac_changes):
security_policy = vim.host.NetworkPolicy.SecurityPolicy()
if promiscuous_mode:
security_policy.allowPromiscuous = promiscuous_mode
if forged_transmits:
security_policy.forgedTransmits = forged_transmits
if mac_changes:
security_policy.macChanges = mac_changes
network_policy = vim.host.NetworkPolicy(security=security_policy)
return network_policy
def create_port_group(host_system, portgroup_name, vlan_id, vswitch_name, network_policy):
config = vim.host.NetworkConfig()
config.portgroup = [vim.host.PortGroup.Config()]
config.portgroup[0].changeOperation = "add"
config.portgroup[0].spec = vim.host.PortGroup.Specification()
config.portgroup[0].spec.name = portgroup_name
config.portgroup[0].spec.vlanId = vlan_id
config.portgroup[0].spec.vswitchName = vswitch_name
config.portgroup[0].spec.policy = network_policy
host_network_config_result = host_system.configManager.networkSystem.UpdateNetworkConfig(config, "modify")
return True
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),
switch_name=dict(required=True, type='str'),
vlan_id=dict(required=True, type='int'),
network_policy=dict(required=False, type='dict', default={})))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
portgroup_name = module.params['portgroup_name']
switch_name = module.params['switch_name']
vlan_id = module.params['vlan_id']
promiscuous_mode = module.params['network_policy'].get('promiscuous_mode', None)
forged_transmits = module.params['network_policy'].get('forged_transmits', None)
mac_changes = module.params['network_policy'].get('mac_changes', None)
try:
content = connect_to_api(module)
host = get_all_objs(content, [vim.HostSystem])
if not host:
raise SystemExit("Unable to locate Physical Host.")
host_system = host.keys()[0]
if find_host_portgroup_by_name(host_system, portgroup_name):
module.exit_json(changed=False)
network_policy = create_network_policy(promiscuous_mode, forged_transmits, mac_changes)
changed = create_port_group(host_system, portgroup_name, vlan_id, switch_name, network_policy)
module.exit_json(changed=changed)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,99 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_target_canonical_facts
short_description: Return canonical (NAA) from an ESXi host
description:
- Return canonical (NAA) from an ESXi host based on SCSI target ID
version_added: "2.0"
author: Joseph Callen
notes:
requirements:
- Tested on vSphere 5.5
- PyVmomi installed
options:
target_id:
description:
- The target id based on order of scsi device
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example vmware_target_canonical_facts command from Ansible Playbooks
- name: Get Canonical name
local_action: >
vmware_target_canonical_facts
hostname="{{ ansible_ssh_host }}" username=root password=vmware
target_id=7
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def find_hostsystem(content):
host_system = get_all_objs(content, [vim.HostSystem])
for host in host_system:
return host
return None
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(target_id=dict(required=True, type='int')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
content = connect_to_api(module)
host = find_hostsystem(content)
target_lun_uuid = {}
scsilun_canonical = {}
# Associate the scsiLun key with the canonicalName (NAA)
for scsilun in host.config.storageDevice.scsiLun:
scsilun_canonical[scsilun.key] = scsilun.canonicalName
# Associate target number with LUN uuid
for target in host.config.storageDevice.scsiTopology.adapter[0].target:
for lun in target.lun:
target_lun_uuid[target.target] = lun.scsiLun
module.exit_json(changed=False, canonical=scsilun_canonical[target_lun_uuid[module.params['target_id']]])
from ansible.module_utils.basic import *
from ansible.module_utils.vmware import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,105 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vm_facts
short_description: Return basic facts pertaining to a vSphere virtual machine guest
description:
- Return basic facts pertaining to a vSphere virtual machine guest
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: Gather all registered virtual machines
local_action:
module: vmware_vm_facts
hostname: esxi_or_vcenter_ip_or_hostname
username: username
password: password
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
# https://github.com/vmware/pyvmomi-community-samples/blob/master/samples/getallvms.py
def get_all_virtual_machines(content):
virtual_machines = get_all_objs(content, [vim.VirtualMachine])
_virtual_machines = {}
for vm in virtual_machines:
_ip_address = ""
summary = vm.summary
if summary.guest is not None:
_ip_address = summary.guest.ipAddress
if _ip_address is None:
_ip_address = ""
virtual_machine = {
summary.config.name: {
"guest_fullname": summary.config.guestFullName,
"power_state": summary.runtime.powerState,
"ip_address": _ip_address
}
}
_virtual_machines.update(virtual_machine)
return _virtual_machines
def main():
argument_spec = vmware_argument_spec()
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
try:
content = connect_to_api(module)
_virtual_machines = get_all_virtual_machines(content)
module.exit_json(changed=False, virtual_machines=_virtual_machines)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,190 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, 2016 Ritesh Khadgaray <khadgaray () gmail.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vm_shell
short_description: Execute a process in VM
description:
- Start a program in a VM without the need for network connection
version_added: 2.1
author: "Ritesh Khadgaray (@ritzk)"
notes:
- Tested on vSphere 5.5
- Only the first match against vm_id is used, even if there are multiple matches
requirements:
- "python >= 2.6"
- PyVmomi
options:
datacenter:
description:
- The datacenter hosting the VM
- Will help speed up search
required: False
default: None
cluster:
description:
- The cluster hosting the VM
- Will help speed up search
required: False
default: None
vm_id:
description:
- The identification for the VM
required: True
vm_id_type:
description:
- The identification tag for the VM
default: vm_name
choices:
- 'uuid'
- 'dns_name'
- 'inventory_path'
- 'vm_name'
required: False
vm_username:
description:
- The user to connect to the VM.
required: False
default: None
vm_password:
description:
- The password used to login to the VM.
required: False
default: None
vm_shell:
description:
- The absolute path to the program to start. On Linux this is executed via bash.
required: True
vm_shell_args:
description:
- The argument to the program.
required: False
default: None
vm_shell_env:
description:
- Comma seperated list of envirnoment variable, specified in the guest OS notation
required: False
default: None
vm_shell_cwd:
description:
- The current working directory of the application from which it will be run
required: False
default: None
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: shell execution
local_action:
module: vmware_vm_shell
hostname: myVSphere
username: myUsername
password: mySecret
datacenter: myDatacenter
vm_id: NameOfVM
vm_username: root
vm_password: superSecret
vm_shell: /bin/echo
vm_shell_args: " $var >> myFile "
vm_shell_env:
- "PATH=/bin"
- "VAR=test"
vm_shell_cwd: "/tmp"
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
# https://github.com/vmware/pyvmomi-community-samples/blob/master/samples/execute_program_in_vm.py
def execute_command(content, vm, vm_username, vm_password, program_path, args="", env=None, cwd=None):
creds = vim.vm.guest.NamePasswordAuthentication(username=vm_username, password=vm_password)
cmdspec = vim.vm.guest.ProcessManager.ProgramSpec(arguments=args, envVariables=env, programPath=program_path, workingDirectory=cwd)
cmdpid = content.guestOperationsManager.processManager.StartProgramInGuest(vm=vm, auth=creds, spec=cmdspec)
return cmdpid
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(datacenter=dict(default=None, type='str'),
cluster=dict(default=None, type='str'),
vm_id=dict(required=True, type='str'),
vm_id_type=dict(default='vm_name', type='str', choices=['inventory_path', 'uuid', 'dns_name', 'vm_name']),
vm_username=dict(required=False, type='str'),
vm_password=dict(required=False, type='str', no_log=True),
vm_shell=dict(required=True, type='str'),
vm_shell_args=dict(default=" ", type='str'),
vm_shell_env=dict(default=None, type='list'),
vm_shell_cwd=dict(default=None, type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(changed=False, msg='pyvmomi is required for this module')
try:
p = module.params
datacenter_name = p['datacenter']
cluster_name = p['cluster']
content = connect_to_api(module)
datacenter = None
if datacenter_name:
datacenter = find_datacenter_by_name(content, datacenter_name)
if not datacenter:
module.fail_json(changed=False, msg="datacenter not found")
cluster = None
if cluster_name:
cluster = find_cluster_by_name(content, cluster_name, datacenter)
if not cluster:
module.fail_json(changed=False, msg="cluster not found")
vm = find_vm_by_id(content, p['vm_id'], p['vm_id_type'], datacenter, cluster)
if not vm:
module.fail_json(msg='VM not found')
msg = execute_command(content, vm, p['vm_username'], p['vm_password'],
p['vm_shell'], p['vm_shell_args'], p['vm_shell_env'], p['vm_shell_cwd'])
module.exit_json(changed=True, uuid=vm.summary.config.uuid, msg=msg)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(changed=False, msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(changed=False, msg=method_fault.msg)
except Exception as e:
module.fail_json(changed=False, msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,162 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vm_vss_dvs_migrate
short_description: Migrates a virtual machine from a standard vswitch to distributed
description:
- Migrates a virtual machine from a standard vswitch to distributed
version_added: 2.0
author: "Joseph Callen (@jcpowermac)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
vm_name:
description:
- Name of the virtual machine to migrate to a dvSwitch
required: True
dvportgroup_name:
description:
- Name of the portgroup to migrate to the virtual machine to
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
- name: Migrate VCSA to vDS
local_action:
module: vmware_vm_vss_dvs_migrate
hostname: vcenter_ip_or_hostname
username: vcenter_username
password: vcenter_password
vm_name: virtual_machine_name
dvportgroup_name: distributed_portgroup_name
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
class VMwareVmVssDvsMigrate(object):
def __init__(self, module):
self.module = module
self.content = connect_to_api(module)
self.vm = None
self.vm_name = module.params['vm_name']
self.dvportgroup_name = module.params['dvportgroup_name']
def process_state(self):
vm_nic_states = {
'absent': self.migrate_network_adapter_vds,
'present': self.state_exit_unchanged,
}
vm_nic_states[self.check_vm_network_state()]()
def find_dvspg_by_name(self):
vmware_distributed_port_group = get_all_objs(self.content, [vim.dvs.DistributedVirtualPortgroup])
for dvspg in vmware_distributed_port_group:
if dvspg.name == self.dvportgroup_name:
return dvspg
return None
def find_vm_by_name(self):
virtual_machines = get_all_objs(self.content, [vim.VirtualMachine])
for vm in virtual_machines:
if vm.name == self.vm_name:
return vm
return None
def migrate_network_adapter_vds(self):
vm_configspec = vim.vm.ConfigSpec()
nic = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
port = vim.dvs.PortConnection()
devicespec = vim.vm.device.VirtualDeviceSpec()
pg = self.find_dvspg_by_name()
if pg is None:
self.module.fail_json(msg="The standard portgroup was not found")
dvswitch = pg.config.distributedVirtualSwitch
port.switchUuid = dvswitch.uuid
port.portgroupKey = pg.key
nic.port = port
for device in self.vm.config.hardware.device:
if isinstance(device, vim.vm.device.VirtualEthernetCard):
devicespec.device = device
devicespec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
devicespec.device.backing = nic
vm_configspec.deviceChange.append(devicespec)
task = self.vm.ReconfigVM_Task(vm_configspec)
changed, result = wait_for_task(task)
self.module.exit_json(changed=changed, result=result)
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def check_vm_network_state(self):
try:
self.vm = self.find_vm_by_name()
if self.vm is None:
self.module.fail_json(msg="A virtual machine with name %s does not exist" % self.vm_name)
for device in self.vm.config.hardware.device:
if isinstance(device, vim.vm.device.VirtualEthernetCard):
if isinstance(device.backing, vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo):
return 'present'
return 'absent'
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(vm_name=dict(required=True, type='str'),
dvportgroup_name=dict(required=True, type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmware_vmnic_migrate = VMwareVmVssDvsMigrate(module)
vmware_vmnic_migrate.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,212 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vmkernel
short_description: Create a VMware VMkernel Interface
description:
- Create a VMware VMkernel Interface
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
vswitch_name:
description:
- The name of the vswitch where to add the VMK interface
required: True
portgroup_name:
description:
- The name of the portgroup for the VMK interface
required: True
ip_address:
description:
- The IP Address for the VMK interface
required: True
subnet_mask:
description:
- The Subnet Mask for the VMK interface
required: True
vland_id:
description:
- The VLAN ID for the VMK interface
required: True
mtu:
description:
- The MTU for the VMK interface
required: False
enable_vsan:
description:
- Enable the VMK interface for VSAN traffic
required: False
enable_vmotion:
description:
- Enable the VMK interface for vMotion traffic
required: False
enable_mgmt:
description:
- Enable the VMK interface for Management traffic
required: False
enable_ft:
description:
- Enable the VMK interface for Fault Tolerance traffic
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example command from Ansible Playbook
- name: Add Management vmkernel port (vmk1)
local_action:
module: vmware_vmkernel
hostname: esxi_hostname
username: esxi_username
password: esxi_password
vswitch_name: vswitch_name
portgroup_name: portgroup_name
vlan_id: vlan_id
ip_address: ip_address
subnet_mask: subnet_mask
enable_mgmt: True
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def create_vmkernel_adapter(host_system, port_group_name,
vlan_id, vswitch_name,
ip_address, subnet_mask,
mtu, enable_vsan, enable_vmotion, enable_mgmt, enable_ft):
host_config_manager = host_system.configManager
host_network_system = host_config_manager.networkSystem
host_virtual_vic_manager = host_config_manager.virtualNicManager
config = vim.host.NetworkConfig()
config.portgroup = [vim.host.PortGroup.Config()]
config.portgroup[0].changeOperation = "add"
config.portgroup[0].spec = vim.host.PortGroup.Specification()
config.portgroup[0].spec.name = port_group_name
config.portgroup[0].spec.vlanId = vlan_id
config.portgroup[0].spec.vswitchName = vswitch_name
config.portgroup[0].spec.policy = vim.host.NetworkPolicy()
config.vnic = [vim.host.VirtualNic.Config()]
config.vnic[0].changeOperation = "add"
config.vnic[0].portgroup = port_group_name
config.vnic[0].spec = vim.host.VirtualNic.Specification()
config.vnic[0].spec.ip = vim.host.IpConfig()
config.vnic[0].spec.ip.dhcp = False
config.vnic[0].spec.ip.ipAddress = ip_address
config.vnic[0].spec.ip.subnetMask = subnet_mask
if mtu:
config.vnic[0].spec.mtu = mtu
host_network_config_result = host_network_system.UpdateNetworkConfig(config, "modify")
for vnic_device in host_network_config_result.vnicDevice:
if enable_vsan:
vsan_system = host_config_manager.vsanSystem
vsan_config = vim.vsan.host.ConfigInfo()
vsan_config.networkInfo = vim.vsan.host.ConfigInfo.NetworkInfo()
vsan_config.networkInfo.port = [vim.vsan.host.ConfigInfo.NetworkInfo.PortConfig()]
vsan_config.networkInfo.port[0].device = vnic_device
host_vsan_config_result = vsan_system.UpdateVsan_Task(vsan_config)
if enable_vmotion:
host_virtual_vic_manager.SelectVnicForNicType("vmotion", vnic_device)
if enable_mgmt:
host_virtual_vic_manager.SelectVnicForNicType("management", vnic_device)
if enable_ft:
host_virtual_vic_manager.SelectVnicForNicType("faultToleranceLogging", vnic_device)
return True
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),
ip_address=dict(required=True, type='str'),
subnet_mask=dict(required=True, type='str'),
mtu=dict(required=False, type='int'),
enable_vsan=dict(required=False, type='bool'),
enable_vmotion=dict(required=False, type='bool'),
enable_mgmt=dict(required=False, type='bool'),
enable_ft=dict(required=False, type='bool'),
vswitch_name=dict(required=True, type='str'),
vlan_id=dict(required=True, type='int')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
port_group_name = module.params['portgroup_name']
ip_address = module.params['ip_address']
subnet_mask = module.params['subnet_mask']
mtu = module.params['mtu']
enable_vsan = module.params['enable_vsan']
enable_vmotion = module.params['enable_vmotion']
enable_mgmt = module.params['enable_mgmt']
enable_ft = module.params['enable_ft']
vswitch_name = module.params['vswitch_name']
vlan_id = module.params['vlan_id']
try:
content = connect_to_api(module)
host = get_all_objs(content, [vim.HostSystem])
if not host:
module.fail_json(msg="Unable to locate Physical Host.")
host_system = host.keys()[0]
changed = create_vmkernel_adapter(host_system, port_group_name,
vlan_id, vswitch_name,
ip_address, subnet_mask,
mtu, enable_vsan, enable_vmotion, enable_mgmt, enable_ft)
module.exit_json(changed=changed)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,127 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vmkernel_ip_config
short_description: Configure the VMkernel IP Address
description:
- Configure the VMkernel IP Address
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
vmk_name:
description:
- VMkernel interface name
required: True
ip_address:
description:
- IP address to assign to VMkernel interface
required: True
subnet_mask:
description:
- Subnet Mask to assign to VMkernel interface
required: True
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example command from Ansible Playbook
- name: Configure IP address on ESX host
local_action:
module: vmware_vmkernel_ip_config
hostname: esxi_hostname
username: esxi_username
password: esxi_password
vmk_name: vmk0
ip_address: 10.0.0.10
subnet_mask: 255.255.255.0
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def configure_vmkernel_ip_address(host_system, vmk_name, ip_address, subnet_mask):
host_config_manager = host_system.configManager
host_network_system = host_config_manager.networkSystem
for vnic in host_network_system.networkConfig.vnic:
if vnic.device == vmk_name:
spec = vnic.spec
if spec.ip.ipAddress != ip_address:
spec.ip.dhcp = False
spec.ip.ipAddress = ip_address
spec.ip.subnetMask = subnet_mask
host_network_system.UpdateVirtualNic(vmk_name, spec)
return True
return False
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(vmk_name=dict(required=True, type='str'),
ip_address=dict(required=True, type='str'),
subnet_mask=dict(required=True, type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
vmk_name = module.params['vmk_name']
ip_address = module.params['ip_address']
subnet_mask = module.params['subnet_mask']
try:
content = connect_to_api(module, False)
host = get_all_objs(content, [vim.HostSystem])
if not host:
module.fail_json(msg="Unable to locate Physical Host.")
host_system = host.keys()[0]
changed = configure_vmkernel_ip_address(host_system, vmk_name, ip_address, subnet_mask)
module.exit_json(changed=changed)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,154 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Bede Carroll <bc+github () bedecarroll.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vmotion
short_description: Move a virtual machine using vMotion
description:
- Using VMware vCenter, move a virtual machine using vMotion to a different
host.
version_added: 2.2
author: "Bede Carroll (@bedecarroll)"
notes:
- Tested on vSphere 6.0
requirements:
- "python >= 2.6"
- pyVmomi
options:
vm_name:
description:
- Name of the VM to perform a vMotion on
required: True
aliases: ['vm']
destination_host:
description:
- Name of the end host the VM should be running on
required: True
aliases: ['destination']
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
Example from Ansible playbook
- name: Perform vMotion of VM
local_action:
module: vmware_vmotion
hostname: 'vcenter_hostname'
username: 'vcenter_username'
password: 'vcenter_password'
validate_certs: False
vm_name: 'vm_name_as_per_vcenter'
destination_host: 'destination_host_as_per_vcenter'
'''
RETURN = '''
running_host:
description: List the host the virtual machine is registered to
returned:
- changed
- success
type: string
sample: 'host1.example.com'
'''
try:
from pyVmomi import vim
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def migrate_vm(vm_object, host_object):
"""
Migrate virtual machine and return the task.
"""
relocate_spec = vim.vm.RelocateSpec(host=host_object)
task_object = vm_object.Relocate(relocate_spec)
return task_object
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(
dict(
vm_name=dict(required=True, aliases=['vm'], type='str'),
destination_host=dict(required=True, aliases=['destination'], type='str'),
)
)
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_PYVMOMI:
module.fail_json(msg='pyVmomi is required for this module')
content = connect_to_api(module=module)
vm_object = find_vm_by_name(content=content, vm_name=module.params['vm_name'])
host_object = find_hostsystem_by_name(content=content, hostname=module.params['destination_host'])
# Setup result
result = {
'changed': False
}
# Check if we could find the VM or Host
if not vm_object:
module.fail_json(msg='Cannot find virtual machine')
if not host_object:
module.fail_json(msg='Cannot find host')
# Make sure VM isn't already at the destination
if vm_object.runtime.host.name == module.params['destination_host']:
module.exit_json(**result)
if not module.check_mode:
# Migrate VM and get Task object back
task_object = migrate_vm(vm_object=vm_object, host_object=host_object)
# Wait for task to complete
wait_for_task(task_object)
# If task was a success the VM has moved, update running_host and complete module
if task_object.info.state == vim.TaskInfo.State.success:
vm_object = find_vm_by_name(content=content, vm_name=module.params['vm_name'])
result['running_host'] = vm_object.runtime.host.name
result['changed'] = True
module.exit_json(**result)
else:
if task_object.info.error is None:
module.fail_json(msg='Unable to migrate VM due to an error, please check vCenter')
else:
module.fail_json(msg='Unable to migrate VM due to an error: %s' % task_object.info.error)
else:
# If we are in check mode return a result as if move was performed
result['running_host'] = module.params['destination_host']
result['changed'] = True
module.exit_json(**result)
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,134 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Russell Teague <rteague2 () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vsan_cluster
short_description: Configure VSAN clustering on an ESXi host
description:
- This module can be used to configure VSAN clustering on an ESXi host
version_added: 2.0
author: "Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
cluster_uuid:
description:
- Desired cluster UUID
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
# Example command from Ansible Playbook
- name: Configure VMware VSAN Cluster
hosts: deploy_node
gather_facts: False
tags:
- vsan
tasks:
- name: Configure VSAN on first host
vmware_vsan_cluster:
hostname: "{{ groups['esxi'][0] }}"
username: "{{ esxi_username }}"
password: "{{ site_password }}"
register: vsan_cluster
- name: Configure VSAN on remaining hosts
vmware_vsan_cluster:
hostname: "{{ item }}"
username: "{{ esxi_username }}"
password: "{{ site_password }}"
cluster_uuid: "{{ vsan_cluster.cluster_uuid }}"
with_items: "{{ groups['esxi'][1:] }}"
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def create_vsan_cluster(host_system, new_cluster_uuid):
host_config_manager = host_system.configManager
vsan_system = host_config_manager.vsanSystem
vsan_config = vim.vsan.host.ConfigInfo()
vsan_config.enabled = True
if new_cluster_uuid is not None:
vsan_config.clusterInfo = vim.vsan.host.ConfigInfo.ClusterInfo()
vsan_config.clusterInfo.uuid = new_cluster_uuid
vsan_config.storageInfo = vim.vsan.host.ConfigInfo.StorageInfo()
vsan_config.storageInfo.autoClaimStorage = True
task = vsan_system.UpdateVsan_Task(vsan_config)
changed, result = wait_for_task(task)
host_status = vsan_system.QueryHostStatus()
cluster_uuid = host_status.uuid
return changed, result, cluster_uuid
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(cluster_uuid=dict(required=False, type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
new_cluster_uuid = module.params['cluster_uuid']
try:
content = connect_to_api(module, False)
host = get_all_objs(content, [vim.HostSystem])
if not host:
module.fail_json(msg="Unable to locate Physical Host.")
host_system = host.keys()[0]
changed, result, cluster_uuid = create_vsan_cluster(host_system, new_cluster_uuid)
module.exit_json(changed=changed, result=result, cluster_uuid=cluster_uuid)
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
module.fail_json(msg=method_fault.msg)
except Exception as e:
module.fail_json(msg=str(e))
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,203 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2015, Joseph Callen <jcallen () csc.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vmware_vswitch
short_description: Add a VMware Standard Switch to an ESXi host
description:
- Add a VMware Standard Switch to an ESXi host
version_added: 2.0
author: "Joseph Callen (@jcpowermac), Russell Teague (@mtnbikenc)"
notes:
- Tested on vSphere 5.5
requirements:
- "python >= 2.6"
- PyVmomi
options:
switch_name:
description:
- vSwitch name to add
required: True
nic_name:
description:
- vmnic name to attach to vswitch
required: True
number_of_ports:
description:
- Number of port to configure on vswitch
default: 128
required: False
mtu:
description:
- MTU to configure on vswitch
required: False
state:
description:
- Add or remove the switch
default: 'present'
choices:
- 'present'
- 'absent'
required: False
extends_documentation_fragment: vmware.documentation
'''
EXAMPLES = '''
Example from Ansible playbook
- name: Add a VMware vSwitch
local_action:
module: vmware_vswitch
hostname: esxi_hostname
username: esxi_username
password: esxi_password
switch_name: vswitch_name
nic_name: vmnic_name
mtu: 9000
'''
try:
from pyVmomi import vim, vmodl
HAS_PYVMOMI = True
except ImportError:
HAS_PYVMOMI = False
def find_vswitch_by_name(host, vswitch_name):
for vss in host.config.network.vswitch:
if vss.name == vswitch_name:
return vss
return None
class VMwareHostVirtualSwitch(object):
def __init__(self, module):
self.host_system = None
self.content = None
self.vss = None
self.module = module
self.switch_name = module.params['switch_name']
self.number_of_ports = module.params['number_of_ports']
self.nic_name = module.params['nic_name']
self.mtu = module.params['mtu']
self.state = module.params['state']
self.content = connect_to_api(self.module)
def process_state(self):
try:
vswitch_states = {
'absent': {
'present': self.state_destroy_vswitch,
'absent': self.state_exit_unchanged,
},
'present': {
'update': self.state_update_vswitch,
'present': self.state_exit_unchanged,
'absent': self.state_create_vswitch,
}
}
vswitch_states[self.state][self.check_vswitch_configuration()]()
except vmodl.RuntimeFault as runtime_fault:
self.module.fail_json(msg=runtime_fault.msg)
except vmodl.MethodFault as method_fault:
self.module.fail_json(msg=method_fault.msg)
except Exception as e:
self.module.fail_json(msg=str(e))
# Source from
# https://github.com/rreubenur/pyvmomi-community-samples/blob/patch-1/samples/create_vswitch.py
def state_create_vswitch(self):
vss_spec = vim.host.VirtualSwitch.Specification()
vss_spec.numPorts = self.number_of_ports
vss_spec.mtu = self.mtu
vss_spec.bridge = vim.host.VirtualSwitch.BondBridge(nicDevice=[self.nic_name])
self.host_system.configManager.networkSystem.AddVirtualSwitch(vswitchName=self.switch_name, spec=vss_spec)
self.module.exit_json(changed=True)
def state_exit_unchanged(self):
self.module.exit_json(changed=False)
def state_destroy_vswitch(self):
config = vim.host.NetworkConfig()
for portgroup in self.host_system.configManager.networkSystem.networkInfo.portgroup:
if portgroup.spec.vswitchName == self.vss.name:
portgroup_config = vim.host.PortGroup.Config()
portgroup_config.changeOperation = "remove"
portgroup_config.spec = vim.host.PortGroup.Specification()
portgroup_config.spec.name = portgroup.spec.name
portgroup_config.spec.name = portgroup.spec.name
portgroup_config.spec.vlanId = portgroup.spec.vlanId
portgroup_config.spec.vswitchName = portgroup.spec.vswitchName
portgroup_config.spec.policy = vim.host.NetworkPolicy()
config.portgroup.append(portgroup_config)
self.host_system.configManager.networkSystem.UpdateNetworkConfig(config, "modify")
self.host_system.configManager.networkSystem.RemoveVirtualSwitch(self.vss.name)
self.module.exit_json(changed=True)
def state_update_vswitch(self):
self.module.exit_json(changed=False, msg="Currently not implemented.")
def check_vswitch_configuration(self):
host = get_all_objs(self.content, [vim.HostSystem])
if not host:
self.module.fail_json(msg="Unable to find host")
self.host_system = host.keys()[0]
self.vss = find_vswitch_by_name(self.host_system, self.switch_name)
if self.vss is None:
return 'absent'
else:
return 'present'
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(switch_name=dict(required=True, type='str'),
nic_name=dict(required=True, type='str'),
number_of_ports=dict(required=False, type='int', default=128),
mtu=dict(required=False, type='int', default=1500),
state=dict(default='present', choices=['present', 'absent'], type='str')))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi is required for this module')
host_virtual_switch = VMwareHostVirtualSwitch(module)
host_virtual_switch.process_state()
from ansible.module_utils.vmware import *
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,195 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2015 Dag Wieers <dag@wieers.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: vsphere_copy
short_description: Copy a file to a vCenter datastore
description:
- Upload files to a vCenter datastore
version_added: 2.0
author: Dag Wieers (@dagwieers) <dag@wieers.com>
options:
host:
description:
- The vCenter server on which the datastore is available.
required: true
login:
description:
- The login name to authenticate on the vCenter server.
required: true
password:
description:
- The password to authenticate on the vCenter server.
required: true
src:
description:
- The file to push to vCenter
required: true
datacenter:
description:
- The datacenter on the vCenter server that holds the datastore.
required: true
datastore:
description:
- The datastore on the vCenter server to push files to.
required: true
path:
description:
- The file to push to the datastore on the vCenter server.
required: true
validate_certs:
description:
- If C(no), SSL certificates will not be validated. This should only be
set to C(no) when no other option exists.
required: false
default: 'yes'
choices: ['yes', 'no']
notes:
- "This module ought to be run from a system that can access vCenter directly and has the file to transfer.
It can be the normal remote target or you can change it either by using C(transport: local) or using C(delegate_to)."
- Tested on vSphere 5.5
'''
EXAMPLES = '''
- vsphere_copy:
host: vhost
login: vuser
password: vpass
src: /some/local/file
datacenter: DC1 Someplace
datastore: datastore1
path: some/remote/file
transport: local
- vsphere_copy:
host: vhost
login: vuser
password: vpass
src: /other/local/file
datacenter: DC2 Someplace
datastore: datastore2
path: other/remote/file
delegate_to: other_system
'''
import atexit
import urllib
import mmap
import errno
import socket
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.pycompat24 import get_exception
from ansible.module_utils.urls import open_url
def vmware_path(datastore, datacenter, path):
''' Constructs a URL path that VSphere accepts reliably '''
path = "/folder/%s" % path.lstrip("/")
# Due to a software bug in vSphere, it fails to handle ampersand in datacenter names
# The solution is to do what vSphere does (when browsing) and double-encode ampersands, maybe others ?
datacenter = datacenter.replace('&', '%26')
if not path.startswith("/"):
path = "/" + path
params = dict( dsName = datastore )
if datacenter:
params["dcPath"] = datacenter
params = urllib.urlencode(params)
return "%s?%s" % (path, params)
def main():
module = AnsibleModule(
argument_spec = dict(
host = dict(required=True, aliases=[ 'hostname' ]),
login = dict(required=True, aliases=[ 'username' ]),
password = dict(required=True, no_log=True),
src = dict(required=True, aliases=[ 'name' ]),
datacenter = dict(required=True),
datastore = dict(required=True),
dest = dict(required=True, aliases=[ 'path' ]),
validate_certs = dict(required=False, default=True, type='bool'),
),
# Implementing check-mode using HEAD is impossible, since size/date is not 100% reliable
supports_check_mode = False,
)
host = module.params.get('host')
login = module.params.get('login')
password = module.params.get('password')
src = module.params.get('src')
datacenter = module.params.get('datacenter')
datastore = module.params.get('datastore')
dest = module.params.get('dest')
validate_certs = module.params.get('validate_certs')
fd = open(src, "rb")
atexit.register(fd.close)
data = mmap.mmap(fd.fileno(), 0, access=mmap.ACCESS_READ)
atexit.register(data.close)
remote_path = vmware_path(datastore, datacenter, dest)
url = 'https://%s%s' % (host, remote_path)
headers = {
"Content-Type": "application/octet-stream",
"Content-Length": str(len(data)),
}
try:
r = open_url(url, data=data, headers=headers, method='PUT',
url_username=login, url_password=password, validate_certs=validate_certs,
force_basic_auth=True)
except socket.error:
e = get_exception()
if isinstance(e.args, tuple) and e[0] == errno.ECONNRESET:
# VSphere resets connection if the file is in use and cannot be replaced
module.fail_json(msg='Failed to upload, image probably in use', status=None, errno=e[0], reason=str(e), url=url)
else:
module.fail_json(msg=str(e), status=None, errno=e[0], reason=str(e), url=url)
except Exception:
e = get_exception()
error_code = -1
try:
if isinstance(e[0], int):
error_code = e[0]
except KeyError:
pass
module.fail_json(msg=str(e), status=None, errno=error_code, reason=str(e), url=url)
status = r.getcode()
if 200 <= status < 300:
module.exit_json(changed=True, status=status, reason=r.msg, url=url)
else:
length = r.headers.get('content-length', None)
if r.headers.get('transfer-encoding', '').lower() == 'chunked':
chunked = 1
else:
chunked = 0
module.fail_json(msg='Failed to upload', errno=None, status=status, reason=r.msg, length=length, headers=dict(r.headers), chunked=chunked, url=url)
if __name__ == '__main__':
main()