Quickstart for Cloud Networking#

Cloud Networking is used to provide on-demand, scalable, and technology-agnostic network abstraction.

Concepts#

To use this service effectively, you should understand how these key ideas are used in this context:

networks

A network provides connectivity to and from instances.

Tenant networks are networks created by users within tenants, or groups of users. By default, networks created with tenants are not shared among other tenants. Useful network types in this category are vlan (802.1q tagged) and gre (unique id). With the use of the L3 agent and Neutron routers, it is possible to route between GRE-based tenant networks. Without a Neutron router, these networks are effectively isolated from each other (and everything else, for that matter).

subnets

A subnetwork, or subnet, is a logical, visible subdivision of an IP network. The practice of dividing a network into two or more networks is called subnetting.

Computers that belong to a subnet are addressed with a common, identical, most-significant bit-group in their IP address. This results in the logical division of an IP address into two fields, a network or routing prefix and the rest field or host identifier. The rest field is an identifier for a specific host or network interface.

ports

In computer networking, a port is a software construct serving as a communications endpoint in a computer’s host operating system. A port is always associated with an IP address of a host and the protocol type of the communication. It completes the destination or origination address of a communications session. A port is identified for each address and protocol by a 16-bit number, commonly known as the port number.

Extensions#

  • Security Groups – Create and enforce ingress and egress traffic rules per-port

  • Virtual Interfaces – Use the Cloud Networks virtual interface extension to create a virtual interface to a specified network and attach that network to an existing server instance. You can attach either an isolated network that you have created or a Rackspace network.

    A virtual interface works in the same way as the network interface card (NIC) inside your laptop. Like a NIC, a virtual interface is the medium through which you can attach a network to your server. You create a virtual interface for a specified network, and the network, which is composed of logical switches, is attached to your server instance through the virtual interface.

    You can create a maximum of one virtual interface per instance per network.

  • Nova-Network – Please see Deprecation of Nova Network: http://docs.openstack.org/openstack-ops/content/nova-network-deprecation.html

Authentication#

To use this service you have to authenticate first. To do this, you will need your Rackspace username and API key. Your username is the one you use to login to the Cloud Control Panel at http://mycloud.rackspace.com/.

To find your API key, use the instructions in View and reset your API key.

You can specify a default region. Here is a list of available regions:

  • DFW (Dallas-Fort Worth, TX, US)

  • HKG (Hong Kong, China)

  • IAD (Blacksburg, VA, US)

  • LON (London, England)

  • SYD (Sydney, Australia)

Some users have access to another region in ORD (Chicago, IL). New users will not have this region.

Once you have these pieces of information, you can pass them into the SDK by replacing {username}, {apiKey}, and {region} with your info:

var identity = new CloudIdentity
{
    APIKey = "{apikey}",
    Username = "{username}"
};
var identityService = new CloudIdentityProvider(identity);
var networkService = new CloudNetworkService(identityService, "{region}");
import (
  "github.com/rackspace/gophercloud"
  "github.com/rackspace/gophercloud/rackspace"
  osNetworks "github.com/rackspace/gophercloud/openstack/networking/v2/networks"
  "github.com/rackspace/gophercloud/rackspace/networking/v2/networks"
  osSubnets "github.com/rackspace/gophercloud/openstack/networking/v2/subnets"
  "github.com/rackspace/gophercloud/rackspace/networking/v2/subnets"
  osPorts "github.com/rackspace/gophercloud/openstack/networking/v2/ports"
  "github.com/rackspace/gophercloud/rackspace/networking/v2/ports"
  osRules "github.com/rackspace/gophercloud/openstack/networking/v2/security/rules"
  "github.com/rackspace/gophercloud/rackspace/networking/v2/security/rules"
  osGroups "github.com/rackspace/gophercloud/openstack/networking/v2/security/groups"
  "github.com/rackspace/gophercloud/rackspace/networking/v2/security/groups"
)

ao := gophercloud.AuthOptions{
  Username: "{username}",
  APIKey: "{apiKey}",
}

provider, err := rackspace.AuthenticatedClient(ao)

client, err := rackspace.NewNetworkV2(provider, gophercloud.EndpointOpts{
  Region: "{region}",
})
// Authentication in jclouds is lazy and happens on the first call to the cloud.
NeutronApi neutronApi = ContextBuilder.newBuilder("rackspace-cloudnetworks-us")
    .credentials("{username}", "{apiKey}")
    .buildApi(NeutronApi.class);
pkgcloud = require('pkgcloud');

// Each client is bound to a specific service and provider.
var client = pkgcloud.network.createClient({
  provider: 'rackspace',
  username: '{username}',
  apiKey: '{apiKey}',
  region: '{region}'
});
require 'vendor/autoload.php';

use OpenCloud\Rackspace;

$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
  'username' => '{username}',
  'apiKey'   => '{apiKey}'
));
import pyrax

pyrax.set_setting("identity_type", "rackspace")
pyrax.set_default_region('{region}')
pyrax.set_credentials('{username}', '{apiKey}')
cm = pyrax.cloud_monitoring
require 'fog'

@client = Fog::Rackspace::NetworkingV2.new(
  :rackspace_username => '{username}',
  :rackspace_api_key => '{apikey}',
  :rackspace_region => '{region}'
)
# {username}, {apiKey} below are placeholders, do not enclose '{}' when you replace them with actual credentials.

curl -s https://identity.api.rackspacecloud.com/v2.0/tokens -X 'POST' \
   -d '{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"{username}", "apiKey":"{apiKey}"}}}' \
   -H "Content-Type: application/json" | python -m json.tool

# From the resulting json, set three environment variables: tenant, TOKEN and endpoint

export TENANT="{tenantId}"
export TOKEN="{tokenId}"
export ENDPOINT="{publicUrl}" # For Monitoring service

Use the API#

Some of the basic operations you can perform with this API are described below.

Create Network#

To create a network:

var networkDefinition = new NetworkDefinition { Name = "{network-name}" };
var network = await networkService.CreateNetworkAsync(networkDefinition);
opts := osNetworks.CreateOpts{
  Name: "MyNewNetwork",
}

network, err := networks.Create(client, opts).Extract()
NetworkApi networkApi = neutronApi.getNetworkApi("{region}");

Network network = networkApi.create(Network.createBuilder("MyNewNetwork").build());
client.createNetwork({
  name: 'MyNewNetwork'
}, function(err, network) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your network here
});
$networkingService = $client->networkingService(null, '{region}');

$network = $networkingService->createNetwork(array(
    'name' => 'MyNewNetwork'
));
// Not currently supported by this SDK
@network = @client.networks.new(:name => "MyNewNetwork").save
curl -X "POST" "https://dfw.networks.api.rackspacecloud.com/v2.0/networks" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -d $'{"network": {"name": "MyNewNetwork"} }' \
  -H "Accept: application/json" | python -m json.tool

List Networks#

To list networks:

IPage<Network> networks = networkService.ListNetworksAsync();
err := networks.List(client, osNetworks.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
  networkList, err := osNetworks.ExtractNetworks(page)

  for _, n := range networkList {

  }

  return true, nil
})
List<Network> networks = networkApi.list().concat().toList();
client.getNetworks(function(err, networks) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your networks here
});
$networks = $networkingService->listNetworks();
// Not currently supported by this SDK
@client.networks
curl -X "GET" "https://dfw.networks.api.rackspacecloud.com/v2.0/networks" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -H "Accept: application/json" | python -m json.tool

Create Subnet#

To create a subnet:

var subnetDefinition = new SubnetCreateDefinition(network.Id, IPVersion.IPv4, "{cidr}}");
var subnet = await networkService.CreateSubnetAsync(subnetDefinition);
opts := osSubnets.CreateOpts{
  Name: "MyNewSubnet",
  CIDR: "192.168.101.1/24",
  NetworkID: network.ID,
  IPVersion: osSubnets.IPv4,
}

subnet, err := subnets.Create(client, opts).Extract()
SubnetApi subnetApi = neutronApi.getSubnetApi("{region}");

Subnet subnet = subnetApi.create(Subnet.createBuilder(network.getId(), "192.168.101.1/24")
    .ipVersion(4)
    .name("MyNewSubnet")
    .build());
client.createSubnet({
  name: 'MyNewSubnet',
  cidr: '192.168.101.1/24',
  networkId: network.id,
  ipVersion: 4
}, function(err, subnet) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your subnet here
});
$subnet = $networkingService->createSubnet(array(
    'name'      => 'MyNewSubnet',
    'cidr'      => '192.168.101.1/24',
    'networkId' => $network->getId(),
    'ipVersion' => 4
));
// Not currently supported by this SDK
@subnet = @client.subnets.new({
  :name       => "MyNewsubnet",
  :cidr       => "192.168.101.1/24",
  :network_id => @network.id,
  :ip_version => "4"
}).save
curl -X "POST" "https://dfw.networks.api.rackspacecloud.com/v2.0/subnets" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -d $'{
    "subnet": {
      "name": "MyNewSubnet",
      "cidr": "192.168.101.1/24",
      "network_id": "'$NETWORK_ID'",
      "ip_version": "4"
    }
  }' \
  -H "Accept: application/json" | python -m json.tool

List Subnets#

To list subnets:

IPage<Subnet> subnets = networkService.ListSubnetsAsync();
err := subnets.List(client, osSubnets.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
  subnetList, err := osSubnets.ExtractSubnets(page)

  for _, subnet := range subnetList {

  }

  return true, nil
})
List<Subnet> subnets = subnetApi.list().concat().toList();
client.getSubnets(function(err, subnets) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your subnets here
});
$subnets = $networkingService->listSubnets();
// Not currently supported by this SDK
@client.subnets
curl -X "GET" "https://dfw.networks.api.rackspacecloud.com/v2.0/subnets" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -H "Accept: application/json" | python -m json.tool

Create Port#

To create a port:

var portDefinition = new PortCreateDefinition(network.Id)
{
    DeviceId = "{device-id}",
    DeviceOwner = "{device-owner}"
};
var port = await networkService.CreatePortAsync(portDefinition);
opts := osPorts.CreateOpts{
  NetworkID: network.ID,
  Name: "MyNewPort",
}

port, err := ports.Create(client, opts).Extract()
PortApi portApi = neutronApi.getPortApi("{region}");
Port port = portApi.create(Port.createBuilder(network.getId())
    .name("MyNewPort")
    .build());
client.createPort({
  name: 'MyNewPort',
  networkId: network.id
}, function(err, port) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your port here
});
$port = $networkingService->createPort(array(
    'name'      => 'MyNewPort',
    'networkId' => $network->getId()
));
// Not currently supported by this SDK
@port = @client.ports.new({:name => "MyNewPort", :network_id => @network.id}).save
curl -X "POST" "https://dfw.networks.api.rackspacecloud.com/v2.0/ports" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -d $'{"port": {"name": "NewPort"}, "network": "$NETWORK_ID"} ' \
  -H "Accept: application/json" | python -m json.tool

List Ports#

To list ports:

IPage<Port> ports = networkService.ListPortsAsync();
err := ports.List(client, osPorts.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
  portList, err := osPorts.ExtractPorts(page)

  for _, port := range portList {

  }

  return true, nil
})
List<Port> ports = portApi.list().concat().toList();
client.getPorts(function(err, ports) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your ports here
});
$ports = $networkingService->listPorts();
// Not currently supported by this SDK
@client.ports
curl -X "GET" "https://dfw.networks.api.rackspacecloud.com/v2.0/ports" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -H "Accept: application/json" | python -m json.tool

Create Security Group#

To create a Security Group:

// Not currently supported by this SDK
opts := osGroups.CreateOpts{
  Name: "MyNewSecurityGroup",
  Description: "MyRules",
}

secgroup, err := groups.Create(client, opts).Extract()
SecurityGroupApi securityGroupApi = neutronApi.getSecurityGroupApi("{region}").get();
SecurityGroup securityGroup = securityGroupApi.create(SecurityGroup.createBuilder()
    .name("MyNewSecurityGroup")
    .description("MyRules")
    .tenantId("{tenantID}")
    .build());
client.createSecurityGroup({
  name: 'MyNewSecurityGroup',
  description: 'MyRules',
  tenantId: '{tenantID}'
}, function(err, securityGroup) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your security group here
});
$securityGroup = $networkingService->createSecurityGroup(array(
    'name' => 'MySecurityGroup',
    'description' => 'MyRules',
    'tenantId' => '{tenantID}'
));
// Not currently supported by this SDK
@security_group = @client.security_groups.new({
  :name        => "MySecurityGroup",
  :description => "MyRules",
  :tenant_id   => "{tenantID}"
}).save
curl -X "POST" "https://dfw.networks.api.rackspacecloud.com/v2.0/security-groups" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -d $'{
  "security_group": {
    "name": "MyNewSecurityGroup",
    "description": "MyRules",
    "tenant_id": "$TENANT_ID"
  }
}' \
-H "Accept: application/json" | python -m json.tool

Create Security Group Rule#

To create a Security Group Rule:

// Not currently supported by this SDK
opts := osRules.CreateOpts{
  Direction: osRules.DirEgress,
  EtherType: osRules.Ether4,
  SecGroupID: secgroup.ID,
}

secrule, err := rules.Create(client, opts).Extract()
Rule rule = securityGroupApi.create(Rule.createBuilder(RuleDirection.INGRESS, securityGroup.getId())
    .ethertype(RuleEthertype.IPV4)
    .build());
client.createSecurityGroupRule({
  direction: 'ingress',
  ethertype: 'IPv4',
  securityGroupId: securityGroup.id
}, function(err, securityGroupRule) {
  if (err) {
    // TODO handle as appropriate
    return;
  }

  // TODO use your security group rule here
});
$securityGroupRule = $networkingService->createSecurityGroupRule(array(
    'direction'       => 'ingress',
    'ethertype'       => 'IPv4',
    'securityGroupId' => $securityGroup->getId()
));
// Not currently supported by this SDK
@rule = @client.security_group_rules.new({
  :direction         => "ingress",
  :ethertype         => "IPv4",
  :security_group_id => @security_group.id
}).save
curl -X "POST" "https://dfw.networks.api.rackspacecloud.com/v2.0/security-group-rules" \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-type: application/json" \
  -d $'{
  "security_group_rule": {
  "direction": "ingress",
  "security_group_id": "$SECURITY_GROUP_ID"
  }
}' \
-H "Accept: application/json" | python -m json.tool

More information#

This quickstart is intentionally brief, demonstrating only a few basic operations. To learn more about interacting with Rackspace cloud services, explore the following sites: