Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ConoHa CLI

[ConoHa API](https://www.conoha.jp/docs/) を CLI で良しなに扱うための何か。
[ConoHa VPS Ver.3.0 の公開 API](https://doc.conoha.jp/reference/api-vps3/) を CLI で良しなに扱うための何か。

自分が使うために作ったものなので、使わない機能は実装していません。

Expand All @@ -11,28 +11,30 @@
```json
{
"endpoint": {
"identity": "https://identity.tyo1.conoha.io/v2.0",
"compute": "https://compute.tyo1.conoha.io/v2/{tenant_id}",
"network": "https://networking.tyo1.conoha.io/v2.0"
"identity": "https://identity.c3j1.conoha.io/v3",
"compute": "https://compute.c3j1.conoha.io/v2.1",
"network": "https://networking.c3j1.conoha.io/v2.0",
"image": "https://image-service.c3j1.conoha.io/v2",
"volume": "https://block-storage.c3j1.conoha.io/v3/{テナントID}"
}
}
```

エンドポイントの設定をここに記述します。
ConoHa のコンソール画面に表示されているものを使って作成してください。
`identity`, `compute`, `network` の3つが必要です
`identity`, `compute`, `network`, `image`, `volume` が必要です

### `~/.conoha/credential.json`

```json
{
"user_name": "{user_name}",
"password": "{password}",
"tenant_id": "{tenant_id}"
"tenant_name": "{tenant_name}",
"password": "{password}"
}
```

API ユーザのユーザ名・パスワードとテナント ID をここに記述します
API ユーザのユーザ名、テナント名、パスワードをここに記述します
ファイルが無ければ `conoha auth login` コマンド実行時に入力を求められます。
入力された内容は `credential.json` に保存されます。

Expand Down
97 changes: 20 additions & 77 deletions conoha/api/compute.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,49 @@
"""
Compute API の呼び出し部分
"""

import base64

from conoha import config
from conoha.util import http

endpoint = config.get_config()["endpoint"]["compute"]
token = config.get_token()


def list_flavors():
"""
https://www.conoha.jp/docs/compute-get_flavors_list.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.get(f"{endpoint}/flavors", headers)


###########################################################################


def list_images():
"""
https://www.conoha.jp/docs/compute-get_images_list.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
return http.get(f"{endpoint}/images", headers)


###########################################################################


def list_servers():
"""
通常: https://www.conoha.jp/docs/compute-get_vms_list.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.get(f"{endpoint}/servers", headers)


def list_servers_detail():
"""
詳細表示: https://www.conoha.jp/docs/compute-get_vms_detail.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.get(f"{endpoint}/servers/detail", headers)


def describe_server(server_id):
"""
https://www.conoha.jp/docs/compute-get_vms_detail_specified.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.get(f"{endpoint}/servers/{server_id}", headers)


def create_server(
image_ref,
volume_id,
flavor_ref,
admin_pass=None,
key_name=None,
security_groups=None,
instance_name_tag=None,
volume_id=None,
vnc_keymap=None,
user_data=None,
):
"""
https://www.conoha.jp/docs/compute-create_vm.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}

headers = {"Accept": "application/json", "X-Auth-Token": token}
# 必須項目
data = {"server": {"imageRef": image_ref, "flavorRef": flavor_ref}}

data = {
"server": {
"block_device_mapping_v2": [{"uuid": volume_id}],
"flavorRef": flavor_ref,
}
}
# Optional 項目
if admin_pass is not None:
data["server"]["adminPass"] = admin_pass
Expand All @@ -86,10 +55,6 @@ def create_server(
data["server"]["security_groups"].append({"name": security_group})
if instance_name_tag is not None:
data["server"]["metadata"] = {"instance_name_tag": instance_name_tag}
if volume_id is not None:
data["server"]["block_device_mapping"] = {"volume_id": volume_id}
if vnc_keymap is not None:
data["server"]["vncKeymap"] = vnc_keymap
if user_data is not None:
# 生の文字列を BASE64 エンコードに変換する
data["server"]["user_data"] = base64.b64encode(
Expand All @@ -99,59 +64,37 @@ def create_server(


def start_server(server_id):
"""
https://www.conoha.jp/docs/compute-power_on_vm.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
data = {"os-start": None}
return http.post(f"{endpoint}/servers/{server_id}/action", data, headers)


def stop_server(server_id, force):
"""
通常停止: https://www.conoha.jp/docs/compute-stop_cleanly_vm.php
強制停止: https://www.conoha.jp/docs/compute-stop_forcibly_vm.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
data = {"os-stop": None}
if force:
data["os-stop"] = {"force_shutdown": True}
data["os-stop"] = {"force_shutdown": True} # type: ignore
return http.post(f"{endpoint}/servers/{server_id}/action", data, headers)


def delete_server(server_id):
"""
https://www.conoha.jp/docs/compute-delete_vm.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.delete(f"{endpoint}/servers/{server_id}", headers)


###########################################################################


def attach_port(server_id, port_id):
"""
https://www.conoha.jp/docs/compute-attach_port.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
data = {"interfaceAttachment": {"port_id": port_id}}
return http.post(f"{endpoint}/servers/{server_id}/os-interface", data, headers)


def detach_port(server_id, port_id):
"""
https://www.conoha.jp/docs/compute-dettach_port.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.delete(
f"{endpoint}/servers/{server_id}/os-interface/{port_id}", headers
)


def list_ports(server_id):
"""
https://www.conoha.jp/docs/compute-get_attached_ports_list.php
"""
headers = {"Accept": "application/json", "X-Auth-Token": config.get_token()["id"]}
headers = {"Accept": "application/json", "X-Auth-Token": token}
return http.get(f"{endpoint}/servers/{server_id}/os-interface", headers)
18 changes: 7 additions & 11 deletions conoha/api/identity.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
"""
Identity API の呼び出し部分
"""

from conoha import config
from conoha.util import http

endpoint = config.get_config()["endpoint"]["identity"]


def get_token(user_name, password, tenant_id):
"""
https://www.conoha.jp/docs/identity-post_tokens.php
"""
def get_token(user_name, password, tenant_name):
headers = {"Accept": "application/json"}
data = {
"auth": {
"passwordCredentials": {"username": user_name, "password": password},
"tenantId": tenant_id,
"identity": {
"methods": ["password"],
"password": {"user": {"name": user_name, "password": password}},
},
"scope": {"project": {"name": tenant_name}},
}
}
return http.post(f"{endpoint}/tokens", data, headers)
return http.post_for_token(f"{endpoint}/auth/tokens", data, headers)
11 changes: 11 additions & 0 deletions conoha/api/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from conoha import config
from conoha.util import http

endpoint = config.get_config()["endpoint"]["image"]
token = config.get_token()


def list_images():
headers = {"Accept": "application/json", "X-Auth-Token": token}
# TODO: クエリパラメータでいい感じに検索できるようにしたい
return http.get(f"{endpoint}/images?limit=200", headers)
Loading