Community

Python SDK - Create Internet Access

Hello community,

I'm currently writing a Python script that creates a data center with a single host in it. The host is based on an image that I manually created earlier (Debian 8 Jessie).

But: How can I create an Internet Access for the given host? What do I have to add to the Python script in order to automatically attach the host to it, so I can access the host via a public IP?

Thanks and best regards.

 
  • **bold**
  • _italics_
  • `code`
  • ```code block```
  • # Heading 1
  • ## Heading 2
  • > Quote
 

Hi Eric,

thank you very much for your extensive answer. The creation of a data center and a server that is connected to the internet now works well:

1 create_datacenter.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

from pprint import pprint
from getpass import getpass
from profitbricks.client import ProfitBricksService, Datacenter, Volume, Server, LAN, NIC, FirewallRule

USER = 'YOUR_USERNAME'
KEY = getpass("Password for user '%s': " % USER)
client = ProfitBricksService(username=USER, password=KEY)

lan1 = LAN(
    name='WAN',
    public=True
    )

lans = [lan1]

d = Datacenter(
    name='Devops Testing DC',
    description='Devops Testing DC',
    location='de/fra',
    lans=lans,
    )

response = client.create_datacenter(datacenter=d)
pprint(response)

2 get_datacenters (to find out datacenter_id)

#!/usr/bin/python
# -*- coding: utf-8 -*-

from pprint import pprint
from getpass import getpass
from profitbricks.client import ProfitBricksService

USER = 'YOUR_USERNAME'
KEY = getpass("Password for user '%s': " % USER)
client = ProfitBricksService(username=USER, password=KEY)

datacenters = client.list_datacenters()
pprint(datacenters)

3 create_server.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

from pprint import pprint
from getpass import getpass
from profitbricks.client import ProfitBricksService, Datacenter, Volume, Server, LAN, NIC, FirewallRule

USER = 'YOUR_USERNAME'
KEY = getpass("Password for user '%s': " % USER)
client = ProfitBricksService(username=USER, password=KEY)

IMAGE_ID ="YOUR_IMAGE_ID"
attach_volumes = [IMAGE_ID]
DC_ID = raw_input("Please enter datacenter_id: ")

fwrule1 = FirewallRule(
    name='Open SSH port',
    protocol='TCP',
    port_range_start=22,
    port_range_end=22
    )

fwrule2 = FirewallRule(
    name='Allow PING',
    protocol='ICMP',
    icmp_type=8,
    icmp_code=0
    )

fw_rules = [fwrule1, fwrule2]

nic1 = NIC(
    name='WAN',
    dhcp='true',
    lan=1,
    firewall_active=True,
    firewall_rules=fw_rules
    )

nic2 = NIC(
    name='LAN',
    ips=['10.2.3.4'],
    lan=2,
    firewall_active=True,
    firewall_rules=fw_rules
    )

nics = [nic1, nic2]

volume1 = Volume(
    name='sys_host1',
    size=20,
    image=IMAGE_ID,
    imagepasswd=False,
    bus='VIRTIO'
    )

volumes = [volume1]

server1 = Server(
    name='host1',
    ram=1024,
    cores=1,
    create_volumes=volumes,
    nics=nics
    )

servers = [server1]

response = client.create_server(datacenter_id=DC_ID, server=server1)
pprint(response)

Is there a way to find out the IP address of server1 with the Python SDK, so I don't have to login to the Data Center Designer?

Thanks again!

Hello,

The short answer is that you need to create a LAN inside the data center that has the "public" property set to "true". Then connect the NIC of your server to that LAN.

In testing this out with the Python SDK, I was not able to get this done all in one request. It seemed possible to do it in one like this.

from profitbricks.client import ProfitBricksService
from profitbricks.client import Datacenter, Volume, Server
from profitbricks.client import LAN, NIC
import json

client = ProfitBricksService(username='YOUR_USERNAME', password='YOUR_PASSWORD')

lan1 = LAN(
    name='Wan1',
    public=True
    )

the_lans = [lan1]

nic1 = NIC(
    name='Nic1',
    dhcp='true',
    lan=1
    )

the_nics = [nic1]

volume1 = Volume(
    name='Volume1',
    size=30,
    image='d35322b4-0f50-11e6-ab6b-52540005ab80',
    bus='VIRTIO'
    )

the_volumes = [volume1]

server1 = Server(
    name='Server1',
    ram=2048,
    cores=1,
    nics=the_nics,
    create_volumes=the_volumes
    )

the_servers = [server1]

d = Datacenter(
    name='PythonTest',
    description='Python Test',
    location='us/las',
    lans=the_lans,
    servers=the_servers
    )

response = client.create_datacenter(datacenter=d)

print json.dumps(response, indent=2, sort_keys=True)

However, "nic1" did not end up getting connected to "lan1", possibly due to a timing issue with "lan1" not being provisioned before "nic1".

Therefore, it seemed more reliable to approach the issue by creating a data center with a public lan first, then making a second call using the ID of the provisioned data center to create the server and NIC.

from profitbricks.client import ProfitBricksService
from profitbricks.client import Datacenter, LAN
import json

client = ProfitBricksService(username='YOUR_USERNAME', password='YOUR_PASSWORD')

lan1 = LAN(
    name='Wan1',
    public=True
    )

the_lans = [lan1]

d = Datacenter(
    name='PythonDC3',
    description='Python DC 3',
    location='us/las',
    lans=the_lans,
    )

response = client.create_datacenter(datacenter=d)

print json.dumps(response, indent=2, sort_keys=True)

And then when that is complete - get the data center ID and run:

from profitbricks.client import ProfitBricksService
from profitbricks.client import Datacenter, Volume, Server, NIC
import json

client = ProfitBricksService(username='YOUR_USERNAME', password='YOUR_PASSWORD')

dcid = 'YOUR_DATA_CENTER_ID'

volume1 = Volume(
    name='Volume1',
    size=32,
    image='YOUR_IMAGE_ID',
    bus='VIRTIO'
    )

the_volumes = [volume1]

nic1 = NIC(
    name='nic1',
    dhcp='true',
    lan=1,
    firewall_active=False
    )

the_nics = [nic1]

i = Server(
    name='Server1',
    ram=2048,
    cores=1,
    create_volumes=the_volumes,
    nics=the_nics
    )

response = client.create_server(datacenter_id=dcid, server=i)

print json.dumps(response, indent=4, sort_keys=True)

The end result is a server with a public IP address assigned by DHCP.

Eric

Hello,

I encountered this 'private internet' issue too, so I'd like to share my solution.

If you want to create a data center with a single host, that has public internet access, you can start with what Eric has tried first: Specify LAN, NIC, volume, server, and use that in creating your data center in one request. If that request is finished, you only have to update your LAN by

response = client.update_lan(dc_id, nic1.lan, public=True)
# wait for request to end

in the same script. Here, dc_id is the data center's UUID, and nic1.lan refers to the LAN-ID used for nic1.

One look behind the scenes:

The call of create_datacenter() is a transaction, that includes sub tasks for creating server, volume, nic and lan. You can get and print out the request to have a look at it.

What happens is that the server is created first, which includes creating volumes and NICs. The LAN is queued for creation after the server. But the NIC itself refers to lan1 as you named it, and so this is created too at this point. The default for new LANs is to be private, so at this point we get a server with a NIC connected to private LAN #1.

Unfortunately, the second sub task for creating the LAN seems to be a bit lazy: Since LAN #1 already exists, this sub task simply does nothing. Although it should be clear, that public=True should override the current private setting.

Hope that helped a bit

Jürgen

Glad to hear that it was helpful. Thank you to Jürgen for providing the update_lan example and extra "behind the scenes" info!

Regarding finding out what the assigned IP address is, that information is available in the output of get_nic, which needs to be passed the ID for the data center, server, and nic. Here is a code snipped which will return all the data centers, select one based on its "name, then return a list of servers in that data center, select one based on its "name", and then return a list of nics associated with that server, then select one nic based on its "name", finally using the three IDs to query the specific NIC for its IP address.

from profitbricks.client import ProfitBricksService
from profitbricks.client import Datacenter, Server, NIC

client = ProfitBricksService(username='username@domain.tld', password='password')

the_dcs = client.list_datacenters()

for dc in the_dcs['items']:
    print dc['properties']['name']
    print dc['id']
    if dc['properties']['name'] == 'PythonDC3':
            dcid = dc['id']

print "\n Our data center id is: ", dcid, "\n"

the_servers = client.list_servers(datacenter_id=dcid)

for server in the_servers['items']:
    print server['properties']['name']
    print server['id']
    if server['properties']['name'] == 'Server1':
            serverid = server['id']

print "\n Our server id is: ", serverid, "\n"

the_nics = client.list_nics(datacenter_id=dcid, server_id=serverid)

for nic in the_nics['items']:
    print nic['properties']['name']
    print nic['id']
    if nic['properties']['name'] == 'nic1':
            nicid = nic['id']

print "\n Our nic id is: ", nicid, "\n"

response = client.get_nic(datacenter_id=dcid, server_id=serverid, nic_id=nicid)

print "\n The first IP address assigned to the NIC is: ", response['properties']['ips'][0]

Hello again,

thank you very much. Now I have a script that creates a data center, waits for the requests completion, then creates a server and finally returns the public IP adress I can connect to. Thanks again!