#!/usr/bin/env python # Copyright 2014, Rackspace US, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DOCUMENTATION=''' --- module: neutron short_description: - Basic module for interacting with openstack neutron description: - Basic module for interacting with openstack neutron options: command: description: - Operation for the module to perform. Currently available choices: - create_network_with_subnet openrc_path: decription: - Path to openrc file from which credentials and keystone endpoint will be extracted network_name: description: - Name of the image to create cidr: description: - cidr to use for the subnet author: Hugh Saunders ''' EXAMPLES = ''' # Create a subnet with parent network - name: Ensure tempest network exists neutron: command: create_network_with_subnet openrc_path: /root/openrc network_name: tempest cidr: "192.168.74.0/24" ''' import re import keystoneclient.v2_0.client as ksclient from neutronclient.neutron import client as nclient COMMAND_MAP = {'create_network_with_subnet': 'create_subnet'} class ManageNeutron(object): def __init__(self, module): self.state_change = False self.neutron = None self.keystone = None self.module = module try: self._keystone_authenticate() self._init_neutron() except Exception as e: self.module.fail_json( err="Initialisation Error: %s" % e, rc=2, msg=str(e)) def _parse_openrc(self): """ Get credentials from an openrc file """ openrc_path = self.module.params['openrc_path'] line_re = re.compile('^export (?POS_\w*)=(?P[^\n]*)') with open(openrc_path) as openrc: matches = [line_re.match(l) for l in openrc] return dict( (g.groupdict()['key'], g.groupdict()['value']) for g in matches if g) def _keystone_authenticate(self): """ Authenticate with Keystone """ openrc = self._parse_openrc() self.keystone = ksclient.Client(username=openrc['OS_USERNAME'], password=openrc['OS_PASSWORD'], tenant_name=openrc['OS_TENANT_NAME'], auth_url=openrc['OS_AUTH_URL']) def _init_neutron(self): """ Create neutron client object using token and url from keystone """ self.neutron = nclient.Client( '2.0', endpoint_url=self.keystone.service_catalog.url_for( service_type='network'), token=self.keystone.get_token(self.keystone.session)) def route(self): """ Run the command specified by the command parameter """ getattr(self, COMMAND_MAP[self.module.params['command']])() def create_network(self): name = self.module.params['name'] if not self.neutron.list_networks(name=name)['networks']: # network doesn't exist, create it self.state_change = True self.neutron.create_network( {"network": {"name": name, "admin_state_up": True}}) def _get_network_by_name(self, name): return self.neutron.list_networks(name=name)['networks'][0] def create_subnet(self, network_id=None): name = self.module.params['name'] cidr = self.module.params['cidr'] if network_id is None: self.create_network() network_id = self._get_network_by_name(name)['id'] if not self.neutron.list_subnets( cidr=cidr, network_id=network_id)['subnets']: # subnet doesn't exist, create it self.state_change = True self.neutron.create_subnet( {"subnet": {"cidr": cidr, "ip_version": 4, "network_id": network_id}}) self.module.exit_json( changed=self.state_change, ansible_facts=dict(neutron=self._get_network_facts())) def _get_network_facts(self): facts={} facts['networks']=self.neutron.list_networks()['networks'] facts['subnets']=self.neutron.list_subnets()['subnets'] return facts def main(): module = AnsibleModule( argument_spec=dict( command=dict(required=True, choices=COMMAND_MAP.keys()), openrc_path=dict(required=True), name=dict(required=True), cidr=dict(required=True), ), supports_check_mode=False ) mg = ManageNeutron(module) mg.route() from ansible.module_utils.basic import * if __name__ == '__main__': main()