libnative-utilities/include/raknet/Rackspace.hpp
2024-08-15 18:40:30 +08:00

414 lines
24 KiB
C++

/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
/// \file Rackspace.h
/// \brief Helper to class to manage Rackspace servers
///
#include "NativeFeatureIncludes.hpp"
#if _RAKNET_SUPPORT_Rackspace==1 && _RAKNET_SUPPORT_TCPInterface==1
#include "Export.hpp"
#include "DS_List.hpp"
#include "RakNetTypes.hpp"
#include "DS_Queue.hpp"
#include "RakString.hpp"
#ifndef __RACKSPACE_H
#define __RACKSPACE_H
namespace RakNet
{
class TCPInterface;
struct Packet;
/// \brief Result codes for Rackspace commands
/// /sa Rackspace::EventTypeToString()
enum RackspaceEventType
{
RET_Success_200,
RET_Success_201,
RET_Success_202,
RET_Success_203,
RET_Success_204,
RET_Cloud_Servers_Fault_500,
RET_Service_Unavailable_503,
RET_Unauthorized_401,
RET_Bad_Request_400,
RET_Over_Limit_413,
RET_Bad_Media_Type_415,
RET_Item_Not_Found_404,
RET_Build_In_Progress_409,
RET_Resize_Not_Allowed_403,
RET_Connection_Closed_Without_Reponse,
RET_Unknown_Failure,
};
/// \internal
enum RackspaceOperationType
{
RO_CONNECT_AND_AUTHENTICATE,
RO_LIST_SERVERS,
RO_LIST_SERVERS_WITH_DETAILS,
RO_CREATE_SERVER,
RO_GET_SERVER_DETAILS,
RO_UPDATE_SERVER_NAME_OR_PASSWORD,
RO_DELETE_SERVER,
RO_LIST_SERVER_ADDRESSES,
RO_SHARE_SERVER_ADDRESS,
RO_DELETE_SERVER_ADDRESS,
RO_REBOOT_SERVER,
RO_REBUILD_SERVER,
RO_RESIZE_SERVER,
RO_CONFIRM_RESIZED_SERVER,
RO_REVERT_RESIZED_SERVER,
RO_LIST_FLAVORS,
RO_GET_FLAVOR_DETAILS,
RO_LIST_IMAGES,
RO_CREATE_IMAGE,
RO_GET_IMAGE_DETAILS,
RO_DELETE_IMAGE,
RO_LIST_SHARED_IP_GROUPS,
RO_LIST_SHARED_IP_GROUPS_WITH_DETAILS,
RO_CREATE_SHARED_IP_GROUP,
RO_GET_SHARED_IP_GROUP_DETAILS,
RO_DELETE_SHARED_IP_GROUP,
RO_NONE,
};
/// \brief Callback interface to receive the results of operations
class RAK_DLL_EXPORT Rackspace2EventCallback
{
public:
Rackspace2EventCallback() {}
virtual ~Rackspace2EventCallback() {}
virtual void OnAuthenticationResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListServersResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListServersWithDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnCreateServerResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnGetServerDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnUpdateServerNameOrPassword(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnDeleteServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListServerAddresses(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnShareServerAddress(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnDeleteServerAddress(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnRebootServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnRebuildServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnResizeServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnConfirmResizedServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnRevertResizedServer(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListFlavorsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnGetFlavorDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListImagesResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnCreateImageResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnGetImageDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnDeleteImageResult(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListSharedIPGroups(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnListSharedIPGroupsWithDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnCreateSharedIPGroup(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnGetSharedIPGroupDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnDeleteSharedIPGroup(RackspaceEventType eventType, const char *htmlAdditionalInfo)=0;
virtual void OnConnectionAttemptFailure(RackspaceOperationType operationType, const char *url)=0;
};
/// \brief Callback interface to receive the results of operations, with a default result
class RAK_DLL_EXPORT RackspaceEventCallback_Default : public Rackspace2EventCallback
{
public:
virtual void ExecuteDefault(const char *callbackName, RackspaceEventType eventType, const char *htmlAdditionalInfo) {(void) callbackName; (void) eventType; (void) htmlAdditionalInfo;}
virtual void OnAuthenticationResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnAuthenticationResult", eventType, htmlAdditionalInfo);}
virtual void OnListServersResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListServersResult", eventType, htmlAdditionalInfo);}
virtual void OnListServersWithDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListServersWithDetailsResult", eventType, htmlAdditionalInfo);}
virtual void OnCreateServerResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnCreateServerResult", eventType, htmlAdditionalInfo);}
virtual void OnGetServerDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnGetServerDetails", eventType, htmlAdditionalInfo);}
virtual void OnUpdateServerNameOrPassword(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnUpdateServerNameOrPassword", eventType, htmlAdditionalInfo);}
virtual void OnDeleteServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnDeleteServer", eventType, htmlAdditionalInfo);}
virtual void OnListServerAddresses(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListServerAddresses", eventType, htmlAdditionalInfo);}
virtual void OnShareServerAddress(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnShareServerAddress", eventType, htmlAdditionalInfo);}
virtual void OnDeleteServerAddress(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnDeleteServerAddress", eventType, htmlAdditionalInfo);}
virtual void OnRebootServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnRebootServer", eventType, htmlAdditionalInfo);}
virtual void OnRebuildServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnRebuildServer", eventType, htmlAdditionalInfo);}
virtual void OnResizeServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnResizeServer", eventType, htmlAdditionalInfo);}
virtual void OnConfirmResizedServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnConfirmResizedServer", eventType, htmlAdditionalInfo);}
virtual void OnRevertResizedServer(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnRevertResizedServer", eventType, htmlAdditionalInfo);}
virtual void OnListFlavorsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListFlavorsResult", eventType, htmlAdditionalInfo);}
virtual void OnGetFlavorDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnGetFlavorDetailsResult", eventType, htmlAdditionalInfo);}
virtual void OnListImagesResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListImagesResult", eventType, htmlAdditionalInfo);}
virtual void OnCreateImageResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnCreateImageResult", eventType, htmlAdditionalInfo);}
virtual void OnGetImageDetailsResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnGetImageDetailsResult", eventType, htmlAdditionalInfo);}
virtual void OnDeleteImageResult(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnDeleteImageResult", eventType, htmlAdditionalInfo);}
virtual void OnListSharedIPGroups(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListSharedIPGroups", eventType, htmlAdditionalInfo);}
virtual void OnListSharedIPGroupsWithDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnListSharedIPGroupsWithDetails", eventType, htmlAdditionalInfo);}
virtual void OnCreateSharedIPGroup(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnCreateSharedIPGroup", eventType, htmlAdditionalInfo);}
virtual void OnGetSharedIPGroupDetails(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnGetSharedIPGroupDetails", eventType, htmlAdditionalInfo);}
virtual void OnDeleteSharedIPGroup(RackspaceEventType eventType, const char *htmlAdditionalInfo) {ExecuteDefault("OnDeleteSharedIPGroup", eventType, htmlAdditionalInfo);}
virtual void OnConnectionAttemptFailure(RackspaceOperationType operationType, const char *url) {(void) operationType; (void) url;}
};
/// \brief Code that uses the TCPInterface class to communicate with the Rackspace API servers
/// \pre Compile RakNet with OPEN_SSL_CLIENT_SUPPORT set to 1
/// \pre Packets returned from TCPInterface::OnReceive() must be passed to Rackspace::OnReceive()
/// \pre Packets returned from TCPInterface::HasLostConnection() must be passed to Rackspace::OnClosedConnection()
class RAK_DLL_EXPORT Rackspace
{
public:
Rackspace();
~Rackspace();
/// \brief Authenticate with Rackspace servers, required before executing any commands.
/// \details All requests to authenticate and operate against Cloud Servers are performed using SSL over HTTP (HTTPS) on TCP port 443.
/// Times out after 24 hours - if you get RET_Authenticate_Unauthorized in the RackspaceEventCallback callback, call again
/// \sa RackspaceEventCallback::OnAuthenticationResult()
/// \param[in] _tcpInterface An instance of TCPInterface, build with OPEN_SSL_CLIENT_SUPPORT 1 and already started
/// \param[in] _authenticationURL See http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf . US-based accounts authenticate through auth.api.rackspacecloud.com. UK-based accounts authenticate through lon.auth.api.rackspacecloud.com
/// \param[in] _rackspaceCloudUsername Username you registered with Rackspace on their website
/// \param[in] _apiAccessKey Obtain your API access key from the Rackspace Cloud Control Panel in the Your Account API Access section.
/// \return The address of the authentication server, or UNASSIGNED_SYSTEM_ADDRESS if the connection attempt failed
SystemAddress Authenticate(TCPInterface *_tcpInterface, const char *_authenticationURL, const char *_rackspaceCloudUsername, const char *_apiAccessKey);
/// \brief Get a list of running servers
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListServersResult()
void ListServers(void);
/// \brief Get a list of running servers, with extended details on each server
/// \sa GetServerDetails()
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListServersWithDetailsResult()
void ListServersWithDetails(void);
/// \brief Create a server
/// \details Create a server with a given image (harddrive contents) and flavor (hardware configuration)
/// Get the available images with ListImages()
/// Get the available flavors with ListFlavors()
/// It is possible to configure the server in more detail. See the XML schema at http://docs.rackspacecloud.com/servers/api/v1.0
/// You can execute such a custom command by calling AddOperation() manually. See the implementation of CreateServer for how to do so.
/// The server takes a while to build. Call GetServerDetails() to get the current build status. Server id to pass to GetServerDetails() is returned in the field <server ... id="1234">
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnCreateServerResult()
/// \param[in] name Name of the server. Only alphanumeric characters, periods, and hyphens are valid. Server Name cannot start or end with a period or hyphen.
/// \param[in] imageId Which image (harddrive contents, including OS) to use
/// \param[in] flavorId Which flavor (hardware config) to use, primarily how much memory is available.
void CreateServer(RakNet::RakString name, RakNet::RakString imageId, RakNet::RakString flavorId);
/// \brief Get details on a particular server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnGetServerDetailsResult()
/// \param[in] serverId Which server to get details on. You can call ListServers() to get the list of active servers.
void GetServerDetails(RakNet::RakString serverId);
/// \brief Changes the name or password for a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnUpdateServerNameOrPasswordResult()
/// \param[in] serverId Which server to get details on. You can call ListServers() to get the list of active servers.
/// \param[in] newName The new server name. Leave blank to leave unchanged. Only alphanumeric characters, periods, and hyphens are valid. Server Name cannot start or end with a period or hyphen.
/// \param[in] newPassword The new server password. Leave blank to leave unchanged.
void UpdateServerNameOrPassword(RakNet::RakString serverId, RakNet::RakString newName, RakNet::RakString newPassword);
/// \brief Deletes a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnDeleteServerResult()
/// \param[in] serverId Which server to get details on. You can call ListServers() to get the list of active servers.
void DeleteServer(RakNet::RakString serverId);
/// \brief Lists the IP addresses available to a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListServerAddressesResult()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
void ListServerAddresses(RakNet::RakString serverId);
/// \brief Shares an IP address with a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnShareServerAddressResult()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] ipAddress Which IP address. You can call ListServerAddresses() to get the list of addresses for the specified server
void ShareServerAddress(RakNet::RakString serverId, RakNet::RakString ipAddress);
/// \brief Stops sharing an IP address with a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnDeleteServerAddressResult()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] ipAddress Which IP address. You can call ListServerAddresses() to get the list of addresses for the specified server
void DeleteServerAddress(RakNet::RakString serverId, RakNet::RakString ipAddress);
/// \brief Reboots a server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnRebootServerResult()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] rebootType Should be either "HARD" or "SOFT"
void RebootServer(RakNet::RakString serverId, RakNet::RakString rebootType);
/// \brief Rebuilds a server with a different image (harddrive contents)
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnRebuildServerResult()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] imageId Which image (harddrive contents, including OS) to use
void RebuildServer(RakNet::RakString serverId, RakNet::RakString imageId);
/// \brief Changes the hardware configuration of a server. This does not take effect until you call ConfirmResizedServer()
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnResizeServerResult()
/// \sa RevertResizedServer()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] flavorId Which flavor (hardware config) to use, primarily how much memory is available.
void ResizeServer(RakNet::RakString serverId, RakNet::RakString flavorId);
/// \brief Confirm a resize for the specified server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnConfirmResizedServerResult()
/// \sa ResizeServer()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
void ConfirmResizedServer(RakNet::RakString serverId);
/// \brief Reverts a resize for the specified server
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnRevertResizedServerResult()
/// \sa ResizeServer()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
void RevertResizedServer(RakNet::RakString serverId);
/// \brief List all flavors (hardware configs, primarily memory)
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListFlavorsResult()
void ListFlavors(void);
/// \brief Get extended details about a specific flavor
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnGetFlavorDetailsResult()
/// \sa ListFlavors()
/// \param[in] flavorId Which flavor (hardware config)
void GetFlavorDetails(RakNet::RakString flavorId);
/// \brief List all images (software configs, including operating systems), which includes images you create yourself
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListImagesResult()
/// \sa CreateImage()
void ListImages(void);
/// \brief Images a running server. This essentially copies the harddrive, and lets you start a server with the same harddrive contents later
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnCreateImageResult()
/// \sa ListImages()
/// \param[in] serverId Which server to operate on. You can call ListServers() to get the list of active servers.
/// \param[in] imageName What to call this image
void CreateImage(RakNet::RakString serverId, RakNet::RakString imageName);
/// \brief Get extended details about a particular image
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnGetImageDetailsResult()
/// \sa ListImages()
/// \param[in] imageId Which image
void GetImageDetails(RakNet::RakString imageId);
/// \brief Delete a custom image created with CreateImage()
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnDeleteImageResult()
/// \sa ListImages()
/// \param[in] imageId Which image
void DeleteImage(RakNet::RakString imageId);
/// \brief List IP groups
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListSharedIPGroupsResult()
void ListSharedIPGroups(void);
/// \brief List IP groups with extended details
/// \sa http://docs.rackspacecloud.com/servers/api/v1.0/cs-devguide-20110112.pdf
/// \sa RackspaceEventCallback::OnListSharedIPGroupsWithDetailsResult()
void ListSharedIPGroupsWithDetails(void);
// I don't know what this does
void CreateSharedIPGroup(RakNet::RakString name, RakNet::RakString optionalServerId);
// I don't know what this does
void GetSharedIPGroupDetails(RakNet::RakString groupId);
// I don't know what this does
void DeleteSharedIPGroup(RakNet::RakString groupId);
/// \brief Adds a callback to the list of callbacks to be called when any of the above functions finish executing
/// The callbacks are called in the order they are added
void AddEventCallback(Rackspace2EventCallback *callback);
/// \brief Removes a callback from the list of callbacks to be called when any of the above functions finish executing
/// The callbacks are called in the order they are added
void RemoveEventCallback(Rackspace2EventCallback *callback);
/// \brief Removes all callbacks
void ClearEventCallbacks(void);
/// Call this anytime TCPInterface returns a packet
void OnReceive(Packet *packet);
/// Call this when TCPInterface returns something other than UNASSIGNED_SYSTEM_ADDRESS from HasLostConnection()
void OnClosedConnection(SystemAddress systemAddress);
/// String representation of each RackspaceEventType
static const char * EventTypeToString(RackspaceEventType eventType);
/// \brief Mostly for internal use, but you can use it to execute an operation with more complex xml if desired
/// See the Rackspace.cpp on how to use it
void AddOperation(RackspaceOperationType type, RakNet::RakString httpCommand, RakNet::RakString operation, RakNet::RakString xml);
protected:
DataStructures::List<Rackspace2EventCallback*> eventCallbacks;
struct RackspaceOperation
{
RackspaceOperationType type;
// RakNet::RakString stringInfo;
SystemAddress connectionAddress;
bool isPendingAuthentication;
RakNet::RakString incomingStream;
RakNet::RakString httpCommand;
RakNet::RakString operation;
RakNet::RakString xml;
};
TCPInterface *tcpInterface;
// RackspaceOperationType currentOperation;
// DataStructures::Queue<RackspaceOperation> nextOperationQueue;
DataStructures::List<RackspaceOperation> operations;
bool HasOperationOfType(RackspaceOperationType t);
unsigned int GetOperationOfTypeIndex(RackspaceOperationType t);
RakNet::RakString serverManagementURL;
RakNet::RakString serverManagementDomain;
RakNet::RakString serverManagementPath;
RakNet::RakString storageURL;
RakNet::RakString storageDomain;
RakNet::RakString storagePath;
RakNet::RakString cdnManagementURL;
RakNet::RakString cdnManagementDomain;
RakNet::RakString cdnManagementPath;
RakNet::RakString storageToken;
RakNet::RakString authToken;
RakNet::RakString rackspaceCloudUsername;
RakNet::RakString apiAccessKey;
bool ExecuteOperation(RackspaceOperation &ro);
void ReadLine(const char *data, const char *stringStart, RakNet::RakString &output);
bool ConnectToServerManagementDomain(RackspaceOperation &ro);
};
} // namespace RakNet
#endif // __RACKSPACE_API_H
#endif // _RAKNET_SUPPORT_Rackspace