混合云V2版本OpenAPI
    • 使用说明
    • 网关签名说明
    • 网关常见问题说明
    • 网关EOP签名说明
    • 常见问题
    • 对齐差异list
    • 天翼混合云云管OpenAPI Cli工具使用文档
    • 接口模块域名映射表
    • 混合云OPENAPI 业务对应域名列表
    • 场景实践
      • 调用前准备
      • 1、创建和使用虚拟私有云VPC
      • 2、创建和使用云硬盘
      • 3、创建和使用弹性云主机
      • 4、云硬盘快照的创建和使用
      • 5、云硬盘备份的创建和使用
      • 6、弹性文件系统的创建和使用
      • 7、云主机快照的创建和使用
      • 8、云主机备份的创建和使用
    • 公共分类
      • 查询job信息
        GET
      • job任务查询
        GET
    • 计算
      • 弹性伸缩
        • 查询伸缩活动列表
        • 停用伸缩组中指定策略
        • 启用伸缩组中指定策略
        • 创建一个伸缩组
        • 修改一个伸缩组
        • 查询伸缩组列表
        • 删除一个伸缩组
        • 启用一个伸缩组
        • 停用一个伸缩组
        • 查询伸缩组内云主机的列表,并列出云主机的信息
        • 查询伸缩组的负载均衡器
        • 添加一个或多个负载均衡
        • 删除一个或多个负载均衡
        • 查询伸缩组内的云主机的可用区分布
        • 检查伸缩组是否可修改
        • 修改弹性伸缩组的云主机回收方式
        • 修改弹性伸缩组的健康检查方式
        • 修改弹性伸缩组的健康检查间隔
        • 修改伸缩组最小实例数
        • 修改伸缩组最大实例数
        • 手动添加云主机
        • 从一个伸缩组移出一台或多台ECS实例
        • 移出一台实例并释放
        • 设置云主机保护
        • 开启云主机保护
        • 关闭云主机保护
        • 获取弹性伸缩实例数量监控数据
        • 设置实例移出规则
        • 查询伸缩活动id列表
        • 查询伸缩活动详情
        • 创建一条伸缩策略
        • 修改一条伸缩策略
        • 查询弹性伸缩组内的策略列表
        • 删除一条伸缩策略
        • 执行一条伸缩规则
        • 创建一个定时任务
        • 修改一个定时任务的信息
        • 查询定时任务信息
        • 删除一个定时任务
        • 创建一个告警策略
        • 修改一个报警策略
        • 查询报警任务的信息
        • 删除一个告警策略
        • 启用一条报警策略
        • 停用一条报警策略
        • 创建一个周期策略
        • 创建一个弹性伸缩配置
        • 修改一个弹性伸缩配置
        • 查询弹性伸缩配置
        • 删除一个弹性伸缩配置
        • 检查弹性伸缩组云防火墙
        • 验证用户是否已开通弹性伸缩服务
      • 裸金属
        • 物理机创建_v4_plus
        • 物理机实例委托信息创建
        • 物理机实例委托信息删除
        • 物理机实例委托信息更新
        • 物理机实例委托信息查询
        • 裸金属轻量信息列表-vdc
        • 查询单台物理机
        • 查询单台物理机
        • 查询批量物理机
        • 查询批量物理机
        • 查询指定物理机的套餐信息
        • 查询指定物理机的本地盘raid信息
        • 查询物理机vnc地址
        • 查询物理机可支持的镜像
        • 查询物理机库存
        • 查询物理机所使用镜像的信息
        • 查询物理机本地盘可选择的raid类型
        • 查询物理机的元数据信息
        • 查询资源池内物理机套餐
        • 物理机创建
        • 物理机关机
        • 物理机创建元数据信息
        • 物理机批量更新元数据信息
        • 物理机删除
        • 物理机卸载卷
        • 物理机密码变更
        • 物理机开机
        • 物理机挂载卷
        • 物理机更新安全组
        • 物理机续订
        • 物理机重启
        • 物理机重装系统
      • 云主机组
        • 云主机加入主机组校验(旧)
        • 云主机组中删除单台云主机
        • 云主机组中添加单台云主机
        • 创建云主机组
        • 创建云主机组
        • 删除云主机组
        • 查询云主机组内的云主机
        • 查询云主机组列表或详情
        • 查询云主机组列表或详情
        • 更新云主机组信息
        • 云主机加入主机组校验(新)
        • 查询云主机组列表或详情-vdc
      • 云主机快照
        • 快照管理
          • 创建云主机快照策略
          • 查询云主机快照策略列表
          • 查询云主机快照策略详情
          • 修改云主机快照策略
          • 停用云主机快照策略
          • 快照策略绑定云主机
          • 查询快照策略绑定云主机列表
          • 查询云主机快照任务列表
          • 删除云主机快照策略
          • 快照策略解绑云主机
          • 启用云主机快照策略
          • 查询云主机快照策略列表-vdc
        • 创建云主机快照
        • 创建云主机快照 _军规后- 新PAAS
        • 删除云主机快照
        • 恢复云主机快照
        • 批量更新云主机快照信息(旧)
        • 批量更新云主机快照信息(新)
        • 更新云主机快照信息(旧)
        • 更新云主机快照信息(新)
        • 查询云主机快照列表(新)
        • 查询云主机快照状态
        • 查询云主机快照详情
        • 统计云主机快照个数
        • 查询云主机快照列表-vdc
      • 云主机规格
        • 判断一台云主机是否可以通过指定规格进行变配
        • 查询一个或多个云主机规格资源
        • 查询一个或多个云主机规格资源_paas
        • 设置云主机实例规格标签(内部)
        • 设置云主机实例规格额外属性
        • 查询资源池虚机规格信息
      • 云主机备份存储库
        • 云主机备份存储库查询-vdc
        • 创建云主机备份存储库
        • 续订云主机备份存储库
        • 云主机备份存储库查询
        • 扩容云主机备份存储库
        • 退订云主机备份存储库
      • 云主机备份策略
        • 创建云主机备份策略
        • 查询云主机备份策略绑定云主机信息
        • 删除云主机备份策略
        • 查询云主机备份策略列表
        • 执行云主机备份策略
      • 云主机备份
        • 创建云主机备份 (全量备份)(旧)
        • 创建云主机备份
        • 查询云主机备份详情post(旧)
        • 查询云主机备份详情
        • 云主机备份查询虚机(旧)
        • 云主机备份查询虚机 get
        • 查询整机备份状态(旧)
        • 查询云主机备份状态-get
        • 云主机备份列表(旧)
        • 查询云主机备份列表
        • 更新云主机整机备份信息(名称、描述)(新)
        • 更新云主机整机备份信息(名称、描述)(旧)
        • 批量更新备份信息 (新)
        • 批量更新备份信息(旧)
        • 云主机备份查询虚机磁盘大小-get(新)
        • 查询主机云盘大小(旧)
        • 查看云主机备份空间占用大小(新)
        • 删除云主机备份
        • 备份信息统计(新)
        • 恢复备份
        • 查询云主机备份列表-vdc
      • 云主机
        • 云主机生命周期管理
          • 创建一台按量付费或者包年包月云主机(旧版)
          • 创建一台按量付费或包年包月的云主机(新版)
          • 批量创建按量付费或者包年包月云主机
          • 退订或销毁云主机
          • 批量退订或销毁云主机
          • 克隆云主机
          • 备份副本创建一台云主机
          • 续订一台包周期的云主机
          • 续订一台包周期的云主机-新
        • 云主机信息查询
          • 查询云主机规格族列表
          • 查询指定规格族下的云主机信息
          • 查询云主机库存
          • 批量查询云主机余量
          • resourceId查询云主机
          • 查询云主机列表
          • 查询一台或多台云主机详细信息(PaaS专供)
          • 查询云主机列表_新PAAS
          • 查询一台或多台云主机详细信息
          • 查询云主机宿主机详情
          • 查询云主机所在主机组
          • 查询云主机的固定IP列表
          • 查询用户云主机统计信息
          • 查询自定义数据
          • 根据快照查询虚拟机
          • 一台或多台ECS实例的详细信息
          • 查询一台ECS实例的Web管理终端地址
          • 查询云主机的web管理终端地址_新PAAS
          • 获取多台云主机的状态信息
          • 获取一组云主机的状态
        • 密钥对管理
          • 创建一对SSH密钥对
          • 为云主机解绑SSH密钥对
          • 为云主机解绑SSH密钥对
          • 绑定SSH密钥对到云主机
          • 绑定SSH密钥对到云主机
          • 创建一对SSH密钥对
          • 删除指定密钥对
          • 导入RSA密钥对公钥
          • 导入RSA密钥对公钥
          • 查询密钥对
          • 查询一个或多个SSH密钥对
        • 修改云主机
          • 更新多台云主机的部分信息
          • 云主机修改带宽或规格
          • 云主机热变配
          • 更新云主机实例删除保护信息
          • 云主机修改规格
          • 批量更新云主机的部分信息
          • 修改一台实例的部分信息
        • 文件系统
          • 云主机挂载文件系统
          • 查询虚机绑定文件系统列表
          • 云主机卸载文件系统
          • 查询文件系统关联虚机列表
        • 委托管理
          • 云主机绑定委托
          • 云主机清除委托
        • 云硬盘管理
          • 云主机挂载云硬盘
          • 云主机卸载云硬盘
          • 为云主机挂载云硬盘
          • 查询一台云主机挂载的云硬盘列表
          • 查询云主机的云硬盘列表_新PAAS
        • 操作云主机
          • 云主机同步状态
          • 挂起云主机
          • 恢复云主机
          • 云主机重装
          • 云主机重装
          • 修改云主机密码
          • 更新云主机密码
          • 批量更新云主机密码
          • 批量重装云主机
          • 批量重启云主机
          • 启动一台实例
          • 启动云主机
          • 停止一台实例
          • 停止云主机
          • 重启实例
          • 重启云主机
          • 启动一台或多台实例
          • 停止一台或多台实例
        • 元数据管理
          • 更新元数据
          • 新增元数据
          • 新增元数据
          • 更新元数据
          • 删除云主机元数据
          • 删除云主机元数据
          • 批量删除云主机元数据
          • 查询元数据
          • 查询元数据
        • 网络管理
          • 云主机添加共享网卡
          • 云主机添加共享网卡
        • 其他
          • 通过云主机IP查询宿主机IP列表
          • 查询账户启用的资源池信息
          • 查询一个异步任务结果
          • 查询多个异步任务的结果
          • 查询多个异步任务的结果-军规后
      • 公共接口
        • 查询账户资源池中可用区信息
        • 查询账户资源池中可用区信息
      • 云助手
        • 查询实例是否安装了云助手agent
        • 创建命令
        • 修改命令
        • 查询命令列表
        • 查询命令详情
        • 云助手执行命令
        • 触发命令
        • 云助手查询结果
        • 删除命令
        • 上传文件
        • 查询文件上传结果
      • 仅内部调用-istack2.0
        • 查询资源池云主机、宿主机总数
        • 查询宿主机信息及使用率
        • 云主机热迁移校验
        • 云主机热迁移
        • 查询云主机列表
        • 查询宿主机详情
        • 查询宿主机列表
    • 存储
      • 弹性文件
        • 海量文件服务
          • 海量文件信息查询(基于sfsUID+regionID)
          • 可用区账户海量文件列表查询
          • 海量文件信息查询(基于sfsName+regionID)
          • 海量文件续订
        • 并行文件
          • 并行文件开通(文件系统开通,走工单流程)
          • 并行文件退订(文件系统退订,走工单流程)
          • 并行文件修改规格(扩容,工单流程)
          • 可用区账户并行文件列表查询
          • 并行文件信息查询(基于sfsUID+regionID)
          • 并行文件信息查询(基于sfsName+regionID)
          • 并行文件集群列表查询
        • 查询指定文件系统挂载点列表(新版)
        • 文件系统添加挂载点
        • 文件系统重命名
        • 创建文件系统(文件系统开通,走工单流程)
        • 弹性文件续订(工单流程)
        • 弹性文件修改规格(扩容,工单流程)
        • 删除文件系统(文件系统退订,走工单流程)
        • 可用区账户弹性文件列表查询
        • 弹性文件信息查询(基于 name + regionID)
        • 弹性文件创建快照
        • 弹性文件修改快照
        • 弹性文件回滚快照
        • 弹性文件删除快照
        • 弹性文件查询快照
        • 弹性文件创建权限组
        • 弹性文件删除权限组
        • 弹性文件修改权限组
        • 弹性文件返回权限组描述信息
        • 弹性文件创建权限组规则
        • 弹性文件修改权限组规则
        • 弹性文件删除已有权限组规则
        • 返回权限组规则描述信息
        • 文件系统VPC换绑权限组
        • 文件系统VPC绑定权限组
        • 文件系统的VPC解绑权限组
        • 文件系统VPC解绑权限组
        • 删除指定文件系统挂载点
        • 查看文件系统只读/读写信息
        • 查询文件系统信息
        • 查询文件系统使用率
        • 查询文件系统剩余容量
        • 查询文件系统已使用容量
        • 查询文件系统总容量
        • 查询文件系统权限组与VPC绑定关系
        • 查询文件系统的VPC信息
        • 查询指定文件系统挂载点列表
        • 查询租户已开通文件系统列表
        • 设置文件系统只读
        • 设置文件系统读写
        • 查询可用区及可用区所支持的文件系统类型
        • 弹性文件资源池支持详情
        • 设置文件系统目录配额
        • 删除文件系统目录配额
        • 修改文件系统目录配额
        • 销毁缓冲区内弹性文件
        • 恢复文件系统
      • 存储库
        • 续订云硬盘备份存储库
      • 镜像服务
        • 创建私有数据盘镜像
        • 创建私有系统盘镜像
        • 删除一份自定义镜像
        • 导入镜像
        • 导出私有镜像
        • 接受共享镜像
        • 拒绝共享镜像
        • 共享私有镜像
        • 取消共享私有镜像
        • 查询共享镜像的所有用户(项目)
        • 查询镜像列表
        • 查询镜像详情
        • 查询私有镜像的共享列表
        • 云主机快照创建系统盘镜像
        • 创建iso镜像
        • 镜像文件创建镜像
      • 弹性文件(新)
        • 返回权限组规则描述信息(新军规)
        • 创建文件系统(新军规)(文件系统开通,走工单流程)
        • 弹性文件修改规格(新军规)(扩容,工单流程)
        • 删除文件系统(新军规)(文件系统退订,走工单流程)
        • 可用区账户弹性文件列表查询(新军规)
        • 文件系统VPC换绑权限组
        • 弹性文件信息查询(新军规)(基于 sfsName + regionID)
        • 弹性文件 创建权限组(新军规)
        • 弹性文件 删除权限组 (新军规)
        • 弹性文件 修改权限组 (新军规)
        • 弹性文件 返回权限组描述信息(新军规)
        • 文件系统VPC绑定权限组
        • 查询文件系统信息
        • 查询租户已开通文件系统列表
        • 弹性文件创建权限组规则(新军规)
        • 弹性文件修改权限组规则(新军规)
        • 弹性文件删除已有权限组规则(新军规)
        • 文件系统新创建订单询价
        • 文件系统扩容升级订单询价
        • 文件系统续订订单询价
        • 删除指定文件系统挂载点(新军规)
        • 查询vpc下的文件系统列表
      • 对象存储
        • 桶ACL策略
          • 桶acl策略创建
          • 桶acl策略修改
          • 桶acl策略删除
          • 桶acl策略查询
        • 对象存储服务开通(工单)
        • 创建桶
        • 复制对象(拷贝文件到其它桶)
        • 批量删除对象
        • 查询对象存储用户桶列表
        • 访问控制【endpoint】查询
        • 查询对象存储开通状态
        • 查询存储空间位置信息
        • 查询存储空间是否有权访问或是否存在
        • 查询对象是否存在
        • 查询 ACCESS_KEY 以及 SECRECT_KEY
        • 生成对象临时下载链接
        • 生成对象临时上传链接
        • 设置对象 HTTP 头
        • 防盗链设置
        • 查询防盗链配置
        • 设置或更新对象(Object)的标签(Tagging)信息
        • 删除指定对象(Object)的标签(Tagging)信息
        • 查询对象(Object)标签
        • 查询正在进行中的分段上传
        • 设置存储空间(Bucket)的版本信息
        • 查询存储空间版本控制配置
        • 查询存储空间静态网站配置信息
        • 设置存储空间静态网站配置信息
        • 删除存储空间静态网站配置信息
        • 设置存储空间授权策略
        • 查询存储空间授权策略
        • 删除存储空间授权策略
        • 设置存储空间标签
        • 查询存储空间标签
        • 删除存储空间标签
        • 查询桶详细信息
        • 删除桶
        • 获取存储空间的访问权限控制列表(ACL)
        • 设置存储空间的访问权限(ACL)
        • 查询oss用户桶下文件列表
        • 查询oss用户桶下对象版本信息
        • 删除对象
        • 修改文件(Object)的访问权限(ACL)
        • 获取存储空间某个文件(Object)的访问权限(ACL)
        • 生命周期查询
        • 生命周期设置
        • 生命周期删除
        • 查询存储空间日志转存配置
        • 日志转存更新
        • 删除日志转存
        • 跨域资源共享查询
        • 跨域资源共享更新
        • 跨域资源共享删除
        • 查询特定分段上传中的已上传的分段的信息
        • 通知OSS初始化一个Multipart Upload事件
        • 根据指定的Object名和uploadId来分块(Part)上传数据
        • 完成整个文件的分片上传
        • 从一个已存在的Object中拷贝数据来上传一个Part
        • 用于取消MultipartUpload事件并删除对应的Part数据
        • 查询存储空间请求支付配置
        • 设置存储空间请求支付配置
        • 删除存储空间默认加密配置
        • 设置存储空间默认加密配置
        • 查询存储空间默认加密配置
        • 设置存储空间上的对象锁定配置
        • 请求获取存储空间的对象锁定配置
      • 云硬盘备份
        • 云硬盘备份创建
        • 云硬盘备份详情查询
        • 恢复云硬盘备份
        • 查看云硬盘备份的存储占用大小
        • 查询云硬盘备份列表
      • 云硬盘快照
        • 查询快照使用容量
        • 查询云硬盘快照列表
        • 批量快照回滚(批量重置云硬盘)
        • 云硬盘快照创建
        • 创建云硬盘快照_新
        • 删除云硬盘快照
        • 删除云硬盘快照_新
        • 重置磁盘(恢复云硬盘快照)
        • 查询快照使用量
        • 查询快照列表
      • 云硬盘备份策略
        • 云盘备份策略绑定云硬盘
        • 云盘备份策略解绑云硬盘
        • 云硬盘备份策略解绑云硬盘
        • 修改云盘备份策略
        • 停用云硬盘备份策略
        • 创建云硬盘备份策略
        • 删除云盘备份策略
        • 启用云硬盘备份策略
        • 执行云硬盘备份策略
        • 云硬盘备份策略绑定云硬盘
        • 查询云硬盘备份策略列表
        • 查询云硬盘备份策略
        • 查询云硬盘备份策略绑定的云硬盘列表
        • 查询备份策略创建的备份任务列表
        • 查询备份策略创建的备份任务
      • 云硬盘快照策略
        • 快照策略 修改
        • 快照策略 创建
        • 创建云硬盘自动快照策略
        • 修改云硬盘自动快照策略
        • 关联云硬盘自动快照策略
        • 取消关联云硬盘自动快照策略
        • 启用或关闭云硬盘自动快照策略
        • 查询云硬盘自动快照策略
        • 快照策略 删除
        • 删除云硬盘自动快照策略
      • 云硬盘
        • 云硬盘续订(旧)
        • 云硬盘续订
        • 云硬盘信息列表
        • 可用区账户云硬盘查询
        • 创建云硬盘(工单流程)
        • 从快照创建云硬盘
        • 新云硬盘开通
        • 云硬盘修改规格 (云硬盘升级-工单流程)
        • 云硬盘修改规格
        • 退订云硬盘(工单流程)
        • 云硬盘退订
        • 云硬盘绑定
        • 云硬盘绑定(pass)
        • 云硬盘解绑
        • 云硬盘解绑(pass)
        • 基于名字查询云硬盘详情
        • 查询云硬盘详情(基于regionID和diskName)
        • 基于资源ID查询云硬盘
        • 基于磁盘ID查询云硬盘
    • 网络
      • 虚拟私有云
        • VPC 绑定扩展网段
        • VPC 解绑扩展网段
        • 修改VPC属性
        • 修改VPC的 IPv6 状态
        • 创建VPC
        • 删除VPC
        • 查询VPC信息
        • 查询VPC列表
        • 查询VPC列表
      • 子网
        • 开启子网的 IPv6
        • 修改子网属性
        • 修改子网的 IPv6 状态
        • 创建子网
        • 删除子网
        • 子网更换ACL
        • 子网更换路由表
        • 子网解绑ACL
        • 查询子网详情
        • 查询VPC下子网列表
        • 同:查询VPC下子网列表
        • 查看子网已使用IP
      • 弹性网卡
        • 计算-创建弹性网卡
        • 计算-删除弹性网卡
        • 计算-查询网卡信息
        • 计算-单个网卡关联多个IPv6地址
        • 计算-单个网卡解绑多个IPv6地址
        • 计算-网卡关联辅助私网IPs
        • 计算-单个网卡解绑多个私网IPs
        • 计算-查询网卡列表
        • 网卡状态查询接口
        • 创建弹性网卡
        • 修改网卡属性
        • 删除弹性网卡
        • 网卡关联辅助私网IPs
        • 网卡解绑辅助私网IPs
        • 单个网卡关联多个IPv6地址
        • 单个网卡解绑多个IPv6地址
        • 多个网卡关联IPv6地址
        • 多个网卡解绑IPv6地址
        • 查询网卡列表
        • 查询网卡信息
        • 网卡绑定实例
        • 网卡解绑实例
        • 新弹性网卡列表
        • 网卡状态批量查询接口
        • 更换VPC
        • 修改内网IP(更换子网)
        • 查询物理机网卡信息
      • VIP
        • 创建HaVip
        • 删除HaVip
        • 查看高可用虚IP详情
        • 查询HaVip
        • 绑定HaVip和ecs实例
        • PaaS绑定HaVip和ecs实例
        • 解绑HaVip
        • 解绑HaVip
      • 路由表
        • 创建路由表
        • 创建网关路由表
        • 删除路由表
        • 查询路由表列表
        • 新查询路由表列表
        • 查询路由表详情
        • 修改路由表属性
        • 批量创建路由表规则
        • 批量删除路由表规则
        • 批量修改路由表规则
        • 查询路由表规则列表
        • 新查询路由表规则列表
        • 创建单条路由表规则
        • 修改单条路由表规则
        • 删除单条路由表规则
      • 安全组
        • 创建安全组入向规则
        • 创建安全组出向规则
        • 批量绑定安全组
        • 查询用户安全组列表
        • 新查询用户安全组列表
        • 查询用户安全组详情
        • 修改安全组出方向规则
        • 修改安全组入方向规则
        • 删除安全组入方向规则
        • 删除安全组出方向规则
        • 删除安全组
        • 创建安全组
        • 修改安全组
        • 绑定安全组
        • 解绑安全组
        • 安全组批量绑定网卡
        • 安全组批量解绑网卡
        • 获取安全组绑定主机
      • ACL
        • acl列表-new
        • 创建子网acl(适配3.0)
        • aclrules列表
        • acl列表
        • acl详情
        • 修改acl
        • 修改aclrules
        • 创建acl
        • 创建aclrules
        • 删除acl
        • 删除aclrules
      • 共享带宽
        • 查询共享带宽列表-new
        • 共享带宽创建询价
        • 共享带宽变配询价
        • 共享带宽续订询价
        • 续订共享带宽
        • 从共享带宽中移出EIPs
        • 从共享带宽中移出IPv6s
        • 修改共享带宽的名称描述
        • 修改共享带宽的数值
        • 创建共享带宽
        • 删除共享带宽
        • 查询共享带宽列表
        • 查询共享带宽详情
        • 添加EIPs到共享带宽中
        • 添加IPv6s至共享带宽
      • IPv6
        • 查询ipv6列表
        • IPv6带宽添加IPv6地址
        • 查看 IPv6 带宽详情
        • IPv6带宽移除IPv6地址
        • 修改IPv6带宽规格
        • 创建IPv6带宽
        • 创建ipv6网关
        • 删除IPv6带宽
        • 删除ipv6网关
        • 新查询ipv6列表
        • 查询ipv6网关列表
        • 查询ipv6网关详情
        • 查询ipv6详情
        • 查看IPv6带宽列表
        • 创建IPv6带宽询价
        • 续订ipv6带宽询价
        • 变配ipv6带宽询价
        • 新查看IPv6带宽列表
        • 修改ipv6带宽名称
        • 查看 IPv6 带宽详情,适配v1返回
        • 续订ipv6带宽
      • Ipv4
        • 获取IPv4网关列表
        • 查看IPv4网关详情
        • IPv4网关绑定网关路由表
        • IPv4网关解绑网关路由表
      • NAT网关
        • SNAT添加EIP
        • SNAT移除EIP
        • 修改SNAT规则
        • 创建SNAT规则
        • 删除SNAT规则
        • 获取SNAT规则详情
        • 获取SNAT规则列表
        • 获取SNAT规则列表-对齐V1接口
        • nat网关添加子网
        • 修改DNAT规则
        • 创建NAT网关
        • 查询DNAT详情
        • 续订nat网关 询价
        • 查询NAT网关详情
        • 创建nat网关询价
        • 续订NAT网关
        • 变配nat网关 询价
        • 修改NAT网关
        • 查询NAT网关接口列表
        • 删除NAT网关
        • 创建DNAT规则
        • 查询DNAT列表
        • 删除指定的DNAT条目
        • 变配NAT网关走订单
      • 私网NAT网关
        • 创建私网NAT网关
        • 查询私网NAT
        • 更新私网NAT
        • 续订私网NAT网关
        • 变配私网NAT网关
        • 删除私网NAT网关
        • 询价--创建私网NAT网关
        • 询价--续订私网NAT网关
        • 询价--变配私网NAT网关
        • 获取中转地址段
        • 创建中转IP
        • 查询中转IP列表
        • 删除中转IP
        • 创建私网SNAT规则
        • 修改私网SNAT规则
        • 查询私网SNAT列表
        • 删除私网SNAT
        • 创建私网DNAT
        • 修改私网DNAT
        • 查询私网DNAT列表
        • 删除私网DNAT
      • 对等连接
        • 创建对等连接
        • 修改对等连接
        • 查询对等连接详情
        • 查询对等连接列表
        • 删除对等连接
        • 获取待处理对等连接请求列表查询接口
        • 同意建立对等链接
        • 拒绝建立对等链接
        • 对等连接路由创建/批量创建
        • 对等连接路由删除/批量删除
        • 对等连接路由查询
      • 内网DNS
        • 获取DNS绑定的VPC列表
        • 检查DNS域名是否冲突和合法
        • DNS绑定标签
        • 查询DNS绑定的标签列表
        • DNS解绑标签
        • 创建内网DNS Copy
        • 修改内网DNS
        • 内网DNS关联vpc
        • 内网DNS列表
        • 新内网DNS列表
        • 内网DNS取消关联vpc
        • 内网DNS详情
        • 创建内网DNS
        • 删除内网DNS
      • 内网DNS记录
        • 修改内网dns记录描述信息
        • 检查CNAME记录集合法性
        • 检查MX记录集合法性
        • 检查TXT记录集合法性
        • 修改内网dns记录
        • 内网dns记录列表
        • 新内网dns记录列表
        • 内网dns记录详情
        • 内网dns记录集批量删除
        • 创建内网dns记录
        • 删除内网dns记录
      • EIP
        • ecs创建EIP
        • ecs删除EIP
        • EIP绑定裸机网卡
        • 创建EIP 询价
        • 续订EIP 询价
        • 变配EIP 询价
        • EIP绑定云主机网卡
        • EIP绑定网卡
        • 修改EIP名字
        • 修改EIP带宽
        • 创建EIP
        • 创建指定地址的EIP
        • 删除EIP
        • 批量检查EIP地址是否被使用
        • 查看EIP详情
        • 查询指定地域已创建的EIP
        • 检查EIP地址是否被使用
        • 绑定EIP
        • 续订EIP
        • 解绑EIP
        • 获取弹性IP列表管理用
        • EIP网关列表查询
        • 查询网关出口类型
        • 查询指定地域已创建的EIP-newlist
        • 获取EIP端口备案状态
        • 获取eip可用地址
        • EIP查询可用cidr
        • 获取eip可用地址仅供测试使用
      • 流量镜像
        • 过滤和规则
          • 更新过滤规则
          • 流量镜像过滤条件创建
          • 流量镜像过滤条件更新
          • 流量镜像过滤条件删除
          • 流量镜像过滤条件列表
          • 流量镜像过滤条件详情
          • 查看过滤规则列表
          • 创建出方向过滤规则
          • 创建入方向过滤规则
          • 调整过滤规则优先级
          • 删除过滤规则
        • 会话
          • 启动流量会话
          • 查看流量会话列表
          • 删除流量会话
          • 创建流量会话
          • 暂停流量会话
          • 查看流量会话详情
          • 更新流量会话
      • 终端节点
        • 工单创建终端节点
        • 删除终端节点白名单
        • 通过终端节点连接申请
        • 拒绝终端节点连接申请
        • 删除终端节点
        • 更新终端节点
        • 查看终端节点列表
        • 查看终端节点详情
        • 查询终端节点白名单
        • 添加终端节点白名单
        • 创建终端节点询价
        • 修改终端节点IP地址类型
      • 终端节点服务
        • 创建终端节点服务
        • 查看终端节点服务列表
        • 新查看终端节点服务列表
        • 修改终端节点服务
        • 删除终端节点服务
        • 删除终端节点服务白名单
        • 查询终端节点服务白名单
        • 添加终端节点服务白名单
        • 终端节点服务连接修改
        • 终端节点服务连接查询
        • 新查询终端节点服务白名单
        • 终端节点服务中转IP列表
        • 新查看终端节点列表
        • 列表终端节点服务中转规则(反向访问规则)
        • 创建终端节点服务中转规则(反向访问规则)
        • 终端节点服务中转IP创建
        • 删除终端节点服务中转规则(反向访问规则)-新PASS
        • 终端节点服务中转IP删除
        • 终端节点服务规则创建接口
        • 终端节点服务规则删除接口
        • 查看天翼云终端节点服务
        • 修改终端节点服务IP地址类型
        • 新查看终端节点列表VDC
        • 查看终端节点服务列表VDC
      • 负载均衡
        • 多证书
          • 创建多证书
          • 删除多证书
          • 更新多证书
          • 查看多证书列表
        • 证书管理 credentials
          • 创建证书
          • 更新证书
          • 查询证书详情
          • 获取证书列表
          • 删除证书
        • 创建性能保障型负载均衡实例
        • 退订性能保障型负载均衡实例
        • 设置监听器空闲超时时间
        • 设置监听器响应超时时间
        • 设置监听器每秒查询数
        • 经典型负载均衡实例升级为性能保障型
        • 性能保障型负载均衡创建询价
        • 性能保障型负载均衡变配询价
        • 性能保障型负载均衡实例续订询价
        • 性能保障型负载均衡变配
        • 续订性能保障型负载均衡实例
        • 查询负载均衡实例绑定的标签列表
        • 负载均衡绑定标签
        • 负载均衡解绑标签
        • 创建负载均衡实例
        • 更新负载均衡实例
        • 查询负载均衡实例
        • 查询负载均衡实例列表
        • 删除负载均衡实例
        • 绑定EIP
        • 解绑EIP
        • 负载均衡开启IPv6
        • 负载均衡关闭IPv6
        • 查看规格列表
        • 创建后端服务组
        • 更新后端服务组
        • 查看后端服务组信息
        • 查看后端服务组列表
        • 删除后端服务组
        • 创建健康检查
        • 更新健康检查
        • 查询健康检查详情
        • 获取健康检查列表
        • 删除健康检查
        • 创建监听器
        • 更新监听器
        • 查看监听器详情
        • 查看监听器列表
        • 删除监听器
        • 启动监听器
        • 停止监听器
        • 创建转发规则
        • 更新转发规则
        • 转发规则列表
        • 转发规则详情
        • 删除转发规则
        • 创建后端服务
        • 更新后端服务
        • 查看后端服务详情
        • 查看后端服务列表
        • 删除后端服务
        • 创建访问控制
        • 更新访问控制
        • 查询访问控制详情
        • 查询访问控制列表
        • 删除访问控制
        • 设置监听器建立连接超时时间
        • 设置监听器每秒新建连接数上限
        • 设置监听器nat64
        • 查询负载均衡实例列表VDC
    • 广域云网
      • 云专线
        • 专线交换机查询
        • 专线交换机创建
        • 专线交换机删除
        • 客户信息删除
        • 客户信息增加
        • 客户信息修改
        • 客户信息查询
        • 查询专线网关绑定的物理专线
        • 物理专线修改
        • 物理专线删除
        • 物理专线接入点查询
        • 物理专线数量查询
        • 专线网关数量查询
        • 专线网关创建
        • 专线网关删除
        • 专线网关绑定物理专线
        • 专线网关解绑物理专线
        • 查询已创建云专线网关
        • BGP路由添加
        • BGP路由删除
        • BGP路由查询
        • 静态路由添加
        • 静态路由删除
        • 静态路由更新
        • 静态路由查询
        • 专线网关VPC数量查询
        • 专线网关VPC查询
        • 专线网关删除VPC
        • 专线网关添加VPC
      • VPN网关
        • VPN连接查询公有云
        • VPN网关订购询价
        • VPN网关续订询价
        • VPN网关升配询价
        • VPN网关升配
        • VPN网关查询
        • VPN网关续订
        • VPN网关订购
        • VPN网关退订
        • VPN连接修改
        • VPN连接创建
        • VPN连接删除
        • VPN连接查询
        • VPN连接策略查询
        • 用户网关修改
        • 用户网关创建
        • 用户网关删除
        • 用户网关查询
    • 资源池
      • 资源池产品信息查询(order服务)
      • 资源池产品可售查询
      • 资源池产品可售查询(军规后)
      • 资源池列表查询
    • 资源池管理-region
      • 查询资源池类型列表
      • 查询资源池详情
      • 切换资源池状态
      • 获取资源池配置信息列表
      • 同步可用区信息
      • 查询可用区
      • 创建可用区
      • 编辑可用区
      • 切换可用区状态
    • 监控
      • 实时监控数据
        • 查询云主机的CPU实时监控数据
        • 查询云主机的内存实时监控数据
        • 查询云主机的磁盘实时监控数据
        • 查询云主机的网卡实时监控数据
        • 查询云主机实时监控数据
        • 查询云磁盘实时监控数据
        • 查询共享带宽实时监控数据
        • 查询弹性IP实时监控数据
        • 查询弹性伸缩组实时监控数据
        • 查询弹性文件实时监控数据
        • 查询监听器实时监控数据
        • 查询裸金属实时监控数据
        • 查询负载均衡实时监控数据
      • 历史监控数据
        • 查询指定时间段内的CPU监控数据
        • 查询指定时间段内的内存监控数据
        • 查询指定时间段内的磁盘监控数据
        • 查询指定时间段内的网卡监控数据
        • 查询云主机历史监控数据
        • 查询云磁盘历史监控数据
        • 查询共享带宽历史监控数据
        • 查询弹性IP历史监控数据
        • 查询弹性伸缩组历史监控数据
        • 查询弹性文件历史监控数据
        • 查询监听器历史监控数据
        • 查询裸金属历史监控数据
        • 查询负载均衡历史监控数据
      • 查询监控项列表
    • PAAS定制接口
      • 创建负载均衡实例PAAS
      • 创建云主机(工单)
      • 创建云硬盘(工单)
      • 修改弹性IP带宽 PAAS
      • 创建弹性IP PAAS
      • 创建NAT网关PAAS
      • 删除负载均衡实例PAAS
      • 创建VPC终端节点PAAS
      • 创建云主机快照PAAS
      • 删除云主机快照PAAS
      • 创建云硬盘快照PAAS
      • 删除云硬盘快照PAAS
      • 删除VPC终端节点PAAS
      • 删除弹性IP PAAS
      • 修改NAT网关PAAS
      • 删除NAT网关PAAS
      • 创建物理机(工单)
      • 云主机修改规格(工单)
      • 删除云硬盘(工单)
      • 变更云硬盘配置(工单)
      • 快照创建云主机(工单)
      • 批量任务结果查询
      • 快照创建云硬盘(工单)
      • 批量创建轻量虚拟机(工单)
    • 用户与vdc
      • V1兼容接口
        • VDC
          • 查询所有VDC组织列表
          • 创建VDC组织
          • 修改VDC组织
          • 删除VDC组织
          • VDC绑定资源池
          • VDC解绑资源池
          • VDC结构信息获取
          • 查询VDC资源池列表
        • 用户
          • 新增一个用户,并为其指定机构(PaaS)
      • PaaS
        • 账号委托
          • 委托用户获取
        • 委托
          • 自动化创建内联委托
          • 根据委托ID获取详情
          • 查询指定账号下的服务委托列表
          • 通过委托名称查询委托是否存在
          • 删除委托
          • 自动化创建服务委托
        • 用户与资源
          • 资源上报接口
          • 判断操作权限
          • 用户策略查询
          • 企业项目查询
          • 根据id查询用户详情
          • 查询策略详情
          • 内部获取用户企业项目权限
          • 查询账号信息
          • 用户获取临时凭证
          • 校验临时凭证
          • 根据VDC查询企业项目列表
      • 其他(开发中,勿用)
        • 企业租户
          • 创建租户
          • 修改租户
          • 删除租户
          • 租户列表
          • 租户详情
          • 查询租户可绑定的资源池信息
          • 租户绑定资源池
          • 租户解绑资源池
          • 查询租户已绑定的资源池信息
          • 获取所有的代维管理员
    • 概览
      • 资源池维度资源分配率
      • 多云资源池数目统计(vdc绑定的资源池)
      • 多云资源池实例数目Top(云主机和云硬盘)
    • 计量计费
      • 账单收支
        • 60. 查询收入/支出分类
        • 61. 查询收入/支出排行榜
        • 62. 查询消费趋势
        • 63. 查询每日收入/支出
        • 64. 查询收入/支出总额
        • 45. 按需流水账单
        • 46. 包周期流水账单(包周期)
        • 47. 账户账单查询
        • 48. 包周期订单账单详情
        • 49. 账单明细产品+账期(包周期)
        • 50. 账单明细资源+明细(按需)
        • 51. 账单明细产品+账期(按需)
        • 52. 账单明细资源+账期(按需)
        • 53. 账单财务统计
        • 54. 账单详情
      • 预算
        • 55. 获取预算管理列表
        • 56. 获取预算详情
        • 57. 追加预算
        • 58. 创建预算
        • 59. 获取预算收支明细列表
      • 订单
        • 36. 撤销子订单
        • 38. 取消支付
        • 39. 支付订单
        • 40. 查询子订单详情
        • 41. 查询子订单列表
        • 43. 报竣子订单
        • 35. 查询订单列表(通用)
        • 42. 查询订单详情
        • 44. 查询主订单信息(通用)
      • 下单询价
      • 订单资源查询
      • 根据masterOrderID查询云主机ID
    • 消息中心
      • 发送消息

    网关签名说明

    网关签名说明#

    天翼混合云网关支持天翼公有云CTAPI网关签名和混合云网关签名两种验签逻辑
    注意:推荐使用天翼云混合云Openapi SDK 对接混合云IAAS OpenAPI,SDK下载地址为https://cloud.189.cn/web/share?code=qYbUFreyyuy2 (访问码:kyq0)

    天翼云公有云签名#

    请登录天翼云公有云后,打开网页如何调用API

    天翼云混合云签名#

    基本签名流程#

    ctyun-eop-ak/ctyun-eop-sk基本签名流程
    1.
    构造规范请求。将待发送的请求内容按照EOP约定的规则组装,确保客户端签名、EOP认证时使用的请求内容一致。
    2.
    使用规范请求和其他入参信息创建待签名字符串。
    3.
    使用HEADER信息、ctyun-eop-sk、ctyun-eop-ak来创建HmacSHA256算法的密钥。
    4.
    使用密钥和待签名字符串通过HmacSHA256来计算签名。
    5.
    将生成的签名信息作为请求消息头添加到HTTP请求中。

    步骤一 信息获取#

    用户型用户通过云管界面用户信息获取ctyun-eop-ak,ctyun-eop-sk
    v2 ak:sk 获取.png
    (https://api.apifox.cn/api/v1/projects/2460723/resources/374261/image-preview)

    步骤二 创建待签名字符串#

    待签名字符串=需要进行签名的Header排序后的组合列表+ "\n" + 排序后的query + "\n" + toHex(SHA256(原封的body))。 toHex指将SHA256的摘要转换为16进制字符串。注意没有请求体时不需要拼接body摘要字符串
    字段名字段描述构造格式说明
    campmocalHeader将需要参与签名的Header信息进行排序后的字符串以 header_name:header_value格式通过\n拼接起来,EOP强制要求ctyun-hybrid-request-id和hybrid-date作为Header中的一部分。进行签名算法的Header需要进行排序(将它们的参数名按ASCII码字典序从小到大排序),将排序后得到的列表遍历组装成待签名的header。
    afterQuery完成排序后的query字符串query使用&拼接,键和值以=连接,排序规则按ASCII码字典序从小到大排序,query参数全部都需要进行签名
    calculateContentHash将原封的body信息进行加密以及进制转换后的字符串toHex(SHA256(body))。传入的body参数进行SHA256摘要,并将结果转换为hex16进制字符串
    forSignature待签名字符串,用于最终签名数据的生成campmocalHeader+"\n+afterQuery+"\n+calculateContentHash

    步骤三 构造动态密钥#

    发起请求前,需要构造名为hybrid-date请求头信息,对应值格式为年月日T时分秒Z即yyyymmddTHHMMSSZ。
    动态密钥生成流程
    1.
    将ctyun-eop-sk作为密钥,hybrid-date作为数据,算出ktime。
    2.
    将ktime作为密钥,ctyun-eop-ak作为数据,算出kAk。
    3.
    将kAk作为密钥,hybrid-date的年月日作为数据,算出kdate。
    hybrid-dateyyyymmddTHHMMSSZ (20230327T023127Z) 年月日时分秒
    hybridDdStryyyymmdd (20230327) 年月日
    ktimeHmacSHA256(hybrid-date,ctyun-eop-sk)
    kAkHmacSHA256(ctyun-eop-ak,ktime)
    kdateHmacSHA256(hybridDdStr,kAk)

    步骤四 计算签名#

    由步骤二得到的待签名字符串forSignature和步骤三得到的最终动态密钥kdate生成签名信息signature
    signatureHmacSHA256(forSignature,kdate),并将结果进行Base64编码得到最终签名结果
    范例
    构建签名流程所需信息信息描述范例值
    调用接口及入参通过部署的网关地址端口调用接口http://ip:port/v4/vpc/get-nat-gateway-attribute?regionID=nm8&natGatewayID=natgw-u4z12jh88f
    queryquery请求参数regionID=nm8&natGatewayID=natgw-u4z12jh88f
    bodypost请求参数null
    ctyun-eop-akak470bbc5b-10f5-4d7f-bae6-2275046380b3
    ctyun-eop-skskb20661e1-7448-405f-ad46-617631a2ea6e
    hybrid-date依据年月日T时分秒Z格式构造的日期信息20230403T154057Z
    ctyun-hybrid-request-id随机字符串0y13p5g41hwr
    campmocalHeader将需要参与签名的Header信息进行排序后的字符串ctyun-hybrid-request-id:0y13p5g41hwr\nhybrid-date:20230403T143447Z
    afterQuery完成排序后的query字符串natGatewayID=natgw-u4z12jh88f&regionID=nm8
    calculateContentHash将原封的body信息进行加密以及进制转换后的字符串null
    forSignature待签名字符串ctyun-hybrid-request-id:wc0d250x8zh\nhybrid-date:20230403T154247Z\nnatGatewayID=natgw-u4z12jh88f&regionID=nm8
    signature最终签名ejXRxfQRbpKRzDKd24QV55Bgih4j4iQJVVZdfBa6xLY=
    Hybrid-Authorization依据最终签名生成的请求头信息470bbc5b-10f5-4d7f-bae6-2275046380b3 Header=hybrid-date;ctyun-hybrid-request-id Signature=ejXRxfQRbpKRzDKd24QV55Bgih4j4iQJVVZdfBa6xLY=
    请求时增加以下请求头信息:
    请求头参数值
    hybrid-date20230403T154057Z
    ctyun-hybrid-request-id0y13p5g41hwr
    Hybrid-Authorization470bbc5b-10f5-4d7f-bae6-2275046380b3 Header=hybrid-date;ctyun-hybrid-request-id Signature=ejXRxfQRbpKRzDKd24QV55Bgih4j4iQJVVZdfBa6xLY=
    完整curl信息如下:
    curl --location --request GET 'http://localhost:9195/v4/vpc/get-nat-gateway-attribute?regionID=nm8&natGatewayID=natgw-u4z12jh88f'
    --header 'hybrid-date: 20230403T154057Z'
    --header 'ctyun-hybrid-request-id: 0y13p5g41hwr'
    --header 'Hybrid-Authorization: 470bbc5b-10f5-4d7f-bae6-2275046380b3 Header=hybrid-date;ctyun-hybrid-request-id Signature=ejXRxfQRbpKRzDKd24QV55Bgih4j4iQJVVZdfBa6xLY='
    注:若需要拓展参与签名的Header,需要在http_client请求头部中添加,同时在Hybrid-Authorization中Header=后增加对应Header名称。
    如果认证信息未通过,返回如下消息体:
    {
    "statusCode": 900,
    "returnObj": {},
    "errorCode": "auth.gateway.460",
    "message": "",
    "description": "生成签名与请求值不一致."
    }

    错误码定义#

    错误码错误描述
    auth.gateway.450请求未提供认证信息Hybrid-Authorization,认证失败.
    auth.gateway.451请求未提供认证信息ctyun-hybrid-request-id,认证失败.
    auth.gateway.452请求未提供认证信息hybrid-date,认证失败.
    auth.gateway.453请求头Hybrid-Authorization、ctyun-hybrid-request-id和hybrid-date值不能为空.
    auth.gateway.454签名时间戳已超过5分钟.
    auth.gateway.455hybrid-Authorization格式有误,签名参数不完整.
    auth.gateway.456请求头缺少待签名HEADER.
    auth.gateway.457待签名HEADER对应值不能为空.
    auth.gateway.458AccessKey不存在或未启用.
    auth.gateway.459签名PATH未配置.
    auth.gateway.460生成签名与请求值不一致.
    auth.gateway.461服务调用异常,或不返回结果.
    auth.gateway.462服务调用超时.
    auth.gateway.463找不到此url,请检查您的配置.
    auth.gateway.464找不到对应选择器,请检查您的配置.
    auth.gateway.465找不到对应规则,请检查您的配置.
    auth.gateway.466请求头字段过大
    auth.gateway.467请求实体过大.
    auth.gateway.468找不到健康的上游url,请检查服务是否启动或者检查网关配置.
    auth.gateway.470认证信息hybrid-date格式错误,认证失败.
    auth.gateway.500服务内部错误

    java 签名参考代码demo#

    注意:此代码仅供参考

    Golang 签名参考代码demo#

    注意:此代码仅供参考
     
    import (
    	"bytes"
    	"crypto/hmac"
    	"crypto/sha256"
    	"encoding/base64"
    	"encoding/hex"
    	"encoding/json"
    	"fmt"
    	"io"
    	"io/ioutil"
    	"net/http"
    	"net/url"
    	"reflect"
    	"sort"
    	"strings"
    	"testing"
    	"time"
    
    	"github.com/google/uuid"
    )
    
    const (
    	timeFormat      = "20060102T150405Z"
    	shortTimeFormat = "20060102"
    )
    
    type Signer interface {
    	Sign(credential *Credential, request *CTYunRequestInfo) (http.Header, error)
    }
    
    // Credential the gateway credential
    type Credential struct {
    	AccessKey       string
    	SecretAccessKey string
    }
    
    // NewCredential create openapi gateway auth credential
    func NewCredential(accessKey, secretAccessKey string) *Credential {
    
    	return &Credential{
    		AccessKey:       accessKey,
    		SecretAccessKey: secretAccessKey,
    	}
    }
    
    // Logger sdk core logger interface
    type Logger interface {
    	// Debugf write debug log
    	Debugf(message string, fmtParam ...interface{})
    	// Infof write info log
    	Infof(message string, fmtParam ...interface{})
    	//Errorf write error log
    	Errorf(err error, message string, fmtParam ...interface{})
    }
    
    type DefaultLoggerLevel int
    
    const (
    	DEBUG DefaultLoggerLevel = iota
    	INFO
    	ERROR
    )
    
    // DefaultLogger sdk core default log object
    type DefaultLogger struct {
    	LoggerLevel DefaultLoggerLevel
    }
    
    // NewDefaultLogger create default logger with default log level ERROR
    func NewDefaultLogger() *DefaultLogger {
    	return &DefaultLogger{LoggerLevel: ERROR}
    }
    
    // NewDefaultLoggerWithLevel create new default sdk logger with log level config
    func NewDefaultLoggerWithLevel(loggerLevel DefaultLoggerLevel) *DefaultLogger {
    	return &DefaultLogger{LoggerLevel: loggerLevel}
    }
    
    // Infof write info log
    func (d *DefaultLogger) Infof(message string, fmtParam ...interface{}) {
    	if d.LoggerLevel >= INFO {
    		fmt.Printf(message+"\n", fmtParam)
    	}
    
    }
    
    // Debugf write debug log
    func (d *DefaultLogger) Debugf(message string, fmtParam ...interface{}) {
    	if d.LoggerLevel >= DEBUG {
    		fmt.Printf(message+"\n", fmtParam)
    	}
    }
    
    // Errorf write error log
    func (d *DefaultLogger) Errorf(err error, message string, fmtParam ...interface{}) {
    	if d.LoggerLevel == ERROR {
    		fmt.Printf("err:%s msg:"+message+"\n,", err, fmtParam)
    	}
    }
    
    type CTYunRequestInfo struct {
    	Header     http.Header
    	Url        *url.URL
    	Query      url.Values
    	Method     string
    	Service    string
    	body       []byte
    	Date       time.Time
    	Singer     Signer
    	Credential *Credential
    	logger     Logger
    }
    
    // HttpSchema http  request schema ,eg:HTTPS HTTP
    type HttpScheme string
    
    const (
    	//HTTPS https 请求
    	HTTPS HttpScheme = "https"
    	//HTTP http 请求
    	HTTP HttpScheme = "http"
    )
    
    // NewCTYunRequestInfo create ctyun sign request info
    func NewCTYunRequestInfo(service, host, path, method string, scheme HttpScheme,
    	header map[string]string, query url.Values, body interface{}, logger Logger) (*CTYunRequestInfo, error) {
    	if logger == nil {
    		logger = &DefaultLogger{}
    	}
    	var ctYunRequest = &CTYunRequestInfo{
    		Header:  http.Header{},
    		Query:   query,
    		logger:  logger,
    		Service: service,
    		Method:  method,
    		Date:    time.Now(),
    	}
    
    	if !strings.HasPrefix(path, "/") {
    		path = "/" + path
    	}
    	requestURL := fmt.Sprintf("%s://%s%s", scheme, host, path)
    	if query != nil {
    		requestURL = fmt.Sprintf("%s?%s", requestURL, query.Encode())
    	}
    	requestUri, err := url.Parse(requestURL)
    	if err != nil {
    		return nil, err
    	}
    	ctYunRequest.Url = requestUri
    	if body != nil {
    		if header != nil && header["content-type"] == "application/x-www-form-urlencoded" {
    			if reflect.TypeOf(body).Kind() == reflect.String {
    				ctYunRequest.body = []byte(body.(string))
    			}
    		} else {
    			data, err := json.Marshal(body)
    			if err == nil {
    				ctYunRequest.body = data
    			}
    		}
    
    	} else {
    		ctYunRequest.body = nil
    	}
    
    	if len(header) > 0 {
    		for k, v := range header {
    			if k != "" {
    				ctYunRequest.Header.Set(k, v)
    			}
    		}
    	}
    
    	return ctYunRequest, nil
    }
    
    // GetBody get the reqeuest body info
    func (c *CTYunRequestInfo) GetBody() []byte {
    	return c.body
    }
    
    // WithCredential set the auth credential for the sign reqeust info
    func (c *CTYunRequestInfo) WithCredential(credential *Credential) {
    	c.Credential = credential
    }
    
    // WithSigner set the signer method for signer
    func (c *CTYunRequestInfo) WithSigner(Signer Signer) {
    	c.Singer = Signer
    }
    
    // DoSign exec the sign method for sign request info
    func (c *CTYunRequestInfo) DoSign() (http.Header, error) {
    	if c.Singer == nil {
    		c.Singer = &CTYunHybridSigner{}
    	}
    	httpHeader, err := c.Singer.Sign(c.Credential, c)
    	if err != nil {
    		return nil, err
    	}
    	for k, v := range httpHeader {
    		c.Header.Set(k, strings.Join(v, ", "))
    	}
    	return httpHeader, nil
    }
    
    func (c *CTYunRequestInfo) BuildRequest() (*http.Request, error) {
    	var bodyContent io.Reader
    	if c.body != nil {
    		bodyContent = io.NopCloser(bytes.NewBuffer(c.body))
    	}
    	// requestURL := fmt.Sprintf("%s://%s%s", c.scheme, c.host, c.path)
    	// if query != nil {
    	// 	requestURL = fmt.Sprintf("%s?%s", requestURL, c.query.Encode())
    	// }
    	req, err := http.NewRequest(c.Method, c.Url.String(), bodyContent)
    	if err != nil {
    		return nil, err
    	}
    	if c.Header != nil {
    		req.Header = c.Header
    	}
    	return req, nil
    }
    
    type CTYunHybridSigner struct {
    }
    
    type ctYunHybridSignerContext struct {
    	header               http.Header
    	query                url.Values
    	body                 []byte
    	method               string
    	requestUrl           *url.URL
    	headerToSign         string
    	queryToSign          string
    	bodyToSign           string
    	stringToSign         string
    	headerSignOrderNames string
    	date                 time.Time
    	formattedTime        string
    	formattedShortTime   string
    	signature            string
    	authorization        string
    	logger               Logger
    	credential           *Credential
    }
    
    // header 以 header_name:header_value 来一个一
    // 个 通 过 \n 拼 接 起 来 , EOP 是 强 制 要 求
    // ctyun-hybrid-request-id和hybrid-date这个头
    // header) 作为 Header 中的一部分,并且必须是待签名
    // Header 里的一个,EOP 末尾 有 \n 混合云没有
    func (c *ctYunHybridSignerContext) buildHeader() {
    	// var host = c.requestUrl.Host
    	// if host != "" {
    	// 	//	c.header.Set("Host", host)
    	// }
    	var headerKeys []string
    	var headersWillSign = map[string]string{}
    	for k, v := range c.header {
    		var valueString = strings.Join(v, ", ")
    		// header_name:header_value
    		headerDataWillSigner := fmt.Sprintf("%s:%s", k, valueString)
    		headersWillSign[k] = headerDataWillSigner
    		headerKeys = append(headerKeys, k)
    	}
    	sort.Strings(headerKeys)
    	var headersWillDatas []string
    	for _, key := range headerKeys {
    		headersWillDatas = append(headersWillDatas, headersWillSign[key])
    
    	}
    	c.headerToSign = strings.Join(headersWillDatas, "\n")
    	c.headerSignOrderNames = strings.Join(headerKeys, ";")
    
    }
    
    // query 以&作为拼接,key 和值以=连接,排序规则
    // 使用 26 个英文字母的顺序来排序,Query 参数全
    // 部都需要进行签 值 需要进行编码 (混合云 值不需要进行编码)注意如果有空格需要进行替换,go 的query编码标准与网关使用的java 不同,java 的 非rfc3986
    func (c *ctYunHybridSignerContext) buildQuery() {
    	if c.query == nil || len(c.query) == 0 {
    		c.queryToSign = ""
    		return
    	}
    	var querys []string
    	for k, v := range c.query {
    		for _, item := range v {
    			queryItem := fmt.Sprintf("%s=%s", k, item)
    			querys = append(querys, queryItem)
    		}
    	}
    	sort.Strings(querys)
    	c.queryToSign = strings.Join(querys, "&")
    }
    
    // EOP body 如果为空需要添加empty sha256 混合云 不需要 也不用拼接
    func (c *ctYunHybridSignerContext) buildBody() {
    	if c.body == nil || len(c.body) == 0 {
    		c.bodyToSign = ""
    		return
    	}
    	c.bodyToSign = hex.EncodeToString(makeSha256(c.body))
    }
    
    func (c *ctYunHybridSignerContext) buildStringToSign() {
    
    	if c.queryToSign != "" && c.bodyToSign != "" {
    		c.stringToSign = c.headerToSign + "\n" + c.queryToSign + "\n" + c.bodyToSign
    	} else if c.queryToSign != "" && c.bodyToSign == "" {
    		c.stringToSign = c.headerToSign + "\n" + c.queryToSign
    	} else if c.queryToSign == "" && c.bodyToSign != "" {
    		c.stringToSign = c.headerToSign + "\n" + c.bodyToSign
    	} else {
    		c.stringToSign = c.headerToSign
    	}
    
    }
    
    // 4.2.1 使用eop-date作为数据,sk作为密钥,算出ktime。
    // 4.2.2 使用ak作为数据,ktime作为密钥,算出kAk。
    // 4.2.3 使用eop-date的年月日值作为数据,kAk作为密钥,算出kdate。
    // eop-date
    // yyyymmddTHHMMSSZ(20211221T163614Z)(年月日T时分秒Z)
    // Ktime
    // 使用eop-date作为数据,sk作为密钥,算出ktime。
    // Ktime = hmacSha256(eop-date,sk)
    // kAk
    // 使用ak作为数据,ktime作为密钥,算出kAk。
    // kAk = hmacsha256(ak,ktime)
    // kdate
    // 使用eop-date的年月日值作为数据,kAk作为密钥,算出kdate。
    // kdate = hmacsha256(eop-date,kAk)
    // 使用kdate作为密钥、sigture作为数据,将其得到的结果进行base64编码得出Signature
    // Signature
    // 1)hmacsha256(sigture,kdate)
    // 2)将上一步的结果进行base64加密得出Signature
    func (c *ctYunHybridSignerContext) buildSignature() {
    	keyTime := makeHmac([]byte(c.credential.SecretAccessKey), []byte(c.formattedTime))
    	c.logger.Debugf("===============signature===================\nkeyTime:%s\n", hex.EncodeToString(keyTime))
    	keyAk := makeHmac(keyTime, []byte(c.credential.AccessKey))
    	c.logger.Debugf("keyAk:%s\n", hex.EncodeToString(keyAk))
    	kDate := makeHmac(keyAk, []byte(c.formattedShortTime))
    	c.logger.Debugf("kdate:%s\n", hex.EncodeToString(kDate))
    	sigtureData := makeHmac(kDate, []byte(c.stringToSign))
    	c.signature = base64.StdEncoding.EncodeToString(sigtureData)
    	c.logger.Debugf("signResult=%s\n=============== end signature===================\n", c.signature)
    }
    
    // 4.4.1 构造Headers。
    // 4.4.2得到Eop-Authorization。
    // Eop-Authorization:ak Headers=xxx Signature==xxx。
    // Headers
    // 将需要进行签名的请求头字段以 “header_name”的形式、以“;”作为间隔符、以英文字母表作为header_name的排序依据将它们拼接起来。
    // 例子(假设你需要将ctyun-eop-request-id、eop-date都要签名):Headers=
    // ctyun-eop-request-id;eop-date
    // Eop-Authorization
    // Eop-Authorization:ak Headers=xxx Signature=xxx。注意,ak、Headers、Signature之间以空格隔开。
    // 例如:Eop-Authorization:ak Headers=ctyun-eop-request-id;eop-date Signature=NlMHOhk5bVfZ9MwDSSJydcZjjENmDtpNYigJGVb
    // 注意:如果你需要进行签名的Header不止默认的ctyun-eop-request-id和eop-date,那么你需要在http_client的请求头部中加上,并且Eop-Authorization中也需要增加
    func (c *ctYunHybridSignerContext) buildAuthorization() {
    	c.authorization = fmt.Sprintf("%s Header=%s Signature=%s", c.credential.AccessKey, c.headerSignOrderNames, c.signature)
    	c.header.Set("Hybrid-Authorization", c.authorization)
    }
    
    func (s *CTYunHybridSigner) Sign(credential *Credential, request *CTYunRequestInfo) (http.Header, error) {
    	signerContext := &ctYunHybridSignerContext{
    		header:     request.Header,
    		query:      request.Query,
    		body:       request.body,
    		method:     request.Method,
    		requestUrl: request.Url,
    		logger:     request.logger,
    		credential: credential,
    		date:       request.Date,
    	}
    	if signerContext.header == nil {
    		signerContext.header = http.Header{}
    	}
    	var requestId = signerContext.header.Get("ctyun-hybrid-request-id")
    	if requestId == "" {
    		requestId = uuid.NewString()
    		signerContext.header.Set("ctyun-hybrid-request-id", requestId)
    	}
    	// hybrid-date:20210531T100101Z
    
    	signerContext.formattedTime = signerContext.date.Format(timeFormat)
    	signerContext.formattedShortTime = signerContext.date.Format(shortTimeFormat)
    	signerContext.header.Set("hybrid-date", signerContext.formattedTime)
    	signerContext.buildHeader()
    	signerContext.buildQuery()
    	signerContext.buildBody()
    	signerContext.buildStringToSign()
    	signerContext.buildSignature()
    	signerContext.buildAuthorization()
    	signerContext.logger.Debugf("------------------------------------------------------------\n")
    	signerContext.logger.Debugf("hybrid-date: %s\n", signerContext.formattedTime)
    	signerContext.logger.Debugf("signedHeaders:%s\n", signerContext.headerSignOrderNames)
    	signerContext.logger.Debugf("headerToSign:%s\n", signerContext.headerToSign)
    	signerContext.logger.Debugf("queryToSign:%s\n", signerContext.queryToSign)
    	signerContext.logger.Debugf("bodyToSign:\n%s\n", signerContext.bodyToSign)
    	signerContext.logger.Debugf("stringToSign:\n%s\n", signerContext.stringToSign)
    	signerContext.logger.Debugf("Hybrid-Authorization:\n%s\n-----------------------------------------------------\n", signerContext.authorization)
    
    	return signerContext.header, nil
    }
    
    func makeHmac(key []byte, data []byte) []byte {
    	hash := hmac.New(sha256.New, key)
    	hash.Write(data)
    	return hash.Sum(nil)
    }
    
    func makeSha256(data []byte) []byte {
    	hash := sha256.New()
    	hash.Write(data)
    	return hash.Sum(nil)
    }
    
    // 执行请求用例
    func Test_GetImageList(t *testing.T) {
    	start := time.Now().Unix()
    	fmt.Printf("start : %d", start)
    	var header = map[string]string{}
    
    	var query = url.Values{}
    	query.Add("regionID", "nm8")
    	query.Add("pageSize", "50")
    	query.Add("pageNo", "1")
    
    	request, err := NewCTYunRequestInfo("1", "127.0.0.1:9080", "/v4/image/list", "GET", HTTP, header, query,
    		nil, NewDefaultLoggerWithLevel(DEBUG))
    	if err != nil {
    		t.Fatal(err)
    	}
    	var authCredential = NewCredential("", "")
    	request.WithCredential(authCredential)
    	request.WithSigner(&CTYunHybridSigner{})
    	signHeader, err := request.DoSign()
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	for k, v := range signHeader {
    		fmt.Printf("%s:%s\n", k, v)
    	}
    
    	req, err := request.BuildRequest()
    	if err != nil {
    		t.Fatal(err)
    	}
    	req.Header.Add("ctuserid", "1000000566")
    
    	resp, err := http.DefaultClient.Do(req)
    	if err != nil {
    		t.Fatal(err)
    	}
    	fmt.Println(resp.Status)
    	if resp.Body != nil {
    		data, err := ioutil.ReadAll(resp.Body)
    		if err != nil {
    			t.Fatal(err)
    		}
    		fmt.Println(string(data))
    	}
    	end := time.Now().Unix()
    	fmt.Printf("end : %d, cost: %d", end, end-start)
    }
    
    
    
    修改于 2025-12-19 03:18:48
    上一页
    使用说明
    下一页
    网关常见问题说明
    Built with