delete cluster and set cluster_id in chef server env

Change-Id: I33b7d978a0f2cfabd1a6e3b0177dfec059dc9666
This commit is contained in:
xiaodongwang 2014-10-24 14:11:40 -07:00
parent 8de7a30142
commit a8b54b2258
23 changed files with 776 additions and 357 deletions

View File

@ -16,11 +16,8 @@
"""binary to deploy a cluster by compass client api.""" """binary to deploy a cluster by compass client api."""
import logging import logging
import netaddr
import os import os
import re import re
import requests
import simplejson as json
import socket import socket
import sys import sys
import time import time
@ -32,6 +29,10 @@ sys.path.append(current_dir)
import switch_virtualenv import switch_virtualenv
import netaddr
import requests
import simplejson as json
from compass.apiclient.restful import Client from compass.apiclient.restful import Client
from compass.utils import flags from compass.utils import flags
from compass.utils import logsetting from compass.utils import logsetting

View File

@ -28,17 +28,19 @@ sys.path.append(current_dir)
import switch_virtualenv import switch_virtualenv
from compass.actions import delete
from compass.db.api import cluster as cluster_api from compass.db.api import cluster as cluster_api
from compass.db.api import database from compass.db.api import database
from compass.db.api import host as host_api
from compass.db.api import user as user_api from compass.db.api import user as user_api
from compass.db.api import utils from compass.tasks.client import celery
from compass.db import models
from compass.utils import flags from compass.utils import flags
from compass.utils import logsetting from compass.utils import logsetting
from compass.utils import setting_wrapper as setting from compass.utils import setting_wrapper as setting
flags.add_bool('async',
help='run in async mode',
default=True)
flags.add('clusternames', flags.add('clusternames',
help='comma seperated cluster names', help='comma seperated cluster names',
default='') default='')
@ -47,27 +49,46 @@ flags.add_bool('delete_hosts',
default=False) default=False)
if __name__ == '__main__': def delete_clusters():
flags.init()
logsetting.init()
database.init()
clusternames = [ clusternames = [
clustername clustername
for clustername in flags.OPTIONS.clusternames.split(',') for clustername in flags.OPTIONS.clusternames.split(',')
if clustername if clustername
] ]
logging.info('delete clusters %s', clusternames)
user = user_api.get_user_object(setting.COMPASS_ADMIN_EMAIL) user = user_api.get_user_object(setting.COMPASS_ADMIN_EMAIL)
clusters = cluster_api.list_clusters( clusters = cluster_api.list_clusters(
user, name=clusternames user, name=clusternames
) )
if flags.OPTIONS.delete_hosts: delete_underlying_host = flags.OPTIONS.delete_hosts
for cluster in clusters:
hosts = cluster_api.list_cluster_hosts(
user, cluster['id'])
for host in hosts:
logging.info('delete host %s', host['hostname'])
host_api.del_host(user, host['id'])
for cluster in clusters: for cluster in clusters:
logging.info('delete cluster %s', cluster['name']) cluster_id = cluster['id']
cluster_api.del_cluster(user, cluster['id']) hosts = cluster_api.list_cluster_hosts(user, cluster_id)
host_id_list = [host['id'] for host in hosts]
if flags.OPTIONS.async:
celery.send_task(
'compass.tasks.delete_cluster',
(
setting.COMPASS_ADMIN_EMAIL,
cluster_id,
host_id_list,
delete_underlying_host
)
)
else:
try:
delete.delete_cluster(
cluster_id,
host_id_list,
setting.COMPASS_ADMIN_EMAIL,
delete_underlying_host
)
except Exception as error:
logging.error('failed to delete cluster %s', cluster)
logging.exception(error)
if __name__ == '__main__':
flags.init()
logsetting.init()
database.init()
delete_clusters()

View File

@ -16,7 +16,6 @@
"""main script to poll machines which is connected to the switches.""" """main script to poll machines which is connected to the switches."""
import functools import functools
import lockfile
import logging import logging
import os import os
import sys import sys
@ -28,6 +27,7 @@ sys.path.append(current_dir)
import switch_virtualenv import switch_virtualenv
import lockfile
from multiprocessing import Pool from multiprocessing import Pool
from compass.actions import poll_switch from compass.actions import poll_switch

View File

@ -16,7 +16,6 @@
"""main script to run as service to update hosts installing progress.""" """main script to run as service to update hosts installing progress."""
import functools import functools
import lockfile
import logging import logging
import os import os
import sys import sys
@ -28,6 +27,8 @@ sys.path.append(current_dir)
import switch_virtualenv import switch_virtualenv
import lockfile
from compass.actions import update_progress from compass.actions import update_progress
from compass.db.api import database from compass.db.api import database
from compass.tasks.client import celery from compass.tasks.client import celery

View File

@ -1,47 +0,0 @@
# Copyright 2014 Huawei Technologies Co. Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module to clean deployment of a given cluster
.. moduleauthor:: Xiaodong Wang <xiaodongwang@huawei.com>
"""
import logging
from compass.actions import util
from compass.config_management.utils.config_manager import ConfigManager
from compass.db.api import database
def clean_deployment(cluster_hosts):
"""Clean deployment of clusters.
:param cluster_hosts: clusters and hosts in each cluster to clean.
:type cluster_hosts: dict of int or str to list of int or str
.. note::
The function should be called out of database session.
"""
with util.lock('serialized_action') as lock:
if not lock:
raise Exception(
'failed to acquire lock to clean deployment')
logging.debug('clean cluster_hosts: %s', cluster_hosts)
with database.session():
cluster_hosts, os_versions, target_systems = (
util.update_cluster_hosts(cluster_hosts))
manager = ConfigManager()
manager.clean_cluster_and_hosts(
cluster_hosts, os_versions, target_systems)
manager.sync()

129
compass/actions/delete.py Normal file
View File

@ -0,0 +1,129 @@
# Copyright 2014 Huawei Technologies Co. Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module to delete a given cluster
"""
import logging
from compass.actions import util
from compass.db.api import user as user_db
from compass.deployment.deploy_manager import DeployManager
from compass.deployment.utils import constants as const
def delete_cluster(
cluster_id, host_id_list,
username=None, delete_underlying_host=False
):
"""Delete cluster.
:param cluster_id: id of the cluster.
:type cluster_id: int
.. note::
The function should be called out of database session.
"""
with util.lock('serialized_action', timeout=100) as lock:
if not lock:
raise Exception('failed to acquire lock to delete cluster')
user = user_db.get_user_object(username)
cluster_info = util.ActionHelper.get_cluster_info(cluster_id, user)
adapter_id = cluster_info[const.ADAPTER_ID]
adapter_info = util.ActionHelper.get_adapter_info(
adapter_id, cluster_id, user)
hosts_info = util.ActionHelper.get_hosts_info(
cluster_id, host_id_list, user)
deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info)
logging.debug('Created deploy manager with %s %s %s'
% (adapter_info, cluster_info, hosts_info))
deploy_manager.remove_hosts(
package_only=not delete_underlying_host,
delete_cluster=True
)
util.ActionHelper.delete_cluster(
cluster_id, host_id_list, user,
delete_underlying_host
)
def delete_cluster_host(
cluster_id, host_id,
username=None, delete_underlying_host=False
):
with util.lock('serialized_action', timeout=100) as lock:
if not lock:
raise Exception('failed to acquire lock to delete clusterhost')
user = user_db.get_user_object(username)
cluster_info = util.ActionHelper.get_cluster_info(cluster_id, user)
adapter_id = cluster_info[const.ADAPTER_ID]
adapter_info = util.ActionHelper.get_adapter_info(
adapter_id, cluster_id, user)
hosts_info = util.ActionHelper.get_hosts_info(
cluster_id, [host_id], user)
deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info)
logging.debug('Created deploy manager with %s %s %s'
% (adapter_info, cluster_info, hosts_info))
deploy_manager.remove_hosts(
package_only=not delete_underlying_host,
delete_cluster=False
)
util.ActionHelper.delete_cluster_host(
cluster_id, host_id, user,
delete_underlying_host
)
def delete_host(
host_id, cluster_id_list, username=None
):
with util.lock('serialized_action', timeout=100) as lock:
if not lock:
raise Exception('failed to acquire lock to delete host')
user = user_db.get_user_object(username)
for cluster_id in cluster_id_list:
cluster_info = util.ActionHelper.get_cluster_info(
cluster_id, user)
adapter_id = cluster_info[const.ADAPTER_ID]
adapter_info = util.ActionHelper.get_adapter_info(
adapter_id, cluster_id, user)
hosts_info = util.ActionHelper.get_hosts_info(
cluster_id, [host_id], user)
deploy_manager = DeployManager(
adapter_info, cluster_info, hosts_info)
logging.debug('Created deploy manager with %s %s %s'
% (adapter_info, cluster_info, hosts_info))
deploy_manager.remove_hosts(
package_only=True,
delete_cluster=False
)
util.ActionHelper.delete_host(
host_id, user
)
ActionHelper = util.ActionHelper

View File

@ -14,15 +14,12 @@
"""Module to deploy a given cluster """Module to deploy a given cluster
""" """
import logging
from compass.actions import util from compass.actions import util
from compass.db.api import adapter_holder as adapter_db
from compass.db.api import cluster as cluster_db
from compass.db.api import machine as machine_db
from compass.db.api import user as user_db from compass.db.api import user as user_db
from compass.deployment.deploy_manager import DeployManager from compass.deployment.deploy_manager import DeployManager
from compass.deployment.utils import constants as const from compass.deployment.utils import constants as const
import logging
def deploy(cluster_id, hosts_id_list, username=None): def deploy(cluster_id, hosts_id_list, username=None):
@ -40,13 +37,13 @@ def deploy(cluster_id, hosts_id_list, username=None):
user = user_db.get_user_object(username) user = user_db.get_user_object(username)
cluster_info = ActionHelper.get_cluster_info(cluster_id, user) cluster_info = util.ActionHelper.get_cluster_info(cluster_id, user)
adapter_id = cluster_info[const.ADAPTER_ID] adapter_id = cluster_info[const.ADAPTER_ID]
adapter_info = ActionHelper.get_adapter_info(adapter_id, cluster_id, adapter_info = util.ActionHelper.get_adapter_info(
user) adapter_id, cluster_id, user)
hosts_info = ActionHelper.get_hosts_info(cluster_id, hosts_id_list, hosts_info = util.ActionHelper.get_hosts_info(
user) cluster_id, hosts_id_list, user)
deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info) deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info)
#deploy_manager.prepare_for_deploy() #deploy_manager.prepare_for_deploy()
@ -54,8 +51,8 @@ def deploy(cluster_id, hosts_id_list, username=None):
% (adapter_info, cluster_info, hosts_info)) % (adapter_info, cluster_info, hosts_info))
deployed_config = deploy_manager.deploy() deployed_config = deploy_manager.deploy()
ActionHelper.save_deployed_config(deployed_config, user) util.ActionHelper.save_deployed_config(deployed_config, user)
ActionHelper.update_state(cluster_id, hosts_id_list, user) util.ActionHelper.update_state(cluster_id, hosts_id_list, user)
def redeploy(cluster_id, hosts_id_list, username=None): def redeploy(cluster_id, hosts_id_list, username=None):
@ -69,20 +66,21 @@ def redeploy(cluster_id, hosts_id_list, username=None):
raise Exception('failed to acquire lock to deploy') raise Exception('failed to acquire lock to deploy')
user = user_db.get_user_object(username) user = user_db.get_user_object(username)
cluster_info = ActionHelper.get_cluster_info(cluster_id, user) cluster_info = util.ActionHelper.get_cluster_info(cluster_id, user)
adapter_id = cluster_info[const.ADAPTER_ID] adapter_id = cluster_info[const.ADAPTER_ID]
adapter_info = ActionHelper.get_adapter_info(adapter_id, adapter_info = util.ActionHelper.get_adapter_info(
cluster_id, adapter_id, cluster_id, user)
user) hosts_info = util.ActionHelper.get_hosts_info(
hosts_info = ActionHelper.get_hosts_info(cluster_id, cluster_id, hosts_id_list, user)
hosts_id_list,
user)
deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info) deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info)
# deploy_manager.prepare_for_deploy() # deploy_manager.prepare_for_deploy()
deploy_manager.redeploy() deploy_manager.redeploy()
ActionHelper.update_state(cluster_id, hosts_id_list, user) util.ActionHelper.update_state(cluster_id, hosts_id_list, user)
ActionHelper = util.ActionHelper
class ServerPowerMgmt(object): class ServerPowerMgmt(object):
@ -117,192 +115,3 @@ class HostPowerMgmt(object):
@staticmethod @staticmethod
def reset(host_id, user): def reset(host_id, user):
pass pass
class ActionHelper(object):
@staticmethod
def get_adapter_info(adapter_id, cluster_id, user):
"""Get adapter information. Return a dictionary as below,
{
"id": 1,
"name": "xxx",
"flavors": [
{
"flavor_name": "xxx",
"roles": ['xxx', 'yyy', ...],
"template": "xxx.tmpl"
},
...
],
"metadata": {
"os_config": {
...
},
"package_config": {
...
}
},
"os_installer": {
"name": "cobbler",
"settings": {....}
},
"pk_installer": {
"name": "chef",
"settings": {....}
},
...
}
To view a complete output, please refer to backend doc.
"""
adapter_info = adapter_db.get_adapter(user, adapter_id)
metadata = cluster_db.get_cluster_metadata(user, cluster_id)
adapter_info.update({const.METADATA: metadata})
for flavor_info in adapter_info[const.FLAVORS]:
roles = flavor_info[const.ROLES]
flavor_info[const.ROLES] = ActionHelper._get_role_names(roles)
return adapter_info
@staticmethod
def _get_role_names(roles):
return [role[const.NAME] for role in roles]
@staticmethod
def get_cluster_info(cluster_id, user):
"""Get cluster information.Return a dictionary as below,
{
"id": 1,
"adapter_id": 1,
"os_version": "CentOS-6.5-x86_64",
"name": "cluster_01",
"flavor": {
"flavor_name": "zzz",
"template": "xx.tmpl",
"roles": [...]
}
"os_config": {..},
"package_config": {...},
"deployed_os_config": {},
"deployed_package_config": {},
"owner": "xxx"
}
"""
cluster_info = cluster_db.get_cluster(user, cluster_id)
# convert roles retrieved from db into a list of role names
roles_info = cluster_info.setdefault(
const.FLAVOR, {}).setdefault(const.ROLES, [])
cluster_info[const.FLAVOR][const.ROLES] = \
ActionHelper._get_role_names(roles_info)
# get cluster config info
cluster_config = cluster_db.get_cluster_config(user, cluster_id)
cluster_info.update(cluster_config)
deploy_config = cluster_db.get_cluster_deployed_config(user,
cluster_id)
cluster_info.update(deploy_config)
return cluster_info
@staticmethod
def get_hosts_info(cluster_id, hosts_id_list, user):
"""Get hosts information. Return a dictionary as below,
{
"hosts": {
1($host_id): {
"reinstall_os": True,
"mac": "xxx",
"name": "xxx",
"roles": [xxx, yyy]
},
"networks": {
"eth0": {
"ip": "192.168.1.1",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "192.168.1.0/24"
},
"eth1": {...}
},
"os_config": {},
"package_config": {},
"deployed_os_config": {},
"deployed_package_config": {}
},
2: {...},
....
}
}
"""
hosts_info = {}
for host_id in hosts_id_list:
info = cluster_db.get_cluster_host(user, cluster_id, host_id)
logging.debug("checking on info %r %r" % (host_id, info))
info[const.ROLES] = ActionHelper._get_role_names(info[const.ROLES])
# TODO(grace): Is following line necessary??
info.setdefault(const.ROLES, [])
config = cluster_db.get_cluster_host_config(user,
cluster_id,
host_id)
info.update(config)
networks = info[const.NETWORKS]
networks_dict = {}
# Convert networks from list to dictionary format
for entry in networks:
nic_info = {}
nic_info = {
entry[const.NIC]: {
const.IP_ADDR: entry[const.IP_ADDR],
const.NETMASK: entry[const.NETMASK],
const.MGMT_NIC_FLAG: entry[const.MGMT_NIC_FLAG],
const.PROMISCUOUS_FLAG: entry[const.PROMISCUOUS_FLAG],
const.SUBNET: entry[const.SUBNET]
}
}
networks_dict.update(nic_info)
info[const.NETWORKS] = networks_dict
hosts_info[host_id] = info
return hosts_info
@staticmethod
def save_deployed_config(deployed_config, user):
cluster_config = deployed_config[const.CLUSTER]
cluster_id = cluster_config[const.ID]
del cluster_config[const.ID]
cluster_db.update_cluster_deployed_config(user, cluster_id,
**cluster_config)
hosts_id_list = deployed_config[const.HOSTS].keys()
for host_id in hosts_id_list:
config = deployed_config[const.HOSTS][host_id]
cluster_db.update_cluster_host_deployed_config(user,
cluster_id,
host_id,
**config)
@staticmethod
def update_state(cluster_id, host_id_list, user):
# update all clusterhosts state
for host_id in host_id_list:
cluster_db.update_cluster_host_state(user, cluster_id, host_id,
state='INSTALLING')
# update cluster state
cluster_db.update_cluster_state(user, cluster_id, state='INSTALLING')
@staticmethod
def get_machine_IPMI(machine_id, user):
machine_info = machine_db.get_machine(user, machine_id)
return machine_info[const.IPMI_CREDS]

View File

@ -21,8 +21,11 @@ import redis
from contextlib import contextmanager from contextlib import contextmanager
from compass.db.api import database from compass.db.api import adapter_holder as adapter_db
from compass.db import models from compass.db.api import cluster as cluster_db
from compass.db.api import host as host_db
from compass.db.api import machine as machine_db
from compass.deployment.utils import constants as const
@contextmanager @contextmanager
@ -53,3 +56,223 @@ def lock(lock_name, blocking=True, timeout=10):
logging.debug('released lock %s', lock_name) logging.debug('released lock %s', lock_name)
else: else:
logging.debug('nothing to release %s', lock_name) logging.debug('nothing to release %s', lock_name)
class ActionHelper(object):
@staticmethod
def get_adapter_info(adapter_id, cluster_id, user):
"""Get adapter information. Return a dictionary as below,
{
"id": 1,
"name": "xxx",
"flavors": [
{
"flavor_name": "xxx",
"roles": ['xxx', 'yyy', ...],
"template": "xxx.tmpl"
},
...
],
"metadata": {
"os_config": {
...
},
"package_config": {
...
}
},
"os_installer": {
"name": "cobbler",
"settings": {....}
},
"pk_installer": {
"name": "chef",
"settings": {....}
},
...
}
To view a complete output, please refer to backend doc.
"""
adapter_info = adapter_db.get_adapter(user, adapter_id)
metadata = cluster_db.get_cluster_metadata(user, cluster_id)
adapter_info.update({const.METADATA: metadata})
for flavor_info in adapter_info[const.FLAVORS]:
roles = flavor_info[const.ROLES]
flavor_info[const.ROLES] = ActionHelper._get_role_names(roles)
return adapter_info
@staticmethod
def _get_role_names(roles):
return [role[const.NAME] for role in roles]
@staticmethod
def get_cluster_info(cluster_id, user):
"""Get cluster information.Return a dictionary as below,
{
"id": 1,
"adapter_id": 1,
"os_version": "CentOS-6.5-x86_64",
"name": "cluster_01",
"flavor": {
"flavor_name": "zzz",
"template": "xx.tmpl",
"roles": [...]
}
"os_config": {..},
"package_config": {...},
"deployed_os_config": {},
"deployed_package_config": {},
"owner": "xxx"
}
"""
cluster_info = cluster_db.get_cluster(user, cluster_id)
# convert roles retrieved from db into a list of role names
roles_info = cluster_info.setdefault(
const.FLAVOR, {}).setdefault(const.ROLES, [])
cluster_info[const.FLAVOR][const.ROLES] = \
ActionHelper._get_role_names(roles_info)
# get cluster config info
cluster_config = cluster_db.get_cluster_config(user, cluster_id)
cluster_info.update(cluster_config)
deploy_config = cluster_db.get_cluster_deployed_config(user,
cluster_id)
cluster_info.update(deploy_config)
return cluster_info
@staticmethod
def get_hosts_info(cluster_id, hosts_id_list, user):
"""Get hosts information. Return a dictionary as below,
{
"hosts": {
1($host_id): {
"reinstall_os": True,
"mac": "xxx",
"name": "xxx",
"roles": [xxx, yyy]
},
"networks": {
"eth0": {
"ip": "192.168.1.1",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "192.168.1.0/24"
},
"eth1": {...}
},
"os_config": {},
"package_config": {},
"deployed_os_config": {},
"deployed_package_config": {}
},
2: {...},
....
}
}
"""
hosts_info = {}
for host_id in hosts_id_list:
info = cluster_db.get_cluster_host(user, cluster_id, host_id)
logging.debug("checking on info %r %r" % (host_id, info))
info[const.ROLES] = ActionHelper._get_role_names(info[const.ROLES])
# TODO(grace): Is following line necessary??
info.setdefault(const.ROLES, [])
config = cluster_db.get_cluster_host_config(user,
cluster_id,
host_id)
info.update(config)
networks = info[const.NETWORKS]
networks_dict = {}
# Convert networks from list to dictionary format
for entry in networks:
nic_info = {}
nic_info = {
entry[const.NIC]: {
const.IP_ADDR: entry[const.IP_ADDR],
const.NETMASK: entry[const.NETMASK],
const.MGMT_NIC_FLAG: entry[const.MGMT_NIC_FLAG],
const.PROMISCUOUS_FLAG: entry[const.PROMISCUOUS_FLAG],
const.SUBNET: entry[const.SUBNET]
}
}
networks_dict.update(nic_info)
info[const.NETWORKS] = networks_dict
hosts_info[host_id] = info
return hosts_info
@staticmethod
def save_deployed_config(deployed_config, user):
cluster_config = deployed_config[const.CLUSTER]
cluster_id = cluster_config[const.ID]
del cluster_config[const.ID]
cluster_db.update_cluster_deployed_config(user, cluster_id,
**cluster_config)
hosts_id_list = deployed_config[const.HOSTS].keys()
for host_id in hosts_id_list:
config = deployed_config[const.HOSTS][host_id]
cluster_db.update_cluster_host_deployed_config(user,
cluster_id,
host_id,
**config)
@staticmethod
def update_state(cluster_id, host_id_list, user):
# update all clusterhosts state
for host_id in host_id_list:
cluster_db.update_cluster_host_state(user, cluster_id, host_id,
state='INSTALLING')
# update cluster state
cluster_db.update_cluster_state(user, cluster_id, state='INSTALLING')
@staticmethod
def delete_cluster(
cluster_id, host_id_list, user, delete_underlying_host=False
):
if delete_underlying_host:
for host_id in host_id_list:
host_db.del_host_from_database(
user, host_id
)
cluster_db.del_cluster_from_database(
user, cluster_id
)
@staticmethod
def delete_cluster_host(
cluster_id, host_id, user, delete_underlying_host=False
):
if delete_underlying_host:
host_db.del_host_from_database(
user, host_id
)
cluster_db.del_cluster_host_from_database(
user, cluster_id, host_id
)
@staticmethod
def delete_host(host_id, user):
host_db.del_host_from_database(
user, host_id
)
@staticmethod
def get_machine_IPMI(machine_id, user):
machine_info = machine_db.get_machine(user, machine_id)
return machine_info[const.IPMI_CREDS]

View File

@ -1346,7 +1346,7 @@ def delete_cluster(cluster_id):
"""Delete cluster.""" """Delete cluster."""
data = _get_request_data() data = _get_request_data()
return utils.make_json_response( return utils.make_json_response(
200, 202,
cluster_api.del_cluster( cluster_api.del_cluster(
current_user, cluster_id, **data current_user, cluster_id, **data
) )
@ -1613,7 +1613,7 @@ def delete_cluster_host(cluster_id, host_id):
"""Delete cluster host.""" """Delete cluster host."""
data = _get_request_data() data = _get_request_data()
return utils.make_json_response( return utils.make_json_response(
200, 202,
cluster_api.del_cluster_host( cluster_api.del_cluster_host(
current_user, cluster_id, host_id, **data current_user, cluster_id, host_id, **data
) )
@ -1630,7 +1630,7 @@ def delete_clusterhost(clusterhost_id):
"""Delete cluster host.""" """Delete cluster host."""
data = _get_request_data() data = _get_request_data()
return utils.make_json_response( return utils.make_json_response(
200, 202,
cluster_api.del_clusterhost( cluster_api.del_clusterhost(
current_user, clusterhost_id, **data current_user, clusterhost_id, **data
) )
@ -1918,7 +1918,7 @@ def delete_host(host_id):
"""Delete host.""" """Delete host."""
data = _get_request_data() data = _get_request_data()
return utils.make_json_response( return utils.make_json_response(
200, 202,
host_api.del_host( host_api.del_host(
current_user, host_id, **data current_user, host_id, **data
) )

View File

@ -292,9 +292,14 @@ def update_cluster(session, updater, cluster_id, **kwargs):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER permission.PERMISSION_DEL_CLUSTER
) )
@utils.wrap_to_dict(RESP_FIELDS) @utils.wrap_to_dict(
['status', 'cluster', 'hosts'],
cluster=RESP_FIELDS,
hosts=RESP_CLUSTERHOST_FIELDS
)
def del_cluster(session, deleter, cluster_id, **kwargs): def del_cluster(session, deleter, cluster_id, **kwargs):
"""Delete a cluster.""" """Delete a cluster."""
from compass.tasks import client as celery_client
cluster = utils.get_db_object( cluster = utils.get_db_object(
session, models.Cluster, id=cluster_id session, models.Cluster, id=cluster_id
) )
@ -302,6 +307,32 @@ def del_cluster(session, deleter, cluster_id, **kwargs):
session, cluster, deleter, session, cluster, deleter,
reinstall_distributed_system_set=True reinstall_distributed_system_set=True
) )
clusterhosts = []
for clusterhost in cluster.clusterhosts:
clusterhosts.append(clusterhost)
celery_client.celery.send_task(
'compass.tasks.delete_cluster',
(
deleter.email, cluster_id,
[clusterhost.host_id for clusterhost in clusterhosts]
)
)
return {
'status': 'delete action sent',
'cluster': cluster,
'hosts': clusterhosts
}
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER
)
def del_cluster_from_database(session, deleter, cluster_id):
cluster = utils.get_db_object(
session, models.Cluster, id=cluster_id
)
return utils.del_db_object(session, cluster) return utils.del_db_object(session, cluster)
@ -802,9 +833,10 @@ def patch_clusterhost(
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER_HOST permission.PERMISSION_DEL_CLUSTER_HOST
) )
@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) @utils.wrap_to_dict(['status', 'host'], host=RESP_CLUSTERHOST_FIELDS)
def del_cluster_host(session, deleter, cluster_id, host_id, **kwargs): def del_cluster_host(session, deleter, cluster_id, host_id, **kwargs):
"""Delete cluster host.""" """Delete cluster host."""
from compass.tasks import client as celery_client
clusterhost = utils.get_db_object( clusterhost = utils.get_db_object(
session, models.ClusterHost, session, models.ClusterHost,
cluster_id=cluster_id, host_id=host_id cluster_id=cluster_id, host_id=host_id
@ -813,9 +845,27 @@ def del_cluster_host(session, deleter, cluster_id, host_id, **kwargs):
session, clusterhost.cluster, deleter, session, clusterhost.cluster, deleter,
reinstall_distributed_system_set=True reinstall_distributed_system_set=True
) )
return utils.del_db_object( celery_client.celery.send_task(
session, clusterhost 'compass.tasks.delete_cluster_host',
(
deleter.email, cluster_id, host_id
)
) )
return {
'status': 'delete action sent',
'host': clusterhost,
}
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER_HOST
)
def del_cluster_host_from_database(session, deleter, cluster_id, host_id):
clusterhost = utils.get_db_object(
session, models.ClusterHost, id=cluster_id, host_id=host_id
)
return utils.del_db_object(session, clusterhost)
@utils.supported_filters([]) @utils.supported_filters([])
@ -823,9 +873,10 @@ def del_cluster_host(session, deleter, cluster_id, host_id, **kwargs):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER_HOST permission.PERMISSION_DEL_CLUSTER_HOST
) )
@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) @utils.wrap_to_dict(['status', 'host'], host=RESP_CLUSTERHOST_FIELDS)
def del_clusterhost(session, deleter, clusterhost_id, **kwargs): def del_clusterhost(session, deleter, clusterhost_id, **kwargs):
"""Delete cluster host.""" """Delete cluster host."""
from compass.tasks import client as celery_client
clusterhost = utils.get_db_object( clusterhost = utils.get_db_object(
session, models.ClusterHost, session, models.ClusterHost,
clusterhost_id=clusterhost_id clusterhost_id=clusterhost_id
@ -834,9 +885,27 @@ def del_clusterhost(session, deleter, clusterhost_id, **kwargs):
session, clusterhost.cluster, deleter, session, clusterhost.cluster, deleter,
reinstall_distributed_system_set=True reinstall_distributed_system_set=True
) )
return utils.del_db_object( celery_client.celery.send_task(
session, clusterhost 'compass.tasks.delete_cluster_host',
(
deleter.email, clusterhost.cluster_id, clusterhost.host_id
)
) )
return {
'status': 'delete action sent',
'host': clusterhost,
}
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_CLUSTER_HOST
)
def del_clusterhost_from_database(session, deleter, clusterhost_id):
clusterhost = utils.get_db_object(
session, models.ClusterHost, clusterhost_id=clusterhost_id
)
return utils.del_db_object(session, clusterhost)
@utils.supported_filters([]) @utils.supported_filters([])

View File

@ -317,9 +317,11 @@ def update_hosts(session, updater, data=[]):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_HOST permission.PERMISSION_DEL_HOST
) )
@utils.wrap_to_dict(RESP_FIELDS) @utils.wrap_to_dict(['status', 'host'], host=RESP_FIELDS)
def del_host(session, deleter, host_id, **kwargs): def del_host(session, deleter, host_id, **kwargs):
"""Delete a host.""" """Delete a host."""
from compass.db.api import cluster as cluster_api
from compass.tasks import client as celery_client
host = utils.get_db_object( host = utils.get_db_object(
session, models.Host, id=host_id session, models.Host, id=host_id
) )
@ -327,6 +329,34 @@ def del_host(session, deleter, host_id, **kwargs):
session, host, deleter, session, host, deleter,
reinstall_os_set=True reinstall_os_set=True
) )
cluster_ids = []
for clusterhost in host.clusterhosts:
cluster_api.is_cluster_editable(
session, clusterhost.cluster, deleter,
reinstall_distributed_system_set=True
)
cluster_ids.append(clusterhost.cluster_id)
celery_client.celery.send_task(
'compass.tasks.delete_host',
(
deleter.email, host_id, cluster_ids
)
)
return {
'status': 'delete action sent',
'host': host,
}
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEL_HOST
)
def del_host_from_database(session, deleter, host_id):
host = utils.get_db_object(
session, models.Host, id=host_id
)
return utils.del_db_object(session, host) return utils.del_db_object(session, host)

View File

@ -128,6 +128,13 @@ def patch_machine(session, updater, machine_id, **kwargs):
def del_machine(session, deleter, machine_id, **kwargs): def del_machine(session, deleter, machine_id, **kwargs):
"""Delete a machine.""" """Delete a machine."""
machine = utils.get_db_object(session, models.Machine, id=machine_id) machine = utils.get_db_object(session, models.Machine, id=machine_id)
if machine.host:
host = machine.host
raise exception.NotAcceptable(
'machine %s has host %s on it' % (
machine.mac, host.name
)
)
return utils.del_db_object(session, machine) return utils.del_db_object(session, machine)

View File

@ -125,4 +125,18 @@ def del_subnet(session, deleter, subnet_id, **kwargs):
subnet = utils.get_db_object( subnet = utils.get_db_object(
session, models.Subnet, id=subnet_id session, models.Subnet, id=subnet_id
) )
if subnet.host_networks:
host_networks = [
'%s:%s=%s' % (
host_network.host.name, host_network.interface,
host_network.ip
)
for host_network in subnet.host_networks
]
raise exception.NotAcceptable(
'subnet %s contains host networks %s' % (
subnet.subnet, host_networks
)
)
return utils.del_db_object(session, subnet) return utils.del_db_object(session, subnet)

View File

@ -462,12 +462,12 @@ def get_db_object(session, table, exception_when_missing=True, **kwargs):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s get db object %s from table %s', 'session %s get db object %s from table %s',
session, kwargs, table.__name__) id(session), kwargs, table.__name__)
db_object = model_filter( db_object = model_filter(
model_query(session, table), table, **kwargs model_query(session, table), table, **kwargs
).first() ).first()
logging.debug( logging.debug(
'session %s got db object %s', session, db_object 'session %s got db object %s', id(session), db_object
) )
if db_object: if db_object:
return db_object return db_object
@ -488,7 +488,7 @@ def add_db_object(session, table, exception_when_existing=True,
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s add object %s atributes %s to table %s', 'session %s add object %s atributes %s to table %s',
session, args, kwargs, table.__name__) id(session), args, kwargs, table.__name__)
argspec = inspect.getargspec(table.__init__) argspec = inspect.getargspec(table.__init__)
arg_names = argspec.args[1:] arg_names = argspec.args[1:]
arg_defaults = argspec.defaults arg_defaults = argspec.defaults
@ -526,7 +526,7 @@ def add_db_object(session, table, exception_when_existing=True,
db_object.initialize() db_object.initialize()
db_object.validate() db_object.validate()
logging.debug( logging.debug(
'session %s db object %s added', session, db_object 'session %s db object %s added', id(session), db_object
) )
return db_object return db_object
@ -536,7 +536,7 @@ def list_db_objects(session, table, order_by=[], **filters):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s list db objects by filters %s in table %s', 'session %s list db objects by filters %s in table %s',
session, filters, table.__name__ id(session), filters, table.__name__
) )
db_objects = model_order_by( db_objects = model_order_by(
model_filter( model_filter(
@ -549,7 +549,7 @@ def list_db_objects(session, table, order_by=[], **filters):
).all() ).all()
logging.debug( logging.debug(
'session %s got listed db objects: %s', 'session %s got listed db objects: %s',
session, db_objects id(session), db_objects
) )
return db_objects return db_objects
@ -559,7 +559,7 @@ def del_db_objects(session, table, **filters):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s delete db objects by filters %s in table %s', 'session %s delete db objects by filters %s in table %s',
session, filters, table.__name__ id(session), filters, table.__name__
) )
query = model_filter( query = model_filter(
model_query(session, table), table, **filters model_query(session, table), table, **filters
@ -567,7 +567,7 @@ def del_db_objects(session, table, **filters):
db_objects = query.all() db_objects = query.all()
query.delete(synchronize_session=False) query.delete(synchronize_session=False)
logging.debug( logging.debug(
'session %s db objects %s deleted', session, db_objects 'session %s db objects %s deleted', id(session), db_objects
) )
return db_objects return db_objects
@ -577,7 +577,7 @@ def update_db_objects(session, table, **filters):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s update db objects by filters %s in table %s', 'session %s update db objects by filters %s in table %s',
session, filters, table.__name__) id(session), filters, table.__name__)
db_objects = model_filter( db_objects = model_filter(
model_query(session, table), table, **filters model_query(session, table), table, **filters
).all() ).all()
@ -587,7 +587,8 @@ def update_db_objects(session, table, **filters):
db_object.update() db_object.update()
db_object.validate() db_object.validate()
logging.debug( logging.debug(
'session %s db objects %s updated', session, db_objects 'session %s db objects %s updated',
id(session), db_objects
) )
return db_objects return db_objects
@ -597,7 +598,7 @@ def update_db_object(session, db_object, **kwargs):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s update db object %s by value %s', 'session %s update db object %s by value %s',
session, db_object, kwargs id(session), db_object, kwargs
) )
for key, value in kwargs.items(): for key, value in kwargs.items():
setattr(db_object, key, value) setattr(db_object, key, value)
@ -605,7 +606,8 @@ def update_db_object(session, db_object, **kwargs):
db_object.update() db_object.update()
db_object.validate() db_object.validate()
logging.debug( logging.debug(
'session %s db object %s updated', session, db_object 'session %s db object %s updated',
id(session), db_object
) )
return db_object return db_object
@ -615,12 +617,12 @@ def del_db_object(session, db_object):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
logging.debug( logging.debug(
'session %s delete db object %s', 'session %s delete db object %s',
session, db_object id(session), db_object
) )
session.delete(db_object) session.delete(db_object)
logging.debug( logging.debug(
'session %s db object %s deleted', 'session %s db object %s deleted',
session, db_object id(session), db_object
) )
return db_object return db_object

View File

@ -486,6 +486,9 @@ class HostNetwork(BASE, TimestampMixin, HelperMixin):
self.interface = interface self.interface = interface
super(HostNetwork, self).__init__(**kwargs) super(HostNetwork, self).__init__(**kwargs)
def __str__(self):
return 'HostNetwork[%s=%s]' % (self.interface, self.ip)
@property @property
def ip(self): def ip(self):
return str(netaddr.IPAddress(self.ip_int)) return str(netaddr.IPAddress(self.ip_int))
@ -558,6 +561,11 @@ class ClusterHostLogHistory(BASE, LogHistoryMixin):
self.filename = filename self.filename = filename
super(ClusterHostLogHistory, self).__init__(**kwargs) super(ClusterHostLogHistory, self).__init__(**kwargs)
def __str__(self):
return 'ClusterHostLogHistory[%s:%s]' % (
self.clusterhost_id, self.filename
)
def initialize(self): def initialize(self):
self.cluster_id = self.clusterhost.cluster_id self.cluster_id = self.clusterhost.cluster_id
self.host_id = self.clusterhost.host_id self.host_id = self.clusterhost.host_id
@ -580,6 +588,9 @@ class HostLogHistory(BASE, LogHistoryMixin):
self.filename = filename self.filename = filename
super(HostLogHistory, self).__init__(**kwargs) super(HostLogHistory, self).__init__(**kwargs)
def __str__(self):
return 'HostLogHistory[%s:%s]' % (self.id, self.filename)
class ClusterHostState(BASE, StateMixin): class ClusterHostState(BASE, StateMixin):
"""ClusterHost state table.""" """ClusterHost state table."""
@ -594,6 +605,11 @@ class ClusterHostState(BASE, StateMixin):
primary_key=True primary_key=True
) )
def __str__(self):
return 'ClusterHostState[%s state %s percentage %s]' % (
self.id, self.state, self.percentage
)
def update(self): def update(self):
super(ClusterHostState, self).update() super(ClusterHostState, self).update()
host_state = self.clusterhost.host.state host_state = self.clusterhost.host.state
@ -655,6 +671,9 @@ class ClusterHost(BASE, TimestampMixin, HelperMixin):
self.state = ClusterHostState() self.state = ClusterHostState()
super(ClusterHost, self).__init__(**kwargs) super(ClusterHost, self).__init__(**kwargs)
def __str__(self):
return 'ClusterHost[%s:%s]' % (self.clusterhost_id, self.name)
def update(self): def update(self):
if self.host.reinstall_os: if self.host.reinstall_os:
if self.state in ['SUCCESSFUL', 'ERROR']: if self.state in ['SUCCESSFUL', 'ERROR']:
@ -662,7 +681,8 @@ class ClusterHost(BASE, TimestampMixin, HelperMixin):
self.state.state = 'INITIALIZED' self.state.state = 'INITIALIZED'
else: else:
self.state.state = 'UNINITIALIZED' self.state.state = 'UNINITIALIZED'
self.state.update() self.state.update()
super(ClusterHost, self).update()
@property @property
def name(self): def name(self):
@ -866,6 +886,11 @@ class HostState(BASE, StateMixin):
primary_key=True primary_key=True
) )
def __str__(self):
return 'HostState[%s state %s percentage %s]' % (
self.id, self.state, self.percentage
)
def update(self): def update(self):
super(HostState, self).update() super(HostState, self).update()
host = self.host host = self.host
@ -944,6 +969,9 @@ class Host(BASE, TimestampMixin, HelperMixin):
backref=backref('host') backref=backref('host')
) )
def __str__(self):
return 'Host[%s:%s]' % (self.id, self.name)
@hybrid_property @hybrid_property
def mac(self): def mac(self):
machine = self.machine machine = self.machine
@ -1004,6 +1032,7 @@ class Host(BASE, TimestampMixin, HelperMixin):
self.os_name = os.name self.os_name = os.name
else: else:
self.os_name = None self.os_name = None
self.state.update()
super(Host, self).update() super(Host, self).update()
def validate(self): def validate(self):
@ -1089,6 +1118,11 @@ class ClusterState(BASE, StateMixin):
default=0 default=0
) )
def __str__(self):
return 'ClusterState[%s state %s percentage %s]' % (
self.id, self.state, self.percentage
)
def to_dict(self): def to_dict(self):
dict_info = super(ClusterState, self).to_dict() dict_info = super(ClusterState, self).to_dict()
dict_info['status'] = { dict_info['status'] = {
@ -1199,8 +1233,8 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
self.state = ClusterState() self.state = ClusterState()
super(Cluster, self).__init__(**kwargs) super(Cluster, self).__init__(**kwargs)
def initialize(self): def __str__(self):
super(Cluster, self).initialize() return 'Cluster[%s:%s]' % (self.id, self.name)
def update(self): def update(self):
creator = self.creator creator = self.creator
@ -1233,6 +1267,7 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
self.flavor_name = flavor.name self.flavor_name = flavor.name
else: else:
self.flavor_name = None self.flavor_name = None
self.state.update()
super(Cluster, self).update() super(Cluster, self).update()
def validate(self): def validate(self):
@ -1375,6 +1410,9 @@ class UserPermission(BASE, HelperMixin, TimestampMixin):
self.user_id = user_id self.user_id = user_id
self.permission_id = permission_id self.permission_id = permission_id
def __str__(self):
return 'UserPermission[%s:%s]' % (self.id, self.name)
@hybrid_property @hybrid_property
def name(self): def name(self):
return self.permission.name return self.permission.name
@ -1404,6 +1442,9 @@ class Permission(BASE, HelperMixin, TimestampMixin):
self.name = name self.name = name
super(Permission, self).__init__(**kwargs) super(Permission, self).__init__(**kwargs)
def __str__(self):
return 'Permission[%s:%s]' % (self.id, self.name)
class UserToken(BASE, HelperMixin): class UserToken(BASE, HelperMixin):
"""user token table.""" """user token table."""
@ -1497,6 +1538,9 @@ class User(BASE, HelperMixin, TimestampMixin):
self.email = email self.email = email
super(User, self).__init__(**kwargs) super(User, self).__init__(**kwargs)
def __str__(self):
return 'User[%s]' % self.email
def validate(self): def validate(self):
super(User, self).validate() super(User, self).validate()
if not self.crypted_password: if not self.crypted_password:
@ -1528,12 +1572,6 @@ class User(BASE, HelperMixin, TimestampMixin):
] ]
return dict_info return dict_info
def __str__(self):
return '%s[email:%s,is_admin:%s,active:%s]' % (
self.__class__.__name__,
self.email, self.is_admin, self.active
)
class SwitchMachine(BASE, HelperMixin, TimestampMixin): class SwitchMachine(BASE, HelperMixin, TimestampMixin):
"""Switch Machine table.""" """Switch Machine table."""
@ -1560,6 +1598,11 @@ class SwitchMachine(BASE, HelperMixin, TimestampMixin):
self.machine_id = machine_id self.machine_id = machine_id
super(SwitchMachine, self).__init__(**kwargs) super(SwitchMachine, self).__init__(**kwargs)
def __str__(self):
return 'SwitchMachine[%s port %s]' % (
self.switch_machine_id, self.port
)
def validate(self): def validate(self):
super(SwitchMachine, self).validate() super(SwitchMachine, self).validate()
if not self.switch: if not self.switch:
@ -1709,6 +1752,9 @@ class Machine(BASE, HelperMixin, TimestampMixin):
self.mac = mac self.mac = mac
super(Machine, self).__init__(**kwargs) super(Machine, self).__init__(**kwargs)
def __str__(self):
return 'Machine[%s:%s]' % (self.id, self.mac)
def validate(self): def validate(self):
super(Machine, self).validate() super(Machine, self).validate()
try: try:
@ -1789,6 +1835,9 @@ class Switch(BASE, HelperMixin, TimestampMixin):
backref=backref('switch') backref=backref('switch')
) )
def __str__(self):
return 'Switch[%s:%s]' % (self.id, self.ip)
@classmethod @classmethod
def parse_filters(cls, filters): def parse_filters(cls, filters):
if isinstance(filters, basestring): if isinstance(filters, basestring):
@ -2094,6 +2143,9 @@ class OperatingSystem(BASE, HelperMixin):
self.name = name self.name = name
super(OperatingSystem, self).__init__() super(OperatingSystem, self).__init__()
def __str__(self):
return 'OperatingSystem[%s:%s]' % (self.id, self.name)
@property @property
def root_metadatas(self): def root_metadatas(self):
return [ return [
@ -2199,6 +2251,9 @@ class AdapterFlavor(BASE, HelperMixin):
UniqueConstraint('name', 'adapter_id', name='constraint'), UniqueConstraint('name', 'adapter_id', name='constraint'),
) )
def __str__(self):
return 'AdapterFlavor[%s:%s]' % (self.id, self.name)
@property @property
def ordered_flavor_roles(self): def ordered_flavor_roles(self):
flavor_roles = dict([ flavor_roles = dict([
@ -2285,6 +2340,9 @@ class AdapterRole(BASE, HelperMixin):
self.adapter_id = adapter_id self.adapter_id = adapter_id
super(AdapterRole, self).__init__(**kwargs) super(AdapterRole, self).__init__(**kwargs)
def __str__(self):
return 'AdapterRole[%s:%s]' % (self.id, self.name)
def initialize(self): def initialize(self):
if not self.description: if not self.description:
self.description = self.name self.description = self.name
@ -2592,6 +2650,9 @@ class DistributedSystem(BASE, HelperMixin):
self.name = name self.name = name
super(DistributedSystem, self).__init__() super(DistributedSystem, self).__init__()
def __str__(self):
return 'DistributedSystem[%s:%s]' % (self.id, self.name)
class OSInstaller(BASE, InstallerMixin): class OSInstaller(BASE, InstallerMixin):
"""OS installer table.""" """OS installer table."""
@ -2612,6 +2673,9 @@ class OSInstaller(BASE, InstallerMixin):
self.alias = alias self.alias = alias
super(OSInstaller, self).__init__(**kwargs) super(OSInstaller, self).__init__(**kwargs)
def __str__(self):
return 'OSInstaller[%s:%s]' % (self.id, self.alias)
class PackageInstaller(BASE, InstallerMixin): class PackageInstaller(BASE, InstallerMixin):
"""package installer table.""" """package installer table."""
@ -2628,6 +2692,9 @@ class PackageInstaller(BASE, InstallerMixin):
self.alias = alias self.alias = alias
super(PackageInstaller, self).__init__(**kwargs) super(PackageInstaller, self).__init__(**kwargs)
def __str__(self):
return 'PackageInstaller[%s:%s]' % (self.id, self.alias)
class Subnet(BASE, TimestampMixin, HelperMixin): class Subnet(BASE, TimestampMixin, HelperMixin):
"""network table.""" """network table."""
@ -2648,6 +2715,9 @@ class Subnet(BASE, TimestampMixin, HelperMixin):
self.subnet = subnet self.subnet = subnet
super(Subnet, self).__init__(**kwargs) super(Subnet, self).__init__(**kwargs)
def __str__(self):
return 'Subnet[%s:%s]' % (self.id, self.subnet)
def to_dict(self): def to_dict(self):
dict_info = super(Subnet, self).to_dict() dict_info = super(Subnet, self).to_dict()
if not self.name: if not self.name:

View File

@ -140,13 +140,13 @@ class DeployManager(object):
self.redeploy_os() self.redeploy_os()
self.redeploy_target_system() self.redeploy_target_system()
def remove_hosts(self, package_only=False): def remove_hosts(self, package_only=False, delete_cluster=False):
"""Remove hosts from both OS and/or package installlers server side.""" """Remove hosts from both OS and/or package installlers server side."""
if self.os_installer and not package_only: if self.os_installer and not package_only:
self.os_installer.delete_hosts() self.os_installer.delete_hosts()
if self.pk_installer: if self.pk_installer:
self.pk_installer.delete_hosts() self.pk_installer.delete_hosts(delete_cluster=delete_cluster)
def _get_hosts_for_os_installation(self, hosts_info): def _get_hosts_for_os_installation(self, hosts_info):
"""Get info of hosts which need to install/reinstall OS.""" """Get info of hosts which need to install/reinstall OS."""

View File

@ -135,10 +135,20 @@ class ChefInstaller(PKInstaller):
return node return node
def delete_hosts(self): def delete_hosts(self, delete_cluster=False):
hosts_id_list = self.config_manager.get_host_id_list() hosts_id_list = self.config_manager.get_host_id_list()
for host_id in hosts_id_list: for host_id in hosts_id_list:
self.delete_node(host_id) self.delete_node(host_id)
if delete_cluster:
self.delete_environment()
def delete_environment(self):
adapter_name = self.config_manager.get_adapter_name()
cluster_name = self.config_manager.get_clustername()
env_name = self.get_env_name(adapter_name, cluster_name)
env = self.get_create_environment(env_name)
if env:
self._delete_environment(env)
def delete_node(self, host_id): def delete_node(self, host_id):
fullname = self.config_manager.get_host_fullname(host_id) fullname = self.config_manager.get_host_fullname(host_id)
@ -146,6 +156,20 @@ class ChefInstaller(PKInstaller):
if node: if node:
self._delete_node(node) self._delete_node(node)
def _delete_environment(self, env):
"""clean env attributes about arget system."""
import chef
if env is None:
raise Exception("env is None, cannot delete a bnone env.")
env_name = env.name
try:
env.delete()
except Exception as error:
logging.debug(
'failed to delete env %s, error: %s',
env_name, error
)
def _delete_node(self, node): def _delete_node(self, node):
"""clean node attributes about target system.""" """clean node attributes about target system."""
import chef import chef

View File

@ -21,6 +21,7 @@ import logging
from celery.signals import celeryd_init from celery.signals import celeryd_init
from celery.signals import setup_logging from celery.signals import setup_logging
from compass.actions import delete
from compass.actions import deploy from compass.actions import deploy
from compass.actions import poll_switch from compass.actions import poll_switch
from compass.actions import update_progress from compass.actions import update_progress
@ -82,8 +83,10 @@ def pollswitch(
def deploy_cluster(deployer_email, cluster_id, clusterhost_ids): def deploy_cluster(deployer_email, cluster_id, clusterhost_ids):
"""Deploy the given cluster. """Deploy the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to deploy. :param cluster_id: id of the cluster
:type cluster_hosts: dict of int to list of int :type cluster_id: int
:param clusterhost_ids: the id of the hosts in the cluster
:type clusterhost_ids: list of int
""" """
try: try:
deploy.deploy(cluster_id, clusterhost_ids, deployer_email) deploy.deploy(cluster_id, clusterhost_ids, deployer_email)
@ -95,10 +98,74 @@ def deploy_cluster(deployer_email, cluster_id, clusterhost_ids):
def reinstall_cluster(installer_email, cluster_id, clusterhost_ids): def reinstall_cluster(installer_email, cluster_id, clusterhost_ids):
"""reinstall the given cluster. """reinstall the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to reinstall. :param cluster_id: id of the cluster
:type cluster_hosts: dict of int to list of int :type cluster_id: int
:param clusterhost_ids: the id of the hosts in the cluster
:type clusterhost_ids: list of int
""" """
pass try:
deploy.redeploy(cluster_id, clusterhost_ids, installer_email)
except Exception as error:
logging.exception(error)
@celery.task(name='compass.tasks.delete_cluster')
def delete_cluster(
deleter_email, cluster_id, clusterhost_ids,
delete_underlying_host=False
):
"""Delete the given cluster.
:param cluster_id: id of the cluster
:type cluster_id: int
:param clusterhost_ids: the id of the hosts in the cluster
:type clusterhost_ids: list of int
"""
try:
delete.delete_cluster(
cluster_id, clusterhost_ids, deleter_email,
delete_underlying_host=delete_underlying_host
)
except Exception as error:
logging.exception(error)
@celery.task(name='compass.tasks.delete_cluster_host')
def delete_cluster_host(
deleter_email, cluster_id, host_id,
delete_underlying_host=False
):
"""Delte the given cluster host.
:param cluster_id: id of the cluster
:type cluster_id: int
:param host_id: id of the host
:type host_id: int
"""
try:
delete.delete_cluster_host(
cluster_id, host_id, deleter_email,
delete_underlying_host=delete_underlying_host
)
except Exception as error:
logging.exception(error)
@celery.task(name='compass.tasks.delete_host')
def delete_host(deleter_email, host_id, cluster_ids):
"""Delete the given host.
:param host_id: id of the host
:type host_id: int
:param cluster_ids: list of cluster id
:type cluster_ids: list of int
"""
try:
delete.delete_host(
host_id, deleter_email, cluster_ids
)
except Exception as error:
logging.exception(error)
@celery.task(name='compass.tasks.poweron_host') @celery.task(name='compass.tasks.poweron_host')

View File

@ -72,6 +72,8 @@ class ApiTestCase(unittest2.TestCase):
self.test_client = application.test_client() self.test_client = application.test_client()
celery.current_app.send_task = mock.Mock() celery.current_app.send_task = mock.Mock()
from compass.tasks import client as celery_client
celery_client.celery.send_task = mock.Mock()
url = '/users/token' url = '/users/token'
data = self.USER_CREDENTIALS data = self.USER_CREDENTIALS
request_data = json.dumps(data) request_data = json.dumps(data)
@ -385,7 +387,7 @@ class TestClusterAPI(ApiTestCase):
# delete a cluster sucessfully # delete a cluster sucessfully
url = '/clusters/1' url = '/clusters/1'
return_value = self.delete(url) return_value = self.delete(url)
self.assertEqual(return_value.status_code, 200) self.assertEqual(return_value.status_code, 202)
def test_list_cluster_hosts(self): def test_list_cluster_hosts(self):
# list cluster_hosts successfully # list cluster_hosts successfully
@ -451,7 +453,7 @@ class TestClusterAPI(ApiTestCase):
# delete a cluster_host successfully # delete a cluster_host successfully
url = '/clusters/1/hosts/1' url = '/clusters/1/hosts/1'
return_value = self.delete(url) return_value = self.delete(url)
self.assertEqual(return_value.status_code, 200) self.assertEqual(return_value.status_code, 202)
# give a non-existed cluster_id # give a non-existed cluster_id
url = '/clusters/99/hosts/1' url = '/clusters/99/hosts/1'
@ -862,7 +864,7 @@ class TestHostAPI(ApiTestCase):
# delete a host successfully # delete a host successfully
url = '/hosts/2' url = '/hosts/2'
return_value = self.delete(url) return_value = self.delete(url)
self.assertEqual(return_value.status_code, 200) self.assertEqual(return_value.status_code, 202)
# give a non-existed id # give a non-existed id
url = '/hosts/99' url = '/hosts/99'

View File

@ -383,15 +383,13 @@ class TestDelCluster(ClusterTestCase):
super(TestDelCluster, self).setUp() super(TestDelCluster, self).setUp()
def test_del_cluster(self): def test_del_cluster(self):
cluster.del_cluster( from compass.tasks import client as celery_client
celery_client.celery.send_task = mock.Mock()
del_cluster = cluster.del_cluster(
self.user_object, self.user_object,
self.cluster_id self.cluster_id
) )
del_clusters = cluster.list_clusters(self.user_object) self.assertIsNotNone(del_cluster['status'])
cluster_ids = []
for del_cluster in del_clusters:
cluster_ids.append(del_cluster['id'])
self.assertNotIn(self.cluster_id, cluster_ids)
def test_is_cluster_editable(self): def test_is_cluster_editable(self):
#state is INSTALLING #state is INSTALLING
@ -907,19 +905,14 @@ class TestDelClusterHost(ClusterTestCase):
super(TestDelClusterHost, self).tearDown() super(TestDelClusterHost, self).tearDown()
def test_del_cluster_host(self): def test_del_cluster_host(self):
cluster.del_cluster_host( from compass.tasks import client as celery_client
celery_client.celery.send_task = mock.Mock()
del_clusterhost = cluster.del_cluster_host(
self.user_object, self.user_object,
self.cluster_id, self.cluster_id,
self.host_id[0] self.host_id[0]
) )
del_cluster_host = cluster.list_cluster_hosts( self.assertIsNotNone(del_clusterhost)
self.user_object,
self.cluster_id
)
result = []
for item in del_cluster_host:
result.append(item['hostname'])
self.assertNotIn('newname1', result)
def test_is_cluster_editable(self): def test_is_cluster_editable(self):
cluster.update_cluster_state( cluster.update_cluster_state(
@ -946,15 +939,13 @@ class TestDelClusterhost(ClusterTestCase):
super(TestDelClusterhost, self).tearDown() super(TestDelClusterhost, self).tearDown()
def test_del_clusterhost(self): def test_del_clusterhost(self):
cluster.del_clusterhost( from compass.tasks import client as celery_client
celery_client.celery.send_task = mock.Mock()
del_clusterhost = cluster.del_clusterhost(
self.user_object, self.user_object,
self.clusterhost_id[0] self.clusterhost_id[0]
) )
del_clusterhost = cluster.list_clusterhosts(self.user_object) self.assertIsNotNone(del_clusterhost)
result = []
for item in del_clusterhost:
result.append(item['hostname'])
self.assertNotIn('newname1', result)
def test_is_cluster_editable(self): def test_is_cluster_editable(self):
cluster.update_cluster_state( cluster.update_cluster_state(

View File

@ -267,11 +267,11 @@ class TestListMachinesOrHosts(HostTestCase):
self.assertIn(item, ['newname1', 'newname2']) self.assertIn(item, ['newname1', 'newname2'])
def test_list_machines(self): def test_list_machines(self):
host.del_host( host.del_host_from_database(
self.user_object, self.user_object,
self.host_ids[0] self.host_ids[0]
) )
host.del_host( host.del_host_from_database(
self.user_object, self.user_object,
self.host_ids[1] self.host_ids[1]
) )
@ -327,7 +327,7 @@ class TestGetMachineOrHost(HostTestCase):
self.assertEqual(get_host['mac'], '28:6e:d4:46:c4:25') self.assertEqual(get_host['mac'], '28:6e:d4:46:c4:25')
def test_get_machine(self): def test_get_machine(self):
host.del_host( host.del_host_from_database(
self.user_object, self.user_object,
self.host_ids[0] self.host_ids[0]
) )
@ -448,17 +448,13 @@ class TestDelHost(HostTestCase):
super(TestDelHost, self).tearDown() super(TestDelHost, self).tearDown()
def test_del_host(self): def test_del_host(self):
host.del_host( from compass.tasks import client as celery_client
celery_client.celery.send_task = mock.Mock()
del_host = host.del_host(
self.user_object, self.user_object,
self.host_ids[0] self.host_ids[0]
) )
del_host = host.list_hosts( self.assertIsNotNone(del_host['status'])
self.user_object
)
ids = []
for item in del_host:
ids.append(item['id'])
self.assertNotIn(self.host_ids[0], ids)
def test_is_host_editable(self): def test_is_host_editable(self):
host.update_host_state( host.update_host_state(

View File

@ -11,6 +11,11 @@
}, },
"json_class": "Chef::Environment", "json_class": "Chef::Environment",
"chef_type": "environment", "chef_type": "environment",
"override_attributes": {
"compass": {
"cluster_id": "$id"
}
},
"default_attributes": { "default_attributes": {
"local_repo": "", "local_repo": "",
"mysql": { "mysql": {

View File

@ -73,6 +73,11 @@
}, },
"json_class": "Chef::Environment", "json_class": "Chef::Environment",
"chef_type": "environment", "chef_type": "environment",
"override_attributes": {
"compass": {
"cluster_id": "$id"
}
},
"default_attributes": { "default_attributes": {
"local_repo": "", "local_repo": "",
"mysql": { "mysql": {