#
# さくらのクラウド
#
from vcpsdk.plugins.spec import VcpSpecResource
CCI_VERSION = "1.1"
BUILD_VERSION = "20191001"
[ドキュメント]
class VcpSpecResourceSakura(VcpSpecResource):
"""
サンプルコード
.. code-block:: python
spec = sdk.get_spec("sakura", "small")
#
# 変更できること
#
# spec.num_nodes = 1
# spec.params_v = ['/opt:/opt']
# spec.params_e = ['USER_NAME=test']
# spec.ip_addresses = ['起動するnodeの静的なIPアドレス']
# さくらのクラウド依存
# https://sacloud.github.io/terraform-provider-sakuracloud/
# spec.num_cores = 1
# spec.memory = 100
# spec.image = "vcp/base:1.1"
# spec.sakuracloud_disk_plan = 'ssd' # or 'hdd'
# spec.sakuracloud_disk_size = 100
# cloud上のVMイメージ設定
# spec.cloud_image = 'niivcp-20170616'
# base containerにssh loginするためのssh公開鍵情報を設定
spec.set_ssh_pubkey('tmp/id_rsa.pub')
"""
version = CCI_VERSION + "+" + BUILD_VERSION
def __init__(self, provider_name, flavor, config_dir):
# flavor から spec を設定
super().__init__(provider_name, flavor, config_dir)
# spec attributes名の設定チェックの回避
super().__setattr__("sakura_cci_", None)
# credentail情報は、vcp_config から設定
self.sakura_cci_ = {"cci_version": CCI_VERSION}
self.sakura_cci_["token"] = self.vcp_config_["sakura"]["token"]
self.sakura_cci_["secret"] = self.vcp_config_["sakura"]["secret"]
self.unit_cci_["private_network"] = self.vcp_config_["sakura"][
"private_network"
] # VPNネットワーク名
# flavorから初期化
self.sakura_cci_["core"] = self.flavor_["core"]
self.sakura_cci_["memory"] = self.flavor_["memory"]
self.sakura_cci_["sakuracloud_disk_plan"] = self.flavor_[
"sakuracloud_disk_plan"
]
self.sakura_cci_["sakuracloud_disk_size"] = self.flavor_[
"sakuracloud_disk_size"
]
self.sakura_cci_["cloud_image"] = "default"
self.sakura_cci_["server_disks"] = []
self.sakura_cci_["ip_address_list"] = []
def __str__(self):
text = """
========================
{provider_name}
------------------------
{unit_info}
""".format(
provider_name=self.unit_cci_["cloud_provider"], unit_info=super().__str__()
)
text += """
cci_version: "{cci_version}"
core: {core}
memory: {memory}
sakuracloud_disk_plan: {sakuracloud_disk_plan}
sakuracloud_disk_size: {sakuracloud_disk_size}
disks: {server_disks}
cloud_image: {cloud_image}
ip_address_list: {ip_address_list}
========================""".format_map(
self.sakura_cci_
)
return text
# buid cci from property
[ドキュメント]
def cci(self, name):
"""
CCI生成
:param name: unit名
:return: CCI文字列
"""
# cloud parameter 情報
my_cci = super().cci(name)
# yaml schema check
self.cci_schema_.validate(self.sakura_cci_, "sakura")
my_cci = super().cci(name)
my_cci += """
cloud_provider: sakura
cloud_params:
cci_version: "{cci_version}"
core: {core}
memory: {memory}
sakuracloud_disk_plan: {sakuracloud_disk_plan}
sakuracloud_disk_size: {sakuracloud_disk_size}
server_disks: {server_disks}
ip_address_list: {ip_address_list}
cloud_image: {cloud_image}
token: {token}
secret: {secret}""".format_map(
self.sakura_cci_
)
return my_cci
# property: core
@property
def num_cores(self):
"""
Sakuraのクラウドに依存する num_cores
.. note::
* VCP SDK flavorで設定可能
"""
return self.sakura_cci_["core"]
@num_cores.setter
def num_cores(self, v):
self.sakura_cci_["core"] = v
# property: memory
@property
def memory(self):
"""
Sakuraのクラウドに依存する memory
.. note::
* VCP SDK flavorで設定可能
"""
return self.sakura_cci_["memory"]
@memory.setter
def memory(self, v):
self.sakura_cci_["memory"] = v
# property: sakuracloud_disk_plan
@property
def sakuracloud_disk_plan(self):
"""
Sakuraのクラウドに依存する sakuracloud_disk_plan
.. note::
* VCP SDK flavorで設定可能
"""
return self.sakura_cci_["sakuracloud_disk_plan"]
@sakuracloud_disk_plan.setter
def sakuracloud_disk_plan(self, v):
self.sakura_cci_["sakuracloud_disk_plan"] = v
# property: sakuracloud_disk_size
@property
def sakuracloud_disk_size(self):
"""
Sakuraのクラウドに依存する sakuracloud_disk_size (単位:GB)
.. note::
* VCP SDK flavorで設定可能
"""
return self.sakura_cci_["sakuracloud_disk_size"]
@sakuracloud_disk_size.setter
def sakuracloud_disk_size(self, v):
self.sakura_cci_["sakuracloud_disk_size"] = v
# property: disks
@property
def disks(self):
"""
Sakuraに依存するdisk id
"""
return self.sakura_cci_["server_disks"]
@disks.setter
def disks(self, v):
# volume_id は、vol-xxxxxxx 形式 と VcNode の2種類がある
import vcplib
volumes = []
for volume in v:
if isinstance(volume, vcplib.occtr.VcNode):
# VcNode 指定
volume_id = "vcp:{vc_id}:{unit_name}:{disk_id}".format(
vc_id=volume.vc.vcid, unit_name=volume.unit.name, disk_id=volume.id
)
else:
volume_id = volume # vol-xxxxxx指定
volumes.append(volume_id)
self.sakura_cci_["server_disks"] = volumes
# property: ip_addresses
@property
def ip_addresses(self):
"""
SakuraのVPC上の静的ip_address_list
"""
return self.sakura_cci_["ip_address_list"]
@ip_addresses.setter
def ip_addresses(self, v):
"""
SakuraのVPC上の静的ip_address_list
.. note::
`num_nodes` と `ip_addresses` は最後にセットされたほうが有効になる。
"""
if 0 < len(v):
self.unit_cci_["num_nodes"] = len(v)
self.sakura_cci_["ip_address_list"] = v
# property: cloud_image
@property
def cloud_image(self):
"""
Sakuraのクラウドに依存するcloud_image
"""
return self.sakura_cci_["cloud_image"]
@cloud_image.setter
def cloud_image(self, v):
self.sakura_cci_["cloud_image"] = v
def __setattr__(self, name, value):
"""
spec の attributes に不正な値を設定した場合に例外を発生
:param name: attributes名
:param value: 設定値
"""
if not hasattr(self, name):
raise AttributeError("spec resource has no attributes!! [{}]".format(name))
super().__setattr__(name, value)