def _validate_and_retrieve_pre_config():
    """
    Validate whether the values in the pre-configuration file are valid
    :return: JSON contents
    """
    if not os.path.exists(PRECONFIG_FILE):
        return

    with open(PRECONFIG_FILE, 'r') as pre_config:
        try:
            config = json.loads(pre_config.read())
        except Exception as ex:
            print Interactive.boxed_message(['JSON contents could not be retrieved from file {0}.\nError message: {1}'.format(PRECONFIG_FILE, ex)])
            sys.exit(1)

    if 'asdmanager' not in config or not isinstance(config['asdmanager'], dict):
        print Interactive.boxed_message(['The ASD manager pre-configuration file must contain a "asdmanager" key with a dictionary as value'])
        sys.exit(1)

    errors = []
    config = config['asdmanager']
    actual_keys = config.keys()
    expected_keys = ['api_ip', 'api_port', 'asd_ips', 'asd_start_port', 'store']
    for key in actual_keys:
        if key not in expected_keys:
            errors.append('Key {0} is not supported by the ASD manager'.format(key))
    if len(errors) > 0:
        print Interactive.boxed_message(['Errors found while verifying pre-configuration:',
                                         ' - {0}'.format('\n - '.join(errors)),
                                         '',
                                         'Allowed keys:\n'
                                         ' - {0}'.format('\n - '.join(expected_keys))])
        sys.exit(1)

    try:
        Toolbox.verify_required_params(actual_params=config,
                                       required_params={'store': (str, ['arakoon', 'etcd'], False),
                                                        'api_ip': (str, Toolbox.regex_ip, True),
                                                        'asd_ips': (list, Toolbox.regex_ip, False),
                                                        'api_port': (int, {'min': 1025, 'max': 65535}, False),
                                                        'asd_start_port': (int, {'min': 1025, 'max': 65435}, False)})
    except RuntimeError as rte:
        print Interactive.boxed_message(['The asd-manager pre-configuration file does not contain correct information\n{0}'.format(rte)])
        sys.exit(1)
    return config
Example #2
0
    def add_service(name, client, params=None, target_name=None, startup_dependency=None, delay_registration=False):
        """
        Add a service
        :param name: Template name of the service to add
        :type name: str
        :param client: Client on which to add the service
        :type client: source.tools.localclient.LocalClient
        :param params: Additional information about the service
        :type params: dict or None
        :param target_name: Overrule default name of the service with this name
        :type target_name: str or None
        :param startup_dependency: Additional startup dependency
        :type startup_dependency: str or None
        :param delay_registration: Register the service parameters in the config management right away or not
        :type delay_registration: bool
        :return: Parameters used by the service
        :rtype: dict
        """
        if params is None:
            params = {}

        service_name = Systemd._get_name(name, client, '/opt/asd-manager/config/systemd/')
        template_file = '/opt/asd-manager/config/systemd/{0}.service'.format(service_name)

        if not client.file_exists(template_file):
            # Given template doesn't exist so we are probably using system init scripts
            return

        if target_name is not None:
            service_name = target_name

        params.update({'SERVICE_NAME': Toolbox.remove_prefix(service_name, 'ovs-'),
                       'STARTUP_DEPENDENCY': '' if startup_dependency is None else '{0}.service'.format(startup_dependency)})
        template_content = client.file_read(template_file)
        for key, value in params.iteritems():
            template_content = template_content.replace('<{0}>'.format(key), value)
        client.file_write('/lib/systemd/system/{0}.service'.format(service_name), template_content)

        try:
            client.run(['systemctl', 'daemon-reload'])
            client.run(['systemctl', 'enable', '{0}.service'.format(service_name)])
        except CalledProcessError as cpe:
            Systemd._logger.exception('Add {0}.service failed, {1}'.format(service_name, cpe.output))
            raise Exception('Add {0}.service failed, {1}'.format(service_name, cpe.output))

        if delay_registration is False:
            Systemd.register_service(service_metadata=params, node_name='')
        return params
 def list(key):
     """
     List all keys starting with specified key
     :param key: Key to list
     :type key: str
     :return: Generator with all keys
     :rtype: generator
     """
     key = ArakoonConfiguration._clean_key(key)
     client = ArakoonConfiguration.get_client()
     entries = []
     for entry in client.prefix(key):
         if key == '' or entry.startswith(key + '/'):
             cleaned = Toolbox.remove_prefix(entry, key).strip('/').split('/')[0]
             if cleaned not in entries:
                 entries.append(cleaned)
                 yield cleaned
Example #4
0
    def add_service(name, client, params=None, target_name=None, startup_dependency=None, delay_registration=False):
        """
        Add a service
        :param name: Template name of the service to add
        :type name: str
        :param client: Client on which to add the service
        :type client: source.tools.localclient.LocalClient
        :param params: Additional information about the service
        :type params: dict or None
        :param target_name: Overrule default name of the service with this name
        :type target_name: str or None
        :param startup_dependency: Additional startup dependency
        :type startup_dependency: str or None
        :param delay_registration: Register the service parameters in the config management right away or not
        :type delay_registration: bool
        :return: Parameters used by the service
        :rtype: dict
        """
        if params is None:
            params = {}

        service_name = Upstart._get_name(name, client, '/opt/asd-manager/config/upstart/')
        template_file = '/opt/asd-manager/config/upstart/{0}.conf'.format(service_name)

        if not client.file_exists(template_file):
            # Given template doesn't exist so we are probably using system init scripts
            return

        if target_name is not None:
            service_name = target_name

        params.update({'SERVICE_NAME': Toolbox.remove_prefix(service_name, 'ovs-'),
                       'STARTUP_DEPENDENCY': '' if startup_dependency is None else 'started {0}'.format(startup_dependency)})
        template_content = client.file_read(template_file)
        for key, value in params.iteritems():
            template_content = template_content.replace('<{0}>'.format(key), value)
        client.file_write('/etc/init/{0}.conf'.format(service_name), template_content)

        if delay_registration is False:
            Upstart.register_service(service_metadata=params, node_name='')
        return params
Example #5
0
 def get_candidate_versions(client, package_names):
     """
     Retrieve the versions candidate for installation of the packages provided
     :param client: Root client on which to check the candidate versions
     :type client: source.tools.localclient.LocalClient
     :param package_names: Name of the packages to check
     :type package_names: list
     :return: Package candidate versions
     :rtype: dict
     """
     DebianPackage.update(client=client)
     versions = {}
     for package_name in package_names:
         versions[package_name] = ''
         for line in client.run(['apt-cache', 'policy', package_name, DebianPackage.APT_CONFIG_STRING]).splitlines():
             line = line.strip()
             if line.startswith('Candidate:'):
                 candidate = Toolbox.remove_prefix(line, 'Candidate:').strip()
                 if candidate == '(none)':
                     candidate = ''
                 versions[package_name] = candidate
                 break
     return versions
def setup():
    """
    Interactive setup part for initial asd manager configuration with etcd
    """
    print Interactive.boxed_message(['ASD Manager setup'])
    local_client = LocalClient()
    service_name = 'asd-manager'

    print '- Verifying distribution'
    if ServiceManager.has_service(service_name, local_client):
        print ''  # Spacing
        print Interactive.boxed_message(['The ASD Manager is already installed.'])
        sys.exit(1)

    ipaddresses = check_output("ip a | grep 'inet ' | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | cut -d '/' -f 1", shell=True).strip().splitlines()
    ipaddresses = [found_ip.strip() for found_ip in ipaddresses if found_ip.strip() != '127.0.0.1']
    if not ipaddresses:
        print Interactive.boxed_message(['Could not retrieve IP information on current node'])
        sys.exit(1)

    config = None
    preconfig = '/opt/OpenvStorage/config/openvstorage_preconfig.json'
    run_interactive = True
    if os.path.exists(preconfig):
        config = {}
        with open(preconfig, 'r') as pre_config:
            try:
                config = json.load(pre_config)
            except Exception as ex:
                raise ValueError('JSON contents could not be retrieved from file {0}.\nErrormessage: {1}'.format(preconfig, ex))
        run_interactive = 'asdmanager' not in config

    if run_interactive is False:
        asd_preconfig = config['asdmanager']
        required = {'api_ip': (str, Toolbox.regex_ip),
                    'asd_ips': (list, Toolbox.regex_ip, False),
                    'api_port': (int, {'min': 1025, 'max': 65535}, False),
                    'asd_start_port': (int, {'min': 1025, 'max': 65435}, False)}
        Toolbox.verify_required_params(required_params=required,
                                       actual_params=asd_preconfig)

        api_ip = asd_preconfig['api_ip']
        api_port = asd_preconfig.get('api_port', 8500)
        asd_ips = asd_preconfig.get('asd_ips', [])
        asd_start_port = asd_preconfig.get('asd_start_port', 8600)

        if api_ip not in ipaddresses:
            print Interactive.boxed_message(['Unknown API IP provided, please choose from: {0}'.format(', '.join(ipaddresses))])
            sys.exit(1)
        if set(asd_ips).difference(set(ipaddresses)):
            print Interactive.boxed_message(['Unknown ASD IP provided, please choose from: {0}'.format(', '.join(ipaddresses))])
            sys.exit(1)
    else:
        api_ip = Interactive.ask_choice(ipaddresses, 'Select the public IP address to be used for the API')
        api_port = Interactive.ask_integer("Select the port to be used for the API", 1025, 65535, 8500)
        ipaddresses.append('All')
        asd_ips = []
        add_ips = True
        while add_ips:
            current_ips = ' - Current selected IPs: {0}'.format(asd_ips)
            new_asd_ip = Interactive.ask_choice(ipaddresses,
                                                'Select an IP address or all IP addresses to be used for the ASDs{0}'.format(current_ips if len(asd_ips) > 0 else ''),
                                                default_value='All')
            if new_asd_ip == 'All':
                ipaddresses.remove('All')
                asd_ips = []
                add_ips = False
            else:
                asd_ips.append(new_asd_ip)
                ipaddresses.remove(new_asd_ip)
                add_ips = Interactive.ask_yesno("Do you want to add another IP?")
        asd_start_port = Interactive.ask_integer("Select the port to be used for the ASDs", 1025, 65435, 8600)

    if api_port in range(asd_start_port, asd_start_port + 100):
        print Interactive.boxed_message(['API port cannot be in the range of the ASD port + 100'])
        sys.exit(1)

    print '- Initializing etcd'
    try:
        alba_node_id = EtcdConfiguration.initialize(api_ip, api_port, asd_ips, asd_start_port)
    except:
        print ''  # Spacing
        print Interactive.boxed_message(['Could not connect to Etcd.',
                                         'Please make sure an Etcd proxy is available, pointing towards an OpenvStorage cluster.'])
        sys.exit(1)

    ServiceManager.add_service(service_name, local_client, params={'ASD_NODE_ID': alba_node_id,
                                                                   'PORT_NUMBER': str(api_port)})
    print '- Starting ASD manager service'
    try:
        ServiceManager.start_service(service_name, local_client)
    except Exception as ex:
        EtcdConfiguration.uninitialize(alba_node_id)
        print Interactive.boxed_message(['Starting asd-manager failed with error:', str(ex)])
        sys.exit(1)

    print Interactive.boxed_message(['ASD Manager setup completed'])
Example #7
0
 def unregister_service(node_name, service_name):
     """
     Un-register the metadata of a service from the configuration management
     :param node_name: Unused
     :type node_name: str
     :param service_name: Name of the service to clean from the configuration management
     :type service_name: str
     :return: None
     """
     _ = node_name
     with open(Toolbox.BOOTSTRAP_FILE, 'r') as bs_file:
         node_id = json.load(bs_file)['node_id']
         Configuration.delete(key='/ovs/alba/asdnodes/{0}/services/{1}'.format(node_id, Toolbox.remove_prefix(service_name, 'ovs-')))
Example #8
0
 def register_service(node_name, service_metadata):
     """
     Register the metadata of the service to the configuration management
     :param node_name: Unused
     :type node_name: str
     :param service_metadata: Metadata of the service
     :type service_metadata: dict
     :return: None
     """
     _ = node_name
     service_name = service_metadata['SERVICE_NAME']
     with open(Toolbox.BOOTSTRAP_FILE, 'r') as bs_file:
         node_id = json.load(bs_file)['node_id']
         Configuration.set(key='/ovs/alba/asdnodes/{0}/services/{1}'.format(node_id, Toolbox.remove_prefix(service_name, 'ovs-')),
                           value=service_metadata)