Solutions API changes

Signed-off-by: plumgrid <Junaid Ali>
This commit is contained in:
plumgrid 2016-08-09 01:07:49 -04:00
parent 420e95c089
commit 3cd01f1099
13 changed files with 293 additions and 8 deletions

8
actions.yaml Normal file
View File

@ -0,0 +1,8 @@
restart-pg:
description: Restart the plumgrid-director unit's service.
post-ips:
description: Post PLUMgrid nodes IPs to Solutions API server.
post-zone-info:
description: Post Zone info to Solutions API server.
post-license:
description: Post PLUMgrid License to Solutions API server.

65
actions/actions.py Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/python
import os
import sys
sys.path.append('hooks/')
from charmhelpers.core.hookenv import action_fail
from pg_dir_utils import (
restart_pg,
sapi_post_zone_info,
sapi_post_license,
sapi_post_ips
)
def restart_pg(args):
"""
Restart PLUMgrid services.
"""
restart_pg()
def post_ips(args):
"""
POST plumgrid nodes IPs to solutions api server.
"""
sapi_post_ips()
def post_zone_info(args):
"""
POST zone information to solutions api server
"""
sapi_post_zone_info()
def post_license(args):
"""
POST PLUMgrid License to solutions api server
"""
sapi_post_license()
# A dictionary of all the defined actions to callables (which take
# parsed arguments).
ACTIONS = {"restart-pg": restart_pg, "post-ips": post_ips, "post-zone-info": post_zone_info,
"post-license": post_license}
def main(args):
action_name = os.path.basename(args[0])
try:
action = ACTIONS[action_name]
except KeyError:
return "Action %s undefined" % action_name
else:
try:
action(args)
except Exception as e:
action_fail(str(e))
if __name__ == "__main__":
sys.exit(main(sys.argv))

1
actions/post-ips Symbolic link
View File

@ -0,0 +1 @@
actions.py

1
actions/post-license Symbolic link
View File

@ -0,0 +1 @@
actions.py

1
actions/post-zone-info Symbolic link
View File

@ -0,0 +1 @@
actions.py

1
actions/restart-pg Symbolic link
View File

@ -0,0 +1 @@
actions.py

View File

@ -56,3 +56,14 @@ options:
default: 127.0.0.1
type: string
description: IP address of the PLUMgrid Operations VM Management interface.
lcm-ip:
type: string
description: IP used by Solutions API to get/post cloud information.
sapi-port:
default: 8099
type: int
description: Port used by Solutions API to get/post cloud information.
sapi-zone:
default: pgzone
type: string
description: Zone name used by Solutions API to get/post cloud information.

View File

@ -26,6 +26,30 @@ from socket import (
)
def _pg_edge_ips():
'''
Inspects edge-peer relation and returns the
ips of the edge nodes
'''
return [get_host_ip(rdata['private-address'])
for rid in relation_ids("plumgrid")
for rdata in
(relation_get(rid=rid, unit=unit) for unit in related_units(rid))
if 'edge-peer' in rdata]
def _pg_gateway_ips():
'''
Inspects gateway-peer relation and returns the
ips of the gateway nodes
'''
return [get_host_ip(rdata['private-address'])
for rid in relation_ids("plumgrid")
for rdata in
(relation_get(rid=rid, unit=unit) for unit in related_units(rid))
if 'gateway-peer' in rdata]
def _pg_dir_ips():
'''
Inspects plumgrid-director peer relation and returns the

View File

@ -9,7 +9,6 @@ import sys
import time
from charmhelpers.core.host import service_running
from charmhelpers.contrib.network.ip import is_ip
from charmhelpers.core.hookenv import (
Hooks,
UnregisteredHookError,
@ -42,7 +41,10 @@ from pg_dir_utils import (
restart_on_change,
director_cluster_ready,
configure_pg_sources,
configure_analyst_opsvm
configure_analyst_opsvm,
sapi_post_ips,
sapi_post_license,
sapi_post_zone_info
)
hooks = Hooks()
@ -67,6 +69,7 @@ def install():
@hooks.hook('director-relation-joined')
@hooks.hook('director-relation-changed')
@restart_on_change(restart_map())
def dir_joined():
'''
@ -77,16 +80,24 @@ def dir_joined():
CONFIGS.write_all()
@hooks.hook('plumgrid-relation-joined')
@hooks.hook('plumgrid-relation-joined',
'plumgrid-relation-changed',
'plumgrid-relation-departed')
def plumgrid_joined(relation_id=None):
'''
This hook is run when relation with edge or gateway is created.
'''
opsvm_ip = config('opsvm-ip')
if not is_ip(opsvm_ip):
raise ValueError('Incorrect OPSVM IP specified')
raise ValueError('Invalid OPSVM IP specified!')
else:
relation_set(relation_id=relation_id, opsvm_ip=opsvm_ip)
if is_leader():
if is_ip(config('lcm-ip')):
sapi_post_ips()
sapi_post_zone_info()
else:
raise ValueError('Invalid LCM IP specified!')
@hooks.hook('plumgrid-configs-relation-joined')
@ -117,6 +128,8 @@ def config_changed():
if charm_config.changed('plumgrid-license-key'):
if is_leader() and post_pg_license():
log("PLUMgrid License Posted")
# Post PG license to Sol-API
sapi_post_license()
if charm_config.changed('fabric-interfaces'):
if not fabric_interface_changed():
log("Fabric interface already set")
@ -124,6 +137,8 @@ def config_changed():
stop_pg()
if charm_config.changed('plumgrid-virtual-ip'):
CONFIGS.write_all()
for rid in relation_ids('plumgrid'):
plumgrid_joined(rid)
stop_pg()
for rid in relation_ids('plumgrid-configs'):
plumgrid_configs_joined(rid)
@ -149,6 +164,12 @@ def config_changed():
for rid in relation_ids('plumgrid'):
plumgrid_joined(rid)
stop_pg()
# TODO
if (charm_config.changed('sapi-port') or
charm_config.changed('lcm-ip') or
charm_config.changed('sapi-zone')):
for rid in relation_ids('plumgrid'):
plumgrid_joined(rid)
ensure_mtu()
CONFIGS.write_all()
if not service_running('plumgrid'):
@ -161,6 +182,7 @@ def start():
This hook is run when the charm is started.
'''
configure_analyst_opsvm()
sapi_post_zone_info()
if config('plumgrid-license-key') is not None:
count = 0
while (count < 10):

View File

@ -24,6 +24,8 @@ from charmhelpers.contrib.network.ip import (
get_bridges,
get_bridge_nics,
is_ip,
get_iface_addr,
get_host_ip
)
from charmhelpers.core.host import (
service_start,
@ -39,6 +41,11 @@ from charmhelpers.fetch import (
from charmhelpers.contrib.openstack.utils import (
os_release,
)
from pg_dir_context import (
_pg_dir_ips,
_pg_edge_ips,
_pg_gateway_ips
)
SOURCES_LIST = '/etc/apt/sources.list'
LXC_CONF = '/etc/libvirt/lxc.conf'
@ -109,8 +116,8 @@ def configure_analyst_opsvm():
'''
if not service_running('plumgrid'):
restart_pg()
NS_ENTER = ('/opt/local/bin/nsenter -t $(ps ho pid --ppid '
'$(cat /var/run/libvirt/lxc/plumgrid.pid)) -m -n -u -i -p ')
NS_ENTER = ('/opt/local/bin/nsenter -t $(ps ho pid --ppid $(cat '
'/var/run/libvirt/lxc/plumgrid.pid)) -m -n -u -i -p ')
sigmund_stop = NS_ENTER + '/usr/bin/service plumgrid-sigmund stop'
sigmund_status = NS_ENTER \
+ '/usr/bin/service plumgrid-sigmund status'
@ -248,7 +255,13 @@ def get_mgmt_interface():
'''
mgmt_interface = config('mgmt-interface')
if not mgmt_interface:
return get_iface_from_addr(unit_get('private-address'))
try:
return get_iface_from_addr(unit_get('private-address'))
except:
for bridge_interface in get_bridges():
if (get_host_ip(unit_get('private-address'))
in get_iface_addr(bridge_interface)):
return bridge_interface
elif interface_exists(mgmt_interface):
return mgmt_interface
else:
@ -398,6 +411,141 @@ def post_pg_license():
return 1
def sapi_post_ips():
pg_edge_ips = _pg_edge_ips()
pg_dir_ips = _pg_dir_ips()
pg_gateway_ips = _pg_gateway_ips()
pg_dir_ips.append(get_host_ip(unit_get('private-address')))
pg_edge_ips = '"edge_ips"' + ':' \
+ '"{}"'.format(','.join(str(i) for i in pg_edge_ips))
pg_dir_ips = '"director_ips"' + ':' \
+ '"{}"'.format(','.join(str(i) for i in pg_dir_ips))
pg_gateway_ips = '"gateway_ips"' + ':' \
+ '"{}"'.format(','.join(str(i) for i in pg_gateway_ips))
opsvm_ip = '"opsvm_ip"' + ':' + '"{}"'.format(config('opsvm-ip'))
virtual_ip = '"virtual_ip"' + ':' \
+ '"{}"'.format(config('plumgrid-virtual-ip'))
JSON_IPS = ','.join([pg_dir_ips, pg_edge_ips, pg_gateway_ips,
opsvm_ip, virtual_ip])
status = (
'curl -H \'Content-Type: application/json\' -X '
'PUT -d \'{{{0}}}\' http://{1}' + ':' + '{2}/v1/zones/{3}/allIps'
).format(JSON_IPS, config('lcm-ip'), config('sapi-port'),
config('sapi-zone'))
print "POST_IPS {}".format(status)
if 'success' in _exec_cmd_output(
status,
'No response from specified LCM IP!'):
log('Successfully posted Zone IPs to Solutions API server!')
def _exec_cmd_output(cmd=None, error_msg='Command exited with ERRORs',
fatal=False):
'''
Function to get output from bash command executed on the node.
'''
if cmd is None:
log("No command specified")
else:
if fatal:
return subprocess.check_output(cmd, shell=True)
else:
try:
return subprocess.check_output(cmd, shell=True)
except subprocess.CalledProcessError:
log(error_msg)
return None
def sapi_post_license():
username = '"user_name":' + '"{}"'.format(config('plumgrid-username'))
password = '"password":' + '"{}"'.format(config('plumgrid-password'))
license = '"license":' + '"{}"'.format(config('plumgrid-license-key'))
JSON_LICENSE = ','.join([username, password, license])
status = (
'curl -H \'Content-Type: application/json\' -X '
'PUT -d \'{{{0}}}\' http://{1}' + ':' + '{2}/v1/zones/{3}/pgLicense'
).format(JSON_LICENSE, config('lcm-ip'), config('sapi-port'),
config('sapi-zone'))
print "POST_LICENSE status: {}".format(status)
if 'success' in _exec_cmd_output(
status,
'No response from specified LCM IP!'):
log('Successfully posted license file for zone "{}"!'
.format(config('sapi-zone')))
def sapi_post_zone_info():
sol_name = '"solution_name":"Ubuntu OpenStack"'
sol_version = '"solution_version":"12"'
pg_ons_version = _exec_cmd_output(
'dpkg -l | grep plumgrid | awk \'{print $3}\' | '
'sed \'s/-/./\' | cut -f1 -d"-"',
'Unable to obtain PG ONS version'
).replace('\n', '')
pg_ons_version = \
'"pg_ons_version":"{}"'.format(pg_ons_version)
hypervisor = '"hypervisor":"Ubuntu"'
hypervisor_version = \
_exec_cmd_output('lsb_release -r | awk \'{print $2}\'',
'Unable to obtain solution version'
).replace('\n', '')
hypervisor_version = '"hypervisor_version":"{}"' \
.format(hypervisor_version)
kernel_version = _exec_cmd_output(
'uname -r',
'Unable to obtain kernal version').replace('\n', '')
kernel_version = \
'"kernel_version":"{}"'.format(kernel_version)
cloudapex_path = '/var/lib/libvirt/filesystems/plumgrid/' \
'opt/pg/web/cloudApex/modules/appCloudApex' \
'/appCloudApex.js'
if os.path.isfile(cloudapex_path):
pg_cloudapex_version = 'cat ' \
+ '{}'.format(cloudapex_path) \
+ ' | grep -i appversion | awk \'{print $2}\''
pg_cloudapex_version = \
_exec_cmd_output(pg_cloudapex_version,
'Unable to retrieve CloudApex version'
).replace('\n', '')
else:
log('CloudApex not installed!')
pg_cloudapex_version = ''
pg_cloudapex_version = \
'"pg_cloudapex_version":"{}"'.format(pg_cloudapex_version)
JSON_ZONE_INFO = ','.join([
sol_name,
sol_version,
pg_ons_version,
hypervisor,
hypervisor_version,
kernel_version,
pg_cloudapex_version,
])
status = (
'curl -H \'Content-Type: application/json\' -X '
'PUT -d \'{{{0}}}\' http://{1}:{2}/v1/zones/{3}/zoneinfo'
).format(JSON_ZONE_INFO, config('lcm-ip'), config('sapi-port'),
config('sapi-zone'))
print "ZONE_INFO status = {}".format(status)
if 'success' in _exec_cmd_output(
status,
'No response from specified LCM IP!'):
log('Successfully posted Zone IPs to Solutions API server!')
def is_zone_info_available():
zone_info = 'curl -H "Content-Type: application/json" -X GET '\
+ 'http://{}:8099/v1/zones/pgzone/zoneInfo'.format(config('lcm-ip'))
try:
status = subprocess.check_output(zone_info, shell=True)
if "success" in status:
return True
except:
log('No response from specified LCM IP')
return False
def load_iptables():
'''
Loads iptables rules to allow all PLUMgrid communication.

View File

@ -0,0 +1 @@
pg_dir_hooks.py

View File

@ -0,0 +1 @@
pg_dir_hooks.py

View File

@ -33,7 +33,8 @@ TO_PATCH = [
'config',
'load_iptables',
'status_set',
'configure_analyst_opsvm'
'configure_analyst_opsvm',
'sapi_post_zone_info'
]
NEUTRON_CONF_DIR = "/etc/neutron"