Merge pull request #94 from cloudnull/Issue62
Resolves Horizon and Nova-Compute key distribution issues
This commit is contained in:
commit
600c0017e1
@ -159,7 +159,6 @@ def _build_container_hosts(container_affinity, container_hosts, type_and_name,
|
||||
cuuid = cuuid.split('-')[0]
|
||||
container_host_name = '%s-%s' % (type_and_name, cuuid)
|
||||
hostvars_options = hostvars[container_host_name] = {}
|
||||
|
||||
if container_host_type not in inventory:
|
||||
inventory[container_host_type] = {
|
||||
"hosts": [],
|
||||
@ -295,14 +294,21 @@ def _add_container_hosts(assignment, config, container_name, container_type,
|
||||
affinity = host_options.get('affinity', {})
|
||||
|
||||
container_affinity = affinity.get(container_name, 1)
|
||||
# Ensures that container names are not longer than 64
|
||||
name_length = len(host_type)
|
||||
if name_length > 25:
|
||||
name_diff = name_length - 25
|
||||
host_name = host_type[:-name_diff]
|
||||
else:
|
||||
host_name = host_type
|
||||
type_and_name = '%s_%s' % (host_name, container_name)
|
||||
# Ensures that container names are not longer than 63
|
||||
# This section will ensure that we are not it by the following bug:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=2239
|
||||
type_and_name = '%s_%s' % (host_type, container_name)
|
||||
max_hostname_len = 52
|
||||
if len(type_and_name) > max_hostname_len:
|
||||
raise SystemExit(
|
||||
'The resulting combination of [ "%s" + "%s" ] is longer than'
|
||||
' 52 characters. This combination will result in a container'
|
||||
' name that is longer than the maximum allowable hostname of'
|
||||
' 63 characters. Before this process can continue please'
|
||||
' adjust the host entries in your "rpc_user_config.yml" to use'
|
||||
' a short hostname. The recommended hostname length is < 20'
|
||||
' characters long.' % (host_type, container_name)
|
||||
)
|
||||
|
||||
physical_host = inventory['_meta']['hostvars'][host_type]
|
||||
container_host_type = '%s_containers' % host_type
|
||||
@ -323,7 +329,7 @@ def _add_container_hosts(assignment, config, container_name, container_type,
|
||||
physical_host_type,
|
||||
config,
|
||||
is_metal,
|
||||
assignment
|
||||
assignment,
|
||||
)
|
||||
|
||||
# Add the physical host type to all containers from the built inventory
|
||||
|
@ -33,4 +33,5 @@ container_packages:
|
||||
|
||||
service_pip_dependencies:
|
||||
- requests
|
||||
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -37,3 +37,5 @@ galera_gcache_size: 1G
|
||||
|
||||
service_pip_dependencies:
|
||||
- MySQL-python
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -20,7 +20,7 @@
|
||||
containerize: true
|
||||
|
||||
## Service Name
|
||||
service_name: apache2
|
||||
service_name: horizon
|
||||
|
||||
# Verbosity Options
|
||||
debug: False
|
||||
@ -40,43 +40,23 @@ container_database: dash
|
||||
system_user: www-data
|
||||
system_group: www-data
|
||||
|
||||
## Git Source
|
||||
git_repo: https://git.openstack.org/openstack/horizon
|
||||
git_fallback_repo: https://github.com/openstack/horizon
|
||||
git_install_branch: stable/icehouse
|
||||
|
||||
# Installation directories
|
||||
install_root_dir: /opt/horizon
|
||||
install_lib_dir: /opt/horizon/lib/python2.7/site-packages
|
||||
|
||||
service_pip_dependencies:
|
||||
- oslo.config
|
||||
- MySQL-python
|
||||
- python-memcached
|
||||
- django-appconf
|
||||
- pycrypto
|
||||
- ply
|
||||
- greenlet
|
||||
install_lib_dir: /usr/local/lib/python2.7/dist-packages
|
||||
|
||||
container_directories:
|
||||
- "{{ install_root_dir }}"
|
||||
- "/etc/horizon"
|
||||
- "{{ install_lib_dir }}"
|
||||
|
||||
container_packages:
|
||||
- apache2
|
||||
- apache2-utils
|
||||
- libapache2-mod-wsgi
|
||||
- libssl-dev
|
||||
- libxslt1.1
|
||||
- openssl
|
||||
service_pip_dependencies:
|
||||
- MySQL-python
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
||||
horizon_fqdn: "{{ external_vip_address }}"
|
||||
horizon_server_name: "{{ container_name }}"
|
||||
horizon_self_signed: true
|
||||
|
||||
pip_install_options: "--install-option='--prefix={{ install_root_dir }}'"
|
||||
service_name: horizon
|
||||
|
||||
## Optional certification options
|
||||
# horizon_cacert_pem: /path/to/cacert.pem
|
||||
# horizon_ssl_cert: /etc/ssl/certs/apache.cert
|
||||
|
@ -66,6 +66,7 @@ service_pip_dependencies:
|
||||
- MySQL-python
|
||||
- pycrypto
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
- python-keystoneclient
|
||||
|
||||
|
||||
|
@ -37,3 +37,7 @@ kibana_fqdn: "{{ external_vip_address }}"
|
||||
kibana_server_name: "{{ container_name }}"
|
||||
kibana_self_signed: true
|
||||
kibana_ssl_port: 8443
|
||||
|
||||
service_pip_dependencies:
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -33,3 +33,6 @@ container_packages:
|
||||
- logstash
|
||||
- logstash-contrib
|
||||
|
||||
service_pip_dependencies:
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -18,3 +18,7 @@ service_name: memcached
|
||||
# only used when the lxc vg is present on the target
|
||||
container_lvm_fstype: ext4
|
||||
container_lvm_fssize: 5GB
|
||||
|
||||
service_pip_dependencies:
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -31,3 +31,7 @@ rabbit_cookie: "{{ rabbitmq_cookie_token }}"
|
||||
enable_management_plugin: true
|
||||
|
||||
rabbit_cluster_name: rpc
|
||||
|
||||
service_pip_dependencies:
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -25,3 +25,7 @@ container_lvm_fssize: 5GB
|
||||
|
||||
apt_container_repos:
|
||||
- { repo: "ppa:adiscon/v8-stable", state: "present" }
|
||||
|
||||
service_pip_dependencies:
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
@ -32,6 +32,8 @@ service_pip_dependencies:
|
||||
- python-neutronclient
|
||||
- python-novaclient
|
||||
- python-swiftclient
|
||||
- python-memcached
|
||||
- pycrypto
|
||||
|
||||
container_packages:
|
||||
- ruby1.9.1
|
||||
|
599
rpc_deployment/library/memcached
Normal file
599
rpc_deployment/library/memcached
Normal file
@ -0,0 +1,599 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# (c) 2014, Kevin Carter <kevin.carter@rackspace.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/>.
|
||||
|
||||
import os
|
||||
import base64
|
||||
import stat
|
||||
import sys
|
||||
|
||||
import memcache
|
||||
try:
|
||||
from Crypto import Random
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
ENCRYPT_IMPORT = True
|
||||
except ImportError:
|
||||
ENCRYPT_IMPORT = False
|
||||
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: memcached
|
||||
version_added: "1.6.6"
|
||||
short_description:
|
||||
- Add, remove, and get items from memcached
|
||||
description:
|
||||
- Add, remove, and get items from memcached
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Memcached key name
|
||||
required: true
|
||||
content:
|
||||
description:
|
||||
- Add content to memcahced. Only used when state is 'present'.
|
||||
required: false
|
||||
file_path:
|
||||
description:
|
||||
- This can be used with state 'present' and 'retrieve'. When set
|
||||
with state 'present' the contents of a file will be used, when
|
||||
set with state 'retrieve' the contents of the memcached key will
|
||||
be written to a file.
|
||||
required: false
|
||||
state:
|
||||
description:
|
||||
- ['absent', 'present', 'retrieve']
|
||||
required: true
|
||||
server:
|
||||
description:
|
||||
- server IP address and port. This can be a comma seperated list of
|
||||
servers to connect to.
|
||||
required: true
|
||||
encrypt_string:
|
||||
description:
|
||||
- Encrypt/Decrypt a memcached object using a provided value.
|
||||
required: false
|
||||
dir_mode:
|
||||
description:
|
||||
- If a directory is created when using the ``file_path`` argument
|
||||
the directory will be created with a set mode.
|
||||
default: '0755'
|
||||
required: false
|
||||
file_mode:
|
||||
description:
|
||||
- If a file is created when using the ``file_path`` argument
|
||||
the file will be created with a set mode.
|
||||
default: '0644'
|
||||
required: false
|
||||
expires:
|
||||
description:
|
||||
- Seconds until an item is expired from memcached.
|
||||
default: 300
|
||||
required: false
|
||||
notes:
|
||||
- The "absent" state will remove an item from memcached.
|
||||
- The "present" state will place an item from a string or a file into
|
||||
memcached.
|
||||
- The "retrieve" state will get an item from memcached and return it as a
|
||||
string. If a ``file_path`` is set this module will also write the value
|
||||
to a file.
|
||||
- All items added into memcached are base64 encoded.
|
||||
- All items retrieved will attempt base64 decode and return the string
|
||||
value if not applicable.
|
||||
- Items retrieve from memcached are returned within a "value" key unless
|
||||
a ``file_path`` is specified which would then write the contents of the
|
||||
memcached key to a file.
|
||||
- The ``file_path`` and ``content`` fields are mutually exclusive.
|
||||
- If you'd like to encrypt items in memcached PyCrypto is a required.
|
||||
requirements:
|
||||
- "python-memcached"
|
||||
optional_requirements:
|
||||
- "pycrypto"
|
||||
author: Kevin Carter
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Add an item into memcached.
|
||||
- memcached:
|
||||
name: "key_name"
|
||||
content: "Super awesome value"
|
||||
state: "present"
|
||||
server: "localhost:11211"
|
||||
|
||||
# Read the contents of a memcached key, returned as "memcached_phrase.value".
|
||||
- memcached:
|
||||
name: "key_name"
|
||||
state: "retrieve"
|
||||
server: "localhost:11211"
|
||||
register: memcached_key
|
||||
|
||||
# Add the contents of a file into memcached.
|
||||
- memcached:
|
||||
name: "key_name"
|
||||
file_path: "/home/user_name/file.txt"
|
||||
state: "present"
|
||||
server: "localhost:11211"
|
||||
|
||||
# Write the contents of a memcached key to a file and is returned as
|
||||
# "memcached_phrase.value".
|
||||
- memcached:
|
||||
name: "key_name"
|
||||
file_path: "/home/user_name/file.txt"
|
||||
state: "retrieve"
|
||||
server: "localhost:11211"
|
||||
register: memcached_key
|
||||
|
||||
# Delete an item from memcached.
|
||||
- memcached:
|
||||
name: "key_name"
|
||||
state: "absent"
|
||||
server: "localhost:11211"
|
||||
"""
|
||||
|
||||
SERVER_MAX_VALUE_LENGTH = 1024 * 256
|
||||
|
||||
MAX_MEMCACHED_CHUNKS = 256
|
||||
|
||||
|
||||
class AESCipher(object):
|
||||
"""Encrypt an a string in using AES.
|
||||
|
||||
Solution derived from "http://stackoverflow.com/a/21928790"
|
||||
"""
|
||||
def __init__(self, key):
|
||||
if ENCRYPT_IMPORT is False:
|
||||
raise ImportError(
|
||||
'PyCrypto failed to be imported. Encryption is not supported'
|
||||
' on this system until PyCrypto is installed.'
|
||||
)
|
||||
|
||||
self.bs = 32
|
||||
if len(key) >= 32:
|
||||
self.key = key[:32]
|
||||
else:
|
||||
self.key = self._pad(key)
|
||||
|
||||
def encrypt(self, raw):
|
||||
"""Encrypt raw message.
|
||||
|
||||
:param raw: ``str``
|
||||
:returns: ``str`` Base64 encoded string.
|
||||
"""
|
||||
raw = self._pad(raw)
|
||||
iv = Random.new().read(AES.block_size)
|
||||
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||
return base64.b64encode(iv + cipher.encrypt(raw))
|
||||
|
||||
def decrypt(self, enc):
|
||||
"""Decrypt an encrypted message.
|
||||
|
||||
:param enc: ``str``
|
||||
:returns: ``str``
|
||||
"""
|
||||
enc = base64.b64decode(enc)
|
||||
iv = enc[:AES.block_size]
|
||||
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||
return self._unpad(cipher.decrypt(enc[AES.block_size:]))
|
||||
|
||||
def _pad(self, string):
|
||||
"""Pad an AES encryption key.
|
||||
|
||||
:param string: ``str``
|
||||
"""
|
||||
base = (self.bs - len(string) % self.bs)
|
||||
back = chr(self.bs - len(string) % self.bs)
|
||||
return string + base * back
|
||||
|
||||
@staticmethod
|
||||
def _unpad(string):
|
||||
"""Un-pad an AES encryption key.
|
||||
|
||||
:param string: ``str``
|
||||
"""
|
||||
ordinal_range = ord(string[len(string)-1:])
|
||||
return string[:-ordinal_range]
|
||||
|
||||
|
||||
class Memcached(object):
|
||||
"""Manage objects within memcached."""
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
self.state_change = False
|
||||
self.mc = None
|
||||
|
||||
def router(self):
|
||||
"""Route all commands to their respected functions.
|
||||
|
||||
If an exception happens a failure will be raised.
|
||||
"""
|
||||
|
||||
try:
|
||||
action = getattr(self, self.module.params['state'])
|
||||
self.mc = memcache.Client(
|
||||
self.module.params['server'].split(','),
|
||||
server_max_value_length=SERVER_MAX_VALUE_LENGTH,
|
||||
debug=0
|
||||
)
|
||||
facts = action()
|
||||
except Exception as exp:
|
||||
self._failure(error=str(exp), rc=1, msg='general exception')
|
||||
else:
|
||||
self.mc.disconnect_all()
|
||||
self.module.exit_json(
|
||||
changed=self.state_change, **facts
|
||||
)
|
||||
|
||||
def _failure(self, error, rc, msg):
|
||||
"""Return a Failure when running an Ansible command.
|
||||
|
||||
:param error: ``str`` Error that occurred.
|
||||
:param rc: ``int`` Return code while executing an Ansible command.
|
||||
:param msg: ``str`` Message to report.
|
||||
"""
|
||||
|
||||
self.module.fail_json(msg=msg, rc=rc, err=error)
|
||||
|
||||
def absent(self):
|
||||
"""Remove a key from memcached.
|
||||
|
||||
If the value is not deleted when instructed to do so an exception will
|
||||
be raised.
|
||||
|
||||
:return: ``dict``
|
||||
"""
|
||||
|
||||
key_name = self.module.params['name']
|
||||
get_keys = [
|
||||
'%s.%s' % (key_name, i) for i in xrange(MAX_MEMCACHED_CHUNKS)
|
||||
]
|
||||
self.mc.delete_multi(get_keys)
|
||||
value = self.mc.get_multi(get_keys)
|
||||
if not value:
|
||||
self.state_change = True
|
||||
return {'absent': True, 'key': self.module.params['name']}
|
||||
else:
|
||||
self._failure(
|
||||
error='Memcache key not deleted',
|
||||
rc=1,
|
||||
msg='Failed to remove an item from memcached please check your'
|
||||
' memcached server for issues. If you are load balancing'
|
||||
' memcahced, attempt to connect to a single node.'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _decode_value(value):
|
||||
"""Return a ``str`` from a base64 decoded value.
|
||||
|
||||
If the content is not a base64 ``str`` the raw value will be returned.
|
||||
|
||||
:param value: ``str``
|
||||
:return:
|
||||
"""
|
||||
|
||||
try:
|
||||
b64_value = base64.decodestring(value)
|
||||
except Exception:
|
||||
return value
|
||||
else:
|
||||
return b64_value
|
||||
|
||||
def _encode_value(self, value):
|
||||
"""Return a base64 encoded value.
|
||||
|
||||
If the value can't be base64 encoded an excption will be raised.
|
||||
|
||||
:param value: ``str``
|
||||
:return: ``str``
|
||||
"""
|
||||
|
||||
try:
|
||||
b64_value = base64.encodestring(value)
|
||||
except Exception as exp:
|
||||
self._failure(
|
||||
error=str(exp),
|
||||
rc=1,
|
||||
msg='The value provided can not be Base64 encoded.'
|
||||
)
|
||||
else:
|
||||
return b64_value
|
||||
|
||||
def _file_read(self, full_path, pass_on_error=False):
|
||||
"""Read the contents of a file.
|
||||
|
||||
This will read the contents of a file. If the ``full_path`` does not
|
||||
exist an exception will be raised.
|
||||
|
||||
:param full_path: ``str``
|
||||
:return: ``str``
|
||||
"""
|
||||
|
||||
try:
|
||||
with open(full_path, 'rb') as f:
|
||||
o_value = f.read()
|
||||
except IOError as exp:
|
||||
if pass_on_error is False:
|
||||
self._failure(
|
||||
error=str(exp),
|
||||
rc=1,
|
||||
msg="The file you've specified does not exist. Please"
|
||||
" check your full path @ [ %s ]." % full_path
|
||||
)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return o_value
|
||||
|
||||
def _chown(self, path, mode_type):
|
||||
"""Chown a file or directory based on a given mode type.
|
||||
|
||||
If the file is modified the state will be changed.
|
||||
|
||||
:param path: ``str``
|
||||
:param mode_type: ``str``
|
||||
"""
|
||||
mode = self.module.params.get(mode_type)
|
||||
# Ensure that the mode type is a string.
|
||||
mode = str(mode)
|
||||
_mode = oct(stat.S_IMODE(os.stat(path).st_mode))
|
||||
if _mode != mode or _mode[1:] != mode:
|
||||
os.chmod(path, int(mode, 8))
|
||||
self.state_change = True
|
||||
|
||||
def _file_write(self, full_path, value):
|
||||
"""Write the contents of ``value`` to the ``full_path``.
|
||||
|
||||
This will return True upon success and will raise an exception upon
|
||||
failure.
|
||||
|
||||
:param full_path: ``str``
|
||||
:param value: ``str``
|
||||
:return: ``bol``
|
||||
"""
|
||||
|
||||
try:
|
||||
# Ensure that the directory exists
|
||||
dir_path = os.path.dirname(full_path)
|
||||
try:
|
||||
os.makedirs(dir_path)
|
||||
except OSError as exp:
|
||||
if exp.errno == errno.EEXIST and os.path.isdir(dir_path):
|
||||
pass
|
||||
else:
|
||||
self._failure(
|
||||
error=str(exp),
|
||||
rc=1,
|
||||
msg="The directory [ %s ] does not exist and couldn't"
|
||||
" be created. Please check the path and that you"
|
||||
" have permission to write the file."
|
||||
)
|
||||
|
||||
# Ensure proper directory permissions
|
||||
self._chown(path=dir_path, mode_type='dir_mode')
|
||||
|
||||
# Write contents of a cached key to a file.
|
||||
with open(full_path, 'wb') as f:
|
||||
if isinstance(value, list):
|
||||
f.writelines(value)
|
||||
else:
|
||||
f.write(value)
|
||||
|
||||
# Ensure proper file permissions
|
||||
self._chown(path=full_path, mode_type='file_mode')
|
||||
|
||||
except IOError as exp:
|
||||
self._failure(
|
||||
error=str(exp),
|
||||
rc=1,
|
||||
msg="There was an issue while attempting to write to the"
|
||||
" file [ %s ]. Please check your full path and"
|
||||
" permissions." % full_path
|
||||
)
|
||||
else:
|
||||
return True
|
||||
|
||||
def retrieve(self):
|
||||
"""Return a value from memcached.
|
||||
|
||||
If ``file_path`` is specified the value of the memcached key will be
|
||||
written to a file at the ``file_path`` location. If the value of a key
|
||||
is None, an exception will be raised.
|
||||
|
||||
:returns: ``dict``
|
||||
"""
|
||||
|
||||
key_name = self.module.params['name']
|
||||
get_keys = [
|
||||
'%s.%s' % (key_name, i) for i in xrange(MAX_MEMCACHED_CHUNKS)
|
||||
]
|
||||
multi_value = self.mc.get_multi(get_keys)
|
||||
if multi_value:
|
||||
value = ''.join([i for i in multi_value.values() if i is not None])
|
||||
# Get the file path if specified.
|
||||
file_path = self.module.params.get('file_path')
|
||||
if file_path is not None:
|
||||
full_path = os.path.abspath(os.path.expanduser(file_path))
|
||||
|
||||
# Decode cached value
|
||||
encrypt_string = self.module.params.get('encrypt_string')
|
||||
if encrypt_string:
|
||||
_d_value = AESCipher(key=encrypt_string)
|
||||
d_value = _d_value.decrypt(enc=value)
|
||||
if not d_value:
|
||||
d_value = self._decode_value(value=value)
|
||||
else:
|
||||
d_value = self._decode_value(value=value)
|
||||
|
||||
o_value = self._file_read(
|
||||
full_path=full_path, pass_on_error=True
|
||||
)
|
||||
|
||||
# compare old value to new value and write if different
|
||||
if o_value != d_value:
|
||||
self.state_change = True
|
||||
self._file_write(full_path=full_path, value=d_value)
|
||||
|
||||
return {
|
||||
'present': True,
|
||||
'key': self.module.params['name'],
|
||||
'value': value,
|
||||
'file_path': full_path
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'present': True,
|
||||
'key': self.module.params['name'],
|
||||
'value': value
|
||||
}
|
||||
else:
|
||||
self._failure(
|
||||
error='Memcache key not found',
|
||||
rc=1,
|
||||
msg='The key you specified was not found within memcached. '
|
||||
'If you are load balancing memcahced, attempt to connect'
|
||||
' to a single node.'
|
||||
)
|
||||
|
||||
def present(self):
|
||||
"""Create and or update a key within Memcached.
|
||||
|
||||
The state processed here is present. This state will ensure that
|
||||
content is written to a memcached server. When ``file_path`` is
|
||||
specified the content will be read in from a file.
|
||||
"""
|
||||
|
||||
file_path = self.module.params.get('file_path')
|
||||
if file_path is not None:
|
||||
full_path = os.path.abspath(os.path.expanduser(file_path))
|
||||
# Read the contents of a file into memcached.
|
||||
o_value = self._file_read(full_path=full_path)
|
||||
else:
|
||||
o_value = self.module.params['content']
|
||||
|
||||
# Encode cached value
|
||||
encrypt_string = self.module.params.get('encrypt_string')
|
||||
if encrypt_string:
|
||||
_d_value = AESCipher(key=encrypt_string)
|
||||
d_value = _d_value.encrypt(raw=o_value)
|
||||
else:
|
||||
d_value = self._encode_value(value=o_value)
|
||||
|
||||
compare = 1024 * 128
|
||||
chunks = sys.getsizeof(d_value) / compare
|
||||
if chunks == 0:
|
||||
chunks = 1
|
||||
elif chunks > MAX_MEMCACHED_CHUNKS:
|
||||
self._failure(
|
||||
error='Memcache content too large',
|
||||
rc=1,
|
||||
msg='The content that you are attempting to cache is larger'
|
||||
' than [ %s ] megabytes.'
|
||||
% ((compare * MAX_MEMCACHED_CHUNKS / 1024 / 1024))
|
||||
)
|
||||
|
||||
step = len(d_value) / chunks
|
||||
if step == 0:
|
||||
step = 1
|
||||
|
||||
key_name = self.module.params['name']
|
||||
split_d_value = {}
|
||||
count = 0
|
||||
for i in range(0, len(d_value), step):
|
||||
split_d_value['%s.%s' % (key_name, count)] = d_value[i:i+step]
|
||||
count += 1
|
||||
|
||||
value = self.mc.set_multi(
|
||||
mapping=split_d_value,
|
||||
time=self.module.params['expires'],
|
||||
min_compress_len=2048
|
||||
)
|
||||
|
||||
if not value:
|
||||
self.state_change = True
|
||||
return {
|
||||
'present': True,
|
||||
'key': self.module.params['name']
|
||||
}
|
||||
else:
|
||||
self._failure(
|
||||
error='Memcache content not created',
|
||||
rc=1,
|
||||
msg='The content you attempted to place within memcached'
|
||||
' was not created. If you are load balancing'
|
||||
' memcahced, attempt to connect to a single node.'
|
||||
' Returned a value of unstored keys [ %s ].' % value
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""Main ansible run method."""
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
name=dict(
|
||||
type='str',
|
||||
required=True
|
||||
),
|
||||
content=dict(
|
||||
type='str',
|
||||
required=False
|
||||
),
|
||||
file_path=dict(
|
||||
type='str',
|
||||
required=False
|
||||
),
|
||||
state=dict(
|
||||
type='str',
|
||||
required=True
|
||||
),
|
||||
server=dict(
|
||||
type='str',
|
||||
required=True
|
||||
),
|
||||
expires=dict(
|
||||
type='int',
|
||||
default=300,
|
||||
required=False
|
||||
),
|
||||
file_mode=dict(
|
||||
type='str',
|
||||
default='0644',
|
||||
required=False
|
||||
),
|
||||
dir_mode=dict(
|
||||
type='str',
|
||||
default='0755',
|
||||
required=False
|
||||
),
|
||||
encrypt_string=dict(
|
||||
type='str',
|
||||
required=False
|
||||
)
|
||||
),
|
||||
supports_check_mode=False,
|
||||
mutually_exclusive=[
|
||||
['content', 'file_path']
|
||||
]
|
||||
)
|
||||
ms = Memcached(module=module)
|
||||
ms.router()
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
if __name__ == '__main__':
|
||||
main()
|
18
rpc_deployment/playbooks/openstack/horizon-all.yml
Normal file
18
rpc_deployment/playbooks/openstack/horizon-all.yml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
# 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.
|
||||
|
||||
- include: horizon-common.yml
|
||||
- include: horizon-ssl.yml
|
||||
- include: horizon.yml
|
25
rpc_deployment/playbooks/openstack/horizon-common.yml
Normal file
25
rpc_deployment/playbooks/openstack/horizon-common.yml
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
# 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.
|
||||
|
||||
- hosts: horizon_all
|
||||
user: root
|
||||
roles:
|
||||
- common
|
||||
- container_common
|
||||
- openstack_common
|
||||
- openstack_openrc
|
||||
- galera_client_cnf
|
||||
vars_files:
|
||||
- vars/repo_packages/horizon.yml
|
53
rpc_deployment/playbooks/openstack/horizon-ssl.yml
Normal file
53
rpc_deployment/playbooks/openstack/horizon-ssl.yml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
# 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.
|
||||
|
||||
- hosts: horizon_all[0]
|
||||
user: root
|
||||
roles:
|
||||
- horizon_ssl
|
||||
vars_files:
|
||||
- vars/repo_packages/horizon.yml
|
||||
|
||||
- hosts: horizon_all[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Distribute apache keys for cluster consumption
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "present"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/etc/ssl/private/apache.key", name: "apache_key" }
|
||||
- { src: "/etc/ssl/certs/apache.cert", name: "apache_cert" }
|
||||
|
||||
- hosts: horizon_all:!horizon_all[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Retrieve apache keys
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "retrieve"
|
||||
file_mode: "{{ item.file_mode }}"
|
||||
dir_mode: "{{ item.dir_mode }}"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/etc/ssl/private/apache.key", name: "apache_key", file_mode: "0640", dir_mode: "0750" }
|
||||
- { src: "/etc/ssl/certs/apache.cert", name: "apache_cert", file_mode: "0644", dir_mode: "0755" }
|
@ -13,29 +13,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- hosts: horizon_all
|
||||
user: root
|
||||
roles:
|
||||
- common
|
||||
- container_common
|
||||
- galera_client_cnf
|
||||
|
||||
- hosts: horizon_all
|
||||
user: root
|
||||
roles:
|
||||
- openstack_common
|
||||
- openstack_openrc
|
||||
- horizon_common
|
||||
vars_files:
|
||||
- vars/openstack_service_vars/horizon.yml
|
||||
|
||||
- hosts: horizon_all[0]
|
||||
user: root
|
||||
roles:
|
||||
- horizon_common
|
||||
- galera_db_setup
|
||||
- horizon_setup
|
||||
- horizon_apache
|
||||
vars_files:
|
||||
- vars/openstack_service_vars/horizon.yml
|
||||
|
||||
- hosts: horizon_all
|
||||
- hosts: horizon_all:!horizon_all[0]
|
||||
user: root
|
||||
roles:
|
||||
- horizon_common
|
||||
- horizon_apache
|
||||
vars_files:
|
||||
- vars/openstack_service_vars/horizon.yml
|
||||
|
@ -13,30 +13,42 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- hosts: localhost
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Remove [ /tmp/authorized_keys ] file if found
|
||||
file:
|
||||
path: "/tmp/authorized_keys"
|
||||
state: "absent"
|
||||
|
||||
- hosts: nova_compute
|
||||
user: root
|
||||
roles:
|
||||
- nova_compute_sshkey_create
|
||||
|
||||
- hosts: nova_compute[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Distribute authorized keys for cluster consumption
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "present"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/var/lib/nova/.ssh/authorized_keys", name: "authorized_keys" }
|
||||
|
||||
- hosts: nova_compute:!nova_compute[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Retrieve authorized keys
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "retrieve"
|
||||
file_mode: "{{ item.file_mode }}"
|
||||
dir_mode: "{{ item.dir_mode }}"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/var/lib/nova/.ssh/authorized_keys", name: "authorized_keys", file_mode: "0640", dir_mode: "0750" }
|
||||
|
||||
- hosts: nova_compute
|
||||
user: root
|
||||
roles:
|
||||
- nova_compute_sshkey_setup
|
||||
|
||||
- hosts: localhost
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Remove [ /tmp/authorized_keys ] file if found
|
||||
file:
|
||||
path: "/tmp/authorized_keys"
|
||||
state: "absent"
|
||||
|
@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- hosts: keystone_all:glance_all:heat_all:neutron_all:nova_all:cinder_all:horizon
|
||||
- hosts: keystone_all:glance_all:heat_all:neutron_all:nova_all:cinder_all
|
||||
user: root
|
||||
roles:
|
||||
- common
|
||||
|
@ -21,6 +21,6 @@
|
||||
- include: nova-all.yml
|
||||
- include: neutron-all.yml
|
||||
- include: cinder-all.yml
|
||||
- include: horizon.yml
|
||||
- include: horizon-all.yml
|
||||
- include: utility.yml
|
||||
- include: ../infrastructure/rsyslog-config.yml
|
||||
|
@ -25,6 +25,38 @@
|
||||
roles:
|
||||
- rpc_support_api
|
||||
|
||||
- hosts: utility[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Distribute authorized keys for cluster consumption
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "present"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/root/.ssh/rpc_support", name: "rpc_support" }
|
||||
- { src: "/root/.ssh/rpc_support.pub", name: "rpc_support_pub" }
|
||||
|
||||
- hosts: utility:utility[0]
|
||||
user: root
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Retrieve authorized keys
|
||||
memcached:
|
||||
name: "{{ item.name }}"
|
||||
file_path: "{{ item.src }}"
|
||||
state: "retrieve"
|
||||
file_mode: "{{ item.file_mode }}"
|
||||
dir_mode: "{{ item.dir_mode }}"
|
||||
server: "{{ hostvars[groups['memcached'][0]]['ansible_ssh_host'] }}:11211"
|
||||
encrypt_string: "{{ memcached_encryption_key }}"
|
||||
with_items:
|
||||
- { src: "/root/.ssh/rpc_support", name: "rpc_support", file_mode: "0600", dir_mode: "0755" }
|
||||
- { src: "/root/.ssh/rpc_support.pub", name: "rpc_support_pub", file_mode: "0640", dir_mode: "0755" }
|
||||
|
||||
# Setup holland backup
|
||||
- hosts: galera
|
||||
user: root
|
||||
|
@ -13,53 +13,50 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: create self-signed SSL cert
|
||||
command: >
|
||||
openssl req -new -nodes -x509 -subj
|
||||
"/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ horizon_server_name }}"
|
||||
-days 3650
|
||||
-keyout /etc/ssl/private/apache.key
|
||||
-out /etc/ssl/certs/apache.cert
|
||||
-extensions v3_ca
|
||||
creates=/etc/ssl/certs/apache.cert
|
||||
when: horizon_self_signed is defined and horizon_self_signed == true
|
||||
- name: Add horizon etc dir
|
||||
file:
|
||||
dest: "/etc/horizon"
|
||||
recurse: "yes"
|
||||
owner: "{{ system_group }}"
|
||||
group: "{{ system_group }}"
|
||||
state: "directory"
|
||||
|
||||
- name: Setup Horizon config
|
||||
template: >
|
||||
src=local_settings.py
|
||||
dest={{ install_lib_dir }}/openstack_dashboard/local/local_settings.py
|
||||
owner={{ system_user }}
|
||||
group={{ system_group }}
|
||||
|
||||
- name: Copy manage.py
|
||||
command: >
|
||||
creates={{ install_lib_dir }}/manage.py
|
||||
cp -a "/opt/{{ service_name }}_{{ git_install_branch | replace('/', '_') }}/manage.py" "{{ install_lib_dir }}"
|
||||
# The Horizon config files should be replaced for the JUNO release
|
||||
# juno_revision: true
|
||||
- name: Setup Horizon config(s)
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: "{{ system_user }}"
|
||||
group: "{{ system_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
with_items:
|
||||
- { src: "local_settings.py", dest: "/etc/horizon/local_settings.py", mode: "0644" }
|
||||
- { src: "horizon-manage.py", dest: "/usr/local/bin/horizon-manage.py", mode: "0755" }
|
||||
|
||||
# /opt/horizon/lib/python2.7/site-packages/manage.py
|
||||
- name: Collect static files
|
||||
command: python /opt/horizon/lib/python2.7/site-packages/manage.py collectstatic --noinput
|
||||
command: horizon-manage.py collectstatic --noinput
|
||||
|
||||
|
||||
- name: Fix missing file issues (1 of 2)
|
||||
file: >
|
||||
src={{ install_lib_dir }}/horizon/static/bootstrap/js
|
||||
dest={{ install_lib_dir }}/openstack_dashboard/static/bootstrap/js
|
||||
owner={{ system_group }}
|
||||
group={{ system_group }}
|
||||
state=link
|
||||
|
||||
- name: Fix missing file issues (2 of 2)
|
||||
file: >
|
||||
src={{ install_lib_dir }}/horizon/static/horizon
|
||||
dest={{ install_lib_dir }}/openstack_dashboard/static/horizon
|
||||
owner={{ system_group }}
|
||||
group={{ system_group }}
|
||||
state=link
|
||||
- name: Create hoirzon links
|
||||
file:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
owner: "{{ system_group }}"
|
||||
group: "{{ system_group }}"
|
||||
state: "link"
|
||||
with_items:
|
||||
- { src: "/etc/horizon/local_settings.py", dest: "{{ install_lib_dir }}/openstack_dashboard/local/local_settings.py" }
|
||||
- { src: "{{ install_lib_dir }}/horizon/static/bootstrap/js", dest: "{{ install_lib_dir }}/openstack_dashboard/static/bootstrap/js" }
|
||||
- { src: "{{ install_lib_dir }}/horizon/static/horizon", dest: "{{ install_lib_dir }}/openstack_dashboard/static/horizon" }
|
||||
|
||||
- name: Set horizon permissions
|
||||
file: >
|
||||
state=directory
|
||||
dest={{ install_root_dir }}
|
||||
recurse=yes
|
||||
owner={{ system_group }}
|
||||
group={{ system_group }}
|
||||
file:
|
||||
dest: "{{ item }}"
|
||||
recurse: "yes"
|
||||
owner: "{{ system_group }}"
|
||||
group: "{{ system_group }}"
|
||||
state: "directory"
|
||||
with_items:
|
||||
- "{{ install_lib_dir }}/horizon"
|
||||
- "{{ install_lib_dir }}/openstack_dashboard"
|
||||
|
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from django.core.management import execute_from_command_line # noqa
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault(
|
||||
"DJANGO_SETTINGS_MODULE", "openstack_dashboard.settings"
|
||||
)
|
||||
execute_from_command_line(sys.argv)
|
@ -14,6 +14,4 @@
|
||||
# limitations under the License.
|
||||
|
||||
- name: Run syncdb
|
||||
command: >
|
||||
chdir={{ install_lib_dir }}
|
||||
python manage.py syncdb --noinput
|
||||
command: horizon-manage.py syncdb --noinput
|
||||
|
25
rpc_deployment/roles/horizon_ssl/tasks/main.yml
Normal file
25
rpc_deployment/roles/horizon_ssl/tasks/main.yml
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
# 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.
|
||||
|
||||
- name: create self-signed SSL cert
|
||||
command: >
|
||||
openssl req -new -nodes -x509 -subj
|
||||
"/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ horizon_server_name }}"
|
||||
-days 3650
|
||||
-keyout /etc/ssl/private/apache.key
|
||||
-out /etc/ssl/certs/apache.cert
|
||||
-extensions v3_ca
|
||||
creates=/etc/ssl/certs/apache.cert
|
||||
when: horizon_self_signed is defined and horizon_self_signed == true
|
@ -13,6 +13,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: Set nova users shell to /bin/bash and generate ssh_key
|
||||
user:
|
||||
name: "nova"
|
||||
shell: "/bin/bash"
|
||||
|
||||
- name: Create the keys directory for the nova user
|
||||
file:
|
||||
state: "directory"
|
||||
@ -21,16 +26,12 @@
|
||||
owner: "nova"
|
||||
mode: "0700"
|
||||
|
||||
- name: Set nova users shell to /bin/bash and generate ssh_key
|
||||
user:
|
||||
name: "nova"
|
||||
shell: "/bin/bash"
|
||||
|
||||
- name: Remove old key if found
|
||||
- name: Remove old key file(s) if found
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: "absent"
|
||||
with_items:
|
||||
- "/var/lib/nova/.ssh/authorized_keys"
|
||||
- "/var/lib/nova/.ssh/id_rsa"
|
||||
- "/var/lib/nova/.ssh/id_rsa.pub"
|
||||
|
||||
@ -53,5 +54,5 @@
|
||||
changed_when: false
|
||||
|
||||
- name: Build authorized keys
|
||||
shell: echo "{{ nova_pub.stdout }}" | tee -a /tmp/authorized_keys
|
||||
delegate_to: localhost
|
||||
shell: echo "{{ nova_pub.stdout }}" | tee -a /var/lib/nova/.ssh/authorized_keys
|
||||
delegate_to: "{{ groups['nova_compute'][0] }}"
|
||||
|
@ -21,11 +21,6 @@
|
||||
group: "nova"
|
||||
mode: "0644"
|
||||
|
||||
- name: Sync authorized_keys file
|
||||
synchronize:
|
||||
src: /tmp/authorized_keys
|
||||
dest: /var/lib/nova/.ssh/authorized_keys
|
||||
|
||||
- name: Set authorized_keys permissions
|
||||
file:
|
||||
path: "/var/lib/nova/.ssh/authorized_keys"
|
||||
|
@ -13,14 +13,16 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: Check for key file
|
||||
shell: ls /root/.ssh/rpc_support
|
||||
failed_when: false
|
||||
changed_when: key_check.rc != 0
|
||||
register: key_check
|
||||
|
||||
- name: Create rpc_support SSH key
|
||||
user:
|
||||
name: root
|
||||
generate_ssh_key: yes
|
||||
ssh_key_bits: 2048
|
||||
ssh_key_comment: "rpc_support key added for Openstack Instances"
|
||||
ssh_key_file: "/root/.ssh/rpc_support"
|
||||
shell: ssh-keygen -f "/root/.ssh/rpc_support" -t rsa -q -N ""
|
||||
register: support_key
|
||||
when: key_check|changed
|
||||
tags:
|
||||
- support_key
|
||||
- support_keypair
|
||||
@ -29,8 +31,18 @@
|
||||
shell: |
|
||||
. /root/openrc
|
||||
nova keypair-list | grep rpc_support
|
||||
failed_when: false
|
||||
register: rpc_support_key
|
||||
when: support_key|changed
|
||||
tags:
|
||||
- support_keypair
|
||||
|
||||
- name: Delete rpc_support keypair in nova
|
||||
shell: |
|
||||
. /root/openrc
|
||||
nova keypair-keypair-delete rpc_support
|
||||
failed_when: false
|
||||
register: rpc_support_key_delete
|
||||
when: support_key|changed and rpc_support_key.rc == 0
|
||||
tags:
|
||||
- support_keypair
|
||||
|
||||
@ -38,6 +50,6 @@
|
||||
shell: |
|
||||
. /root/openrc
|
||||
nova keypair-add --pub-key /root/.ssh/rpc_support.pub rpc_support
|
||||
when: support_key|changed and rpc_support_key.rc != 0
|
||||
when: rpc_support_key.rc != 0 or rpc_support_key_delete|changed
|
||||
tags:
|
||||
- support_keypair
|
||||
|
45
rpc_deployment/vars/repo_packages/horizon.yml
Normal file
45
rpc_deployment/vars/repo_packages/horizon.yml
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
# 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.
|
||||
|
||||
repo_package_name: horizon
|
||||
|
||||
repo_path: "{{ repo_package_name }}_{{ git_install_branch | replace('/', '_') }}"
|
||||
|
||||
## Git Source
|
||||
git_repo: https://git.openstack.org/openstack/horizon
|
||||
git_fallback_repo: https://github.com/openstack/horizon
|
||||
git_dest: "/opt/{{ repo_path }}"
|
||||
git_install_branch: e53cc81fe554ac27c9c3797336f62f9da7d96226
|
||||
|
||||
pip_wheel_name: horizon
|
||||
|
||||
container_packages:
|
||||
- apache2
|
||||
- apache2-utils
|
||||
- libapache2-mod-wsgi
|
||||
- libssl-dev
|
||||
- libxslt1.1
|
||||
- openssl
|
||||
|
||||
service_pip_dependencies:
|
||||
- oslo.config
|
||||
- MySQL-python
|
||||
- python-memcached
|
||||
- django-appconf
|
||||
- pycrypto
|
||||
- ply
|
||||
- greenlet
|
||||
- python-keystoneclient
|
||||
- keystonemiddleware
|
Loading…
x
Reference in New Issue
Block a user