Move API call to function and implement keys

Move all API calls to a new common function called call_api to
facilitate easier future changes. Use this function to implement API key
handling via request header value as well as integrate the request URI
generation and debug output handling.

Closes #65
This commit is contained in:
Joshua Boniface 2020-01-08 19:34:24 -05:00
parent 10d892c698
commit 6e5065511c
7 changed files with 298 additions and 756 deletions

View File

@ -24,33 +24,14 @@ import re
import json
import time
import math
import requests
import cli_lib.ansiprint as ansiprint
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
from cli_lib.common import call_api
#
# Supplemental functions
#
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
# Format byte sizes to/from human-readable units
byte_unit_matrix = {
'B': 1,
@ -126,12 +107,7 @@ def ceph_status(config):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/status')
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/status')
if response.status_code == 200:
return True, response.json()
@ -146,12 +122,7 @@ def ceph_util(config):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/utilization')
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/utilization')
if response.status_code == 200:
return True, response.json()
@ -177,12 +148,7 @@ def ceph_osd_info(config, osd):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/osd/{osd}'.format(osd=osd))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/osd/{osd}'.format(osd=osd))
if response.status_code == 200:
return True, response.json()
@ -201,13 +167,7 @@ def ceph_osd_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/storage/ceph/osd')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/osd', params=params)
if response.status_code == 200:
return True, response.json()
@ -222,17 +182,12 @@ def ceph_osd_add(config, node, device, weight):
API arguments: node={node}, device={device}, weight={weight}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/osd')
response = requests.post(
request_uri,
params={
params = {
'node': node,
'device': device,
'weight': weight
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/osd', params=params)
if response.status_code == 200:
retstatus = True
@ -249,15 +204,10 @@ def ceph_osd_remove(config, osdid):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/osd/{osdid}'.format(osdid=osdid))
response = requests.delete(
request_uri,
params={
params = {
'yes-i-really-mean-it': 'yes'
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/storage/ceph/osd/{osdid}'.format(osdid=osdid), params=params)
if response.status_code == 200:
retstatus = True
@ -274,15 +224,10 @@ def ceph_osd_state(config, osdid, state):
API arguments: state={state}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/osd/{osdid}/state'.format(osdid=osdid))
response = requests.post(
request_uri,
params={
params = {
'state': state
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/osd/{osdid}/state'.format(osdid=osdid), params=params)
if response.status_code == 200:
retstatus = True
@ -299,16 +244,11 @@ def ceph_osd_option(config, option, action):
API arguments: option={option}, action={action}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/option')
response = requests.post(
request_uri,
params={
params = {
'option': option,
'action': action
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/option', params=params)
if response.status_code == 200:
retstatus = True
@ -588,12 +528,7 @@ def ceph_pool_info(config, pool):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/pool/{pool}'.format(pool=pool))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/pool/{pool}'.format(pool=pool))
if response.status_code == 200:
return True, response.json()
@ -612,13 +547,7 @@ def ceph_pool_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/storage/ceph/pool')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/pool', params=params)
if response.status_code == 200:
return True, response.json()
@ -633,17 +562,12 @@ def ceph_pool_add(config, pool, pgs, replcfg):
API arguments: pool={pool}, pgs={pgs}, replcfg={replcfg}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/pool')
response = requests.post(
request_uri,
params={
params = {
'pool': pool,
'pgs': pgs,
'replcfg': replcfg
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/pool', params=params)
if response.status_code == 200:
retstatus = True
@ -660,15 +584,10 @@ def ceph_pool_remove(config, pool):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/pool/{pool}'.format(pool=pool))
response = requests.delete(
request_uri,
params={
params = {
'yes-i-really-mean-it': 'yes'
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/storage/ceph/pool/{pool}'.format(pool=pool), params=params)
if response.status_code == 200:
retstatus = True
@ -886,12 +805,7 @@ def ceph_volume_info(config, pool, volume):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool))
if response.status_code == 200:
return True, response.json()
@ -912,13 +826,7 @@ def ceph_volume_list(config, limit, pool):
if pool:
params['pool'] = pool
request_uri = get_request_uri(config, '/storage/ceph/volume')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/volume', params=params)
if response.status_code == 200:
return True, response.json()
@ -933,17 +841,12 @@ def ceph_volume_add(config, pool, volume, size):
API arguments: volume={volume}, pool={pool}, size={size}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/volume')
response = requests.post(
request_uri,
params={
params = {
'volume': volume,
'pool': pool,
'size': size
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/volume', params=params)
if response.status_code == 200:
retstatus = True
@ -960,12 +863,7 @@ def ceph_volume_remove(config, pool, volume):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool))
if response.status_code == 200:
retstatus = True
@ -989,13 +887,7 @@ def ceph_volume_modify(config, pool, volume, new_name=None, new_size=None):
if new_size:
params['new_size'] = new_size
request_uri = get_request_uri(config, '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool))
response = requests.put(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/storage/ceph/volume/{pool}/{volume}'.format(volume=volume, pool=pool), params=params)
if response.status_code == 200:
retstatus = True
@ -1012,15 +904,10 @@ def ceph_volume_clone(config, pool, volume, new_volume):
API arguments: new_volume={new_volume
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/volume/{pool}/{volume}/clone'.format(volume=volume, pool=pool))
response = requests.post(
request_uri,
params={
params = {
'new_volume': new_volume
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/volume/{pool}/{volume}/clone'.format(volume=volume, pool=pool), params=params)
if response.status_code == 200:
retstatus = True
@ -1155,12 +1042,7 @@ def ceph_snapshot_info(config, pool, volume, snapshot):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool))
if response.status_code == 200:
return True, response.json()
@ -1183,13 +1065,7 @@ def ceph_snapshot_list(config, limit, volume, pool):
if pool:
params['pool'] = pool
request_uri = get_request_uri(config, '/storage/ceph/snapshot')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/storage/ceph/snapshot', params=params)
if response.status_code == 200:
return True, response.json()
@ -1204,17 +1080,12 @@ def ceph_snapshot_add(config, pool, volume, snapshot):
API arguments: snapshot={snapshot}, volume={volume}, pool={pool}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/snapshot')
response = requests.post(
request_uri,
params={
params = {
'snapshot': snapshot,
'volume': volume,
'pool': pool
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/storage/ceph/snapshot', params=params)
if response.status_code == 200:
retstatus = True
@ -1231,12 +1102,7 @@ def ceph_snapshot_remove(config, pool, volume, snapshot):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool))
if response.status_code == 200:
retstatus = True
@ -1258,13 +1124,7 @@ def ceph_snapshot_modify(config, pool, volume, snapshot, new_name=None):
if new_name:
params['new_name'] = new_name
request_uri = get_request_uri(config, '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool))
response = requests.put(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/storage/ceph/snapshot/{pool}/{volume}/{snapshot}'.format(snapshot=snapshot, volume=volume, pool=pool), params=params)
if response.status_code == 200:
retstatus = True

View File

@ -21,28 +21,9 @@
###############################################################################
import json
import requests
import cli_lib.ansiprint as ansiprint
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: POST {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
from cli_lib.common import call_api
def initialize(config):
"""
@ -52,12 +33,7 @@ def initialize(config):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/initialize')
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/initialize')
if response.status_code == 200:
retstatus = True
@ -74,12 +50,7 @@ def get_info(config):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/status')
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/status')
if response.status_code == 200:
return True, response.json()

View File

@ -0,0 +1,82 @@
#!/usr/bin/env python3
# common.py - PVC CLI client function library, Common functions
# Part of the Parallel Virtual Cluster (PVC) system
#
# Copyright (C) 2018-2019 Joshua M. Boniface <joshua@boniface.me>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
import requests
import click
def call_api(config, operation, request_uri, params=None, data=None):
# Craft the URI
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
request_uri
)
# Craft the authentication header if required
if config['api_key']:
headers = {'X-Api-Key': config['api_key']}
else:
headers = None
# Determine the request type and hit the API
if operation == 'get':
response = requests.get(
uri,
headers=headers,
params=params,
data=data
)
if operation == 'post':
response = requests.post(
uri,
headers=headers,
params=params,
data=data
)
if operation == 'put':
response = requests.put(
uri,
headers=headers,
params=params,
data=data
)
if operation == 'patch':
response = requests.patch(
uri,
headers=headers,
params=params,
data=data
)
if operation == 'delete':
response = requests.delete(
uri,
headers=headers,
params=params,
data=data
)
# Display debug output
if config['debug']:
click.echo('API endpoint: {}'.format(uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
# Return the response object
return response

View File

@ -22,28 +22,9 @@
import difflib
import colorama
import requests
import cli_lib.ansiprint as ansiprint
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: POST {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
from cli_lib.common import call_api
def isValidMAC(macaddr):
allowed = re.compile(r"""
@ -82,12 +63,7 @@ def net_info(config, net):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/network/{net}'.format(net=net))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network/{net}'.format(net=net))
if response.status_code == 200:
return True, response.json()
@ -106,13 +82,7 @@ def net_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/network')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network', params=params)
if response.status_code == 200:
return True, response.json()
@ -127,10 +97,7 @@ def net_add(config, vni, description, nettype, domain, name_servers, ip4_network
API arguments: lots
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network')
response = requests.post(
request_uri,
params={
params = {
'vni': vni,
'description': description,
'nettype': nettype,
@ -144,9 +111,7 @@ def net_add(config, vni, description, nettype, domain, name_servers, ip4_network
'dhcp4_start': dhcp4_start,
'dhcp4_end': dhcp4_end
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/network', params=params)
if response.status_code == 200:
retstatus = True
@ -163,7 +128,6 @@ def net_modify(config, net, description, domain, name_servers, ip4_network, ip4_
API arguments: lots
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network/{net}'.format(net=net))
params = dict()
if description is not None:
params['description'] = description
@ -186,12 +150,7 @@ def net_modify(config, net, description, domain, name_servers, ip4_network, ip4_
if dhcp4_end is not None:
params['dhcp4_end'] = dhcp4_end
response = requests.put(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/network/{net}'.format(net=net), params=params)
if response.status_code == 200:
retstatus = True
@ -208,12 +167,7 @@ def net_remove(config, net):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network/{net}'.format(net=net))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/network/{net}'.format(net=net))
if response.status_code == 200:
retstatus = True
@ -233,12 +187,7 @@ def net_dhcp_info(config, net, mac):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/network/{net}/lease/{mac}'.format(net=net, mac=mac))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network/{net}/lease/{mac}'.format(net=net, mac=mac))
if response.status_code == 200:
return True, response.json()
@ -259,13 +208,7 @@ def net_dhcp_list(config, net, limit, only_static=False):
if only_static:
params['static'] = True
request_uri = get_request_uri(config, '/network/{net}/lease'.format(net=net))
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network/{net}/lease'.format(net=net), params=params)
if response.status_code == 200:
return True, response.json()
@ -280,17 +223,12 @@ def net_dhcp_add(config, net, ipaddr, macaddr, hostname):
API arguments: macaddress=macaddr, ipaddress=ipaddr, hostname=hostname
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network/{net}/lease'.format(net=net))
response = requests.post(
request_uri,
params={
params = {
'macaddress': macaddr,
'ipaddress': ipaddr,
'hostname': hostname
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/network/{net}/lease'.format(net=net), params=params)
if response.status_code == 200:
retstatus = True
@ -307,12 +245,7 @@ def net_dhcp_remove(config, net, mac):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network/{net}/lease/{mac}'.format(net=net, mac=mac))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/network/{net}/lease/{mac}'.format(net=net, mac=mac))
if response.status_code == 200:
retstatus = True
@ -332,12 +265,7 @@ def net_acl_info(config, net, description):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/network/{net}/acl/{description}'.format(net=net, description=description))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network/{net}/acl/{description}'.format(net=net, description=description))
if response.status_code == 200:
return True, response.json()
@ -358,13 +286,7 @@ def net_acl_list(config, net, limit, direction):
if direction is not None:
params['direction'] = direction
request_uri = get_request_uri(config, '/network/{net}/acl'.format(net=net))
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/network/{net}/acl'.format(net=net), params=params)
if response.status_code == 200:
return True, response.json()
@ -386,13 +308,7 @@ def net_acl_add(config, net, direction, description, rule, order):
if order is not None:
params['order'] = order
request_uri = get_request_uri(config, '/network/{net}/acl'.format(net=net))
response = requests.post(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/network/{net}/acl'.format(net=net), params=params)
if response.status_code == 200:
retstatus = True
@ -409,12 +325,7 @@ def net_acl_remove(config, net, description):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/network/{net}/acl/{description}'.format(net=net, description=description))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/network/{net}/acl/{description}'.format(net=net, description=description))
if response.status_code == 200:
retstatus = True

View File

@ -20,28 +20,8 @@
#
###############################################################################
import requests
import cli_lib.ansiprint as ansiprint
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: POST {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
from cli_lib.common import call_api
#
# Primary functions
@ -54,15 +34,10 @@ def node_coordinator_state(config, node, action):
API arguments: action={action}
API schema: {"message": "{data}"}
"""
request_uri = get_request_uri(config, '/node/{node}/coordinator-state'.format(node=node))
response = requests.post(
request_uri,
params={
'state': action
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/node/{node}/coordinator-state'.format(node=node), params=params)
if response.status_code == 200:
retstatus = True
@ -79,16 +54,11 @@ def node_domain_state(config, node, action, wait):
API arguments: action={action}, wait={wait}
API schema: {"message": "{data}"}
"""
request_uri = get_request_uri(config, '/node/{node}/domain-state'.format(node=node))
response = requests.post(
request_uri,
params={
'state': action,
'wait': wait
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/node/{node}/domain-state'.format(node=node), params=params)
if response.status_code == 200:
retstatus = True
@ -105,12 +75,7 @@ def node_info(config, node):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/node/{node}'.format(node=node))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/node/{node}'.format(node=node))
if response.status_code == 200:
return True, response.json()
@ -125,20 +90,11 @@ def node_list(config, limit):
API arguments: limit={limit}
API schema: [{json_data_object},{json_data_object},etc.]
"""
params = dict()
if limit:
params = {
'limit': limit
}
else:
params = {}
params['limit'] = limit
request_uri = get_request_uri(config, '/node')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/node', params=params)
if response.status_code == 200:
return True, response.json()

View File

@ -23,28 +23,9 @@
import time
import re
import subprocess
import requests
import cli_lib.ansiprint as ansiprint
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: POST {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
from cli_lib.common import call_api
#
# Primary functions
@ -57,12 +38,7 @@ def template_info(config, template, template_type):
API arguments:
API schema: {json_template_object}
"""
request_uri = get_request_uri(config, '/provisioner/template/{template_type}/{template}'.format(template_type=template_type, template=template))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/template/{template_type}/{template}'.format(template_type=template_type, template=template))
if response.status_code == 200:
return True, response.json()
@ -82,15 +58,9 @@ def template_list(config, limit, template_type=None):
params['limit'] = limit
if template_type is not None:
request_uri = get_request_uri(config, '/provisioner/template/{template_type}'.format(template_type=template_type))
response = call_api(config, 'get', '/provisioner/template/{template_type}'.format(template_type=template_type), params=params)
else:
request_uri = get_request_uri(config, '/provisioner/template')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/template', params=params)
if response.status_code == 200:
return True, response.json()
@ -105,13 +75,7 @@ def template_add(config, params, template_type=None):
API_arguments: args
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/template/{template_type}'.format(template_type=template_type))
response = requests.post(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/template/{template_type}'.format(template_type=template_type), params=params)
if response.status_code == 200:
retvalue = True
@ -128,12 +92,7 @@ def template_remove(config, name, template_type=None):
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/template/{template_type}/{name}'.format(template_type=template_type, name=name))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/provisioner/template/{template_type}/{name}'.format(template_type=template_type, name=name))
if response.status_code == 200:
retvalue = True
@ -150,13 +109,7 @@ def template_element_add(config, name, element_id, params, element_type=None, te
API_arguments: args
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id))
response = requests.post(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id), params=params)
if response.status_code == 200:
retvalue = True
@ -173,12 +126,7 @@ def template_element_remove(config, name, element_id, element_type=None, templat
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/provisioner/template/{template_type}/{name}/{element_type}/{element_id}'.format(template_type=template_type, name=name, element_type=element_type, element_id=element_id))
if response.status_code == 200:
retvalue = True
@ -195,12 +143,7 @@ def userdata_info(config, userdata):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/userdata/{userdata}'.format(userdata=userdata))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/userdata/{userdata}'.format(userdata=userdata))
if response.status_code == 200:
return True, response.json()[0]
@ -219,13 +162,7 @@ def userdata_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/provisioner/userdata')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/userdata', params=params)
if response.status_code == 200:
return True, response.json()
@ -243,18 +180,13 @@ def userdata_add(config, params):
name = params.get('name')
userdata_data = params.get('data')
request_uri = get_request_uri(config, '/provisioner/userdata')
response = requests.post(
request_uri,
params={
params = {
'name': name
},
data={
}
data = {
'data': userdata_data
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/userdata', params=params, data=data)
if response.status_code == 200:
retvalue = True
@ -273,18 +205,13 @@ def userdata_modify(config, name, params):
"""
userdata_data = params.get('data')
request_uri = get_request_uri(config, '/provisioner/userdata/{name}'.format(name=name))
response = requests.put(
request_uri,
params={
params = {
'name': name
},
data={
}
data = {
'data': userdata_data
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/provisioner/userdata/{name}'.format(name=name), params=params, data=data)
if response.status_code == 200:
retvalue = True
@ -301,12 +228,7 @@ def userdata_remove(config, name):
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/userdata/{name}'.format(name=name))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/provisioner/userdata/{name}'.format(name=name))
if response.status_code == 200:
retvalue = True
@ -323,12 +245,7 @@ def script_info(config, script):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/script/{script}'.format(script=script))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/script/{script}'.format(script=script))
if response.status_code == 200:
return True, response.json()[0]
@ -347,13 +264,7 @@ def script_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/provisioner/script')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/script', params=params)
if response.status_code == 200:
return True, response.json()
@ -371,18 +282,13 @@ def script_add(config, params):
name = params.get('name')
script_data = params.get('data')
request_uri = get_request_uri(config, '/provisioner/script')
response = requests.post(
request_uri,
params={
params = {
'name': name
},
data={
}
data = {
'data': script_data
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/script', params=params, data=data)
if response.status_code == 200:
retvalue = True
@ -401,18 +307,13 @@ def script_modify(config, name, params):
"""
script_data = params.get('data')
request_uri = get_request_uri(config, '/provisioner/script/{name}'.format(name=name))
response = requests.put(
request_uri,
params={
params = {
'name': name
},
data={
}
data = {
'data': script_data
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/provisioner/script/{name}'.format(name=name), params=params, data=data)
if response.status_code == 200:
retvalue = True
@ -429,12 +330,7 @@ def script_remove(config, name):
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/script/{name}'.format(name=name))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/provisioner/script/{name}'.format(name=name))
if response.status_code == 200:
retvalue = True
@ -451,12 +347,7 @@ def profile_info(config, profile):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{profile}'.format(profile=profile))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/profile/{profile}'.format(profile=profile))
if response.status_code == 200:
return True, response.json()[0]
@ -475,13 +366,7 @@ def profile_list(config, limit):
if limit:
params['limit'] = limit
request_uri = get_request_uri(config, '/provisioner/profile')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/profile', params=params)
if response.status_code == 200:
return True, response.json()
@ -496,13 +381,7 @@ def profile_add(config, params):
API_arguments: args
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/profile')
response = requests.post(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/profile', params=params)
if response.status_code == 200:
retvalue = True
@ -519,13 +398,7 @@ def profile_modify(config, name, params):
API_arguments: args
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{name}'.format(name=name))
response = requests.put(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'put', '/provisioner/profile/{name}'.format(name=name), params=params)
if response.status_code == 200:
retvalue = True
@ -542,12 +415,7 @@ def profile_remove(config, name):
API_arguments:
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/profile/{name}'.format(name=name))
response = requests.delete(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/provisioner/profile/{name}'.format(name=name))
if response.status_code == 200:
retvalue = True
@ -564,16 +432,11 @@ def vm_create(config, name, profile, wait_flag):
API_arguments: name={name}, profile={profile}
API schema: {message}
"""
request_uri = get_request_uri(config, '/provisioner/create')
response = requests.post(
request_uri,
params={
params = {
'name': name,
'profile': profile
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/provisioner/create', params=params)
if response.status_code == 202:
retvalue = True
@ -596,12 +459,7 @@ def task_status(config, task_id, is_watching=False):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/provisioner/status/{task_id}'.format(task_id=task_id))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/provisioner/status/{task_id}'.format(task_id=task_id))
if response.status_code == 200:
retvalue = True

View File

@ -23,31 +23,12 @@
import time
import re
import subprocess
import requests
from collections import deque
import cli_lib.ansiprint as ansiprint
import cli_lib.ceph as ceph
def debug_output(config, request_uri, response):
if config['debug']:
import click
click.echo('API endpoint: POST {}'.format(request_uri), err=True)
click.echo('Response code: {}'.format(response.status_code), err=True)
click.echo('Response headers: {}'.format(response.headers), err=True)
def get_request_uri(config, endpoint):
"""
Return the fully-formed URI for {endpoint}
"""
uri = '{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
endpoint
)
return uri
from cli_lib.common import call_api
#
# Primary functions
@ -60,12 +41,7 @@ def vm_info(config, vm):
API arguments:
API schema: {json_data_object}
"""
request_uri = get_request_uri(config, '/vm/{vm}'.format(vm=vm))
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/vm/{vm}'.format(vm=vm))
if response.status_code == 200:
return True, response.json()
@ -88,13 +64,7 @@ def vm_list(config, limit, target_node, target_state):
if target_state:
params['state'] = target_state
request_uri = get_request_uri(config, '/vm')
response = requests.get(
request_uri,
params=params
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/vm', params=params)
if response.status_code == 200:
return True, response.json()
@ -109,21 +79,16 @@ def vm_define(config, xml, node, node_limit, node_selector, node_autostart):
API arguments: xml={xml}, node={node}, limit={node_limit}, selector={node_selector}, autostart={node_autostart}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm')
response = requests.post(
request_uri,
params={
params = {
'node': node,
'limit': node_limit,
'selector': node_selector,
'autostart': node_autostart
},
data={
}
data = {
'xml': xml
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/vm', params=params, data=data)
if response.status_code == 200:
retstatus = True
@ -140,16 +105,13 @@ def vm_modify(config, vm, xml, restart):
API arguments: xml={xml}, restart={restart}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}'.format(vm=vm))
response = requests.put(
request_uri,
params={
'xml': xml,
params = {
'restart': restart
}
)
debug_output(config, request_uri, response)
data = {
'xml': xml
}
response = call_api(config, 'put', '/vm/{vm}'.format(vm=vm), params=params, data=data)
if response.status_code == 200:
retstatus = True
@ -166,14 +128,7 @@ def vm_metadata(config, vm, node_limit, node_selector, node_autostart):
API arguments: limit={node_limit}, selector={node_selector}, autostart={node_autostart}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/meta'.format(vm=vm))
# Get the existing metadata so we can perform a fully dynamic update
response = requests.get(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/vm/{vm}/meta'.format(vm=vm))
metadata = response.json()
@ -191,17 +146,12 @@ def vm_metadata(config, vm, node_limit, node_selector, node_autostart):
metadata['node_autostart'] = node_autostart
# Write the new metadata
print(metadata['node_limit'])
response = requests.post(
request_uri,
params={
'limit': metadata['node_limit'],
'selector': metadata['node_selector'],
'autostart': metadata['node_autostart']
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/vm/{vm}/meta'.format(vm=vm), params=params)
if response.status_code == 200:
retstatus = True
@ -218,15 +168,10 @@ def vm_remove(config, vm, delete_disks=False):
API arguments: delete_disks={delete_disks}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}'.format(vm=vm))
response = requests.delete(
request_uri,
params={
'delete_disks': delete_disks
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'delete', '/vm/{vm}'.format(vm=vm), params=params)
if response.status_code == 200:
retstatus = True
@ -243,15 +188,10 @@ def vm_state(config, vm, target_state):
API arguments: state={state}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/state'.format(vm=vm))
response = requests.post(
request_uri,
params={
'state': target_state,
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/vm/{vm}/state'.format(vm=vm), params=params)
if response.status_code == 200:
retstatus = True
@ -268,17 +208,12 @@ def vm_node(config, vm, target_node, action, force=False):
API arguments: node={target_node}, action={action}, force={force}
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/node'.format(vm=vm))
response = requests.post(
request_uri,
params={
'node': target_node,
'action': action,
'force': force
}
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/vm/{vm}/node'.format(vm=vm), params=params)
if response.status_code == 200:
retstatus = True
@ -295,12 +230,7 @@ def vm_locks(config, vm):
API arguments:
API schema: {"message":"{data}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/locks'.format(vm=vm))
response = requests.post(
request_uri
)
debug_output(config, request_uri, response)
response = call_api(config, 'post', '/vm/{vm}/locks'.format(vm=vm))
if response.status_code == 200:
retstatus = True
@ -317,13 +247,10 @@ def view_console_log(config, vm, lines=100):
API arguments: lines={lines}
API schema: {"name":"{vmname}","data":"{console_log}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/console'.format(vm=vm))
response = requests.get(
request_uri,
params={'lines': lines}
)
debug_output(config, request_uri, response)
params = {
'lines': lines
}
response = call_api(config, 'get', '/vm/{vm}/console'.format(vm=vm), params=params)
if response.status_code != 200:
return False, response.json()['message']
@ -344,15 +271,10 @@ def follow_console_log(config, vm, lines=10):
API arguments: lines={lines}
API schema: {"name":"{vmname}","data":"{console_log}"}
"""
request_uri = get_request_uri(config, '/vm/{vm}/console'.format(vm=vm))
response = requests.get(
request_uri,
params={'lines': lines}
)
debug_output(config, request_uri, response)
console_log = response.json()['data']
params = {
'lines': lines
}
response = call_api(config, 'get', '/vm/{vm}/console'.format(vm=vm), params=params)
# Shrink the log buffer to length lines
shrunk_log = console_log.split('\n')[-lines:]
@ -363,19 +285,7 @@ def follow_console_log(config, vm, lines=10):
while True:
# Grab the next line set
# Get the (initial) data from the API
response = requests.get(
'{}://{}{}{}'.format(
config['api_scheme'],
config['api_host'],
config['api_prefix'],
'/vm/{}/console'.format(vm)
),
params={'lines': lines}
)
debug_output(config, request_uri, response)
response = call_api(config, 'get', '/vm/{vm}/console'.format(vm=vm), params=params)
new_console_log = response.json()['data']
# Split the new and old log strings into constitutent lines
old_console_loglines = console_log.split('\n')
@ -480,10 +390,7 @@ def format_info(config, domain_information, long_output):
else:
net_vni = re.sub('br', '', net['source'])
request_uri = get_request_uri(config, '/network/{net}'.format(net=net_vni))
response = requests.get(
request_uri
)
response = call_api(config, 'get', '/network/{net}'.format(net=net_vni))
if response.status_code != 200 and net_vni != 'cluster':
net_list.append(ansiprint.red() + net_vni + ansiprint.end() + ' [invalid]')
else:
@ -632,10 +539,7 @@ def format_list(config, vm_list, raw):
vm_net_colour = ''
for net_vni in raw_net_list:
if not net_vni in valid_net_list:
request_uri = get_request_uri(config, '/network/{net}'.format(net=net_vni))
response = requests.get(
request_uri
)
response = call_api(config, 'get', '/network/{net}'.format(net=net_vni))
if response.status_code != 200 and net_vni != 'cluster':
vm_net_colour = ansiprint.red()
else: