diff --git a/rpc_deployment/library/neutron b/rpc_deployment/library/neutron new file mode 100644 index 0000000000..6fa7acbeeb --- /dev/null +++ b/rpc_deployment/library/neutron @@ -0,0 +1,153 @@ +#!/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() + diff --git a/rpc_deployment/roles/tempest/files/rpc_tempest_gate.sh b/rpc_deployment/roles/tempest/files/rpc_tempest_gate.sh index 3a1ceaf3e9..3934f326d6 100644 --- a/rpc_deployment/roles/tempest/files/rpc_tempest_gate.sh +++ b/rpc_deployment/roles/tempest/files/rpc_tempest_gate.sh @@ -19,7 +19,7 @@ set -e set -x -API_TESTS="identity" +API_TESTS="identity image volume" pushd /opt/tempest_* source /root/openrc diff --git a/rpc_deployment/roles/tempest_resources/tasks/main.yml b/rpc_deployment/roles/tempest_resources/tasks/main.yml index c3bb9854aa..02474ac226 100644 --- a/rpc_deployment/roles/tempest_resources/tasks/main.yml +++ b/rpc_deployment/roles/tempest_resources/tasks/main.yml @@ -64,3 +64,10 @@ with_items: - demo - alt_demo + +- name: Ensure tempest network exists + neutron: + command: create_network_with_subnet + openrc_path: /root/openrc + name: tempest + cidr: "192.168.74.0/24"