hplefthandclient Package

hplefthandclient Package

HP LeftHand REST Client

Author:Kurt Martin
Author:Walter A. Boring IV
Copyright:Copyright 2013, Hewlett Packard Development Company, L.P.
License:Apache v2.0
hplefthandclient.__init__.get_version_string()[source]
hplefthandclient.__init__.version = '1.0.1'

Current version of HPLeftHandClient.

client Module

HPLeftHand REST Client

Author:Kurt Martin
Description:This is the LeftHand/StoreVirtual Client that talks to the

LeftHand OS REST Service.

This client requires and works with version 11.5 of the LeftHand firmware

class hplefthandclient.client.HPLeftHandClient(api_url)[source]

Bases: object

addServerAccess(volume_id, server_id, optional=None)[source]

Assign a Volume to a Server

Parameters:
  • volume_id – Volume ID of the volume
  • server_id – Server ID of the server to add the volume to
  • optional (dict) – Dictionary of optional params
optional = {
    'Transport' : 0,
    'Lun' : 1,
}
cloneSnapshot(name, source_snapshot_id, optional=None)[source]

Create a clone of an existing Shapshot

Parameters:
  • name (str) – Name of the Snapshot clone
  • source_snapshot_id (int) – The snapshot you want to clone
  • optional (dict) – Dictionary of optional params
optional = {
    'description' : "some comment"
}
cloneVolume(name, source_volume_id, optional=None)[source]

Create a clone of an existing Volume

Parameters:
  • name (str) – Name of the Volume clone
  • source_volume_id (int) – The Volume you want to clone
  • optional (dict) – Dictionary of optional params
optional = {
    'description' : "some comment"
}
createServer(name, iqn, optional=None)[source]

Create a server by name

Parameters:
  • name (str) – The name of the server to create
  • iqn – The iSCSI qualified name
  • optional (dict) – Dictionary of optional params
optional = {
    'description' : "some comment",
    'iscsiEnabled' : True,
    'chapName': "some chap name",
    'chapAuthenticationRequired': False,
    'chapInitiatorSecret': "initiator secret",
    'chapTargetSecret': "target secret",
    'iscsiLoadBalancingEnabled': True,
    'controllingServerName': "server name",
    'fibreChannelEnabled': False,
    'inServerCluster": True
}
Returns:server
Raises:HTTPNotFound -

NON_EXISTENT_SERVER - server doesn’t exist

createSnapshot(name, source_volume_id, optional=None)[source]

Create a snapshot of an existing Volume

Parameters:
  • name (str) – Name of the Snapshot
  • source_volume_id (int) – The volume you want to snapshot
  • optional (dict) – Dictionary of optional params
optional = {
    'description' : "some comment",
    'inheritAccess' : false
}
createVolume(name, cluster_id, size, optional=None)[source]

Create a new volume

Parameters:
  • name (str) – the name of the volume
  • cluster_id (int) – the cluster Id
  • sizeKB (int) – size in KB for the volume
  • optional (dict) – dict of other optional items
optional = {
 'description': 'some comment',
 'isThinProvisioned': 'true',
 'autogrowSeconds': 200,
 'clusterName': 'somename',
 'isAdaptiveOptimizationEnabled': 'true',
 'dataProtectionLevel': 2,
}
Returns:List of Volumes
Raises:HTTPConflict -

EXISTENT_SV - Volume Exists already

debug_rest(flag)[source]

This is useful for debugging requests to LeftHand

Parameters:flag (bool) – set to True to enable debugging
deleteServer(server_id)[source]

Delete a Server

Parameters:server_id – the server ID to delete
Raises:HTTPNotFound -

NON_EXISTENT_SERVER - The server does not exist

deleteSnapshot(snapshot_id)[source]

Delete a Snapshot

Parameters:snapshot_id – the snapshot ID to delete
Raises:HTTPNotFound -

NON_EXISTENT_SNAPSHOT - The snapshot does not exist

deleteVolume(volume_id)[source]

Delete a volume

Parameters:name (str) – the name of the volume
Raises:HTTPNotFound -

NON_EXISTENT_VOL - The volume does not exist

getCluster(cluster_id)[source]

Get information about a Cluster

Parameters:cluster_id (str) – The id of the cluster to find
Returns:cluster
getClusterByName(name)[source]

Get information about a cluster by name

Parameters:name (str) – The name of the cluster to find
Returns:cluster
Raises:HTTPNotFound -

NON_EXISTENT_CLUSTER - cluster doesn’t exist

getClusters()[source]

Get the list of Clusters

Returns:list of Clusters
getServer(server_id)[source]

Get information about a server

Parameters:server_id (str) – The id of the server to find
Returns:server
Raises:HTTPServerError
getServerByName(name)[source]

Get information about a server by name

Parameters:name (str) – The name of the server to find
Returns:server
Raises:HTTPNotFound -

NON_EXISTENT_SERVER - server doesn’t exist

getServers()[source]

Get the list of Servers

Returns:list of Servers
getSnapshot(snapshot_id)[source]

Get information about a Snapshot

Returns:snapshot
Raises:HTTPServerError
getSnapshotByName(name)[source]

Get information about a snapshot by name

Parameters:name – The name of the snapshot to find
Returns:volume
Raises:HTTPNotFound -

NON_EXISTENT_SNAP - shapshot doesn’t exist

getSnapshots()[source]

Get the list of Snapshots

Returns:list of Snapshots
getVolume(volume_id)[source]

Get information about a volume

Parameters:volume_id (str) – The id of the volume to find
Returns:volume
Raises:HTTPNotFound -

NON_EXISTENT_VOL - volume doesn’t exist

getVolumeByName(name)[source]

Get information about a volume by name

Parameters:name – The name of the volume to find
Returns:volume
Raises:HTTPNotFound -

NON_EXISTENT_VOL - volume doesn’t exist

getVolumes()[source]

Get the list of Volumes

Returns:list of Volumes
login(username, password)[source]

This authenticates against the LH OS REST server and creates a session.

Parameters:
  • username (str) – The username
  • password (str) – The password
Returns:

None

logout()[source]

This destroys the session and logs out from the LH OS server

Returns:None
modifyVolume(volume_id, optional)[source]

Modify an existing volume.

Parameters:volume_id (str) – The id of the volume to find
Returns:volume
Raises:HTTPNotFound -

NON_EXISTENT_VOL - volume doesn’t exist

removeServerAccess(volume_id, server_id)[source]

Unassign a Volume from a Server

Parameters:
  • volume_id – Volume ID of the volume
  • server_id – Server ID of the server to remove the volume fom

exceptions Module

Exceptions for the client

Author:Walter A. Boring IV
Description:This contains the HTTP exceptions that can come back from the REST calls
exception hplefthandclient.exceptions.AuthorizationFailure[source]

Bases: Exception

exception hplefthandclient.exceptions.ClientException(error=None)[source]

Bases: Exception

The base exception class for all exceptions this library raises.

Parameters:error (array) – The error array
get_code()[source]
get_description()[source]
exception hplefthandclient.exceptions.CommandError[source]

Bases: Exception

exception hplefthandclient.exceptions.HTTPBadGateway(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 502 - The server was acting as a gateway or proxy and received an invalid response from the upstream server.

http_status = 502
message = 'Bad Gateway'
exception hplefthandclient.exceptions.HTTPBadRequest(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 400 - Bad request: you sent some malformed data.

http_status = 400
message = 'Bad request'
exception hplefthandclient.exceptions.HTTPConflict(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 409 - Conflict: A Conflict happened on the server

http_status = 409
message = 'Conflict'
exception hplefthandclient.exceptions.HTTPExpectationFailed(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 417 - The server cannot meet the requirements of the Expect request-header field.

http_status = 417
message = 'Expectation Failed'
exception hplefthandclient.exceptions.HTTPForbidden(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 403 - Forbidden: your credentials don’t give you access to this resource.

http_status = 403
message = 'Forbidden'
exception hplefthandclient.exceptions.HTTPGatewayTimeout(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 504 - The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.

http_status = 504
message = 'Gateway Timeout'
exception hplefthandclient.exceptions.HTTPGone(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 410 - Indicates that the resource requested is no longer available and will not be available again.

http_status = 410
message = 'Gone'
exception hplefthandclient.exceptions.HTTPLengthRequired(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 411 - The request did not specify the length of its content, which is required by the requested resource.

http_status = 411
message = 'Length Required'
exception hplefthandclient.exceptions.HTTPMethodNotAllowed(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 405 - Method not Allowed

http_status = 405
message = 'Method Not Allowed'
exception hplefthandclient.exceptions.HTTPNotAcceptable(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 406 - Method not Acceptable

http_status = 406
message = 'Method Not Acceptable'
exception hplefthandclient.exceptions.HTTPNotFound(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 404 - Not found

http_status = 404
message = 'Not found'
exception hplefthandclient.exceptions.HTTPNotImplemented(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 501 - Not Implemented: the server does not support this operation.

http_status = 501
message = 'Not Implemented'
exception hplefthandclient.exceptions.HTTPPreconditionFailed(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 412 - The server does not meet one of the preconditions that the requester put on the request.

http_status = 412
message = 'Over limit'
exception hplefthandclient.exceptions.HTTPProxyAuthRequired(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 407 - The client must first authenticate itself with the proxy.

http_status = 407
message = 'Proxy Authentication Required'
exception hplefthandclient.exceptions.HTTPRequestEntityTooLarge(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 413 - The request is larger than the server is willing or able to process

http_status = 413
message = 'Request Entity Too Large'
exception hplefthandclient.exceptions.HTTPRequestTimeout(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 408 - The server timed out waiting for the request.

http_status = 408
message = 'Request Timeout'
exception hplefthandclient.exceptions.HTTPRequestURITooLong(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 414 - The URI provided was too long for the server to process.

http_status = 414
message = 'Request URI Too Large'
exception hplefthandclient.exceptions.HTTPRequestedRangeNotSatisfiable(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 416 - The client has asked for a portion of the file, but the server cannot supply that portion.

http_status = 416
message = 'Requested Range Not Satisfiable'
exception hplefthandclient.exceptions.HTTPServerError(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 500 -

http_status = 500
message = 'Error'
exception hplefthandclient.exceptions.HTTPServiceUnavailable(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 503 - The server is currently unavailable

http_status = 503
message = 'Service Unavailable'
exception hplefthandclient.exceptions.HTTPTeaPot(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 418 - I’m a Tea Pot

http_status = 418
message = "I'm A Teapot. (RFC 2324)"
exception hplefthandclient.exceptions.HTTPUnauthorized(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 401 - Unauthorized: bad credentials.

http_status = 401
message = 'Unauthorized'
exception hplefthandclient.exceptions.HTTPUnsupportedMediaType(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 415 - The request entity has a media type which the server or resource does not support.

http_status = 415
message = 'Unsupported Media Type'
exception hplefthandclient.exceptions.HTTPVersionNotSupported(error=None)[source]

Bases: hplefthandclient.exceptions.ClientException

HTTP 505 - The server does not support the HTTP protocol version used in the request.

http_status = 505
message = 'Version Not Supported'
exception hplefthandclient.exceptions.NoUniqueMatch[source]

Bases: Exception

exception hplefthandclient.exceptions.UnsupportedVersion[source]

Bases: Exception

Indicates that the user is trying to use an unsupported version of the API

hplefthandclient.exceptions.from_response(response, body)[source]

Return an instance of an ClientException or subclass based on an httplib2 response.

Usage:

resp, body = http.request(...)
if resp.status != 200:
    raise exception_from_response(resp, body)

http Module

HPLeftHand HTTP Client :Author: Walter A. Boring IV :Description: This is the HTTP Client that is used to make the actual calls.

It includes the authentication that knows the cookie name for LH.
class hplefthandclient.http.HTTPJSONRESTClient(api_url, insecure=False, http_log_debug=False)[source]

Bases: httplib2.Http

An HTTP REST Client that sends and recieves JSON data as the body of the HTTP request.

Parameters:
  • api_url (str) – The url to the LH OS REST service ie. https://<hostname or IP>:<port>/lhos
  • insecure (bool) – Use https? requires a local certificate
USER_AGENT = 'python-hplefthandclient'
authenticate(user, password, optional=None)[source]

This tries to create an authenticated session with the LH OS server

Parameters:
  • user (str) – The username
  • password (str) – The password
delete(url, **kwargs)[source]

Make an HTTP DELETE request to the server.

#example call
try {
    headers, body = http.delete('/volumes/%s' % name)
} except exceptions.HTTPUnauthorized as ex:
    print "Not logged in"
}
Parameters:url (str) – The relative url from the LH api_url
Returns:headers - dict of HTTP Response headers
Returns:body - the body of the response. If the body was JSON,

it will be an object

get(url, **kwargs)[source]

Make an HTTP GET request to the server.

#example call
try {
    headers, body = http.get('/volumes')
} except exceptions.HTTPUnauthorized as ex:
    print "Not logged in"
}
Parameters:url (str) – The relative url from the LH api_url
Returns:headers - dict of HTTP Response headers
Returns:body - the body of the response. If the body was JSON,

it will be an object

get_timings()[source]

Ths gives an array of the request timings since last reset_timings call

post(url, **kwargs)[source]

Make an HTTP POST request to the server.

#example call
try {
    info = {'name': 'new volume name', 'sizeMiB': 300}
    headers, body = http.post('/volumes', body=info)
} except exceptions.HTTPUnauthorized as ex:
    print "Not logged in"
}
Parameters:url (str) – The relative url from the LH api_url
Returns:headers - dict of HTTP Response headers
Returns:body - the body of the response. If the body was JSON,

it will be an object

put(url, **kwargs)[source]

Make an HTTP PUT request to the server.

#example call
try {
    info = {'name': 'something'}
    headers, body = http.put('/volumes', body=info)
} except exceptions.HTTPUnauthorized as ex:
    print "Not logged in"
}
Parameters:url (str) – The relative url from the LH api_url
Returns:headers - dict of HTTP Response headers
Returns:body - the body of the response. If the body was JSON,

it will be an object

request(*args, **kwargs)[source]

This makes an HTTP Request to the LH server. You should use get, post, delete instead.

reset_timings()[source]

This resets the request/response timings array

set_debug_flag(flag)[source]

This turns on/off http request/response debugging output to console

Parameters:flag (bool) – Set to True to enable debugging output
set_url(api_url)[source]
unauthenticate()[source]

This clears the authenticated session with the LH server. It logs out.