def add_component(name, node, cluster, ha=None): """Add a component to a specified node of a specified. :param name: Component name :type name: str :param node: Machine name :type node: str :param cluster: Cluster name :type cluster: str :raises ex.LoadError: [description] :raises ex.CreationError: [description] """ for i, m in enumerate(ss.svars['nodes']): if m['name'] == node: m_index = i break else: raise ex.LoadError('node', node, 'NotExist') service = check_component(name) if not service: raise ex.LoadError('component', name, 'NotExist') if not check_service_cluster(service): raise ex.CreationError( 'cluster', cluster, 'service', service, 'NotInstalled') for i, m in enumerate(ss.svars['nodes']): if m['name'] == node: m_index = i if ha is None: ha = check_comp_number(service, name) missing_serv, missing_comp = check_service_req_service(service, ha) if missing_serv: raise ex.CreationError('component', name, 'services', missing_serv, 'ReqNotMet') if missing_comp: print_missing = [] print_missing.append('Default:') for k, v in missing_comp['default'].items(): print_missing.append(' - {} {}'.format(v, k)) print_missing.append('or High Availability:') for k, v in missing_comp['ha'].items(): print_missing.append(' - {} {}'.format(v, k)) raise ex.CreationError('service', name, 'components', print_missing, 'ReqNotMet') if name in ss.svars['nodes'][m_index]['components']: raise ex.CreationError('node', node, 'component', name, 'Installed') ss.svars['nodes'][m_index]['components'].append(name) ss.dump_config(get_services_components_hosts())
def add_node(name, ip, ram, types, cpus=1, *, cluster): """Add a node to a cluster. :param name: Machine name :type name: str :param ip: Machine's IP address :type ip: str :param ram: Machine's allocated RAM in MB :type ram: int :param types: Machine's types :type types: list str :param cluster: Cluster in which to create the node :type cluster: str :param cpus: Machine's number of CPUs, defaults to 1 :param cpus: int, optional :raises ex.LoadError: If the cluster doesn't exist or was not specified :raises ex.CreationError: If the node couldn't be created :return: True if the session context has changed :rtype: bool """ if check_node(cluster=cluster, node=name): raise ex.CreationError('node', name, 'name', name, 'Exists') if check_ip(ip, cluster=cluster): raise ex.CreationError('node', name, 'IP', ip, 'Exists') if name[0] in string.digits: raise ex.CreationError('node', name, 'name', 'A node name cannot start with a digit.', 'NameNotAllowed') if 'ldap' in types: if len(types) > 1: raise ex.CreationError('node', name, 'type', 'ldap', 'LDAPNotCompatible') m = { 'name': name, 'ip': ip, 'ram': ram, 'types': types, 'cpus': cpus, 'components': [], 'groups': [] } ss.load_config(cluster=cluster) ss.add_node(m) ss.dump_config()
def check_comp_number(service, component): """Check the maximum number of a component is not already reached. :param service: Service name :type service: str :param component: Component name :type component: str :return: True if the service is in HA mode, false otherwise """ ha = 'ha' if check_ha(service) else 'default' serv_comp_host = get_services_components_hosts() number_comp = 1 if serv_comp_host[service].get(component): number_comp = len(serv_comp_host[service][component]) + 1 for s in config['services']: if s['name'] == service: for c in s['components']: if c['name'] == component: if number_comp > c['number'][ha] \ and c['number'][ha] != -1: raise ex.CreationError('cluster', ss.svars['cluster'], 'components', component, 'MaxNumber') elif number_comp == c['number']['ha']: to_remove = {} for comp in s['components']: n = 0 max_n = comp['number']['ha'] if serv_comp_host[service].get(comp['name']): n = len(serv_comp_host[service][comp['name']]) if n > max_n and max_n != -1: to_remove[comp['name']] = n - max_n if to_remove: print_remove = [] for k, v in to_remove.items(): print_remove.append('{} {}'.format(v, k)) raise ex.CreationError('service', service, 'components', print_remove, 'TooManyHA') return True return False raise ex.LoadError('component', component, 'NotExist') raise ex.LoadError('service', service, 'NotExist')
def remove_component(component, *, node, cluster): """Remove a service of a specified node in a specified cluster. :param name: Service name :type name: str :param node: Machine name :type node: str :param cluster: Cluster name :type cluster: str :raises ex.LoadError: [description] :raises ex.CreationError: [description] """ ss.load_config(cluster) if not nodes.check_node(cluster=cluster, node=node): raise ex.LoadError('node', node, 'NotExist') service = check_component(component) if not service: raise ex.LoadError('component', component, 'NotExist') for i, m in enumerate(ss.svars['nodes']): if m['name'] == node: m_index = i if component not in ss.svars['nodes'][m_index]['components']: raise ex.CreationError('node', node, 'component', component, 'NotInstalled') ss.svars['nodes'][m_index]['components'].remove(component) ss.dump_config(get_services_components_hosts())
def edit_node(name, ip=None, ram=None, cpus=None, *, cluster): """Modify an existing node in a cluster. """ ss.load_config(cluster=cluster) if not check_node(cluster=cluster, node=name): raise ex.LoadError('node', name, 'NotExist') if check_ip(ip, cluster=cluster): raise ex.CreationError('node', name, 'IP', ip, 'Exists') changed = [] for i, m in enumerate(ss.svars['nodes']): if m['name'] == name: if ip: changed.append(["IP", ss.svars['nodes'][i]['ip'], ip]) ss.svars['nodes'][i]['ip'] = ip if ram: changed.append(["RAM", ss.svars['nodes'][i]['ram'], ram]) ss.svars['nodes'][i]['ram'] = ram if cpus: changed.append(["CPUs", ss.svars['nodes'][i]['cpus'], cpus]) ss.svars['nodes'][i]['cpus'] = cpus ss.dump_config() return changed
def create_cluster(domain, template=None, *, cluster): """Create a new cluster and load it in the session. :param name: New cluster name :type name: str :param domain: New cluster domain name :type domain: str :raises ex.CreationError: If name already used :return: True on creation success """ if checks.check_cluster(cluster): raise ex.CreationError('cluster', cluster, 'name', cluster, 'Exists') allowed_chars = string.ascii_letters + string.digits + '-' for l in cluster: if l not in allowed_chars: raise ex.CreationError('cluster', cluster, 'name', 'Allowed characters: ' + allowed_chars, 'NameNotAllowed') ss.clear() data_dir = os.path.dirname(os.path.abspath(__file__)) + '/data/' config_dir = os.path.dirname(os.path.abspath(__file__)) + '/config/' if template: try: with open(config_dir + 'templates/' + template + '.json') \ as template_file: ss.svars = json.load(template_file) except: raise ex.LoadError('template', template, 'NotExist') pathlib.Path(JUMBODIR + cluster).mkdir(parents=True) dir_util.copy_tree(data_dir, JUMBODIR + cluster) dir_util._path_created = {} ss.svars['cluster'] = cluster ss.svars['domain'] = domain if domain else '%s.local' % cluster services_components_hosts = None if template: services_components_hosts = services.get_services_components_hosts() ss.dump_config(services_components_hosts) return True
def add_service(name, ha=False, *, cluster): """Add a service to a specified cluster. :param name: Service name :type name: str :param cluster: Cluster name :type cluster: str :raises ex.LoadError: [description] :raises ex.CreationError: [description] """ ss.load_config(cluster) if not check_service(name): raise ex.LoadError('service', name, 'NotExist') if name in ss.svars['services']: raise ex.CreationError('cluster', cluster, 'service', name, 'Installed') if check_service_cluster(name): raise ex.CreationError( 'cluster', cluster, 'service', name, 'Installed') missing_serv, missing_comp = check_service_req_service(name, ha) if missing_serv: raise ex.CreationError('service', name, 'services', (' - %s' % s for s in missing_serv), 'ReqNotMet') if missing_comp: print_missing = [] print_missing.append('Default:') for k, v in missing_comp['default'].items(): print_missing.append(' - {} {}'.format(v, k)) print_missing.append('or High Availability:') for k, v in missing_comp['ha'].items(): print_missing.append(' - {} {}'.format(v, k)) raise ex.CreationError('service', name, 'components', print_missing, 'ReqNotMet') ss.svars['services'].append(name) auto_install_service(name, cluster, ha) ss.dump_config(get_services_components_hosts())
def auto_assign(service, ha, *, cluster): """Auto-install a service and its components on the best fitting hosts. :param service: Service name :type service: str :param cluster: Cluster name :type cluster: str :raises ex.LoadError: If the cluster doesn't exist :raises ex.CreationError: If the requirements are not met to install """ ss.load_config(cluster) scfg = check_service(service) if not scfg: raise ex.LoadError('service', service, 'NotExist') # dist is 'default' or 'ha' dist = 'ha' if ha else 'default' # Check loop for atomicity for component in scfg['components']: left = auto_assign_service_comp(component, dist, cluster, check=True) if left == -1: raise ex.CreationError('component', component['name'], 'hosts type (need at least 1 of them)', (' - %s' % c for c in component['hosts_types']), 'ReqNotMet') elif left > 0: raise ex.CreationError('component', component['name'], 'hosts type (need ' + str(left) + ' of them)', (' - %s' % c for c in component['hosts_types']), 'ReqNotMet') count = 0 for component in scfg['components']: auto_assign_service_comp(component, dist, cluster, check=False) count += 1 return count
def remove_service(service, *, cluster): """Remove a service of a specified cluster. :param name: Service name :type name: str :param cluster: Cluster name :type cluster: str :raises ex.LoadError: [description] :raises ex.CreationError: [description] """ ss.load_config(cluster) if not check_service(service): raise ex.LoadError('service', service, 'NotExist') if not check_service_cluster(service): raise ex.CreationError( 'cluster', cluster, 'service', service, 'NotInstalled') dependent = check_dependent_services(service) if dependent: raise ex.CreationError( 'service', service, 'services', dependent, 'Dependency' ) serv_comp = get_service_components(service) for m in ss.svars['nodes']: to_remove = [] for c in m['components']: if c in serv_comp: to_remove.append(c) for c in to_remove: m['components'].remove(c) ss.svars['services'].remove(service) ss.dump_config(get_services_components_hosts())
def generate_hbasesite_ha(hbase_comp): raise ex.CreationError('service', 'HBASE', 'mode', 'High Availability', 'NotSupported')