NeutonOS
    NeutonOS
    • 产品 API 使用指南
    • SDDC
      • 概览
        • overview
          • /overview/
      • 计算
        • 虚拟机
          • virtual-machines
            • /virtual-machines/
            • /virtual-machines/
            • /virtual-machines/{clone}
            • /virtual-machines/{id}
            • /virtual-machines/{id}
            • /virtual-machines/{id}
            • /virtual-machines/{id}/{failure-migrate}
            • /virtual-machines/{id}/{flatten}
            • /virtual-machines/{id}/{migrate}
            • /virtual-machines/{id}/{reboot}
            • /virtual-machines/{id}/{rollback}
            • /virtual-machines/{id}/{start}
            • /virtual-machines/{id}/{stop}
            • /virtual-machines/{id}/{verify-gpasswd}
          • vm-cd-roms
            • /vm-cd-roms/
            • /vm-cd-roms/
            • /vm-cd-roms/{id}
            • /vm-cd-roms/{id}
          • vm-cleanup-jobs
            • /vm-cleanup-jobs/
            • /vm-cleanup-jobs/{id}
          • vm-disk-cleanup-jobs
            • /vm-disk-cleanup-jobs/
            • /vm-disk-cleanup-jobs/{id}
          • vm-disks
            • /vm-disks/
            • /vm-disks/
            • /vm-disks/{id}
            • /vm-disks/{id}
            • /vm-disks/{id}
          • vm-migration-jobs
            • /vm-migration-jobs/
            • /vm-migration-jobs/{id}
          • vm-nic-cleanup-jobs
            • /vm-nic-cleanup-jobs/
            • /vm-nic-cleanup-jobs/{id}
          • vm-nics
            • /vm-nics/
            • /vm-nics/
            • /vm-nics/{id}
            • /vm-nics/{id}
            • /vm-nics/{id}
          • vm-scheduling-rules
            • /vm-scheduling-rules/
            • /vm-scheduling-rules/
            • /vm-scheduling-rules/{id}
            • /vm-scheduling-rules/{id}
        • 虚拟机快照
          • vm-cd-rom-snaps
            • /vm-cd-rom-snaps/
            • /vm-cd-rom-snaps/{id}
          • vm-disk-snaps
            • /vm-disk-snaps/
            • /vm-disk-snaps/{id}
          • vm-nic-snaps
            • /vm-nic-snaps/
            • /vm-nic-snaps/{id}
          • vm-snaps
            • /vm-snaps/
            • /vm-snaps/
            • /vm-snaps/{id}
            • /vm-snaps/{id}
            • /vm-snaps/{id}
        • 镜像
          • vm-images
            • /vm-images/
            • /vm-images/
            • /vm-images/{id}
            • /vm-images/{id}
            • /vm-images/{id}
            • /vm-images/{id}:upload
          • os-releases
            • /os-releases/
            • /os-releases/{id}
      • 网络
        • 虚拟交换机
          • nics
            • /nics/
            • /nics/{id}
          • vsws
            • /vsws/
            • /vsws/
            • /vsws/{id}
            • /vsws/{id}
            • /vsws/{id}
            • /vsws/{id}/{attach-nics}
            • /vsws/{id}/{detach-nics}
        • 桥接网络
          • br-net-nss
            • /br-net-nss/
            • /br-net-nss/{id}
          • br-nets
            • /br-nets/
            • /br-nets/
            • /br-nets/{id}
            • /br-nets/{id}
            • /br-nets/{id}
          • bridges
            • /bridges/
            • /bridges/{id}
          • l3-nets
            • /l3-nets/
            • /l3-nets/{id}
      • 块存储
        • 块存储策略
          • bs-policies
            • /bs-policies/
            • /bs-policies/
            • /bs-policies/summary
            • /bs-policies/{id}
            • /bs-policies/{id}
            • /bs-policies/{id}
        • 块存储卷
          • bs-volumes
            • /bs-volumes/
            • /bs-volumes/
            • /bs-volumes/{clone}
            • /bs-volumes/{id}
            • /bs-volumes/{id}
            • /bs-volumes/{id}
            • /bs-volumes/{id}/{flatten}
            • /bs-volumes/{id}/{rollback}
        • 卷快照
          • bs-snaps
            • /bs-snaps/
            • /bs-snaps/
            • /bs-snaps/{id}
            • /bs-snaps/{id}
            • /bs-snaps/{id}
      • 弹性存储
        • 存储池
        • 硬盘
      • 集群
        • 拓扑
          • chassises
            • /chassises/
            • /chassises/
            • /chassises/{id}
            • /chassises/{id}
            • /chassises/{id}
            • /chassises/{id}/{switch-chassis}
          • data-centers
            • /data-centers/
            • /data-centers/
            • /data-centers/{id}
            • /data-centers/{id}
            • /data-centers/{id}
          • racks
            • /racks/
            • /racks/
            • /racks/{id}
            • /racks/{id}
            • /racks/{id}
          • rooms
            • /rooms/
            • /rooms/
            • /rooms/{id}
            • /rooms/{id}
            • /rooms/{id}
        • 节点
          • nodes
            • /nodes/
            • /nodes/
            • /nodes/summary
            • /nodes/{id}
            • /nodes/{id}
            • /nodes/{id}
            • /nodes/{id}/{unset-role-check}
            • /nodes/{ip}/node-info
          • node-validators
            • /node-validators/
            • /node-validators/
            • /node-validators/{id}
      • 运维管理
        • 监控分析
          • metrics
            • /metrics/alert
            • /metrics/label-names/{metric}
            • /metrics/label-values/{metric}/{label_name}
            • /metrics/monitor
          • monitor-views
            • /monitor-views/
            • /monitor-views/
            • /monitor-views/{id}
            • /monitor-views/{id}
            • /monitor-views/{id}
            • /monitor-views/{id}/{reset-to-default}
          • samples
            • /samples/query
            • /samples/query-range
        • 告警信息
          • alerts
            • /alerts/
            • /alerts/stats
            • /alerts/{id}
            • /alerts/{id}
        • 告警规则
          • alert-rules
            • /alert-rules/
            • /alert-rules/
            • /alert-rules/{id}
            • /alert-rules/{id}
            • /alert-rules/{id}
          • flows
            • /flows/
            • /flows/
            • /flows/{id}
          • email-configs
            • /email-configs/
            • /email-configs/{id}
            • /email-configs/{id}
        • 事件
          • events
            • /events/
            • /events/{id}
        • 审计日志
          • audit-logs
            • /audit-logs/
            • /audit-logs/{id}
      • 标签管理
        • label-keys
          • /label-keys/
          • /label-keys/
          • /label-keys/{id}
          • /label-keys/{id}
        • label-values
          • /label-values/
          • /label-values/
          • /label-values/{id}
          • /label-values/{id}
          • /label-values/{id}/{attach}
          • /label-values/{id}/{detach}
      • 权限访问
        • tokens
          • /tokens/{login}
          • /tokens/{logout}
          • /tokens/{reauth-in-project}
      • 加密
        • rsa-keys
          • /rsa-keys/
      • 用户管理
        • users
          • /users/
          • /users/
          • /users/{verify-password}
          • /users/{id}
          • /users/{id}
          • /users/{id}
          • /users/{id}/{allow-login}
          • /users/{id}/{set-default-project}
          • /users/{id}/{ui-profile}
          • /users/{id}/{ui-profile}
          • /users/{id}/projects
          • /users/{id}/projects/{project_id}/{set-role}
        • roles
          • /roles/
          • /roles/{id}
        • projects
          • /projects/
          • /projects/
          • /projects/{id}
          • /projects/{id}
          • /projects/{id}
          • /projects/{id}/{add-user}
          • /projects/{id}/{remove-user}
          • /projects/{id}/users
      • 产品信息
        • version
          • /version/
        • license-summary
          • /license-summary/
      • 系统设置
        • settings
          • /settings/
          • /settings/
        • sysctl-confs
          • /sysctl-confs/
          • /sysctl-confs/{id}
        • cluster-topologies
          • /cluster-topologies/
          • /cluster-topologies/{id}
          • /cluster-topologies/{id}/{failover}
        • cluster-failover-histories
          • /cluster-failover-histories/
          • /cluster-failover-histories/{id}
    • SDS
      • action-logs
        • /action-logs/
        • /action-logs/{action_log_id}
      • alert-info-groups
        • /alert-info-groups/
        • /alert-info-groups/report
        • /alert-info-groups/stats
        • /alert-info-groups/{alert_info_group_id}
        • /alert-info-groups/{alert_info_group_id}
        • /alert-info-groups/{alert_info_group_id}:ack
        • /alert-info-groups/{alert_info_group_id}:resolve
      • alert-infos
        • /alert-infos/
        • /alert-infos/report
        • /alert-infos/stats
        • /alert-infos/{alert_info_id}
        • /alert-infos/{alert_info_id}
        • /alert-infos/{alert_info_id}:ack
        • /alert-infos/{alert_info_id}:resolve
      • alert-rule-groups
        • /alert-rule-groups/
        • /alert-rule-groups/{id}/detail
        • /alert-rule-groups/{id}/detail
      • alert-rules
        • /alert-rules/schema
        • /alert-rules/{rule_id}
        • /alert-rules/{rule_id}
        • /alert-rules/{rule_id}
        • /alert-rules/{rule_id}/blacklist
        • /alert-rules/{rule_id}/blacklist
        • /alert-rules/{rule_id}/blacklist
      • chunks
        • /chunks/{chunk_id}
      • disks
        • /disks/
        • /disks/{disk_id}
        • /disks/{disk_id}
        • /disks/{disk_id}/partitions
        • /disks/{disk_id}/partitions
        • /disks/{disk_id}/samples
      • osds
        • /osds/
        • /osds/
        • /osds/{osd_id}
        • /osds/{osd_id}
        • /osds/{osd_id}/chunks
        • /osds/{osd_id}/predictions
        • /osds/{osd_id}/samples
        • /osds/{osd_id}:activate
        • /osds/{osd_id}:maintain
        • /osds/{osd_id}:rebuild
        • /osds/{osd_id}:switch-role
        • /osds/{osd_id}:unmaintain
        • /osds/{osd_id}:unset-isolation
      • pools
        • /pools/
        • /pools/
        • /pools/{calc-capacity}
        • /pools/{check-full}
        • /pools/{pool_id}
        • /pools/{pool_id}
        • /pools/{pool_id}
        • /pools/{pool_id}/osds
        • /pools/{pool_id}/osds
        • /pools/{pool_id}/predictions
        • /pools/{pool_id}/samples
        • /pools/{pool_id}/topology
        • /pools/{pool_id}:disable-device-type-check
        • /pools/{pool_id}:enable-device-type-check
        • /pools/{pool_id}:initialize
        • /pools/{pool_id}:reweight
        • /pools/{pool_id}:switch-role
        • /pools/{pool_id}:update-ec-crush-rule
        • /pools/{pool_id}:update-gc-policy

    产品 API 使用指南

    产品 API 使用指南

    一、1 分钟例子

    因为 XHERE 的 Auth 方式是使用 API Key,需要在 HTTP 请求的 Header 设置,参数名是 x-sddc-token ,token 值可以通过两种方法获取:

    1. 通过 SSH 登录已安装 XHERE 的主节点,然后使用命令行创建获取 Raw Token。

    2. 在 XHERE 管理平台中的 Access Token 界面中创建得到,此方法需要 V2.2 版本才支持。

    可以在 XHERE 管理面上的“全局设置”-“访问令牌”页面中,可以生成访问令牌。

    获得 token 之后,可以使用 curl 命令,向 XHERE 管理平台发起 HTTP 请求 GET /overview/ 。假设 XHERE 集群的主节点是 10.16.11.91 。

    # curl --location --request \
    GET 'http://10.16.11.91:6012/sddc/v1/overview/' \
    --header 'x-sddc-token: sddc-***'
    

    得到响应如下。

    {
     "stats": {
      "vm_num": 5,
      "vm_running_num": 5,
      "vm_stopped_num": 0,
      "vm_running_cpu_num": 28,
      "vm_available_cpu_num": 24,
      "vm_running_memory_mb": 20480,
      "vm_available_memory_mb": 114688,
      "vm_disk_num": 6,
      "vm_nic_num": 7,
      "vm_image_num": 4,
      "vm_snap_num": 1,
      "bs_volume_num": 11,
      "node_num": 2,
      "node_cpu_num": 32,
      "node_memory_mb": 131072
     }
    

    二、学习和调试工具

    查看和调试 OpenAPI 的工具

    可以使用 Swagger/Postman/Apifox 工具导入本产品的 OpenAPI Json 文件。

    本产品的 OpenAPI/Swagger 数据 URL 地址是:

    • SDDC API: http://{XHERE管理节点IP地址}/docs/sddc_openapi.json

    • SDS API: http://{XHERE管理节点IP地址}/docs/sds_openapi.json

    活 API 字典

    可以在 XHERE 产品中各个资源的审计日志中看到“非 GET 的 API 请求”,可以点击【请求内容】,查看具体 API 请求的参数内容。因此可以通过查看操作路径和请求内容,在情景中快速学习到此 API 请求的具体用法,方便第三方系统对接。

    三、API Auth 方式

    XHERE 的 API Auth 方式是使用 API Key,需要在 HTTP 请求的 Header 设置,参数名是 x-sddc-token ,token 值可以通过两种方法获取:

    1. 通过 SSH 登录已安装 XHERE 的主节点,然后使用命令行创建获取 Raw Token。

    2. 在 XHERE 管理平台中的 Access Token 界面中创建得到,此方法需要 V2.2 版本才支持。

    这里介绍下使用命令行方式创建获取 Raw Token,假设 XHERE 集群的主节点是 10.16.11.91,通过 SSH 登录此节点,然后通过 sddc-cli user login -u admin -p {password} 获得 Raw Token。注意 Raw Token 的默认生效时间是 1 小时。

    ➜  ~ ssh root@10.16.11.91
    Last login: Tue Nov  8 00:12:03 2022 from 10.3.0.205
    [root@node-91 ~]#
    [root@node-91 ~]# sddc-cli user login -u admin -p admin
    ******
    [root@node-91 ~]#
    

    四、API 敏感字段加密

    XHERE API 中对敏感字段需要进行加密。对涉及敏感数据的接口调用,需要做如下处理:

    1. 客户端先调用一个接口获取public key,然后用public key加密敏感数据,最后调用接口,发送加密后的密文。
    2. 服务端使用public key对应的private key解密获得明文,进行后续业务处理。

    以用户登录为例

    用户登录操作需要发送2个请求

    1. 创建RSA key。服务端会生成RSA key(包含一对private key和public key),关联uuid,放入缓存中,有效期5分钟。返回响应中有public key,uuid,expiration。

    样例:
    POST /sddc/rsa-keys

    Response Body

    {
        "data": {
            "rsaKeyCreateOne": {
                "expiration": "2022-02-10T14:13:48.165748404+08:00",
                "publicKey": "MIGJAoGBAORO/+TrJSnoaR2bXlf4SqYr7EXiUjxnDAl1oOvPaC3RuiB/Fjx+rsAnDWoDS195d6jyd2V//m3KN7m8s+/c6kKtInC8inAjzhRJHlBO0j11bOxIH1ynD/Dn866bBPCGJiY8rWx3+cjnQfbQ+rG9qJFExPzlgJhip5baWYLkh3b/AgMBAAE=",
                "uuid": "f494dd2184a14551ab96ed04412edb98",
                "__typename": "RsaKey"
            }
        }
    }
    
    1. 提交用户登录信息。客户端使用public key加密敏感字段(用户密码),并在请求参数中带上public key对应的uuid。服务端收到请求后,会根据uuid从缓存中找到RSA key,解密敏感字段。进行后续业务处理(此处是验证密码,生成token)。

    样例:
    POST /sddc/tokens/:login

    Request Body

    {"data":{"name":"admin","password":"GTEDpzHHbuhvk1uZE8eexuPSeDLb1H52xOhuh7XfaRYEzr5vEuJPIFeAtRAShlL/FCaRuaNIG5AFZLEbOgOKqhdXZGazhqGQ1g/51ZCFwQkfLllxulJpesXfgRbQAXjN/cXkq9J7CctiK07hgwYn1IgsfK/2PSfvGdLZQ+Or8Fc=","rsaKeyUuid":"f494dd2184a14551ab96ed04412edb98"}}
    

    Response Header

    set-cookie: X_SDDC_TOKEN=******; max-age=3600; Path=/;
    

    Response Body

    {"data":{"tokenLogin":{"data":{"id":4,"name":"","etag":"6c3057ef-54fe-40b4-a222-076b561910bc","uuid":"d8ac595019894363a6f1350f0df80d61","valid":true,"__typename":"TokenData"},"__typename":"Token"}}}
    

    需要加密处理的字段

    • UserData.Password
    • EmailConfigData.Password
    • VirtualMachineSpec.GraphicsPassword
    • VirtualMachineSpec.OsUserPassword

    需要加密处理的接口

    接口名称URI敏感字段
    用户登录POST /sddc/tokens/:loginUserData.Password
    创建用户POST /sddc/users/UserData.Password
    更新用户PATCH /sddc/users/{id}UserData.Password
    验证用户密码POST /sddc/users/:verify-passwordUserData.Password
    创建email服务器配置POST /sddc/email-configs/EmailConfigData.Password
    更新email服务器配置PATCH /sddc/email-configs/{id}EmailConfigData.Password
    创建虚拟机POST /sddc/virtual-machines/VirtualMachineSpec.GraphicsPassword
    VirtualMachineSpec.OsUserPassword
    更新虚拟机PATCH /sddc/virtual-machines/{id}VirtualMachineSpec.GraphicsPassword

    Python 程序举例

    import requests
    import base64
    from cryptography.hazmat.primitives import serialization
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding
    api = "http://localhost:6012/sddc/v1"
    user_api = f"{api}/users"
    rsa_key_api = f"{api}/rsa-keys"
    login_api = f"{api}/tokens/:login"
    def get_rsa_key():
        resp = requests.post(rsa_key_api, headers={"content-type": "application/json"})
        return resp.json()
    def login(name, password, rsa_key):
        uuid = rsa_key["uuid"]
        key = base64.b64decode(rsa_key["public_key"])
        key = serialization.load_der_public_key(key)
        crypted = key.encrypt(password.encode(), padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
          )
        )
        encrypted_passwd = base64.b64encode(crypted).decode()
        data = {"data": {"name": name, "password": encrypted_passwd, "rsa_key_uuid": uuid}}
        resp = requests.post(login_api, json=data)
        return resp.json()
    rsa_key = get_rsa_key()
    token = login("admin", "admin", rsa_key)
    print(token["data"]["uuid"])
    

    五、API 设计规范

    声明式 API

    Kubernetes 流行的一个原因是采用了声明式 API。声明式 API 是一套基于期望状态的系统,用户通过向该系统提出一个期望状态来达成特定的目的。使用声明式 API,用户不需要告诉该系统具体要执行哪些步骤,只需要告诉该系统:我希望哪个资源处于哪种状态。

    XHERE 产品从设计开始就采用声明式 API,声明式 API 可以对用户屏蔽系统实现的复杂性,提升 API 的使用体验,有助于实现 IaC。但是,对于一套复杂系统来说,无差别的使用声明式 API 可能会带来不必要的复杂性,因此 XHERE 也在必要的地方使用命令式 API。

    ResourceModel

    在 SDDC 平台中,我们以 resource 的粒度来管理业务。Resource 可能是虚拟机,存储,网络等硬件资源,也可能是告警,角色等平台所需的软件虚拟资源。SDDC 会对外暴露 REST API 来管理这些资源。

    术语

    • Model Layout 是指我们如何为一个 resource 设计它的 model 使用方式。

    • ResourceType 是指 SDDC 中管理的某种资源,例如 VirtualMachine, VmDisk, AlertRule, Alert 等。

    • Resource 则是指单个资源

    • ResourceList 是指某个资源类型的列表

    Resource

    Resource 是个抽象的概念,包含一个资源的全部信息。Resource 分为两个部分:metadata and data:

    • Metadata:包含可以用于定位这个资源的相关信息,以及可以确定这个资源整体状态的相关信息。这些信息本身都是存在 data 中的某些对象里,只是构建 resource 的过程中被提取出来放到 metadata 中。

    • Data:包含实际存放在数据库中的信息。一个资源的 data 部分可能会存在多个表中,这样的一个表我们称为一个 object。data 部分中的 object 在 resource 中如何摆放,属于下文要提到的 model layout 讨论的范畴。

    所以,一个 resource 的结构示例如下:

    {
        "metadata": {},
        "object1": {},
        "object2": {}
     }
    

    ResourceList

    ResourceList 就是由 resource 组成的列表。ResourceList 分为两个部分:metadata and items:

    • Metadata:包含这个列表相关的信息,比如分页信息 Pagination 等。

    • Items:包含这个列表的元素。其中每个元素都是一个 resource。

    一个 ResourceList 的结构示例如下:

    {
        "metadata": {
            "pagination": {}
        },
        "items": [
            {},
            {}
        ]
    }
    

    两种 Model Layout

    在 SDDC 中,一开始就要在资源的数据中表达出资源的当前状态和期望状态。但是,有些资源并不需要区分当前状态和期望状态,例如 alert,事件日志等,这些资源,我们也需要设计一个适合的 model 形式来表达。

    这样,我们就有两种 model 表达需求:

    • 区分当前状态和期望状态

    • 不区分当前状态和期望状态(当前状态 = 期望状态)

    不同的表达需求,对应不同的 model 设计形式,这种设计形式,我们称为 layout,即每种表达形式都有自己的 model layout。Model layout 描述的是 Resource 的 data 部分的结构。

    第一种 Model Layout: Metadata/Spec/Status

    这种类型的 model 分为 3 个部分:

    • Metadata

    • Spec:包含用户对于资源的期望状态

    • Status:包含资源的当前状态

    {
        "metadata": {},
        "spec": {},
        "status": {}
    }
    

    Get Resource

    无论是 GET 一个资源,或者 LIST 多个资源,都是以资源的 Spec 表为准。

    Create Resource

    当用户要创建一个资源时,提交的是 Spec。

    对于新建的资源,Spec.CreationFinish = nil,表示资源创建还未完成;当资源创建完成后,这个值就会被设置为一个有效的时间。

    Update Resource

    我们说用户要修改一个资源,指的是 修改这个资源的期望状态,即修改 Spec。

    Delete Resource

    我们会通过 update-to-deleted 来实现删除操作,避免直接删除。

    但是当用户通过 API 发起一个删除请求时,资源是异步删除的(Spec/Stats layout 一定是这样的),所以,在删除完成之前,用户还要能够从 API 里读取到这个资源。我们使用如下实现方案。

    1. Spec 表增加两个字段:DeletionBegin 和 DeletionFinish。这两个字段都是时间类型,允许为空,非空表示设置过。

    2. API 请求删除一个资源时,设置 Spec.DeletionBegin 字段,表示这个资源开始要被删除。

    3. 当系统后台执行完资源的实际删除操作后,设置 Spec.DeletionFinish。

    4. 系统后台发现 Spec.DeletionFinish 已经被设置,则设置 deleted_at 字段的值。这个字段执行过后,API 无法再查询到这个记录,虽然它还在数据库中。

    Resource Metadata

    PropetyRequiredDescription
    id or uuidyes. 这两个二选一资源 id
    name资源名称
    created_atyes资源的创建时间
    creation_finish资源创建完成的时间
    deletion_begin资源被标记为删除的时间
    deletion_finish资源删除操作执行完成的时间。注意,不是从数据库中删除的时间。

    状态表达

    根据 metadata,可以得到一个资源的状态:

    条件状态
    created_at != nil AND creation_finish == nil创建中
    created_at != nil AND creation_finish != nil创建完成
    deletion_begin != nil AND deletion_finish == nil删除中
    deletion_begin != nil AND deletion_finish != nil删除操作完成
    deletion_begin != nil AND deletion_finish != nilORM 已删除。
    Row deletedDeleted from database

    可能在回收站中

    AND deleted_at != nil

    Soft deleted, wait GC

    第二种 Model Layout: Metadata/Data

    这种类型的 model 分为两个部分:

    • Metadata

    • Data:resource 的 data 部分不再进行细分。

    • 包含资源的数据表的相关内容。

    这种类型的 model 在 API 操作是比较直接的,所有的操作都作用于 data 字段,data 字段只是为了规范 model layout 而增加的一层抽象。

    When

    这个 layout 适用于最简单的资源表达方式:资源只需要一张数据库表,每个资源对应这个表的一行。

    Get Resource

    直接调用 model 层封装的 list 接口即可。

    无论是 GET 一个资源,或者 LIST 多个资源,都是以资源的 Spec 表为准。

    Create Resource

    当用户要创建一个资源的时候,提交的是一个 data。

    Update Resource

    如果是用户提出修改请求,可以通过 PUT,PATCH 等请求提交一个 data。

    Delete Resource

    通过 API 的 delete 请求实现。

    Resource Metadata

    每个 resource 都具有如下的元数据:

    PropetyRequiredDescription
    id or uuidyes. 这两个二选一资源 id
    name资源名称
    created_atyes资源的创建时间

    状态表达

    根据 metadata,可以得到一个资源的状态:

    条件状态
    created_at != nil创建完成
    deletion_begin != nil AND deletion_finish != nilORM 已删除。
    Row deletedDeleted from database

    AND deleted_at != nil

    Soft deleted, wait GC

    六、API 使用规范

    我们的 API 是 REST ( Representational state transfer) 风格的,我们设计的 API 在路径、动词的使用、以及返回结果上都需要尽量满足 REST 标准,并在 REST 标准之外提供一些灵活性(这里最主要是指 POST action 这种操作,见下文描述)

    API 路径

    XHERE 包括两种类型的 API,本文只讨论 SDDC 类型。XHERE API 监听端口是 6012。

    • SDDC API: http://{XHERE管理节点IP地址}:6012/sddc/v1/

    • SDDC Sample API:

    • SDS API: http://{XHERE管理节点IP地址:6012/sds/v1/

    • SDS Sample API:

    PATH Style

    这个 PATH 的完整结构如下:

    /sddc/v1/{resource-type}/{uuid|id}[:action-name]?[&queries]
    

    参数解释:

    • resource_type : 我们的资源类型的路径形式,例如 virtual-machiens, vm-disks 等。

    • uuid | id : 资源的标识符。

    • action=action_name : 表示一个 action,具体使用方法见下文。

    • 其他 query 参数。

    Body Style

    API 请求和响应的 body 都是 JSON object。在 Body 形式上,在 SDDC 中,我们将 Resource 或者 ResouceList 的 JSON 格式直接返回。

    Requeset Body

    API 请求时的 body 包含的内容根据 model layout 的不同而不同,但是都是直接包含对应的 object 对象。与 SDS 的对比如下:

    SDS API

    // 相关数据会放在一个资源名称(单数)的子 object 下。
    POST /sds/v1/osds
    {
        "osd": {
            "disk_id": 1
        }
    }
    

    SDDC API

    以 Spec/Status layout 举例:

    // 相关数据直接作为 resource object
    POST /sddc/v1/virtual-machines
    {
        "spec": {}
    }
    

    Response Body

    响应内容的对比如下:

    SDS 的 API

    // 获取单个资源,相关数据会放在一个资源名称(单数)的子 object 下。
    GET /sds/v1/osds/1/
    {
      "osd": {
        "id"
      }
    }
    
    
    // 获取列表,相关数据会放在一个资源名称(复数)的子 object 下,同时还有一个 paging 的子 object 返回分页相关的信息。
    GET /sds/v1/osds
    {
      "osds": [
        {
          "id": 1
        },
        {
          "id": 2
        }
      ],
      "paging": {
      }
    }
    

    SDDC 的 API

    以 Spec/Status layout 举例:

    // 获取单个资源,相关数据直接作为返回的 JSON object。
    GET /sddc/v1/virtual-machines/{uuid}
    {
      "metadata": {
        "uuid": "uuid1"
      },
      "spec": {},
      "status": {}
    }
    
    
    // 获取列表,会有一个统一的列表数据返回格式作为返回的 JSON object。
    GET /sddc/v1/virtual-machines
    {
      "metadata": {
        "pagination": {}
      },
      "items": [
        {
          "metadata": {
            "uuid": "uuid1"
          },
          "spec": {},
          "status": {]
        },
        {
          "metadata": {
            "uuid": "uuid2"
          },
          "spec": {},
          "status": {]
        }
      ]
    }
    

    总的来说,API 有两种响应形式:

    • 单个资源

    • 单个资源主要是返回资源类型所定义的 model 数据,根据 model layout 来返回。

    • 多个资源

    • 其返回格式是全局定义的,见下文。

    多个资源的 Response: ResourceList

    响应的 body 定义如下:

    {
      "metadata": {
        "pagination": {}
      },
      "items": [
        { /* item1 */ },
        { /* item2 */ }
      ]
    }
    

    每个 item 内的数据同单个资源的响应,与单独 get 这个资源时获得的数据一致。

    Resource Operations

    我们可以对资源或者资源类型发起一个操作,即 operation。operation 是由 method, path, query, req body 形成的一个组合。

    Model Layout 1: Metadata, Spec and Status

    METHODPATHQuery LimitReq Body LimitResp CodeResp BodyDescription
    POST/sddc/v1/{resource-type}- metadata (optional)- 201Resource创建一个资源。
    GET/sddc/v1/{resource-type}/{uuid, id}null- 200Resource获取一个资源。
    GET/sddc/v1/{resource-type}- paging parameters (optional)null- 200ResourceList获取多个资源
    PATCH/sddc/v1/{resource-type}/{uuid, id}- metadata (optional)- 200 如果资源没有修改Resource修改一个资源的期望状态。只能用于修改 spec 中的标量字段,即普通类型字段,不能是 array 类型或者 object 类型的字段。
    DELETE/sddc/v1/{resource-type}/{uuid, id}null- 202Resource删除一个资源
    POST/sddc/v1/{resource-type}/{uuid, id}:{action}- 202Resource对某个资源执行一个操作。

    no: 禁止

    optional: 可选

    must: 必选

    • spec (must)

    • status (no)

    • spec (must)

    • status (no)

    • 202 如果资源被修改了

    Ref: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/

    可以用于修改 spec 中的非标量字段,即数组和类型。

    如果 action 以 get- 开头,表示这个 API 是只读 API。

    Model Layout 2: Metadata and Data

    METHODPATHQuery LimitReq Body LimitResp CodeResp BodyDescription
    POST/sddc/v1/{resource-type}- metadata (optional)- 201Resource创建一个资源。
    GET/sddc/v1/{resource-type}/{uuid, id}null- 200Resource获取一个资源。
    GET/sddc/v1/{resource-type}- paging parameters (optional)null- 200Resource List获取多个资源
    PATCH/sddc/v1/{resource-type}/{uuid, id}- metadata (optional)- 200Resource修改一个资源的指定字段。
    DELETE/sddc/v1/{resource-type}/{uuid, id}null- 204Resource获取一个资源
    POST/sddc/v1/{resource-type}/{uuid, id}:{action}- 202Resource对某个资源执行一个操作。

    no: 禁止

    optional: 可选

    must: 必选

    • data (must)

    • data (must)

    如果 action 以 get- 开头,表示这个 API 是只读 API。

    分页 Pagination

    Offset Based

    所有的 List API 都支持此种类型的分页。API 在处理时,会按照如下的顺序处理请求里的 query 参数:

    1. 字段查询参数。

    2. 排序参数。

    3. 分页参数。

    Offset based 分页方式是我们产品里提供的一种遍历所有资源的方式。作为一个基础架构的产品,我们需要让用户在必要的时候可以处理所有的资源,所以必须提供一种遍历所有资源的方式。

    参数设计

    参数位置合法值默认值说明
    offsetquery>= 00
    limitquery> 0100

    返回值

    分页的返回值存放在 ListMeta 的一个子对象中:

    {
        "metadata": {
            "pagination": {
                "offset": {offset},
                "limit": {limit},
                "count": {count},
                "total_count": {total_count}
            }
        }
    }
    

    Example

    GET /sddc/v1/compute/virutal-machines?offset=11&limit=10
    
    {
        "metadata": {
            "pagination": {
                "offset": 11,
                "limit": 10,
                "count": 10,
                "total_count": 99
            }
        },
        "items": {
        }
    }
    

    API 通用查询 & 排序

    查询

    Venus 针对资源列表 api,实现了通用的查询语法。在 api 查询参数中,通过设置“q”查询参数的值,就可以实现对资源的列表过滤。比如:列出 vm id 为 1 的虚拟机所有的硬盘,示例如下:

    GET /sddc/v1/vm-disks/?q=spec.virtual_machine_id:1

    查询参数 q 会被解析为一组基本字段条件、逻辑运算符(可选)和括号(可选)组成。

    基本查询

    基本字段条件包括四部分:字段名称、":"分隔符、比较运算符(可选)和值。

    其中,资源的所以字段都有对应的字段名称,包括如下三种类型:

    • data.,比如告警的严重等级,对应的字段名称为 data.severity

    • spec.,比如虚拟机名称,对应的字段名称为 spec.name

    • status.,比如虚拟机的当前运行状态,对应的字段名称为 status.power_state

    比较运算符,包括如下七种类型:

    • =,等于(默认值)

    • <>,不等于

    • ,大于

    • =,大于等于

    • <,小于

    • <=,小于等于

    • ~,正则匹配

    比如:列出 size_mb 大于 1024 的所有虚拟机硬盘,示例如下:

    GET /sddc/v1/vm-disks/?q=spec.size_mb:>1024

    特别的,有时我们需要查询字段为空,或者非空的资源,我们引入了"null" 和 "exists"两个特殊字段名称。

    • 过滤出被虚拟机使用中的所有虚拟机硬盘

    GET /sddc/v1/vm-disks/?q=exists:status.virtual_machine_id

    • 过滤出没被虚拟机使用的所有虚拟机硬盘

    GET /sddc/v1/vm-disks/?q=null:status.virtual_machine_id

    • 过滤出所有名称以 test 开头的虚拟机。":~"后面可以跟所有常见的正则表达式语法

    GET /sddc/v1/virtual-machines/?q=spec.name:~^test

    • 过滤出名称包含 test 的虚拟机

    GET /sddc/v1/virtual-machines/?q=spec.name:~test

    多个值的集合查询

    除了基本的比较运算符以外,我们还基于数据库的 IN 查询语法实现了基于多个值的集合查询。注意,集合查询只支持 =(等于)和 <>(不等于)两种运算符。

    示例如下,筛选出操作系统名称为 CentOS 7 或者 Centos 8 的镜像。

    GET /sddc/v1/images/?q=spec.os_name:("CentOS 7" "CentOS 8")

    筛选出操作系统名称不为 CentOS 7 或者 Centos 8 的镜像。

    GET /sddc/v1/images/?q=spec.os_name:<>("CentOS 7" "CentOS 8")

    如果值中不包含空格字符,可以省略掉引号,不同值之间只用空格分隔。示例如下,筛选出名称为 image-1 或者 image-3 的镜像。

    GET /sddc/v1/images/?q=spec.name:(image-1 image-2)

    示例,查询 id 为 1 或者 2 的存储策略。

    GET /sddc/v1/bs-policys/?q=data.id:(1 2)

    SDS 资源,比如 pool 和 osd,多值查询使用 SDS 的语法;SDDC 资源使用上面所示的 SDDC 语法,不要带 OR。

    GET /sds/v1/pools/?q=id:(1 OR 2 OR 3)

    日期时间查询

    对于日期类型,我们目前要求日期格式满足 RFC3339,并通过如下语法实现 range 查询。使用中括号,表示包含边界的 range 查询 [min TO max];使用花括号,表示不包含边界的 range 查询 {min TO max}。* 表示通配符,比如:

    • 创建于 2021 年的虚拟机硬盘

    GET /sddc/v1/vm-disks/?q=spec.created_at:[2021-01-01T00:00:00.00Z TO 2022-01-01T00:00:00.00Z}

    • 创建于 2021 年和之后的虚拟机硬盘

    GET /sddc/v1/vm-disks/?q=spec.created_at:[2021-01-01T00:00:00.00Z TO *}

    组合字段

    除了基本字段条件以外,通用查询还支持通过使用逻辑运算符和括号,对多个基本字段条件进行组合。逻辑运算符目前支持 AND 和 OR 两种。其中 AND 运算符高于 OR 运算符,比如

    GET /sddc/v1/vm-disks/?q=size_mb:>1024 OR spec.virtual_machine_id:1 AND status.virtual_machine_id:1

    等同于

    GET /sddc/v1/vm-disks/?q=size_mb:>1024 OR (spec.virtual_machine_id:1 AND status.virtual_machine_id:1)

    值包含空格

    如果查询条件中值包含有空格,则需要使用双引号将值扩起来,比如:

    GET /sddc/v1/os-releases/?q=data.name:"Windows 7"

    GET /sddc/v1/xxxxxx/?q=spec.yyyy:"aaaa bbb ccc"

    排序

    在 api 查询参数中,通过设置 "sort" 排序参数的值实现对资源列表的排序,值选项如下:

    • data.:desc,data.:desc,...... 降序

    • data.:asc,data.:asc,...... 升序

    • spec.:desc,spec.:desc,...... 降序

    • spec.:asc,spec.:asc,...... 升序

    • data.:desc,data.:asc,...... 混合

    • spec.:desc,spec.:asc,...... 混合

    支持多个字段排序,每一个字段排序可选为 desc、asc,如果没有指定,则默认为 desc 即降序。如果 sort 不设置,则查询结果默认以 id desc 排序。

    示例 1,列出虚拟机硬盘,根据 id 降序:

    /sddc/v1/vm-disks/?sort=spec.id:desc

    示例 2,列出节点,根据名称降序:

    /sddc/v1/nodes/?sort=spec.name:desc

    • 声明式 API

    • SDDC 和 SDS

    • Access Token

    七、资源关系

    分类中文英文所属功能模块
    集群数据中心DataCenter拓扑
    机房Room拓扑
    机架Rack拓扑
    机框Chassis拓扑
    节点Node节点
    弹性存储物理盘Disk存储池
    硬盘Osd硬盘
    存储池Pool存储池
    块存储块存储策略BsPolicy块存储策略
    块存储卷BsVolume块存储卷
    卷快照BsSnap卷快照
    网络虚拟交换机Vsw虚拟交换机
    网卡Nic虚拟交换机
    桥接网络BrNet桥接网络
    桥接网络命名空间BrNetNs桥接网络
    网桥Bridge桥接网络
    三层网络L3Net桥接网络
    三层网路 IP 区间L3NetIpRange桥接网络
    计算镜像VmImage镜像
    虚拟机VirtualMachine虚拟机
    虚拟网卡VmNic虚拟机
    虚拟硬盘VmDisk虚拟机
    虚拟光盘VmCdRom虚拟机
    虚拟机快照VmSnap虚拟机快照
    虚拟网卡快照VmNicSnap虚拟机快照
    虚拟硬盘快照VmDiskSnap虚拟机快照
    虚拟光盘快照VmCdRomSnap虚拟机快照
    虚拟机调度规则VmSchedulingRule虚拟机
    虚拟机迁移任务VmMigrationJob虚拟机
    运维管理告警信息Alert告警信息
    告警规则AlertRule告警规则
    审计日志AuditLog审计日志
    告警邮件配置EmailConfig
    事件Event事件
    监控指标Metric监控分析
    监控视图MonitorView监控分析
    监控数据点Sample监控分析
    告警信息组AlertInfoGroup告警信息
    告警规则组AlertRuleGroup告警规则
    操作日志ActionLog

    八、资源状态

    XHERE 的资源有两种 Model Layout(参考“二、API 设计规范”)。但是不论哪种 layout,我们都没有一个专门的字段来表示这个资源的当前状态。这主要是因为我们这套系统,资源的状态很复杂,不适合只使用一个字段来表达资源的当前状态了。但对于用户来说,还是需要知道一个资源的当前状态。

    Spec/Status Layout 的不一致字段的收敛

    我们先来看看 第一种 Model Layout(Metadata/Spec/Status)的字段的特点:字段的收敛。当我们讨论一个字段是否可以收敛时,说明该字段在 Spec 和 Status 中都存在。

    当一个字段在 Spec/Status 的值不同时,有如下两种情况:

    可收敛字段对于大部分的资源和大部分的字段来说,Spec 和 Status 不一致都是可收敛的。比如虚拟机的 CPU number 这种,系统会在合适的时候进行收敛尝试,直到该差异被收敛为止。
    不可收敛字段某些资源的某些字段,在操作失败后,会处于一个无法继续尝试操作的情况,这种字段,就属于不可收敛的字段,系统不会再进行任何尝试。修复的办法是改变 Spec。

    对于第二种 Model Layout(Metadata/Data)来说,我们就不用考虑字段差异收敛的问题了。

    状态分类

    虽然我们不能将资源的状态存储在一个字段中,但是我们还是可以表达出资源的当前状态。

    首先,我们将一个资源的状态进行分类。资源的状态分为两类:

    1. 中间状态

    2. 稳定状态

    什么是中间状态?

    不论是哪种 Model Layout 的资源,都含有以下的中间状态:

    • creating:即资源还未完成创建流程。

    • deleting:资源正在进行删除流程。

    对于 Metadata/Spec/Status,还增加了如下状态:

    • reconciling:资源的 Spec/Status 有差异,正在收敛的过程中。

    辅助状态:irreconcilable

    对于所有的中间状态,都会包含一个特殊的字段,表示这个资源是否有无法收敛的字段。如果存在无法收敛的字段,那么该资源会一直停在当前状态,知道做出一些操作为止,才有可能发生状态变化。

    上述的三个中间状态配合上 irreconcilable 这个辅助状态后,资源的状态解释如下:

    • creating + irreconcilable: 资源创建失败

    • deleting + irreconcilable: 资源删除失败

    • reconciling + irreconcilable: 资源无法收敛

    稳定状态

    以下状态时是稳定状态:

    • deleted(deletion_finish != nil):资源已经完成删除流程。虽然你还能查到该资源,但是它已经不能提供任何服务。

    • active:其他情况下,都属于该状态。

    状态如何展示?

    状态的展示,基本思路是在 API 的 Metadata 中返回资源的总体状态。如果资源正在发生更新,还要返回有差异的字段的信息。

    状态方案设计

    API

    在 API 响应的 Metadata 中增加两个字段:

    • state:是一个字符串,表示该资源的总体状态,可选值如下:

    • creating

    • active

    • deleting

    • deleted

    • reconciling:表示资源正在更新中。

    • diff_fields: 是一个对象,目前还有两个 key

    • reconciling: 内容是一个字段名组成的列表,表示需要收敛的字段有哪些。

    • irreconcilable: 内容是一个字段名组成的列表,表示有哪些字段是不可收敛的。

    • 当这个列表不为空时,表示辅助状态 irreconcilable 为 true。

    • 这个列表的字段都会在 reconciling 列表中。

    返回值示例如下:

    {
      "metadata": {
        "state": {
          "state": "reconciling",
          "diff_fields": {
            "reconciling": [
              "bios",
              "core_num_per_socket",
              "cpu_mode",
              "memory_mb"
            ],
            "irreconcilable": [
              "filed"
            ]
          }
        }
      }
    }
    

    前端展示设计

    • 资源列表页

    • 用独立字段表示 metadata 中的 state,并且可以 hover 展示 diff 的字段信息。

    • 可以根据字段需要,单独设计字段的 diff 样式。

    • 对于 diff 的字段,优先展示 Status 中的值。

    • 资源详情

    • 展示 Spec 和 Status 中的所有信息。

    九、资源操作举例

    集群概览信息获取

    方法说明
    GET /overview/物理资源和虚拟资源的数量统计信息
    GET /settings/集群信息,包括集群名称、集群地址、集群网络段配置、全局 CPU 和内存超分比、全局 VM HA 设置等。
    GET /license-summary/产品许可信息
    GET /version/产品版本信息

    节点信息获取

    方法说明
    GET /nodes/LIST 节点
    GET /modes/{id}获取节点信息


    虚拟机信息获取

    方法说明
    GET /virtual-machines/LIST 虚拟机
    GET /virtual-machines/{id}获取虚拟机信息


    获取虚拟机信息 API 返回数据如下所示。

    {
        "metadata": {
            "id": 10,
            "name": "rongze-test",
            "created_at": "2022-10-31T19:17:56.192352+08:00",
            "creation_finish": "2022-10-31T19:18:08.033611+08:00",
            "project_id": 1,
            "state": {
                "state": "active",
                "diff_fields": {
                    "reconciling": null,
                    "irreconcilable": null
                }
            },
            "labels": []
        },
        "spec": {
            "id": 10,
            "name": "rongze-test",
            "created_at": "2022-10-31T19:17:56.192352+08:00",
            "updated_at": "2022-11-03T18:05:47.976022+08:00",
            "deleted_at": null,
            "creation_finish": "2022-10-31T19:18:08.033611+08:00",
            "deletion_begin": null,
            "deletion_finish": null,
            "etag": "cb1d052e-1d27-4ada-8533-2dafb02ce7fb",
            "project_id": 1,
            "uuid": "89860d8f-37e2-4efc-945b-cbb8ac14c711",
            "description": "",
            "time_zone": "UTC",
            "arch": "x86_64",
            "cpu_num": 4,
            "socket_num": 1,
            "core_num_per_socket": 4,
            "thread_num_per_core": 1,
            "cpu_mode": "host-model",
            "memory_mb": 4096,
            "power_state": "RUNNING",
            "ha_enabled": false,
            "bios": "Legacy",
            "boot_device_order": [
                "DISK",
                "CDROM",
                "NIC"
            ],
            "node_id": 1,
            "dest_node_id": null,
            "graphics_auth_enabled": false,
            "graphics_spice_enabled": false,
            "os_type": "Linux",
            "os_distribution": "CentOS",
            "os_name": "CentOS 7",
            "cloud_init_uuid": "146a1131-83aa-46e9-90ed-b086dbc002d9",
            "hostname": "",
            "os_user_name": "",
            "ssh_public_key": "",
            "user_data": "",
            "hugepage_enabled": false,
            "vm_snap_id": null,
            "flattened": false,
            "rollback_vm_snap_id": null,
            "rollback_time": null,
            "power_action_type": "start",
            "power_action_forced": false,
            "power_action_time": "2022-11-01T11:47:58.964162+08:00"
        },
        "status": {
            "id": 10,
            "created_at": "2022-10-31T19:17:56.193285+08:00",
            "updated_at": "2022-11-03T18:06:05.009698+08:00",
            "deleted_at": null,
            "etag": "d3e23514-9161-4cc9-8c5b-528ac91b08bd",
            "time_zone": "UTC",
            "cpu_num": 4,
            "socket_num": 1,
            "core_num_per_socket": 4,
            "thread_num_per_core": 1,
            "cpu_mode": "host-model",
            "memory_mb": 4096,
            "power_state": "RUNNING",
            "power_state_reason": "migrated",
            "bios": "Legacy",
            "boot_device_order": [
                "DISK",
                "CDROM",
                "NIC"
            ],
            "node_id": 1,
            "dest_node_id": null,
            "vm_migration_job_id": null,
            "launched_at": null,
            "terminated_at": null,
            "graphics_auth_enabled": false,
            "graphics_spice_enabled": false,
            "last_node_id": 1,
            "machine_type": "pc-i440fx-rhel7.6.0",
            "graphics_vnc_port": 5900,
            "graphics_spice_port": null,
            "unschedulable": false,
            "unstoppable": false,
            "flattened": false,
            "rollback_time": null,
            "power_action_time": "2022-11-01T11:47:58.964162+08:00",
            "storage_fenced": false,
            "ip_addresses": [
                "10.16.58.3"
            ],
            "vm_snap_num": 0
        }
    }
    

    查看指定虚拟机下的虚拟硬盘列表

    方法说明
    GET /vm-disks/?q=spec.virtual_machine_id:{id}查看指定虚拟机下的虚拟硬盘列表

    查看指定虚拟机下的虚拟硬盘列表 API 返回数据如下所示。

    {
        "metadata": {
            "pagination": {
                "offset": 0,
                "limit": 100,
                "count": 2,
                "total_count": 2
            }
        },
        "items": [
            {
                "metadata": {
                    "id": 11,
                    "name": "disk-Bg45d",
                    "created_at": "2022-10-31T19:17:56.204107+08:00",
                    "creation_finish": "2022-10-31T19:18:08.020337+08:00",
                    "project_id": 1,
                    "state": {
                        "state": "active",
                        "diff_fields": {
                            "reconciling": null,
                            "irreconcilable": null
                        }
                    },
                    "labels": []
                },
                "spec": {
                    "id": 11,
                    "name": "disk-Bg45d",
                    "created_at": "2022-10-31T19:17:56.204107+08:00",
                    "updated_at": "2022-11-03T18:05:47.98081+08:00",
                    "deleted_at": null,
                    "creation_finish": "2022-10-31T19:18:08.020337+08:00",
                    "deletion_begin": null,
                    "deletion_finish": null,
                    "etag": "1e6d6531-45fd-4552-a0d0-b07bb46e79b8",
                    "project_id": 1,
                    "virtual_machine_id": 10,
                    "node_id": 1,
                    "dest_node_id": null,
                    "bus_type": "Virtio",
                    "size_mb": 102400,
                    "storage_type": "rbd",
                    "bs_policy_id": 2,
                    "bs_volume_id": 19,
                    "vm_image_id": null,
                    "device_index": 1,
                    "root": false,
                    "del_vol_on_del": false,
                    "vhost_enabled": false,
                    "serial": "129c0eebd18c12f7",
                    "vm_disk_snap_id": null,
                    "flattened": false,
                    "rollback_vm_disk_snap_id": null,
                    "rollback_time": null
                },
                "status": {
                    "id": 11,
                    "created_at": "2022-10-31T19:17:56.204394+08:00",
                    "updated_at": "2022-11-03T18:05:48.973948+08:00",
                    "deleted_at": null,
                    "etag": "77631dc8-de90-4601-b589-f0dcc131e294",
                    "size_mb": 102400,
                    "bs_volume_size_mb": 102400,
                    "attached": true,
                    "node_id": 1,
                    "dest_node_id": null,
                    "bus_type": "Virtio",
                    "device_index": 1,
                    "source_name": "pool-290e9a3e56f545d0969a624661b94c0e/129c0eebd18c12f7",
                    "vhost_enabled": false,
                    "flattened": false,
                    "rollback_time": null,
                    "device_address": "0000:00:08.0",
                    "fenced_epoch": null
                }
            },
            {
                "metadata": {
                    "id": 10,
                    "name": "disk-wFdA3",
                    "created_at": "2022-10-31T19:17:56.201656+08:00",
                    "creation_finish": "2022-10-31T19:18:08.02746+08:00",
                    "project_id": 1,
                    "state": {
                        "state": "active",
                        "diff_fields": {
                            "reconciling": null,
                            "irreconcilable": null
                        }
                    },
                    "labels": []
                },
                "spec": {
                    "id": 10,
                    "name": "disk-wFdA3",
                    "created_at": "2022-10-31T19:17:56.201656+08:00",
                    "updated_at": "2022-11-03T18:05:47.981856+08:00",
                    "deleted_at": null,
                    "creation_finish": "2022-10-31T19:18:08.02746+08:00",
                    "deletion_begin": null,
                    "deletion_finish": null,
                    "etag": "2b4cd4d6-710e-45f0-afd3-d0ff605dfcdf",
                    "project_id": 1,
                    "virtual_machine_id": 10,
                    "node_id": 1,
                    "dest_node_id": null,
                    "bus_type": "Virtio",
                    "size_mb": 102400,
                    "storage_type": "rbd",
                    "bs_policy_id": 2,
                    "bs_volume_id": 18,
                    "vm_image_id": 6,
                    "device_index": 0,
                    "root": true,
                    "del_vol_on_del": false,
                    "vhost_enabled": false,
                    "serial": "117f756ad5123b70",
                    "vm_disk_snap_id": null,
                    "flattened": false,
                    "rollback_vm_disk_snap_id": null,
                    "rollback_time": null
                },
                "status": {
                    "id": 10,
                    "created_at": "2022-10-31T19:17:56.20222+08:00",
                    "updated_at": "2022-11-03T18:05:48.976945+08:00",
                    "deleted_at": null,
                    "etag": "dcfc98f8-2225-4393-a21b-c9cd0557189f",
                    "size_mb": 102400,
                    "bs_volume_size_mb": 102400,
                    "attached": true,
                    "node_id": 1,
                    "dest_node_id": null,
                    "bus_type": "Virtio",
                    "device_index": 0,
                    "source_name": "pool-290e9a3e56f545d0969a624661b94c0e/117f756ad5123b70",
                    "vhost_enabled": false,
                    "flattened": false,
                    "rollback_time": null,
                    "device_address": "0000:00:07.0",
                    "fenced_epoch": null
                }
            }
        ]
    }
    

    块存储策略信息获取

    方法说明
    GET /bs-policies/{id}获取块存储策略信息


    获取块存储策略信息 API 返回数据如下所示。

    {
        "metadata": {
            "id": 2,
            "name": "bs-policy",
            "created_at": "2022-10-31T14:46:27.389292+08:00",
            "creation_finish": "2022-10-31T14:46:27.389292+08:00",
            "state": {
                "state": "active"
            },
            "labels": []
        },
        "data": {
            "id": 2,
            "name": "bs-policy",
            "created_at": "2022-10-31T14:46:27.389292+08:00",
            "updated_at": "2022-10-31T14:46:27.389292+08:00",
            "deleted_at": null,
            "creation_finish": "2022-10-31T14:46:27.389292+08:00",
            "deletion_begin": null,
            "deletion_finish": null,
            "etag": "6e29645e-3924-450d-8e33-3ec3801db597",
            "description": "",
            "storage_type": "rbd",
            "sds_pool_id": 3,
            "pool_name": "pool-290e9a3e56f545d0969a624661b94c0e",
            "max_total_bps": 0,
            "burst_total_bps": 0,
            "max_total_iops": 0,
            "burst_total_iops": 0,
            "performance_priority": false,
            "crc_check": false,
            "bs_volume_num": 11,
            "provisioned_size_mb": 798832
        }
    }
    

    虚拟机镜像上传

    虚拟机镜像上传分两个步骤:

    1. 创建镜像,不提供 URL
    2. 上传镜像文件
      这两个步骤对应的 API 分别如下:
    方法说明
    POST /vm-images/创建镜像
    POST /vm-images/{id}:upload上传镜像文件

    创建上传镜像举例:

    curl -H 'x-sddc-token: 651af9ee5aba447cb365a9b75f9dcba2' \
    -H 'Content-Type: application/json' \
    -X POST -L 'http://127.0.0.1:6012/sddc/v1/vm-images/' -d '
    {
        "spec": {
            "arch": "x86_64",
            "bios": "Legacy",
            "bootable": true,
            "bs_policy_id": 1,
            "cloud_config_enabled": true,
            "name": "test",
            "os_name": "CentOS",
            "os_type": "Linux",
            "os_distribution": "CentOS",
            "size_byte": 619511808,
            "type": "vm_disk"
        }
    }'
    

    上传镜像文件举例:

    curl -H 'x-sddc-token: 651af9ee5aba447cb365a9b75f9dcba2' \
    -F 'image=@./CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2' \
    -X POST -L 'http://127.0.0.1:6012/sddc/v1/vm-images/4:upload'
    

    十、批量操作

    在 V2.2 版本会支持 /sddc/v1/batch/ 批量操作 API。

    十一、监控指标获取

    TODO

    十二、API 索引

    使用 OpenAPI 自动生成。

    修改于 2023-03-21 08:46:13
    下一页
    /overview/
    Built with