def get(self, cluster_id): """Lists progress details of a specific cluster :param cluster_id: the unique identifier of the cluster """ progress_result = {} with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id)\ .first() if not cluster: error_msg = "The cluster id=%s does not exist!" % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if not cluster.state: progress_result = { 'id': cluster_id, 'state': 'UNINITIALIZED', 'percentage': 0, 'message': "Waiting..............", 'severity': "INFO" } else: progress_result['id'] = cluster_id progress_result['state'] = cluster.state.state progress_result['percentage'] = cluster.state.progress progress_result['message'] = cluster.state.message progress_result['severity'] = cluster.state.severity logging.info('progress result for cluster %s: %s', cluster_id, progress_result) return util.make_json_response( 200, {"status": "OK", "progress": progress_result})
def _remove_hosts(cluster_id, hosts): """Remove existing cluster host from the cluster""" removed_hosts = [] with database.session() as session: failed_hosts = [] for host_id in hosts: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: failed_hosts.append(host) continue host_res = {"id": host_id, "machine_id": host.machine_id} removed_hosts.append(host_res) if failed_hosts: error_msg = 'Cluster hosts do not exist!' value = {"failedHosts": failed_hosts} return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg), value) filter_clause = [] for host_id in hosts: filter_clause.append('id=%s' % host_id) # Delete the requested hosts from database session.query(ModelClusterHost).filter(or_(*filter_clause))\ .delete(synchronize_session='fetch') return util.make_json_response(200, { "status": "OK", "cluster_hosts": removed_hosts })
def get(self, host_id): """ Lists progress details of a specific cluster host :param host_id: cluster host ID in db """ progress_result = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if not host.state: progress_result = { 'id': host_id, 'state': 'UNINITIALIZED', 'percentage': 0, 'message': "Waiting..............", 'severity': "INFO", } else: progress_result['id'] = host_id progress_result['state'] = host.state.state progress_result['percentage'] = host.state.progress progress_result['message'] = host.state.message progress_result['severity'] = host.state.severity logging.info('progress result for %s: %s', host_id, progress_result) return util.make_json_response( 200, {"status": "OK", "progress": progress_result})
def _deploy(cluster_id): """Deploy the cluster""" deploy_hosts_urls = [] with database.session() as session: cluster_hosts_ids = session.query(ModelClusterHost.id)\ .filter_by(cluster_id=cluster_id).all() if not cluster_hosts_ids: # No host belongs to this cluster error_msg = ('Cannot find any host in cluster id=%s' % cluster_id) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for elm in cluster_hosts_ids: host_id = str(elm[0]) progress_url = '/cluster_hosts/%s/progress' % host_id deploy_hosts_urls.append(progress_url) # Lock cluster hosts and its cluster session.query(ModelClusterHost).filter_by(cluster_id=cluster_id)\ .update({'mutable': False}) session.query(ModelCluster).filter_by(id=cluster_id)\ .update({'mutable': False}) celery.send_task("compass.tasks.trigger_install", (cluster_id, )) return util.make_json_response(202, { "status": "OK", "deployment": deploy_hosts_urls })
def get(self, host_id): """ Lists progress details of a specific cluster host :param host_id: cluster host ID in db """ progress_result = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if not host.state: progress_result = { 'id': host_id, 'state': 'UNINITIALIZED', 'percentage': 0, 'message': "Waiting..............", 'severity': "INFO", } else: progress_result['id'] = host_id progress_result['state'] = host.state.state progress_result['percentage'] = host.state.progress progress_result['message'] = host.state.message progress_result['severity'] = host.state.severity logging.info('progress result for %s: %s', host_id, progress_result) return util.make_json_response(200, { "status": "OK", "progress": progress_result })
def delete(self, host_id, subkey): """ Delete one attribute in configuration of a specific cluster host :param host_id: the cluster host ID :param subkey: the attribute name in configuration """ available_delete_keys = ['ip', 'role'] with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if subkey not in available_delete_keys: error_msg = "subkey %s is not supported!" % subkey return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) if not host.mutable: error_msg = "The host 'id=%s' is not mutable!" % host_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) config = json.loads(host.config_data) # Set the subkey's value to "" util.update_dict_value(subkey, "", config) host.config = config return util.make_json_response( 200, {"status": "OK"})
def get(self, switch_id): """ Lists details of the switch with the specific switch id. :param switch_id: switch ID in db """ switch_res = {} with database.session() as session: switch = session.query(ModelSwitch).filter_by(id=switch_id).first() logging.info('switch for id %s: %s', switch_id, switch) if not switch: error_msg = "Cannot find the switch with id=%s" % switch_id logging.error("[/switches/{id}]error_msg: %s", error_msg) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) switch_res['id'] = switch.id switch_res['state'] = switch.state switch_res['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(switch.id)))} logging.info('switch info for %s: %s', switch_id, switch_res) return util.make_json_response( 200, {"status": "OK", "switch": switch_res})
def get(self, machine_id): """ Lists details of the machine with specific machine id. :param machine_id: the machine ID in db """ machine_res = {} with database.session() as session: machine = session.query(ModelMachine)\ .filter_by(id=machine_id)\ .first() logging.info('machine for id %s: %s', machine_id, machine) if not machine: error_msg = "Cannot find the machine with id=%s" % machine_id logging.error("[/api/machines/{id}]error_msg: %s", error_msg) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) machine_res['id'] = machine.id machine_res['mac'] = machine.mac machine_res['port'] = machine.port machine_res['vlan'] = machine.vlan if machine.switch: machine_res['switch_ip'] = machine.switch.ip else: machine_res['switch_ip'] = None machine_res['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(machine.id)))} logging.info('machine info for %s: %s', machine_id, machine_res) return util.make_json_response( 200, {"status": "OK", "machine": machine_res})
def list_adapter_roles(adapter_id): """Lists details of all roles of the specified adapter :param adapter_id: the unique identifier of the adapter """ roles_list = [] with database.session() as session: adapter_q = session.query(Adapter)\ .filter_by(id=adapter_id).first() if not adapter_q: error_msg = "Adapter id=%s does not exist!" % adapter_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) roles = session.query(Role, Adapter)\ .filter(Adapter.id == adapter_id, Adapter.target_system == Role.target_system)\ .all() for role, adapter in roles: role_res = {} role_res['name'] = role.name role_res['description'] = role.description roles_list.append(role_res) return util.make_json_response(200, {"status": "OK", "roles": roles_list})
def delete(self, host_id, subkey): """ Delete one attribute in configuration of the specified cluster host :param host_id: the unique identifier of the host :param subkey: the attribute name in configuration """ available_delete_keys = ['ip', 'roles'] with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if subkey not in available_delete_keys: error_msg = "subkey %s is not supported!" % subkey return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) if not host.mutable: error_msg = "The host 'id=%s' is not mutable!" % host_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) config = json.loads(host.config_data) # Set the subkey's value to "" util.update_dict_value(subkey, "", config) host.config = config return util.make_json_response(200, {"status": "OK"})
def get(self, cluster_id): """Lists progress details of a specific cluster :param cluster_id: the unique identifier of the cluster """ progress_result = {} with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id)\ .first() if not cluster: error_msg = "The cluster id=%s does not exist!" % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if not cluster.state: progress_result = { 'id': cluster_id, 'state': 'UNINITIALIZED', 'percentage': 0, 'message': "Waiting..............", 'severity': "INFO" } else: progress_result['id'] = cluster_id progress_result['state'] = cluster.state.state progress_result['percentage'] = cluster.state.progress progress_result['message'] = cluster.state.message progress_result['severity'] = cluster.state.severity logging.info('progress result for cluster %s: %s', cluster_id, progress_result) return util.make_json_response(200, { "status": "OK", "progress": progress_result })
def list_adapter(adapter_id): """ Lists details of the specified adapter. :param adapter_id: the unique identifier of the adapter """ endpoint = '/adapters' adapter_res = {} with database.session() as session: adapter = session.query(Adapter).filter_by(id=adapter_id).first() if not adapter: error_msg = "Adapter id=%s does not exist!" % adapter_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) adapter_res['name'] = adapter.name adapter_res['os'] = adapter.os adapter_res['id'] = adapter.id adapter_res['target_system'] = adapter.target_system, adapter_res['link'] = { "href": "/".join((endpoint, str(adapter.id))), "rel": "self"} return util.make_json_response( 200, {"status": "OK", "adapter": adapter_res})
def list_adapter_roles(adapter_id): """ Lists details of all roles of a specific adapter :param adapter_id: the adaper ID in db """ roles_list = [] with database.session() as session: adapter_q = session.query(Adapter)\ .filter_by(id=adapter_id).first() if not adapter_q: error_msg = "Adapter id=%s does not exist!" % adapter_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) roles = session.query(Role, Adapter)\ .filter(Adapter.id == adapter_id, Adapter.target_system == Role.target_system)\ .all() for role, adapter in roles: role_res = {} role_res['name'] = role.name role_res['description'] = role.description roles_list.append(role_res) return util.make_json_response( 200, {"status": "OK", "roles": roles_list})
def get(self): """ Return a list of dashboard links """ cluster_id = request.args.get('cluster_id', None) logging.info('get cluster links with cluster_id=%s', cluster_id) links = {} with database.session() as session: hosts = session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id).all() if not hosts: error_msg = "Cannot find hosts in cluster id=%s" % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for host in hosts: config = host.config if ('has_dashboard_roles' in config and config['has_dashboard_roles']): ip = config.get( 'networking', {}).get( 'interfaces', {}).get( 'management', {}).get( 'ip', '') roles = config.get('roles', []) for role in roles: links[role] = 'http://%s' % ip return util.make_json_response( 200, {"status": "OK", "dashboardlinks": links} )
def list_adapter(adapter_id): """ Lists details of the specified adapter. :param adapter_id: the unique identifier of the adapter """ endpoint = '/adapters' adapter_res = {} with database.session() as session: adapter = session.query(Adapter).filter_by(id=adapter_id).first() if not adapter: error_msg = "Adapter id=%s does not exist!" % adapter_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) adapter_res['name'] = adapter.name adapter_res['os'] = adapter.os adapter_res['id'] = adapter.id adapter_res['target_system'] = adapter.target_system, adapter_res['link'] = { "href": "/".join((endpoint, str(adapter.id))), "rel": "self" } return util.make_json_response(200, { "status": "OK", "adapter": adapter_res })
def get(self, switch_id): """Lists details of the specified switch. :param switch_id: switch ID in db """ switch_res = {} with database.session() as session: switch = session.query(ModelSwitch).filter_by(id=switch_id).first() logging.info('switch for id %s: %s', switch_id, switch) if not switch: error_msg = "Cannot find the switch with id=%s" % switch_id logging.error("[/switches/{id}]error_msg: %s", error_msg) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) switch_res['id'] = switch.id switch_res['ip'] = switch.ip switch_res['state'] = switch.state switch_res['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(switch.id))) } logging.info('switch info for %s: %s', switch_id, switch_res) return util.make_json_response(200, { "status": "OK", "switch": switch_res })
def get(self): """ Return a list of dashboard links """ cluster_id = request.args.get('cluster_id', None) logging.info('get cluster links with cluster_id=%s', cluster_id) links = {} with database.session() as session: hosts = session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id).all() if not hosts: error_msg = "Cannot find hosts in cluster id=%s" % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for host in hosts: config = host.config if ('has_dashboard_roles' in config and config['has_dashboard_roles']): ip = config.get('networking', {}).get('interfaces', {}).get('management', {}).get('ip', '') roles = config.get('roles', []) for role in roles: links[role] = 'http://%s' % ip return util.make_json_response(200, { "status": "OK", "dashboardlinks": links })
def _deploy(cluster_id): """Deploy the cluster""" deploy_hosts_urls = [] with database.session() as session: cluster_hosts_ids = session.query(ModelClusterHost.id)\ .filter_by(cluster_id=cluster_id).all() if not cluster_hosts_ids: # No host belongs to this cluster error_msg = ('Cannot find any host in cluster id=%s' % cluster_id) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for host_id in cluster_hosts_ids: progress_url = '/cluster_hosts/%s/progress' % str(host_id) deploy_hosts_urls.append(progress_url) # Lock cluster hosts and its cluster session.query(ModelClusterHost).filter_by(cluster_id=cluster_id)\ .update({'mutable': False}) session.query(ModelCluster).filter_by(id=cluster_id)\ .update({'mutable': False}) celery.send_task("compass.tasks.trigger_install", (cluster_id,)) return util.make_json_response( 202, {"status": "OK", "deployment": deploy_hosts_urls})
def put(self, cluster_id, resource): """ Update the resource information of the specified cluster in database :param cluster_id: the unique identifier of the cluster :param resource: resource name(security, networking, partition) """ resources = { self.SECURITY: { 'validator': 'is_valid_security_config', 'column': 'security_config' }, self.NETWORKING: { 'validator': 'is_valid_networking_config', 'column': 'networking_config' }, self.PARTITION: { 'validator': 'is_valid_partition_config', 'column': 'partition_config' }, } request_data = json.loads(request.data) with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id)\ .first() if not cluster: error_msg = 'You are trying to update a non-existing cluster!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if resource not in request_data: error_msg = "Invalid resource name '%s'" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) value = request_data[resource] if resource not in resources.keys(): error_msg = "Invalid resource name '%s'" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) validate_func = resources[resource]['validator'] module = globals()['util'] is_valid, msg = getattr(module, validate_func)(value) if is_valid: column = resources[resource]['column'] session.query(ModelCluster).filter_by(id=cluster_id)\ .update({column: json.dumps(value)}) else: return errors.handle_mssing_input( errors.InputMissingError(msg)) return util.make_json_response(200, {"status": "OK"})
def put(self, host_id): """ Update configuration of the specified cluster host :param host_id: the unique identifier of the host """ with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) logging.debug("cluster config put request.data %s", request.data) request_data = json.loads(request.data) if not request_data: error_msg = "request data is %s" % request_data return errors.handle_mssing_input( errors.InputMissingError(error_msg)) if not host.mutable: error_msg = "The host 'id=%s' is not mutable!" % host_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) #Valid if keywords in request_data are all correct if 'hostname' in request_data: hostname = request_data['hostname'] cluster_id = host.cluster_id test_host = session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id, hostname=hostname).first() if test_host: error_msg = ("Hostname '%s' has been used for other host " "in the cluster, cluster ID is %s!" % (hostname, cluster_id)) return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) session.query(ModelClusterHost).filter_by(id=host_id)\ .update({"hostname": request_data['hostname']}) del request_data['hostname'] try: util.valid_host_config(request_data) except errors.UserInvalidUsage as exc: return errors.handle_invalid_usage(exc) host.config = request_data return util.make_json_response( 200, {"status": "OK"})
def _add_hosts(cluster_id, hosts): """Add cluster host(s) to the cluster by cluster_id""" cluseter_hosts = [] available_machines = [] failed_machines = [] with database.session() as session: failed_machines = [] for host in hosts: # Check if machine exists machine = session.query(ModelMachine).filter_by(id=host)\ .first() if not machine: error_msg = "Machine id=%s does not exist!" % host return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) clusterhost = session.query(ModelClusterHost)\ .filter_by(machine_id=host)\ .first() if clusterhost: # Machine is already used failed_machines.append(clusterhost.machine_id) continue # Add the available machine to available_machines list available_machines.append(machine) if failed_machines: value = { 'failedMachines': failed_machines } error_msg = "Conflict!" return errors.handle_duplicate_object( errors.ObjectDuplicateError(error_msg), value ) for machine, host in zip(available_machines, hosts): host = ModelClusterHost(cluster_id=cluster_id, machine_id=machine.id) session.add(host) session.flush() cluster_res = {} cluster_res['id'] = host.id cluster_res['machine_id'] = machine.id cluseter_hosts.append(cluster_res) logging.info('cluster_hosts result is %s', cluseter_hosts) return util.make_json_response( 200, { "status": "OK", "clusterHosts": cluseter_hosts } )
def put(self, cluster_id, resource): """ Update the resource information of the specified cluster in database :param cluster_id: the unique identifier of the cluster :param resource: resource name(security, networking, partition) """ resources = { self.SECURITY: {'validator': 'is_valid_security_config', 'column': 'security_config'}, self.NETWORKING: {'validator': 'is_valid_networking_config', 'column': 'networking_config'}, self.PARTITION: {'validator': 'is_valid_partition_config', 'column': 'partition_config'}, } request_data = json.loads(request.data) with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id)\ .first() if not cluster: error_msg = 'You are trying to update a non-existing cluster!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) if resource not in request_data: error_msg = "Invalid resource name '%s'" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) value = request_data[resource] if resource not in resources.keys(): error_msg = "Invalid resource name '%s'" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) validate_func = resources[resource]['validator'] module = globals()['util'] is_valid, msg = getattr(module, validate_func)(value) if is_valid: column = resources[resource]['column'] session.query(ModelCluster).filter_by(id=cluster_id)\ .update({column: json.dumps(value)}) else: return errors.handle_mssing_input( errors.InputMissingError(msg)) return util.make_json_response( 200, {"status": "OK"})
def _deploy(cluster_id, hosts): """Deploy the cluster""" deploy_hosts_info = [] deploy_cluster_info = {} with database.session() as session: if not hosts: # Deploy all hosts in the cluster cluster_hosts = session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id).all() if not cluster_hosts: # No host belongs to this cluster error_msg = ('Cannot find any host in cluster id=%s' % cluster_id) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for host in cluster_hosts: if not host.mutable: # The host is not allowed to modified error_msg = ("The host id=%s is not allowed to be " "modified now!") % host.id return errors.UserInvalidUsage( errors.UserInvalidUsage(error_msg)) hosts.append(host.id) deploy_cluster_info["cluster_id"] = int(cluster_id) deploy_cluster_info["url"] = '/clusters/%s/progress' % cluster_id for host_id in hosts: host_info = {} progress_url = '/cluster_hosts/%s/progress' % host_id host_info["host_id"] = host_id host_info["url"] = progress_url deploy_hosts_info.append(host_info) # Lock cluster hosts and its cluster session.query(ModelClusterHost).filter_by(cluster_id=cluster_id)\ .update({'mutable': False}) session.query(ModelCluster).filter_by(id=cluster_id)\ .update({'mutable': False}) celery.send_task("compass.tasks.trigger_install", (cluster_id, hosts)) return util.make_json_response( 202, {"status": "accepted", "deployment": { "cluster": deploy_cluster_info, "hosts": deploy_hosts_info }})
def get(self, cluster_id, resource=None): """ Lists details of the specified cluster if resource is not specified. Otherwise, lists details of the resource of this cluster :param cluster_id: the unique identifier of the cluster :param resource: the resource name(security, networking, partition) """ cluster_resp = {} resp = {} with database.session() as session: cluster = session.query(ModelCluster)\ .filter_by(id=cluster_id)\ .first() logging.debug('cluster is %s', cluster) if not cluster: error_msg = 'Cannot found the cluster with id=%s' % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) if resource: # List resource details if resource == self.SECURITY: cluster_resp = cluster.security elif resource == self.NETWORKING: cluster_resp = cluster.networking elif resource == self.PARTITION: cluster_resp = cluster.partition else: error_msg = "Invalid resource name '%s'!" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg) ) resp = {"status": "OK", resource: cluster_resp} else: cluster_resp['clusterName'] = cluster.name cluster_resp['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(cluster.id))) } cluster_resp['id'] = cluster.id resp = {"status": "OK", "cluster": cluster_resp} logging.info('get cluster result is %s', cluster_resp) return util.make_json_response(200, resp)
def _add_hosts(cluster_id, hosts): """Add cluster host(s) to the cluster by cluster_id""" cluseter_hosts = [] available_machines = [] failed_machines = [] with database.session() as session: failed_machines = [] for host in hosts: # Check if machine exists machine = session.query(ModelMachine).filter_by(id=host)\ .first() if not machine: error_msg = "Machine id=%s does not exist!" % host return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) clusterhost = session.query(ModelClusterHost)\ .filter_by(machine_id=host)\ .first() if clusterhost: # Machine is already used failed_machines.append(clusterhost.machine_id) continue # Add the available machine to available_machines list available_machines.append(machine) if failed_machines: value = {'failedMachines': failed_machines} error_msg = "Conflict!" return errors.handle_duplicate_object( errors.ObjectDuplicateError(error_msg), value) for machine, host in zip(available_machines, hosts): host = ModelClusterHost(cluster_id=cluster_id, machine_id=machine.id) session.add(host) session.flush() cluster_res = {} cluster_res['id'] = host.id cluster_res['machine_id'] = machine.id cluseter_hosts.append(cluster_res) logging.info('cluster_hosts result is %s', cluseter_hosts) return util.make_json_response(200, { "status": "OK", "cluster_hosts": cluseter_hosts })
def put(self, switch_id): """Update an existing switch information. :param switch_id: the unqiue identifier of the switch """ switch = None with database.session() as session: switch = session.query(ModelSwitch).filter_by(id=switch_id).first() logging.info('PUT switch id is %s: %s', switch_id, switch) if not switch: # No switch is found. error_msg = 'Cannot update a non-existing switch!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) credential = None logging.debug('PUT a switch request from curl is %s', request.data) json_data = json.loads(request.data) credential = json_data['switch']['credential'] logging.info('PUT switch id=%s credential=%s(%s)', switch_id, credential, type(credential)) ip_addr = None switch_res = {} with database.session() as session: switch = session.query(ModelSwitch).filter_by(id=switch_id).first() switch.credential = credential switch.state = "not_reached" ip_addr = switch.ip switch_res['id'] = switch.id switch_res['ip'] = switch.ip switch_res['state'] = switch.state link = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(switch.id))) } switch_res['link'] = link celery.send_task("compass.tasks.pollswitch", (ip_addr, )) return util.make_json_response(202, { "status": "accepted", "switch": switch_res })
def get(self, cluster_id, resource=None): """ Lists details of the specified cluster if resource is not specified. Otherwise, lists details of the resource of this cluster :param cluster_id: the unique identifier of the cluster :param resource: the resource name(security, networking, partition) """ cluster_resp = {} resp = {} with database.session() as session: cluster = session.query(ModelCluster)\ .filter_by(id=cluster_id)\ .first() logging.debug('cluster is %s', cluster) if not cluster: error_msg = 'Cannot found the cluster with id=%s' % cluster_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if resource: # List resource details if resource == self.SECURITY: cluster_resp = cluster.security elif resource == self.NETWORKING: cluster_resp = cluster.networking elif resource == self.PARTITION: cluster_resp = cluster.partition else: error_msg = "Invalid resource name '%s'!" % resource return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) resp = {"status": "OK", resource: cluster_resp} else: cluster_resp['clusterName'] = cluster.name cluster_resp['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(cluster.id))) } cluster_resp['id'] = cluster.id resp = {"status": "OK", "cluster": cluster_resp} logging.info('get cluster result is %s', cluster_resp) return util.make_json_response(200, resp)
def put(self, switch_id): """Update an existing switch information. :param switch_id: the unqiue identifier of the switch """ switch = None credential = None logging.debug('PUT a switch request from curl is %s', request.data) ip_addr = None switch_res = {} with database.session() as session: switch = session.query(ModelSwitch).filter_by(id=switch_id).first() logging.info('PUT switch id is %s: %s', switch_id, switch) if not switch: # No switch is found. error_msg = 'Cannot update a non-existing switch!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) json_data = json.loads(request.data) credential = json_data['switch']['credential'] logging.info('PUT switch id=%s credential=%s(%s)', switch_id, credential, type(credential)) switch.credential = credential switch.state = "repolling" switch.err_msg = "" ip_addr = switch.ip switch_res['id'] = switch.id switch_res['ip'] = switch.ip switch_res['state'] = switch.state link = {'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(switch.id)))} switch_res['link'] = link celery.send_task("compass.tasks.pollswitch", (ip_addr,)) return util.make_json_response( 202, {"status": "accepted", "switch": switch_res})
def _remove_hosts(cluster_id, hosts): """Remove existing cluster host from the cluster""" removed_hosts = [] with database.session() as session: failed_hosts = [] for host_id in hosts: host = session.query(ModelClusterHost)\ .filter_by(id=host_id, cluster_id=cluster_id)\ .first() if not host: failed_hosts.append(host_id) continue host_res = { "id": host_id, "machine_id": host.machine_id } removed_hosts.append(host_res) if failed_hosts: error_msg = 'Hosts do not exist! Or not in this cluster' value = { "failedHosts": failed_hosts } return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg), value ) filter_clause = [] for host_id in hosts: filter_clause.append('id=%s' % host_id) # Delete the requested hosts from database session.query(ModelClusterHost).filter(or_(*filter_clause))\ .delete(synchronize_session='fetch') return util.make_json_response( 200, { "status": "OK", "cluster_hosts": removed_hosts } )
def post(self): """Create a new cluster. :param name: the name of the cluster :param adapter_id: the unique identifier of the adapter """ request_data = None request_data = json.loads(request.data) cluster_name = request_data['cluster']['name'] adapter_id = request_data['cluster']['adapter_id'] cluster_resp = {} cluster = None with database.session() as session: cluster = session.query(ModelCluster).filter_by(name=cluster_name)\ .first() if cluster: error_msg = "Cluster name '%s' already exists!" % cluster.name return errors.handle_duplicate_object( errors.ObjectDuplicateError(error_msg)) adapter = session.query(Adapter).filter_by(id=adapter_id).first() if not adapter: error_msg = "No adapter id=%s can be found!" % adapter_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) # Create a new cluster in database cluster = ModelCluster(name=cluster_name, adapter_id=adapter_id) session.add(cluster) session.flush() cluster_resp['id'] = cluster.id cluster_resp['name'] = cluster.name cluster_resp['adapter_id'] = cluster.adapter_id cluster_resp['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(cluster.id))) } return util.make_json_response( 200, {"status": "OK", "cluster": cluster_resp} )
def get(self, host_id): """ Lists configuration details of a specific cluster host :param host_id: the cluster host ID """ config_res = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: # The host does not exist. error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) config_res = host.config logging.debug("The config of host id=%s is %s", host_id, config_res) return util.make_json_response( 200, {"status": "OK", "config": config_res})
def get(self, host_id): """Lists configuration details of the specified cluster host :param host_id: the unique identifier of the host """ config_res = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: # The host does not exist. error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) config_res = host.config logging.debug("The config of host id=%s is %s", host_id, config_res) return util.make_json_response(200, { "status": "OK", "config": config_res })
def put(self, host_id): """ Update configuration of the specified cluster host :param host_id: the unique identifier of the host """ with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) logging.debug("cluster config put request.data %s", request.data) request_data = json.loads(request.data) if not request_data: error_msg = "request data is %s" % request_data return errors.handle_mssing_input( errors.InputMissingError(error_msg)) if not host.mutable: error_msg = "The host 'id=%s' is not mutable!" % host_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) #Valid if keywords in request_data are all correct if 'hostname' in request_data: session.query(ModelClusterHost).filter_by(id=host_id)\ .update({"hostname": request_data['hostname']}) del request_data['hostname'] try: util.valid_host_config(request_data) except errors.UserInvalidUsage as exc: return errors.handle_invalid_usage(exc) host.config = request_data return util.make_json_response(200, {"status": "OK"})
def get(self, machine_id): """ Lists details of the specified machine. :param machine_id: the unique identifier of the machine """ machine_res = {} with database.session() as session: machine = session.query(ModelMachine)\ .filter_by(id=machine_id)\ .first() logging.info('machine for id %s: %s', machine_id, machine) if not machine: error_msg = "Cannot find the machine with id=%s" % machine_id logging.error("[/api/machines/{id}]error_msg: %s", error_msg) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) machine_res['id'] = machine.id machine_res['mac'] = machine.mac machine_res['port'] = machine.port machine_res['vlan'] = machine.vlan if machine.switch: machine_res['switch_ip'] = machine.switch.ip else: machine_res['switch_ip'] = None machine_res['link'] = { 'rel': 'self', 'href': '/'.join((self.ENDPOINT, str(machine.id))) } logging.info('machine info for %s: %s', machine_id, machine_res) return util.make_json_response(200, { "status": "OK", "machine": machine_res })
def get(self, host_id): """ Lists details of a specific cluster host :param host_id: cluster host ID in db """ host_res = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) host_res['hostname'] = host.hostname host_res['mutable'] = host.mutable host_res['id'] = host.id host_res['link'] = { "href": '/'.join((self.ENDPOINT, str(host.id))), "rel": "self" } return util.make_json_response( 200, {"status": "OK", "cluster_host": host_res})
def get(self, host_id): """Lists details of the specified cluster host :param host_id: the unique identifier of the host """ host_res = {} with database.session() as session: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: error_msg = "The host id=%s does not exist!" % host_id return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) host_res['hostname'] = host.hostname host_res['mutable'] = host.mutable host_res['id'] = host.id host_res['link'] = { "href": '/'.join((self.ENDPOINT, str(host.id))), "rel": "self" } return util.make_json_response(200, { "status": "OK", "cluster_host": host_res })
def execute_cluster_action(cluster_id): """Execute the specified action to the cluster. :param cluster_id: the unique identifier of the cluster :param addHosts: the action of adding excepted hosts to the cluster :param removeHosts: the action of removing expected hosts from the cluster :param replaceAllHosts: the action of removing all existing hosts in cluster and add new hosts :param deploy: the action of starting to deploy """ def _add_hosts(cluster_id, hosts): """Add cluster host(s) to the cluster by cluster_id""" cluseter_hosts = [] available_machines = [] failed_machines = [] with database.session() as session: failed_machines = [] for host in hosts: # Check if machine exists machine = session.query(ModelMachine).filter_by(id=host)\ .first() if not machine: error_msg = "Machine id=%s does not exist!" % host return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) clusterhost = session.query(ModelClusterHost)\ .filter_by(machine_id=host)\ .first() if clusterhost: # Machine is already used failed_machines.append(clusterhost.machine_id) continue # Add the available machine to available_machines list available_machines.append(machine) if failed_machines: value = {'failedMachines': failed_machines} error_msg = "Conflict!" return errors.handle_duplicate_object( errors.ObjectDuplicateError(error_msg), value) for machine, host in zip(available_machines, hosts): host = ModelClusterHost(cluster_id=cluster_id, machine_id=machine.id) session.add(host) session.flush() cluster_res = {} cluster_res['id'] = host.id cluster_res['machine_id'] = machine.id cluseter_hosts.append(cluster_res) logging.info('cluster_hosts result is %s', cluseter_hosts) return util.make_json_response(200, { "status": "OK", "cluster_hosts": cluseter_hosts }) def _remove_hosts(cluster_id, hosts): """Remove existing cluster host from the cluster""" removed_hosts = [] with database.session() as session: failed_hosts = [] for host_id in hosts: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: failed_hosts.append(host) continue host_res = {"id": host_id, "machine_id": host.machine_id} removed_hosts.append(host_res) if failed_hosts: error_msg = 'Cluster hosts do not exist!' value = {"failedHosts": failed_hosts} return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg), value) filter_clause = [] for host_id in hosts: filter_clause.append('id=%s' % host_id) # Delete the requested hosts from database session.query(ModelClusterHost).filter(or_(*filter_clause))\ .delete(synchronize_session='fetch') return util.make_json_response(200, { "status": "OK", "cluster_hosts": removed_hosts }) def _replace_all_hosts(cluster_id, hosts): """Remove all existing hosts from the cluster and add new ones""" with database.session() as session: # Delete all existing hosts of the cluster session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id).delete() session.flush() return _add_hosts(cluster_id, hosts) def _deploy(cluster_id): """Deploy the cluster""" deploy_hosts_urls = [] with database.session() as session: cluster_hosts_ids = session.query(ModelClusterHost.id)\ .filter_by(cluster_id=cluster_id).all() if not cluster_hosts_ids: # No host belongs to this cluster error_msg = ('Cannot find any host in cluster id=%s' % cluster_id) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for elm in cluster_hosts_ids: host_id = str(elm[0]) progress_url = '/cluster_hosts/%s/progress' % host_id deploy_hosts_urls.append(progress_url) # Lock cluster hosts and its cluster session.query(ModelClusterHost).filter_by(cluster_id=cluster_id)\ .update({'mutable': False}) session.query(ModelCluster).filter_by(id=cluster_id)\ .update({'mutable': False}) celery.send_task("compass.tasks.trigger_install", (cluster_id, )) return util.make_json_response(202, { "status": "OK", "deployment": deploy_hosts_urls }) request_data = None with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id).first() if not cluster: error_msg = 'Cluster id=%s does not exist!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) if not cluster.mutable: # The cluster cannot be deploy again error_msg = "The cluster id=%s cannot deploy again!" % cluster_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) request_data = json.loads(request.data) action = request_data.keys()[0] value = request_data.get(action) if 'addHosts' in request_data: return _add_hosts(cluster_id, value) elif 'removeHosts' in request_data: return _remove_hosts(cluster_id, value) elif 'deploy' in request_data: return _deploy(cluster_id) elif 'replaceAllHosts' in request_data: return _replace_all_hosts(cluster_id, value) else: return errors.handle_invalid_usage( errors.UserInvalidUsage('%s action is not support!' % action))
def execute_cluster_action(cluster_id): """ Execute a specific action to the cluster: addHosts: add excepted hosts to the cluster removeHosts: remove expected hosts from the cluster replaceAllHosts: remove all existing hosts in cluster and add new hosts deploy: start to deploy :param cluster_id: string of cluster id """ def _add_hosts(cluster_id, hosts): """Add cluster host(s) to the cluster by cluster_id""" cluseter_hosts = [] available_machines = [] failed_machines = [] with database.session() as session: failed_machines = [] for host in hosts: # Check if machine exists machine = session.query(ModelMachine).filter_by(id=host)\ .first() if not machine: error_msg = "Machine id=%s does not exist!" % host return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) clusterhost = session.query(ModelClusterHost)\ .filter_by(machine_id=host)\ .first() if clusterhost: # Machine is already used failed_machines.append(clusterhost.machine_id) continue # Add the available machine to available_machines list available_machines.append(machine) if failed_machines: value = { 'failedMachines': failed_machines } error_msg = "Conflict!" return errors.handle_duplicate_object( errors.ObjectDuplicateError(error_msg), value ) for machine, host in zip(available_machines, hosts): host = ModelClusterHost(cluster_id=cluster_id, machine_id=machine.id) session.add(host) session.flush() cluster_res = {} cluster_res['id'] = host.id cluster_res['machine_id'] = machine.id cluseter_hosts.append(cluster_res) logging.info('cluster_hosts result is %s', cluseter_hosts) return util.make_json_response( 200, { "status": "OK", "clusterHosts": cluseter_hosts } ) def _remove_hosts(cluster_id, hosts): """Remove existing cluster host from the cluster""" removed_hosts = [] with database.session() as session: failed_hosts = [] for host_id in hosts: host = session.query(ModelClusterHost).filter_by(id=host_id)\ .first() if not host: failed_hosts.append(host) continue host_res = { "id": host_id, "machine_id": host.machine_id } removed_hosts.append(host_res) if failed_hosts: error_msg = 'Cluster hosts do not exist!' value = { "failedHosts": failed_hosts } return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg), value ) filter_clause = [] for host_id in hosts: filter_clause.append('id=%s' % host_id) # Delete the requested hosts from database session.query(ModelClusterHost).filter(or_(*filter_clause))\ .delete(synchronize_session='fetch') return util.make_json_response( 200, { "status": "OK", "clusterHosts": removed_hosts } ) def _replace_all_hosts(cluster_id, hosts): """Remove all existing hosts from the cluster and add new ones""" with database.session() as session: # Delete all existing hosts of the cluster session.query(ModelClusterHost)\ .filter_by(cluster_id=cluster_id).delete() session.flush() return _add_hosts(cluster_id, hosts) def _deploy(cluster_id): """Deploy the cluster""" deploy_hosts_urls = [] with database.session() as session: cluster_hosts_ids = session.query(ModelClusterHost.id)\ .filter_by(cluster_id=cluster_id).all() if not cluster_hosts_ids: # No host belongs to this cluster error_msg = ('Cannot find any host in cluster id=%s' % cluster_id) return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg)) for host_id in cluster_hosts_ids: progress_url = '/cluster_hosts/%s/progress' % str(host_id) deploy_hosts_urls.append(progress_url) # Lock cluster hosts and its cluster session.query(ModelClusterHost).filter_by(cluster_id=cluster_id)\ .update({'mutable': False}) session.query(ModelCluster).filter_by(id=cluster_id)\ .update({'mutable': False}) celery.send_task("compass.tasks.trigger_install", (cluster_id,)) return util.make_json_response( 202, {"status": "OK", "deployment": deploy_hosts_urls}) request_data = None with database.session() as session: cluster = session.query(ModelCluster).filter_by(id=cluster_id).first() if not cluster: error_msg = 'Cluster id=%s does not exist!' return errors.handle_not_exist( errors.ObjectDoesNotExist(error_msg) ) if not cluster.mutable: # The cluster cannot be deploy again error_msg = "The cluster id=%s cannot deploy again!" % cluster_id return errors.handle_invalid_usage( errors.UserInvalidUsage(error_msg)) request_data = json.loads(request.data) action = request_data.keys()[0] value = request_data.get(action) if 'addHosts' in request_data: return _add_hosts(cluster_id, value) elif 'removeHosts' in request_data: return _remove_hosts(cluster_id, value) elif 'deploy' in request_data: return _deploy(cluster_id) elif 'replaceAllHosts' in request_data: return _replace_all_hosts(cluster_id, value) else: return errors.handle_invalid_usage( errors.UserInvalidUsage('%s action is not support!' % action) )