ゼロからヒーローへ:K5 OpenStack IaaS API(Python 2.7X)でサーバーをデプロイする

2017-01-27

ゼロからヒーローへ:K5 OpenStack IaaS API(Python 2.7X)でサーバーをデプロイする

Machine-translated from English. Read the English original

今日は、OpenStackベースのAPI呼び出しのみを使用して、Fujitsu K5のIaaSプラットフォーム上にサーバーをデプロイするために必要なすべての手順を順を追って説明します。デモンストレーションのためにPython 2.7Xを選択したのは、OpenStack自体が主にこれに基づいて構築されているからです。ただし、中間ライブラリを使用していないため、API呼び出しを他のスクリプト言語にポートするのは容易であるはずです。私のHTTPリクエストはすべて、K5のエンドポイントに直接通信しています。

このチュートリアルの前提条件:

OpenStack APIを使用してサーバーを構築するために必要な手順

上記の前提条件を満たしたら、OpenStack内のプロジェクトでサーバーを構築するために必要なものを簡単にレビューしましょう。

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

このチュートリアルの残りの部分では、各API呼び出しをステップバイステップで説明し、送信される内容と返される内容を詳述します。

sbstep1

ステップ1 – デプロイしたいサーバーが存在するプロジェクトにスコープされた有効なK5トークンを取得します。ここでK5/OpenStackのログイン資格情報が必要です。これらの資格情報は、プロジェクトスコープのトークンの初期リクエストとして以下のように提供されます:

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)

有効な資格情報が提供された場合、K5エンドポイントがそのOpenStack Keystoneカタログに登録されているJSONレスポンスオブジェクトが返されます。以下のように:

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

この情報は非常に重要です。K5を完全に自動化したい場合、これが必要なサービスのエンドポイントを検出する方法だからです。

注: 名前に「-ex」サフィックスが付いているエンドポイントは、OpenStack拡張エンドポイントです。これらのエンドポイントには、標準のOpenStack機能を超えてFujitsuがK5に追加した追加機能が含まれています。

では、この画像から何が欠けているのでしょうか……トークンはどこにあるのでしょうか? 心配しないでください。実際、それは「X-Subject-Token」という変数名のレスポンスヘッダーに保存されています。例えば –

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

…トークンを明らかにします。ちなみに、このトークンは2時間有効です。以下のように:

K5 Project Scoped Token : f5b72cd06517447fae59360f6deba7d8

このトークンは、認証および認可資格情報を各サービスリクエストに提供するために、後続のすべてのK5 API呼び出しでヘッダーとして渡す必要があります。

標準のOpenStack Neutron APIエンドポイントは、上記のレスポンスから「networking」と呼ばれるエンドポイントを探すことで抽出できます。私は以下のような関数を使用して、探しているエンドポイントのURLを返しています –

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

例えば –

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

必要なNeutron APIエンドポイントを返します –

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

これで必要なトークンとエンドポイントの詳細が揃ったので、次の段階に進みましょう。

sbstep2

ステップ2 – レイヤ2ネットワークを作成します。以下のNeutron呼び出しは、APIを介して渡すプロパティを持つK5レイヤ2サブネットを作成します。以下のように:

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

例えば –

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

以下を生成します –

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

新しく作成されたネットワークのIDをキャプチャする必要があります。これは後続のAPI呼び出しで使用するためです –

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

さて、サブネットを作成しましょう。

sbstep3

ステップ3 – レイヤ3サブネットを作成します。ここでは標準のNeutron API呼び出しを使用し、新しく作成されたネットワークIDを呼び出しに渡しています。使用される関数は以下のようになります –

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

以下のように呼び出すと –

    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

以下のレスポンスを生成します –

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

ここで、新しいサブネットIDもキャプチャしたことに注意してください。次のステップに進むにつれて、パターンが明らかになってきていることを願っています。

sbstep4

ステップ4 – 仮想ルーターを作成します。再び、今回は仮想ルーターを構築するためにOpenStack Neutronsのエンドポイントで作業しています。以下の関数が使用されています –

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

これは以下のように呼び出すと –

    # 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

以下を返します –

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

再び、新しく作成されたリソース識別子 – router_idをキャプチャします。

sbstep5

ステップ5 – これでルーターを設定しましょう。まず、以下の関数呼び出しを使用して外部ゲートウェイを設定します –

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

スクリプト本体から以下のように呼び出します –

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

以下の結果を生成します –

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

ステップ6 – この関数呼び出しを使用して、仮想ネットワークを仮想ルーターに「プラグイン」します –

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

これは以下のように呼び出されます –

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

以下の出力と共に –

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

これでネットワークインフラストラクチャの基本が完了しました。

sbstep7

ステップ7 – サーバーには、ネットワークインターフェースに割り当てるセキュリティグループが必要なので、SSH、TCP、およびRDPプロトコルをインバウンドのみで許可するルールとともにこれを作成します。

セキュリティグループを作成するために使用されたAPI呼び出しは以下の通りです –

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

これは以下のように呼び出されます –

    # 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

これにより、この出力が得られます –

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

ステップ8 – 以下の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())

再び(繰り返しがわかりますが)、呼び出しは以下のように呼び出されます –

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

出力して –

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

ステップ9 – サーバーに接続される新しいサブネットからポートを取得しましょう。以下のようなAPI呼び出しで –

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

以下のように呼び出されます –

    # 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

以下の出力を生成します –

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

ステップ10 – ほぼ完了です。サーバーをデプロイする前に必要な最後のピースはSSHキーです。次の関数はSSHキーを作成します – 秘密鍵を安全な場所に保存してください。K5は設計上、公開鍵のみを保存します。

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

このように呼び出すと –

    # 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

以下を生成するはずです –

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

ステップ11 – 私たちが待望していた、仮想マシンのデプロイです。これには、インスタンスのvCPUとRAMのフレーバー(またはTシャツサイズ)のID、および使用するオペレーティングシステムイメージのIDという2つの追加の前提条件パラメータを設定していることに気づくでしょう。API呼び出しは以下の通りです –

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

以下のように呼び出されます –

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

以下を出力して –

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

これで完了です!これでK5上で新しいインスタンスが実行されているはずです。
次のステップは、新しいインスタンスに外部/パブリックのフローティングIPアドレスを接続したい場合にのみ必要です。

sbstep12

ステップ12 – 以下のAPI呼び出しを使用して、新しい仮想マシンにフローティングまたはグローバルIPアドレスを追加します –

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

これは呼び出されると以下のように見えるはずです –

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

そして以下を出力します –

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

上記のIPアドレスを使用して、インターネットからサーバーにアクセスできます!

これは意図的にかなり詳細なチュートリアルであることにご注意ください。これよりも少ないステップでこれを行うことも可能です。つまり、最初にポートを作成しないことです。これは、少し追加の詳細を必要とするユーザー向けです。

例のチュートリアルの完全なリストはここにあります..

このファイルには、以下に表示されるものとは異なる方法で解釈またはコンパイルされる可能性がある、隠されたまたは双方向のUnicode文字が含まれています。確認するには、隠されたUnicode文字を表示するエディタでファイルを開きます。
双方向のUnicode文字について詳しく学ぶ

隠された文字を表示

#!/usr/bin/python
"""概要:
以下のチュートリアルは、ネイティブなOpenStack APIを使用して、サーバー、ネットワーク、サブネット、およびルーターをデプロイする方法を示しています
Fujitsu K5 IaaSプラットフォーム上で
著者:Graham Land
日付:2017年1月27日
Twitter:@allthingsclowd
Github:https://github.com/allthingscloud
ブログ:https://allthingscloud.eu
"""
import requests
import sys
import json
import pprint
def get_endpoint(k5token, endpoint_type):
# エンドポイントを一覧表示
for ep in k5token.json()['token']['catalog']:
if len(ep['endpoints'])>0:
# これが探しているエンドポイントの場合、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():
# 環境パラメータを初期化
adminUser = 'username goes here' # k5/openstack ユーザーログイン名
adminPassword = 'password goes here' # k5/openstack ユーザーパスワード
contract = 'contract name goes here' # k5契約名またはopenstackドメイン名
defaultProject = 'default project name goes here' # デフォルトプロジェクトID – k5では、契約名で始まり -prj で終わるプロジェクト名です
extaz2 = 'd730db50-0e0c-4790-9972-1f6e2b8c4915' # K5 利用可能ゾーンB 外部ネットワークID
demoProjectA = 'target project goes here' # k5/openstack デモ対象プロジェクト名
demoProjectAid = 'demo project id' # k5/openstack デモ対象プロジェクトID
region = 'uk-1' # 対象リージョン
# プロジェクトスコープのトークンを取得
k5token = get_scoped_token(adminUser, adminPassword, contract, demoProjectAid, region)
# レイヤ2仮想ネットワークを作成
network = create_network(k5token, "demonet", "uk-1b")
print network
print network.json()
network_id = network.json()['network'].get('id')
print network_id
# レイヤ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
# レイヤ3仮想ルーターを作成
router = create_router(k5token, "demorouter", "uk-1b")
print router
print router.json()
router_id = router.json()['router'].get('id')
print router_id
# ルーターに外部ゲートウェイを追加(extaz2は、利用可能ゾーンBの外部ネットワークの外部ネットワークIDです)
router_gateway = update_router_gateway(k5token, router_id, extaz2)
print router_gateway
print router_gateway.json()
# 新しいネットワークサブネットをルーターにプラグイン
router_interface = add_interface_to_router(k5token, router_id, subnet_id)
print router_interface
print router_interface.json()
# 新しいセキュリティグループを作成
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')
# セキュリティグループルールを作成
# rdpを許可
rdp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "3389", "3389", "tcp")
print rdp_rule
print rdp_rule.json()
# sshを許可 # rdpを許可
ssh_rule = create_security_group_rule(k5token, security_group_id, "ingress", "22", "22", "tcp")
print ssh_rule
print ssh_rule.json()
# icmpを許可
icmp_rule = create_security_group_rule(k5token, security_group_id, "ingress", "0", "0", "icmp")
print icmp_rule
print icmp_rule.json()
# サーバー用の新しいポートを作成
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
# サーバーに注入できるSSHキーペアを作成
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の事前定義されたイメージとフレーバーのパラメータ
# これはK5 UbuntuイメージのIDです
image_id = "ffa17298-537d-40b2-a848-0a4d22b49df5"
# これは小さなフレーバーサイズ(T-1またはP1…確認が必要)のIDです
flavor_id = "1901"
# 仮想マシンを作成
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()
# グローバル/パブリックIPアドレスを割り当て
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()

rawを表示
OpenStack_Fujitsu_K5_Server_Build_API_Demo.py
❤️でホスト:GitHub

または、ここからGitHubからダウンロードできます..

https://github.com/allthingsclowd/OpenStack_Fujitsu_K5_Server_Build_API_Demo

main関数にある入力パラメータを、対象の環境に合わせて構成してください。また、前の投稿で作成したパージスクリプトも、ここでは非常に便利です。

Happy Stacking!

withk5youcan

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

← All posts