From Zero to Hero con l'API IaaS OpenStack di K5 (Python 2.7X)

2017-01-27

From Zero to Hero con l'API IaaS OpenStack di K5 (Python 2.7X)

Machine-translated from English. Read the English original

Oggi esaminerò tutti i passaggi necessari per distribuire un server sulla piattaforma IaaS di Fujitsu K5 utilizzando esclusivamente chiamate API basate su OpenStack. Ho scelto Python 2.7X a scopo dimostrativo poiché è su questo che OpenStack è principalmente costruito. Tuttavia, dovrebbe essere abbastanza facile portare le chiamate API in un altro linguaggio di scripting, in quanto non sto utilizzando librerie intermedie: tutte le mie richieste http parlano direttamente agli endpoint di K5.

Prerequisiti per questo tutorial:

Passaggi richiesti per creare un server utilizzando l'API OpenStack

Una volta soddisfatti i prerequisiti sopra, esaminiamo rapidamente cosa è necessario per creare un server in un progetto all'interno di OpenStack.

k5-iaas-server-build-via-api-1

Per il resto di questo tutorial, passerò in rassegna ciascuna chiamata API, dettagliando cosa viene inviato e cosa viene restituito.

sbstep1

Passaggio 1 – Ottenere un token K5 valido limitato al progetto in cui si desidera distribuire il server. Qui avrai bisogno delle tue credenziali di accesso K5/OpenStack. Queste verranno fornite con la richiesta iniziale per un token limitato al progetto come segue:

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)

Se sono state fornite credenziali valide, riceverai un oggetto di risposta JSON che contiene gli endpoint K5 registrati nel suo catalogo Keystone di OpenStack come segue:

{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'}}}

Queste informazioni sono molto importanti perché quando si desidera automatizzare completamente K5, è così che si rilevano i vari endpoint per i servizi che è necessario consumare.

Nota: Gli endpoint che hanno un suffisso ‘-ex’ nei loro nomi sono gli endpoint migliorati di OpenStack. Questi endpoint includono le funzionalità aggiuntive che Fujitsu ha aggiunto a K5 oltre alle funzionalità standard di OpenStack.

Quindi cosa manca in questo quadro... dov'è il token??? Non temere, in realtà è memorizzato nell'intestazione della risposta in una variabile chiamata ‘X-Subject-Token’. Ad esempio –

  # print the K5 poject scoped token
  print "\n\n K5 Project Scoped Token :", k5token.headers['X-Subject-Token'], "\n"

...rivela un token, che tra l'altro è valido per 2 ore, come segue..

K5 Project Scoped Token : f5b72cd06517447fae59360f6deba7d8

Questo token deve essere passato con tutte le chiamate API K5 successive nell'intestazione per fornire le tue credenziali di autenticazione e autorizzazione a ciascuna richiesta di servizio.

L'endpoint standard dell'API OpenStack neutron può essere estratto dalla risposta sopra cercando l'endpoint chiamato ‘networking’. Ho utilizzato la seguente funzione per restituire l'URL dell'endpoint che sto cercando –

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')

Ad esempio –

  # list the networking endpoints
    print get_endpoint(k5token,"networking")

restituirà l'endpoint dell'API neutron di cui ho bisogno –

 K5 Networking EndPoints :
https://networking.uk-1.cloud.global.fujitsu.com

Ora che abbiamo i dettagli del token e dell'endpoint necessari, passiamo alla fase successiva.

sbstep2

Passaggio 2 – Creare la rete layer 2. La seguente chiamata neutron crea una subnet layer 2 di K5 con le proprietà che passi tramite l'API come segue:

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())

Ad esempio –

    # Create a layer 2 virtual network
    network = create_network(k5token, "demonet", "uk-1b")
    print network
    print network.json()

produce –

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'}}

Dobbiamo catturare l'id della rete appena creata poiché lo useremo nella chiamata API successiva –

    network_id = network.json()['network'].get('id')

Ora creiamo la nostra subnet.

sbstep3

Passaggio 3 – Creare la subnet layer 3. Anche in questo caso stiamo utilizzando la chiamata API neutron standard qui e passando l'id della rete appena creata alla chiamata. La funzione utilizzata ha questo aspetto –

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())

E quando viene chiamata come segue –

    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

produce la seguente risposta –

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

Nota che ora abbiamo anche catturato il nuovo id della subnet. Si spera che il pattern stia diventando ovvio ora mentre procediamo al passo successivo.

sbstep4

Passaggio 4 – Creare un router virtuale. Ancora una volta stiamo lavorando con l'endpoint neutrons di OpenStack questa volta costruendo un router virtuale. È stata utilizzata la seguente funzione –

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())

che, quando invocata in questo modo –

    # 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

restituisce –

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

Ancora una volta catturiamo l'identificatore della risorsa appena creata – router_id.

sbstep5

Passaggio 5 – Ora configuriamo il router. Prima impostiamo il gateway esterno utilizzando la seguente chiamata di funzione –

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())

chiamata dal corpo dello script in questo modo –

    # 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()

producendo i seguenti risultati –

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'}}

sbstep6

Passaggio 6 – Ora ‘collegheremo’ la nostra rete virtuale al nostro router virtuale con questa chiamata di funzione –

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())

che viene invocata in questo modo –

    # 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()

con il seguente output –

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'}

Questo completa le basi dell'infrastruttura di rete.

sbstep7

Passaggio 7 – Il server avrà bisogno di un gruppo di sicurezza assegnato alle sue interfacce di rete, quindi lo creeremo ora insieme alle regole che consentiranno solo l'ingresso dei protocolli ssh, tcp e rdp.

Questa chiamata API è stata utilizzata per creare il gruppo di sicurezza –

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())

che viene invocato come segue –

    # 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

risultando in questo output –

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

sbstep8

Passaggio 8 – Crea le regole del nostro gruppo di sicurezza con la seguente chiamata API –

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())

ancora (ripetitivo, lo so) la chiamata viene invocata in questo modo –

    # 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()

outputting –

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'}}

sbstep9

Passaggio 9 – Prendiamo una porta dalla nostra nuova subnet che verrà allegata al server con una chiamata api come questa –

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())

invocata in questo modo –

    # 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

producendo il seguente output –

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

sbstep10

Passaggio 10 – Siamo quasi arrivati. L'ultimo pezzo del puzzle prima di poter distribuire un server è la chiave SSH. La prossima funzione crea una chiave SSH per te: assicurati di memorizzare la chiave privata da qualche parte sicura. K5 memorizza solo le chiavi pubbliche per progettazione.

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())

invocata in questo modo –

    # 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

dovrebbe produrre –

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

sbstep11

Passaggio 11 – Quello per cui tutti abbiamo aspettato, la distribuzione della macchina virtuale. Per questo noterai che ho configurato altri due parametri prerequisito: l'id del flavor o della taglia della maglietta del vCPU e della RAM dell'istanza, e l'id dell'immagine del sistema operativo che useremo. La chiamata API ha questo aspetto –

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())

e viene chiamata in questo modo –

    # 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()

outputting il seguente –

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'}]}}

E questo è tutto! Dovresti ora avere una nuova istanza in esecuzione su K5.
Il passo successivo è necessario solo se desideri allegare un indirizzo ip floating/esterno pubblico alla tua nuova istanza.

sbstep12

Passaggio 12 – Aggiungi un indirizzo ip floating o globale alla nuova macchina virtuale utilizzando la seguente chiamata API –

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())

che dovrebbe apparire così quando invocato –

    # 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')

e outputtare questo –

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

sbstep13

L'indirizzo ip sopra può essere utilizzato per accedere al tuo server da internet!

Ti preghiamo di notare che questo è deliberatamente un tutorial piuttosto dettagliato. È anche possibile farlo senza così tanti passaggi, cioè senza creare prima una porta. Questo è per gli utenti che richiedono quel piccolo dettaglio in più.

L'elenco completo del tutorial di esempio è qui..

Questo file contiene testo Unicode nascosto o bidirezionale che potrebbe essere interpretato o compilato in modo diverso da quanto appare di seguito. Per rivedere, apri il file in un editor che riveli i caratteri Unicode nascosti.
Maggiori informazioni sui caratteri Unicode bidirezionali

Mostra caratteri nascosti

#!/usr/bin/python
"""Riepilogo:
Il seguente tutorial dimostra come le API native di OpenStack possono essere utilizzate per distribuire un server, una rete, una subnet e un router
sulla piattaforma IaaS Fujitsu K5
Autore: Graham Land
Data: 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):
# elenca gli endpoint
for ep in k5token.json()['token']['catalog']:
if len(ep['endpoints'])>0:
# se questo è l'endpoint che sto cercando restituisci l'url
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 'Regional Project Token Scoping Failure'
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())
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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", 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 ("\nUnexpected error:", sys.exc_info())
def main():
# Inizializza i parametri dell'ambiente
adminUser = 'username goes here' # nome utente k5/openstack
adminPassword = 'password goes here' # password utente k5/openstack
contract = 'contract name goes here' # nome contratto k5 o nome dominio openstack
defaultProject = 'default project name goes here' # id progetto predefinito – su k5 è il nome del progetto che inizia con il nome del contratto e termina con -prj
extaz2 = 'd730db50-0e0c-4790-9972-1f6e2b8c4915' # K5 availability zone b external network id
demoProjectA = 'target project goes here' # nome progetto demo target k5/openstack
demoProjectAid = 'demo project id' # id progetto demo target k5/openstack
region = 'uk-1' # regione target
# Ottieni un token limitato al progetto
k5token = get_scoped_token(adminUser, adminPassword, contract, demoProjectAid, region)
# Crea una rete virtuale layer 2
network = create_network(k5token, "demonet", "uk-1b")
print network
print network.json()
network_id = network.json()['network'].get('id')
print network_id
# Crea una subnet layer 3
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
# Crea un router virtuale layer 3
router = create_router(k5token, "demorouter", "uk-1b")
print router
print router.json()
router_id = router.json()['router'].get('id')
print router_id
# Aggiungi gateway esterno al router (extaz2 è l'id della rete esterna per la rete esterna nella zona di disponibilità b)
router_gateway = update_router_gateway(k5token, router_id, extaz2)
print router_gateway
print router_gateway.json()
# Collega la nuova subnet di rete al router
router_interface = add_interface_to_router(k5token, router_id, subnet_id)
print router_interface
print router_interface.json()
# Crea un nuovo gruppo di sicurezza
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
security_group_name = security_group.json()['security_group'].get('name')
# Crea regole del gruppo di sicurezza
# consenti rdp
rdp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "3389", "3389", "tcp")
print rdp_rule
print rdp_rule.json()
# consenti ssh # consenti rdp
ssh_rule = create_security_group_rule(k5token, security_group_id, "ingress", "22", "22", "tcp")
print ssh_rule
print ssh_rule.json()
# consenti icmp
icmp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "0", "0", "icmp")
print icmp_rule
print icmp_rule.json()
# Crea una nuova porta per il 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
# Crea coppia di chiavi ssh che può essere iniettata nel 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
server_key_name = server_key.json()['keypair'].get('name')
# Parametri predefiniti K5 per immagini e flavors
# questo è l'id dell'immagine ubuntu K5
image_id = "ffa17298-537d-40b2-a848-0a4d22b49df5"
# questo è l'id di una dimensione di flavor piccola (T-1 o P1...da verificare)
flavor_id = "1901"
# Crea la macchina virtuale
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()
# Assegna un indirizzo ip globale/pubblico
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()

view raw
OpenStack_Fujitsu_K5_Server_Build_API_Demo.py
hosted with ❤ by GitHub

oppure può essere scaricato da github qui..

https://github.com/allthingsclowd/OpenStack_Fujitsu_K5_Server_Build_API_Demo

Assicurati di configurare i parametri di input situati nella funzione main per corrispondere al tuo ambiente target. C'è anche uno script di purge che ho creato nel mio post precedente che è piuttosto utile qui per i test.

Happy Stacking!

withk5youcan

Originally published on allthingscloud.eu (2017-01-27).

← All posts