HUAWEI CLOUD组件库使用分享

HUAWEI CLOUD分享

import json
import random

from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkcore.http.http_config import HttpConfig
from huaweicloudsdkecs.v2 import *
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkims.v2 import ImsClient, ListImagesRequest
from huaweicloudsdkims.v2.region.ims_region import ImsRegion
from huaweicloudsdkvpc.v2 import ListSubnetsRequest, VpcClient, ListVpcsRequest, CreateVpcRequest, CreateVpcOption, \
    CreateVpcRequestBody, CreateSubnetRequest, CreateSubnetOption, CreateSubnetRequestBody, ListSecurityGroupsRequest, \
    CreateSecurityGroupRequest, CreateSecurityGroupOption, CreateSecurityGroupRequestBody, \
    DeleteSecurityGroupRuleRequest, CreateSecurityGroupRuleRequest, CreateSecurityGroupRuleOption, \
    CreateSecurityGroupRuleRequestBody
from huaweicloudsdkvpc.v2.region.vpc_region import VpcRegion

from base.international import t_
from app import app_settings
from app.applications import logger


def try_catch(func_name):
    def decorator(func):
        def execute(*args, **kwargs):
            try:
                response = func(*args, **kwargs)

                return response
            except exceptions.ClientRequestException as e:
                error_msg = f'status_code={e.status_code}, request_id={e.request_id}, error_code={e.error_code}, ' \
                            f'error_msg={e.error_msg}'
                logger.error(f'【{func_name}-异常(HW)】:{error_msg}')

                raise Exception(t_('【{0}-异常(HW)】:{1}').format(func_name, error_msg), True)

            except Exception as ex:
                error_msg = f'ex={str(ex)}'
                logger.error(f'【{func_name}-异常(HW)】:{error_msg}')

                raise Exception(t_('【{0}-异常(HW)】:{1}').format(func_name, error_msg), True)

        return execute

    return decorator


class _HWCloudBaseHandler(object):

    def __init__(self, project_name, ak, sk, timeout=None):
        self.project_name = project_name  # 所属项目/区域
        self.ak = ak
        self.sk = sk
        self.admin_pass = app_settings.ADMIN_PASS
        self.timeout = timeout  # 超时时间 (connect timeout, read timeout)
        self.image_name = app_settings.DEFAULT_IMAGE_NAME
        self.vpc_data = app_settings.DEFAULT_VPC_DATA
        self.vpc_subnet_data = app_settings.DEFAULT_VPC_SUBNET_DATA
        self.security_groups_name = app_settings.DEFAULT_SECURITY_GROUP_NAME
        self.security_group_rules = app_settings.SECURTY_GROUP_RULES
        self.root_volume_type = app_settings.ROOT_VOLUME_TYPE  # 系统盘类型
        self.data_volume_type = app_settings.DATA_VOLUME_TYPE  # 数据盘类型
        self.data_volume_size = app_settings.DATA_VOLUME_SIZE  # 数据盘大小
        self.eip_type = app_settings.EIP_TYPE  # EIP的类型: 静态BGP
        self.eip_size = app_settings.EIP_SIZE  # 带宽大小
        self.eip_share_type = app_settings.EIP_SHARE_TYPE  # 带宽共享类型:独享
        self.eip_charge_mode = app_settings.EIP_CHARGE_MODE  # 带宽计费类型:按流量计费

    def ecs_client(self):
        """
        初始化 弹性云服务器(ESC)客户端
        https://support.huaweicloud.com/sdkreference-mpc/mpc_05_0076.html
        添加日志:.with_file_log()
        """
        credentials = BasicCredentials(self.ak, self.sk)
        region = EcsRegion.value_of(self.project_name)

        ecs_client = EcsClient.new_builder() \
            .with_credentials(credentials) \
            .with_region(region) \
            .with_http_config(self.http_config) \
            .build()

        return ecs_client

    def vpc_client(self):
        """
        初始化 虚拟私有云 客户端
        https://support.huaweicloud.com/sdkreference-mpc/mpc_05_0076.html
        """
        credentials = BasicCredentials(self.ak, self.sk)
        region = VpcRegion.value_of(self.project_name)

        vpc_client = VpcClient.new_builder() \
            .with_credentials(credentials) \
            .with_region(region) \
            .with_http_config(self.http_config) \
            .build()

        return vpc_client

    def image_client(self):
        """
        初始化 镜像 客户端
        https://support.huaweicloud.com/sdkreference-mpc/mpc_05_0076.html
        """
        credentials = BasicCredentials(self.ak, self.sk)
        region = ImsRegion.value_of(self.project_name)

        image_client = ImsClient.new_builder() \
            .with_credentials(credentials) \
            .with_region(region) \
            .with_http_config(self.http_config) \
            .build()

        return image_client

    @property
    def http_config(self):
        """
        默认连接超时时间为60秒,读取超时时间为120秒
        :param timeout: (connect timeout, read timeout)
        """
        http_config = HttpConfig.get_default_config()

        if self.timeout:
            http_config.timeout = self.timeout

        return http_config

    @classmethod
    def format_server_ids(cls, server_ids):
        return [ServerId(id=item) for item in server_ids]

    @classmethod
    def format_response(cls, response):
        json_response = json.loads(str(response))
        if json_response.get('error'):
            raise Exception(
                f'error_code={json_response["error"]["code"]}, error_message={json_response["error"]["message"]}')

        return json_response


class _HWListAvailabilityZones(_HWCloudBaseHandler):

    @try_catch('查询可用区列表')
    def list_available_zones(self):
        """
        查询可用区列表
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=NovaListAvailabilityZones
        :returns: list of available
        """
        request = NovaListAvailabilityZonesRequest()
        response = self.ecs_client().nova_list_availability_zones(request)
        zone_list = response.availability_zone_info

        return [item.zone_name for item in zone_list]


class _HWListFlavors(_HWCloudBaseHandler):

    @try_catch('查询规格详情和规格扩展信息列表')
    def list_flavors(self, zone_name):
        """
        查询可用区可用规格
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=ListFlavors
        :returns: list of flavors
        """
        request = ListFlavorsRequest()
        request.availability_zone = zone_name
        response = self.ecs_client().list_flavors(request)
        flavor_list = response.flavors

        return [item.id for item in flavor_list]


class _HWListImages(_HWCloudBaseHandler):

    @try_catch('查询镜像列表')
    def list_images(self, image_name=None):
        """
        查询镜像列表
        https://console.huaweicloud.com/apiexplorer/#/openapi/IMS/debug?locale=zh-cn&consoleCurrentProductId=ims&consoleCurrentProductshort=&api=ListImages
        """
        _image_name = image_name or self.image_name

        request = ListImagesRequest()
        request.name = _image_name
        response = self.image_client().list_images(request)

        return json.loads(str(response))['images']

    def filter_images(self, image_name=None):
        """
        根据 image_name 进行过滤,返回匹配的ID
        """
        _image_name = image_name or self.image_name
        image_list = self.list_images(_image_name)

        for item in image_list:
            if _image_name == item.get('name'):
                return item['id']


class _HWListVpcs(_HWCloudBaseHandler):

    @try_catch('查询VPC列表')
    def list_vpcs(self):
        """
        查询VPC列表
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/doc?api=ListVpcs&version=v2
        """
        request = ListVpcsRequest()
        response = self.vpc_client().list_vpcs(request)

        return json.loads(str(response))['vpcs']

    def filter_vpcs(self, vpc_name=None):
        """
        根据vpc_name进行过滤,返回匹配的ID
        """
        _vpc_name = vpc_name or self.vpc_data['name']
        vpc_list = self.list_vpcs()

        for item in vpc_list:
            if _vpc_name == item.get('name'):
                return item['id']


class _HWListSubnets(_HWCloudBaseHandler):

    @try_catch('查询子网列表')
    def list_subnet(self, vpc_id):
        """
        查询 vpc_id 子网信息
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/doc?api=ListSubnets&version=v2
        """
        request = ListSubnetsRequest()
        request.vpc_id = vpc_id
        response = self.vpc_client().list_subnets(request)

        return json.loads(str(response))['subnets']

    def filter_subnets(self, vpc_id, subnet_name=None):
        """
        根据 subnet_name 进行过滤,返回匹配的ID
        """
        _subnet_name = subnet_name or self.vpc_subnet_data['name']
        subnet_list = self.list_subnet(vpc_id)

        for item in subnet_list:
            if _subnet_name == item.get('name'):
                return item['id']


class _HWListSecurityGroup(_HWCloudBaseHandler):

    @try_catch('查询安全组列表')
    def list_security_groups(self, vpc_id):
        """
        根据 vpc_id 查询对应安全组
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/sdk?version=v2&api=ListSecurityGroups
        """
        request = ListSecurityGroupsRequest()
        request.vpc_id = vpc_id
        response = self.vpc_client().list_security_groups(request)

        return json.loads(str(response))['security_groups']

    def filter_security_groups(self, vpc_id, security_groups_name=None):
        """
        根据 security_groups_name 进行过滤,返回匹配的ID
        """
        _security_groups_name = security_groups_name or self.security_groups_name
        security_groups_list = self.list_security_groups(vpc_id)

        for item in security_groups_list:
            if _security_groups_name == item.get('name'):
                return item['id']


class _HWShowJob(_HWCloudBaseHandler):

    @try_catch('查询任务的执行状态')
    def job_status(self, job_id):
        """
        查询任务的执行状态,成功SUCCESS、RUNNING运行中、FAIL失败、INIT正在初始化、PENDING_PAYMENT待支付
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=ShowJob
        :param job_id: Job id
        return:
        {
            "job_id": "ff8080828848fa840189239bd5ef6c1f",
            "job_type": "createServer",
            "begin_time": "2023-07-05T01:12:42.733Z",
            "end_time": "2023-07-05T01:13:50.062Z",
            "status": "SUCCESS",
            "error_code": null,
            "fail_reason": null,
            "entities": {
                "sub_jobs_total": 1,
                ...
            }
        }
        """
        request = ShowJobRequest()
        request.job_id = job_id
        response = self.ecs_client().show_job(request)

        return json.loads(str(response))


class _HWServiceDetails(_HWCloudBaseHandler):

    @try_catch("查询云服务器详情列表")
    def server_details(self, server_ids=None, limit=None):
        """
        查询云服务器详情列表
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=ListServersDetails
        :param server_ids: 服务器server_id列表
        :param limit: 显示多少条,默认25,最大500
        return:
        """
        request = ListServersDetailsRequest()

        if server_ids:
            request.server_id = server_ids[:500]

        if limit:
            request.limit = limit

        response = self.ecs_client().list_servers_details(request)
        # logger.info(f'server_id:{server_id}, res: {response}')

        return json.loads(str(response))['servers']


class _HWCreateServers(_HWCloudBaseHandler):

    @try_catch("创建云服务器(按需)")
    def create_server(self, server_name, image_id, flavor_ref, vpcid, subnet_id, security_groups=None,
                      admin_pass=None, tags=None, count=1):
        """
        创建云服务器(按需):异步
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=CreatePostPaidServers
        :param server_name: 服务器名,str
        :param image_id: 镜像ID,str
        :param flavor_ref: 规格名称,如:s6.small.1,str
        :param vpcid: vpc id, str
        :param subnet_id: 所属vpc的子网id
        :param security_groups: 安全组列表,list
        :param admin_pass: 服务器密码(一般私有镜像无效),str
        :param tags: 服务器标签,如:{"key": key, "value": value},dict
        :param count: 创建台数,int
        return:
        {
            "job_id": "ff808082739334d80173941567f21d4f",
            "serverIds": [
                "118258c5-0c6a-4e73-8b51-8d1ea3272e1b",
                "e51b9e20-7088-4914-a4f3-6c76bcfed0be"
            ]
        }
        """
        logger.info(f'【创建云服务器(按需)-开始】name={server_name},  region={self.project_name}, image_id={image_id}')

        server_body = PostPaidServer(
            name=server_name,
            image_ref=image_id,
            admin_pass=admin_pass or self.admin_pass,
            availability_zone=self.get_availability_zone(flavor_ref),
            data_volumes=self.get_data_volume(),
            flavor_ref=flavor_ref,
            nics=self.get_subnets(subnet_id),
            publicip=self.get_public_cip(),
            root_volume=self.get_volume_type(),
            server_tags=self.get_server_tags(tags),
            vpcid=vpcid,
            count=count,
            is_auto_rename=False,
            security_groups=self.get_security_groups(security_groups)
        )

        request = CreatePostPaidServersRequest()
        request.body = CreatePostPaidServersRequestBody(
            server=server_body
        )
        response = self.ecs_client().create_post_paid_servers(request)
        logger.info(f'【创建云服务器(按需)-请求成功】name={server_name}, image_id={image_id}, res={response}')

        return self.format_response(response)

    @classmethod
    def get_server_tags(cls, server_tags):
        if server_tags is None:
            return

        return [
            PostPaidServerTag(
                key=server_tags['key'],
                value=server_tags['value']
            )
        ]

    def get_data_volume(self):
        """
        数据盘
        """
        return [
            PostPaidServerDataVolume(
                volumetype=self.data_volume_type,
                size=self.data_volume_size
            )
        ]

    def get_volume_type(self):
        """
        系统盘类型
        """
        return PostPaidServerRootVolume(
            volumetype=self.root_volume_type
        )

    def get_public_cip(self):
        """
        配置云服务器的弹性IP信息
        """
        return PostPaidServerPublicip(
            eip=self.get_eip()
        )

    def get_eip(self):
        """
        配置云服务器自动分配弹性IP时, 创建弹性IP的配置参数
        """
        return PostPaidServerEip(
            iptype=self.eip_type,
            bandwidth=self.get_bandwidth_eip()
        )

    def get_bandwidth_eip(self):
        """
        弹性IP地址带宽参数
        """
        return PostPaidServerEipBandwidth(
            size=self.eip_size,
            sharetype=self.eip_share_type,
            chargemode=self.eip_charge_mode
        )

    def get_subnets(self, subnet_id):
        return [PostPaidServerNic(subnet_id=subnet_id)]

    def get_security_groups(self, security_groups):
        """
        构造安全组数据
        :param security_groups: 安全组列表
        """

        return [PostPaidServerSecurityGroup(id=item) for item in security_groups]

    def get_availability_zone(self, flavor_ref):
        """
        根据规格筛选可用可用区
        (部分规格在部分可用区无法使用)
        """
        zone_list = _HWListAvailabilityZones(project_name=self.project_name, ak=self.ak, sk=self.sk).list_available_zones()

        if not zone_list:
            raise Exception(f'当前区域:{self.project_name} 无可用区可用')

        available_flavor_zone = []
        for item in zone_list:
            res = _HWListFlavors(project_name=self.project_name, ak=self.ak, sk=self.sk).list_flavors(item)
            if flavor_ref in res:
                available_flavor_zone.append(item)

        return random.choice(available_flavor_zone)


class _HWStopServer(_HWCloudBaseHandler):

    @try_catch('批量关闭云服务器')
    def stop_servers(self, server_ids):
        """
        批量关闭云服务器:异步,最大1000
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=BatchStopServers
        :param server_ids: 服务器server_id列表
        return:
        {
            "job_id": "70a599e0-31e7-49b7-b260-868f441e862b"
        }
        """
        logger.info(f'【批量关闭云服务器-开始】server_ids=[{server_ids}]')

        request = BatchStopServersRequest()
        request.body = BatchStopServersOption(
            servers=self.format_server_ids(server_ids)
        )
        response = self.ecs_client().batch_stop_servers(request)
        logger.info(f'【批量关闭云服务器-请求成功】server_ids=[{server_ids}], response={response}')

        return self.format_response(response)


class _HWRestartServer(_HWCloudBaseHandler):

    @try_catch('批量重启云服务器')
    def restart_servers(self, server_ids, type='SOFT'):
        """
        重启服务器:异步
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=BatchRebootServers
        :param server_ids: 服务器server_id列表
        :param type: 重启类型,SOFT/HARD
        return:
        {
            "job_id": "70a599e0-31e7-49b7-b260-868f441e862b"
        }
        """
        logger.info(f'【批量重启云服务器-开始】server_ids=[{server_ids}]')

        request = BatchRebootServersRequest()
        request.body = BatchRebootServersRequestBody(
            reboot=BatchRebootSeversOption(
                servers=self.format_server_ids(server_ids),
                type=type
            )
        )
        response = self.ecs_client().batch_reboot_servers(request)
        logger.info(f'【批量重启云服务器-请求成功】server_ids=[{server_ids}], response={response}')

        return self.format_response(response)


class _HWReinstallServer(_HWCloudBaseHandler):

    @try_catch('重装弹性云服务器操作系统(未安装Cloud init)')
    def reinstall_server(self, server_id):
        """
        重装弹性云服务器操作系统(开机状态下重建会先关闭服务器,再进行重建)
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=ReinstallServerWithoutCloudInit
        :param server_id: 服务器server_id
        return:
        {
            "job_id": "70a599e0-31e7-49b7-b260-868f441e862b"
        }
        """
        logger.info(f'【重装弹性云服务器操作系统(未安装Cloud init)-开始】server_id=[{server_id}]')

        request = ReinstallServerWithoutCloudInitRequest()
        request.server_id = server_id

        os_reinstall_body = ReinstallServerWithoutCloudInitOption(
            mode="withStopServer"
        )
        request.body = ReinstallServerWithoutCloudInitRequestBody(
            os_reinstall=os_reinstall_body
        )

        response = self.ecs_client().reinstall_server_without_cloud_init(request)
        logger.info(
            f'【重装弹性云服务器操作系统(未安装Cloud init)-请求成功】server_ids=[{server_id}], response={response}')

        return self.format_response(response)


class _HWDeleteServer(_HWCloudBaseHandler):

    @try_catch('删除云服务器')
    def delete_servers(self, server_ids):
        """
        删除服务器:异步
        https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=DeleteServers
        :param server_ids: 服务器server_id列表
        return:
        {
            "job_id": "70a599e0-31e7-49b7-b260-868f441e862b"
        }
        """
        logger.info(f'【删除云服务器-开始】server_ids=[{server_ids}]')

        request = DeleteServersRequest()
        request.body = DeleteServersRequestBody(
            servers=self.format_server_ids(server_ids),
            delete_volume=True,
            delete_publicip=True
        )
        response = self.ecs_client().delete_servers(request)
        logger.info(f'【删除云服务器-请求成功】server_ids=[{server_ids}], response={response}')

        return self.format_response(response)


class _HWCreateVpcs(_HWCloudBaseHandler):

    @try_catch('创建VPC')
    def create_vpcs(self):
        """
        创建VPC
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/doc?api=CreateVpc&version=v2
        """
        request = CreateVpcRequest()
        vpcbody = CreateVpcOption(
            cidr=self.vpc_data['cidr'],
            name=self.vpc_data['name'],
            description=self.vpc_data['description']
        )
        request.body = CreateVpcRequestBody(
            vpc=vpcbody
        )
        response = self.vpc_client().create_vpc(request)

        return json.loads(str(response))['vpc']['id']


class _HWCreateVpcSubnet(_HWCloudBaseHandler):

    @try_catch('创建子网')
    def create_vpc_subnet(self, vpc_id):
        """
        创建子网
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/doc?api=CreateSubnet&version=v2
        """
        request = CreateSubnetRequest()
        subnetbody = CreateSubnetOption(
            name=self.vpc_subnet_data['name'],
            description=self.vpc_subnet_data['description'],
            cidr=self.vpc_subnet_data['cidr'],
            vpc_id=vpc_id,
            gateway_ip=self.vpc_subnet_data['gateway_ip'],
            dhcp_enable=self.vpc_subnet_data['dhcp_enable']
        )
        request.body = CreateSubnetRequestBody(
            subnet=subnetbody
        )
        response = self.vpc_client().create_subnet(request)

        return json.loads(str(response))['subnet']['id']


class _HWCreateSecurityGroup(_HWCloudBaseHandler):

    @try_catch('查询安全组列表')
    def create_security_groups(self, vpc_id):
        """
        创建默认安全组
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/debug?version=v2&api=CreateSecurityGroup
        """
        request = CreateSecurityGroupRequest()
        securityGroupbody = CreateSecurityGroupOption(
            name=self.security_groups_name,
            vpc_id=vpc_id
        )
        request.body = CreateSecurityGroupRequestBody(
            security_group=securityGroupbody
        )
        response = self.vpc_client().create_security_group(request)

        return json.loads(str(response))['security_group']

    def create_security_groups_rules(self, group_id):
        for group_rule in self.security_group_rules:
            request = CreateSecurityGroupRuleRequest()
            securityGroupRulebody = CreateSecurityGroupRuleOption(
                security_group_id=group_id,
                direction=group_rule["direction"],
                ethertype=group_rule["ethertype"]
            )
            request.body = CreateSecurityGroupRuleRequestBody(
                security_group_rule=securityGroupRulebody
            )
            self.vpc_client().create_security_group_rule(request)

    def delete_security_groups_rules(self, rule_ids):
        """
        删除安全组规则
        https://console.huaweicloud.com/apiexplorer/#/openapi/VPC/debug?version=v2&api=DeleteSecurityGroupRule
        """
        for rule_id in rule_ids:
            request = DeleteSecurityGroupRuleRequest()
            request.security_group_rule_id = rule_id
            self.vpc_client().delete_security_group_rule(request)


class HWQueryManager(_HWListAvailabilityZones,
                     _HWListImages,
                     _HWListSubnets,
                     _HWListVpcs,
                     _HWListFlavors,
                     _HWListSecurityGroup,
                     _HWShowJob,
                     _HWServiceDetails):
    """
    查询类
    """
    pass


class HWOperateManger(_HWCreateServers,
                      _HWStopServer,
                      _HWRestartServer,
                      _HWReinstallServer,
                      _HWDeleteServer,
                      _HWCreateVpcSubnet,
                      _HWCreateVpcs,
                      _HWCreateSecurityGroup):
    """
    操作类
    """
    pass


class HWServerManager(HWQueryManager,
                      HWOperateManger):
    pass


'''
使用示例:
# 查询VPC下的子网
res = HWServerManager().get_subnets()
print(res)

# [{"subnet_id": "93089f63-ba1e-2345-8b7a-8c58b5c123678"}]
'''

settings文件:根据实际情况填写

```python
# 账户信息
HUAWEI_CLOUD_USERNAME = 'username'
HUAWEI_CLOUD_AK = "ak"  # 私有密钥,导出
HUAWEI_CLOUD_SK = "sk"  # 私有密钥,导出

# 磁盘
ROOT_VOLUME_TYPE = "SSD"  # 系统盘类型
DATA_VOLUME_TYPE = "SSD"  # 数据盘类型
DATA_VOLUME_SIZE = 40

# 弹性IP信息
EIP_SHARE_TYPE = "PER"  # 带宽共享类型:独享
EIP_CHARGE_MODE = 'traffic'  # 带宽计费类型:按流量计费
EIP_TYPE = '5_sbgp'  # EIP的类型: 静态BGP
EIP_SIZE = 1  # 带宽大小

# 镜像名
DEFAULT_IMAGE_NAME = "image_name"

# 安全组
DEFAULT_SECURITY_GROUP_NAME = "vpn_security_group"

# VPC网络配置
DEFAULT_VPC_DATA = {
    "cidr": "10.10.0.0/16",
    "name": "vpn_vpc",
    "description": "用于vpn网络"
}

# VPC 子网配置
DEFAULT_VPC_SUBNET_DATA = {
    "name": "vpn_subnet",
    "description": "用于vpn_vpc的子网",
    "cidr": "10.10.10.0/24",
    "gateway_ip": "10.10.10.254",
    "dhcp_enable": True
}

# 安全组规则,放行所有
SECURTY_GROUP_RULES = [
    {"direction": "egress", "ethertype": "IPv4"},
    {"direction": "egress", "ethertype": "IPv6"},
    {"direction": "ingress", "ethertype": "IPv4"},
    {"direction": "ingress", "ethertype": "IPv6"},
]

# 系统密码
ADMIN_PASS = 'admin_pass'

# 安全组
DEFAULT_SECURITY_GROUPS = ['feebe7f3-fdad-4b14-81c8-90febc5ea6c2']

# 查询异步job结果最长间隔
QUERY_SERVER_STATUS_INTERVAL = 120

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值