New API client and example.py for API2.0
Will patch flavor to it once flavor code gets checked in Change-Id: I9b0b579f2977d07df44ac8f0b527a8ce39578f17
This commit is contained in:
parent
f0124ca7b1
commit
b16eab3774
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2014 Huawei Technologies Co. Ltd
|
||||
# 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.
|
||||
@ -21,47 +20,50 @@ import requests
|
||||
import sys
|
||||
import time
|
||||
|
||||
from compass.apiclient.restful import Client
|
||||
# from compass.apiclient.restful import Client
|
||||
from restful import Client
|
||||
|
||||
|
||||
COMPASS_SERVER_URL = 'http://127.0.0.1/api'
|
||||
SWITCH_IP = '10.145.81.220'
|
||||
SWITCH_SNMP_VERSION = 'v2c'
|
||||
COMPASS_SERVER_URL = 'http://10.145.89.120/api'
|
||||
COMPASS_LOGIN_EMAIL = 'admin@huawei.com'
|
||||
COMPASS_LOGIN_PASSWORD = 'admin'
|
||||
SWITCH_IP = '172.29.8.40'
|
||||
SWITCH_SNMP_VERSION = '2c'
|
||||
SWITCH_SNMP_COMMUNITY = 'public'
|
||||
#MACHINES_TO_ADD = ['00:11:20:30:40:01']
|
||||
CLUSTER_NAME = 'cluster2'
|
||||
#MACHINES_TO_ADD = ['00:0c:29:05:bd:eb']
|
||||
CLUSTER_NAME = 'test_cluster'
|
||||
HOST_NAME_PREFIX = 'host'
|
||||
SERVER_USERNAME = 'root'
|
||||
SERVER_PASSWORD = 'root'
|
||||
SERVICE_USERNAME = 'service'
|
||||
SERVICE_PASSWORD = 'service'
|
||||
CONSOLE_USERNAME = 'console'
|
||||
CONSOLE_PASSWORD = 'console'
|
||||
DASHBOARD_USERNAME = 'console'
|
||||
DASHBOARD_PASSWORD = 'console'
|
||||
HA_VIP = ''
|
||||
#NAMESERVERS = '192.168.10.6'
|
||||
SEARCH_PATH = 'ods.com'
|
||||
#GATEWAY = '192.168.10.6'
|
||||
#NAMESERVERS = '10.145.88.211'
|
||||
SEARCH_PATH = ['ods.com']
|
||||
#GATEWAY = '10.145.88.1'
|
||||
#PROXY = 'http://192.168.10.6:3128'
|
||||
#NTP_SERVER = '192.168.10.6'
|
||||
MANAGEMENT_IP_START = '192.168.10.130'
|
||||
MANAGEMENT_IP_END = '192.168.10.254'
|
||||
MANAGEMENT_IP_GATEWAY = '192.168.10.1'
|
||||
#NTP_SERVER = '10.145.88.211'
|
||||
|
||||
MANAGEMENT_IP_START = '10.145.88.130'
|
||||
MANAGEMENT_IP_END = '10.145.88.254'
|
||||
MANAGEMENT_IP_GATEWAY = '10.145.88.1'
|
||||
MANAGEMENT_NETMASK = '255.255.255.0'
|
||||
MANAGEMENT_NIC = 'eth0'
|
||||
MANAGEMENT_PROMISC = 0
|
||||
TENANT_IP_START = '192.168.10.100'
|
||||
TENANT_IP_START = '192.168.10.130'
|
||||
TENANT_IP_END = '192.168.10.255'
|
||||
TENANT_IP_GATEWAY = '192.168.10.1'
|
||||
TENANT_NETMASK = '255.255.255.0'
|
||||
TENANT_NIC = 'eth0'
|
||||
TENANT_PROMISC = 0
|
||||
PUBLIC_IP_START = '12.234.32.100'
|
||||
PUBLIC_IP_START = '12.234.32.130'
|
||||
PUBLIC_IP_END = '12.234.32.255'
|
||||
PUBLIC_IP_GATEWAY = '12.234.32.1'
|
||||
PUBLIC_NETMASK = '255.255.255.0'
|
||||
PUBLIC_NIC = 'eth1'
|
||||
PUBLIC_PROMISC = 1
|
||||
STORAGE_IP_START = '172.16.100.100'
|
||||
STORAGE_IP_START = '172.16.100.130'
|
||||
STORAGE_IP_END = '172.16.100.255'
|
||||
STORAGE_NETMASK = '255.255.255.0'
|
||||
STORAGE_IP_GATEWAY = '172.16.100.1'
|
||||
@ -71,14 +73,22 @@ HOME_PERCENTAGE = 5
|
||||
TMP_PERCENTAGE = 5
|
||||
VAR_PERCENTAGE = 10
|
||||
#ROLES_LIST = [['os-dashboard']]
|
||||
HOST_OS = 'CentOS-6.5-x86_64'
|
||||
|
||||
LANGUAGE = 'EN'
|
||||
TIMEZONE = 'GMT -7:00'
|
||||
HTTPS_PROXY = 'https://10.145.88.211:3128'
|
||||
NO_PROXY = ['127.0.0.1']
|
||||
DNS_SERVER = '10.145.88.211'
|
||||
DOMAIN = 'ods.com'
|
||||
|
||||
PRESET_VALUES = {
|
||||
'NAMESERVERS': '192.168.10.1',
|
||||
'NTP_SERVER': '192.168.10.1',
|
||||
'GATEWAY': '192.168.10.1',
|
||||
'PROXY': 'http://192.168.10.1:3128',
|
||||
'ROLES_LIST': 'os-dashboard',
|
||||
'MACHINES_TO_ADD': '00:11:20:30:40:01',
|
||||
'NAMESERVERS': ['10.145.88.211'],
|
||||
'NTP_SERVER': '10.145.88.211',
|
||||
'GATEWAY': '10.145.88.211',
|
||||
'PROXY': 'http://10.145.88.211:3128',
|
||||
'ROLES_LIST': ['allinone'],
|
||||
'MACHINES_TO_ADD': ['00:0c:29:05:bd:eb'],
|
||||
'BUILD_TIMEOUT': 60
|
||||
}
|
||||
for v in PRESET_VALUES:
|
||||
@ -88,218 +98,295 @@ for v in PRESET_VALUES:
|
||||
else:
|
||||
print (PRESET_VALUES[v])
|
||||
|
||||
# get apiclient object.
|
||||
# instantiate a client
|
||||
client = Client(COMPASS_SERVER_URL)
|
||||
|
||||
# login
|
||||
status, token = client.login(COMPASS_LOGIN_EMAIL, COMPASS_LOGIN_PASSWORD)
|
||||
|
||||
# get all switches.
|
||||
status, resp = client.get_switches()
|
||||
print 'get all switches status: %s resp: %s' % (status, resp)
|
||||
# list all switches
|
||||
status, response = client.list_switches()
|
||||
print '============================================================='
|
||||
print 'get all switches status: %s response: %s' % (status, response)
|
||||
|
||||
# add a switch.
|
||||
status, resp = client.add_switch(
|
||||
SWITCH_IP, version=SWITCH_SNMP_VERSION,
|
||||
community=SWITCH_SNMP_COMMUNITY)
|
||||
|
||||
print 'add a switch status: %s resp: %s' % (status, resp)
|
||||
# add a switch
|
||||
status, response = client.add_switch(
|
||||
SWITCH_IP,
|
||||
SWITCH_SNMP_VERSION,
|
||||
SWITCH_SNMP_COMMUNITY
|
||||
)
|
||||
print '============================================'
|
||||
print 'adding a switch..status: %s, response: %s' % (status, response)
|
||||
|
||||
# if switch already exists, get one from all switches
|
||||
switch = None
|
||||
if status < 400:
|
||||
switch = resp['switch']
|
||||
switch = response
|
||||
else:
|
||||
status, resp = client.get_switches()
|
||||
print 'get all switches status: %s resp: %s' % (status, resp)
|
||||
switch = None
|
||||
for switch in resp['switches']:
|
||||
if switch['ip'] == SWITCH_IP:
|
||||
status, response = client.list_switches()
|
||||
for switch_ in response:
|
||||
if switch_['ip'] == SWITCH_IP:
|
||||
switch = switch_
|
||||
break
|
||||
|
||||
switch_id = switch['id']
|
||||
switch_ip = switch['ip']
|
||||
print '======================'
|
||||
print 'switch has been set as %s' % switch_ip
|
||||
|
||||
|
||||
# if the switch is not in under_monitoring, wait for the poll switch task
|
||||
# update the swich information and change the switch state.
|
||||
# wait till switch state becomes under_monitoring
|
||||
while switch['state'] != 'under_monitoring':
|
||||
print 'waiting for the switch into under_monitoring'
|
||||
print 'waiting for state to become under_monitoring'
|
||||
client.poll_switch(switch_id)
|
||||
status, resp = client.get_switch(switch_id)
|
||||
print 'get switch %s status: %s, resp: %s' % (switch_id, status, resp)
|
||||
switch = resp['switch']
|
||||
time.sleep(10)
|
||||
switch = resp
|
||||
print 'switch is in state: %s' % switch['state']
|
||||
time.sleep(5)
|
||||
status, response = client.poll_switch(switch_id)
|
||||
print '========================================='
|
||||
print 'switch state now is %s' % (switch['state'])
|
||||
|
||||
|
||||
# get machines connected to the switch.
|
||||
status, resp = client.get_machines(switch_id=switch_id)
|
||||
print 'get all machines under switch %s status: %s, resp: %s' % (
|
||||
switch_id, status, resp)
|
||||
# create a machine list
|
||||
machine_macs = {}
|
||||
machines = {}
|
||||
MACHINES_TO_ADD = PRESET_VALUES['MACHINES_TO_ADD'].split()
|
||||
for machine in resp['machines']:
|
||||
mac = machine['mac']
|
||||
if mac in MACHINES_TO_ADD:
|
||||
machines[machine['id']] = mac
|
||||
for machine in PRESET_VALUES['MACHINES_TO_ADD']:
|
||||
status, response = client.list_machines(mac=machine)
|
||||
if status == 200 and response != []:
|
||||
id = response[0]['id']
|
||||
machine_macs[id] = response[0]['mac']
|
||||
machines = response
|
||||
|
||||
print 'machine to add: %s' % machines
|
||||
print '================================='
|
||||
print 'found machines are : %s' % machines
|
||||
|
||||
if set(machines.values()) != set(MACHINES_TO_ADD):
|
||||
MACHINES_TO_ADD = PRESET_VALUES['MACHINES_TO_ADD']
|
||||
if set(machine_macs.values()) != set(MACHINES_TO_ADD):
|
||||
print 'only found macs %s while expected are %s' % (
|
||||
machines.values(), MACHINES_TO_ADD)
|
||||
machine_macs.values(), MACHINES_TO_ADD)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# get adapters.
|
||||
status, resp = client.get_adapters()
|
||||
print 'get all adapters status: %s, resp: %s' % (status, resp)
|
||||
# list all adapters
|
||||
status, response = client.list_adapters()
|
||||
print '==============================='
|
||||
print 'all adapters are: %s' % response
|
||||
adapters = response
|
||||
adapter_ids = []
|
||||
for adapter in resp['adapters']:
|
||||
for adapter in adapters:
|
||||
adapter_ids.append(adapter['id'])
|
||||
|
||||
adapter_id = adapter_ids[0]
|
||||
print 'adpater for deploying a cluster: %s' % adapter_id
|
||||
adapter = adapters[adapter_id]
|
||||
print '=========================='
|
||||
print 'using adapter %s to deploy cluster' % adapter_id
|
||||
|
||||
# get all supported oses
|
||||
supported_oses = adapter['supported_oses']
|
||||
|
||||
# add a cluster.
|
||||
status, resp = client.add_cluster(
|
||||
cluster_name=CLUSTER_NAME, adapter_id=adapter_id)
|
||||
print 'add cluster %s status: %s, resp: %s' % (CLUSTER_NAME, status, resp)
|
||||
cluster = resp['cluster']
|
||||
# get os_id
|
||||
os_id = None
|
||||
os_name = None
|
||||
for supported_os in supported_oses:
|
||||
if HOST_OS in supported_os.values():
|
||||
os_id = supported_os['os_id']
|
||||
os_name = supported_os['name']
|
||||
break
|
||||
|
||||
print '===================================='
|
||||
print 'use %s as host os, the os_id is %s' % (os_name, os_id)
|
||||
|
||||
"""
|
||||
# get flavor_id
|
||||
flavor_id = None
|
||||
flavors = adapter['flavors']
|
||||
print '=============================='
|
||||
print 'all flavors are: %s' % flavors
|
||||
|
||||
for flavor in flavors:
|
||||
if flavor['name'] == PRESET_VALUES['ROLES_LIST']:
|
||||
flavor_id = flavor['id']
|
||||
break
|
||||
|
||||
print '===================================='
|
||||
print 'cluster info: adapter_id: %s, os_id: %s, flavor_id: %s' %
|
||||
(adapter_id, os_id, flavor_id)
|
||||
"""
|
||||
|
||||
# add a cluster
|
||||
status, response = client.add_cluster(
|
||||
CLUSTER_NAME,
|
||||
adapter_id,
|
||||
os_id,
|
||||
#flavor_id
|
||||
)
|
||||
if status < 400:
|
||||
print 'add cluster %s: %s' % (CLUSTER_NAME, response)
|
||||
cluster = response
|
||||
else:
|
||||
status, response = client.list_clusters(name=CLUSTER_NAME)
|
||||
print response
|
||||
cluster = response[0]
|
||||
print 'cluster already exists, fetching it'
|
||||
cluster_id = cluster['id']
|
||||
|
||||
# add hosts to the cluster.
|
||||
status, resp = client.add_hosts(
|
||||
cluster_id=cluster_id,
|
||||
machine_ids=machines.keys())
|
||||
print 'add hosts to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
host_ids = []
|
||||
for host in resp['cluster_hosts']:
|
||||
host_ids.append(host['id'])
|
||||
print '=================='
|
||||
print 'cluster is %s' % cluster
|
||||
|
||||
print 'added hosts: %s' % host_ids
|
||||
# Add hosts to the cluster
|
||||
machines_dict = {}
|
||||
machine_id_list = []
|
||||
for machine in machines:
|
||||
id_mapping = {}
|
||||
id_mapping['machine_id'] = machine['id']
|
||||
machine_id_list.append(id_mapping)
|
||||
|
||||
machines_dict['machines'] = machine_id_list
|
||||
|
||||
status, response = client.add_hosts_to_cluster(
|
||||
cluster_id, machines_dict
|
||||
)
|
||||
print '==================================='
|
||||
print 'add hosts %s to cluster: %s' % (machines_dict, response)
|
||||
|
||||
# Add two subnets
|
||||
subnet_1 = '10.145.89.0/24'
|
||||
subnet_2 = '192.168.100.0/24'
|
||||
|
||||
status, response = client.add_subnet(subnet_1)
|
||||
print '=================='
|
||||
print 'add subnet %s' % response
|
||||
|
||||
status, response = client.add_subnet(subnet_2)
|
||||
print '=================='
|
||||
print 'add subnet %s' % response
|
||||
|
||||
status, subnet1 = client.list_subnets(subnet=subnet_1)
|
||||
status, subnet2 = client.list_subnets(subnet=subnet_2)
|
||||
subnet1_id = subnet1[0]['id']
|
||||
subnet2_id = subnet2[0]['id']
|
||||
print '========================'
|
||||
print 'subnet1 has id: %s, subnet is %s' % (subnet1_id, subnet1)
|
||||
print 'subnet2 has id: %s, subnet is %s' % (subnet2_id, subnet2)
|
||||
|
||||
# Add host network
|
||||
status, response = client.list_cluster_hosts(cluster_id)
|
||||
host = response[0]
|
||||
host_id = host['id']
|
||||
print '=================='
|
||||
print 'host is: %s' % host
|
||||
|
||||
status, response = client.add_host_network(
|
||||
host_id,
|
||||
'eth0',
|
||||
'10.145.89.200',
|
||||
subnet1_id,
|
||||
is_mgmt=True
|
||||
)
|
||||
print '======================='
|
||||
print 'add eth0 network: %s' % response
|
||||
|
||||
status, response = client.add_host_network(
|
||||
host_id,
|
||||
'eth1',
|
||||
'192.168.100.200',
|
||||
subnet2_id,
|
||||
is_promiscuous=True
|
||||
)
|
||||
print '======================='
|
||||
print 'add eth1 network: %s' % response
|
||||
|
||||
# Update os config to cluster
|
||||
cluster_os_config = {
|
||||
'general': {
|
||||
'language': LANGUAGE,
|
||||
'timezone': TIMEZONE,
|
||||
'http_proxy': PRESET_VALUES['PROXY'],
|
||||
'https_proxy': HTTPS_PROXY,
|
||||
'no_proxy': NO_PROXY,
|
||||
'ntp_server': PRESET_VALUES['NTP_SERVER'],
|
||||
'dns_servers': PRESET_VALUES['NAMESERVERS'],
|
||||
'domain': DOMAIN,
|
||||
'search_path': SEARCH_PATH,
|
||||
'default_gateway': PRESET_VALUES['GATEWAY']
|
||||
},
|
||||
'server_credentials': {
|
||||
'username': SERVER_USERNAME,
|
||||
'password': SERVER_PASSWORD
|
||||
},
|
||||
'partition': {
|
||||
'/var': {
|
||||
'percentage': VAR_PERCENTAGE,
|
||||
},
|
||||
'/home': {
|
||||
'percentage': HOME_PERCENTAGE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# set cluster security
|
||||
status, resp = client.set_security(
|
||||
cluster_id, server_username=SERVER_USERNAME,
|
||||
server_password=SERVER_PASSWORD,
|
||||
service_username=SERVICE_USERNAME,
|
||||
service_password=SERVICE_PASSWORD,
|
||||
console_username=CONSOLE_USERNAME,
|
||||
console_password=CONSOLE_PASSWORD)
|
||||
print 'set security config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
cluster_package_config = {
|
||||
'roles': PRESET_VALUES['ROLES_LIST'],
|
||||
'security': {
|
||||
'service_credential': {
|
||||
'image': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'compute': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'dashboard': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'identity': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'metering': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'rabbitmq': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'volume': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
},
|
||||
'mysql': {
|
||||
'username': SERVICE_USERNAME,
|
||||
'password': SERVICE_PASSWORD
|
||||
}
|
||||
},
|
||||
'dashboard_credential': {
|
||||
'username': DASHBOARD_USERNAME,
|
||||
'password': DASHBOARD_PASSWORD
|
||||
}
|
||||
},
|
||||
'network_mapping': {
|
||||
'management': MANAGEMENT_NIC,
|
||||
'tenant': TENANT_NIC,
|
||||
'storage': STORAGE_NIC,
|
||||
'public': PUBLIC_NIC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# set cluster networking
|
||||
status, resp = client.set_networking(
|
||||
status, response = client.update_cluster_config(
|
||||
cluster_id,
|
||||
nameservers=PRESET_VALUES["NAMESERVERS"],
|
||||
search_path=SEARCH_PATH,
|
||||
gateway=PRESET_VALUES["GATEWAY"],
|
||||
proxy=PRESET_VALUES["PROXY"],
|
||||
ntp_server=PRESET_VALUES["NTP_SERVER"],
|
||||
ha_vip=HA_VIP,
|
||||
management_ip_start=MANAGEMENT_IP_START,
|
||||
management_ip_end=MANAGEMENT_IP_END,
|
||||
management_netmask=MANAGEMENT_NETMASK,
|
||||
management_nic=MANAGEMENT_NIC,
|
||||
management_gateway=MANAGEMENT_IP_GATEWAY,
|
||||
management_promisc=MANAGEMENT_PROMISC,
|
||||
tenant_ip_start=TENANT_IP_START,
|
||||
tenant_ip_end=TENANT_IP_END,
|
||||
tenant_netmask=TENANT_NETMASK,
|
||||
tenant_nic=TENANT_NIC,
|
||||
tenant_gateway=TENANT_IP_GATEWAY,
|
||||
tenant_promisc=TENANT_PROMISC,
|
||||
public_ip_start=PUBLIC_IP_START,
|
||||
public_ip_end=PUBLIC_IP_END,
|
||||
public_netmask=PUBLIC_NETMASK,
|
||||
public_nic=PUBLIC_NIC,
|
||||
public_gateway=PUBLIC_IP_GATEWAY,
|
||||
public_promisc=PUBLIC_PROMISC,
|
||||
storage_ip_start=STORAGE_IP_START,
|
||||
storage_ip_end=STORAGE_IP_END,
|
||||
storage_netmask=STORAGE_NETMASK,
|
||||
storage_nic=STORAGE_NIC,
|
||||
storage_gateway=STORAGE_IP_GATEWAY,
|
||||
storage_promisc=STORAGE_PROMISC)
|
||||
print 'set networking config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
cluster_os_config,
|
||||
cluster_package_config
|
||||
)
|
||||
|
||||
print '======================================='
|
||||
print 'cluster %s has been updated to: %s' % (cluster_id, response)
|
||||
|
||||
# set partiton of each host in cluster
|
||||
status, resp = client.set_partition(
|
||||
cluster_id,
|
||||
home_percentage=HOME_PERCENTAGE,
|
||||
tmp_percentage=TMP_PERCENTAGE,
|
||||
var_percentage=VAR_PERCENTAGE)
|
||||
print 'set partition config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
# Review and deploy
|
||||
status, response = client.review_cluster(cluster_id)
|
||||
print '======================================='
|
||||
print 'reviewing cluster: %s' % response
|
||||
|
||||
|
||||
# set each host config in cluster.
|
||||
ROLES_LIST = [PRESET_VALUES['ROLES_LIST'].split()]
|
||||
for host_id in host_ids:
|
||||
if ROLES_LIST:
|
||||
roles = ROLES_LIST.pop(0)
|
||||
else:
|
||||
roles = []
|
||||
status, resp = client.update_host_config(
|
||||
host_id, hostname='%s%s' % (HOST_NAME_PREFIX, host_id),
|
||||
roles=roles)
|
||||
print 'set roles to host %s status: %s, resp: %s' % (
|
||||
host_id, status, resp)
|
||||
|
||||
|
||||
# deploy cluster.
|
||||
status, resp = client.deploy_hosts(cluster_id)
|
||||
print 'deploy cluster %s status: %s, resp: %s' % (cluster_id, status, resp)
|
||||
|
||||
|
||||
# get intalling progress.
|
||||
BUILD_TIMEOUT = float(PRESET_VALUES['BUILD_TIMEOUT'])
|
||||
timeout = time.time() + BUILD_TIMEOUT * 60
|
||||
while True:
|
||||
status, resp = client.get_cluster_installing_progress(cluster_id)
|
||||
print 'get cluster %s installing progress status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
progress = resp['progress']
|
||||
if (
|
||||
progress['state'] not in ['UNINITIALIZED', 'INSTALLING'] or
|
||||
progress['percentage'] >= 1.0
|
||||
):
|
||||
break
|
||||
if (
|
||||
time.time() > timeout
|
||||
):
|
||||
raise Exception("Timeout! The system is not ready in time.")
|
||||
|
||||
for host_id in host_ids:
|
||||
status, resp = client.get_host_installing_progress(host_id)
|
||||
print 'get host %s installing progress status: %s, resp: %s' % (
|
||||
host_id, status, resp)
|
||||
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
status, resp = client.get_dashboard_links(cluster_id)
|
||||
print 'get cluster %s dashboardlinks status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
dashboardlinks = resp['dashboardlinks']
|
||||
if not dashboardlinks.keys():
|
||||
raise Exception("Dashboard link is not found!")
|
||||
for x in dashboardlinks.keys():
|
||||
if x in ("os-dashboard", "os-controller"):
|
||||
dashboardurl = dashboardlinks.get(x)
|
||||
if dashboardurl is None:
|
||||
raise Exception("No dashboard link is found")
|
||||
r = requests.get(dashboardurl, verify=False)
|
||||
r.raise_for_status()
|
||||
match = re.search(
|
||||
r'(?m)(http://\d+\.\d+\.\d+\.\d+:5000/v2\.0)', r.text)
|
||||
if match:
|
||||
print 'dashboard login page can be downloaded'
|
||||
break
|
||||
print (
|
||||
'dashboard login page failed to be downloaded\n'
|
||||
'the context is:\n%s\n') % r.text
|
||||
raise Exception("os-dashboard is not properly installed!")
|
||||
status, response = client.deploy_cluster(cluster_id)
|
||||
print '======================================='
|
||||
print 'deploy cluster %s' % response
|
||||
|
File diff suppressed because it is too large
Load Diff
0
compass/apiclient/v1/__init__.py
Normal file
0
compass/apiclient/v1/__init__.py
Normal file
305
compass/apiclient/v1/example.py
Executable file
305
compass/apiclient/v1/example.py
Executable file
@ -0,0 +1,305 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Example code to deploy a cluster by compass client api."""
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import sys
|
||||
import time
|
||||
|
||||
from compass.apiclient.restful import Client
|
||||
|
||||
|
||||
COMPASS_SERVER_URL = 'http://127.0.0.1/api'
|
||||
SWITCH_IP = '10.145.81.220'
|
||||
SWITCH_SNMP_VERSION = 'v2c'
|
||||
SWITCH_SNMP_COMMUNITY = 'public'
|
||||
#MACHINES_TO_ADD = ['00:11:20:30:40:01']
|
||||
CLUSTER_NAME = 'cluster2'
|
||||
HOST_NAME_PREFIX = 'host'
|
||||
SERVER_USERNAME = 'root'
|
||||
SERVER_PASSWORD = 'root'
|
||||
SERVICE_USERNAME = 'service'
|
||||
SERVICE_PASSWORD = 'service'
|
||||
CONSOLE_USERNAME = 'console'
|
||||
CONSOLE_PASSWORD = 'console'
|
||||
HA_VIP = ''
|
||||
#NAMESERVERS = '192.168.10.6'
|
||||
SEARCH_PATH = 'ods.com'
|
||||
#GATEWAY = '192.168.10.6'
|
||||
#PROXY = 'http://192.168.10.6:3128'
|
||||
#NTP_SERVER = '192.168.10.6'
|
||||
MANAGEMENT_IP_START = '192.168.10.130'
|
||||
MANAGEMENT_IP_END = '192.168.10.254'
|
||||
MANAGEMENT_IP_GATEWAY = '192.168.10.1'
|
||||
MANAGEMENT_NETMASK = '255.255.255.0'
|
||||
MANAGEMENT_NIC = 'eth0'
|
||||
MANAGEMENT_PROMISC = 0
|
||||
TENANT_IP_START = '192.168.10.100'
|
||||
TENANT_IP_END = '192.168.10.255'
|
||||
TENANT_IP_GATEWAY = '192.168.10.1'
|
||||
TENANT_NETMASK = '255.255.255.0'
|
||||
TENANT_NIC = 'eth0'
|
||||
TENANT_PROMISC = 0
|
||||
PUBLIC_IP_START = '12.234.32.100'
|
||||
PUBLIC_IP_END = '12.234.32.255'
|
||||
PUBLIC_IP_GATEWAY = '12.234.32.1'
|
||||
PUBLIC_NETMASK = '255.255.255.0'
|
||||
PUBLIC_NIC = 'eth1'
|
||||
PUBLIC_PROMISC = 1
|
||||
STORAGE_IP_START = '172.16.100.100'
|
||||
STORAGE_IP_END = '172.16.100.255'
|
||||
STORAGE_NETMASK = '255.255.255.0'
|
||||
STORAGE_IP_GATEWAY = '172.16.100.1'
|
||||
STORAGE_NIC = 'eth0'
|
||||
STORAGE_PROMISC = 0
|
||||
HOME_PERCENTAGE = 5
|
||||
TMP_PERCENTAGE = 5
|
||||
VAR_PERCENTAGE = 10
|
||||
#ROLES_LIST = [['os-dashboard']]
|
||||
|
||||
PRESET_VALUES = {
|
||||
'NAMESERVERS': '192.168.10.1',
|
||||
'NTP_SERVER': '192.168.10.1',
|
||||
'GATEWAY': '192.168.10.1',
|
||||
'PROXY': 'http://192.168.10.1:3128',
|
||||
'ROLES_LIST': 'os-dashboard',
|
||||
'MACHINES_TO_ADD': '00:11:20:30:40:01',
|
||||
'BUILD_TIMEOUT': 60
|
||||
}
|
||||
for v in PRESET_VALUES:
|
||||
if v in os.environ.keys():
|
||||
PRESET_VALUES[v] = os.environ.get(v)
|
||||
print (v + PRESET_VALUES[v] + " is set by env variables")
|
||||
else:
|
||||
print (PRESET_VALUES[v])
|
||||
|
||||
# get apiclient object.
|
||||
client = Client(COMPASS_SERVER_URL)
|
||||
|
||||
|
||||
# get all switches.
|
||||
status, resp = client.get_switches()
|
||||
print 'get all switches status: %s resp: %s' % (status, resp)
|
||||
|
||||
# add a switch.
|
||||
status, resp = client.add_switch(
|
||||
SWITCH_IP, version=SWITCH_SNMP_VERSION,
|
||||
community=SWITCH_SNMP_COMMUNITY)
|
||||
|
||||
print 'add a switch status: %s resp: %s' % (status, resp)
|
||||
|
||||
if status < 400:
|
||||
switch = resp['switch']
|
||||
else:
|
||||
status, resp = client.get_switches()
|
||||
print 'get all switches status: %s resp: %s' % (status, resp)
|
||||
switch = None
|
||||
for switch in resp['switches']:
|
||||
if switch['ip'] == SWITCH_IP:
|
||||
break
|
||||
|
||||
switch_id = switch['id']
|
||||
switch_ip = switch['ip']
|
||||
|
||||
|
||||
# if the switch is not in under_monitoring, wait for the poll switch task
|
||||
# update the swich information and change the switch state.
|
||||
while switch['state'] != 'under_monitoring':
|
||||
print 'waiting for the switch into under_monitoring'
|
||||
status, resp = client.get_switch(switch_id)
|
||||
print 'get switch %s status: %s, resp: %s' % (switch_id, status, resp)
|
||||
switch = resp['switch']
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
# get machines connected to the switch.
|
||||
status, resp = client.get_machines(switch_id=switch_id)
|
||||
print 'get all machines under switch %s status: %s, resp: %s' % (
|
||||
switch_id, status, resp)
|
||||
machines = {}
|
||||
MACHINES_TO_ADD = PRESET_VALUES['MACHINES_TO_ADD'].split()
|
||||
for machine in resp['machines']:
|
||||
mac = machine['mac']
|
||||
if mac in MACHINES_TO_ADD:
|
||||
machines[machine['id']] = mac
|
||||
|
||||
print 'machine to add: %s' % machines
|
||||
|
||||
if set(machines.values()) != set(MACHINES_TO_ADD):
|
||||
print 'only found macs %s while expected are %s' % (
|
||||
machines.values(), MACHINES_TO_ADD)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# get adapters.
|
||||
status, resp = client.get_adapters()
|
||||
print 'get all adapters status: %s, resp: %s' % (status, resp)
|
||||
adapter_ids = []
|
||||
for adapter in resp['adapters']:
|
||||
adapter_ids.append(adapter['id'])
|
||||
|
||||
adapter_id = adapter_ids[0]
|
||||
print 'adpater for deploying a cluster: %s' % adapter_id
|
||||
|
||||
|
||||
# add a cluster.
|
||||
status, resp = client.add_cluster(
|
||||
cluster_name=CLUSTER_NAME, adapter_id=adapter_id)
|
||||
print 'add cluster %s status: %s, resp: %s' % (CLUSTER_NAME, status, resp)
|
||||
cluster = resp['cluster']
|
||||
cluster_id = cluster['id']
|
||||
|
||||
# add hosts to the cluster.
|
||||
status, resp = client.add_hosts(
|
||||
cluster_id=cluster_id,
|
||||
machine_ids=machines.keys())
|
||||
print 'add hosts to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
host_ids = []
|
||||
for host in resp['cluster_hosts']:
|
||||
host_ids.append(host['id'])
|
||||
|
||||
print 'added hosts: %s' % host_ids
|
||||
|
||||
|
||||
# set cluster security
|
||||
status, resp = client.set_security(
|
||||
cluster_id, server_username=SERVER_USERNAME,
|
||||
server_password=SERVER_PASSWORD,
|
||||
service_username=SERVICE_USERNAME,
|
||||
service_password=SERVICE_PASSWORD,
|
||||
console_username=CONSOLE_USERNAME,
|
||||
console_password=CONSOLE_PASSWORD)
|
||||
print 'set security config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
|
||||
|
||||
# set cluster networking
|
||||
status, resp = client.set_networking(
|
||||
cluster_id,
|
||||
nameservers=PRESET_VALUES["NAMESERVERS"],
|
||||
search_path=SEARCH_PATH,
|
||||
gateway=PRESET_VALUES["GATEWAY"],
|
||||
proxy=PRESET_VALUES["PROXY"],
|
||||
ntp_server=PRESET_VALUES["NTP_SERVER"],
|
||||
ha_vip=HA_VIP,
|
||||
management_ip_start=MANAGEMENT_IP_START,
|
||||
management_ip_end=MANAGEMENT_IP_END,
|
||||
management_netmask=MANAGEMENT_NETMASK,
|
||||
management_nic=MANAGEMENT_NIC,
|
||||
management_gateway=MANAGEMENT_IP_GATEWAY,
|
||||
management_promisc=MANAGEMENT_PROMISC,
|
||||
tenant_ip_start=TENANT_IP_START,
|
||||
tenant_ip_end=TENANT_IP_END,
|
||||
tenant_netmask=TENANT_NETMASK,
|
||||
tenant_nic=TENANT_NIC,
|
||||
tenant_gateway=TENANT_IP_GATEWAY,
|
||||
tenant_promisc=TENANT_PROMISC,
|
||||
public_ip_start=PUBLIC_IP_START,
|
||||
public_ip_end=PUBLIC_IP_END,
|
||||
public_netmask=PUBLIC_NETMASK,
|
||||
public_nic=PUBLIC_NIC,
|
||||
public_gateway=PUBLIC_IP_GATEWAY,
|
||||
public_promisc=PUBLIC_PROMISC,
|
||||
storage_ip_start=STORAGE_IP_START,
|
||||
storage_ip_end=STORAGE_IP_END,
|
||||
storage_netmask=STORAGE_NETMASK,
|
||||
storage_nic=STORAGE_NIC,
|
||||
storage_gateway=STORAGE_IP_GATEWAY,
|
||||
storage_promisc=STORAGE_PROMISC)
|
||||
print 'set networking config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
|
||||
|
||||
# set partiton of each host in cluster
|
||||
status, resp = client.set_partition(
|
||||
cluster_id,
|
||||
home_percentage=HOME_PERCENTAGE,
|
||||
tmp_percentage=TMP_PERCENTAGE,
|
||||
var_percentage=VAR_PERCENTAGE)
|
||||
print 'set partition config to cluster %s status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
|
||||
|
||||
# set each host config in cluster.
|
||||
ROLES_LIST = [PRESET_VALUES['ROLES_LIST'].split()]
|
||||
for host_id in host_ids:
|
||||
if ROLES_LIST:
|
||||
roles = ROLES_LIST.pop(0)
|
||||
else:
|
||||
roles = []
|
||||
status, resp = client.update_host_config(
|
||||
host_id, hostname='%s%s' % (HOST_NAME_PREFIX, host_id),
|
||||
roles=roles)
|
||||
print 'set roles to host %s status: %s, resp: %s' % (
|
||||
host_id, status, resp)
|
||||
|
||||
|
||||
# deploy cluster.
|
||||
status, resp = client.deploy_hosts(cluster_id)
|
||||
print 'deploy cluster %s status: %s, resp: %s' % (cluster_id, status, resp)
|
||||
|
||||
|
||||
# get intalling progress.
|
||||
BUILD_TIMEOUT = float(PRESET_VALUES['BUILD_TIMEOUT'])
|
||||
timeout = time.time() + BUILD_TIMEOUT * 60
|
||||
while True:
|
||||
status, resp = client.get_cluster_installing_progress(cluster_id)
|
||||
print 'get cluster %s installing progress status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
progress = resp['progress']
|
||||
if (
|
||||
progress['state'] not in ['UNINITIALIZED', 'INSTALLING'] or
|
||||
progress['percentage'] >= 1.0
|
||||
):
|
||||
break
|
||||
if (
|
||||
time.time() > timeout
|
||||
):
|
||||
raise Exception("Timeout! The system is not ready in time.")
|
||||
|
||||
for host_id in host_ids:
|
||||
status, resp = client.get_host_installing_progress(host_id)
|
||||
print 'get host %s installing progress status: %s, resp: %s' % (
|
||||
host_id, status, resp)
|
||||
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
status, resp = client.get_dashboard_links(cluster_id)
|
||||
print 'get cluster %s dashboardlinks status: %s, resp: %s' % (
|
||||
cluster_id, status, resp)
|
||||
dashboardlinks = resp['dashboardlinks']
|
||||
if not dashboardlinks.keys():
|
||||
raise Exception("Dashboard link is not found!")
|
||||
for x in dashboardlinks.keys():
|
||||
if x in ("os-dashboard", "os-controller"):
|
||||
dashboardurl = dashboardlinks.get(x)
|
||||
if dashboardurl is None:
|
||||
raise Exception("No dashboard link is found")
|
||||
r = requests.get(dashboardurl, verify=False)
|
||||
r.raise_for_status()
|
||||
match = re.search(
|
||||
r'(?m)(http://\d+\.\d+\.\d+\.\d+:5000/v2\.0)', r.text)
|
||||
if match:
|
||||
print 'dashboard login page can be downloaded'
|
||||
break
|
||||
print (
|
||||
'dashboard login page failed to be downloaded\n'
|
||||
'the context is:\n%s\n') % r.text
|
||||
raise Exception("os-dashboard is not properly installed!")
|
656
compass/apiclient/v1/restful.py
Normal file
656
compass/apiclient/v1/restful.py
Normal file
@ -0,0 +1,656 @@
|
||||
# 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.
|
||||
|
||||
"""Compass api client library.
|
||||
|
||||
.. moduleauthor:: Xiaodong Wang <xiaodongwang@huawei.com>
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
import requests
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""wrapper for compass restful api.
|
||||
|
||||
.. note::
|
||||
Every api client method returns (status as int, resp as dict).
|
||||
If the api succeeds, the status is 2xx, the resp includes
|
||||
{'status': 'OK'} and other keys depend on method.
|
||||
If the api fails, the status is 4xx, the resp includes {
|
||||
'status': '...', 'message': '...'}
|
||||
"""
|
||||
|
||||
def __init__(self, url, headers=None, proxies=None, stream=None):
|
||||
"""Restful api client initialization.
|
||||
|
||||
:param url: url to the compass web service.
|
||||
:type url: str.
|
||||
:param headers: http header sent in each restful request.
|
||||
:type headers: dict of header name (str) to heade value (str).
|
||||
:param proxies: the proxy address for each protocol.
|
||||
:type proxies: dict of protocol (str) to proxy url (str).
|
||||
:param stream: wether the restful response should be streamed.
|
||||
:type stream: bool.
|
||||
"""
|
||||
self.url_ = url
|
||||
self.session_ = requests.Session()
|
||||
if headers:
|
||||
self.session_.headers = headers
|
||||
|
||||
if proxies is not None:
|
||||
self.session_.proxies = proxies
|
||||
|
||||
if stream is not None:
|
||||
self.session_.stream = stream
|
||||
|
||||
def __del__(self):
|
||||
self.session_.close()
|
||||
|
||||
@classmethod
|
||||
def _get_response(cls, resp):
|
||||
"""decapsulate the resp to status code and python formatted data."""
|
||||
resp_obj = {}
|
||||
try:
|
||||
resp_obj = resp.json()
|
||||
except Exception as error:
|
||||
logging.error('failed to load object from %s: %s',
|
||||
resp.url, resp.content)
|
||||
logging.exception(error)
|
||||
resp_obj['status'] = 'Json Parsing Failure'
|
||||
resp_obj['message'] = resp.content
|
||||
|
||||
return resp.status_code, resp_obj
|
||||
|
||||
def _get(self, relative_url, params=None):
|
||||
"""encapsulate get method."""
|
||||
url = '%s%s' % (self.url_, relative_url)
|
||||
if params:
|
||||
resp = self.session_.get(url, params=params)
|
||||
else:
|
||||
resp = self.session_.get(url)
|
||||
|
||||
return self._get_response(resp)
|
||||
|
||||
def _post(self, relative_url, data=None):
|
||||
"""encapsulate post method."""
|
||||
url = '%s%s' % (self.url_, relative_url)
|
||||
if data:
|
||||
resp = self.session_.post(url, json.dumps(data))
|
||||
else:
|
||||
resp = self.session_.post(url)
|
||||
|
||||
return self._get_response(resp)
|
||||
|
||||
def _put(self, relative_url, data=None):
|
||||
"""encapsulate put method."""
|
||||
url = '%s%s' % (self.url_, relative_url)
|
||||
if data:
|
||||
resp = self.session_.put(url, json.dumps(data))
|
||||
else:
|
||||
resp = self.session_.put(url)
|
||||
|
||||
return self._get_response(resp)
|
||||
|
||||
def _delete(self, relative_url):
|
||||
"""encapsulate delete method."""
|
||||
url = '%s%s' % (self.url_, relative_url)
|
||||
return self._get_response(self.session_.delete(url))
|
||||
|
||||
def get_switches(self, switch_ips=None, switch_networks=None, limit=None):
|
||||
"""List details for switches.
|
||||
|
||||
.. note::
|
||||
The switches can be filtered by switch_ips, siwtch_networks and
|
||||
limit. These params can be None or missing. If the param is None
|
||||
or missing, that filter will be ignored.
|
||||
|
||||
:param switch_ips: Filter switch(es) with IP(s).
|
||||
:type switch_ips: list of str. Each is as 'xxx.xxx.xxx.xxx'.
|
||||
:param switch_networks: Filter switche(es) with network(s).
|
||||
:type switch_networks: list of str. Each is as 'xxx.xxx.xxx.xxx/xx'.
|
||||
:param limit: int, The maximum number of switches to return.
|
||||
:type limit: int. 0 means unlimited.
|
||||
"""
|
||||
params = {}
|
||||
if switch_ips:
|
||||
params['switchIp'] = switch_ips
|
||||
|
||||
if switch_networks:
|
||||
params['switchIpNetwork'] = switch_networks
|
||||
|
||||
if limit:
|
||||
params['limit'] = limit
|
||||
return self._get('/switches', params=params)
|
||||
|
||||
def get_switch(self, switch_id):
|
||||
"""Lists details for a specified switch.
|
||||
|
||||
:param switch_id: switch id.
|
||||
:type switch_id: int.
|
||||
"""
|
||||
return self._get('/switches/%s' % switch_id)
|
||||
|
||||
def add_switch(self, switch_ip, version=None, community=None,
|
||||
username=None, password=None, raw_data=None):
|
||||
"""Create a switch with specified details.
|
||||
|
||||
.. note::
|
||||
It will trigger switch polling if successful. During
|
||||
the polling, MAC address of the devices connected to the
|
||||
switch will be learned by SNMP or SSH.
|
||||
|
||||
:param switch_ip: the switch IP address.
|
||||
:type switch_ip: str, as xxx.xxx.xxx.xxx.
|
||||
:param version: SNMP version when using SNMP to poll switch.
|
||||
:type version: str, one in ['v1', 'v2c', 'v3']
|
||||
:param community: SNMP community when using SNMP to poll switch.
|
||||
:type community: str, usually 'public'.
|
||||
:param username: SSH username when using SSH to poll switch.
|
||||
:type username: str.
|
||||
:param password: SSH password when using SSH to poll switch.
|
||||
:type password: str.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['switch'] = {}
|
||||
data['switch']['ip'] = switch_ip
|
||||
data['switch']['credential'] = {}
|
||||
if version:
|
||||
data['switch']['credential']['version'] = version
|
||||
|
||||
if community:
|
||||
data['switch']['credential']['community'] = community
|
||||
|
||||
if username:
|
||||
data['switch']['credential']['username'] = username
|
||||
|
||||
if password:
|
||||
data['switch']['credential']['password'] = password
|
||||
|
||||
return self._post('/switches', data=data)
|
||||
|
||||
def update_switch(self, switch_id, ip_addr=None,
|
||||
version=None, community=None,
|
||||
username=None, password=None,
|
||||
raw_data=None):
|
||||
"""Updates a switch with specified details.
|
||||
|
||||
.. note::
|
||||
It will trigger switch polling if successful. During
|
||||
the polling, MAC address of the devices connected to the
|
||||
switch will be learned by SNMP or SSH.
|
||||
|
||||
:param switch_id: switch id
|
||||
:type switch_id: int.
|
||||
:param ip_addr: the switch ip address.
|
||||
:type ip_addr: str, as 'xxx.xxx.xxx.xxx' format.
|
||||
:param version: SNMP version when using SNMP to poll switch.
|
||||
:type version: str, one in ['v1', 'v2c', 'v3'].
|
||||
:param community: SNMP community when using SNMP to poll switch.
|
||||
:type community: str, usually be 'public'.
|
||||
:param username: username when using SSH to poll switch.
|
||||
:type username: str.
|
||||
:param password: password when using SSH to poll switch.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['switch'] = {}
|
||||
if ip_addr:
|
||||
data['switch']['ip'] = ip_addr
|
||||
|
||||
data['switch']['credential'] = {}
|
||||
if version:
|
||||
data['switch']['credential']['version'] = version
|
||||
|
||||
if community:
|
||||
data['switch']['credential']['community'] = community
|
||||
|
||||
if username:
|
||||
data['switch']['credential']['username'] = username
|
||||
|
||||
if password:
|
||||
data['switch']['credential']['password'] = password
|
||||
|
||||
return self._put('/switches/%s' % switch_id, data=data)
|
||||
|
||||
def delete_switch(self, switch_id):
|
||||
"""Not implemented in api."""
|
||||
return self._delete('/switches/%s' % switch_id)
|
||||
|
||||
def get_machines(self, switch_id=None, vlan_id=None,
|
||||
port=None, limit=None):
|
||||
"""Get the details of machines.
|
||||
|
||||
.. note::
|
||||
The machines can be filtered by switch_id, vlan_id, port
|
||||
and limit. These params can be None or missing. If the param
|
||||
is None or missing, the filter will be ignored.
|
||||
|
||||
:param switch_id: Return machine(s) connected to the switch.
|
||||
:type switch_id: int.
|
||||
:param vlan_id: Return machine(s) belonging to the vlan.
|
||||
:type vlan_id: int.
|
||||
:param port: Return machine(s) connect to the port.
|
||||
:type port: int.
|
||||
:param limit: the maximum number of machines will be returned.
|
||||
:type limit: int. 0 means no limit.
|
||||
"""
|
||||
params = {}
|
||||
if switch_id:
|
||||
params['switchId'] = switch_id
|
||||
|
||||
if vlan_id:
|
||||
params['vlanId'] = vlan_id
|
||||
|
||||
if port:
|
||||
params['port'] = port
|
||||
|
||||
if limit:
|
||||
params['limit'] = limit
|
||||
|
||||
return self._get('/machines', params=params)
|
||||
|
||||
def get_machine(self, machine_id):
|
||||
"""Lists the details for a specified machine.
|
||||
|
||||
:param machine_id: Return machine with the id.
|
||||
:type machine_id: int.
|
||||
"""
|
||||
return self._get('/machines/%s' % machine_id)
|
||||
|
||||
def get_clusters(self):
|
||||
"""Lists the details for all clusters.
|
||||
"""
|
||||
return self._get('/clusters')
|
||||
|
||||
def get_cluster(self, cluster_id):
|
||||
"""Lists the details of the specified cluster.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
"""
|
||||
return self._get('/clusters/%d' % cluster_id)
|
||||
|
||||
def add_cluster(self, cluster_name, adapter_id, raw_data=None):
|
||||
"""Creates a cluster by specified name and given adapter id.
|
||||
|
||||
:param cluster_name: cluster name.
|
||||
:type cluster_name: str.
|
||||
:param adapter_id: adapter id.
|
||||
:type adapter_id: int.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['cluster'] = {}
|
||||
data['cluster']['name'] = cluster_name
|
||||
data['cluster']['adapter_id'] = adapter_id
|
||||
return self._post('/clusters', data=data)
|
||||
|
||||
def add_hosts(self, cluster_id, machine_ids, raw_data=None):
|
||||
"""add the specified machine(s) as the host(s) to the cluster.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
:param machine_ids: machine ids to add to cluster.
|
||||
:type machine_ids: list of int, each is the id of one machine.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['addHosts'] = machine_ids
|
||||
return self._post('/clusters/%d/action' % cluster_id, data=data)
|
||||
|
||||
def remove_hosts(self, cluster_id, host_ids, raw_data=None):
|
||||
"""remove the specified host(s) from the cluster.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
:param host_ids: host ids to remove from cluster.
|
||||
:type host_ids: list of int, each is the id of one host.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['removeHosts'] = host_ids
|
||||
return self._post('/clusters/%s/action' % cluster_id, data=data)
|
||||
|
||||
def replace_hosts(self, cluster_id, machine_ids, raw_data=None):
|
||||
"""replace the cluster hosts with the specified machine(s).
|
||||
|
||||
:param cluster_id: int, The unique identifier of the cluster.
|
||||
:type cluster_id: int.
|
||||
:param machine_ids: the machine ids to replace the hosts in cluster.
|
||||
:type machine_ids: list of int, each is the id of one machine.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['replaceAllHosts'] = machine_ids
|
||||
return self._post('/clusters/%s/action' % cluster_id, data=data)
|
||||
|
||||
def deploy_hosts(self, cluster_id, raw_data=None):
|
||||
"""Deploy the cluster.
|
||||
|
||||
:param cluster_id: The unique identifier of the cluster
|
||||
:type cluster_id: int.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
data['deploy'] = []
|
||||
return self._post('/clusters/%d/action' % cluster_id, data=data)
|
||||
|
||||
@classmethod
|
||||
def parse_security(cls, kwargs):
|
||||
"""parse the arguments to security data."""
|
||||
data = {}
|
||||
for key, value in kwargs.items():
|
||||
if '_' not in key:
|
||||
continue
|
||||
key_name, key_value = key.split('_', 1)
|
||||
data.setdefault(
|
||||
'%s_credentials' % key_name, {})[key_value] = value
|
||||
|
||||
return data
|
||||
|
||||
def set_security(self, cluster_id, **kwargs):
|
||||
"""Update the cluster security configuration.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
:param <security_name>_username: username of the security name.
|
||||
:type <security_name>_username: str.
|
||||
:param <security_name>_password: passowrd of the security name.
|
||||
:type <security_name>_password: str.
|
||||
|
||||
.. note::
|
||||
security_name should be one of ['server', 'service', 'console'].
|
||||
"""
|
||||
data = {}
|
||||
data['security'] = self.parse_security(kwargs)
|
||||
return self._put('/clusters/%d/security' % cluster_id, data=data)
|
||||
|
||||
@classmethod
|
||||
def parse_networking(cls, kwargs):
|
||||
"""parse arguments to network data."""
|
||||
data = {}
|
||||
global_keys = [
|
||||
'nameservers', 'search_path', 'gateway',
|
||||
'proxy', 'ntp_server', 'ha_vip']
|
||||
for key, value in kwargs.items():
|
||||
if key in global_keys:
|
||||
data.setdefault('global', {})[key] = value
|
||||
else:
|
||||
if '_' not in key:
|
||||
continue
|
||||
|
||||
key_name, key_value = key.split('_', 1)
|
||||
data.setdefault(
|
||||
'interfaces', {}
|
||||
).setdefault(
|
||||
key_name, {}
|
||||
)[key_value] = value
|
||||
|
||||
return data
|
||||
|
||||
def set_networking(self, cluster_id, **kwargs):
|
||||
"""Update the cluster network configuration.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
:param nameservers: comma seperated nameserver ip address.
|
||||
:type nameservers: str.
|
||||
:param search_path: comma seperated dns name search path.
|
||||
:type search_path: str.
|
||||
:param gateway: gateway ip address for routing to outside.
|
||||
:type gateway: str.
|
||||
:param proxy: proxy url for downloading packages.
|
||||
:type proxy: str.
|
||||
:param ntp_server: ntp server ip address to sync timestamp.
|
||||
:type ntp_server: str.
|
||||
:param ha_vip: ha vip address to run ha proxy.
|
||||
:type ha_vip: str.
|
||||
:param <interface>_ip_start: start ip address to host's interface.
|
||||
:type <interface>_ip_start: str.
|
||||
:param <interface>_ip_end: end ip address to host's interface.
|
||||
:type <interface>_ip_end: str.
|
||||
:param <interface>_netmask: netmask to host's interface.
|
||||
:type <interface>_netmask: str.
|
||||
:param <interface>_nic: host physical interface name.
|
||||
:type <interface>_nic: str.
|
||||
:param <interface>_promisc: if the interface in promiscous mode.
|
||||
:type <interface>_promisc: int, 0 or 1.
|
||||
|
||||
.. note::
|
||||
interface should be one of ['management', 'tenant',
|
||||
'public', 'storage'].
|
||||
"""
|
||||
data = {}
|
||||
data['networking'] = self.parse_networking(kwargs)
|
||||
return self._put('/clusters/%d/networking' % cluster_id, data=data)
|
||||
|
||||
@classmethod
|
||||
def parse_partition(cls, kwargs):
|
||||
"""parse arguments to partition data."""
|
||||
data = {}
|
||||
for key, value in kwargs.items():
|
||||
if key.endswith('_percentage'):
|
||||
key_name = key[:-len('_percentage')]
|
||||
data[key_name] = '%s%%' % value
|
||||
elif key.endswitch('_mbytes'):
|
||||
key_name = key[:-len('_mbytes')]
|
||||
data[key_name] = str(value)
|
||||
|
||||
return ';'.join([
|
||||
'/%s %s' % (key, value) for key, value in data.items()
|
||||
])
|
||||
|
||||
def set_partition(self, cluster_id, **kwargs):
|
||||
"""Update the cluster partition configuration.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
:param <partition>_percentage: the partiton percentage.
|
||||
:type <partition>_percentage: float between 0 to 100.
|
||||
:param <partition>_mbytes: the partition mbytes.
|
||||
:type <partition>_mbytes: int.
|
||||
|
||||
.. note::
|
||||
partition should be one of ['home', 'var', 'tmp'].
|
||||
"""
|
||||
data = {}
|
||||
data['partition'] = self.parse_partition(kwargs)
|
||||
return self._put('/clusters/%s/partition' % cluster_id, data=data)
|
||||
|
||||
def get_hosts(self, hostname=None, clustername=None):
|
||||
"""Lists the details of hosts.
|
||||
|
||||
.. note::
|
||||
The hosts can be filtered by hostname, clustername.
|
||||
These params can be None or missing. If the param
|
||||
is None or missing, the filter will be ignored.
|
||||
|
||||
:param hostname: The name of a host.
|
||||
:type hostname: str.
|
||||
:param clustername: The name of a cluster.
|
||||
:type clustername: str.
|
||||
"""
|
||||
params = {}
|
||||
if hostname:
|
||||
params['hostname'] = hostname
|
||||
|
||||
if clustername:
|
||||
params['clustername'] = clustername
|
||||
|
||||
return self._get('/clusterhosts', params=params)
|
||||
|
||||
def get_host(self, host_id):
|
||||
"""Lists the details for the specified host.
|
||||
|
||||
:param host_id: host id.
|
||||
:type host_id: int.
|
||||
"""
|
||||
return self._get('/clusterhosts/%s' % host_id)
|
||||
|
||||
def get_host_config(self, host_id):
|
||||
"""Lists the details of the config for the specified host.
|
||||
|
||||
:param host_id: host id.
|
||||
:type host_id: int.
|
||||
"""
|
||||
return self._get('/clusterhosts/%s/config' % host_id)
|
||||
|
||||
def update_host_config(self, host_id, hostname=None,
|
||||
roles=None, raw_data=None, **kwargs):
|
||||
"""Updates config for the host.
|
||||
|
||||
:param host_id: host id.
|
||||
:type host_id: int.
|
||||
:param hostname: host name.
|
||||
:type hostname: str.
|
||||
:param security_<security>_username: username of the security name.
|
||||
:type security_<security>_username: str.
|
||||
:param security_<security>_password: passowrd of the security name.
|
||||
:type security_<security>_password: str.
|
||||
:param networking_nameservers: comma seperated nameserver ip address.
|
||||
:type networking_nameservers: str.
|
||||
:param networking_search_path: comma seperated dns name search path.
|
||||
:type networking_search_path: str.
|
||||
:param networking_gateway: gateway ip address for routing to outside.
|
||||
:type networking_gateway: str.
|
||||
:param networking_proxy: proxy url for downloading packages.
|
||||
:type networking_proxy: str.
|
||||
:param networking_ntp_server: ntp server ip address to sync timestamp.
|
||||
:type networking_ntp_server: str.
|
||||
:param networking_<interface>_ip: ip address to host interface.
|
||||
:type networking_<interface>_ip: str.
|
||||
:param networking_<interface>_netmask: netmask to host's interface.
|
||||
:type networking_<interface>_netmask: str.
|
||||
:param networking_<interface>_nic: host physical interface name.
|
||||
:type networking_<interface>_nic: str.
|
||||
:param networking_<interface>_promisc: if the interface is promiscous.
|
||||
:type networking_<interface>_promisc: int, 0 or 1.
|
||||
:param partition_<partition>_percentage: the partiton percentage.
|
||||
:type partition_<partition>_percentage: float between 0 to 100.
|
||||
:param partition_<partition>_mbytes: the partition mbytes.
|
||||
:type partition_<partition>_mbytes: int.
|
||||
:param roles: host assigned roles in the cluster.
|
||||
:type roles: list of str.
|
||||
"""
|
||||
data = {}
|
||||
if raw_data:
|
||||
data = raw_data
|
||||
else:
|
||||
if hostname:
|
||||
data['hostname'] = hostname
|
||||
|
||||
sub_kwargs = {}
|
||||
for key, value in kwargs.items():
|
||||
key_name, key_value = key.split('_', 1)
|
||||
sub_kwargs.setdefault(key_name, {})[key_value] = value
|
||||
|
||||
if 'security' in sub_kwargs:
|
||||
data['security'] = self.parse_security(sub_kwargs['security'])
|
||||
|
||||
if 'networking' in sub_kwargs:
|
||||
data['networking'] = self.parse_networking(
|
||||
sub_kwargs['networking'])
|
||||
if 'partition' in sub_kwargs:
|
||||
data['partition'] = self.parse_partition(
|
||||
sub_kwargs['partition'])
|
||||
|
||||
if roles:
|
||||
data['roles'] = roles
|
||||
|
||||
return self._put('/clusterhosts/%s/config' % host_id, data)
|
||||
|
||||
def delete_from_host_config(self, host_id, delete_key):
|
||||
"""Deletes one key in config for the host.
|
||||
|
||||
:param host_id: host id.
|
||||
:type host_id: int.
|
||||
:param delete_key: the key in host config to be deleted.
|
||||
:type delete_key: str.
|
||||
"""
|
||||
return self._delete('/clusterhosts/%s/config/%s' % (
|
||||
host_id, delete_key))
|
||||
|
||||
def get_adapters(self, name=None):
|
||||
"""Lists details of adapters.
|
||||
|
||||
.. note::
|
||||
the adapter can be filtered by name of name is given and not None.
|
||||
|
||||
:param name: adapter name.
|
||||
:type name: str.
|
||||
"""
|
||||
params = {}
|
||||
if name:
|
||||
params['name'] = name
|
||||
|
||||
return self._get('/adapters', params=params)
|
||||
|
||||
def get_adapter(self, adapter_id):
|
||||
"""Lists details for the specified adapter.
|
||||
|
||||
:param adapter_id: adapter id.
|
||||
:type adapter_id: int.
|
||||
"""
|
||||
return self._get('/adapters/%s' % adapter_id)
|
||||
|
||||
def get_adapter_roles(self, adapter_id):
|
||||
"""Lists roles to assign to hosts for the specified adapter.
|
||||
|
||||
:param adapter_id: adapter id.
|
||||
:type adapter_id: int.
|
||||
"""
|
||||
return self._get('/adapters/%s/roles' % adapter_id)
|
||||
|
||||
def get_host_installing_progress(self, host_id):
|
||||
"""Lists progress details for the specified host.
|
||||
|
||||
:param host_id: host id.
|
||||
:type host_id: int.
|
||||
"""
|
||||
return self._get('/clusterhosts/%s/progress' % host_id)
|
||||
|
||||
def get_cluster_installing_progress(self, cluster_id):
|
||||
"""Lists progress details for the specified cluster.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:param cluster_id: int.
|
||||
"""
|
||||
|
||||
return self._get('/clusters/%s/progress' % cluster_id)
|
||||
|
||||
def get_dashboard_links(self, cluster_id):
|
||||
"""Lists links for dashboards of deployed cluster.
|
||||
|
||||
:param cluster_id: cluster id.
|
||||
:type cluster_id: int.
|
||||
"""
|
||||
params = {}
|
||||
params['cluster_id'] = cluster_id
|
||||
return self._get('/dashboardlinks', params)
|
Loading…
x
Reference in New Issue
Block a user