~junaidali/charms/trusty/plumgrid-director/oil-sapi-changes

« back to all changes in this revision

Viewing changes to hooks/pg_dir_utils.py

  • Committer: Junaid Ali
  • Date: 2016-10-15 04:33:21 UTC
  • Revision ID: junaidali@plumgrid.com-20161015043321-me89c7s143ud1lue
Changes:
  Added charm series in metadata.yaml file
  Updated README file
  Added Solutions API support for PG-ONS 6.X.X
  Added actions
  Wrapper to deal with Ubuntu versions don't have py2 installed
  Edge and gateway relations will also be used to get node's IPs
  Catalyst OPSVM changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
import time
8
8
import os
9
9
import json
10
 
import shlex
11
10
from collections import OrderedDict
12
11
from socket import gethostname as get_unit_hostname
13
12
from copy import deepcopy
25
24
    get_bridges,
26
25
    get_bridge_nics,
27
26
    is_ip,
 
27
    get_iface_addr,
 
28
    get_host_ip
28
29
)
29
30
from charmhelpers.core.host import (
30
31
    service_start,
31
 
    service_restart,
32
32
    service_stop,
33
33
    service_running,
34
34
    path_hash,
35
 
    set_nic_mtu
 
35
    set_nic_mtu,
 
36
    service_restart
36
37
)
37
38
from charmhelpers.fetch import (
38
39
    apt_cache,
41
42
from charmhelpers.contrib.openstack.utils import (
42
43
    os_release,
43
44
)
 
45
from pg_dir_context import (
 
46
    _pg_dir_ips,
 
47
    _pg_edge_ips,
 
48
    _pg_gateway_ips
 
49
)
44
50
 
45
51
SOURCES_LIST = '/etc/apt/sources.list'
46
52
LXC_CONF = '/etc/libvirt/lxc.conf'
57
63
AUTH_KEY_PATH = '%s/root/.ssh/authorized_keys' % PG_LXC_DATA_PATH
58
64
TEMP_LICENSE_FILE = '/tmp/license'
59
65
 
 
66
# Constant values for OpenStack releases as Canonical-Ubuntu
 
67
# doesn't have any specific solution version associated
 
68
OPENSTACK_RELEASE_VERS = {
 
69
    'kilo': '10',
 
70
    'liberty': '11',
 
71
    'mitaka': '12'
 
72
}
 
73
 
60
74
BASE_RESOURCE_MAP = OrderedDict([
61
75
    (PG_KA_CONF, {
62
76
        'services': ['plumgrid'],
105
119
        log('Unable to update /etc/apt/sources.list')
106
120
 
107
121
 
 
122
def configure_analyst_opsvm():
 
123
    '''
 
124
    Configures Anaylyst for OPSVM
 
125
    '''
 
126
    if not service_running('plumgrid'):
 
127
        restart_pg()
 
128
    NS_ENTER = ('/opt/local/bin/nsenter -t $(ps ho pid --ppid $(cat '
 
129
                '/var/run/libvirt/lxc/plumgrid.pid)) -m -n -u -i -p ')
 
130
    sigmund_stop = NS_ENTER + '/usr/bin/service plumgrid-sigmund stop'
 
131
    sigmund_status = NS_ENTER \
 
132
        + '/usr/bin/service plumgrid-sigmund status'
 
133
    sigmund_autoboot = NS_ENTER \
 
134
        + '/usr/bin/sigmund-configure --ip {0} --start --autoboot' \
 
135
        .format(config('opsvm-ip'))
 
136
    try:
 
137
        status = subprocess.check_output(sigmund_status, shell=True)
 
138
        if 'start/running' in status:
 
139
            if subprocess.call(sigmund_stop, shell=True):
 
140
                log('plumgrid-sigmund couldn\'t be stopped!')
 
141
                return
 
142
        subprocess.check_call(sigmund_autoboot, shell=True)
 
143
    except:
 
144
        log('plumgrid-sigmund couldn\'t be started!')
 
145
 
 
146
 
108
147
def determine_packages():
109
148
    '''
110
149
    Returns list of packages required by PLUMgrid director as specified
131
170
    return pkgs
132
171
 
133
172
 
 
173
def disable_apparmor_libvirt():
 
174
    '''
 
175
    Disables Apparmor profile of libvirtd.
 
176
    '''
 
177
    apt_install('apparmor-utils')
 
178
    apt_install('cgroup-bin')
 
179
    _exec_cmd(['sudo', 'aa-disable', '/usr/sbin/libvirtd'],
 
180
              error_msg='Error disabling AppArmor profile of libvirtd')
 
181
    disable_apparmor()
 
182
    service_restart('libvirt-bin')
 
183
 
 
184
 
 
185
def disable_apparmor():
 
186
    '''
 
187
    Disables Apparmor security for lxc.
 
188
    '''
 
189
    try:
 
190
        f = open(LXC_CONF, 'r')
 
191
    except IOError:
 
192
        log('Libvirt not installed yet')
 
193
        return 0
 
194
    filedata = f.read()
 
195
    f.close()
 
196
    newdata = filedata.replace("security_driver = \"apparmor\"",
 
197
                               "#security_driver = \"apparmor\"")
 
198
    f = open(LXC_CONF, 'w')
 
199
    f.write(newdata)
 
200
    f.close()
 
201
 
 
202
 
134
203
def register_configs(release=None):
135
204
    '''
136
205
    Returns an object of the Openstack Tempating Class which contains the
161
230
    return {cfg: rscs['services'] for cfg, rscs in resource_map().iteritems()}
162
231
 
163
232
 
164
 
def start_gateway():
165
 
    '''
166
 
    Brings up PE-gateway interface. Initial hack but will be solved when docker
167
 
    plumgrid-director package will be used. 
168
 
    '''
169
 
    count = 0
170
 
    while (count < 7):
171
 
        cmd = 'ps aux | grep launch_metadata_helper'
172
 
        output = subprocess.check_output([cmd], shell=True)
173
 
        roots = 0
174
 
        v = shlex.split(output)
175
 
        for i in v:
176
 
            if i == 'root':
177
 
                roots += 1
178
 
        if roots < 3:
179
 
            stop_pg()
180
 
            time.sleep(3)
181
 
            service_start('plumgrid')
182
 
        else:
183
 
            break
184
 
        count += 1
185
 
        time.sleep(20)
186
 
 
187
 
 
188
 
def restart_pg(gateway=None):
 
233
def restart_pg():
189
234
    '''
190
235
    Stops and Starts PLUMgrid service after flushing iptables.
191
236
    '''
203
248
                    raise ValueError("plumgrid service couldn't be started")
204
249
            else:
205
250
                raise ValueError("libvirt-bin service couldn't be started")
206
 
    if gateway:
207
 
        start_gateway()
208
251
    status_set('active', 'Unit is ready')
209
252
 
210
253
 
251
294
    '''
252
295
    mgmt_interface = config('mgmt-interface')
253
296
    if not mgmt_interface:
254
 
        return get_iface_from_addr(unit_get('private-address'))
255
 
    elif mgmt_interface and interface_exists(mgmt_interface):
 
297
        try:
 
298
            return get_iface_from_addr(unit_get('private-address'))
 
299
        except:
 
300
            for bridge_interface in get_bridges():
 
301
                if (get_host_ip(unit_get('private-address'))
 
302
                        in get_iface_addr(bridge_interface)):
 
303
                    return bridge_interface
 
304
    elif interface_exists(mgmt_interface):
256
305
        return mgmt_interface
257
306
    else:
258
307
        log('Provided managment interface %s does not exist'
317
366
    set_nic_mtu(fabric_interface, interface_mtu)
318
367
 
319
368
 
320
 
def disable_apparmor_libvirt():
321
 
    '''
322
 
    Disables Apparmor profile of libvirtd.
323
 
    '''
324
 
    apt_install('apparmor-utils')
325
 
    apt_install('cgroup-bin')
326
 
    _exec_cmd(['sudo', 'aa-disable', '/usr/sbin/libvirtd'],
327
 
              error_msg='Error disabling AppArmor profile of libvirtd')
328
 
    disable_apparmor()
329
 
    service_restart('libvirt-bin')
330
 
 
331
 
 
332
 
def disable_apparmor():
333
 
    '''
334
 
    Disables Apparmor security for lxc.
335
 
    '''
336
 
    try:
337
 
        f = open(LXC_CONF, 'r')
338
 
    except IOError:
339
 
        log('Libvirt not installed yet')
340
 
        return 0
341
 
    filedata = f.read()
342
 
    f.close()
343
 
    newdata = filedata.replace("security_driver = \"apparmor\"",
344
 
                               "#security_driver = \"apparmor\"")
345
 
    f = open(LXC_CONF, 'w')
346
 
    f.write(newdata)
347
 
    f.close()
348
 
 
349
 
 
350
369
def _exec_cmd(cmd=None, error_msg='Command exited with ERRORs', fatal=False):
351
370
    '''
352
371
    Function to execute any bash command on the node.
431
450
    return 1
432
451
 
433
452
 
 
453
def sapi_post_ips():
 
454
    """
 
455
    Posts PLUMgrid nodes IPs to solutions api server.
 
456
    """
 
457
    if not config('enable-sapi'):
 
458
        log('Solutions API support is disabled!')
 
459
        return 1
 
460
    pg_edge_ips = _pg_edge_ips()
 
461
    pg_dir_ips = _pg_dir_ips()
 
462
    pg_gateway_ips = _pg_gateway_ips()
 
463
    pg_dir_ips.append(get_host_ip(unit_get('private-address')))
 
464
    pg_edge_ips = '"edge_ips"' + ':' \
 
465
        + '"{}"'.format(','.join(str(i) for i in pg_edge_ips))
 
466
    pg_dir_ips = '"director_ips"' + ':' \
 
467
        + '"{}"'.format(','.join(str(i) for i in pg_dir_ips))
 
468
    pg_gateway_ips = '"gateway_ips"' + ':' \
 
469
        + '"{}"'.format(','.join(str(i) for i in pg_gateway_ips))
 
470
    opsvm_ip = '"opsvm_ip"' + ':' + '"{}"'.format(config('opsvm-ip'))
 
471
    virtual_ip = '"virtual_ip"' + ':' \
 
472
        + '"{}"'.format(config('plumgrid-virtual-ip'))
 
473
    JSON_IPS = ','.join([pg_dir_ips, pg_edge_ips, pg_gateway_ips,
 
474
                        opsvm_ip, virtual_ip])
 
475
    status = (
 
476
        'curl -H \'Content-Type: application/json\' -X '
 
477
        'PUT -d \'{{{0}}}\' http://{1}' + ':' + '{2}/v1/zones/{3}/allIps'
 
478
    ).format(JSON_IPS, config('lcm-ip'), config('sapi-port'),
 
479
             config('sapi-zone'))
 
480
    POST_ZONE_IPs = _exec_cmd_output(
 
481
        status,
 
482
        'Posting Zone IPs to Solutions API server failed!')
 
483
    if POST_ZONE_IPs:
 
484
        if 'success' in POST_ZONE_IPs:
 
485
            log('Successfully posted Zone IPs to Solutions API server!')
 
486
        log(POST_ZONE_IPs)
 
487
 
 
488
 
 
489
def _exec_cmd_output(cmd=None, error_msg='Command exited with ERRORs',
 
490
                     fatal=False):
 
491
    '''
 
492
    Function to get output from bash command executed on the node.
 
493
    '''
 
494
    if cmd is None:
 
495
        log("No command specified")
 
496
    else:
 
497
        if fatal:
 
498
            return subprocess.check_output(cmd, shell=True)
 
499
        else:
 
500
            try:
 
501
                return subprocess.check_output(cmd, shell=True)
 
502
            except subprocess.CalledProcessError:
 
503
                log(error_msg)
 
504
                return None
 
505
 
 
506
 
 
507
def sapi_post_license():
 
508
    '''
 
509
    Posts PLUMgrid License to solutions api server
 
510
    '''
 
511
    if not config('enable-sapi'):
 
512
        log('Solutions API support is disabled!')
 
513
        return 1
 
514
    username = '"user_name":' + '"{}"'.format(config('plumgrid-username'))
 
515
    password = '"password":' + '"{}"'.format(config('plumgrid-password'))
 
516
    license = '"license":' + '"{}"'.format(config('plumgrid-license-key'))
 
517
    JSON_LICENSE = ','.join([username, password, license])
 
518
    status = (
 
519
        'curl -H \'Content-Type: application/json\' -X '
 
520
        'PUT -d \'{{{0}}}\' http://{1}' + ':' + '{2}/v1/zones/{3}/pgLicense'
 
521
    ).format(JSON_LICENSE, config('lcm-ip'), config('sapi-port'),
 
522
             config('sapi-zone'))
 
523
    POST_LICENSE = _exec_cmd_output(
 
524
        status,
 
525
        'Posting PLUMgrid License to Solutions API server failed!')
 
526
    if POST_LICENSE:
 
527
        if 'success' in POST_LICENSE:
 
528
            log('Successfully posted license file for zone "{}"!'
 
529
                .format(config('sapi-zone')))
 
530
        log(POST_LICENSE)
 
531
 
 
532
 
 
533
def sapi_post_zone_info():
 
534
    '''
 
535
    Posts zone information to solutions api server
 
536
    '''
 
537
    if not config('enable-sapi'):
 
538
        log('Solutions API support is disabled!')
 
539
        return 1
 
540
    sol_name = '"solution_name":"Ubuntu OpenStack"'
 
541
    release = config('openstack-release')
 
542
    for key, value in OPENSTACK_RELEASE_VERS.iteritems():
 
543
        if release == value:
 
544
            sol_version = value
 
545
        else:
 
546
            sol_version = 10
 
547
    sol_version = '"solution_version":"{}"'.format(sol_version)
 
548
    pg_ons_version = _exec_cmd_output(
 
549
        'dpkg -l | grep plumgrid | awk \'{print $3}\' | '
 
550
        'sed \'s/-/./\' | cut -f1 -d"-"',
 
551
        'Unable to obtain PG ONS version'
 
552
    ).replace('\n', '')
 
553
    pg_ons_version = \
 
554
        '"pg_ons_version":"{}"'.format(pg_ons_version)
 
555
    hypervisor = '"hypervisor":"Ubuntu"'
 
556
    hypervisor_version = \
 
557
        _exec_cmd_output('lsb_release -r | awk \'{print $2}\'',
 
558
                         'Unable to obtain solution version'
 
559
                         ).replace('\n', '')
 
560
    hypervisor_version = '"hypervisor_version":"{}"' \
 
561
                         .format(hypervisor_version)
 
562
    kernel_version = _exec_cmd_output(
 
563
        'uname -r',
 
564
        'Unable to obtain kernal version').replace('\n', '')
 
565
    kernel_version = \
 
566
        '"kernel_version":"{}"'.format(kernel_version)
 
567
    cloudapex_path = '/var/lib/libvirt/filesystems/plumgrid/' \
 
568
                     'opt/pg/web/cloudApex/modules/appCloudApex' \
 
569
                     '/appCloudApex.js'
 
570
    if os.path.isfile(cloudapex_path):
 
571
        pg_cloudapex_version = 'cat ' \
 
572
            + '{}'.format(cloudapex_path) \
 
573
            + ' | grep -i appversion | awk \'{print $2}\''
 
574
        pg_cloudapex_version = \
 
575
            _exec_cmd_output(pg_cloudapex_version,
 
576
                             'Unable to retrieve CloudApex version'
 
577
                             ).replace('\n', '')
 
578
    else:
 
579
        log('CloudApex not installed!')
 
580
        pg_cloudapex_version = ''
 
581
    pg_cloudapex_version = \
 
582
        '"pg_cloudapex_version":"{}"'.format(pg_cloudapex_version)
 
583
    JSON_ZONE_INFO = ','.join([
 
584
        sol_name,
 
585
        sol_version,
 
586
        pg_ons_version,
 
587
        hypervisor,
 
588
        hypervisor_version,
 
589
        kernel_version,
 
590
        pg_cloudapex_version,
 
591
    ])
 
592
    status = (
 
593
        'curl -H \'Content-Type: application/json\' -X '
 
594
        'PUT -d \'{{{0}}}\' http://{1}:{2}/v1/zones/{3}/zoneinfo'
 
595
    ).format(JSON_ZONE_INFO, config('lcm-ip'), config('sapi-port'),
 
596
             config('sapi-zone'))
 
597
    POST_ZONE_INFO = _exec_cmd_output(
 
598
        status,
 
599
        'Posting Zone Information to Solutions API server failed!')
 
600
    if POST_ZONE_INFO:
 
601
        if 'success' in POST_ZONE_INFO:
 
602
            log('Successfully posted Zone information to Solutions API'
 
603
                ' server!')
 
604
        log(POST_ZONE_INFO)
 
605
 
 
606
 
434
607
def load_iptables():
435
608
    '''
436
609
    Loads iptables rules to allow all PLUMgrid communication.