FJCS API

```py

import json
import urllib.request

"""FJCS for OSSのAPIトークンを取得するモジュール

    本モジュールは公式ドキュメントを元にしたFJCS for OSSのAPIトークンを取得するPythonプログラムである
    https://doc.cloud.global.fujitsu.com/lib/iaas/jp/api-user-guide/index.html#task/task_deployment_of_shell_jp.html

"""
class FjcsClient():
    """FJCS APIへのHTTPリクエストを行うクラス

    Attributes:
        domain_name: ドメイン名 (契約番号)
        tenant_id: テナントID ( プロジェクトID )
        user_name: ユーザー名
        user_password: パスワード

    """

    def __init__(self, region, account_file_path):

        with open(account_file_path, "r") as _account_file:
            _account_info = json.loads(_account_file.read())
            _account_file.close()

        self.domain_name = _account_info["domain_name"]
        self.tenant_id = _account_info["projectid"]
        self.project_id = self.tenant_id
        self.user_name = _account_info["user"]
        self.user_password = _account_info["pass"]
        #TOKEN_URL = "https://identity.jp-east-3.cloud.global.fujitsu.com/v3/auth/tokens"
        self.token_endpoint = "https://identity." + region + ".cloud.global.fujitsu.com"
        self.identity_endpoint = self.token_endpoint
        self.network_endpoint = "https://networking." + region + ".cloud.global.fujitsu.com"
        self.compute_endpoint = "https://compute." + region + ".cloud.global.fujitsu.com"
        self.ceilometer_endpoint = "https://telemetry." + region + ".cloud.global.fujitsu.com"
        self.telemetry_endpoint = self.ceilometer_endpoint
        self.db_endpoint = "https://database." + region + ".cloud.global.fujitsu.com"
        self.blockstorage_endpoint = "https://blockstorage." + region + ".cloud.global.fujitsu.com"
        self.host_blockstoragev2_endpoint = self.blockstorage_endpoint
        self.objectstorage_endpoint = "https://objectstorage." + region + ".cloud.global.fujitsu.com"
        self.orchestration_endpoint = "https://orchestration." + region + ".cloud.global.fujitsu.com"
        self.lb_endpoint = "https://loadbalancing." + region + ".cloud.global.fujitsu.com"
        self.autoscale_endpoint = "https://autoscale." + region + ".cloud.global.fujitsu.com"
        self.image_endpoint = "https://image." + region + ".cloud.global.fujitsu.com"
        self.mailservice_endpoint = "https://mail." + region + ".cloud.global.fujitsu.com"
        self.network_ex_endpoint = "https://networking-ex." + region + ".cloud.global.fujitsu.com"
        self.dns_endpoint = "https://dns.gls.cloud.global.fujitsu.com"
        self.compute_sap_endpoint = "https://compute-w." + region + ".cloud.global.fujitsu.com"
        self.keymanagement_endpoint = "https://keymanagement." + region + ".cloud.global.fujitsu.com"
        self.software_endpoint = "https://software." + region + ".cloud.global.fujitsu.com"
        self.vmimport_endpoint = "https://vmimport." + region + ".cloud.global.fujitsu.com"
        self.vmexport_endpoint = "https://import-export." + region + ".cloud.global.fujitsu.com"

    def get_token(self):
        """FJCS for OSSのAPIトークンを取得
    
        """
        
        token_url = self.token_endpoint + "/v3/auth/tokens"
        
        project_id = {"id" : self.tenant_id}
        scope = {"project" : project_id}
        domain_name = {"name" : self.domain_name}
        domain = {
            "domain" : domain_name,
            "name" : self.user_name,
            "password" : self.user_password,
        }
        user = { "user" : domain }
        password = [ "password" ]
        methods = { "methods" : password, "password" : user }
        identity = { 
            "identity" : methods,
            "scope" : scope
        }
        
        # Exsample: 
        #     request_data = {"auth": {"identity": {"methods": ["password"], "password": {"user": 
        #         {"domain": {"name": "DOMAIN_NAME"},"name": "USER_NAME", "password": "USER_PW"}}}, "scope": {"project": {"id": "PROJECT_ID"}}}}
        request_data = { 
            'auth': identity
        }
        
        request_headers = {
            'Content-Type' : 'application/json',
            'Accept' : 'application/json',
        }
        
        token_request = urllib.request.Request(token_url, json.dumps(request_data).encode(), request_headers, method='POST')
        with urllib.request.urlopen(token_request) as response:
            response_headers = response.headers
            token_string = response_headers.get("X-Subject-Token")
            #print("%s" % (token_string))
    
        return token_string

    def make_request_header(self, token_string):
        """リクエストヘッダ文字列を作成
    
        Args:
            token_string (str): 認証トークン文字列

        Returns:
            str: リクエストヘッダ文字列

        """

        request_headers = {
            'X-Auth-Token' : token_string,
            'Content-Type' : 'application/json',
            'Accept' : 'application/json',
        }

        return request_headers

    def _request(self, token_string, request_url, request_data, request_method='GET'):
        """基本HTTPリクエストメソッド(他のメソッドから呼び出す)
    
        Args:
            token_string (str): 認証トークン文字列
            request_url (str): リクエストURL
            request_data (dict): リクエストパラメータ
            request_method (str): HTTPメソッド

        Returns:
            dict: レスポンスボディ

        """

        request_headers = self.make_request_header(token_string)
        request = urllib.request.Request(request_url, data=json.dumps(request_data).encode(), headers=request_headers, method=request_method)

        with urllib.request.urlopen(request) as response:
            response_body = json.loads(response.read().decode())
            return response_body
    
    def get_loadbalancer(self, token_string):
        """ロードバランサー情報を取得
    
        Args:
            token_string (str): 認証トークン文字列

        Returns:
            dict: ロードバランサー情報

        """

        request_url = self.network_endpoint + "/v2.0/lbaas/loadbalancers"

        request_data = None
        request_method = "GET"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body
    
    def update_loadbalancer_name(self, token_string, loadbalancer_id, loadbalancer_name):
        """ロードバランサー情報を取得
    
        Args:
            token_string (str): 認証トークン文字列

        Returns:
            dict: ロードバランサー情報

        """

        request_url = self.network_endpoint + "/v2.0/lbaas/loadbalancers/" + loadbalancer_id + "?loadbalancer_id=" + loadbalancer_id
        print(request_url)
        request_data = {
            "loadbalancer": {
                "name": loadbalancer_name,
            }
         }
    

        request_data = None
        request_method = "PUT"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def get_network(self, token_string, network_id=None):
        """ネットワーク情報を取得
    
        Args:
            token_string (str): 認証トークン文字列
            network_id (str): ネットワークID

        Returns:
            dict: ネットワーク情報

        """

        if network_id == None:
            #self.network_endpoint = "https://networking." + region + ".cloud.global.fujitsu.com"
            request_url = self.network_endpoint + "/v2.0/networks"
        else:
            request_url = self.network_endpoint + "/v2.0/networks/" + network_id

        request_data = None
        request_method = "GET"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def get_subnetwork(self, token_string, network_id=None):
        """ネットワーク情報を取得
    
        Args:
            token_string (str): 認証トークン文字列
            network_id (str): ネットワークID

        Returns:
            dict: ネットワーク情報

        """

        request_url = self.network_endpoint + "/v2.0/subnets" 

        request_data = None
        request_method = "GET"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def get_port(self, token_string, port_id=None):
        """ポート情報を取得
    
        Args:
            token_string (str): 認証トークン文字列
            port_id (str): ポートID

        Returns:
            dict: ポート情報

        """

        if port_id == None:
            request_url = self.network_endpoint + "/v2.0/ports"
        else:
            request_url = self.network_endpoint + "/v2.0/ports/" + port_id

        request_data = None
        request_method = "GET"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def get_floating_ip(self, token_string, floating_ip_id=None):
        """フローティングIP情報を取得
    
        Args:
            token_string (str): 認証トークン文字列
            floating_ip_id (str): フローティングIPのID

        Returns:
            dict: ポート情報

        """

        if floating_ip_id == None:
            request_url = self.network_endpoint + "/v2.0/floatingips"
        else:
            request_url = self.network_endpoint + "/v2.0/floatingips/" + floating_ip_id

        request_data = None
        request_method = "GET"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def delete_port(self, token_string, port_id=None):
        """ポートを削除
    
        Args:
            token_string (str): 認証トークン文字列
            port_id (str): ポートID

        Returns:
            dict: ポート情報

       TODO:
           * urllib.error.HTTPError: HTTP Error 400: Bad Request : 何故かバッドリクエストになる

        """

        if port_id == None:
            request_url = self.network_endpoint + "/v2.0/ports"
        else:
            request_url = self.network_endpoint + "/v2.0/ports/" + port_id + "?port_id=" + port_id

        print(request_url)
        request_data = {"port_id": port_id}
        #request_data = None
        request_method = "DELETE"
        #token_request = urllib.request.Request(request_url, json.dumps(request_data), self.make_request_header(token_string), method=request_method)
        response_body = self._request(token_string, request_url, request_data, request_method=request_method)

        return response_body

    def update_port_name(self, token_string, port_id, port_name):
        """ポート名を変更
    
        Args:
            token_string (str): 認証トークン文字列
            port_id (str): ポートID
            port_name (str): ポート名

        Returns:
            dict: ポート情報

        """

        request_url = self.network_endpoint + "/v2.0/ports/" + port_id + "?port_id=" + port_id

        request_data = {
            "port": {
                "name": port_name,
            }
         }
    
        request_method = "PUT"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def create_port(self, token_string, network_id=None):
        """ネットワークにポートを作成
    
        Args:
            token_string (str): 認証トークン文字列
            port_id (str): ポートID

        Returns:
            dict: ポート情報

        TODO:
            * TEST

        """

        request_url = self.network_endpoint + "/v2.0/ports"

        request_data = {
            "port": {
                "admin_state_up": True,
                "port_security_enabled": True,
                "tenant_id" : self.tenant_id,
                "project_id" : self.project_id,
                "name": "bridge_operation-port",
                "network_id": network_id,
                "security_groups" : ["a9c274b9-2144-4307-9bab-d50aad3a32cc"],
                "fixed_ips" : [
                    {
                        "subnet_id" : "f1d74952-f76f-4d80-99f6-b4e5769510b4", 
                        "ip_address": "192.168.100.9"
                    }
                ]
            }
        }
    
        request_method = "POST"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def update_floating_ip(self, token_string, port_id, floating_ip_id=None):
        """フローティングIPを割当て
    
        Args:
            token_string (str): 認証トークン文字列
            port_id (str): ポートID
            floating_ip_id (str): フローティングIPのID

        Returns:
            dict: ポート情報

        """

        if floating_ip_id == None:
            request_url = self.network_endpoint + "/v2.0/floatingips"
        else:
            request_url = self.network_endpoint + "/v2.0/floatingips/" + floating_ip_id

        request_data = { 
            "floatingip" : {
                "port_id" : port_id,
                "fixed_ip_address" : None,
                "description" : "Description of resource"
            }
        }
        request_method = "PUT"
        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

    def update_subnetwork_name(self, token_string, subnetwork_id, subnetwork_name):
        """ネットワーク情報を取得
    
        Args:
            token_string (str): 認証トークン文字列
            network_id (str): ネットワークID

        Returns:
            dict: ネットワーク情報

        """
#f1d74952-f76f-4d80-99f6-b4e5769510b4
        request_url = self.network_endpoint + "/v2.0/subnets/"  + subnetwork_id 

        request_data = None
        request_method = "PUT"

        request_data = {
            "subnet": {
                "name": subnetwork_name,
            }
         }

        response_body = self._request(token_string, request_url, request_data, request_method)

        return response_body

def main():

    ACCOUNT_FILE_PATH = "/var/etc/eiotpkg/config/stage/k5key/k5key.json"
    ACCOUNT_FILE_PATH = "/tmp/k5key.json"
    REGION = "jp-east-3"
    fjcs_client = FjcsClient(REGION , ACCOUNT_FILE_PATH)
    token_string = fjcs_client.get_token()

    network_id = "cfb61908-ec99-495c-9b2d-872e6116065a"
    floating_ip_id = "ac4e6ee6-78cc-4904-a2ee-b69b516839c7"
    subnetwork_id = "09f949b6-fe42-401f-991b-1a6a492f7594"
    subnetwork_name="stress-operation_subnet"
#    fjcs_client.create_port(token_string, network_id)
#    fjcs_client.create_port(token_string, network_id)
    print(fjcs_client.update_subnetwork_name( token_string, subnetwork_id,  subnetwork_name ))
    print(fjcs_client.get_subnetwork(token_string))
    print(fjcs_client.get_subnetwork(token_string))
    
    ports = fjcs_client.get_port(token_string)
    port_infos = ports["ports"]
    
#    lb = fjcs_client.update_loadbalancer_name(token_string, "9848b200-b7f5-4a9d-aaa4-17f1c748e639", "operation_lb")
#    print(lb)
#    print("name, id, mac_address, ip_address, status")
#    for port_info in port_infos:
#        port_info_dict = port_info
#        fixed_ips_info = port_info_dict["fixed_ips"]
#        print("%s, %s, %s, %s, %s" % (port_info_dict["name"], port_info_dict["id"], port_info_dict["mac_address"],fixed_ips_info[0]["ip_address"], port_info_dict["status"]))
#       
    # グローバルIP    
    #fjcs_client.update_floating_ip(token_string, port_id, floating_ip_id)
    #floating_ips = fjcs_client.get_floating_ip(token_string, floating_ip_id)

if __name__ == "__main__":

    main()
---

import json
import urllib.request
import fjcs

"""FJCS for OSSのAPIからポート情報一覧をCSV形式で表示する

    本モジュールは公式ドキュメントを元にしたFJCS for OSSのAPIトークンを取得するPythonプログラムである
    https://doc.cloud.global.fujitsu.com/lib/iaas/jp/api-user-guide/index.html#task/task_deployment_of_shell_jp.html

Examples:

    ::
        $ python get_port_list.py | column -t -s,

"""

ACCOUNT_FILE_PATH = "/var/etc/eiotpkg/config/stage/k5key/k5key.json"
REGION = "jp-east-3"

def main():

    fjcs_client = fjcs.FjcsClient(REGION, ACCOUNT_FILE_PATH)
    token_string = fjcs_client.get_token()

    ports = fjcs_client.get_port(token_string)
    port_infos = ports["ports"]

    print("name, id, mac_address, ip_address, status")
    for port_info in port_infos:
        port_info_dict = port_info
        fixed_ips_info = port_info_dict["fixed_ips"]
        print("%s, %s, %s, %s, %s" % (port_info_dict["name"], port_info_dict["id"], port_info_dict["mac_address"],fixed_ips_info[0]["ip_address"], port_info_dict["status"]))
       
        # ポート削除
        #if port_info_dict["name"] == "operation-act_operation-port":
        #if port_info_dict["network_id"] == "cfb61908-ec99-495c-9b2d-872e6116065a":
        #if port_info_dict["name"] == "bridge_operation-port":
        #    port_id = port_info_dict["id"]
      
#            for key, value in port_info.items():
#                print("%s : %s"  % (key, value))
#            print("")


if __name__ == "__main__":

    main()
```