jClouds

jclouds is an open source multi-cloud toolkit for the Java platform that gives you the freedom to create applications that are portable across clouds while giving you full control to use cloud-specific features.

This guide will show you how to programmatically use the ProfitBricks provider in jclouds to perform common management tasks available in the ProfitBricks Data Center Designer.

Getting Started

Before you begin you will need to have signed-up for a ProfitBricks account. The credentials you setup during sign-up will be used to authenticate against the API.

Concepts

The jclouds library wraps the ProfitBricks Cloud API v3. All operations are performed over SSL and authenticated using your ProfitBricks portal credentials. The API can be accessed within an instance running in ProfitBricks or directly over the Internet from any application that can send an HTTPS request and receive an HTTPS response.

Installation

jclouds has some pre-requisities before you're able to use it. You will need to:

  • Ensure you are using the Java Development Kit (JDK) version 6 or later. You can check this by running: javac -version.
  • Ensure you are using Maven version 3 or later. You can check this by running: mvn -version.

Now that you have validated the pre-requisities, you will want to do the following:

  • Create a directory to try out jclouds. This can be done by doing:

mkdir jclouds cd jclouds

  • Make a local copy of the pom.xml file below in the jclouds directory.

mvn dependency:copy-dependencies "-DoutputDirectory=./lib"

You should now have a directory with the following structure:

jclouds/
    pom.xml
    lib/
        *.jar

The ProfitBricks provider is currently available as part of the jclouds labs project.

Authentication

Connecting to ProfitBricks can be done by creating a compute connection with the ProfitBricks provider.

pbApi = ContextBuilder.newBuilder("profitbricks-rest")
        .credentials(username, apiKey)
        .buildApi(ProfitBricksApi.class);

Caution: You will want to ensure you follow security best practices when using credentials within your code or stored in a file.

Operations

Data Centers

Virtual Data Centers (VDCs) are the foundation of the ProfitBricks platform. VDCs act as logical containers for all other objects you will be creating, e.g., servers. You can provision as many data centers as you want. Data centers have their own private network and are logically segmented from each other to create isolation.

List Data Centers

List<DataCenter> list = dataCenterApi().list();


Retrieve a Data Center

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
id string The unique ID of the data center. Yes

DataCenter dataCenter = dataCenterApi().getDataCenter(dataCenter.id());


Create a Data Center

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
name string The name of the data center. Yes
location string The physical location where the data center will be created. This will be where all of your servers live. Yes
name string A description for the data center, e.g. staging, production. No

The following table outlines the locations currently supported:

VALUE COUNTRY CITY
us/las United States Las Vegas
de/fra Germany Frankfurt
de/fkb Germany Karlsruhe
DataCenter datacenter = api.dataCenterApi().create("test-data-center", "example description", "us/las");

NOTES: - The value for name cannot contain the following characters: (@, /, , |, ‘’, ‘). - You cannot change a data center's location once it has been provisioned.


Update a Data Center

After retrieving a data center, either by getting it by id, or as a create response object, you can change it's properties and call the update method:

DataCenter dataCenter = dataCenterApi().update(dataCenter.id(), "test-data-center2");

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
name string The new name of the data center. No
description string The new description of the data center. No

Delete a Data Center

This will remove all objects within the data center and remove the data center object itself.

NOTE: This is a highly destructive operation which should be used with extreme caution.

dataCenter = getDataCenter(dataCenter.id());


Servers

List Servers

You can retrieve a list of all servers within a data center.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
List<Server> servers = serverApi().getList('datacenter_id');

Retrieve a Server

Returns information about a server such as its configuration, provisioning status, etc.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
Server server = serverApi().getServer('datacenter_id', 'server-id');

Create a Server

Creates a server within an existing data center. You can configure additional properties such as specifying a boot volume and connecting the server to an existing LAN.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
name string The hostname of the server. Yes
cores int The total number of cores for the server. Yes
ram int The amount of memory for the server in MB, e.g. 2048. Size must be specified in multiples of 256 MB with a minimum of 256 MB; however, if you set ramHotPlug to TRUE then you must use a minimum of 1024 MB. Yes
availabilityZone string The availability zone in which the server should exist. No
licenceType string Sets the OS type of the server. If undefined the OS type will be inherited from the boot image or boot volume. No*
bootVolume string Reference to a Volume used for booting. If not ‘null’ then bootCdrom has to be ‘null’. No
bootCdrom string Reference to a CD-ROM used for booting. If not 'null' then bootVolume has to be 'null'. No
volumes collection A collection of volume IDs that you want to connect to the server. If the volume does not exist it will be created implicitly. No
nics collection A collection of NICs you wish to create at the time the server is provisioned. No
cpuFamily string Sets the CPU type. "AMD_OPTERON" or "INTEL_XEON". Defaults to "AMD_OPTERON". No

The following table outlines the various licence types you can define:

LICENCE TYPE COMMENT
WINDOWS You must specify this if you are using your own, custom Windows image due to Microsoft's licensing terms.
LINUX
UNKNOWN If you are using an image uploaded to your account your OS Type will inherit as UNKNOWN.

The following table outlines the availability zones currently supported:

LICENCE TYPE COMMENT
AUTO Automatically Selected Zone
ZONE_1 Fire Zone 1
ZONE_2 Fire Zone 2
Server server = serverApi().createServer(
              Server.Request.creatingBuilder()
              .dataCenterId('datacenter_id')
              .name("name")
              .cpuFamily('cpuFamily')
              .availabilityZone('availabilityZone')
              .cores(cores)
              .ram(ram)
              .build());

The server can take time to provision. The "waitUntilAvailable" server object method will wait until the server state is available before continuing. This is useful when chaining requests together that are dependent on one another.

waitUntilAvailable = Predicates2.retry(
      new ProvisioningStatusPollingPredicate(api, ProvisioningStatusAware.SERVER, ProvisioningState.AVAILABLE),
      2l * 60l, 2l, TimeUnit.SECONDS);

NOTE: When creating a volume, you must specify either the licence_type or an image.


Update a Server

Perform updates to attributes of a server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
name string The name of the server. No
cores int The number of cores for the server. No
ram int The amount of memory in the server. No
availabilityZone string The new availability zone for the server. No
licenceType string The licence type for the server. No
bootVolume string Reference to a Volume used for booting. If not ‘null’ then bootCdrom has to be ‘null’ No
bootCdrom string Reference to a CD-ROM used for booting. If not 'null' then bootVolume has to be 'null'. No

After retrieving a server, either by getting it by id, or as a create response object, you can change it's properties and call the update method:

Server updated = api.serverApi().updateServer(
              Server.Request.updatingBuilder()
              .id(server-id)
              .dataCenterId(datacenter_id)
              .name("name")
              .ram(ram)
              .cores(cores)
              .build());

Delete a Server

This will remove a server from a data center. NOTE: This will not automatically remove the storage volume(s) attached to a server. A separate API call is required to perform that action.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

serverApi().deleteServer(datacenter_id, server-id);

List Attached Volumes

Retrieves a list of volumes attached to the server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the get_volumes method directly on the object:

List<Volume> volumes = serverApi().listAttachedVolumes('datacenter_id', 'server-id');

Attach a Volume

This will attach a pre-existing storage volume to the server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
storage-id string The unique ID of a storage volume. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the attach_volume method directly on the object:

Volume attachedVolume = serverApi().attachVolume(
              Server.Request.attachVolumeBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server-id')
              .volumeId('storage-id')
              .build()

Retrieve an Attached Volume

This will retrieve the properties of an attached volume.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
volume-id string The unique ID of the attached volume. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the get_attached_volume method directly on the object:

Volume volume = serverApi().getVolume('datacenter_id', 'server-id', 'storage-id');

Detach a Volume

This will detach the volume from the server. Depending on the volume "hot_unplug" settings, this may result in the server being rebooted.

This will NOT delete the volume from your data center. You will need to make a separate request to delete a volume.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
volume-id string The unique ID of the attached volume. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the detach_volume method directly on the object:

serverApi().detachVolume('datacenter_id', 'server-id', 'storage-id');

List Attached CD-ROMs

Retrieves a list of CD-ROMs attached to the server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the get_cdroms method directly on the object:

List<Image> images = serverApi().listAttachedCdroms('datacenter_id', 'server-id');

Attach a CD-ROM

You can attach a CD-ROM to an existing server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
cdrom-image-id string The unique ID of a CD-ROM. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the attach_cdrom method directly on the object:

Image attachedCdrom = serverApi().attachCdrom(
              Server.Request.attachCdromBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server-id')
              .imageId('cdrom-image-id')
              .build()
      );

Retrieve an Attached CD-ROM

You can retrieve a specific CD-ROM attached to the server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
cdrom-id string The unique ID of the attached CD-ROM. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the get_attached_cdrom method directly on the object:

Image cdrom = serverApi().getCdrom('datacenter_id', 'server-id', 'cdrom-image-id');

Detach a CD-ROM

This will detach a CD-ROM from the server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
cdrom-id string The unique ID of the attached CD-ROM. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the detach_cdrom method directly on the object:

serverApi().detachCdrom('datacenter_id', 'server-id', 'cdrom-image-id');

Reboot a Server

This will force a hard reboot of the server. Do not use this method if you want to gracefully reboot the machine. This is the equivalent of powering off the machine and turning it back on.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the reboot method directly on the object:

serverApi().rebootServer('datacenter_id', 'server-id');

Start a Server

This will start a server. If the server's public IP was deallocated then a new IP will be assigned.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the start method directly on the object:

serverApi().startServer('datacenter_id', 'server-id');

Stop a Server

This will stop a server. The machine will be forcefully powered off, billing will cease, and the public IP, if one is allocated, will be deallocated.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes

After retrieving a server, either by getting it by id, or as a create response object, you can call the stop method directly on the object:

serverApi().stopServer('datacenter_id', 'server-id');

Volumes

List Volumes

Retrieve a list of volumes within the data center. If you want to retrieve a list of volumes attached to a server please see the Servers section for examples on how to do so.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
List<Volume> volumes = volumeApi().getList('datacenter_id');

Get a Volume

Retrieves the attributes of a given volume.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
volume-id string The unique ID of the volume. Yes
Volume volume = volumeApi().getVolume('datacenter_id', 'volume-id');

Create a Volume

Creates a volume within the data center. This will NOT attach the volume to a server. Please see the Servers section for details on how to attach storage volumes.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
name string The name of the volume. No
size int The size of the volume in GB. Yes
bus string The bus type of the volume (VIRTIO or IDE). Default: VIRTIO. No
image string The image or snapshot ID. Yes*
type string The volume type, HDD or SSD. Yes
licenceType string The licence type of the volume. Options: LINUX, WINDOWS, UNKNOWN, OTHER Yes*
imagePassword string One-time password is set on the Image for the appropriate account. This field may only be set in creation requests. When reading, it always returns null. Password has to contain 8-50 characters. Only these characters are allowed: [abcdefghjkmnpqrstuvxABCDEFGHJKLMNPQRSTUVX23456789] Yes*
sshKeys string SSH keys to allow access to the volume via SSH Yes*
availabilityZone string The storage availability zone assigned to the volume. Valid values: AUTO, ZONE_1, ZONE_2, or ZONE_3. This only applies to HDD volumes. Leave blank or set to AUTO when provisioning SSD volumes. No

*You will need to provide either the image or the licenceType parameters. licenceType is required, but if image is supplied, it is already set and cannot be changed. Similarly either the imagePassword or sshKeys parameters need to be supplied when creating a volume. We recommend setting a valid value for imagePassword even when using sshKeys so that it is possible to authenticate using the remote console feature of the DCD.

testVolume = volumeApi().createVolume(
              Volume.Request.creatingBuilder()
              .dataCenterId('datacenter_id')
              .name("name")
              .size(size)
              .licenceType('licenceType')
              .type('type')
              .image('image')
              .sshKeys('sshKeys')
              .build());

Update a Volume

You can update -- in full or partially -- various attributes on the volume; however, some restrictions are in place:

You can increase the size of an existing storage volume. You cannot reduce the size of an existing storage volume. The volume size will be increased without reboot if the hot plug settings have been set to true. The additional capacity is not added to any partition therefore you will need to partition it afterwards. Once you have increased the volume size you cannot decrease the volume size.

Since an existing volume is being modified , none of the request parameters are specifically required as long as the changes being made satisfy the requirements for creating a volume.

After retrieving a volume, either by getting it by id, or as a create response object, you can change it's properties and call the update method:

Volume volume = api.volumeApi().updateVolume(
              Volume.Request.updatingBuilder()
              .dataCenterId('datacenter_id')
              .id('volume-id')
              .name("name")
              .build());

Delete a Volume

Deletes the specified volume. This will result in the volume being removed from your data center. Use this with caution.

After retrieving a volume, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

volumeApi().deleteVolume('datacenter_id', 'volume-id');

Create a Volume Snapshot

Creates a snapshot of a volume within the data center. You can use a snapshot to create a new storage volume or to restore a storage volume.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
name string The name of the snapshot.
description string The description of the snapshot.

After retrieving a volume, either by getting it by id, or as a create response object, you can call the create_snapshot method directly on the object:

Snapshot snapshot = volumeApi().createSnapshot(
              Volume.Request.createSnapshotBuilder()
              .dataCenterId('datacenter_id')
              .volumeId('volume-id')
              .name('My snapshot')
              .description("snapshot desc...")
              .build());

Restore a Volume Snapshot

This will restore a snapshot onto a volume. A snapshot is created as just another image that can be used to create new volumes or to restore an existing volume.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
snapshotId string The ID of the snapshot. Yes

After retrieving a volume, either by getting it by id, or as a create response object, you can call the restore_snapshot method directly on the object:

volumeApi().restoreSnapshot(
              Volume.Request.restoreSnapshotBuilder()
              .dataCenterId('datacenter_id')
              .volumeId('volume-id')
              .snapshotId('snapshot-id')
              .build()

Snapshots

List Snapshots

You can retrieve a list of all snapshots.

List<Snapshot> snapshots = snapshotApi().list();

Get a Snapshot

Retrieves the attributes of a specific snapshot.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
snapshotId string The ID of the snapshot. Yes
Snapshot snapshot = snapshotApi().get('snapshotId');

Update a Snapshot

Perform updates to attributes of a snapshot.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
snapshotId string The ID of the snapshot. Yes
name string The name of the snapshot.
description string The description of the snapshot.
cpuHotPlug bool This volume is capable of CPU hot plug (no reboot required)
cpuHotUnplug bool This volume is capable of CPU hot unplug (no reboot required)
ramHotPlug bool This volume is capable of memory hot plug (no reboot required)
ramHotUnplug bool This volume is capable of memory hot unplug (no reboot required)
nicHotPlug bool This volume is capable of NIC hot plug (no reboot required)
nicHotUnplug bool This volume is capable of NIC hot unplug (no reboot required)
discVirtioHotPlug bool This volume is capable of Virt-IO drive hot plug (no reboot required)
discVirtioHotUnplug bool This volume is capable of Virt-IO drive hot unplug (no reboot required)
discScsiHotPlug bool This volume is capable of SCSI drive hot plug (no reboot required)
discScsiHotUnplug bool This volume is capable of SCSI drive hot unplug (no reboot required)
licencetype string The snapshot's licence type: LINUX, WINDOWS, or UNKNOWN.

After retrieving a snapshot, either by getting it by id, or as a create response object, you can change it's properties and call the update method:

Snapshot snapshot = snapshotApi().update(
              Snapshot.Request.updatingBuilder()
              .id('snapshotId')
              .name("name")
              .build()

Delete a Snapshot

Deletes the specified snapshot.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
snapshotId string The ID of the snapshot. Yes

After retrieving a snapshot, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

snapshotApi().delete('snapshotId');

Firewall Rules

List Firewall Rules

Retrieves a list of firewall rules associated with a particular NIC.

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic_id string The unique ID of the NIC. Yes
List<FirewallRule> firewalls = firewallApi().list('datacenter_id', 'server_id', 'nic_id');

Get a Firewall Rule

Retrieves the attributes of a given firewall rule.

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic_id string The unique ID of the NIC. Yes
firewall_rule_id string The unique ID of the firewall rule. Yes
FirewallRule firewallRule = firewallApi().get('datacenter_id', 'server_id', 'nic_id', 'firewall_rule_id');

Create a Firewall Rule

This will add a firewall rule to the NIC.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic_id string The unique ID of the NIC. Yes
name string The name of the Firewall Rule.
protocol string The protocol for the rule: TCP, UDP, ICMP, ANY. Yes
sourceMac string Only traffic originating from the respective MAC address is allowed. Valid format: aa:bb:cc:dd:ee:ff. Value null allows all source MAC address.
sourceIp string Only traffic originating from the respective IPv4 address is allowed. Value null allows all source IPs.
targetIp string In case the target NIC has multiple IP addresses, only traffic directed to the respective IP address of the NIC is allowed. Value null allows all target IPs.
portRangeStart string Defines the start range of the allowed port (from 1 to 65534) if protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd value null to allow all ports.
portRangeEnd string Defines the end range of the allowed port (from 1 to 65534) if the protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd null to allow all ports.
icmpType string Defines the allowed type (from 0 to 254) if the protocol ICMP is chosen. Value null allows all types.
icmpCode string Defines the allowed code (from 0 to 254) if protocol ICMP is chosen. Value null allows all codes.
testFirewallRule = firewallApi().create(
              FirewallRule.Request.creatingBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server_id')
              .nicId('nic_id')
              .name("name")
              .protocol('protocol')
              .portRangeStart(1)
              .portRangeEnd(600)
              .build());

Update a Firewall Rule

Perform updates to attributes of a firewall rule.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic_id string The unique ID of the NIC. Yes
firewall_rule_id string The unique ID of the firewall rule. Yes
name string The name of the Firewall Rule.
sourceMac string Only traffic originating from the respective MAC address is allowed. Valid format: aa:bb:cc:dd:ee:ff. Value null allows all source MAC address.
sourceIp string Only traffic originating from the respective IPv4 address is allowed. Value null allows all source IPs.
targetIp string In case the target NIC has multiple IP addresses, only traffic directed to the respective IP address of the NIC is allowed. Value null allows all target IPs.
portRangeStart string Defines the start range of the allowed port (from 1 to 65534) if protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd value null to allow all ports.
portRangeEnd string Defines the end range of the allowed port (from 1 to 65534) if the protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd null to allow all ports.
icmpType string Defines the allowed type (from 0 to 254) if the protocol ICMP is chosen. Value null allows all types.
icmpCode string Defines the allowed code (from 0 to 254) if protocol ICMP is chosen. Value null allows all codes.

After retrieving a firewall rule, either by getting it by id, or as a create response object, you can change its properties and call the update method:

FirewallRule updated = firewallApi().update(FirewallRule.Request.updatingBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server_id')
              .nicId('nic_id')
              .id('firewall_rule_id')
              .name("name")
              .build());

Delete a Firewall Rule

Removes the specific firewall rule.

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic_id string The unique ID of the NIC. Yes
firewall_rule_id string The unique ID of the firewall rule. Yes

After retrieving a firewall rule, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

firewallApi().delete('datacenter_id', 'server_id', 'nic_id', 'firewall_rule_id');

Images

List Images

Retrieve a list of images.

List<Image> images = imageApi().getList();

Get an Image

Retrieves the attributes of a specific image.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
image-id string The unique ID of the image. Yes
Image image = imageApi().getImage('image-id');

Network Interfaces (NICs)

List NICs

Retrieve a list of LANs within the data center.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
List<Nic> nics = nicApi().list('datacenter_id', 'server-id');

Get a NIC

Retrieves the attributes of a given NIC.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server-id string The unique ID of the server. Yes
nic-id string The unique ID of the NIC. Yes
Nic nic = nicApi().get('datacenter_id', 'server-id', 'nic-id');

Create a NIC

Adds a NIC to the target server.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
name string The name of the NIC.
ips string collection IPs assigned to the NIC. This can be a collection.
dhcp bool Set to FALSE if you wish to disable DHCP on the NIC. Default: TRUE.
lan int The LAN ID the NIC will sit on. If the LAN ID does not exist it will be created. Yes
nat bool Indicates the private IP address has outbound access to the public internet.
firewallActive bool Once you add a firewall rule this will reflect a true value.
firewallrules string collection A list of firewall rules associated to the NIC represented as a collection.
Nic nic = nicApi().create(
              Nic.Request.creatingBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server_id')
              .name("name")
              .lan(lan)
              .build());

Update a NIC

You can update -- in full or partially -- various attributes on the NIC; however, some restrictions are in place:

The primary address of a NIC connected to a load balancer can only be changed by changing the IP of the load balancer. You can also add additional reserved, public IPs to the NIC.

The user can specify and assign private IPs manually. Valid IP addresses for private networks are 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic-id string The unique ID of the NIC. Yes
name string The name of the NIC.
ips string collection IPs assigned to the NIC represented as a collection.
dhcp bool Boolean value that indicates if the NIC is using DHCP or not.
lan int The LAN ID the NIC sits on.
nat bool Indicates the private IP address has outbound access to the public internet.

After retrieving a NIC, either by getting it by id, or as a create response object, you can call the update method directly on the object:

Nic updated = nicApi().update(
              Nic.Request.updatingBuilder()
              .dataCenterId('datacenter_id')
              .serverId('server_id')
              .id('nic_id')
              .name('name')
              .build());

Delete a NIC

Deletes the specified NIC.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
server_id string The unique ID of the server. Yes
nic-id string The unique ID of the NIC. Yes

After retrieving a NIC, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

nicApi().delete('datacenter_id', 'server_id', 'nic_id');

IP Blocks

List IP Blocks

Retrieve a list of IP Blocks.

List<IpBlock> ipBlocks = ipBlockApi().list();

Get an IP Block

Retrieves the attributes of a specific IP Block.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
ipblock-id string The unique ID of the IP block. Yes
IpBlock ipBlock = ipBlockApi().get('ipblock-id');

Create an IP Block

Creates an IP block.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
location string This must be one of the locations: us/las, de/fra, de/fkb. Yes
size int The size of the IP block you want. Yes
name string A descriptive name for the IP block No
IpBlock IpBlock = ipBlockApi().create(IpBlock.Request.creatingBuilder()
              .properties(IpBlock.PropertiesRequest.create('name', 'location', 'size')).build());

Delete an IP Block

Deletes the specified IP Block.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
ipblock-id string The unique ID of the IP block. Yes

After retrieving an IP block, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

ipb = compute.ip_blocks.get('ipblock-id')
ipb.delete
ipBlockApi().delete('ipblock-id');

LANs

List LANs

Retrieve a list of LANs within the data center.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
List<Lan> lans = lanApi().list('datacenter_id');

Create a LAN

Creates a LAN within a data center.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
name string The name of your LAN.
public bool Boolean indicating if the LAN faces the public Internet or not.
nics string collection A collection of NICs associated with the LAN.
Lan Lan = lanApi().create(
              Lan.Request.creatingBuilder()
              .dataCenterId('datacenter_id')
              .name('name')
              .build());

Get a LAN

Retrieves the attributes of a given LAN.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
lan-id string The unique ID of the LAN. Yes
Lan lan = lanApi().get('datacenter_id', 'lan-id');

Update a LAN

Perform updates to attributes of a LAN.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
lan-id string The unique ID of the LAN. Yes
name string A descriptive name for the LAN.
public bool Boolean indicating if the LAN faces the public Internet or not.

After retrieving a LAN, either by getting it by id, or as a create response object, you can change it's properties and call the update method:

Lan updated = api.lanApi().update(
              Lan.Request.updatingBuilder()
              .dataCenterId('datacenter_id')
              .id('lan-id')
              .isPublic(public)
              .build());

Delete a LAN

Deletes the specified LAN.

The following table describes the request arguments:

NAME TYPE DESCRIPTION REQUIRED
datacenter_id string The unique ID of the data center. Yes
lan-id string The unique ID of the LAN. Yes

After retrieving a LAN, either by getting it by id, or as a create response object, you can call the delete method directly on the object:

lanApi().delete('datacenter_id', 'lan-id');

Example:

package com.profitbricks.example;

import com.google.common.base.Predicate;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.jclouds.ContextBuilder;
import org.jclouds.profitbricks.ProfitBricksApi;
import org.jclouds.profitbricks.compute.internal.ProvisioningStatusAware;
import org.jclouds.profitbricks.compute.internal.ProvisioningStatusPollingPredicate;
import org.jclouds.profitbricks.domain.DataCenter;
import org.jclouds.profitbricks.domain.Image;
import org.jclouds.profitbricks.domain.Location;
import org.jclouds.profitbricks.domain.ProvisioningState;
import org.jclouds.profitbricks.domain.Server;
import org.jclouds.profitbricks.domain.Storage;
import org.jclouds.util.Predicates2;

public class App {

    private static Predicate<String> waitUntilAvailable;
    private static final String provider = "profitbricks";
    private static final String username = "username";
    private static final String apikey = "apikey";

    public static void main(String[] args) {

        ProfitBricksApi api = ContextBuilder.newBuilder(provider)
                .credentials(username, apikey)
                .buildApi(ProfitBricksApi.class);

        /*
         * CreateDataCenterRequest.
         * The only required field is DataCenterName.
         * If location parameter is left empty data center will be created in the default region of the customer
         */
        DataCenter dc = api.dataCenterApi().createDataCenter(
                DataCenter.Request.CreatePayload.create("JClouds", Location.DE_FKB)
        );

        /*
         * DataCenterId: Defines the data center wherein the server is to be created.
         * AvailabilityZone: Selects the zone in which the server is going to be created (AUTO, ZONE_1, ZONE_2).
         * Cores: Number of cores to be assigned to the specified server. Required field.
         * InternetAccess: Set to TRUE to connect the server to the Internet via the specified LAN ID.
         * OsType: Sets the OS type of the server.
         * Ram: Number of RAM memory (in MiB) to be assigned to the server.
         */
        String serverId = api.serverApi().createServer(Server.Request.creatingBuilder()
                .dataCenterId(dc.id())
                .name("jclouds-node")
                .cores(1)
                .ram(1024)
                .build());

        /*
         * The "waitUntilAvailable" server object method will wait until the server state is available before continuing
         */
        waitUntilAvailable = Predicates2.retry(
                new ProvisioningStatusPollingPredicate(api, ProvisioningStatusAware.SERVER, ProvisioningState.AVAILABLE),
                2l * 60l, 2l, TimeUnit.SECONDS);

        /*
         * Get list of all images.
         */
        List<Image> images = api.imageApi().getAllImages();

        /* dataCenterId: Defines the data center wherein the storage is to be created. If left empty, the storage will be created in a new data center
         * name: names the new volume.
         * Size: Storage size (in GiB). Required Field.
         */
        String storageId = api.storageApi().createStorage(
                Storage.Request.creatingBuilder()
                .dataCenterId(dc.id())
                .name("hdd-1")
                .size(2f)
                .build());

        /*
         * ServerId: Id of the server to be updated.
         * ServerName: Renames target virtual server
         * Cores: Updates the amount of cores of the target virtual server
         * Ram: Updates the RAM memory (in MiB) of the target virtual
         */
        api.serverApi().updateServer(
                Server.Request.updatingBuilder()
                .id(serverId)
                .name("apache-node")
                .cores(2)
                .ram(2 * 1024)
                .build());

        /*
         * id: identifier of a storage to be updated
         * name: changes the name of the storage
         */
        api.storageApi().updateStorage(
                Storage.Request.updatingBuilder()
                .id(storageId)
                .name("hdd-2")
                .build());

        /*
         * Disconnects storage from the server.
         */
        api.storageApi().disconnectStorageFromServer(storageId, serverId);

        /*
         * Fetches list of all DataCenters
         */
        List<DataCenter> dataCenters = api.dataCenterApi().getAllDataCenters();

        /*
         * Fetches list of all Volumes
         */
        List<Storage> storages = api.storageApi().getAllStorages();

        /*
         * Fetches list of all Servers
         */
        List<Server> servers = api.serverApi().getAllServers();

        api.dataCenterApi().deleteDataCenter(dc.id());
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.apache.jclouds.labs</groupId>
        <artifactId>jclouds-labs</artifactId>
        <version>2.0.0-SNAPSHOT</version>
    </parent>

    <!-- TODO: when out of labs, switch to org.jclouds.api -->
    <artifactId>profitbricks-rest</artifactId>
    <name>jclouds ProfitBricks REST api</name>
    <description>jclouds components to access an implementation of ProfitBricks</description>
    <packaging>bundle</packaging>

    <properties>
        <test.profitbricks-rest.endpoint>https://api.profitbricks.com/cloudapi/v3/</test.profitbricks-rest.endpoint>
        <test.profitbricks-rest.identity>FIXME</test.profitbricks-rest.identity>
        <test.profitbricks-rest.credential>FIXME</test.profitbricks-rest.credential>
        <test.profitbricks-rest.api-version>1.3</test.profitbricks-rest.api-version>
        <jclouds.osgi.export>org.jclouds.profitbricks*;version="${project.version}"</jclouds.osgi.export>
        <jclouds.osgi.import>
            org.jclouds.labs*;version="${project.version}",
            org.jclouds*;version="${jclouds.version}",
            *
        </jclouds.osgi.import>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.jclouds</groupId>
            <artifactId>jclouds-core</artifactId>
            <version>${jclouds.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds</groupId>
            <artifactId>jclouds-compute</artifactId>
            <version>${jclouds.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.auto.service</groupId>
            <artifactId>auto-service</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.auto.value</groupId>
            <artifactId>auto-value</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds.driver</groupId>
            <artifactId>jclouds-okhttp</artifactId>
            <version>${jclouds.version}</version>
        </dependency>
        <!-- Test dependencies -->
        <dependency>
            <groupId>org.apache.jclouds</groupId>
            <artifactId>jclouds-core</artifactId>
            <version>${jclouds.version}</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds</groupId>
            <artifactId>jclouds-compute</artifactId>
            <version>${jclouds.version}</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds.driver</groupId>
            <artifactId>jclouds-sshj</artifactId>
            <version>${jclouds.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp</groupId>
            <artifactId>mockwebserver</artifactId>
            <exclusions>
                <!-- Already provided by jclouds-sshj -->
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcprov-jdk15on</artifactId>
                </exclusion>
            </exclusions>
            <type>jar</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds.driver</groupId>
            <artifactId>jclouds-slf4j</artifactId>
            <version>${jclouds.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.jclouds.driver</groupId>
            <artifactId>jclouds-log4j</artifactId>
            <version>${jclouds.version}</version>
            <scope>test</scope>
            <type>jar</type>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>live</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>integration</id>
                                <phase>integration-test</phase>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                                <configuration>
                                    <threadCount>1</threadCount>
                                    <systemPropertyVariables>
                                        <test.profitbricks-rest.endpoint>${test.profitbricks-rest.endpoint}</test.profitbricks-rest.endpoint>
                                        <test.profitbricks-rest.identity>${test.profitbricks-rest.identity}</test.profitbricks-rest.identity>
                                        <test.profitbricks-rest.credential>${test.profitbricks-rest.credential}</test.profitbricks-rest.credential>
                                        <test.profitbricks-rest.api-version>${test.profitbricks-rest.api-version}</test.profitbricks-rest.api-version>
                                        <test.profitbricks-rest.template>${test.profitbricks-rest.template}</test.profitbricks-rest.template>
                                    </systemPropertyVariables>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>