Removing heat_facts because GPLv3

This module, while potentially extremely useful, is GPLv3 and thus
creates a need to file an OSRB approval request before distributing it.
The less we need to get approval for, the better, at this late stage.

Change-Id: I38effea12e498fee86b5876e1d27f9741172cec0
This commit is contained in:
Clint Byrum 2014-08-21 13:22:54 -07:00
parent 06fa192e91
commit 6ce7aa7b92
3 changed files with 0 additions and 417 deletions

View File

@ -1,38 +0,0 @@
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# 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.
- name: rebuild using heat facts
hosts: localhost
tasks:
- name: gather facts from heat
local_action:
module: heat_facts
region_name: regionOne
login_username: admin
login_password: setpassword
login_tenant_name: admin
auth_url: http://192.0.2.1:5000/v3
stacks: all
- name: rebuild all instances
nova_rebuild:
region_name: regionOne
login_username: admin
login_password: setpassword
login_tenant_name: admin
auth_url: http://192.0.2.1:5000/v2.0
name: "{{ item.key }}"
image_id: "{{ item.value.heat_image.id }}"
preserve_ephemeral: yes
wait_for: 200
with_dict: heat_instances

View File

@ -1,33 +0,0 @@
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# 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.
- name: examine heat facts
hosts: localhost
tasks:
- name: display facts from heat
local_action:
module: heat_facts
region_name: regionOne
login_username: '{{ lookup("env", "OS_USERNAME") }}'
login_password: '{{ lookup("env", "OS_PASSWORD") }}'
login_tenant_name: '{{ lookup("env", "OS_TENANT_NAME") }}'
auth_url: '{{ lookup("env", "OS_AUTH_URL") }}'
stacks: all
- name: Stacks debug info
debug: msg="Stack Name {{ item.key }}, stack status {{ item.value.heat_stack_status }}"
with_dict: heat_stacks
- name: Instances debug info
debug: msg="Instance Name {{ item.key }}, instance resource type {{ item.value.heat_resource_type }}"
with_dict: heat_instances

View File

@ -1,346 +0,0 @@
#!/usr/bin/python
# (c) 2014 Patrick "CaptTofu" Galbraith <patg@patg.net>
# (c) 2014 Clint Byrum <clint@fewbar.com>
# (c) 2014 Allison Randal <allison@lohutok.net>
# Code also from rax_facts, docker_facts, nova_facts and the primary heat module
#
#
# 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/>.
# This is a DOCUMENTATION stub specific to this module, it extends
# a documentation fragment located in ansible.utils.module_docs_fragments
DOCUMENTATION = '''
---
module: heat_facts
short_description: Gather facts for Heat instances and images
description:
- Gather facts for Heat instances and images
version_added: "0.1"
options:
id:
description:
- instance ID to retrieve facts for
default: null (all instances if neither name nor id specified)
name:
description:
- instance name to retrieve facts for
default: null (all instances if neither name nor id specified)
address:
description
- instance address, internal or external (floating) to retrieve
facts for
default: null
group:
description
- server group to retrieve facts for (filter instances)
default: null
author: Allison Randal
'''
EXAMPLES = '''
- name: Gather info about instances
hosts: localhost
gather_facts: False
tasks:
- name: Get facts about instance with server id 123
local_action:
login_username: galt
login_password: starnesville
login_tenant_name: galt-project1
auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v3/
region_name: region-b.geo-1
module: heat_facts
id: f062f85b-5586-479a-b6a2-647385b04715
key_name: test
wait_for: 200
security_groups: default
- name: Get facts about instance with ip address of 10.0.0.102
local_action:
module: heat_facts
address: 10.0.0.102
- name: Gather info about all instances and images
hosts: heat
gather_facts: True
tasks:
- name: Get facts about instances
local_action:
module: heat_facts
stacks: all
- name: stacks debug info
debug: msg="Stack Name {{ item.key }}"
with_dict: heat_stacks
- name: instances debug info
debug: msg="Instance Name {{ item.key }}"
with_dict: heat_instances
'''
from types import NoneType
HAS_KEYSTONE_CLIENT = True
HAS_HEAT_CLIENT = True
HAS_NOVA_CLIENT = True
NON_CALLABLES = (basestring, bool, dict, int, list, NoneType)
try:
from heatclient.v1 import client as heat_client
# from heatclient import exceptions
except ImportError:
HAS_HEAT_CLIENT = False
print("failed=True msg='heatclient is required for this module'")
try:
from novaclient.v1_1 import client as nova_client
except ImportError:
HAS_NOVA_CLIENT = False
print("failed=True msg='novaclient is required for this module'")
try:
from keystoneclient.v3 import client as keystone_client
except ImportError:
HAS_KEYSTONE_CLIENT = False
print("failed=True msg='keystoneclient is required for this module'")
class HeatFacts:
def __init__(self, module):
self._ksclient = None
self._hclient = None
self._nclient = None
self.module = module
self.name = module.params.get('name')
self.id = module.params.get('id')
self.address = module.params.get('address')
self.stacks = module.params.get('stacks')
self.group = module.params.get('group')
self.stack_list = None
if self.stacks and self.stacks != 'all':
self.stack_list = [ module.params.get('stacks') ]
def key_cleanup(self, value):
return 'heat_%s' % (re.sub('[^\w-]', '_', value).lower().lstrip('_'))
def object_to_dict(self, obj):
instance = {}
for key in dir(obj):
value = getattr(obj, key)
if key == 'manager':
next
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
key = self.key_cleanup(key)
instance[key] = value
return instance
def object_list_to_dict(self, object_list, name):
dicts = {}
for obj in object_list:
dictn = self.object_to_dict(obj)
if name is not None and \
name != dictn['heat_stack_name']:
next
else:
dicts[dictn['heat_stack_name']] = dictn
return dicts
def get_instances(self):
instance_obj_list = []
instances_dict = {}
for stack_name in self.stack_list:
stack_obj = self.heat.stacks.get(stack_name)
stack_id = stack_obj.id
for res in self.heat.resources.list(stack_id):
if res.resource_type == 'OS::Nova::Server':
if self.id and self.id != res.physical_resource_id:
break
instance = self.object_to_dict(res)
server = self.nova.servers.get(res.physical_resource_id)
if self.name and self.name != server.name:
break
group_match = re.search("compute|controller|undercloud", server.name, flags=re.IGNORECASE)
if group_match:
instance['heat_group'] = group_match.group(0)
if self.group and self.group != instance['heat_group']:
break
instance.update(self.object_to_dict(server))
if self.address and self.address != instance['heat_networks']['ctlplane'][0]:
break
image = self.nova.images.get(instance['heat_image']['id'])
instance['heat_image'].update(image.metadata)
instance['heat_stack_name'] = stack_name
instances_dict[server.name] = instance
# this is specific to instances, hence not in object_list_to_dict()
if self.address is not None:
for iname, instance_dict in instances_dict.iteritems():
for netname, networks in \
instance_dict['heat_networks'].iteritems():
for address in networks:
if self.address == address:
instances_dict = {iname: instances_dict[iname]}
return instances_dict
def get_stacks(self):
stacks_dict = {}
stack_obj_list = []
stack_id = None
if self.stacks != 'all':
stack_id = self.stacks
try:
stack_obj_list.append(self.heat.stacks.get(stack_id))
except Exception, e:
self.module.fail_json(msg='%s' % e. message)
else:
try:
stack_obj_list = self.heat.stacks.list()
except Exception, e:
self.module.fail_json(msg='%s' % e. message)
stacks_dict = self.object_list_to_dict(stack_obj_list, stack_id)
for sname, sdict in stacks_dict.iteritems():
if 'heat_parameters' in sdict:
del sdict['heat_parameters']
return stacks_dict
def heat_facts(self, module):
changed = False
facts = {}
# get all stacks
facts['heat_stacks'] = self.get_stacks()
if self.stacks == 'all':
self.stack_list = facts['heat_stacks'].keys()
# get all instances
facts['heat_instances'] = self.get_instances()
module.exit_json(changed=changed, ansible_facts=facts)
@property
def keystone(self):
if self._ksclient is None:
self._ksclient = keystone_client.Client(
auth_url=self.module.params['auth_url'],
username=self.module.params['login_username'],
password=self.module.params['login_password'])
try:
self._ksclient.authenticate()
except exceptions.Unauthorized, e:
module.fail_json(msg="Invalid OpenStack Keystone credentials.: %s" %
e.message)
except exceptions.AuthorizationFailure, e:
module.fail_json(msg="Unable to authorize user: %s" % e.message)
return self._ksclient
@property
def heat(self):
if self._hclient is None:
ksclient = self.keystone
endpoint = ksclient.service_catalog.url_for(
service_type='orchestration', endpoint_type='publicURL')
self._hclient = heat_client.Client(
endpoint=endpoint,
token=ksclient.auth_token)
if self._hclient is None:
module.fail_json(msg="Failed to instantiate heat client. This "
"could mean that your credentials are wrong.")
return self._hclient
@property
def nova(self):
if self._nclient is None:
ksclient = self.keystone
endpoint = ksclient.service_catalog.url_for(
service_type='compute', endpoint_type='publicURL')
self._nclient = nova_client.Client(
bypass_url=endpoint,
username=None,
api_key=None,
auth_url=self.module.params['auth_url'],
auth_token=ksclient.auth_token)
if self._nclient is None:
module.fail_json(msg="Failed to instantiate nova client. This "
"could mean that your credentials are wrong.")
return self._nclient
def main():
if not HAS_HEAT_CLIENT:
module.fail_json(msg=
'The heat python client is required \
for this module')
if not HAS_KEYSTONE_CLIENT:
module.fail_json(msg=
'The keystone python client is required \
for this module')
if not HAS_NOVA_CLIENT:
module.fail_json(msg=
'The nova python client is required \
for this module')
argument_spec = dict(
id=dict(default=None),
name=dict(default=None),
address=dict(default=None),
stacks=dict(default=None),
group=dict(default=None),
login_username=dict(default='admin'),
login_password=dict(required=True),
login_tenant_name=dict(required='True'),
auth_url=dict(default='http://127.0.0.1:35357/v3/'),
region_name=dict(default=None),
image_id=dict(default=None),
flavor_id=dict(default=1),
key_name=dict(default=None),
security_groups=dict(default='default'),
nics=dict(default=None),
meta=dict(default=None),
wait=dict(default='yes', choices=['yes', 'no']),
wait_for=dict(default=180),
state=dict(default='present', choices=['absent', 'present']),
user_data=dict(default=None)
)
module = AnsibleModule(
argument_spec=argument_spec,
mutually_exclusive=[['id', 'name']]
)
manager = HeatFacts(module)
manager.heat_facts(module)
# import module snippets
from ansible.module_utils.basic import *
### invoke the module
main()