Von Null zum Helden mit der K5 OpenStack IaaS API (Python 2.7X)
2017-01-27
Machine-translated from English. Read the English original
Heute werde ich alle Schritte durchgehen, die notwendig sind, um einen Server auf der IaaS-Plattform von Fujitsu K5 ausschließlich mit OpenStack-basierten API-Aufrufen bereitzustellen. Ich habe Python 2.7X zu Demonstrationszweilen gewählt, da Openstack selbst hauptsächlich darauf aufgebaut ist. Es sollte jedoch einfach genug sein, die API-Aufrufe in eine andere Skriptsprache zu portieren, da ich keine Zwischenbibliotheken verwende – meine HTTP-Anfragen kommunizieren direkt mit den K5-Endpunkten.
Voraussetzungen für dieses Tutorial:
- Ein gültiges K5-Konto mit Zugriff auf ein Projekt oder ein gültiges OpenStack-Konto, das Keystone V3 mit Domains verwendet und Zugriff auf ein Projekt hat.
- Das Konto muss ein Projektadministrator sein – d. h. Sie müssen die Rollen besitzen, um Ressourcen innerhalb des Projekts zu erstellen und zu löschen.
- Ein Windows- oder Linux-System mit installierter Python 2.7X sowie dem Requests-Modul.
Schritte zum Erstellen eines Servers mit der OpenStack-API
Sobald Sie die oben genannten Voraussetzungen erfüllt haben, werfen wir einen kurzen Blick darauf, was zum Erstellen eines Servers in einem Projekt innerhalb von OpenStack erforderlich ist.

Im weiteren Verlauf dieses Tutorials werde ich jeden API-Aufruf Schritt für Schritt durchgehen und erläutern, was übermittelt und was zurückgegeben wird.

Schritt 1 – Holen Sie sich einen gültigen K5-Token, der auf das Projekt beschränkt ist, in dem Sie den Server bereitstellen möchten. Hier benötigen Sie Ihre K5/OpenStack-Anmeldeinformationen. Diese werden bei der ersten Anfrage nach einem projektbeschränkten Token wie folgt übermittelt:
def get_scoped_token(adminUser, adminPassword, contract, projectid, region):
identityURL = 'https://identity.' + region + \
'.cloud.global.fujitsu.com/v3/auth/tokens'
try:
response = requests.post(identityURL,
headers={'Content-Type': 'application/json',
'Accept': 'application/json'},
json={"auth":
{"identity":
{"methods": ["password"], "password":
{"user":
{"domain":
{"name": contract},
"name": adminUser,
"password": adminPassword
}}},
"scope":
{"project":
{"id": projectid
}}}})
return response
except:
return 'Regional Project Token Scoping Failure'
def main():
k5token = get_scoped_token(adminUser, adminPassword, contract, demoProjectAid, region).json()
# print the output for demonstartion purposes
pprint.pprint(k5token)
Wenn gültige Anmeldeinformationen übermittelt wurden, erhalten Sie ein JSON-Antwortobjekt, das die in seinem OpenStack-Keystone-Katalog registrierten K5-Endpunkte wie folgt enthält:
{u'token': {u'catalog': [{u'endpoints': [{u'id': u'b506af0e016a4b5fb592f196da569a41',
u'interface': u'public',
u'name': u'objectstorage',
u'region': u'uk-1',
u'url': u'https://objectstorage.uk-1.cloud.global.fujitsu.com/v1/AUTH_7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'024329e4fde148e58ecd90b7d9872438',
u'type': u'object-store'},
{u'endpoints': [{u'id': u'0419c448001845af8f6828cf49745e72',
u'interface': u'public',
u'name': u'keymanagement',
u'region': u'uk-1',
u'url': u'https://keymanagement.uk-1.cloud.global.fujitsu.com/v1'}],
u'id': u'07f309b0ef9d42758ea4de47bdca9c32',
u'type': u'keystore'},
{u'endpoints': [{u'id': u'e1cc93936fb94cdbadc20f17c4ad3140',
u'interface': u'public',
u'name': u'certificate',
u'region': u'uk-1',
u'url': u'https://certificate.uk-1.cloud.global.fujitsu.com/v1'}],
u'id': u'0bd9a971e97d4c15af6b94311e4e9c15',
u'type': u'certificate'},
{u'endpoints': [{u'id': u'c3ee708a6ae24ddf92c078526c36a446',
u'interface': u'public',
u'name': u'orchestration',
u'region': u'uk-1',
u'url': u'https://orchestration.uk-1.cloud.global.fujitsu.com/v1/7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'0dafa2a9240c41268c37818979769c88',
u'type': u'orchestration'},
{u'endpoints': [{u'id': u'ba9061d324954b1a9f6b1c1f5d4a5c5e',
u'interface': u'public',
u'name': u'blockstorage',
u'region': u'uk-1',
u'url': u'https://blockstorage.uk-1.cloud.global.fujitsu.com/v1/7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'0ec640e57e4d4374841d2ab7b292f2c2',
u'type': u'volume'},
{u'endpoints': [{u'id': u'169bcb3f92384f709232864f4d5304eb',
u'interface': u'public',
u'name': u'loadbalancing',
u'region': u'uk-1',
u'url': u'https://loadbalancing.uk-1.cloud.global.fujitsu.com'}],
u'id': u'15ef761fa00a438985213aec7b6fb18a',
u'type': u'loadbalancing'},
{u'endpoints': [],
u'id': u'1a53a2e82370422d90174c4acf585ea9',
u'type': u'dwh'},
{u'endpoints': [],
u'id': u'1b35fa74ae0e46ebbc2014f976fec0e1',
u'type': u'contract'},
{u'endpoints': [],
u'id': u'253096ed430c49c48c9f3549e867b538',
u'type': u'appplatform'},
{u'endpoints': [{u'id': u'e26ad89a682d4c8f8a71c9e76cd785b4',
u'interface': u'public',
u'name': u'compute-w',
u'region': u'uk-1',
u'url': u'https://compute-w.uk-1.cloud.global.fujitsu.com'}],
u'id': u'327c11710f184555b43bc6fdfc47626b',
u'type': u'compute-w'},
{u'endpoints': [],
u'id': u'3435ad7a1da04b1cb2e249665529eb51',
u'type': u'notification'},
{u'endpoints': [{u'id': u'f70e51b9a6a74a87a4c7055b8df8bedf',
u'interface': u'public',
u'name': u'compute',
u'region': u'uk-1',
u'url': u'https://compute.uk-1.cloud.global.fujitsu.com/v2/7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'3e19093f50cc4590973c8953e2c327f9',
u'type': u'compute'},
{u'endpoints': [{u'id': u'c46b5ec51ab04402a9ffd8177743ba6f',
u'interface': u'public',
u'name': u'queue',
u'region': u'uk-1',
u'url': u'https://queue.uk-1.cloud.global.fujitsu.com'}],
u'id': u'4a9ab69b74ec4948a0a6958177d30387',
u'type': u'queue'},
{u'endpoints': [{u'id': u'071ee50be4b341558e37f84abac47d02',
u'interface': u'public',
u'name': u'autoscale',
u'region': u'uk-1',
u'url': u'https://autoscale.uk-1.cloud.global.fujitsu.com/autoscale_schedulers'}],
u'id': u'4f158b2836434c7ca6ee47e40a3ee56c',
u'type': u'autoscale'},
{u'endpoints': [{u'id': u'6ac15657fbc548d7ab2ed986b8d94192',
u'interface': u'public',
u'name': u'telemetry',
u'region': u'uk-1',
u'url': u'https://telemetry.uk-1.cloud.global.fujitsu.com'}],
u'id': u'54ee7596f0e1433cb8db6201be2cf772',
u'type': u'metering'},
{u'endpoints': [],
u'id': u'5954129d136e4a76b7cd6f3d1f3808b5',
u'type': u'cdn'},
{u'endpoints': [],
u'id': u'5a252878ffd7402498b6b74b575a899a',
u'type': u'oss'},
{u'endpoints': [{u'id': u'2d600a5de6ec42c6a5eab7b519832d87',
u'interface': u'public',
u'name': u'rolemanagement',
u'region': u'uk-1',
u'url': u'https://rolemanagement.uk-1.cloud.global.fujitsu.com/v1'}],
u'id': u'5bc90099f0ad490c811239a6a3a8f853',
u'type': u'rolemanagement'},
{u'endpoints': [{u'id': u'768450282d5546409395d2cb35502dad',
u'interface': u'public',
u'name': u'compute-b',
u'region': u'uk-1',
u'url': u'https://compute-b.uk-1.cloud.global.fujitsu.com'}],
u'id': u'65f754202b6049578e9a292a801e28f7',
u'type': u'compute-b'},
{u'endpoints': [{u'id': u'675910513a7e466c84c39c5ca9445b81',
u'interface': u'public',
u'name': u'networking',
u'region': u'uk-1',
u'url': u'https://networking.uk-1.cloud.global.fujitsu.com'}],
u'id': u'6cf37e33dc7140b9b032faabfa53a53e',
u'type': u'network'},
{u'endpoints': [],
u'id': u'7426c97af5174c1abdb8b84ba02227ce',
u'type': u'dns'},
{u'endpoints': [{u'id': u'6976cbeed14c464da15c13e949b41607',
u'interface': u'public',
u'name': u'database',
u'region': u'uk-1',
u'url': u'https://database.uk-1.cloud.global.fujitsu.com/v1.0/7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'75c0280f15844d7a9eb22b1ad5a978e8',
u'type': u'database'},
{u'endpoints': [{u'id': u'db15a7126d4a4f1f81903bb4d56be32b',
u'interface': u'admin',
u'name': u'identity',
u'region': u'uk-1',
u'url': u'https://identity.uk-1.cloud.global.fujitsu.com/v2.0'}],
u'id': u'79066fe949064550930a61b33a49eb53',
u'type': u'identity'},
{u'endpoints': [],
u'id': u'804190a423804019aab8fd934db0086e',
u'type': u'intdns'},
{u'endpoints': [],
u'id': u'8d364df08cbc4d7188f0cf83744b0336',
u'type': u'invoicing'},
{u'endpoints': [],
u'id': u'9674ae5917af401397071c028ff33b68',
u'type': u'catalog'},
{u'endpoints': [{u'id': u'fd6g35fgknrzumut7bx6p6bwzehkfhrz',
u'interface': u'public',
u'name': u'software',
u'region': u'uk-1',
u'url': u'https://software.uk-1.cloud.global.fujitsu.com/v1.0'}],
u'id': u'9760973e49b04b00b41e60c180a80562',
u'type': u'software'},
{u'endpoints': [{u'id': u'8c4ace3bbbd44883b5762a9ad8432a46',
u'interface': u'public',
u'name': u'blockstoragev2',
u'region': u'uk-1',
u'url': u'https://blockstorage.uk-1.cloud.global.fujitsu.com/v2/7015d1478a4c4bd7b970215d7b0260dd'}],
u'id': u'9bf82d0466714eee86e304ab3301aec9',
u'type': u'volumev2'},
{u'endpoints': [],
u'id': u'a2b90094346c48deabb9ca645bacf588',
u'type': u'dnsadmin'},
{u'endpoints': [{u'id': u'225257ec50ef47668185587cc6edb95d',
u'interface': u'public',
u'name': u'vmimport',
u'region': u'uk-1',
u'url': u'https://vmimport.uk-1.cloud.global.fujitsu.com'}],
u'id': u'c73fa07c3b604b4f89d5a2b9c4621cf2',
u'type': u'vmimport'},
{u'endpoints': [{u'id': u'27dc2bba1c5d4a14b68657fc8fdd4e3e',
u'interface': u'public',
u'name': u'identityv3',
u'region': u'uk-1',
u'url': u'https://identity.uk-1.cloud.global.fujitsu.com/v3'}],
u'id': u'cc6f50d496884ef0a751acb2e1eceedd',
u'type': u'identityv3'},
{u'endpoints': [{u'id': u'06fbcf8235434f23a08faed03b4af9ac',
u'interface': u'public',
u'name': u'appmanagement',
u'region': u'uk-1',
u'url': u'https://applicationmanagement.uk-1.cloud.global.fujitsu.com'}],
u'id': u'ce2f6bbe7a9f446b82d63725bd7bb484',
u'type': u'appmanagement'},
{u'endpoints': [],
u'id': u'd07aa581c0734b6bb85cd496115b5110',
u'type': u'nosql'},
{u'endpoints': [],
u'id': u'd2f57dcae4c84466ac357220ff3d8900',
u'type': u'baremetal'},
{u'endpoints': [],
u'id': u'd4601f51af8f43f3b0e3409e4cbac690',
u'type': u'mail'},
{u'endpoints': [{u'id': u'bf356065e45349a5bde5e043c95a1923',
u'interface': u'public',
u'name': u'networking-ex',
u'region': u'uk-1',
u'url': u'https://networking-ex.uk-1.cloud.global.fujitsu.com'}],
u'id': u'd4937aa1275c41378bf2ae1dbe829c68',
u'type': u'networking-ex'},
{u'endpoints': [{u'id': u'dc2ebf9d6fc04f1facc263a733cf754d',
u'interface': u'public',
u'name': u'global-identity',
u'region': u'jp-east-1',
u'url': u'https://identity.gls.cloud.global.fujitsu.com/v3'}],
u'id': u'e74b9c29d6504f10a8fb8e1495f3f5c6',
u'type': u'global-identity'},
{u'endpoints': [{u'id': u'a832d640886b4ef89027339a2edf8fcd',
u'interface': u'public',
u'name': u'image',
u'region': u'uk-1',
u'url': u'https://image.uk-1.cloud.global.fujitsu.com'}],
u'id': u'ea850dab0e964e12a9f66787ee8623ae',
u'type': u'image'},
{u'endpoints': [],
u'id': u'f1302a2477bf492bb3e867952175974a',
u'type': u'billing'},
{u'endpoints': [{u'id': u'e8bde8fe61a14a88b414e5568fc17201',
u'interface': u'public',
u'name': u'import-export',
u'region': u'uk-1',
u'url': u'https://import-export.uk-1.cloud.global.fujitsu.com'}],
u'id': u'fc302725919645199373077fa299fc6e',
u'type': u'import-export'}],
u'expires_at': u'2017-01-27T13:53:55.982381Z',
u'extras': {},
u'issued_at': u'2017-01-27T10:53:55.982425Z',
u'methods': [u'password'],
u'project': {u'domain': {u'id': u'3256d41b17014d5c99727993d6fca821',
u'name': u'YssmW1yI'},
u'id': u'7015d1478a4c4bd7b970215d7b0260dd',
u'name': u'Project_A'},
u'roles': [{u'id': u'0739580a550d4a0f9c78f45a9f038c05',
u'name': u'cpf_systemowner'},
{u'id': u'3af119c426a742999e7890f6d1f70b36',
u'name': u'cpf_admin'}],
u'user': {u'domain': {u'id': u'3256d41b17014d5c99727993d6fca821',
u'name': u'YssmW1yI'},
u'id': u'03758af9df694db784c3547ab8217abb',
u'name': u'landg'}}}
Diese Informationen sind sehr wichtig, da Sie auf diese Weise Ihre verschiedenen Endpunkte für die Dienste erkennen können, die Sie nutzen möchten, wenn Sie K5 vollständig automatisieren möchten.
Hinweis: Endpunkte, deren Namen ein Suffix „-ex“ haben, sind die OpenStack-erweiterten Endpunkte. Diese Endpunkte enthalten die zusätzlichen Funktionen, die Fujitsu zu K5 hinzugefügt hat, über die Standard-OpenStack-Funktionen hinaus.
Was fehlt also in diesem Bild … wo ist der Token? Keine Sorge, er wird tatsächlich im Header der Antwort in einer Variable namens „X-Subject-Token“ gespeichert. Zum Beispiel –
# print the K5 poject scoped token
print "\n\n K5 Project Scoped Token :", k5token.headers['X-Subject-Token'], "\n"
… enthüllt einen Token, der übrigens 2 Stunden gültig ist, wie folgt ..
K5 Project Scoped Token : f5b72cd06517447fae59360f6deba7d8
Dieser Token muss bei allen nachfolgenden K5-API-Aufrufen im Header übermittelt werden, um Ihre Authentifizierungs- und Autorisierungsberechtigungen für jede Dienstanfrage bereitzustellen.
Der Standard-OpenStack-Neutron-API-Endpunkt kann aus der obigen Antwort extrahiert werden, indem man nach dem Endpunkt mit dem Namen „networking“ sucht. Ich habe die folgende Funktion verwendet, um die URL des gesuchten Endpunkts zurückzugeben –
def get_endpoint(k5token, endpoint_type):
# list the endpoints
for ep in k5token.json()['token']['catalog']:
if len(ep['endpoints'])>0:
# if this is the endpoint that I'm looking for return the url
if endpoint_type == ep['endpoints'][0].get('name'):
#pprint.pprint(ep)
return ep['endpoints'][0].get('url')
Beispielsweise –
# list the networking endpoints
print get_endpoint(k5token,"networking")
wird den Neutron-API-Endpunkt zurückgeben, den ich benötige –
K5 Networking EndPoints :
https://networking.uk-1.cloud.global.fujitsu.com
Nun, da wir die notwendigen Token- und Endpunktdetails haben, fahren wir mit dem nächsten Schritt fort.

Schritt 2 – Erstellen Sie das Layer-2-Netzwerk. Der folgende Neutron-Aufruf erstellt ein K5-Layer-2-Subnetz mit den Eigenschaften, die Sie über die API wie folgt übermitteln:
def create_network(k5token, name, availability_zone):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/networks')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={'X-Auth-Token': token,
'Content-Type': 'application/json'},
json={
"network":
{
"name": name,
"admin_state_up": True,
"availability_zone": availability_zone
}
})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
Beispielsweise –
# Create a layer 2 virtual network
network = create_network(k5token, "demonet", "uk-1b")
print network
print network.json()
erzeugt –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/networks
{u'network': {u'status': u'ACTIVE', u'subnets': [], u'name': u'demonet', u'admin_state_up': True, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'availability_zone': u'uk-1b', u'shared': False, u'id': u'02fd7be4-b5f1-455c-8aea-37b299e85ddd'}}
Wir müssen die ID des neu erstellten Netzwerks erfassen, da wir sie im folgenden API-Aufruf verwenden werden –
network_id = network.json()['network'].get('id')
Nun erstellen wir unser Subnetz.

Schritt 3 – Erstellen Sie das Layer-3-Subnetz. Auch hier verwenden wir den Standard-Neutron-API-Aufruf und übermitteln die neu erstellte Netzwerk-ID an den Aufruf. Die verwendete Funktion sieht wie folgt aus –
def create_subnet(k5token, name, netid, cidr, az):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/subnets')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={'X-Auth-Token': token,
'Content-Type': 'application/json'},
json={
"subnet": {
"name": name,
"network_id": netid,
"ip_version": 4,
"cidr": cidr,
"availability_zone": az
}
})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
Und wenn sie wie folgt aufgerufen wird –
subnet = create_subnet(k5token, "demosubnet", network_id, "192.168.10.0/24", "uk-1b")
print subnet
print subnet.json()
subnet_id = subnet.json()['subnet'].get('id')
print subnet_id
erzeugt die folgende Antwort –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/subnets
{u'subnet': {u'name': u'demosubnet', u'enable_dhcp': True, u'availability_zone': u'uk-1b', u'network_id': u'1af9e3fe-4546-4b59-a5a5-10e48af5302a', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'dns_nameservers': [], u'allocation_pools': [{u'start': u'192.168.10.2', u'end': u'192.168.10.254'}], u'host_routes': [], u'ip_version': 4, u'gateway_ip': u'192.168.10.1', u'cidr': u'192.168.10.0/24', u'id': u'2322908f-cf58-4124-a273-86a33cc429b5'}}
2322908f-cf58-4124-a273-86a33cc429b5
Beachten Sie, dass wir nun auch die neue Subnetz-ID erfasst haben. Hoffentlich wird das Muster jetzt offensichtlich, während wir zum nächsten Schritt übergehen.

Schritt 4 – Erstellen Sie einen virtuellen Router. Auch hier arbeiten wir mit dem Neutron-Endpunkt von OpenStack und erstellen diesmal einen virtuellen Router. Die folgende Funktion wurde verwendet –
def create_router(k5token, name, availability_zone):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={'X-Auth-Token': token,
'Content-Type': 'application/json'},
json={
"router": {
"name": name,
"admin_state_up": True,
"availability_zone": availability_zone
}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
welche, wenn sie wie folgt aufgerufen wird –
# Create a layer 3 virtual router
router = create_router(k5token, "demorouter", "uk-1b")
print router
print router.json()
router_id = router.json()['router'].get('id')
print router_id
folgendes zurückgibt –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/routers
{u'router': {u'status': u'ACTIVE', u'external_gateway_info': None, u'name': u'demorouter', u'admin_state_up': True, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'availability_zone': u'uk-1b', u'id': u'0a0661a9-7e30-4f8e-904a-c4a9469d3fca'}}
0a0661a9-7e30-4f8e-904a-c4a9469d3fca
Auch hier erfassen wir die ID der neu erstellten Ressource – router_id.

Schritt 5 – Konfigurieren wir nun den Router. Zuerst setzen wir das externe Gateway mit dem folgenden Funktionsaufruf –
def update_router_gateway(k5token, router_id, network_id):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers/') + router_id
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.put(networkURL,
headers={'X-Auth-Token': token,
'Content-Type': 'application/json'},
json={
"router": {
"external_gateway_info": {
"network_id": network_id
}
}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
aus dem Skript-Body wie folgt aufgerufen –
# Add external gateway to router (extaz2 is the external network id for the external network in availability zone b)
router_gateway = update_router_gateway(k5token, router_id, extaz2)
print router_gateway
print router_gateway.json()
mit den folgenden Ergebnissen –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/routers/245a02e7-8b0e-4d1f-af6a-dfc07ed916e0
{u'router': {u'status': u'ACTIVE', u'external_gateway_info': {u'network_id': u'd730db50-0e0c-4790-9972-1f6e2b8c4915', u'enable_snat': True}, u'name': u'demorouter', u'admin_state_up': True, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'availability_zone': u'uk-1b', u'routes': [], u'id': u'245a02e7-8b0e-4d1f-af6a-dfc07ed916e0'}}

Schritt 6 – Wir „stecken“ nun unser virtuelles Netzwerk in unseren virtuellen Router mit diesem Funktionsaufruf –
def add_interface_to_router(k5token, router_id, subnet_id):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers/') + router_id + '/add_router_interface'
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.put(networkURL,
headers={'X-Auth-Token': token,
'Content-Type': 'application/json'},
json={
"subnet_id": subnet_id})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
welcher wie folgt aufgerufen wird –
# Plug new network subnet into the router
router_interface = add_interface_to_router(k5token, router_id, subnet_id)
print router_interface
print router_interface.json()
mit der folgenden Ausgabe –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/routers/43e95138-9124-4e04-a5d4-ae5b90f4fded/add_router_interface
{u'subnet_id': u'16b59543-c303-4e33-9b96-b538625f40b2', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'port_id': u'1ba71079-288e-49b7-925d-fb31658bc9c6', u'id': u'43e95138-9124-4e04-a5d4-ae5b90f4fded', u'availability_zone': u'uk-1b'}
Dies schließt die Grundlagen der Netzwerkinfrastruktur ab.

Schritt 7 – Der Server benötigt eine Sicherheitsgruppe, die seinen Netzwerkschnittstellen zugewiesen werden soll, also erstellen wir diese nun zusammen mit den Regeln, die nur eingehende ssh-, tcp- und rdp-Protokolle zulassen.
Dieser API-Aufruf wurde verwendet, um die Sicherheitsgruppe zu erstellen –
def create_security_group(k5token, name, description):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/security-groups')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'},
json={
"security_group": {
"name": name,
"description": description
}
})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
welcher wie folgt aufgerufen wird –
# Create a new security group
security_group = create_security_group(k5token, "demosecuritygroup", "Demo Security Group Allows RDP, SSH and ICMP")
print security_group
print security_group.json()
security_group_id = security_group.json()['security_group'].get('id')
print security_group_id
mit folgender Ausgabe –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/security-groups
{u'security_group': {u'id': u'ae44389e-f884-4726-8bc3-ec3cbc7b876e', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'description': u'Demo Security Group Allows RDP, SSH and ICMP', u'security_group_rules': [{u'remote_group_id': None, u'direction': u'egress', u'protocol': None, u'ethertype': u'IPv6', u'port_range_max': None, u'security_group_id': u'ae44389e-f884-4726-8bc3-ec3cbc7b876e', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'port_range_min': None, u'remote_ip_prefix': None, u'id': u'55d5c3f1-3cf0-46c0-b876-6e89a1a1fc55'}, {u'remote_group_id': None, u'direction': u'egress', u'protocol': None, u'ethertype': u'IPv4', u'port_range_max': None, u'security_group_id': u'ae44389e-f884-4726-8bc3-ec3cbc7b876e', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'port_range_min': None, u'remote_ip_prefix': None, u'id': u'c83371a8-f217-4038-982a-0165df8e9f4f'}], u'name': u'demosecuritygroup'}}
ae44389e-f884-4726-8bc3-ec3cbc7b876e

Schritt 8 – Erstellen Sie unsere Sicherheitsgruppenregeln mit dem folgenden API-Aufruf –
def create_security_group_rule(k5token, security_group_id, direction, portmin, portmax, protocol):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/security-group-rules')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'},
json={
"security_group_rule": {
"direction": direction,
"port_range_min": portmin,
"ethertype": "IPv4",
"port_range_max": portmax,
"protocol": protocol,
"security_group_id": security_group_id
}
})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
wieder (ich weiß, repetitiv) wird der Aufruf wie folgt aufgerufen –
# Create security group rules
# allow rdp
rdp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "3389", "3389", "tcp")
print rdp_rule
print rdp_rule.json()
# allow ssh # allow rdp
ssh_rule = create_security_group_rule(k5token, security_group_id, "ingress", "22", "22", "tcp")
print ssh_rule
print ssh_rule.json()
# allow icmp
icmp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "0", "0", "icmp")
print icmp_rule
print icmp_rule.json()
mit der Ausgabe –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/security-group-rules
{u'security_group_rule': {u'remote_group_id': None, u'direction': u'ingress', u'remote_ip_prefix': None, u'protocol': u'tcp', u'ethertype': u'IPv4', u'port_range_max': 3389, u'security_group_id': u'778052d3-d9b8-4eee-9ddc-655f185729ff', u'port_range_min': 3389, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'id': u'7054f52e-b284-4f37-a859-e043dbb6393e'}}
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/security-group-rules
{u'security_group_rule': {u'remote_group_id': None, u'direction': u'ingress', u'remote_ip_prefix': None, u'protocol': u'tcp', u'ethertype': u'IPv4', u'port_range_max': 22, u'security_group_id': u'778052d3-d9b8-4eee-9ddc-655f185729ff', u'port_range_min': 22, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'id': u'f70815f8-ac23-43d9-b808-ebf8e12948a2'}}
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/security-group-rules
{u'security_group_rule': {u'remote_group_id': None, u'direction': u'ingress', u'remote_ip_prefix': None, u'protocol': u'icmp', u'ethertype': u'IPv4', u'port_range_max': 0, u'security_group_id': u'778052d3-d9b8-4eee-9ddc-655f185729ff', u'port_range_min': 0, u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'id': u'49bdf8b6-618c-4714-b112-7420d815cd83'}}

Schritt 9 – Holen wir uns einen Port aus unserem neuen Subnetz, der mit einem API-Aufruf wie diesem an den Server angehängt werden soll –
def create_port(k5token, name, network_id, security_group_id, availability_zone):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/ports')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={
'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'},
json={"port":
{"network_id": network_id,
"name": name,
"admin_state_up": True,
"availability_zone": availability_zone,
"security_groups":
[security_group_id]}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
aufgerufen wie folgt –
# Create a new port for the server
server_port = create_port(k5token, "demoserverport", network_id, security_group_id, "uk-1b")
print server_port
print server_port.json()
server_port_id = server_port.json()['port'].get('id')
print server_port_id
mit folgender Ausgabe –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/ports
{u'port': {u'status': u'DOWN', u'name': u'demoserverport', u'allowed_address_pairs': [], u'admin_state_up': True, u'network_id': u'bc491d0d-56c2-4706-b7b4-6e97029dbeaf', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'availability_zone': u'uk-1b', u'binding:vnic_type': u'normal', u'device_owner': u'', u'mac_address': u'fa:16:3e:60:d6:31', u'fixed_ips': [{u'subnet_id': u'bafdfc08-b55b-4a99-b1c9-2f43cf661a54', u'ip_address': u'192.168.10.2'}], u'id': u'f1db8672-2923-46fb-a65b-4f1e643f5a9e', u'security_groups': [u'7e35e0bc-6254-4ce6-9233-fce162db4a8e'], u'device_id': u''}}
f1db8672-2923-46fb-a65b-4f1e643f5a9e

Schritt 10 – Wir sind fast da. Das letzte Puzzleteil, bevor wir einen Server bereitstellen können, ist der SSH-Schlüssel. Die nächste Funktion erstellt einen SSH-Schlüssel für Sie – bitte stellen Sie sicher, dass Sie den privaten Schlüssel an einem sicheren Ort speichern. K5 speichert aus Designgründen nur die öffentlichen Schlüssel.
def create_keypair(k5token, keypair_name, availability_zone):
computeURL = unicode(get_endpoint(k5token, "compute")) + unicode('/os-keypairs')
print computeURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(computeURL,
headers={
'X-Auth-Token': token,
'Content-Type': 'application/json',
'Accept': 'application/json'},
json={
"keypair": {
"name": keypair_name,
"availability_zone": availability_zone
}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
aufgerufen auf diese Weise –
# Create ssh key pair that can be injected into the server
server_key = create_keypair(k5token, "demokeypair", "uk-1b")
print server_key
print server_key.json()
server_key_id = server_key.json()['keypair'].get('id')
print server_key_id
server_key_private = server_key.json()['keypair'].get('private_key')
print server_key_private
server_key_public = server_key.json()['keypair'].get('public_key')
print server_key_public
sollte erzeugen –
https://compute.uk-1.cloud.global.fujitsu.com/v2/7015d1478a4c4bd7b970215d7b0260dd/os-keypairs
{u'keypair': {u'public_key': u'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu6R92WdwAgPJrWiwkd+wdHQ61ZX/1PL+yVWUXZ86Of+sHhHFUN2vCj6YfzuqKNJaAYjvy6Mga6rT1VBNyoD5EPryaop7w/1GMzRdZ7UaAwtJnNezu8bG054BVpTJ6vspNYsEGZs0KpggsN5O0f0qa2inxq/jDGTy+Le1qWBaQqB33PPVsH6y8a2DgZmDp6n8BY1DTd32GQzprq7ARfWhNu3nNXYmjAjUe/F1H2z2FmkfTDGvs1Un8ETUdywK7Deh938Nqi7agT7ECYSvawlAjwiBILjx0EsERQJr02dRw/BsgbeLsWY50X3l76tmRaiNE95jDGgzovGDBwm8fIL9LQ== Generated by Nova\n', u'private_key': u'-----BEGIN RSA PRIVATE KEY-----\nMIIEoQIBAAKCAQEAu6R92WdwAgPJrWiwkd+wdHQ61ZX/1PL+yVWUXZ86Of+sHhHF\nUN2vCj6YfzuqKNJaAYjvy6Mga6rT1VBNyoD5EPryaop7w/1GMzRdZ7UaAwtJnNez\nu8bG054BVpTJ6vspNYsEGZs0KpggsN5O0f0qa2inxq/jDGTy+Le1qWBaQqB33PPV\nsH6y8a2DgZmDp6n8BY1DTd32GQzprq7ARfWhNu3nNXYmjAjUe/F1H2z2FmkfTDGv\ns1Un8ETUdywK7Deh938Nqi7agT7ECYSvawlAjwiBILjx0EsERQJr02dRw/BsgbeL\nsWY50X3l76tmRaiNE95jDGgzovGDBwm8fIL9LQIBIwKCAQBAVad9vRB1uCfjrt1z\n16o2jkAOtxXinHSczOJpPegT4qFpZS21U1H04kLpy1BIgqKELvMhPz5QzNrqDOd4\noT9ziT0r17VnxI0Y3sDwW1lgISCNi8iYJuUVWr6hV5WvppHJNvoXaGmoNCh3J6X+\n2nTxoDmF8ylGE/uIeYAc0JP5lYQfHpMkMwG1pLOLf6Eb7OZg752+Dp07jedPabYx\n1i/PIkozmslKbgGM3R2CmhoYEWMKpmoOnPlzb4blRcxCiopSWQuhlj/2EI0sE1hc\n6+NE6pbQ5ddsZmm4DvQTACfy/l8H444DvLOAU2zEOVIp5hkCLP4Yv6YBBjfClqWq\nE7YLAoGBAOE/6AqprnrKzaAcboSiOMW4oidUKFFe9heqJJC54LIqGFyl1qEeJAvt\nllr9DjVA1xY/PRrCtb3D8y5ZJXmHjiRmwT/3UWW/Y0Zy+RkewLbmr0X/jVjk75Ns\n6wTcHlW/6/GEj9ny2ed+kul8IKOH1CFtxEVjiaTGXPy1yvxGSezlAoGBANVCR/My\nkMh/v4JjoWkeqOuyMDqPYFohuO9c6zF6uY5GBtzOcWT/eUQI1i66x/S6Cf2DOd+b\nVZKbobIBUFL36r915MEbkeTe1eHV/dSSmIgfV63qjTnvMLx/QR8VMzIp8+XQz/4z\npfFx96nh45MY9U1fwY3gr5VZl7kEXLJbf5KpAoGBAK3Dlb8VLtPBBQZ8VUG++JiH\nHgEVCSjUOi+DQMdq0eiG35ftpZI70qodroC0le6RGvPnpCqWNG3RrPfeXrzWSRTE\nS++ERhtKf8ih1hqxUtY87ZxmDfQeUmpp9yEBk75+HGnbSmZNoMiGNtFfwWg1lQPY\nVZSdPkvpeu7VYhMRpr4PAoGAc8TlOuDvgskBj+zxORCk17iAlNF9csHZa/892Qgb\nlmCHYexpcVd8WCIN3tpsjCp6c62jEvyNihn4sRan8oaVYJ8Vx+plJHj3w71PR4LH\n1N3QgvurwF1GV7LLlIfZ9qkPX3/74cREI/wKGmSuvZE0tPl3s2tYAJ5ZrZSnWYIg\nrrMCgYBvNCvqchbyDrClZTDJqAm+dpMKAdhKABHpuQUqG3hI+3M/hvjCRmFvLPdZ\nD1LNYXX2xB695iXuwF0Ekyvlf0QajToswSrl3wF06osObJ3iGb1IMtfTmb++JL9d\ncKclHW55JWix70Be6/krDsR6CSGT8Q1DiAJDxYxlzlb496AJ8A==\n-----END RSA PRIVATE KEY-----\n', u'user_id': u'03758af9df694db784c3547ab8217abb', u'name': u'demokeypair', u'fingerprint': u'38:a1:83:52:fd:fa:81:a3:87:3b:01:fc:0f:f1:8a:86'}}
None
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAu6R92WdwAgPJrWiwkd+wdHQ61ZX/1PL+yVWUXZ86Of+sHhHF
UN2vCj6YfzuqKNJaAYjvy6Mga6rT1VBNyoD5EPryaop7w/1GMzRdZ7UaAwtJnNez
u8bG054BVpTJ6vspNYsEGZs0KpggsN5O0f0qa2inxq/jDGTy+Le1qWBaQqB33PPV
sH6y8a2DgZmDp6n8BY1DTd32GQzprq7ARfWhNu3nNXYmjAjUe/F1H2z2FmkfTDGv
s1Un8ETUdywK7Deh938Nqi7agT7ECYSvawlAjwiBILjx0EsERQJr02dRw/BsgbeL
sWY50X3l76tmRaiNE95jDGgzovGDBwm8fIL9LQIBIwKCAQBAVad9vRB1uCfjrt1z
16o2jkAOtxXinHSczOJpPegT4qFpZS21U1H04kLpy1BIgqKELvMhPz5QzNrqDOd4
oT9ziT0r17VnxI0Y3sDwW1lgISCNi8iYJuUVWr6hV5WvppHJNvoXaGmoNCh3J6X+
2nTxoDmF8ylGE/uIeYAc0JP5lYQfHpMkMwG1pLOLf6Eb7OZg752+Dp07jedPabYx
1i/PIkozmslKbgGM3R2CmhoYEWMKpmoOnPlzb4blRcxCiopSWQuhlj/2EI0sE1hc
6+NE6pbQ5ddsZmm4DvQTACfy/l8H444DvLOAU2zEOVIp5hkCLP4Yv6YBBjfClqWq
E7YLAoGBAOE/6AqprnrKzaAcboSiOMW4oidUKFFe9heqJJC54LIqGFyl1qEeJAvt
llr9DjVA1xY/PRrCtb3D8y5ZJXmHjiRmwT/3UWW/Y0Zy+RkewLbmr0X/jVjk75Ns
6wTcHlW/6/GEj9ny2ed+kul8IKOH1CFtxEVjiaTGXPy1yvxGSezlAoGBANVCR/My
kMh/v4JjoWkeqOuyMDqPYFohuO9c6zF6uY5GBtzOcWT/eUQI1i66x/S6Cf2DOd+b
VZKbobIBUFL36r915MEbkeTe1eHV/dSSmIgfV63qjTnvMLx/QR8VMzIp8+XQz/4z
pfFx96nh45MY9U1fwY3gr5VZl7kEXLJbf5KpAoGBAK3Dlb8VLtPBBQZ8VUG++JiH
HgEVCSjUOi+DQMdq0eiG35ftpZI70qodroC0le6RGvPnpCqWNG3RrPfeXrzWSRTE
S++ERhtKf8ih1hqxUtY87ZxmDfQeUmpp9yEBk75+HGnbSmZNoMiGNtFfwWg1lQPY
VZSdPkvpeu7VYhMRpr4PAoGAc8TlOuDvgskBj+zxORCk17iAlNF9csHZa/892Qgb
lmCHYexpcVd8WCIN3tpsjCp6c62jEvyNihn4sRan8oaVYJ8Vx+plJHj3w71PR4LH
1N3QgvurwF1GV7LLlIfZ9qkPX3/74cREI/wKGmSuvZE0tPl3s2tYAJ5ZrZSnWYIg
rrMCgYBvNCvqchbyDrClZTDJqAm+dpMKAdhKABHpuQUqG3hI+3M/hvjCRmFvLPdZ
D1LNYXX2xB695iXuwF0Ekyvlf0QajToswSrl3wF06osObJ3iGb1IMtfTmb++JL9d
cKclHW55JWix70Be6/krDsR6CSGT8Q1DiAJDxYxlzlb496AJ8A==
-----END RSA PRIVATE KEY-----
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu6R92WdwAgPJrWiwkd+wdHQ61ZX/1PL+yVWUXZ86Of+sHhHFUN2vCj6YfzuqKNJaAYjvy6Mga6rT1VBNyoD5EPryaop7w/1GMzRdZ7UaAwtJnNezu8bG054BVpTJ6vspNYsEGZs0KpggsN5O0f0qa2inxq/jDGTy+Le1qWBaQqB33PPVsH6y8a2DgZmDp6n8BY1DTd32GQzprq7ARfWhNu3nNXYmjAjUe/F1H2z2FmkfTDGvs1Un8ETUdywK7Deh938Nqi7agT7ECYSvawlAjwiBILjx0EsERQJr02dRw/BsgbeLsWY50X3l76tmRaiNE95jDGgzovGDBwm8fIL9LQ== Generated by Nova

Schritt 11 – Der, auf den wir alle gewartet haben, die Bereitstellung der virtuellen Maschine. Dafür werden Sie feststellen, dass ich zwei weitere Voraussetzungsparameter konfiguriert habe: die ID der Flavor (oder T-Shirt-Größe) der vCPU und des RAM der Instanz sowie die ID des Betriebssystem-Images, das wir verwenden werden. Der API-Aufruf sieht wie folgt aus –
def create_server_with_port(k5token, name, imageid, flavorid, sshkey_name, security_group_name, availability_zone, volsize, port_id):
computeURL = unicode(get_endpoint(k5token, "compute")) + unicode('/servers')
print computeURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(computeURL,
headers={'X-Auth-Token':token,'Content-Type': 'application/json','Accept':'application/json'},
json={"server": {
"name": name,
"security_groups":[{"name": security_group_name }],
"availability_zone":availability_zone,
"imageRef": imageid,
"flavorRef": flavorid,
"key_name": sshkey_name,
"block_device_mapping_v2": [{
"uuid": imageid,
"boot_index": "0",
"device_name": "/dev/vda",
"source_type": "image",
"volume_size": volsize,
"destination_type": "volume",
"delete_on_termination": True
}],
"networks": [{"port": port_id}],
"metadata": {"Example Custom Tag": "Finance Department"}
}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
und wird wie folgt aufgerufen –
# K5 predefined parameters for images and flavors
# this is the id of the K5 ubuntu image
image_id = "ffa17298-537d-40b2-a848-0a4d22b49df5"
# the is the id of a small flavor size (T-1 or P1...need to verify)
flavor_id = "1901"
# Create the virtual machine
new_server = create_server_with_port(k5token, "demoserver", image_id, flavor_id, server_key_name, security_group_name, "uk-1b", 3, server_port_id)
print new_server
print new_server.json()
mit folgender Ausgabe –
https://compute.uk-1.cloud.global.fujitsu.com/v2/7015d1478a4c4bd7b970215d7b0260dd/servers
{u'server': {u'links': [{u'href': u'http://10.23.0.201/v2/7015d1478a4c4bd7b970215d7b0260dd/servers/5c57d8bc-6c2d-42bf-a84a-77745651b8e4', u'rel': u'self'}, {u'href': u'http://10.23.0.201/7015d1478a4c4bd7b970215d7b0260dd/servers/5c57d8bc-6c2d-42bf-a84a-77745651b8e4', u'rel': u'bookmark'}], u'OS-DCF:diskConfig': u'MANUAL', u'id': u'5c57d8bc-6c2d-42bf-a84a-77745651b8e4', u'security_groups': [{u'name': u'demosecuritygroup'}]}}
Und das war’s! Sie sollten nun eine neue Instanz auf K5 haben.
Der nächste Schritt ist nur erforderlich, wenn Sie Ihrer neuen Instanz eine externe/öffentliche Floating-IP-Adresse zuweisen möchten.

Schritt 12 – Fügen Sie der neuen virtuellen Maschine eine Floating- oder globale IP-Adresse hinzu, indem Sie den folgenden API-Aufruf verwenden –
def create_global_ip(k5token, ext_network_id, port_id, availability_zone):
networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/floatingips')
print networkURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(networkURL,
headers={
'X-Auth-Token': token,
'Content-Type': 'application/json',
'Accept': 'application/json'},
json={
"floatingip": {
"floating_network_id": ext_network_id,
"port_id": port_id,
"availability_zone": availability_zone
},
})
return response
except:
return ("\nUnexpected error:", sys.exc_info())
welcher wie folgt aufgerufen aussehen sollte –
# Assign a global/public ip address
public_ip = create_global_ip(k5token, extaz2, server_port_id, "uk-1b")
print public_ip
print public_ip.json()
print public_ip.json()['floatingip'].get('floating_ip_address')
und dies ausgeben –
https://networking.uk-1.cloud.global.fujitsu.com/v2.0/floatingips
{u'floatingip': {u'router_id': u'4dde5593-6657-4dea-9095-e0f80129e3f4', u'status': u'DOWN', u'availability_zone': u'uk-1b', u'tenant_id': u'7015d1478a4c4bd7b970215d7b0260dd', u'floating_network_id': u'd730db50-0e0c-4790-9972-1f6e2b8c4915', u'fixed_ip_address': u'192.168.10.2', u'floating_ip_address': u'62.60.42.67', u'port_id': u'f5b24292-8a73-4903-afe1-a71da61a18db', u'id': u'77214fa3-e04a-40f6-93a6-400743bb0862'}}
62.60.42.67

Die obige IP-Adresse kann verwendet werden, um von Internet aus auf Ihren Server zuzugreifen!
Bitte beachten Sie, dass dies absichtlich ein recht detailliertes Tutorial ist. Es ist auch möglich, dies ohne so viele Schritte zu tun, d. h. keinen Port im Voraus zu erstellen. Dies ist für Benutzer gedacht, die ein wenig mehr Detailgenauigkeit benötigen.
Die vollständige Auflistung des Beispiel-Tutorials finden Sie hier ..
Diese Datei enthält versteckte oder bidirektionale Unicode-Zeichen, die anders interpretiert oder kompiliert werden könnten als das, was unten angezeigt wird. Um sie zu überprüfen, öffnen Sie die Datei in einem Editor, der versteckte Unicode-Zeichen anzeigt.
Mehr über bidirektionale Unicode-Zeichen erfahren
| #!/usr/bin/python | |
| """Zusammenfassung: | |
| Das folgende Tutorial zeigt, wie die nativen OpenStack-APIs verwendet werden können, um einen Server, ein Netzwerk, ein Subnetz und einen Router bereitzustellen | |
| auf der Fujitsu K5 IaaS-Plattform | |
| Autor: Graham Land | |
| Datum: 27/01/17 | |
| Twitter: @allthingsclowd | |
| Github: https://github.com/allthingscloud | |
| Blog: https://allthingscloud.eu | |
| """ | |
| import requests | |
| import sys | |
| import json | |
| import pprint | |
| def get_endpoint(k5token, endpoint_type): | |
| # Endpunkte auflisten | |
| for ep in k5token.json()['token']['catalog']: | |
| if len(ep['endpoints'])>0: | |
| # wenn dies der Endpunkt ist, den ich suche, gebe die URL zurück | |
| if endpoint_type == ep['endpoints'][0].get('name'): | |
| #pprint.pprint(ep) | |
| return ep['endpoints'][0].get('url') | |
| def get_scoped_token(adminUser, adminPassword, contract, projectid, region): | |
| identityURL = 'https://identity.' + region + \ | |
| '.cloud.global.fujitsu.com/v3/auth/tokens' | |
| try: | |
| response = requests.post(identityURL, | |
| headers={'Content-Type': 'application/json', | |
| 'Accept': 'application/json'}, | |
| json={"auth": | |
| {"identity": | |
| {"methods": ["password"], "password": | |
| {"user": | |
| {"domain": | |
| {"name": contract}, | |
| "name": adminUser, | |
| "password": adminPassword | |
| }}}, | |
| "scope": | |
| {"project": | |
| {"id": projectid | |
| }}}}) | |
| return response | |
| except: | |
| return 'Fehler beim Scoping des regionalen Projekt-Tokens' | |
| def create_network(k5token, name, availability_zone): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/networks') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={'X-Auth-Token': token, | |
| 'Content-Type': 'application/json'}, | |
| json={ | |
| "network": | |
| { | |
| "name": name, | |
| "admin_state_up": True, | |
| "availability_zone": availability_zone | |
| } | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_subnet(k5token, name, netid, cidr, availability_zone): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/subnets') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={'X-Auth-Token': token, | |
| 'Content-Type': 'application/json'}, | |
| json={ | |
| "subnet": { | |
| "name": name, | |
| "network_id": netid, | |
| "ip_version": 4, | |
| "cidr": cidr, | |
| "availability_zone": availability_zone | |
| } | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_router(k5token, name, availability_zone): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={'X-Auth-Token': token, | |
| 'Content-Type': 'application/json'}, | |
| json={ | |
| "router": { | |
| "name": name, | |
| "admin_state_up": True, | |
| "availability_zone": availability_zone | |
| }}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def update_router_gateway(k5token, router_id, network_id): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers/') + router_id | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.put(networkURL, | |
| headers={'X-Auth-Token': token, | |
| 'Content-Type': 'application/json'}, | |
| json={ | |
| "router": { | |
| "external_gateway_info": { | |
| "network_id": network_id | |
| } | |
| }}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def add_interface_to_router(k5token, router_id, subnet_id): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/routers/') + router_id + '/add_router_interface' | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.put(networkURL, | |
| headers={'X-Auth-Token': token, | |
| 'Content-Type': 'application/json'}, | |
| json={ | |
| "subnet_id": subnet_id}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_security_group(k5token, name, description): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/security-groups') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'}, | |
| json={ | |
| "security_group": { | |
| "name": name, | |
| "description": description | |
| } | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_security_group_rule(k5token, security_group_id, direction, portmin, portmax, protocol): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/security-group-rules') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'}, | |
| json={ | |
| "security_group_rule": { | |
| "direction": direction, | |
| "port_range_min": portmin, | |
| "ethertype": "IPv4", | |
| "port_range_max": portmax, | |
| "protocol": protocol, | |
| "security_group_id": security_group_id | |
| } | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_port(k5token, name, network_id, security_group_id, availability_zone): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/ports') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={ | |
| 'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'}, | |
| json={"port": | |
| {"network_id": network_id, | |
| "name": name, | |
| "admin_state_up": True, | |
| "availability_zone": availability_zone, | |
| "security_groups": | |
| [security_group_id]}}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_keypair(k5token, keypair_name, availability_zone): | |
| computeURL = unicode(get_endpoint(k5token, "compute")) + unicode('/os-keypairs') | |
| print computeURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(computeURL, | |
| headers={ | |
| 'X-Auth-Token': token, | |
| 'Content-Type': 'application/json', | |
| 'Accept': 'application/json'}, | |
| json={ | |
| "keypair": { | |
| "name": keypair_name, | |
| "availability_zone": availability_zone | |
| }}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_server_with_port(k5token, name, imageid, flavorid, sshkey_name, security_group_name, availability_zone, volsize, port_id): | |
| computeURL = unicode(get_endpoint(k5token, "compute")) + unicode('/servers') | |
| print computeURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(computeURL, | |
| headers={'X-Auth-Token':token,'Content-Type': 'application/json','Accept':'application/json'}, | |
| json={"server": { | |
| "name": name, | |
| "security_groups":[{"name": security_group_name }], | |
| "availability_zone":availability_zone, | |
| "imageRef": imageid, | |
| "flavorRef": flavorid, | |
| "key_name": sshkey_name, | |
| "block_device_mapping_v2": [{ | |
| "uuid": imageid, | |
| "boot_index": "0", | |
| "device_name": "/dev/vda", | |
| "source_type": "image", | |
| "volume_size": volsize, | |
| "destination_type": "volume", | |
| "delete_on_termination": True | |
| }], | |
| "networks": [{"port": port_id}], | |
| "metadata": {"Example Custom Tag": "Finance Department"} | |
| }}) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def create_global_ip(k5token, ext_network_id, port_id, availability_zone): | |
| networkURL = unicode(get_endpoint(k5token, "networking")) + unicode('/v2.0/floatingips') | |
| print networkURL | |
| token = k5token.headers['X-Subject-Token'] | |
| try: | |
| response = requests.post(networkURL, | |
| headers={ | |
| 'X-Auth-Token': token, | |
| 'Content-Type': 'application/json', | |
| 'Accept': 'application/json'}, | |
| json={ | |
| "floatingip": { | |
| "floating_network_id": ext_network_id, | |
| "port_id": port_id, | |
| "availability_zone": availability_zone | |
| }, | |
| }) | |
| return response | |
| except: | |
| return ("\nUnerwarteter Fehler:", sys.exc_info()) | |
| def main(): | |
| # Umgebungsparameter initialisieren | |
| adminUser = 'Benutzername hier eingeben' # k5/openstack Benutzer-Anmeldename | |
| adminPassword = 'Passwort hier eingeben' # k5/openstack Benutzer-Passwort | |
| contract = 'Vertragsname hier eingeben' # k5-Vertragsname oder OpenStack-Domänenname | |
| defaultProject = 'Standardprojektname hier eingeben' # Standard-Projekt-ID – bei K5 ist es der Projektname, der mit dem Vertragsnamen beginnt und mit -prj endet | |
| extaz2 = 'd730db50-0e0c-4790-9972-1f6e2b8c4915' # K5 Verfügbarkeitszone b externe Netzwerk-ID | |
| demoProjectA = 'Zielprojekt hier eingeben' # k5/openstack Demo-Zielprojektname | |
| demoProjectAid = 'Demo-Projekt-ID' # k5/openstack Demo-Zielprojekt-ID | |
| region = 'uk-1' # Zielregion | |
| # Holen Sie sich ein projektbeschränktes Token | |
| k5token = get_scoped_token(adminUser, adminPassword, contract, demoProjectAid, region) | |
| # Erstellen Sie ein Layer-2-virtuelles Netzwerk | |
| network = create_network(k5token, "demonet", "uk-1b") | |
| print network | |
| print network.json() | |
| network_id = network.json()['network'].get('id') | |
| print network_id | |
| # Erstellen Sie ein Layer-3-Subnetz | |
| subnet = create_subnet(k5token, "demosubnet", network_id, "192.168.10.0/24", "uk-1b") | |
| print subnet | |
| print subnet.json() | |
| subnet_id = subnet.json()['subnet'].get('id') | |
| print subnet_id | |
| # Erstellen Sie einen Layer-3-virtuellen Router | |
| router = create_router(k5token, "demorouter", "uk-1b") | |
| print router | |
| print router.json() | |
| router_id = router.json()['router'].get('id') | |
| print router_id | |
| # Fügen Sie dem Router ein externes Gateway hinzu (extaz2 ist die externe Netzwerk-ID für das externe Netzwerk in Verfügbarkeitszone b) | |
| router_gateway = update_router_gateway(k5token, router_id, extaz2) | |
| print router_gateway | |
| print router_gateway.json() | |
| # Stecken Sie das neue Netzwerk-Subnetz in den Router | |
| router_interface = add_interface_to_router(k5token, router_id, subnet_id) | |
| print router_interface | |
| print router_interface.json() | |
| # Erstellen Sie eine neue Sicherheitsgruppe | |
| security_group = create_security_group(k5token, "demosecuritygroup", "Demo-Sicherheitsgruppe erlaubt RDP, SSH und ICMP") | |
| print security_group | |
| print security_group.json() | |
| security_group_id = security_group.json()['security_group'].get('id') | |
| print security_group_id | |
| security_group_name = security_group.json()['security_group'].get('name') | |
| # Sicherheitsgruppenregeln erstellen | |
| # rdp erlauben | |
| rdp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "3389", "3389", "tcp") | |
| print rdp_rule | |
| print rdp_rule.json() | |
| # ssh erlauben # rdp erlauben | |
| ssh_rule = create_security_group_rule(k5token, security_group_id, "ingress", "22", "22", "tcp") | |
| print ssh_rule | |
| print ssh_rule.json() | |
| # icmp erlauben | |
| icmp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "0", "0", "icmp") | |
| print icmp_rule | |
| print icmp_rule.json() | |
| # Erstellen Sie einen neuen Port für den Server | |
| server_port = create_port(k5token, "demoserverport", network_id, security_group_id, "uk-1b") | |
| print server_port | |
| print server_port.json() | |
| server_port_id = server_port.json()['port'].get('id') | |
| print server_port_id | |
| # Erstellen Sie ein SSH-Schlüsselpaar, das in den Server eingespeist werden kann | |
| server_key = create_keypair(k5token, "demokeypair", "uk-1b") | |
| print server_key | |
| print server_key.json() | |
| server_key_id = server_key.json()['keypair'].get('id') | |
| print server_key_id | |
| server_key_private = server_key.json()['keypair'].get('private_key') | |
| print server_key_private | |
| server_key_public = server_key.json()['keypair'].get('public_key') | |
| print server_key_public | |
| server_key_name = server_key.json()['keypair'].get('name') | |
| # K5 vordefinierte Parameter für Images und Flavors | |
| # dies ist die ID des K5 Ubuntu-Images | |
| image_id = "ffa17298-537d-40b2-a848-0a4d22b49df5" | |
| # dies ist die ID einer kleinen Flavor-Größe (T-1 oder P1… muss noch überprüft werden) | |
| flavor_id = "1901" | |
| # Erstellen Sie die virtuelle Maschine | |
| new_server = create_server_with_port(k5token, "demoserver", image_id, flavor_id, server_key_name, security_group_name, "uk-1b", 3, server_port_id) | |
| print new_server | |
| print new_server.json() | |
| # Weisen Sie eine globale/öffentliche IP-Adresse zu | |
| public_ip = create_global_ip(k5token, extaz2, server_port_id, "uk-1b") | |
| print public_ip | |
| print public_ip.json() | |
| print public_ip.json()['floatingip'].get('floating_ip_address') | |
| if __name__ == "__main__": | |
| main() |
Rohansicht
OpenStack_Fujitsu_K5_Server_Build_API_Demo.py
gehostet mit ❤ von GitHub
oder kann hier von GitHub heruntergeladen werden ..
https://github.com/allthingsclowd/OpenStack_Fujitsu_K5_Server_Build_API_Demo
Bitte stellen Sie sicher, dass Sie die Eingabeparameter in der main-Funktion so konfigurieren, dass sie mit Ihrer Zielumgebung übereinstimmen. Es gibt auch ein Bereinigungsskript, das ich in meinem vorherigen Beitrag erstellt habe, das hier sehr praktisch ist zum Testen.
Happy Stacking!
withk5youcan
Originally published on allthingscloud.eu (2017-01-27).