API Architecture

Introduction

This article contains information about using the API related to CrashPlan PRO Release 3.08.2010 and later. If you are using CrashPlan PRO Version 11.5.2009 or older, refer to this API Documentation - Previous

The CrashPlan Web Services Interface lets you manipulate a set of resources using a collection of web services built on REST design principles.

One of the great things about this type of API is that you can use your browser to download or view the data before you write a script to do it. For example, try this right now with your browser (You will have to enter an admin username and password):

http://<your.proserver.ip.address>:4280/rest/users?status=Active     (downloads all active users)

Sample python scripts are below. If you write a script accessing our API to do something unique, feel free to post an example to our PRO forum to help others to write scripts.

Overview

You can manipulate resources using a set of actions. These actions include most of the standard create, read, update and delete operations as well as a list operation, which supports retrieving all instances of a particular resource. You can constrain this list so that only resources matching specific criteria are returned. For example, a list of all orgs may be constrained to show only those orgs with the name 'Test'.

The framework supports this full set of actions:

  • Create a new resource
  • Retrieve information about a resource
  • Update an existing resource
  • List all instances of a resource

Note that not all actions are supported for all resources; details can be found below.

Mapping Requests onto Actions

An incoming HTTP request corresponds to the application of exactly one action on exactly one resource. The only exception is the list action which operates on an entire class of resources, but even in this case a single request corresponds to a single action. HTTP requests are mapped onto actions using a combination of the HTTP method and the URI:

HTTP method URI Action Request body Response body
GEThttp://localhost:4280/rest/orgs/234Retrieve org with ID of 234NoneDetailed information about org with ID of 234
GEThttp://localhost:4280/rest/orgsList all orgsNoneList of all orgs
POSThttp://localhost:4280/rest/orgsCreate a new orgValues to use when creating the new orgDetailed information about new org; identical to a retrieve operation
PUThttp://localhost:4280/rest/orgs/234Update org 234Values to use when updating org 234Detailed information about updated org; identical to a retrieve operation

As mentioned above, a list operation is constrained to return only resources that match one or more criteria. You can include these constraints as query parameters of the GET request, if desired. For example, changing the sample URL above to http://localhost:4280/rest/org?name=Test returns only orgs with the name “Test”. Also see the section on paging query parameters.

Note that not all methods are available for all resources. If a particular resource receives a request using an HTTP method that it does not support, an HTTP type 405 error is returned. The response also includes an “Allow” header that indicates which methods are acceptable for the specified resource.

Data Formats

CrashPlan Web services support sending and receiving data in both XML and JSON formats. There are two headers associated with data format: Accept and Content-Type. The Accept header controls the response format. The Content-Type header tells the server what type of content the client is sending and is required when content is provided.

Content-Type

This header identifies the type of the content contained in an incoming HTTP request. Use of this header is required for requests that contain content, such as a PUT or POST request. The server returns an HTTP type 415 error if a request includes content but excludes the Content-Type header or if the value of the header is not a supported type.

Accept (optional)

The client specifies a response type with the Accept header. If client does not provide the Accept header, the server assumes a response type of JSON. The server returns an HTTP type 406 error if it cannot create a response of the type identified in the header.

Supported Types

Identify types by including a MIME type in one or both of the headers discussed above. The following types (and their corresponding MIME types) are available:

Type Supported MIME type(s) Note
XML text/xml,application/xmlVerbose. Most scripting languages support XML.
JSON application/json Low bandwidth.
PLAINTEXTtext/plain Only supported for a few resources.

Date Values

Date information is always returned as a string value containing the ISO 8601 representation of the underlying date.

Common Properties

All resources contain at least three properties:

  • id = an identifier value unique to a specific instance of a resource
  • creationDate = timestamp recording when a resource was created
  • modificationDate = timestamp recording when a resource was last modified

Result Paging

Resources that can return many items support “paging” request parameters that return just a portion of the complete result set. This is most useful when accessing a large database and memory constraints on the client side. By default, however, paging is disabled without the parameters listed below.

You have a choice of paging parameters. For example, these two requests will return the exact same objects.

http://.../rest/users?page=2&pageSize=100
http://.../rest/users?offset=100&limit=100

The accepted parameters are:

offset/limit - defaults are both zero (first object/unlimited objects)
page/pageSize - default page is 1, default pageSize is zero (unlimited)

Resources

Org

An org represents a collection of users. Every user must belong to an org and cannot belong to more than one org at the same time. Orgs may also contains suborgs.

Properties

Properties in list view
nameCurrent name of the org
status“Active” if the org is currently active, “Deactivated” if the org has been deactivated
parentIdThe id value of the parent org or null if this org has no parent
registrationKeyThe registration key for this org
masterGuidIf not null then this org is a slave org and the value of this field contains the GUID for the corresponding master


Additional properties in detail view
Properties below are aggregated for all computers within this org. These values are retrieved from the last successful run of the ArchiveRecord report (which is scheduled to run each night).
selectedFilesCount of all files selected for backup
selectedBytesByte count for all files selected for backup
todoFilesCount of all files waiting to be backed up
todoBytesByte count for all files waiting to be backed up
archiveBytesNumber of bytes stored in all archives within the org
archiveBytesDeltaChange in the number of bytes stored in all archives within the org
archiveBytesDeltaMonthChange in the number of bytes stored in all archives within the org over 30 days
dailyChange?
quota.bytesConfigured size quota for this org (in gigabytes)
quota.seatsConfigured seat quota for this org

Properties required for creation: name, parentId

Query parameters available for constraining list action: name, status, parentId, and paging query parameters. (Anything not specified here should be considered “undocumented” which means it may change at any time)

Examples

Retrieve

To retrieve detailed information about the org with an ID of 43:

HTTP Request

1: GET http://localhost:4280/rest/orgs/43 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Thu, 30 Oct 2008 21:41:00 GMT
 4: Content-length: 548
 5:
 6: {
 7:   "id": 43,
 8:   "name": "SubOrg1",
 9:   "status": "Active",
10:   "creationDate": "2008-10-28T10:58:47.632-05:00",
11:   "modificationDate": "2008-10-30T16:37:02.083-05:00",
12:   "parentId": 2,
13:   "registrationKey": "8hj492h4w9pw8498",
14:   "masterGuid": null,
15:   "selectedFiles": 5183,
16:   "selectedBytes": 88879043,
17:   "todoFiles": 0,
18:   "todoBytes": 0,
19:   "archiveBytes": 78213557,
20:   "archiveBytesDelta": 78213557,
21:   "archiveBytesDeltaMonth": 78213557,
22:   "dailyChange": 0,
23:   "quota":   {
24:     "seats": 10,
25:     "bytes": 250
26:   }
27: }

List

To retrieve a list of all orgs on this server:

HTTP Request

1: GET http://localhost:4280/rest/orgs HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Tue, 28 Oct 2008 19:49:00 GMT
 4: Content-length: 1901
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 8,
 9:     "params": {},
10:     "timestamp": "2008-10-28T14:49:00.676-05:00"
11:   },
12:   "orgs":   [
13:         {
14:       "id": 2,
15:       "name": "PROServer Demo",
16:       "status": "Active",
17:       "parentId": null,
18:       "registrationKey": "H9RH-JWCT-SJCM-WS8T",
19:       "masterGuid": null,
20:       "creationDate": "2008-10-28T10:51:47.000-05:00",
21:       "modificationDate": "2008-10-28T10:51:47.000-05:00"
22:     },
23:         {
24:       "id": 3,
25:       "name": "PROServer Customer",
26:       "status": "Active",
27:       "parentId": null,
28:       "registrationKey": "8HJ4-92H4-W9PW-8498",
29:       "masterGuid": null,
30:       "creationDate": "2008-10-28T10:51:47.000-05:00",
31:       "modificationDate": "2008-10-28T10:51:47.000-05:00"
32:     },
33:         {
34:       "id": 42,
35:       "name": "CrashPlan",
36:       "status": "Active",
37:       "parentId": null,
38:       "registrationKey": "2RU9-49RR-9K7T-R9TT",
39:       "masterGuid": null,
40:       "creationDate": "2008-10-28T10:51:47.000-05:00",
41:       "modificationDate": "2008-10-28T10:51:47.000-05:00"
42:     },
43:         {
44:       "id": 43,
45:       "name": "SubOrg1",
46:       "status": "Active",
47:       "parentId": 2,
48:       "registrationKey": "M9WP-2MH7-H8PJ-7SW4",
49:       "masterGuid": null,
50:       "creationDate": "2008-10-28T10:58:47.632-05:00",
51:       "modificationDate": "2008-10-28T10:58:47.654-05:00"
52:     }
53: ...
54:   ]
55: }

Create

To create a new org:

HTTP Request

1: POST http://localhost:4280/rest/orgs HTTP/1.1
2: Content-length: 34
3: Content-Type: application/json
4: Accept: application/json
5: Authorization: Basic YWRtaW46YWRtaW4=
6:
7: {"name": "SubOrg5", "parentId": 2}

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 18:42:05 GMT
 4: Content-length: 181
 5:
 6: {
 7:   "id": 139,
 8:   "name": "SubOrg5",
 9:   "status": "Active",
10:   "creationDate": "2008-10-29T13:42:05.247-05:00",
11:   "modificationDate": "2008-10-29T13:42:05.314-05:00",
12:   "parentId": 2
13: }

Update

To deactivate the org with an ID of 43:

HTTP Request

1: PUT http://localhost:4280/rest/orgs/43 HTTP/1.1
2: Content-length: 25
3: Content-Type: application/json
4: Accept: application/json
5: Authorization: Basic YWRtaW46YWRtaW4=
6:
7: {"status": "Deactivated"}

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Tue, 28 Oct 2008 19:58:36 GMT
 4: Content-length: 294
 5:
 6: {
 7:   "id": 43,
 8:   "name": "SubOrg1 deactivated 2008-10-28 14:58",
 9:   "status": "Deactivated",
10:   "creationDate": "2008-10-28T10:58:47.632-05:00",
11:   "modificationDate": "2008-10-28T14:58:36.516-05:00",
12:   "parentId": 2,
13:   "selectedFiles": 0,
14:   "selectedBytes": 0,
15:   "todoFiles": 0,
16:   "todoBytes": 0
17:   "archiveBytes": 78213557,
18:   "archiveBytesDelta": 78213557,
19:   "archiveBytesDeltaMonth": 78213557,
20:   "dailyChange": 0,
21: }

User

A user represents a distinct entity which uses the CrashPlan PRO Server for backups. Every user is a member of exactly one org. Users may also contain one or more computers.

Properties

Properties in list and detail view
idUnique numeric ID of the user
status“Active” if the user is currently active, “Deactivated” if the user has been deactivated
emailEmail address of the user
firstNameFirst name of the user
lastNameLast name of the user
orgIdThe id of the org to which this user belongs
creationDateThe creation date and time of the user account
modificationDateThe modification date and time the user account


Additional properties in detail view
Properties below are aggregated for all computers associated with this user. These values are retrieved from the last successful run of the ArchiveRecord report (which is scheduled to run each night).
selectedFilesCount of all files selected for backup
selectedBytesByte count for all files selected for backup
todoFilesCount of all files waiting to be backed up
todoBytesByte count for all files waiting to be backed up
archiveBytesNumber of bytes stored in the user's archive(s)
archiveBytesDeltaChange in the number of bytes stored in the user's archive(s)
archiveBytesDeltaMonthChange in the number of bytes stored in the user's archive(s) over a month
dailyChange?
quota.bytesConfigured size quota for this org (in gigabytes)

Properties required for creation: orgId, firstName, lastName, username, password

Query parameters available for constraining list action: id, status, email, firstName, lastName, orgId, and paging query parameters

Examples

Retrieve

To retrieve detailed information about the user with an ID of 69:

HTTP Request

1: GET http://localhost:4280/rest/users/69 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Thu, 30 Oct 2008 21:38:25 GMT
 4: Content-length: 593
 5:
 6: {
 7:   "id": 69,
 8:   "status": "Active",
 9:   "email": "userthree@testorg.org",
10:   "firstName": "User",
11:   "lastName": "Three",
12:   "orgId": 43,
13:   "creationDate": "2008-10-29T14:08:06.141-05:00",
14:   "modificationDate": "2008-10-30T16:37:02.645-05:00",
15:   "selectedFiles": 5183,
16:   "selectedBytes": 88879043,
17:   "todoFiles": 0,
18:   "todoBytes": 0,
19:   "archiveBytes": 78213557,
20:   "archiveBytesDelta": 0,
21:   "archiveBytesDeltaMonth": 0,
22:   "dailyChange": 0,
23:   "quota": {"bytes": 150}
24: }

List

To retrieve a list all users on this server:

HTTP Request

1: GET http://localhost:4280/rest/users HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Server: Apache-Coyote/1.1
 3: X-Powered-By: Servlet 2.4; JBoss-4.0.5.GA (build: CVSTag=Branch_4_0 date=200610162339)/Tomcat-5.5
 4: Content-Type: application/json;charset=UTF-8
 5: X-Transfer-Encoding: chunked
 6: Date: Wed, 29 Oct 2008 19:39:44 GMT
 7: Content-length: 2717
 8:
 9: {
10:   "metadata":   {
11:     "count": 3,
12:     "params": {},
13:     "timestamp": "2008-10-29T14:39:44.825-05:00"
14:   },
15:   "users":   [
16:         {
17:       "id": 67,
18:       "status": "Active",
19:       "email": "userone@testorg.org",
20:       "firstName": "User",
21:       "lastName": "One",
22:       "orgId": 43,
23:       "creationDate": "2008-10-29T13:46:40.242-05:00",
24:       "modificationDate": "2008-10-29T14:06:02.123-05:00"
25:     },
26:         {
27:       "id": 68,
28:       "status": "Active",
29:       "email": "usertwo@testorg.org",
30:       "firstName": "User",
31:       "lastName": "Two",
32:       "orgId": 43,
33:       "creationDate": "2008-10-29T13:47:11.796-05:00",
34:       "modificationDate": "2008-10-29T13:51:06.943-05:00"
35:     },
36:         {
37:       "id": 69,
38:       "status": "Active",
39:       "email": "userthree@testorg.org",
40:       "firstName": "User",
41:       "lastName": "Three",
42:       "orgId": 43,
43:       "creationDate": "2008-10-29T14:08:06.141-05:00",
44:       "modificationDate": "2008-10-29T14:08:06.172-05:00"
45:     }
46:   ]
47: }

Create

To create a new user:

HTTP Request

1: POST http://localhost:4280/rest/users HTTP/1.1
2: Content-length: 114
3: Content-Type: application/json
4: Accept: application/json
5: Authorization: Basic YWRtaW46YWRtaW4=
6:
7: {"lastName": "Three", "password": "userthree", "orgId": 43, "email": "userthree@testorg.org", "firstName": "User"}

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:08:06 GMT
 4: Content-length: 239
 5:
 6: {
 7:   "id": 69,
 8:   "status": "Active",
 9:   "email": "userthree@testorg.org",
10:   "firstName": "User",
11:   "lastName": "Three",
12:   "orgId": 43,
13:   "creationDate": "2008-10-29T14:08:06.141-05:00",
14:   "modificationDate": "2008-10-29T14:08:06.172-05:00"
15: }

Update

To deactivate the user with an ID of 69:

HTTP Request

1: PUT http://localhost:4280/rest/users/67 HTTP/1.1
2: Content-length: 25
3: Content-Type: application/json
4: Accept: application/json
5: Authorization: Basic YWRtaW46YWRtaW4=
6:
7: {"status": "Deactivated"}

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:06:01 GMT
 4: Content-length: 320
 5:
 6: {
 7:   "id": 67,
 8:   "status": "Deactivated",
 9:   "email": "userone@testorg.org",
10:   "firstName": "User",
11:   "lastName": "One",
12:   "orgId": 43,
13:   "creationDate": "2008-10-29T13:46:40.242-05:00",
14:   "modificationDate": "2008-10-29T14:06:01.968-05:00",
15:   "selectedFiles": 0,
16:   "selectedBytes": 0,
17:   "todoFiles": 0,
18:   "todoBytes": 0,
19:   "archiveBytes": 78213557,
20:   "archiveBytesDelta": 0,
21:   "archiveBytesDeltaMonth": 0,
22:   "dailyChange": 0,
23:   "quota": {"bytes": 150}
24: }

Computer

A computer represents a unique resource which has connected to a CrashPlanPRO server and (perhaps) backed up data. Every computer must belong to exactly one user.

Properties

Properties in list view
nameThe name of this computer
guidThe GUID (globally unique identifier) for this computer
status“Active” if the computer is currently active, “Deactivated” if the computer has been deactivated
alertStates“OK” if the computer has backed up within defined days, “WARN” if computer has exceeded “warning” threshold, “ALERT” if computer has exceeded “alert” threshold
userIdThe id of the user to which this computer belongs
mountPointIdThe id number of the mount point where the computer's archive resides


Additional properties in detail view
osNameName of the operating system in use on this computer
osVersionVersion of the operating system in use on this computer
osArchThe underlying architecture of this computer
remoteAddressThe IP address used by this computer to communicate with the PRO Server
javaVersionThe Java virtual machine version in use on this computer
timeZoneThe time zone confgured on this computer
versionThe version of CrashPlan software used on this computer
serverBackupStats.numberSelectedThe number of files selected for backup to the PRO Server. This value is equivalent to the “Selected” field in this view of the admin console.
serverBackupStats.selectedBytesThe total size of files selected for backup to the PRO Server. This value is equivalent to the “Bytes” field in this view of the admin console.
serverBackupStats.percentCompleteThe completion percentage for backups of this computer to the PRO Server. This value is equivalent to the ”% Complete” field in this view of the admin console.
serverBackupStats.archiveBytesThe total disk space used by the PRO Server to store backups from this computer. This value is equivalent to the “Stored” field in this view of the admin console.
serverBackupStats.compressionRateThe compression rate of backups from this computer to the PRO Server. This value is equivalent to the “Comp %” field in this view of the admin console.
serverBackupStats.connectedA boolean value indicating whether this computer is currently connected to the PRO Server. This value is equivalent to the “Connected” field in this view of the admin console.

Properties required for creation: Creation action not supported for this resource

Query parameters available for constraining list action: id, status, name, guid, userId, and paging query parameters

Examples

Retrieve

To retrieve detailed information about the computer with an ID of 2

HTTP Request

1: GET http://localhost:4280/rest/computers/2 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:28:24 GMT
 4: Content-length: 263
 5:
 6: {
 7:   "id": 2,
 8:   "name": "c42-dhcp-191.c42",
 9:   "guid": 343195742699662015,
10:   "status": "Active",
11:   "alertStates": ["OK"],
12:   "userId": 69,
13:   "mountPointId": 1,
14:   "creationDate": "2008-10-29T14:23:58.779-05:00",
15:   "modificationDate": "2008-10-29T14:23:59.738-05:00",
16:   "osName": "Linux",
17:   "osVersion": "2.6.31-14-generic",
18:   "osArch": "i386",
19:   "remoteAddress": "127.0.0.1",
20:   "javaVersion": "1.6.0_0",
21:   "timeZone": "SystemV/CST6CDT",
22:   "version": "3.8.2010",
23:   "serverBackupStats":   {
24:     "numberSelected": 96,
25:     "selectedBytes": 2247629,
26:     "percentComplete": 100,
27:     "archiveBytes": 706201,
28:     "compressionRate": 68.6,
29:     "connected": false,
30:     "lastBackup": "2010-03-30T18:36:10.221Z",
31:     "lastConnected": "2010-03-30T18:35:50.133Z"
32:   }
33: }

List

To retrieve a list of all computers on the server:

HTTP Request

1: GET http://localhost:4280/rest/computers HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:44:13 GMT
 4: Content-length: 412
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 1,
 9:     "params": {},
10:     "timestamp": "2008-10-29T14:44:13.820-05:00"
11:   },
12:   "computers": [  {
13:     "id": 2,
14:     "name": "c42-dhcp-191.c42",
15:     "guid": 343195742699662015,
16:     "status": "Active",
17:     "alertStates": ["OK"],
18:     "userId": 69,
19:     "mountPointId": 1,
20:     "creationDate": "2008-10-29T14:23:58.779-05:00",
21:     "modificationDate": "2008-10-29T14:23:59.738-05:00"
22:   }]
23: }

Usages

A Usage represents a computers backup target (usage). There are also Computer and Computer Usage resources that have some more detail, however if you are using the REST API to monitor the backups of a lot of computers on a regular basis then this resource is much more efficient.

Properties

Properties in list view
sourceIdThe identifier of the source computer
sourceGuidThe GUID of the source computer
sourceConnectedToServera boolean representing the connected state of the source computer
sourceLastConnectedToServera timestamp showing when the source computer last checked in with the server
sourceStatus“Active” if the computer is currently active, “Deactivated” if the computer has been deactivated
sourceUserIdThe id of the user to which this computer belongs
sourceOrgIdThe id of the user to which this computer belongs
targetIdThe id of the computer the source is backing up to
targetGuIdThe GUID of the computer the source is backing up to
selectedFilesThe number of files selected on the source computer
selectedBytesThe number of bytes selected on the source computer
todoFilesThe number of files left to backup from the source computer
todoBytesThe number of bytes left to backup from the source computer
archiveBytesThe number of bytes used on the target computer
lastConnectedThe last time the source connected to the target
lastActivityThe last time the source backed up to the target
isUsingWill be false if backed up to a server and there is an archive hold period in effect. When false, no ongoing backups are occurring.
alertStatesAlerts that have been triggered for this source/target combination

Query parameters available for constraining list action: orgId, userId, and paging query parameters

Examples

List

To retrieve a list of all usages on the server:

HTTP Request

1: GET http://localhost:4280/rest/usages?orgId=23 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 1 Sep 2010 19:28:24 GMT
 4: Content-length: 412
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 1,
 9:     "params": { "orgId": 23 },
10:     "timestamp": "2010-09-01T19:28:24.820-05:00"
11:   },
12:   "usages": [  {
13:     "sourceId": 2,
14:     "sourceGuid": 343195742699662015,
15:     "sourceConnectedToServer": true,
16:     "sourceLastConnectedToServer": "2010-09-01T19:20:59.738-05:00",
17:     "sourceStatus": "Blocked,Active",
18:     "sourceUserId": 234,
19:     "sourceOrgId": 23,
20:     "targetId": 1,
21:     "targetGuId": 345095742699645987,
22:     "selectedFiles": 1513,
23:     "selectedBytes": 19839461229438,
24:     "todoFiles": 0,
25:     "todoBytes": 0,
26:     "archiveBytes": 1828461229332,
27:     "lastConnected": "2010-09-01T19:23:58.779-05:00,
28:     "lastActivity": "2010-09-01T19:10:13.450-05:00,
29:     "isUsing": true,
30:     "alertStates": []
31:   }]
32: }

ComputerUsage

A record of computer usage provides statistics about the interaction between a pair of computers.

Properties

Properties in list view
sourceIdThe id of the source computer
sourceGuidThe GUID of the source computer
targetIdThe id of the target computer
targetGuidThe GUID of the target computer
selectedFilesCount of all files selected for backup
selectedBytesByte count for all files selected for backup
todoFilesCount of all files waiting to be backed up
todoBytesByte count for all files waiting to be backed up
lastActivityTimestamp indicating the last backup activity between the source and target or null if there has been no activity
lastConnectedTimestamp indicating the last time the source connected to the target or null if there has been no connection
archiveBytesSource computer's archive size at the destination in bytes
isUsingIf checked, Computer B is a backup destination for Computer A

Additional properties in detail view: Detail view not available for this resource

Properties required for creation: Creation action not supported for this resource

Query parameters available for constraining list action: sourceId, sourceGuid, targetId, targetGuid, and paging query parameters

Examples

List

To retrieve a list of all computer usage records where the source computer has a GUID of 343195742699662015:

HTTP Request

1: GET http://localhost:4280/rest/computerUsage?sourceGuid=343195742699662015 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Thu, 30 Oct 2008 21:42:46 GMT
 4: Content-length: 624
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 1,
 9:     "params": {"sourceGuid": "343195742699662015"},
10:     "timestamp": "2008-10-30T16:42:47.389-05:00"
11:   },
12:   "computerUsages": [  {
13:     "sourceId": 2,
14:     "sourceGuid": 343195742699662015,
15:     "targetId": 1,
16:     "targetGuid": 42,
17:     "selectedFiles": 0,
18:     "selectedBytes": 0,
19:     "todoFiles": 0,
20:     "todoBytes": 0,
21:     "archiveBytes": 0,
22:     "lastActivity": null,
23:     "lastConnected": "2008-10-29T14:24:18.652-05:00",
24:     "isUsing": true,
25:     "creationDate": "2008-10-29T14:24:17.758-05:00",
26:     "modificationDate": "2008-10-30T16:37:01.822-05:00"
27:   }]
28: }

MountPoint

A mount point is a location where CrashPlan PRO can store backups or other information.

NOTE: Only administrators can access mount point information.

Properties

Properties in list view
nameCurrent name for this mount point
status“ENABLED” if the mount point is enabled, “DISABLED” otherwise
type“DIR” (except for VMWare instances)
volumeLabelName of the mount point's directory on the file system
noteText entered in the note field
bytesPerSecondWrite speed of this mount point. Only available if a write speed test has been executed on this mount point.


Additional properties in detail view
bytesTotalTotal bytes available on this mount point
bytesFreeCount of available bytes on this mount point
bytesUsedCount of in-use bytes on this mount point
percentFreePercentage of this mount point which is still available

Properties required for creation: Creation action not supported for this resource

Query parameters available for constraining list action: id, name, status, type, volumeLabel, note

Examples

Retrieve

To retrieve detailed information about the mount point with an ID of 1:

HTTP Request

1: GET http://localhost:4280/rest/mountPoints/1 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:34:29 GMT
 4: Content-length: 358
 5:
 6: {
 7:   "id": 1,
 8:   "name": "manifest",
 9:   "status": "ENABLED",
10:   "type": "DIR",
11:   "volumeLabel": "manifest",
12:   "note": null,
13:   "bytesPerSecond": null,
14:   "creationDate": "2008-10-28T10:51:47.000-05:00",
15:   "modificationDate": "2008-10-28T10:51:47.000-05:00",
16:   "bytesTotal": 99424124928,
17:   "bytesUsed": 97548881920,
18:   "bytesFree": 1875243008,
19:   "percentFree": 1.9
20: }

List

To list all mount points on this server:

HTTP Request

1: GET http://localhost:4280/rest/mountPoints HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:33:05 GMT
 4: Content-length: 403
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 1,
 9:     "params": {},
10:     "timestamp": "2008-10-29T14:33:05.487-05:00"
11:   },
12:   "mountPoints": [  {
13:     "id": 1,
14:     "name": "manifest",
15:     "status": "ENABLED",
16:     "type": "DIR",
17:     "volumeLabel": "manifest",
18:     "note": null,
19:     "bytesPerSecond": null,
20:     "creationDate": "2008-10-28T10:51:47.000-05:00",
21:     "modificationDate": "2008-10-28T10:51:47.000-05:00"
22:   }]
23: }

Server Statistics

Real-time statistics about what is happening inside the server.

NOTE: Only administrators can access the serverStats resource

Properties

Properties in view
currentArchiveBytesThe total number of bytes used by archives on this system
previousMonthArchiveBytesThe above total from 30 days ago
orgCountThe number of active (versus deactivated) orgs
seatCountThe number of active (versus deactivated) computers
versionThe software version date
backupSessionCountThe number of computers currently sending backup data to this server
connectedClientCountThe number of computers currently connected to this server
hostNameThe name of this host
hostPortThe port used by clients to connect to this server
hostAddressesEach of the IP addresses that this server might be using
hostMemoryTotalThe total amount of RAM available to the host operating system
hostMemoryFreeThe unused RAM available to the host operating system
hostMemoryCachedThe swap size for the host operating system
engineMemoryTotalThe total RAM available to the server (Java virtual machine)
engineMemoryFreeThe unused RAM inside the Java virtual machine
cpuUtilizationThe percentage of CPU currently being used
uptimeThe human-readable amount of time this PRO Server has been running
uptimeMillisecondsThe milliseconds this PRO Server has been running
loadThe load average on the system in the last 1 minute, 5 minutes, and 15 minutes
diskTotalThe amount of disk space on the host OS boot drive
diskFreeThe disk space available on the host OS boot drive
diskUtilizationThe percentage of disk space used on the host OS boot drive

Properties required for creation: Creation action not supported for this resource

Examples

Retrieve

To retrieve server statistics:

HTTP Request

1: GET http://localhost:4280/rest/serverStats HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Wed, 29 Oct 2008 19:34:29 GMT
 4: Content-length: 358
 5:
 6: {
 7:   "currentArchiveBytes": 37724715178678,
 8:   "previousMonthArchiveBytes": 43128889830903,
 9:   "orgCount": 1304,
10:   "seatCount": 18642,
11:   "version": "10.29.2008",
12:   "backupSessionCount": 90,
13:   "connectedClientCount": 4755,
14:   "hostName": "proserver.acme.com",
15:   "hostPort": 4242,
16:   "hostAddresses":   [
17:     "10.10.10.4",
18:     "69.54.39.68",
19:     "69.54.39.67",
20:     "69.54.39.66",
21:     "69.54.39.76"
22:   ],
23:   "hostMemoryTotal": "7.9 GB",
24:   "hostMemoryFree": "44.3 MB",
25:   "hostMemoryCached": "3.3 GB",
26:   "engineMemoryTotal": "3.6 GB",
27:   "engineMemoryFree": "2.1 GB",
28:   "cpuUtilization": "29%",
29:   "uptime": "1.5 hrs",
30:   "uptimeMilliseconds": 1225806954620,
31:   "load": "5.14, 4.38, 3.95",
32:   "diskTotal": "89.2 GB",
33:   "diskFree": "28.8 GB",
34:   "diskUtilization": "68%"
35: }

Archive Record

Daily historical record of archive statistics. Records for users and orgs are summaries of all the computers in that user or organization.

Properties

Properties in list view
sourceIdThe id of the source computer - will be null if userId or orgId is not null
targetIdThe id of the target computer - will be null if userId or orgId is not null
userIdThe id of the user this record represents - will be null if sourceId, targetId, or orgId are not null
orgIdThe id of the org this record represents - will be null if sourceId, targetId, or userId are not null
selectedFilesCount of all files selected for backup
selectedBytesByte count for all files selected for backup
todoFilesCount of all files waiting to be backed up
todoBytesByte count for all files waiting to be backed up
archiveBytesBytes used by the archive
lastActivityTimestamp indicating the last backup activity or null if there has been no activity
lastConnectedTimestamp indicating the last time a computer connected to the target or null if there has been no connection
dailyChangeA rolling 30-day average of bytes added or removed from the archive
archiveBytesDeltaMonthBytes in the archive 30 days ago

Additional properties in detail view: Detail view not available for this resource

Properties required for creation: Creation action not supported for this resource

Query parameters available for constraining list action: userId, orgId, sourceId, sourceGuid, targetId, targetGuid, daysBack, and paging query parameters

Examples

List

To retrieve a list of the 2 most recent archiveRecord resources where for userId 240:

HTTP Request

1: GET http://localhost:4280/rest/archiveRecords?userId=240&daysBack=2 HTTP/1.1
2: Authorization: Basic YWRtaW46YWRtaW4=

HTTP Response

 1: HTTP/1.1 200 OK
 2: Content-Type: application/json;charset=UTF-8
 3: Date: Thu, 30 Apr 2009 15:28:56 GMT
 4: Content-length: 999
 5:
 6: {
 7:   "metadata":   {
 8:     "count": 2,
 9:     "params":     {
10:       "userId": "240",
11:       "daysBack": "2"
12:     },
13:     "timestamp": "2009-04-30T15:28:56.825-05:00"
14:   },
15:   "archiveRecords":   [
16:         {
17:       "sourceId": null,
18:       "targetId": null,
19:       "userId": 240,
20:       "orgId": null,
21:       "selectedFiles": 27240,
22:       "selectedBytes": 15511731881,
23:       "todoFiles": 0,
24:       "todoBytes": 0,
25:       "archiveBytes": 12179848763,
26:       "lastActivity": "2009-04-14T22:52:45.181-05:00",
27:       "lastConnected": "2009-04-15T01:17:53.289-05:00",
28:       "dailyChange": 450852,
29:       "archiveBytesDeltaMonth": 12757604,
30:       "creationDate": "2009-04-15T01:46:28.530-05:00"
31:     },
32:         {
33:       "sourceId": null,
34:       "targetId": null,
35:       "userId": 240,
36:       "orgId": null,
37:       "selectedFiles": 27272,
38:       "selectedBytes": 15548641388,
39:       "todoFiles": 0,
40:       "todoBytes": 0,
41:       "archiveBytes": 12179196493,
42:       "lastActivity": "2009-04-13T04:59:18.455-05:00",
43:       "lastConnected": "2009-04-13T07:00:46.610-05:00",
44:       "dailyChange": 462021,
45:       "archiveBytesDeltaMonth": 12488051,
46:       "creationDate": "2009-04-14T02:08:58.408-05:00"
47:     }]
48: }

Sample Implementation in Python

The sample code below is implemented in the Python programming language. We have chosen to use Python for our sample code because it's easy to read and understand even if you're not familiar with the details of the language. Python is not a requirement, feel free to use whatever language you are most fluent in. If you write your own script, it would be great if you could help others by posting an example to our PRO forum.

We are using features found in Python 2.6 as our code makes extensive use of the JSON package which is standard in Python 2.6. Other than this requirement a standard Python distribution should be adequate; no external or third-party libraries are required.

Assumptions

For purposes of the sample code below we make the following assumptions about our environment:

  • CrashPlan PRO Server has been installed and configured on the same host where our scripts will run.
  • This CrashPlan PRO Server is configured to use HTTPS on port 4285.
  • This CrashPlan PRO Server includes an org with an ID of 43. It is this org that we will monitor and report on.
  • Org 43 contains exactly three users, userone@testorg.org, usertwo@testorg.org and userthree@testorg.org.
  • The ArchiveRecordService has been run at least once. This service runs as part of the daily maintenance job executed by the CrashPlan PRO Server and is responsible for populating usage statistics about computers, users and orgs.

Lesson 1: List of users

We begin with a simple script which will test our ability to access the API in order to retrieve information. We execute a query which should return every user on the system and print the results of this query. We use the httplib library (from the standard library) to perform our HTTPS operations. We could also use the urllib2 library, however urllib2 does not currently support HTTP PUT requests. We will need PUT later in our development so we use httplib throughout for sake of consistency.

Test Script

script1.py

import json
import httplib
import base64
cpc_host = "localhost"
cpc_port = 4285
cpc_username = "admin"
cpc_password = "admin"
def getAuthHeader(u,p):
        # Compute base64 representation of the authentication token.
    token = base64.b64encode('%s:%s' % (u,p))
    return "Basic %s" % token
def getUsers():
        # We supply HTTP authentication headers in advance.
        # And while the "Accept" header below is not strictly required
        # (JSON is the default encoding for the CrashPlan API)
        # it's good practice to explicitly include it.
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users",None,headers)
        data = conn.getresponse().read()
        conn.close()
        return json.loads(data)
    except httplib.HTTPException as inst:
        print "Exception: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
for u in getUsers()["users"]:
    print str(u["email"])

Results

script1.py Output

samplehost:~ sample$ python script1.py
userone@testorg.org
usertwo@testorg.org
userthree@testorg.org
user1@example.com
user2@example.com
...

Lesson 2: List of users in an org

We now enhance our function to accept an org ID and return only those users who are members of that org ID.

Script

script2.py

import json
import httplib
import base64
cpc_host = "localhost"
cpc_port = 4285
cpc_username = "admin"
cpc_password = "admin"
def getAuthHeader(u,p):
        # Compute base64 representation of the authentication token.
    token = base64.b64encode('%s:%s' % (u,p))
    return "Basic %s" % token
def getUsers(orgid):
        # We supply HTTP authentication headers in advance.
        # And while the "Accept" header below is not strictly required
        # (JSON is the default encoding for the CrashPlan API)
        # it's good practice to explicitly include it.
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users",None,headers)
        data = conn.getresponse().read()
        conn.close()
        userlist = json.loads(data)["users"]
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
    else:
               # The list above will return all users for all orgs.
               # We're only interested in users who belong to the
               # org with an ID matching our input argument.
               # Also be sure to limit ourselves to active users only.
        return [u for u in userlist if u["orgId"]
== orgid if u["status"] == "Active"]
for u in getUsers(43):
    print str(u["email"])

Results

script2.py Output

samplehost:~ sample$ python script2.py
userone@testorg.org
usertwo@testorg.org
userthree@testorg.org

Lesson 3: Disk usage for each user

We now wish to further enhance our script by retrieving and displaying information about the disk usage of each user. We implement a new function getUser(userid) which uses the httplib package in Python's standard library to send an HTTP GET request to a URI which returns detailed user information. This information is then returned to the user as a Python dictionary. As described in the CrashPlan API documentation, this detail information includes a field named “archiveBytes” which describes the total number of bytes used to store user data.

We invoke this method for each user in our target org and display the results as well as a warning message if the user has exceeded their allowed quota. For purposes of our demonstration we impose a quota of 10M.

script3.py

import json
import httplib
import base64
 
cpc_host = "localhost"
cpc_port = 4285
cpc_username = "admin"
cpc_password = "admin"
 
def getAuthHeader(u,p):
 
    # Compute base64 representation of the authentication token.
    token = base64.b64encode('%s:%s' % (u,p))
    return "Basic %s" % token
 
def getUsers(orgid):
 
    # We supply HTTP authentication headers in advance.  And while the "Accept" header
    # below is not strictly required (JSON is the default encoding for the CrashPlan API)
    # it's good practice to explicitly include it.
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users",None,headers)
        data = conn.getresponse().read()
        conn.close()
        userlist = json.loads(data)["users"]
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
    else:
        # The list we compute above will return all users for all orgs.  We're only interested
        # in users who belong to the org with an ID matching our input argument.  Also make sure
        # to limit ourselves to active users only.
        return [u for u in userlist if u["orgId"] == orgid if u["status"] == "Active"]
 
def getUser(userid):
 
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users/%s" % userid,None,headers)
        data = conn.getresponse().read()
        conn.close()
        return json.loads(data)
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
 
# We now have a list of users in our target org.  For each of these users, retrieve user detail
# information and check to see how many bytes they're using.
users = getUsers(43)
for user in users:
 
    detail = getUser(user["id"])
    print "Disk usage for user %s %s (%s): %i bytes" % (detail["firstName"],detail["lastName"],detail["email"],detail["archiveBytes"])
    if detail["archiveBytes"] > (1024 * 1024 * 10):
        print "User %s has exceeded 10M limit" % detail["email"]

script3.py Output

samplehost:~ sample$ python script3.py
Disk usage for user User One (userone@testorg.org): 0 bytes
Disk usage for user User Two (usertwo@testorg.org): 0 bytes
Disk usage for user User Three (userthree@testorg.org): 78213557 bytes
User userthree@testorg.org has exceeded 10M limit

Lesson 4: Deactivate user based on a quota

For our final enhancement we wish to automatically deactivate any user that has exceeded their allowed quota. We define a new function deactivateUser(userid) which deactivates the user corresponding to the input user ID. This function uses Python's httplib package to send an HTTP PUT request which results in the deactivation of the user.

script4.py

import json
import httplib
import base64
 
cpc_host = "localhost"
cpc_port = 4285
cpc_username = "admin"
cpc_password = "admin"
 
def getAuthHeader(u,p):
 
    # Compute base64 representation of the authentication token.
    token = base64.b64encode('%s:%s' % (u,p))
    return "Basic %s" % token
 
def getUsers(orgid):
 
    # We supply HTTP authentication headers in advance.  And while the "Accept" header
    # below is not strictly required (JSON is the default encoding for the CrashPlan API)
    # it's good practice to explicitly include it.
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users",None,headers)
        data = conn.getresponse().read()
        conn.close()
        userlist = json.loads(data)["users"]
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
    else:
        # The list we compute above will return all users for all orgs.  We're only interested
        # in users who belong to the org with an ID matching our input argument.  Also make sure
        # to limit ourselves to active users only.
        return [u for u in userlist if u["orgId"] == orgid if u["status"] == "Active"]
 
def getUser(userid):
 
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users/%s" % userid,None,headers)
        data = conn.getresponse().read()
        conn.close()
        return json.loads(data)
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
 
def deactivateUser(userid):
 
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json","Content-Type":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("PUT","/rest/users/%s" % userid,json.dumps({"status": "Deactivated"}),headers)
        data = conn.getresponse().read()
        conn.close()
        respuser = json.loads(data)
        return respuser["status"] == "Deactivated"
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
 
# We now have a list of users in our target org.  For each of these users, retrieve user detail
# information and check to see how many bytes they're using and, if they've exceeded our quota,
# deactivate them.
users = getUsers(43)
for user in users:
 
    detail = getUser(user["id"])
    print "Disk usage for user %s %s (%s): %i bytes" % (detail["firstName"],detail["lastName"],detail["email"],detail["archiveBytes"])
    if detail["archiveBytes"] > (1024 * 1024 * 10):
        print "User %s has exceeded 10M limit, deactivating" % detail["email"]
        succ = deactivateUser(detail["id"])
        if succ:
            print "Deactivation successful"
        else:
            print "Deactivation unsuccessful"

script4.py Output

samplehost:~ sample$ python script4.py
Disk usage for user User One (userone@testorg.org): 0 bytes
Disk usage for user User Two (usertwo@testorg.org): 0 bytes
Disk usage for user User Three (userthree@testorg.org): 78213557 bytes
User userthree@testorg.org has exceeded 10M limit, deactivating
Deactivation successful

Variation 1: Determine costs for each user

We now consider a few variations on our working script in order to illustrate some common uses for the CrashPlan API. One such case may be the generation of a report showing the usage for each user as well as the total cost of that usage where the total cost is determined by some pricing function.

Variation 1 code

import json
import httplib
import base64
 
cpc_host = "localhost"
cpc_port = 4285
cpc_username = "admin"
cpc_password = "admin"
 
def getAuthHeader(u,p):
 
    # Compute base64 representation of the authentication token.
    token = base64.b64encode('%s:%s' % (u,p))
    return "Basic %s" % token
 
def getUsers(orgid):
 
    # We supply HTTP authentication headers in advance.  And while the "Accept" header
    # below is not strictly required (JSON is the default encoding for the CrashPlan API)
    # it's good practice to explicitly include it.
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users",None,headers)
        data = conn.getresponse().read()
        conn.close()
        userlist = json.loads(data)["users"]
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
    else:
        # The list we compute above will return all users for all orgs.  We're only interested
        # in users who belong to the org with an ID matching our input argument.  Also make sure
        # to limit ourselves to active users only.
        return [u for u in userlist if u["orgId"] == orgid if u["status"] == "Active"]
 
def getUser(userid):
 
    headers = {"Authorization":getAuthHeader(cpc_username,cpc_password),"Accept":"application/json"}
 
    try:
        conn = httplib.HTTPSConnection(cpc_host,cpc_port)
        conn.request("GET","/rest/users/%s" % userid,None,headers)
        data = conn.getresponse().read()
        conn.close()
        return json.loads(data)
    except httplib.HTTPException as inst:
        print "Exception in HTTP operations: %s" % inst
        return None
    except ValueError as inst:
        print "Exception decoding JSON: %s" % inst
        return None
 
 
# This function serves as a simple cost formula; it returns the number of dollars charged
# as a function of the number of bytes used.
def computeCost(bytes):
 
    # We charge a base rate of $2.50/MB used.  1048576 is the number of bytes in one MB
    return round(2.5 * bytes/1048576,2)
 
# We now have a list of users in our target org.  For each of these users, retrieve user detail
# information and check to see how many bytes they're using and, if they've exceeded our quota,
# deactivate them.
users = getUsers(43)
for user in users:
 
    detail = getUser(user["id"])
    bytesused = int(detail["archiveBytes"])
    print "Disk usage for user %s %s (%s): %i bytes.  Total cost: $%.2f" % (detail["firstName"],detail["lastName"],detail["email"],bytesused,computeCost(bytesused))

Variation 1 Output

Disk usage for user User One (userone@testorg.org): 0 bytes.  Total cost: $0.00
Disk usage for user User Two (usertwo@testorg.org): 0 bytes.  Total cost: $0.00
Disk usage for user User Three (userthree@testorg.org): 78213557 bytes.  Total cost: $186.48
api.txt · Last modified: 2012/01/25 10:40 (external edit)