/*
 * Copyright 2018 JDCLOUD.COM
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * 用户设置
 * 查询用户设置接口
 *
 * OpenAPI spec version: v1
 * Contact:
 *
 * NOTE: This class is auto generated by the jdcloud code generator program.
 */

require('../../../lib/node_loader')
var JDCloud = require('../../../lib/core')
var Service = JDCloud.Service
var serviceId = 'nativecontainer'
Service._services[serviceId] = true

/**
 * nativecontainer service.
 * @version 2.3.0
 */

class NATIVECONTAINER extends Service {
  constructor (options = {}) {
    options._defaultEndpoint = {}
    options._defaultEndpoint.protocol =
      options._defaultEndpoint.protocol || 'https'
    options._defaultEndpoint.host =
      options._defaultEndpoint.host || 'nativecontainer.jdcloud-api.com'
    options.basePath = '/v1' // 默认要设为空""
    super(serviceId, options)
  }

  /**
      *  批量查询原生容器的详细信息&lt;br&gt;
此接口支持分页查询，默认每页20条。

      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 页码；默认为1  optional
      * @param {integer} [opts.pageSize] - 分页大小；默认为20；取值范围[10, 100]  optional
      * @param {filter} [opts.filters] - containerId - 实例ID，精确匹配，支持多个
privateIpAddress - 主网卡IP地址，模糊匹配，支持单个
az - 可用区，精确匹配，支持多个
vpcId - 私有网络ID，精确匹配，支持多个
status - 容器状态，精确匹配，支持多个
name - 容器名称，模糊匹配，支持单个
subnetId - 子网ID，精确匹配，支持多个
agId - 镜像ID，精确匹配，支持多个
  optional
      * @param {tagFilter} [opts.tags] - Tag筛选条件  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param container containers
      * @param number totalCount
      */

  describeContainers (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeContainers"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))
    Object.assign(queryParams, super.buildTagFilterParam(opts.tags, 'tags'))

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeContainers with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  创建一台或多台指定配置容器
- 创建容器需要通过实名认证
- 可用区
  - 容器所属的可用区
  - 创建容器，需要使用中心可用区的相关资源：
    - 具有中心可用区属性的子网
    - 公网IP服务商
- 镜像
  - 容器的镜像通过镜像名称来确定
  - nginx:tag, mysql/mysql-server:tag这样命名的镜像表示docker hub官方镜像
  - container-registry/image:tag这样命名的镜像表示私有仓储的镜像
  - 私有仓储必须兼容docker registry认证机制，并通过secret来保存机密信息
- hostname规范
  - 支持两种方式：以标签方式书写或以完整主机名方式书写
  - 标签规范
    - 0-9，a-z(不分大小写)和-（减号），其他的都是无效的字符串
    - 不能以减号开始，也不能以减号结尾
    - 最小1个字符，最大63个字符
  - 完整的主机名由一系列标签与点连接组成
    - 标签与标签之间使用“.”(点)进行连接
    - 不能以“.”(点)开始，也不能以“.”(点)结尾
    - 整个主机名（包括标签以及分隔点“.”）最多有63个ASCII字符
- 网络配置
  - 指定主网卡配置信息
    - 必须指定vpcId、subnetId、securityGroupIds
    - 可以指定elasticIp规格来约束创建的弹性IP，带宽取值范围[1-200]Mbps，步进1Mbps
    - 可以指定网卡的主IP(primaryIpAddress)和辅助IP(secondaryIpAddresses)，此时maxCount只能为1
    - 可以指定希望的辅助IP个数(secondaryIpAddressCount)让系统自动创建内网IP
    - 可以设置网卡的自动删除autoDelete属性，指明是否删除实例时自动删除网卡
    - 安全组securityGroup需与子网Subnet在同一个私有网络VPC内
    - 每个容器至多指定5个安全组
    - 主网卡deviceIndex设置为0
- 存储
  - volume分为root volume和data volume，root volume的挂载目录是/，data volume的挂载目录可以随意指定
  - volume的底层存储介质当前只支持cloud类别，也就是云硬盘
  - 云盘类型为 ssd.io1 时，用户可以指定 iops，其他类型云盘无效，对已经存在的云盘无效，具体规则如下
    - 步长 10
    - 范围 [200，min(32000，size*50)]
    - 默认值 size*30
  - root volume
  - root volume支持cloud和local
    - 云硬盘类型可以选择hdd.std1、ssd.gp1、ssd.io1
    - 磁盘大小
      - 所有类型：范围[10,100]GB，步长为10G
    - 自动删除
      - 默认自动删除
    - 可以选择已存在的云硬盘
  - data volume
    - data volume当前只能选择cloud类别
    - 云硬盘类型可以选择hdd.std1、ssd.gp1、ssd.io1
    - 磁盘大小
      - 所有类型：范围[20,2000]GB，步长为10G
    - 自动删除
      - 默认自动删除
    - 可以选择已存在的云硬盘
    - 可以从快照创建磁盘
    - 单个容器可以挂载7个data volume
- 容器日志
  - default：默认在本地分配10MB的存储空间，自动rotate
- 其他
  - 创建完成后，容器状态为running
  - maxCount为最大努力，不保证一定能达到maxCount

      * @param {Object} opts - parameters
      * @param {containerSpec} opts.containerSpec - 创建容器规格
      * @param {integer} opts.maxCount - 购买实例数量；取值范围：[1,100]
      * @param {string} [opts.clientToken] - 保证请求幂等性  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string containerIds
      */

  createContainers (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  createContainers"
      )
    }

    opts = opts || {}

    if (opts.containerSpec === undefined || opts.containerSpec === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerSpec' when calling createContainers"
      )
    }
    if (opts.maxCount === undefined || opts.maxCount === null) {
      throw new Error(
        "Missing the required parameter 'opts.maxCount' when calling createContainers"
      )
    }

    let postBody = {}
    if (opts.containerSpec !== undefined && opts.containerSpec !== null) {
      postBody['containerSpec'] = opts.containerSpec
    }
    if (opts.maxCount !== undefined && opts.maxCount !== null) {
      postBody['maxCount'] = opts.maxCount
    }
    if (opts.clientToken !== undefined && opts.clientToken !== null) {
      postBody['clientToken'] = opts.clientToken
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call createContainers with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  &quot;查询一台原生容器的详细信息&quot;

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param container container
      */

  describeContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling describeContainer"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  容器状态必须为 stopped、running 或 error状态。 &lt;br&gt;
按量付费的实例，如不主动删除将一直运行，不再使用的实例，可通过本接口主动停用。&lt;br&gt;
只能支持主动删除按配置计费类型的实例。包年包月过期的容器也可以删除，其它的情况还请发工单系统。计费状态异常的容器无法删除。

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  deleteContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  deleteContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling deleteContainer"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call deleteContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}',
      'DELETE',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  启动处于关闭状态的单个容器，处在任务执行中的容器无法启动。&lt;br&gt;
容器实例或其绑定的云盘已欠费时，容器将无法正常启动。&lt;br&gt;

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  startContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  startContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling startContainer"
      )
    }

    let postBody = {}

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call startContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:startContainer',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  停止处于运行状态的单个实例，处于任务执行中的容器无法启动。

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  stopContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  stopContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling stopContainer"
      )
    }

    let postBody = {}

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call stopContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:stopContainer',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  修改容器的 名称 和 描述。&lt;br&gt;
name 和 description 必须要指定一个

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} [opts.name] - 容器名称  optional
      * @param {string} [opts.description] - 容器描述  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  modifyContainerAttribute (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  modifyContainerAttribute"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling modifyContainerAttribute"
      )
    }

    let postBody = {}
    if (opts.name !== undefined && opts.name !== null) {
      postBody['name'] = opts.name
    }
    if (opts.description !== undefined && opts.description !== null) {
      postBody['description'] = opts.description
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call modifyContainerAttribute with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:modifyContainerAttribute',
      'PATCH',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  容器绑定弹性公网 IP，绑定的是主网卡、主内网IP对应的弹性IP. &lt;br&gt;
一台云主机只能绑定一个弹性公网 IP(主网卡)，若主网卡已存在弹性公网IP，会返回错误。&lt;br&gt;
如果是黑名单中的用户，会返回错误。

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} opts.elasticIpId - 弹性IP ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  associateElasticIp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  associateElasticIp"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling associateElasticIp"
      )
    }
    if (opts.elasticIpId === undefined || opts.elasticIpId === null) {
      throw new Error(
        "Missing the required parameter 'opts.elasticIpId' when calling associateElasticIp"
      )
    }

    let postBody = {}
    if (opts.elasticIpId !== undefined && opts.elasticIpId !== null) {
      postBody['elasticIpId'] = opts.elasticIpId
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call associateElasticIp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:associateElasticIp',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  容器解绑公网 IP，解绑的是主网卡、主内网 IP 对应的弹性 IP.

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} opts.elasticIpId - 弹性IP ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  disassociateElasticIp (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  disassociateElasticIp"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling disassociateElasticIp"
      )
    }
    if (opts.elasticIpId === undefined || opts.elasticIpId === null) {
      throw new Error(
        "Missing the required parameter 'opts.elasticIpId' when calling disassociateElasticIp"
      )
    }

    let postBody = {}
    if (opts.elasticIpId !== undefined && opts.elasticIpId !== null) {
      postBody['elasticIpId'] = opts.elasticIpId
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call disassociateElasticIp with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:disassociateElasticIp',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询单个容器日志

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {integer} [opts.tailLines] - 返回日志文件中倒数 tailLines 行，如不指定，默认从容器启动时或 sinceSeconds 指定的时间读取。
  optional
      * @param {integer} [opts.sinceSeconds] - 返回相对于当前时间之前sinceSeconds之内的日志。
  optional
      * @param {integer} [opts.limitBytes] - 限制返回的日志文件内容字节数，取值范围 [1-4]KB，最大 4KB.
  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param object logs
      */

  getLogs (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  getLogs"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling getLogs"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.tailLines !== undefined && opts.tailLines !== null) {
      queryParams['tailLines'] = opts.tailLines
    }
    if (opts.sinceSeconds !== undefined && opts.sinceSeconds !== null) {
      queryParams['sinceSeconds'] = opts.sinceSeconds
    }
    if (opts.limitBytes !== undefined && opts.limitBytes !== null) {
      queryParams['limitBytes'] = opts.limitBytes
    }

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call getLogs with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:getLogs',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  重置原生容器，对已有原生容器使用新的镜像重置。
原容器 id 不变，不涉及计费变动，暂不支持修改实例类型，不会改变原生容器所在的物理节点，也不支持修改已经使用的系统盘和数据盘以及网络相关参数。
- 镜像
    - 容器的镜像通过镜像名称来确定
    - nginx:tag 或 mysql/mysql-server:tag 这样命名的镜像表示 docker hub 官方镜像
    - container-registry/image:tag 这样命名的镜像表示私有仓储的镜像
    - 私有仓储必须兼容 docker registry 认证机制，并通过 secret 来保存机密信息
- 其他
    - rebuild 之前容器必须处于关闭状态
    - rebuild 完成后，容器仍为关闭状态

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} opts.image - 镜像名称 &lt;/br&gt; 1. Docker Hub官方镜像通过类似nginx, mysql/mysql-server的名字指定 &lt;/br&gt; &lt;/br&gt; repository长度最大256个字符，tag最大128个字符，registry最大255个字符 &lt;/br&gt; 下载镜像超时时间：10分钟
      * @param {string} [opts.secret] - 镜像仓库认证信息；使用Docker Hub和京东云CR的镜像不需要secret  optional
      * @param {array} [opts.command] - 容器启动执行的命令, 如果不指定默认是镜像的ENTRYPOINT. 数组字符总长度范围：[0-256]  optional
      * @param {array} [opts.args] - 容器启动执行命令的参数, 如果不指定默认是镜像的CMD. 数组字符总长度范围：[0-2048]  optional
      * @param {boolean} [opts.tty] - 容器是否分配tty。默认不分配  optional
      * @param {string} [opts.workingDir] - 容器的工作目录。如果不指定，默认是根目录（/），必须是绝对路径。字符长度范围：[0-1024]  optional
      * @param {array} [opts.envs] - 容器执行的环境变量；如果和镜像中的环境变量Key相同，会覆盖镜像中的值；&lt;/br&gt; 最大100对  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  rebuildContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  rebuildContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling rebuildContainer"
      )
    }
    if (opts.image === undefined || opts.image === null) {
      throw new Error(
        "Missing the required parameter 'opts.image' when calling rebuildContainer"
      )
    }

    let postBody = {}
    if (opts.image !== undefined && opts.image !== null) {
      postBody['image'] = opts.image
    }
    if (opts.secret !== undefined && opts.secret !== null) {
      postBody['secret'] = opts.secret
    }
    if (opts.command !== undefined && opts.command !== null) {
      postBody['command'] = opts.command
    }
    if (opts.args !== undefined && opts.args !== null) {
      postBody['args'] = opts.args
    }
    if (opts.tty !== undefined && opts.tty !== null) {
      postBody['tty'] = opts.tty
    }
    if (opts.workingDir !== undefined && opts.workingDir !== null) {
      postBody['workingDir'] = opts.workingDir
    }
    if (opts.envs !== undefined && opts.envs !== null) {
      postBody['envs'] = opts.envs
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call rebuildContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:rebuild',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  调整原生容器实例类型配置。
- 原生容器状态为停止;
- 支持升配、降配；**不支持原有规格**
- 计费类型不变
    - 包年包月：需要计算配置差价，如果所选配置价格高，需要补齐到期前的差价，到期时间不变；如果所选配置价格低，需要延长到期时间
    - 按配置：按照所选规格，进行计费

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} opts.instanceType - 新实例类型，不可与原实例类型相同
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  resizeContainer (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  resizeContainer"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling resizeContainer"
      )
    }
    if (opts.instanceType === undefined || opts.instanceType === null) {
      throw new Error(
        "Missing the required parameter 'opts.instanceType' when calling resizeContainer"
      )
    }

    let postBody = {}
    if (opts.instanceType !== undefined && opts.instanceType !== null) {
      postBody['instanceType'] = opts.instanceType
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call resizeContainer with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:resize',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  创建exec

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {array} [opts.command] - 执行命令  optional
      * @param {boolean} [opts.tty] - 执行命令是否添加tty  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string execId
      */

  execCreate (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  execCreate"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling execCreate"
      )
    }

    let postBody = {}
    if (opts.command !== undefined && opts.command !== null) {
      postBody['command'] = opts.command
    }
    if (opts.tty !== undefined && opts.tty !== null) {
      postBody['tty'] = opts.tty
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call execCreate with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:execCreate',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  获取exec退出码

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {string} opts.execId - exec ID
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param integer exitCode
      */

  execGetExitCode (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  execGetExitCode"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling execGetExitCode"
      )
    }
    if (opts.execId === undefined || opts.execId === null) {
      throw new Error(
        "Missing the required parameter 'opts.execId' when calling execGetExitCode"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.execId !== undefined && opts.execId !== null) {
      queryParams['execId'] = opts.execId
    }

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call execGetExitCode with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:execGetExitCode',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  调整TTY大小

      * @param {Object} opts - parameters
      * @param {string} opts.containerId - Container ID
      * @param {integer} opts.height - tty row
      * @param {integer} opts.width - tty column
      * @param {string} [opts.execId] - exec ID  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  resizeTTY (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  resizeTTY"
      )
    }

    opts = opts || {}

    if (opts.containerId === undefined || opts.containerId === null) {
      throw new Error(
        "Missing the required parameter 'opts.containerId' when calling resizeTTY"
      )
    }
    if (opts.height === undefined || opts.height === null) {
      throw new Error(
        "Missing the required parameter 'opts.height' when calling resizeTTY"
      )
    }
    if (opts.width === undefined || opts.width === null) {
      throw new Error(
        "Missing the required parameter 'opts.width' when calling resizeTTY"
      )
    }

    let postBody = {}
    if (opts.height !== undefined && opts.height !== null) {
      postBody['height'] = opts.height
    }
    if (opts.width !== undefined && opts.width !== null) {
      postBody['width'] = opts.width
    }
    if (opts.execId !== undefined && opts.execId !== null) {
      postBody['execId'] = opts.execId
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      containerId: opts.containerId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call resizeTTY with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/containers/{containerId}:resizeTTY',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询实例规格信息列表

      * @param {Object} opts - parameters
      * @param {filter} [opts.filters] - instanceTypes - 实例规格，精确匹配，支持多个
az - 可用区，精确匹配，支持多个
  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param instanceType instanceTypes
      * @param instanceType specificInstanceTypes
      * @param integer totalCount  总数量
      */

  describeInstanceTypes (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeInstanceTypes"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}
    Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeInstanceTypes with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/instanceTypes',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询资源的配额，支持：原生容器 pod 和 secret.

      * @param {Object} opts - parameters
      * @param {string} opts.resourceType - resourceType - 资源类型，支持 [container, pod, secret]

      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param quota quota
      */

  describeQuota (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeQuota"
      )
    }

    opts = opts || {}

    if (opts.resourceType === undefined || opts.resourceType === null) {
      throw new Error(
        "Missing the required parameter 'opts.resourceType' when calling describeQuota"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.resourceType !== undefined && opts.resourceType !== null) {
      queryParams['resourceType'] = opts.resourceType
    }

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeQuota with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/quotas',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询 secret 列表。&lt;br&gt;
此接口支持分页查询，默认每页20条。

      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 页码；默认为1  optional
      * @param {integer} [opts.pageSize] - 分页大小；默认为20；取值范围[10, 100]  optional
      * @param {filter} [opts.filters] - name - secret名称，支持模糊搜索
  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param secret secrets
      * @param number totalCount
      */

  describeSecrets (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeSecrets"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeSecrets with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/secrets',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  创建一个 secret，用于存放镜像仓库认证信息。

      * @param {Object} opts - parameters
      * @param {string} opts.name - 镜像仓库认证信息名称，不能重复

      * @param {string} opts.secretType - 镜像仓库认证信息类型，目前仅支持：docker-registry 类型，用来和docker registry认证的类型。

      * @param {dockerRegistryData} opts.data - 镜像仓库认证信息数据。&lt;br&gt;
必须包含server、username、password 字段，email 字段是可选的。&lt;br&gt;

      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string secretName
      */

  createSecret (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  createSecret"
      )
    }

    opts = opts || {}

    if (opts.name === undefined || opts.name === null) {
      throw new Error(
        "Missing the required parameter 'opts.name' when calling createSecret"
      )
    }
    if (opts.secretType === undefined || opts.secretType === null) {
      throw new Error(
        "Missing the required parameter 'opts.secretType' when calling createSecret"
      )
    }
    if (opts.data === undefined || opts.data === null) {
      throw new Error(
        "Missing the required parameter 'opts.data' when calling createSecret"
      )
    }

    let postBody = {}
    if (opts.name !== undefined && opts.name !== null) {
      postBody['name'] = opts.name
    }
    if (opts.secretType !== undefined && opts.secretType !== null) {
      postBody['secretType'] = opts.secretType
    }
    if (opts.data !== undefined && opts.data !== null) {
      postBody['data'] = opts.data
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call createSecret with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/secrets',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询单个 secret 详情

      * @param {Object} opts - parameters
      * @param {string} opts.name - Secret Name
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param secret secret
      */

  describeSecret (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeSecret"
      )
    }

    opts = opts || {}

    if (opts.name === undefined || opts.name === null) {
      throw new Error(
        "Missing the required parameter 'opts.name' when calling describeSecret"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      name: opts.name
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeSecret with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/secrets/{name}',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  删除单个 secret

      * @param {Object} opts - parameters
      * @param {string} opts.name - Secret Name
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  deleteSecret (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  deleteSecret"
      )
    }

    opts = opts || {}

    if (opts.name === undefined || opts.name === null) {
      throw new Error(
        "Missing the required parameter 'opts.name' when calling deleteSecret"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      name: opts.name
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  nativecontainer/2.3.0'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call deleteSecret with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = super.makeRequest(
      '/regions/{regionId}/secrets/{name}',
      'DELETE',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }
}
module.exports = NATIVECONTAINER
