Merge "Update API"
This commit is contained in:
@@ -285,6 +285,7 @@ class MachineList(Resource):
|
|||||||
ENDPOINT = "/machines"
|
ENDPOINT = "/machines"
|
||||||
|
|
||||||
SWITCHID = 'switchId'
|
SWITCHID = 'switchId'
|
||||||
|
MAC = 'mac'
|
||||||
VLANID = 'vladId'
|
VLANID = 'vladId'
|
||||||
PORT = 'port'
|
PORT = 'port'
|
||||||
LIMIT = 'limit'
|
LIMIT = 'limit'
|
||||||
@@ -296,11 +297,13 @@ class MachineList(Resource):
|
|||||||
be filtered.
|
be filtered.
|
||||||
|
|
||||||
:param switchId: the unique identifier of the switch
|
:param switchId: the unique identifier of the switch
|
||||||
|
:param mac: the MAC address
|
||||||
:param vladId: the vlan ID
|
:param vladId: the vlan ID
|
||||||
:param port: the port number
|
:param port: the port number
|
||||||
:param limit: the number of records expected to return
|
:param limit: the number of records expected to return
|
||||||
"""
|
"""
|
||||||
switch_id = request.args.get(self.SWITCHID, type=int)
|
switch_id = request.args.get(self.SWITCHID, type=int)
|
||||||
|
mac = request.args.get(self.MAC, None, type=str)
|
||||||
vlan = request.args.get(self.VLANID, type=int)
|
vlan = request.args.get(self.VLANID, type=int)
|
||||||
port = request.args.get(self.PORT, None)
|
port = request.args.get(self.PORT, None)
|
||||||
limit = request.args.get(self.LIMIT, 0, type=int)
|
limit = request.args.get(self.LIMIT, 0, type=int)
|
||||||
@@ -311,6 +314,9 @@ class MachineList(Resource):
|
|||||||
if switch_id:
|
if switch_id:
|
||||||
filter_clause.append('switch_id=%d' % switch_id)
|
filter_clause.append('switch_id=%d' % switch_id)
|
||||||
|
|
||||||
|
if mac:
|
||||||
|
filter_clause.append('mac=%s' % mac)
|
||||||
|
|
||||||
if vlan:
|
if vlan:
|
||||||
filter_clause.append('vlan=%d' % vlan)
|
filter_clause.append('vlan=%d' % vlan)
|
||||||
|
|
||||||
@@ -488,6 +494,12 @@ class Cluster(Resource):
|
|||||||
return errors.handle_duplicate_object(
|
return errors.handle_duplicate_object(
|
||||||
errors.ObjectDuplicateError(error_msg))
|
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!"
|
||||||
|
return errors.handle_not_exist(
|
||||||
|
errors.ObjectDoesNotExist(error_msg))
|
||||||
|
|
||||||
# Create a new cluster in database
|
# Create a new cluster in database
|
||||||
cluster = ModelCluster(name=cluster_name, adapter_id=adapter_id)
|
cluster = ModelCluster(name=cluster_name, adapter_id=adapter_id)
|
||||||
session.add(cluster)
|
session.add(cluster)
|
||||||
|
@@ -260,6 +260,7 @@ def valid_host_config(config):
|
|||||||
|
|
||||||
from api import errors
|
from api import errors
|
||||||
valid_format = {"/networking/interfaces/management/ip": "is_valid_ip",
|
valid_format = {"/networking/interfaces/management/ip": "is_valid_ip",
|
||||||
|
"/networking/interfaces/tenant/ip": "is_valid_ip",
|
||||||
"/networking/global/gateway": "is_valid_gateway",
|
"/networking/global/gateway": "is_valid_gateway",
|
||||||
"/networking/global/nameserver": "",
|
"/networking/global/nameserver": "",
|
||||||
"/networking/global/search_path": "",
|
"/networking/global/search_path": "",
|
||||||
|
@@ -129,7 +129,7 @@ class Client(object):
|
|||||||
return self._get('/api/switches/%s' % switch_id)
|
return self._get('/api/switches/%s' % switch_id)
|
||||||
|
|
||||||
def add_switch(self, switch_ip, version=None, community=None,
|
def add_switch(self, switch_ip, version=None, community=None,
|
||||||
username=None, password=None):
|
username=None, password=None, raw_data=None):
|
||||||
"""Create a switch with specified details.
|
"""Create a switch with specified details.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@@ -149,6 +149,9 @@ class Client(object):
|
|||||||
:type password: str.
|
:type password: str.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['switch'] = {}
|
data['switch'] = {}
|
||||||
data['switch']['ip'] = switch_ip
|
data['switch']['ip'] = switch_ip
|
||||||
data['switch']['credential'] = {}
|
data['switch']['credential'] = {}
|
||||||
@@ -168,7 +171,8 @@ class Client(object):
|
|||||||
|
|
||||||
def update_switch(self, switch_id, ip_addr=None,
|
def update_switch(self, switch_id, ip_addr=None,
|
||||||
version=None, community=None,
|
version=None, community=None,
|
||||||
username=None, password=None):
|
username=None, password=None,
|
||||||
|
raw_data=None):
|
||||||
"""Updates a switch with specified details.
|
"""Updates a switch with specified details.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@@ -189,6 +193,9 @@ class Client(object):
|
|||||||
:param password: password when using SSH to poll switch.
|
:param password: password when using SSH to poll switch.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['switch'] = {}
|
data['switch'] = {}
|
||||||
if ip_addr:
|
if ip_addr:
|
||||||
data['switch']['ip'] = ip_addr
|
data['switch']['ip'] = ip_addr
|
||||||
@@ -266,7 +273,7 @@ class Client(object):
|
|||||||
"""
|
"""
|
||||||
return self._get('/api/clusters/%s' % cluster_id)
|
return self._get('/api/clusters/%s' % cluster_id)
|
||||||
|
|
||||||
def add_cluster(self, cluster_name, adapter_id):
|
def add_cluster(self, cluster_name, adapter_id, raw_data=None):
|
||||||
"""Creates a cluster by specified name and given adapter id.
|
"""Creates a cluster by specified name and given adapter id.
|
||||||
|
|
||||||
:param cluster_name: cluster name.
|
:param cluster_name: cluster name.
|
||||||
@@ -275,12 +282,15 @@ class Client(object):
|
|||||||
:type adapter_id: int.
|
:type adapter_id: int.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['cluster'] = {}
|
data['cluster'] = {}
|
||||||
data['cluster']['name'] = cluster_name
|
data['cluster']['name'] = cluster_name
|
||||||
data['cluster']['adapter_id'] = adapter_id
|
data['cluster']['adapter_id'] = adapter_id
|
||||||
return self._post('/api/clusters', data=data)
|
return self._post('/api/clusters', data=data)
|
||||||
|
|
||||||
def add_hosts(self, cluster_id, machine_ids):
|
def add_hosts(self, cluster_id, machine_ids, raw_data=None):
|
||||||
"""add the specified machine(s) as the host(s) to the cluster.
|
"""add the specified machine(s) as the host(s) to the cluster.
|
||||||
|
|
||||||
:param cluster_id: cluster id.
|
:param cluster_id: cluster id.
|
||||||
@@ -289,10 +299,13 @@ class Client(object):
|
|||||||
:type machine_ids: list of int, each is the id of one machine.
|
:type machine_ids: list of int, each is the id of one machine.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['addHosts'] = machine_ids
|
data['addHosts'] = machine_ids
|
||||||
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
||||||
|
|
||||||
def remove_hosts(self, cluster_id, host_ids):
|
def remove_hosts(self, cluster_id, host_ids, raw_data=None):
|
||||||
"""remove the specified host(s) from the cluster.
|
"""remove the specified host(s) from the cluster.
|
||||||
|
|
||||||
:param cluster_id: cluster id.
|
:param cluster_id: cluster id.
|
||||||
@@ -301,10 +314,13 @@ class Client(object):
|
|||||||
:type host_ids: list of int, each is the id of one host.
|
:type host_ids: list of int, each is the id of one host.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['removeHosts'] = host_ids
|
data['removeHosts'] = host_ids
|
||||||
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
||||||
|
|
||||||
def replace_hosts(self, cluster_id, machine_ids):
|
def replace_hosts(self, cluster_id, machine_ids, raw_data=None):
|
||||||
"""replace the cluster hosts with the specified machine(s).
|
"""replace the cluster hosts with the specified machine(s).
|
||||||
|
|
||||||
:param cluster_id: int, The unique identifier of the cluster.
|
:param cluster_id: int, The unique identifier of the cluster.
|
||||||
@@ -313,17 +329,23 @@ class Client(object):
|
|||||||
:type machine_ids: list of int, each is the id of one machine.
|
:type machine_ids: list of int, each is the id of one machine.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
data['replaceAllHosts'] = machine_ids
|
data['replaceAllHosts'] = machine_ids
|
||||||
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
||||||
|
|
||||||
def deploy_hosts(self, cluster_id):
|
def deploy_hosts(self, cluster_id, raw_data=None):
|
||||||
"""Deploy the cluster.
|
"""Deploy the cluster.
|
||||||
|
|
||||||
:param cluster_id: The unique identifier of the cluster
|
:param cluster_id: The unique identifier of the cluster
|
||||||
:type cluster_id: int.
|
:type cluster_id: int.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
data['deploy'] = {}
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
|
data['deploy'] = []
|
||||||
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
return self._post('/api/clusters/%s/action' % cluster_id, data=data)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -481,7 +503,7 @@ class Client(object):
|
|||||||
return self._get('/api/clusterhosts/%s/config' % host_id)
|
return self._get('/api/clusterhosts/%s/config' % host_id)
|
||||||
|
|
||||||
def update_host_config(self, host_id, hostname=None,
|
def update_host_config(self, host_id, hostname=None,
|
||||||
roles=None, **kwargs):
|
roles=None, raw_data=None, **kwargs):
|
||||||
"""Updates config for the host.
|
"""Updates config for the host.
|
||||||
|
|
||||||
:param host_id: host id.
|
:param host_id: host id.
|
||||||
@@ -518,6 +540,9 @@ class Client(object):
|
|||||||
:type roles: list of str.
|
:type roles: list of str.
|
||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
|
if raw_data:
|
||||||
|
data = raw_data
|
||||||
|
else:
|
||||||
if hostname:
|
if hostname:
|
||||||
data['hostname'] = hostname
|
data['hostname'] = hostname
|
||||||
|
|
||||||
@@ -533,7 +558,8 @@ class Client(object):
|
|||||||
data['networking'] = self.parse_networking(
|
data['networking'] = self.parse_networking(
|
||||||
sub_kwargs['networking'])
|
sub_kwargs['networking'])
|
||||||
if 'partition' in sub_kwargs:
|
if 'partition' in sub_kwargs:
|
||||||
data['partition'] = self.parse_partition(sub_kwargs['partition'])
|
data['partition'] = self.parse_partition(
|
||||||
|
sub_kwargs['partition'])
|
||||||
|
|
||||||
if roles:
|
if roles:
|
||||||
data['roles'] = roles
|
data['roles'] = roles
|
||||||
|
@@ -270,7 +270,8 @@ class TestSwtichMachineAPI(ApiTestCase):
|
|||||||
{'url': '/machines?switchId=1', 'expected': 8},
|
{'url': '/machines?switchId=1', 'expected': 8},
|
||||||
# TODO:
|
# TODO:
|
||||||
#{'url': '/machines?switchId=1&port=6', 'expected': 1},
|
#{'url': '/machines?switchId=1&port=6', 'expected': 1},
|
||||||
{'url': '/machines?switchId=4', 'expected': 0}]
|
{'url': '/machines?switchId=4', 'expected': 0},
|
||||||
|
{'url': "/machines?mac='00:27:88:0c:01'", 'expected': 1}]
|
||||||
|
|
||||||
for test in testList:
|
for test in testList:
|
||||||
url = test['url']
|
url = test['url']
|
||||||
@@ -365,21 +366,29 @@ class TestClusterAPI(ApiTestCase):
|
|||||||
|
|
||||||
# Create a cluster
|
# Create a cluster
|
||||||
def test_post_cluster(self):
|
def test_post_cluster(self):
|
||||||
# a. Post a new cluster
|
# a. Post a new cluster but no adapter exists
|
||||||
cluster_req = {'cluster': {'name': 'cluster_02',
|
cluster_req = {'cluster': {'name': 'cluster_02',
|
||||||
'adapter_id': 1}}
|
'adapter_id': 1}}
|
||||||
url = '/clusters'
|
url = '/clusters'
|
||||||
rv = self.app.post(url, data=json.dumps(cluster_req))
|
rv = self.app.post(url, data=json.dumps(cluster_req))
|
||||||
data = json.loads(rv.get_data())
|
data = json.loads(rv.get_data())
|
||||||
|
|
||||||
self.assertEqual(rv.status_code, 200)
|
self.assertEqual(rv.status_code, 404)
|
||||||
|
|
||||||
|
#b. Post a cluster sucessfully
|
||||||
|
with database.session() as session:
|
||||||
|
adapter = Adapter(name='Centos_openstack', os='Centos',
|
||||||
|
target_system='openstack')
|
||||||
|
session.add(adapter)
|
||||||
|
rv = self.app.post(url, data=json.dumps(cluster_req))
|
||||||
|
data = json.loads(rv.get_data())
|
||||||
self.assertEqual(data['cluster']['id'], 2)
|
self.assertEqual(data['cluster']['id'], 2)
|
||||||
self.assertEqual(data['cluster']['name'], 'cluster_02')
|
self.assertEqual(data['cluster']['name'], 'cluster_02')
|
||||||
|
|
||||||
#b. Post an existing cluster, return 409
|
#c. Post an existing cluster, return 409
|
||||||
rv = self.app.post(url, data=json.dumps(cluster_req))
|
rv = self.app.post(url, data=json.dumps(cluster_req))
|
||||||
self.assertEqual(rv.status_code, 409)
|
self.assertEqual(rv.status_code, 409)
|
||||||
#c. Post a new cluster without providing a name
|
#d. Post a new cluster without providing a name
|
||||||
cluster_req['cluster']['name'] = ''
|
cluster_req['cluster']['name'] = ''
|
||||||
rv = self.app.post(url, data=json.dumps(cluster_req))
|
rv = self.app.post(url, data=json.dumps(cluster_req))
|
||||||
data = json.loads(rv.get_data())
|
data = json.loads(rv.get_data())
|
||||||
@@ -981,6 +990,9 @@ class TestAPIWorkFlow(ApiTestCase):
|
|||||||
"interfaces": {
|
"interfaces": {
|
||||||
"management": {
|
"management": {
|
||||||
"ip": ""
|
"ip": ""
|
||||||
|
},
|
||||||
|
"tenant": {
|
||||||
|
"ip": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1009,6 +1021,10 @@ class TestAPIWorkFlow(ApiTestCase):
|
|||||||
|
|
||||||
session.add_all(machines)
|
session.add_all(machines)
|
||||||
|
|
||||||
|
adapter = Adapter(name='Centos_openstack', os='Centos',
|
||||||
|
target_system='openstack')
|
||||||
|
session.add(adapter)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(TestAPIWorkFlow, self).tearDown()
|
super(TestAPIWorkFlow, self).tearDown()
|
||||||
|
|
||||||
@@ -1032,6 +1048,7 @@ class TestAPIWorkFlow(ApiTestCase):
|
|||||||
machines = json.loads(rv.get_data())['machines']
|
machines = json.loads(rv.get_data())['machines']
|
||||||
|
|
||||||
# Create a Cluster and get cluster id from response
|
# Create a Cluster and get cluster id from response
|
||||||
|
# In this example, adapter_id will be 1 by default.
|
||||||
url = '/clusters'
|
url = '/clusters'
|
||||||
data = {
|
data = {
|
||||||
"cluster": {
|
"cluster": {
|
||||||
@@ -1080,9 +1097,12 @@ class TestAPIWorkFlow(ApiTestCase):
|
|||||||
]
|
]
|
||||||
names = ["host_01", "host_02", "host_03"]
|
names = ["host_01", "host_02", "host_03"]
|
||||||
mgmt_ips = ["10.120.8.100", "10.120.8.101", "10.120.8.102"]
|
mgmt_ips = ["10.120.8.100", "10.120.8.101", "10.120.8.102"]
|
||||||
for config, name, ip in zip(hosts_configs, names, mgmt_ips):
|
tenant_ips = ["12.120.8.100", "12.120.8.101", "12.120.8.102"]
|
||||||
|
for config, name, mgmt_ip, tenant_ip in zip(hosts_configs, names,
|
||||||
|
mgmt_ips, tenant_ips):
|
||||||
config["hostname"] = name
|
config["hostname"] = name
|
||||||
config["networking"]["interfaces"]["management"]["ip"] = ip
|
config["networking"]["interfaces"]["management"]["ip"] = mgmt_ip
|
||||||
|
config["networking"]["interfaces"]["tenant"]["ip"] = tenant_ip
|
||||||
|
|
||||||
for config, host_info in zip(hosts_configs, hosts_info):
|
for config, host_info in zip(hosts_configs, hosts_info):
|
||||||
host_id = host_info["id"]
|
host_id = host_info["id"]
|
||||||
|
Reference in New Issue
Block a user