You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2022/04/18 08:21:22 UTC

[cloudstack-go] 01/01: Updating for 4.16.1

This is an automated email from the ASF dual-hosted git repository.

davidjumani pushed a commit to branch 4161
in repository https://gitbox.apache.org/repos/asf/cloudstack-go.git

commit f6950f058088ae4a2e0beb0afdcf56880eae621b
Author: davidjumani <dj...@gmail.com>
AuthorDate: Mon Apr 18 13:51:03 2022 +0530

    Updating for 4.16.1
---
 Makefile                                           |      2 +-
 cloudstack/AccountService.go                       |    247 -
 cloudstack/AccountService_mock.go                  |     58 -
 cloudstack/AnnotationService.go                    |    563 +
 cloudstack/AnnotationService_mock.go               |    190 +
 cloudstack/HypervisorService.go                    |     78 +
 cloudstack/KubernetesService.go                    |   2152 +
 cloudstack/KubernetesService_mock.go               |    527 +
 cloudstack/LoadBalancerService.go                  |      8 +-
 cloudstack/PoolService.go                          |    107 +
 cloudstack/PoolService_mock.go                     |     29 +
 cloudstack/ProjectService.go                       |    495 +
 cloudstack/ProjectService_mock.go                  |    116 +
 cloudstack/RoleService.go                          |    144 +
 cloudstack/RoleService_mock.go                     |     29 +
 cloudstack/SSHService.go                           |     68 +
 cloudstack/SSHService_mock.go                      |     42 +
 cloudstack/VolumeService.go                        |    964 +-
 cloudstack/VolumeService_mock.go                   |    150 +
 cloudstack/ZoneService.go                          |    398 +
 cloudstack/ZoneService_mock.go                     |     92 +
 cloudstack/cloudstack.go                           |     22 +
 generate/generate.go                               |      7 +-
 generate/layout.go                                 |     32 +-
 generate/listApis.json                             | 113631 +++++++++---------
 test/AccountService_test.go                        |     24 -
 ...olService_test.go => AnnotationService_test.go} |     56 +-
 test/KubernetesService_test.go                     |    182 +
 test/PoolService_test.go                           |     12 +
 test/ProjectService_test.go                        |     48 +
 test/RoleService_test.go                           |     12 +
 test/VolumeService_test.go                         |     36 +
 test/ZoneService_test.go                           |     12 +
 test/testdata/AnnotationService.json               |     72 +
 test/testdata/KubernetesService.json               |    331 +
 35 files changed, 65328 insertions(+), 55608 deletions(-)

diff --git a/Makefile b/Makefile
index 3c52362..fe37f68 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ mock-gen:
 	done
 
 test:
-	go test -v ./...
+	go test github.com/apache/cloudstack-go/v2/test
 
 MOCKGEN := $(shell pwd)/bin/mockgen
 mockgen: ## Download conversion-gen locally if necessary.
diff --git a/cloudstack/AccountService.go b/cloudstack/AccountService.go
index 32680e5..66270b6 100644
--- a/cloudstack/AccountService.go
+++ b/cloudstack/AccountService.go
@@ -28,14 +28,10 @@ import (
 )
 
 type AccountServiceIface interface {
-	AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error)
-	NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams
 	CreateAccount(p *CreateAccountParams) (*CreateAccountResponse, error)
 	NewCreateAccountParams(email string, firstname string, lastname string, password string, username string) *CreateAccountParams
 	DeleteAccount(p *DeleteAccountParams) (*DeleteAccountResponse, error)
 	NewDeleteAccountParams(id string) *DeleteAccountParams
-	DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error)
-	NewDeleteAccountFromProjectParams(account string, projectid string) *DeleteAccountFromProjectParams
 	DisableAccount(p *DisableAccountParams) (*DisableAccountResponse, error)
 	NewDisableAccountParams(lock bool) *DisableAccountParams
 	EnableAccount(p *EnableAccountParams) (*EnableAccountResponse, error)
@@ -58,154 +54,6 @@ type AccountServiceIface interface {
 	NewUpdateAccountParams() *UpdateAccountParams
 }
 
-type AddAccountToProjectParams struct {
-	p map[string]interface{}
-}
-
-func (p *AddAccountToProjectParams) toURLValues() url.Values {
-	u := url.Values{}
-	if p.p == nil {
-		return u
-	}
-	if v, found := p.p["account"]; found {
-		u.Set("account", v.(string))
-	}
-	if v, found := p.p["email"]; found {
-		u.Set("email", v.(string))
-	}
-	if v, found := p.p["projectid"]; found {
-		u.Set("projectid", v.(string))
-	}
-	if v, found := p.p["projectroleid"]; found {
-		u.Set("projectroleid", v.(string))
-	}
-	if v, found := p.p["roletype"]; found {
-		u.Set("roletype", v.(string))
-	}
-	return u
-}
-
-func (p *AddAccountToProjectParams) SetAccount(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["account"] = v
-}
-
-func (p *AddAccountToProjectParams) GetAccount() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["account"].(string)
-	return value, ok
-}
-
-func (p *AddAccountToProjectParams) SetEmail(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["email"] = v
-}
-
-func (p *AddAccountToProjectParams) GetEmail() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["email"].(string)
-	return value, ok
-}
-
-func (p *AddAccountToProjectParams) SetProjectid(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["projectid"] = v
-}
-
-func (p *AddAccountToProjectParams) GetProjectid() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["projectid"].(string)
-	return value, ok
-}
-
-func (p *AddAccountToProjectParams) SetProjectroleid(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["projectroleid"] = v
-}
-
-func (p *AddAccountToProjectParams) GetProjectroleid() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["projectroleid"].(string)
-	return value, ok
-}
-
-func (p *AddAccountToProjectParams) SetRoletype(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["roletype"] = v
-}
-
-func (p *AddAccountToProjectParams) GetRoletype() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["roletype"].(string)
-	return value, ok
-}
-
-// You should always use this function to get a new AddAccountToProjectParams instance,
-// as then you are sure you have configured all required params
-func (s *AccountService) NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams {
-	p := &AddAccountToProjectParams{}
-	p.p = make(map[string]interface{})
-	p.p["projectid"] = projectid
-	return p
-}
-
-// Adds account to a project
-func (s *AccountService) AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error) {
-	resp, err := s.cs.newRequest("addAccountToProject", p.toURLValues())
-	if err != nil {
-		return nil, err
-	}
-
-	var r AddAccountToProjectResponse
-	if err := json.Unmarshal(resp, &r); err != nil {
-		return nil, err
-	}
-
-	// If we have a async client, we need to wait for the async result
-	if s.cs.async {
-		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
-		if err != nil {
-			if err == AsyncTimeoutErr {
-				return &r, err
-			}
-			return nil, err
-		}
-
-		if err := json.Unmarshal(b, &r); err != nil {
-			return nil, err
-		}
-	}
-
-	return &r, nil
-}
-
-type AddAccountToProjectResponse struct {
-	Displaytext string `json:"displaytext"`
-	JobID       string `json:"jobid"`
-	Jobstatus   int    `json:"jobstatus"`
-	Success     bool   `json:"success"`
-}
-
 type CreateAccountParams struct {
 	p map[string]interface{}
 }
@@ -672,101 +520,6 @@ type DeleteAccountResponse struct {
 	Success     bool   `json:"success"`
 }
 
-type DeleteAccountFromProjectParams struct {
-	p map[string]interface{}
-}
-
-func (p *DeleteAccountFromProjectParams) toURLValues() url.Values {
-	u := url.Values{}
-	if p.p == nil {
-		return u
-	}
-	if v, found := p.p["account"]; found {
-		u.Set("account", v.(string))
-	}
-	if v, found := p.p["projectid"]; found {
-		u.Set("projectid", v.(string))
-	}
-	return u
-}
-
-func (p *DeleteAccountFromProjectParams) SetAccount(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["account"] = v
-}
-
-func (p *DeleteAccountFromProjectParams) GetAccount() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["account"].(string)
-	return value, ok
-}
-
-func (p *DeleteAccountFromProjectParams) SetProjectid(v string) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	p.p["projectid"] = v
-}
-
-func (p *DeleteAccountFromProjectParams) GetProjectid() (string, bool) {
-	if p.p == nil {
-		p.p = make(map[string]interface{})
-	}
-	value, ok := p.p["projectid"].(string)
-	return value, ok
-}
-
-// You should always use this function to get a new DeleteAccountFromProjectParams instance,
-// as then you are sure you have configured all required params
-func (s *AccountService) NewDeleteAccountFromProjectParams(account string, projectid string) *DeleteAccountFromProjectParams {
-	p := &DeleteAccountFromProjectParams{}
-	p.p = make(map[string]interface{})
-	p.p["account"] = account
-	p.p["projectid"] = projectid
-	return p
-}
-
-// Deletes account from the project
-func (s *AccountService) DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error) {
-	resp, err := s.cs.newRequest("deleteAccountFromProject", p.toURLValues())
-	if err != nil {
-		return nil, err
-	}
-
-	var r DeleteAccountFromProjectResponse
-	if err := json.Unmarshal(resp, &r); err != nil {
-		return nil, err
-	}
-
-	// If we have a async client, we need to wait for the async result
-	if s.cs.async {
-		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
-		if err != nil {
-			if err == AsyncTimeoutErr {
-				return &r, err
-			}
-			return nil, err
-		}
-
-		if err := json.Unmarshal(b, &r); err != nil {
-			return nil, err
-		}
-	}
-
-	return &r, nil
-}
-
-type DeleteAccountFromProjectResponse struct {
-	Displaytext string `json:"displaytext"`
-	JobID       string `json:"jobid"`
-	Jobstatus   int    `json:"jobstatus"`
-	Success     bool   `json:"success"`
-}
-
 type DisableAccountParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/AccountService_mock.go b/cloudstack/AccountService_mock.go
index 02bbd6f..605bb3a 100644
--- a/cloudstack/AccountService_mock.go
+++ b/cloudstack/AccountService_mock.go
@@ -52,21 +52,6 @@ func (m *MockAccountServiceIface) EXPECT() *MockAccountServiceIfaceMockRecorder
 	return m.recorder
 }
 
-// AddAccountToProject mocks base method.
-func (m *MockAccountServiceIface) AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AddAccountToProject", p)
-	ret0, _ := ret[0].(*AddAccountToProjectResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AddAccountToProject indicates an expected call of AddAccountToProject.
-func (mr *MockAccountServiceIfaceMockRecorder) AddAccountToProject(p interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAccountToProject", reflect.TypeOf((*MockAccountServiceIface)(nil).AddAccountToProject), p)
-}
-
 // CreateAccount mocks base method.
 func (m *MockAccountServiceIface) CreateAccount(p *CreateAccountParams) (*CreateAccountResponse, error) {
 	m.ctrl.T.Helper()
@@ -97,21 +82,6 @@ func (mr *MockAccountServiceIfaceMockRecorder) DeleteAccount(p interface{}) *gom
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).DeleteAccount), p)
 }
 
-// DeleteAccountFromProject mocks base method.
-func (m *MockAccountServiceIface) DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteAccountFromProject", p)
-	ret0, _ := ret[0].(*DeleteAccountFromProjectResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteAccountFromProject indicates an expected call of DeleteAccountFromProject.
-func (mr *MockAccountServiceIfaceMockRecorder) DeleteAccountFromProject(p interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccountFromProject", reflect.TypeOf((*MockAccountServiceIface)(nil).DeleteAccountFromProject), p)
-}
-
 // DisableAccount mocks base method.
 func (m *MockAccountServiceIface) DisableAccount(p *DisableAccountParams) (*DisableAccountResponse, error) {
 	m.ctrl.T.Helper()
@@ -301,20 +271,6 @@ func (mr *MockAccountServiceIfaceMockRecorder) MarkDefaultZoneForAccount(p inter
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDefaultZoneForAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).MarkDefaultZoneForAccount), p)
 }
 
-// NewAddAccountToProjectParams mocks base method.
-func (m *MockAccountServiceIface) NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "NewAddAccountToProjectParams", projectid)
-	ret0, _ := ret[0].(*AddAccountToProjectParams)
-	return ret0
-}
-
-// NewAddAccountToProjectParams indicates an expected call of NewAddAccountToProjectParams.
-func (mr *MockAccountServiceIfaceMockRecorder) NewAddAccountToProjectParams(projectid interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddAccountToProjectParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewAddAccountToProjectParams), projectid)
-}
-
 // NewCreateAccountParams mocks base method.
 func (m *MockAccountServiceIface) NewCreateAccountParams(email, firstname, lastname, password, username string) *CreateAccountParams {
 	m.ctrl.T.Helper()
@@ -329,20 +285,6 @@ func (mr *MockAccountServiceIfaceMockRecorder) NewCreateAccountParams(email, fir
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewCreateAccountParams), email, firstname, lastname, password, username)
 }
 
-// NewDeleteAccountFromProjectParams mocks base method.
-func (m *MockAccountServiceIface) NewDeleteAccountFromProjectParams(account, projectid string) *DeleteAccountFromProjectParams {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "NewDeleteAccountFromProjectParams", account, projectid)
-	ret0, _ := ret[0].(*DeleteAccountFromProjectParams)
-	return ret0
-}
-
-// NewDeleteAccountFromProjectParams indicates an expected call of NewDeleteAccountFromProjectParams.
-func (mr *MockAccountServiceIfaceMockRecorder) NewDeleteAccountFromProjectParams(account, projectid interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteAccountFromProjectParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewDeleteAccountFromProjectParams), account, projectid)
-}
-
 // NewDeleteAccountParams mocks base method.
 func (m *MockAccountServiceIface) NewDeleteAccountParams(id string) *DeleteAccountParams {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/AnnotationService.go b/cloudstack/AnnotationService.go
new file mode 100644
index 0000000..915a345
--- /dev/null
+++ b/cloudstack/AnnotationService.go
@@ -0,0 +1,563 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+type AnnotationServiceIface interface {
+	AddAnnotation(p *AddAnnotationParams) (*AddAnnotationResponse, error)
+	NewAddAnnotationParams() *AddAnnotationParams
+	ListAnnotations(p *ListAnnotationsParams) (*ListAnnotationsResponse, error)
+	NewListAnnotationsParams() *ListAnnotationsParams
+	GetAnnotationByID(id string, opts ...OptionFunc) (*Annotation, int, error)
+	RemoveAnnotation(p *RemoveAnnotationParams) (*RemoveAnnotationResponse, error)
+	NewRemoveAnnotationParams(id string) *RemoveAnnotationParams
+	UpdateAnnotationVisibility(p *UpdateAnnotationVisibilityParams) (*UpdateAnnotationVisibilityResponse, error)
+	NewUpdateAnnotationVisibilityParams(adminsonly bool, id string) *UpdateAnnotationVisibilityParams
+}
+
+type AddAnnotationParams struct {
+	p map[string]interface{}
+}
+
+func (p *AddAnnotationParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["adminsonly"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("adminsonly", vv)
+	}
+	if v, found := p.p["annotation"]; found {
+		u.Set("annotation", v.(string))
+	}
+	if v, found := p.p["entityid"]; found {
+		u.Set("entityid", v.(string))
+	}
+	if v, found := p.p["entitytype"]; found {
+		u.Set("entitytype", v.(string))
+	}
+	return u
+}
+
+func (p *AddAnnotationParams) SetAdminsonly(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["adminsonly"] = v
+}
+
+func (p *AddAnnotationParams) GetAdminsonly() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["adminsonly"].(bool)
+	return value, ok
+}
+
+func (p *AddAnnotationParams) SetAnnotation(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["annotation"] = v
+}
+
+func (p *AddAnnotationParams) GetAnnotation() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["annotation"].(string)
+	return value, ok
+}
+
+func (p *AddAnnotationParams) SetEntityid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["entityid"] = v
+}
+
+func (p *AddAnnotationParams) GetEntityid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["entityid"].(string)
+	return value, ok
+}
+
+func (p *AddAnnotationParams) SetEntitytype(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["entitytype"] = v
+}
+
+func (p *AddAnnotationParams) GetEntitytype() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["entitytype"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new AddAnnotationParams instance,
+// as then you are sure you have configured all required params
+func (s *AnnotationService) NewAddAnnotationParams() *AddAnnotationParams {
+	p := &AddAnnotationParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// add an annotation.
+func (s *AnnotationService) AddAnnotation(p *AddAnnotationParams) (*AddAnnotationResponse, error) {
+	resp, err := s.cs.newRequest("addAnnotation", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	if resp, err = getRawValue(resp); err != nil {
+		return nil, err
+	}
+
+	var r AddAnnotationResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type AddAnnotationResponse struct {
+	Adminsonly bool   `json:"adminsonly"`
+	Annotation string `json:"annotation"`
+	Created    string `json:"created"`
+	Entityid   string `json:"entityid"`
+	Entityname string `json:"entityname"`
+	Entitytype string `json:"entitytype"`
+	Id         string `json:"id"`
+	JobID      string `json:"jobid"`
+	Jobstatus  int    `json:"jobstatus"`
+	Removed    string `json:"removed"`
+	Userid     string `json:"userid"`
+	Username   string `json:"username"`
+}
+
+type ListAnnotationsParams struct {
+	p map[string]interface{}
+}
+
+func (p *ListAnnotationsParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["annotationfilter"]; found {
+		u.Set("annotationfilter", v.(string))
+	}
+	if v, found := p.p["entityid"]; found {
+		u.Set("entityid", v.(string))
+	}
+	if v, found := p.p["entitytype"]; found {
+		u.Set("entitytype", v.(string))
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["keyword"]; found {
+		u.Set("keyword", v.(string))
+	}
+	if v, found := p.p["page"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("page", vv)
+	}
+	if v, found := p.p["pagesize"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("pagesize", vv)
+	}
+	if v, found := p.p["userid"]; found {
+		u.Set("userid", v.(string))
+	}
+	return u
+}
+
+func (p *ListAnnotationsParams) SetAnnotationfilter(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["annotationfilter"] = v
+}
+
+func (p *ListAnnotationsParams) GetAnnotationfilter() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["annotationfilter"].(string)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetEntityid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["entityid"] = v
+}
+
+func (p *ListAnnotationsParams) GetEntityid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["entityid"].(string)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetEntitytype(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["entitytype"] = v
+}
+
+func (p *ListAnnotationsParams) GetEntitytype() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["entitytype"].(string)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListAnnotationsParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetKeyword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keyword"] = v
+}
+
+func (p *ListAnnotationsParams) GetKeyword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keyword"].(string)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetPage(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["page"] = v
+}
+
+func (p *ListAnnotationsParams) GetPage() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["page"].(int)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetPagesize(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["pagesize"] = v
+}
+
+func (p *ListAnnotationsParams) GetPagesize() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["pagesize"].(int)
+	return value, ok
+}
+
+func (p *ListAnnotationsParams) SetUserid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["userid"] = v
+}
+
+func (p *ListAnnotationsParams) GetUserid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["userid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new ListAnnotationsParams instance,
+// as then you are sure you have configured all required params
+func (s *AnnotationService) NewListAnnotationsParams() *ListAnnotationsParams {
+	p := &ListAnnotationsParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *AnnotationService) GetAnnotationByID(id string, opts ...OptionFunc) (*Annotation, int, error) {
+	p := &ListAnnotationsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListAnnotations(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.Annotations[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for Annotation UUID: %s!", id)
+}
+
+// Lists annotations.
+func (s *AnnotationService) ListAnnotations(p *ListAnnotationsParams) (*ListAnnotationsResponse, error) {
+	resp, err := s.cs.newRequest("listAnnotations", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ListAnnotationsResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ListAnnotationsResponse struct {
+	Count       int           `json:"count"`
+	Annotations []*Annotation `json:"annotation"`
+}
+
+type Annotation struct {
+	Adminsonly bool   `json:"adminsonly"`
+	Annotation string `json:"annotation"`
+	Created    string `json:"created"`
+	Entityid   string `json:"entityid"`
+	Entityname string `json:"entityname"`
+	Entitytype string `json:"entitytype"`
+	Id         string `json:"id"`
+	JobID      string `json:"jobid"`
+	Jobstatus  int    `json:"jobstatus"`
+	Removed    string `json:"removed"`
+	Userid     string `json:"userid"`
+	Username   string `json:"username"`
+}
+
+type RemoveAnnotationParams struct {
+	p map[string]interface{}
+}
+
+func (p *RemoveAnnotationParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *RemoveAnnotationParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *RemoveAnnotationParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new RemoveAnnotationParams instance,
+// as then you are sure you have configured all required params
+func (s *AnnotationService) NewRemoveAnnotationParams(id string) *RemoveAnnotationParams {
+	p := &RemoveAnnotationParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// remove an annotation.
+func (s *AnnotationService) RemoveAnnotation(p *RemoveAnnotationParams) (*RemoveAnnotationResponse, error) {
+	resp, err := s.cs.newRequest("removeAnnotation", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	if resp, err = getRawValue(resp); err != nil {
+		return nil, err
+	}
+
+	var r RemoveAnnotationResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type RemoveAnnotationResponse struct {
+	Adminsonly bool   `json:"adminsonly"`
+	Annotation string `json:"annotation"`
+	Created    string `json:"created"`
+	Entityid   string `json:"entityid"`
+	Entityname string `json:"entityname"`
+	Entitytype string `json:"entitytype"`
+	Id         string `json:"id"`
+	JobID      string `json:"jobid"`
+	Jobstatus  int    `json:"jobstatus"`
+	Removed    string `json:"removed"`
+	Userid     string `json:"userid"`
+	Username   string `json:"username"`
+}
+
+type UpdateAnnotationVisibilityParams struct {
+	p map[string]interface{}
+}
+
+func (p *UpdateAnnotationVisibilityParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["adminsonly"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("adminsonly", vv)
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *UpdateAnnotationVisibilityParams) SetAdminsonly(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["adminsonly"] = v
+}
+
+func (p *UpdateAnnotationVisibilityParams) GetAdminsonly() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["adminsonly"].(bool)
+	return value, ok
+}
+
+func (p *UpdateAnnotationVisibilityParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *UpdateAnnotationVisibilityParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new UpdateAnnotationVisibilityParams instance,
+// as then you are sure you have configured all required params
+func (s *AnnotationService) NewUpdateAnnotationVisibilityParams(adminsonly bool, id string) *UpdateAnnotationVisibilityParams {
+	p := &UpdateAnnotationVisibilityParams{}
+	p.p = make(map[string]interface{})
+	p.p["adminsonly"] = adminsonly
+	p.p["id"] = id
+	return p
+}
+
+// update an annotation visibility.
+func (s *AnnotationService) UpdateAnnotationVisibility(p *UpdateAnnotationVisibilityParams) (*UpdateAnnotationVisibilityResponse, error) {
+	resp, err := s.cs.newRequest("updateAnnotationVisibility", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r UpdateAnnotationVisibilityResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type UpdateAnnotationVisibilityResponse struct {
+	Adminsonly bool   `json:"adminsonly"`
+	Annotation string `json:"annotation"`
+	Created    string `json:"created"`
+	Entityid   string `json:"entityid"`
+	Entityname string `json:"entityname"`
+	Entitytype string `json:"entitytype"`
+	Id         string `json:"id"`
+	JobID      string `json:"jobid"`
+	Jobstatus  int    `json:"jobstatus"`
+	Removed    string `json:"removed"`
+	Userid     string `json:"userid"`
+	Username   string `json:"username"`
+}
diff --git a/cloudstack/AnnotationService_mock.go b/cloudstack/AnnotationService_mock.go
new file mode 100644
index 0000000..7eaa490
--- /dev/null
+++ b/cloudstack/AnnotationService_mock.go
@@ -0,0 +1,190 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+
+// Code generated by MockGen. DO NOT EDIT.
+// Source: ./cloudstack/AnnotationService.go
+
+// Package cloudstack is a generated GoMock package.
+package cloudstack
+
+import (
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+)
+
+// MockAnnotationServiceIface is a mock of AnnotationServiceIface interface.
+type MockAnnotationServiceIface struct {
+	ctrl     *gomock.Controller
+	recorder *MockAnnotationServiceIfaceMockRecorder
+}
+
+// MockAnnotationServiceIfaceMockRecorder is the mock recorder for MockAnnotationServiceIface.
+type MockAnnotationServiceIfaceMockRecorder struct {
+	mock *MockAnnotationServiceIface
+}
+
+// NewMockAnnotationServiceIface creates a new mock instance.
+func NewMockAnnotationServiceIface(ctrl *gomock.Controller) *MockAnnotationServiceIface {
+	mock := &MockAnnotationServiceIface{ctrl: ctrl}
+	mock.recorder = &MockAnnotationServiceIfaceMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockAnnotationServiceIface) EXPECT() *MockAnnotationServiceIfaceMockRecorder {
+	return m.recorder
+}
+
+// AddAnnotation mocks base method.
+func (m *MockAnnotationServiceIface) AddAnnotation(p *AddAnnotationParams) (*AddAnnotationResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AddAnnotation", p)
+	ret0, _ := ret[0].(*AddAnnotationResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AddAnnotation indicates an expected call of AddAnnotation.
+func (mr *MockAnnotationServiceIfaceMockRecorder) AddAnnotation(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAnnotation", reflect.TypeOf((*MockAnnotationServiceIface)(nil).AddAnnotation), p)
+}
+
+// GetAnnotationByID mocks base method.
+func (m *MockAnnotationServiceIface) GetAnnotationByID(id string, opts ...OptionFunc) (*Annotation, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetAnnotationByID", varargs...)
+	ret0, _ := ret[0].(*Annotation)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetAnnotationByID indicates an expected call of GetAnnotationByID.
+func (mr *MockAnnotationServiceIfaceMockRecorder) GetAnnotationByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAnnotationByID", reflect.TypeOf((*MockAnnotationServiceIface)(nil).GetAnnotationByID), varargs...)
+}
+
+// ListAnnotations mocks base method.
+func (m *MockAnnotationServiceIface) ListAnnotations(p *ListAnnotationsParams) (*ListAnnotationsResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListAnnotations", p)
+	ret0, _ := ret[0].(*ListAnnotationsResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListAnnotations indicates an expected call of ListAnnotations.
+func (mr *MockAnnotationServiceIfaceMockRecorder) ListAnnotations(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAnnotations", reflect.TypeOf((*MockAnnotationServiceIface)(nil).ListAnnotations), p)
+}
+
+// NewAddAnnotationParams mocks base method.
+func (m *MockAnnotationServiceIface) NewAddAnnotationParams() *AddAnnotationParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewAddAnnotationParams")
+	ret0, _ := ret[0].(*AddAnnotationParams)
+	return ret0
+}
+
+// NewAddAnnotationParams indicates an expected call of NewAddAnnotationParams.
+func (mr *MockAnnotationServiceIfaceMockRecorder) NewAddAnnotationParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddAnnotationParams", reflect.TypeOf((*MockAnnotationServiceIface)(nil).NewAddAnnotationParams))
+}
+
+// NewListAnnotationsParams mocks base method.
+func (m *MockAnnotationServiceIface) NewListAnnotationsParams() *ListAnnotationsParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewListAnnotationsParams")
+	ret0, _ := ret[0].(*ListAnnotationsParams)
+	return ret0
+}
+
+// NewListAnnotationsParams indicates an expected call of NewListAnnotationsParams.
+func (mr *MockAnnotationServiceIfaceMockRecorder) NewListAnnotationsParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListAnnotationsParams", reflect.TypeOf((*MockAnnotationServiceIface)(nil).NewListAnnotationsParams))
+}
+
+// NewRemoveAnnotationParams mocks base method.
+func (m *MockAnnotationServiceIface) NewRemoveAnnotationParams(id string) *RemoveAnnotationParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewRemoveAnnotationParams", id)
+	ret0, _ := ret[0].(*RemoveAnnotationParams)
+	return ret0
+}
+
+// NewRemoveAnnotationParams indicates an expected call of NewRemoveAnnotationParams.
+func (mr *MockAnnotationServiceIfaceMockRecorder) NewRemoveAnnotationParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveAnnotationParams", reflect.TypeOf((*MockAnnotationServiceIface)(nil).NewRemoveAnnotationParams), id)
+}
+
+// NewUpdateAnnotationVisibilityParams mocks base method.
+func (m *MockAnnotationServiceIface) NewUpdateAnnotationVisibilityParams(adminsonly bool, id string) *UpdateAnnotationVisibilityParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewUpdateAnnotationVisibilityParams", adminsonly, id)
+	ret0, _ := ret[0].(*UpdateAnnotationVisibilityParams)
+	return ret0
+}
+
+// NewUpdateAnnotationVisibilityParams indicates an expected call of NewUpdateAnnotationVisibilityParams.
+func (mr *MockAnnotationServiceIfaceMockRecorder) NewUpdateAnnotationVisibilityParams(adminsonly, id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateAnnotationVisibilityParams", reflect.TypeOf((*MockAnnotationServiceIface)(nil).NewUpdateAnnotationVisibilityParams), adminsonly, id)
+}
+
+// RemoveAnnotation mocks base method.
+func (m *MockAnnotationServiceIface) RemoveAnnotation(p *RemoveAnnotationParams) (*RemoveAnnotationResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RemoveAnnotation", p)
+	ret0, _ := ret[0].(*RemoveAnnotationResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RemoveAnnotation indicates an expected call of RemoveAnnotation.
+func (mr *MockAnnotationServiceIfaceMockRecorder) RemoveAnnotation(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveAnnotation", reflect.TypeOf((*MockAnnotationServiceIface)(nil).RemoveAnnotation), p)
+}
+
+// UpdateAnnotationVisibility mocks base method.
+func (m *MockAnnotationServiceIface) UpdateAnnotationVisibility(p *UpdateAnnotationVisibilityParams) (*UpdateAnnotationVisibilityResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateAnnotationVisibility", p)
+	ret0, _ := ret[0].(*UpdateAnnotationVisibilityResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateAnnotationVisibility indicates an expected call of UpdateAnnotationVisibility.
+func (mr *MockAnnotationServiceIfaceMockRecorder) UpdateAnnotationVisibility(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAnnotationVisibility", reflect.TypeOf((*MockAnnotationServiceIface)(nil).UpdateAnnotationVisibility), p)
+}
diff --git a/cloudstack/HypervisorService.go b/cloudstack/HypervisorService.go
index e1df253..729480e 100644
--- a/cloudstack/HypervisorService.go
+++ b/cloudstack/HypervisorService.go
@@ -213,6 +213,7 @@ type HypervisorCapability struct {
 	Maxhostspercluster   int    `json:"maxhostspercluster"`
 	Securitygroupenabled bool   `json:"securitygroupenabled"`
 	Storagemotionenabled bool   `json:"storagemotionenabled"`
+	Vmsnapshotenabled    bool   `json:"vmsnapshotenabled"`
 }
 
 type ListHypervisorsParams struct {
@@ -291,14 +292,30 @@ func (p *UpdateHypervisorCapabilitiesParams) toURLValues() url.Values {
 	if v, found := p.p["id"]; found {
 		u.Set("id", v.(string))
 	}
+	if v, found := p.p["maxdatavolumeslimit"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("maxdatavolumeslimit", vv)
+	}
 	if v, found := p.p["maxguestslimit"]; found {
 		vv := strconv.FormatInt(v.(int64), 10)
 		u.Set("maxguestslimit", vv)
 	}
+	if v, found := p.p["maxhostspercluster"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("maxhostspercluster", vv)
+	}
 	if v, found := p.p["securitygroupenabled"]; found {
 		vv := strconv.FormatBool(v.(bool))
 		u.Set("securitygroupenabled", vv)
 	}
+	if v, found := p.p["storagemotionenabled"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("storagemotionenabled", vv)
+	}
+	if v, found := p.p["vmsnapshotenabled"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("vmsnapshotenabled", vv)
+	}
 	return u
 }
 
@@ -317,6 +334,21 @@ func (p *UpdateHypervisorCapabilitiesParams) GetId() (string, bool) {
 	return value, ok
 }
 
+func (p *UpdateHypervisorCapabilitiesParams) SetMaxdatavolumeslimit(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["maxdatavolumeslimit"] = v
+}
+
+func (p *UpdateHypervisorCapabilitiesParams) GetMaxdatavolumeslimit() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["maxdatavolumeslimit"].(int)
+	return value, ok
+}
+
 func (p *UpdateHypervisorCapabilitiesParams) SetMaxguestslimit(v int64) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
@@ -332,6 +364,21 @@ func (p *UpdateHypervisorCapabilitiesParams) GetMaxguestslimit() (int64, bool) {
 	return value, ok
 }
 
+func (p *UpdateHypervisorCapabilitiesParams) SetMaxhostspercluster(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["maxhostspercluster"] = v
+}
+
+func (p *UpdateHypervisorCapabilitiesParams) GetMaxhostspercluster() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["maxhostspercluster"].(int)
+	return value, ok
+}
+
 func (p *UpdateHypervisorCapabilitiesParams) SetSecuritygroupenabled(v bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
@@ -347,6 +394,36 @@ func (p *UpdateHypervisorCapabilitiesParams) GetSecuritygroupenabled() (bool, bo
 	return value, ok
 }
 
+func (p *UpdateHypervisorCapabilitiesParams) SetStoragemotionenabled(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["storagemotionenabled"] = v
+}
+
+func (p *UpdateHypervisorCapabilitiesParams) GetStoragemotionenabled() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["storagemotionenabled"].(bool)
+	return value, ok
+}
+
+func (p *UpdateHypervisorCapabilitiesParams) SetVmsnapshotenabled(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["vmsnapshotenabled"] = v
+}
+
+func (p *UpdateHypervisorCapabilitiesParams) GetVmsnapshotenabled() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["vmsnapshotenabled"].(bool)
+	return value, ok
+}
+
 // You should always use this function to get a new UpdateHypervisorCapabilitiesParams instance,
 // as then you are sure you have configured all required params
 func (s *HypervisorService) NewUpdateHypervisorCapabilitiesParams() *UpdateHypervisorCapabilitiesParams {
@@ -381,4 +458,5 @@ type UpdateHypervisorCapabilitiesResponse struct {
 	Maxhostspercluster   int    `json:"maxhostspercluster"`
 	Securitygroupenabled bool   `json:"securitygroupenabled"`
 	Storagemotionenabled bool   `json:"storagemotionenabled"`
+	Vmsnapshotenabled    bool   `json:"vmsnapshotenabled"`
 }
diff --git a/cloudstack/KubernetesService.go b/cloudstack/KubernetesService.go
new file mode 100644
index 0000000..c01dbff
--- /dev/null
+++ b/cloudstack/KubernetesService.go
@@ -0,0 +1,2152 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+type KubernetesServiceIface interface {
+	AddKubernetesSupportedVersion(p *AddKubernetesSupportedVersionParams) (*AddKubernetesSupportedVersionResponse, error)
+	NewAddKubernetesSupportedVersionParams(mincpunumber int, minmemory int, semanticversion string) *AddKubernetesSupportedVersionParams
+	CreateKubernetesCluster(p *CreateKubernetesClusterParams) (*CreateKubernetesClusterResponse, error)
+	NewCreateKubernetesClusterParams(description string, kubernetesversionid string, name string, serviceofferingid string, size int64, zoneid string) *CreateKubernetesClusterParams
+	DeleteKubernetesCluster(p *DeleteKubernetesClusterParams) (*DeleteKubernetesClusterResponse, error)
+	NewDeleteKubernetesClusterParams(id string) *DeleteKubernetesClusterParams
+	DeleteKubernetesSupportedVersion(p *DeleteKubernetesSupportedVersionParams) (*DeleteKubernetesSupportedVersionResponse, error)
+	NewDeleteKubernetesSupportedVersionParams(id string) *DeleteKubernetesSupportedVersionParams
+	GetKubernetesClusterConfig(p *GetKubernetesClusterConfigParams) (*GetKubernetesClusterConfigResponse, error)
+	NewGetKubernetesClusterConfigParams() *GetKubernetesClusterConfigParams
+	ListKubernetesClusters(p *ListKubernetesClustersParams) (*ListKubernetesClustersResponse, error)
+	NewListKubernetesClustersParams() *ListKubernetesClustersParams
+	GetKubernetesClusterID(name string, opts ...OptionFunc) (string, int, error)
+	GetKubernetesClusterByName(name string, opts ...OptionFunc) (*KubernetesCluster, int, error)
+	GetKubernetesClusterByID(id string, opts ...OptionFunc) (*KubernetesCluster, int, error)
+	ListKubernetesSupportedVersions(p *ListKubernetesSupportedVersionsParams) (*ListKubernetesSupportedVersionsResponse, error)
+	NewListKubernetesSupportedVersionsParams() *ListKubernetesSupportedVersionsParams
+	GetKubernetesSupportedVersionID(keyword string, opts ...OptionFunc) (string, int, error)
+	GetKubernetesSupportedVersionByName(name string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error)
+	GetKubernetesSupportedVersionByID(id string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error)
+	ScaleKubernetesCluster(p *ScaleKubernetesClusterParams) (*ScaleKubernetesClusterResponse, error)
+	NewScaleKubernetesClusterParams(id string) *ScaleKubernetesClusterParams
+	StartKubernetesCluster(p *StartKubernetesClusterParams) (*StartKubernetesClusterResponse, error)
+	NewStartKubernetesClusterParams(id string) *StartKubernetesClusterParams
+	StopKubernetesCluster(p *StopKubernetesClusterParams) (*StopKubernetesClusterResponse, error)
+	NewStopKubernetesClusterParams(id string) *StopKubernetesClusterParams
+	UpdateKubernetesSupportedVersion(p *UpdateKubernetesSupportedVersionParams) (*UpdateKubernetesSupportedVersionResponse, error)
+	NewUpdateKubernetesSupportedVersionParams(id string, state string) *UpdateKubernetesSupportedVersionParams
+	UpgradeKubernetesCluster(p *UpgradeKubernetesClusterParams) (*UpgradeKubernetesClusterResponse, error)
+	NewUpgradeKubernetesClusterParams(id string, kubernetesversionid string) *UpgradeKubernetesClusterParams
+}
+
+type AddKubernetesSupportedVersionParams struct {
+	p map[string]interface{}
+}
+
+func (p *AddKubernetesSupportedVersionParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["checksum"]; found {
+		u.Set("checksum", v.(string))
+	}
+	if v, found := p.p["mincpunumber"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("mincpunumber", vv)
+	}
+	if v, found := p.p["minmemory"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("minmemory", vv)
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["semanticversion"]; found {
+		u.Set("semanticversion", v.(string))
+	}
+	if v, found := p.p["url"]; found {
+		u.Set("url", v.(string))
+	}
+	if v, found := p.p["zoneid"]; found {
+		u.Set("zoneid", v.(string))
+	}
+	return u
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetChecksum(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["checksum"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetChecksum() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["checksum"].(string)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetMincpunumber(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["mincpunumber"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetMincpunumber() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["mincpunumber"].(int)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetMinmemory(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["minmemory"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetMinmemory() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["minmemory"].(int)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetSemanticversion(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["semanticversion"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetSemanticversion() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["semanticversion"].(string)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetUrl(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["url"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetUrl() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["url"].(string)
+	return value, ok
+}
+
+func (p *AddKubernetesSupportedVersionParams) SetZoneid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["zoneid"] = v
+}
+
+func (p *AddKubernetesSupportedVersionParams) GetZoneid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["zoneid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new AddKubernetesSupportedVersionParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewAddKubernetesSupportedVersionParams(mincpunumber int, minmemory int, semanticversion string) *AddKubernetesSupportedVersionParams {
+	p := &AddKubernetesSupportedVersionParams{}
+	p.p = make(map[string]interface{})
+	p.p["mincpunumber"] = mincpunumber
+	p.p["minmemory"] = minmemory
+	p.p["semanticversion"] = semanticversion
+	return p
+}
+
+// Add a supported Kubernetes version
+func (s *KubernetesService) AddKubernetesSupportedVersion(p *AddKubernetesSupportedVersionParams) (*AddKubernetesSupportedVersionResponse, error) {
+	resp, err := s.cs.newRequest("addKubernetesSupportedVersion", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r AddKubernetesSupportedVersionResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type AddKubernetesSupportedVersionResponse struct {
+	Id                  string `json:"id"`
+	Isoid               string `json:"isoid"`
+	Isoname             string `json:"isoname"`
+	Isostate            string `json:"isostate"`
+	JobID               string `json:"jobid"`
+	Jobstatus           int    `json:"jobstatus"`
+	Mincpunumber        int    `json:"mincpunumber"`
+	Minmemory           int    `json:"minmemory"`
+	Name                string `json:"name"`
+	Semanticversion     string `json:"semanticversion"`
+	State               string `json:"state"`
+	Supportsautoscaling bool   `json:"supportsautoscaling"`
+	Supportsha          bool   `json:"supportsha"`
+	Zoneid              string `json:"zoneid"`
+	Zonename            string `json:"zonename"`
+}
+
+type CreateKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *CreateKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["account"]; found {
+		u.Set("account", v.(string))
+	}
+	if v, found := p.p["controlnodes"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("controlnodes", vv)
+	}
+	if v, found := p.p["description"]; found {
+		u.Set("description", v.(string))
+	}
+	if v, found := p.p["dockerregistrypassword"]; found {
+		u.Set("dockerregistrypassword", v.(string))
+	}
+	if v, found := p.p["dockerregistryurl"]; found {
+		u.Set("dockerregistryurl", v.(string))
+	}
+	if v, found := p.p["dockerregistryusername"]; found {
+		u.Set("dockerregistryusername", v.(string))
+	}
+	if v, found := p.p["domainid"]; found {
+		u.Set("domainid", v.(string))
+	}
+	if v, found := p.p["externalloadbalanceripaddress"]; found {
+		u.Set("externalloadbalanceripaddress", v.(string))
+	}
+	if v, found := p.p["keypair"]; found {
+		u.Set("keypair", v.(string))
+	}
+	if v, found := p.p["kubernetesversionid"]; found {
+		u.Set("kubernetesversionid", v.(string))
+	}
+	if v, found := p.p["masternodes"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("masternodes", vv)
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["networkid"]; found {
+		u.Set("networkid", v.(string))
+	}
+	if v, found := p.p["noderootdisksize"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("noderootdisksize", vv)
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["serviceofferingid"]; found {
+		u.Set("serviceofferingid", v.(string))
+	}
+	if v, found := p.p["size"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("size", vv)
+	}
+	if v, found := p.p["zoneid"]; found {
+		u.Set("zoneid", v.(string))
+	}
+	return u
+}
+
+func (p *CreateKubernetesClusterParams) SetAccount(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["account"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetAccount() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["account"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetControlnodes(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["controlnodes"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetControlnodes() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["controlnodes"].(int64)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetDescription(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["description"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetDescription() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["description"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetDockerregistrypassword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["dockerregistrypassword"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetDockerregistrypassword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["dockerregistrypassword"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetDockerregistryurl(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["dockerregistryurl"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetDockerregistryurl() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["dockerregistryurl"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetDockerregistryusername(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["dockerregistryusername"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetDockerregistryusername() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["dockerregistryusername"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetDomainid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["domainid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetDomainid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["domainid"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetExternalloadbalanceripaddress(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["externalloadbalanceripaddress"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetExternalloadbalanceripaddress() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["externalloadbalanceripaddress"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetKeypair(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keypair"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetKeypair() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keypair"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetKubernetesversionid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["kubernetesversionid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetKubernetesversionid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["kubernetesversionid"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetMasternodes(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["masternodes"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetMasternodes() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["masternodes"].(int64)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetNetworkid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["networkid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetNetworkid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["networkid"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetNoderootdisksize(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["noderootdisksize"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetNoderootdisksize() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["noderootdisksize"].(int64)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetServiceofferingid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["serviceofferingid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetServiceofferingid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["serviceofferingid"].(string)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetSize(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["size"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetSize() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["size"].(int64)
+	return value, ok
+}
+
+func (p *CreateKubernetesClusterParams) SetZoneid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["zoneid"] = v
+}
+
+func (p *CreateKubernetesClusterParams) GetZoneid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["zoneid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new CreateKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewCreateKubernetesClusterParams(description string, kubernetesversionid string, name string, serviceofferingid string, size int64, zoneid string) *CreateKubernetesClusterParams {
+	p := &CreateKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["description"] = description
+	p.p["kubernetesversionid"] = kubernetesversionid
+	p.p["name"] = name
+	p.p["serviceofferingid"] = serviceofferingid
+	p.p["size"] = size
+	p.p["zoneid"] = zoneid
+	return p
+}
+
+// Creates a Kubernetes cluster
+func (s *KubernetesService) CreateKubernetesCluster(p *CreateKubernetesClusterParams) (*CreateKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("createKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r CreateKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type CreateKubernetesClusterResponse struct {
+	Account               string            `json:"account"`
+	Associatednetworkname string            `json:"associatednetworkname"`
+	Autoscalingenabled    bool              `json:"autoscalingenabled"`
+	Consoleendpoint       string            `json:"consoleendpoint"`
+	Controlnodes          int64             `json:"controlnodes"`
+	Cpunumber             string            `json:"cpunumber"`
+	Description           string            `json:"description"`
+	Domain                string            `json:"domain"`
+	Domainid              string            `json:"domainid"`
+	Endpoint              string            `json:"endpoint"`
+	Hasannotations        bool              `json:"hasannotations"`
+	Id                    string            `json:"id"`
+	Ipaddress             string            `json:"ipaddress"`
+	Ipaddressid           string            `json:"ipaddressid"`
+	JobID                 string            `json:"jobid"`
+	Jobstatus             int               `json:"jobstatus"`
+	Keypair               string            `json:"keypair"`
+	Kubernetesversionid   string            `json:"kubernetesversionid"`
+	Kubernetesversionname string            `json:"kubernetesversionname"`
+	Masternodes           int64             `json:"masternodes"`
+	Maxsize               int64             `json:"maxsize"`
+	Memory                string            `json:"memory"`
+	Minsize               int64             `json:"minsize"`
+	Name                  string            `json:"name"`
+	Networkid             string            `json:"networkid"`
+	Project               string            `json:"project"`
+	Projectid             string            `json:"projectid"`
+	Serviceofferingid     string            `json:"serviceofferingid"`
+	Serviceofferingname   string            `json:"serviceofferingname"`
+	Size                  int64             `json:"size"`
+	State                 string            `json:"state"`
+	Templateid            string            `json:"templateid"`
+	Virtualmachines       []*VirtualMachine `json:"virtualmachines"`
+	Zoneid                string            `json:"zoneid"`
+	Zonename              string            `json:"zonename"`
+}
+
+type DeleteKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *DeleteKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *DeleteKubernetesClusterParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *DeleteKubernetesClusterParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new DeleteKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewDeleteKubernetesClusterParams(id string) *DeleteKubernetesClusterParams {
+	p := &DeleteKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Deletes a Kubernetes cluster
+func (s *KubernetesService) DeleteKubernetesCluster(p *DeleteKubernetesClusterParams) (*DeleteKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("deleteKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r DeleteKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type DeleteKubernetesClusterResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
+type DeleteKubernetesSupportedVersionParams struct {
+	p map[string]interface{}
+}
+
+func (p *DeleteKubernetesSupportedVersionParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *DeleteKubernetesSupportedVersionParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *DeleteKubernetesSupportedVersionParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new DeleteKubernetesSupportedVersionParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewDeleteKubernetesSupportedVersionParams(id string) *DeleteKubernetesSupportedVersionParams {
+	p := &DeleteKubernetesSupportedVersionParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Deletes a Kubernetes cluster
+func (s *KubernetesService) DeleteKubernetesSupportedVersion(p *DeleteKubernetesSupportedVersionParams) (*DeleteKubernetesSupportedVersionResponse, error) {
+	resp, err := s.cs.newRequest("deleteKubernetesSupportedVersion", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r DeleteKubernetesSupportedVersionResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type DeleteKubernetesSupportedVersionResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
+type GetKubernetesClusterConfigParams struct {
+	p map[string]interface{}
+}
+
+func (p *GetKubernetesClusterConfigParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *GetKubernetesClusterConfigParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *GetKubernetesClusterConfigParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new GetKubernetesClusterConfigParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewGetKubernetesClusterConfigParams() *GetKubernetesClusterConfigParams {
+	p := &GetKubernetesClusterConfigParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// Get Kubernetes cluster config
+func (s *KubernetesService) GetKubernetesClusterConfig(p *GetKubernetesClusterConfigParams) (*GetKubernetesClusterConfigResponse, error) {
+	resp, err := s.cs.newRequest("getKubernetesClusterConfig", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r GetKubernetesClusterConfigResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type GetKubernetesClusterConfigResponse struct {
+	Configdata string `json:"configdata"`
+	Id         string `json:"id"`
+	JobID      string `json:"jobid"`
+	Jobstatus  int    `json:"jobstatus"`
+	Name       string `json:"name"`
+}
+
+type ListKubernetesClustersParams struct {
+	p map[string]interface{}
+}
+
+func (p *ListKubernetesClustersParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["account"]; found {
+		u.Set("account", v.(string))
+	}
+	if v, found := p.p["domainid"]; found {
+		u.Set("domainid", v.(string))
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["isrecursive"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("isrecursive", vv)
+	}
+	if v, found := p.p["keyword"]; found {
+		u.Set("keyword", v.(string))
+	}
+	if v, found := p.p["listall"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("listall", vv)
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["page"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("page", vv)
+	}
+	if v, found := p.p["pagesize"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("pagesize", vv)
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["state"]; found {
+		u.Set("state", v.(string))
+	}
+	return u
+}
+
+func (p *ListKubernetesClustersParams) SetAccount(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["account"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetAccount() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["account"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetDomainid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["domainid"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetDomainid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["domainid"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetIsrecursive(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["isrecursive"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetIsrecursive() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["isrecursive"].(bool)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetKeyword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keyword"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetKeyword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keyword"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetListall(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["listall"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetListall() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["listall"].(bool)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetPage(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["page"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetPage() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["page"].(int)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetPagesize(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["pagesize"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetPagesize() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["pagesize"].(int)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesClustersParams) SetState(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["state"] = v
+}
+
+func (p *ListKubernetesClustersParams) GetState() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["state"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new ListKubernetesClustersParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewListKubernetesClustersParams() *ListKubernetesClustersParams {
+	p := &ListKubernetesClustersParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesClusterID(name string, opts ...OptionFunc) (string, int, error) {
+	p := &ListKubernetesClustersParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["name"] = name
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return "", -1, err
+		}
+	}
+
+	l, err := s.ListKubernetesClusters(p)
+	if err != nil {
+		return "", -1, err
+	}
+
+	if l.Count == 0 {
+		return "", l.Count, fmt.Errorf("No match found for %s: %+v", name, l)
+	}
+
+	if l.Count == 1 {
+		return l.KubernetesClusters[0].Id, l.Count, nil
+	}
+
+	if l.Count > 1 {
+		for _, v := range l.KubernetesClusters {
+			if v.Name == name {
+				return v.Id, l.Count, nil
+			}
+		}
+	}
+	return "", l.Count, fmt.Errorf("Could not find an exact match for %s: %+v", name, l)
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesClusterByName(name string, opts ...OptionFunc) (*KubernetesCluster, int, error) {
+	id, count, err := s.GetKubernetesClusterID(name, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+
+	r, count, err := s.GetKubernetesClusterByID(id, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+	return r, count, nil
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesClusterByID(id string, opts ...OptionFunc) (*KubernetesCluster, int, error) {
+	p := &ListKubernetesClustersParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListKubernetesClusters(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.KubernetesClusters[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for KubernetesCluster UUID: %s!", id)
+}
+
+// Lists Kubernetes clusters
+func (s *KubernetesService) ListKubernetesClusters(p *ListKubernetesClustersParams) (*ListKubernetesClustersResponse, error) {
+	resp, err := s.cs.newRequest("listKubernetesClusters", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ListKubernetesClustersResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ListKubernetesClustersResponse struct {
+	Count              int                  `json:"count"`
+	KubernetesClusters []*KubernetesCluster `json:"kubernetescluster"`
+}
+
+type KubernetesCluster struct {
+	Account               string            `json:"account"`
+	Associatednetworkname string            `json:"associatednetworkname"`
+	Autoscalingenabled    bool              `json:"autoscalingenabled"`
+	Consoleendpoint       string            `json:"consoleendpoint"`
+	Controlnodes          int64             `json:"controlnodes"`
+	Cpunumber             string            `json:"cpunumber"`
+	Description           string            `json:"description"`
+	Domain                string            `json:"domain"`
+	Domainid              string            `json:"domainid"`
+	Endpoint              string            `json:"endpoint"`
+	Hasannotations        bool              `json:"hasannotations"`
+	Id                    string            `json:"id"`
+	Ipaddress             string            `json:"ipaddress"`
+	Ipaddressid           string            `json:"ipaddressid"`
+	JobID                 string            `json:"jobid"`
+	Jobstatus             int               `json:"jobstatus"`
+	Keypair               string            `json:"keypair"`
+	Kubernetesversionid   string            `json:"kubernetesversionid"`
+	Kubernetesversionname string            `json:"kubernetesversionname"`
+	Masternodes           int64             `json:"masternodes"`
+	Maxsize               int64             `json:"maxsize"`
+	Memory                string            `json:"memory"`
+	Minsize               int64             `json:"minsize"`
+	Name                  string            `json:"name"`
+	Networkid             string            `json:"networkid"`
+	Project               string            `json:"project"`
+	Projectid             string            `json:"projectid"`
+	Serviceofferingid     string            `json:"serviceofferingid"`
+	Serviceofferingname   string            `json:"serviceofferingname"`
+	Size                  int64             `json:"size"`
+	State                 string            `json:"state"`
+	Templateid            string            `json:"templateid"`
+	Virtualmachines       []*VirtualMachine `json:"virtualmachines"`
+	Zoneid                string            `json:"zoneid"`
+	Zonename              string            `json:"zonename"`
+}
+
+type ListKubernetesSupportedVersionsParams struct {
+	p map[string]interface{}
+}
+
+func (p *ListKubernetesSupportedVersionsParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["keyword"]; found {
+		u.Set("keyword", v.(string))
+	}
+	if v, found := p.p["minimumkubernetesversionid"]; found {
+		u.Set("minimumkubernetesversionid", v.(string))
+	}
+	if v, found := p.p["minimumsemanticversion"]; found {
+		u.Set("minimumsemanticversion", v.(string))
+	}
+	if v, found := p.p["page"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("page", vv)
+	}
+	if v, found := p.p["pagesize"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("pagesize", vv)
+	}
+	if v, found := p.p["zoneid"]; found {
+		u.Set("zoneid", v.(string))
+	}
+	return u
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetKeyword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keyword"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetKeyword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keyword"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetMinimumkubernetesversionid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["minimumkubernetesversionid"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetMinimumkubernetesversionid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["minimumkubernetesversionid"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetMinimumsemanticversion(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["minimumsemanticversion"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetMinimumsemanticversion() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["minimumsemanticversion"].(string)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetPage(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["page"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetPage() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["page"].(int)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetPagesize(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["pagesize"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetPagesize() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["pagesize"].(int)
+	return value, ok
+}
+
+func (p *ListKubernetesSupportedVersionsParams) SetZoneid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["zoneid"] = v
+}
+
+func (p *ListKubernetesSupportedVersionsParams) GetZoneid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["zoneid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new ListKubernetesSupportedVersionsParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewListKubernetesSupportedVersionsParams() *ListKubernetesSupportedVersionsParams {
+	p := &ListKubernetesSupportedVersionsParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesSupportedVersionID(keyword string, opts ...OptionFunc) (string, int, error) {
+	p := &ListKubernetesSupportedVersionsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["keyword"] = keyword
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return "", -1, err
+		}
+	}
+
+	l, err := s.ListKubernetesSupportedVersions(p)
+	if err != nil {
+		return "", -1, err
+	}
+
+	if l.Count == 0 {
+		return "", l.Count, fmt.Errorf("No match found for %s: %+v", keyword, l)
+	}
+
+	if l.Count == 1 {
+		return l.KubernetesSupportedVersions[0].Id, l.Count, nil
+	}
+
+	if l.Count > 1 {
+		for _, v := range l.KubernetesSupportedVersions {
+			if v.Name == keyword {
+				return v.Id, l.Count, nil
+			}
+		}
+	}
+	return "", l.Count, fmt.Errorf("Could not find an exact match for %s: %+v", keyword, l)
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesSupportedVersionByName(name string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error) {
+	id, count, err := s.GetKubernetesSupportedVersionID(name, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+
+	r, count, err := s.GetKubernetesSupportedVersionByID(id, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+	return r, count, nil
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *KubernetesService) GetKubernetesSupportedVersionByID(id string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error) {
+	p := &ListKubernetesSupportedVersionsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListKubernetesSupportedVersions(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.KubernetesSupportedVersions[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for KubernetesSupportedVersion UUID: %s!", id)
+}
+
+// Lists supported Kubernetes version
+func (s *KubernetesService) ListKubernetesSupportedVersions(p *ListKubernetesSupportedVersionsParams) (*ListKubernetesSupportedVersionsResponse, error) {
+	resp, err := s.cs.newRequest("listKubernetesSupportedVersions", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ListKubernetesSupportedVersionsResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ListKubernetesSupportedVersionsResponse struct {
+	Count                       int                           `json:"count"`
+	KubernetesSupportedVersions []*KubernetesSupportedVersion `json:"kubernetessupportedversion"`
+}
+
+type KubernetesSupportedVersion struct {
+	Id                  string `json:"id"`
+	Isoid               string `json:"isoid"`
+	Isoname             string `json:"isoname"`
+	Isostate            string `json:"isostate"`
+	JobID               string `json:"jobid"`
+	Jobstatus           int    `json:"jobstatus"`
+	Mincpunumber        int    `json:"mincpunumber"`
+	Minmemory           int    `json:"minmemory"`
+	Name                string `json:"name"`
+	Semanticversion     string `json:"semanticversion"`
+	State               string `json:"state"`
+	Supportsautoscaling bool   `json:"supportsautoscaling"`
+	Supportsha          bool   `json:"supportsha"`
+	Zoneid              string `json:"zoneid"`
+	Zonename            string `json:"zonename"`
+}
+
+type ScaleKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *ScaleKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["autoscalingenabled"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("autoscalingenabled", vv)
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["maxsize"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("maxsize", vv)
+	}
+	if v, found := p.p["minsize"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("minsize", vv)
+	}
+	if v, found := p.p["nodeids"]; found {
+		vv := strings.Join(v.([]string), ",")
+		u.Set("nodeids", vv)
+	}
+	if v, found := p.p["serviceofferingid"]; found {
+		u.Set("serviceofferingid", v.(string))
+	}
+	if v, found := p.p["size"]; found {
+		vv := strconv.FormatInt(v.(int64), 10)
+		u.Set("size", vv)
+	}
+	return u
+}
+
+func (p *ScaleKubernetesClusterParams) SetAutoscalingenabled(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["autoscalingenabled"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetAutoscalingenabled() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["autoscalingenabled"].(bool)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetMaxsize(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["maxsize"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetMaxsize() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["maxsize"].(int64)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetMinsize(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["minsize"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetMinsize() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["minsize"].(int64)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetNodeids(v []string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["nodeids"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetNodeids() ([]string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["nodeids"].([]string)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetServiceofferingid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["serviceofferingid"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetServiceofferingid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["serviceofferingid"].(string)
+	return value, ok
+}
+
+func (p *ScaleKubernetesClusterParams) SetSize(v int64) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["size"] = v
+}
+
+func (p *ScaleKubernetesClusterParams) GetSize() (int64, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["size"].(int64)
+	return value, ok
+}
+
+// You should always use this function to get a new ScaleKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewScaleKubernetesClusterParams(id string) *ScaleKubernetesClusterParams {
+	p := &ScaleKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Scales a created, running or stopped Kubernetes cluster
+func (s *KubernetesService) ScaleKubernetesCluster(p *ScaleKubernetesClusterParams) (*ScaleKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("scaleKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ScaleKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type ScaleKubernetesClusterResponse struct {
+	Account               string            `json:"account"`
+	Associatednetworkname string            `json:"associatednetworkname"`
+	Autoscalingenabled    bool              `json:"autoscalingenabled"`
+	Consoleendpoint       string            `json:"consoleendpoint"`
+	Controlnodes          int64             `json:"controlnodes"`
+	Cpunumber             string            `json:"cpunumber"`
+	Description           string            `json:"description"`
+	Domain                string            `json:"domain"`
+	Domainid              string            `json:"domainid"`
+	Endpoint              string            `json:"endpoint"`
+	Hasannotations        bool              `json:"hasannotations"`
+	Id                    string            `json:"id"`
+	Ipaddress             string            `json:"ipaddress"`
+	Ipaddressid           string            `json:"ipaddressid"`
+	JobID                 string            `json:"jobid"`
+	Jobstatus             int               `json:"jobstatus"`
+	Keypair               string            `json:"keypair"`
+	Kubernetesversionid   string            `json:"kubernetesversionid"`
+	Kubernetesversionname string            `json:"kubernetesversionname"`
+	Masternodes           int64             `json:"masternodes"`
+	Maxsize               int64             `json:"maxsize"`
+	Memory                string            `json:"memory"`
+	Minsize               int64             `json:"minsize"`
+	Name                  string            `json:"name"`
+	Networkid             string            `json:"networkid"`
+	Project               string            `json:"project"`
+	Projectid             string            `json:"projectid"`
+	Serviceofferingid     string            `json:"serviceofferingid"`
+	Serviceofferingname   string            `json:"serviceofferingname"`
+	Size                  int64             `json:"size"`
+	State                 string            `json:"state"`
+	Templateid            string            `json:"templateid"`
+	Virtualmachines       []*VirtualMachine `json:"virtualmachines"`
+	Zoneid                string            `json:"zoneid"`
+	Zonename              string            `json:"zonename"`
+}
+
+type StartKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *StartKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *StartKubernetesClusterParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *StartKubernetesClusterParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new StartKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewStartKubernetesClusterParams(id string) *StartKubernetesClusterParams {
+	p := &StartKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Starts a stopped Kubernetes cluster
+func (s *KubernetesService) StartKubernetesCluster(p *StartKubernetesClusterParams) (*StartKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("startKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r StartKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type StartKubernetesClusterResponse struct {
+	Account               string            `json:"account"`
+	Associatednetworkname string            `json:"associatednetworkname"`
+	Autoscalingenabled    bool              `json:"autoscalingenabled"`
+	Consoleendpoint       string            `json:"consoleendpoint"`
+	Controlnodes          int64             `json:"controlnodes"`
+	Cpunumber             string            `json:"cpunumber"`
+	Description           string            `json:"description"`
+	Domain                string            `json:"domain"`
+	Domainid              string            `json:"domainid"`
+	Endpoint              string            `json:"endpoint"`
+	Hasannotations        bool              `json:"hasannotations"`
+	Id                    string            `json:"id"`
+	Ipaddress             string            `json:"ipaddress"`
+	Ipaddressid           string            `json:"ipaddressid"`
+	JobID                 string            `json:"jobid"`
+	Jobstatus             int               `json:"jobstatus"`
+	Keypair               string            `json:"keypair"`
+	Kubernetesversionid   string            `json:"kubernetesversionid"`
+	Kubernetesversionname string            `json:"kubernetesversionname"`
+	Masternodes           int64             `json:"masternodes"`
+	Maxsize               int64             `json:"maxsize"`
+	Memory                string            `json:"memory"`
+	Minsize               int64             `json:"minsize"`
+	Name                  string            `json:"name"`
+	Networkid             string            `json:"networkid"`
+	Project               string            `json:"project"`
+	Projectid             string            `json:"projectid"`
+	Serviceofferingid     string            `json:"serviceofferingid"`
+	Serviceofferingname   string            `json:"serviceofferingname"`
+	Size                  int64             `json:"size"`
+	State                 string            `json:"state"`
+	Templateid            string            `json:"templateid"`
+	Virtualmachines       []*VirtualMachine `json:"virtualmachines"`
+	Zoneid                string            `json:"zoneid"`
+	Zonename              string            `json:"zonename"`
+}
+
+type StopKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *StopKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *StopKubernetesClusterParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *StopKubernetesClusterParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new StopKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewStopKubernetesClusterParams(id string) *StopKubernetesClusterParams {
+	p := &StopKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Stops a running Kubernetes cluster
+func (s *KubernetesService) StopKubernetesCluster(p *StopKubernetesClusterParams) (*StopKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("stopKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r StopKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type StopKubernetesClusterResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
+type UpdateKubernetesSupportedVersionParams struct {
+	p map[string]interface{}
+}
+
+func (p *UpdateKubernetesSupportedVersionParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["state"]; found {
+		u.Set("state", v.(string))
+	}
+	return u
+}
+
+func (p *UpdateKubernetesSupportedVersionParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *UpdateKubernetesSupportedVersionParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *UpdateKubernetesSupportedVersionParams) SetState(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["state"] = v
+}
+
+func (p *UpdateKubernetesSupportedVersionParams) GetState() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["state"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new UpdateKubernetesSupportedVersionParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewUpdateKubernetesSupportedVersionParams(id string, state string) *UpdateKubernetesSupportedVersionParams {
+	p := &UpdateKubernetesSupportedVersionParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	p.p["state"] = state
+	return p
+}
+
+// Update a supported Kubernetes version
+func (s *KubernetesService) UpdateKubernetesSupportedVersion(p *UpdateKubernetesSupportedVersionParams) (*UpdateKubernetesSupportedVersionResponse, error) {
+	resp, err := s.cs.newRequest("updateKubernetesSupportedVersion", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r UpdateKubernetesSupportedVersionResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type UpdateKubernetesSupportedVersionResponse struct {
+	Id                  string `json:"id"`
+	Isoid               string `json:"isoid"`
+	Isoname             string `json:"isoname"`
+	Isostate            string `json:"isostate"`
+	JobID               string `json:"jobid"`
+	Jobstatus           int    `json:"jobstatus"`
+	Mincpunumber        int    `json:"mincpunumber"`
+	Minmemory           int    `json:"minmemory"`
+	Name                string `json:"name"`
+	Semanticversion     string `json:"semanticversion"`
+	State               string `json:"state"`
+	Supportsautoscaling bool   `json:"supportsautoscaling"`
+	Supportsha          bool   `json:"supportsha"`
+	Zoneid              string `json:"zoneid"`
+	Zonename            string `json:"zonename"`
+}
+
+type UpgradeKubernetesClusterParams struct {
+	p map[string]interface{}
+}
+
+func (p *UpgradeKubernetesClusterParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["kubernetesversionid"]; found {
+		u.Set("kubernetesversionid", v.(string))
+	}
+	return u
+}
+
+func (p *UpgradeKubernetesClusterParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *UpgradeKubernetesClusterParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *UpgradeKubernetesClusterParams) SetKubernetesversionid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["kubernetesversionid"] = v
+}
+
+func (p *UpgradeKubernetesClusterParams) GetKubernetesversionid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["kubernetesversionid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new UpgradeKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewUpgradeKubernetesClusterParams(id string, kubernetesversionid string) *UpgradeKubernetesClusterParams {
+	p := &UpgradeKubernetesClusterParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	p.p["kubernetesversionid"] = kubernetesversionid
+	return p
+}
+
+// Upgrades a running Kubernetes cluster
+func (s *KubernetesService) UpgradeKubernetesCluster(p *UpgradeKubernetesClusterParams) (*UpgradeKubernetesClusterResponse, error) {
+	resp, err := s.cs.newRequest("upgradeKubernetesCluster", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r UpgradeKubernetesClusterResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type UpgradeKubernetesClusterResponse struct {
+	Account               string            `json:"account"`
+	Associatednetworkname string            `json:"associatednetworkname"`
+	Autoscalingenabled    bool              `json:"autoscalingenabled"`
+	Consoleendpoint       string            `json:"consoleendpoint"`
+	Controlnodes          int64             `json:"controlnodes"`
+	Cpunumber             string            `json:"cpunumber"`
+	Description           string            `json:"description"`
+	Domain                string            `json:"domain"`
+	Domainid              string            `json:"domainid"`
+	Endpoint              string            `json:"endpoint"`
+	Hasannotations        bool              `json:"hasannotations"`
+	Id                    string            `json:"id"`
+	Ipaddress             string            `json:"ipaddress"`
+	Ipaddressid           string            `json:"ipaddressid"`
+	JobID                 string            `json:"jobid"`
+	Jobstatus             int               `json:"jobstatus"`
+	Keypair               string            `json:"keypair"`
+	Kubernetesversionid   string            `json:"kubernetesversionid"`
+	Kubernetesversionname string            `json:"kubernetesversionname"`
+	Masternodes           int64             `json:"masternodes"`
+	Maxsize               int64             `json:"maxsize"`
+	Memory                string            `json:"memory"`
+	Minsize               int64             `json:"minsize"`
+	Name                  string            `json:"name"`
+	Networkid             string            `json:"networkid"`
+	Project               string            `json:"project"`
+	Projectid             string            `json:"projectid"`
+	Serviceofferingid     string            `json:"serviceofferingid"`
+	Serviceofferingname   string            `json:"serviceofferingname"`
+	Size                  int64             `json:"size"`
+	State                 string            `json:"state"`
+	Templateid            string            `json:"templateid"`
+	Virtualmachines       []*VirtualMachine `json:"virtualmachines"`
+	Zoneid                string            `json:"zoneid"`
+	Zonename              string            `json:"zonename"`
+}
diff --git a/cloudstack/KubernetesService_mock.go b/cloudstack/KubernetesService_mock.go
new file mode 100644
index 0000000..0f6d5a3
--- /dev/null
+++ b/cloudstack/KubernetesService_mock.go
@@ -0,0 +1,527 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+//
+
+// Code generated by MockGen. DO NOT EDIT.
+// Source: ./cloudstack/KubernetesService.go
+
+// Package cloudstack is a generated GoMock package.
+package cloudstack
+
+import (
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+)
+
+// MockKubernetesServiceIface is a mock of KubernetesServiceIface interface.
+type MockKubernetesServiceIface struct {
+	ctrl     *gomock.Controller
+	recorder *MockKubernetesServiceIfaceMockRecorder
+}
+
+// MockKubernetesServiceIfaceMockRecorder is the mock recorder for MockKubernetesServiceIface.
+type MockKubernetesServiceIfaceMockRecorder struct {
+	mock *MockKubernetesServiceIface
+}
+
+// NewMockKubernetesServiceIface creates a new mock instance.
+func NewMockKubernetesServiceIface(ctrl *gomock.Controller) *MockKubernetesServiceIface {
+	mock := &MockKubernetesServiceIface{ctrl: ctrl}
+	mock.recorder = &MockKubernetesServiceIfaceMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockKubernetesServiceIface) EXPECT() *MockKubernetesServiceIfaceMockRecorder {
+	return m.recorder
+}
+
+// AddKubernetesSupportedVersion mocks base method.
+func (m *MockKubernetesServiceIface) AddKubernetesSupportedVersion(p *AddKubernetesSupportedVersionParams) (*AddKubernetesSupportedVersionResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AddKubernetesSupportedVersion", p)
+	ret0, _ := ret[0].(*AddKubernetesSupportedVersionResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AddKubernetesSupportedVersion indicates an expected call of AddKubernetesSupportedVersion.
+func (mr *MockKubernetesServiceIfaceMockRecorder) AddKubernetesSupportedVersion(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddKubernetesSupportedVersion", reflect.TypeOf((*MockKubernetesServiceIface)(nil).AddKubernetesSupportedVersion), p)
+}
+
+// CreateKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) CreateKubernetesCluster(p *CreateKubernetesClusterParams) (*CreateKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateKubernetesCluster", p)
+	ret0, _ := ret[0].(*CreateKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateKubernetesCluster indicates an expected call of CreateKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) CreateKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).CreateKubernetesCluster), p)
+}
+
+// DeleteKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) DeleteKubernetesCluster(p *DeleteKubernetesClusterParams) (*DeleteKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteKubernetesCluster", p)
+	ret0, _ := ret[0].(*DeleteKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteKubernetesCluster indicates an expected call of DeleteKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) DeleteKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).DeleteKubernetesCluster), p)
+}
+
+// DeleteKubernetesSupportedVersion mocks base method.
+func (m *MockKubernetesServiceIface) DeleteKubernetesSupportedVersion(p *DeleteKubernetesSupportedVersionParams) (*DeleteKubernetesSupportedVersionResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteKubernetesSupportedVersion", p)
+	ret0, _ := ret[0].(*DeleteKubernetesSupportedVersionResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteKubernetesSupportedVersion indicates an expected call of DeleteKubernetesSupportedVersion.
+func (mr *MockKubernetesServiceIfaceMockRecorder) DeleteKubernetesSupportedVersion(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteKubernetesSupportedVersion", reflect.TypeOf((*MockKubernetesServiceIface)(nil).DeleteKubernetesSupportedVersion), p)
+}
+
+// GetKubernetesClusterByID mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesClusterByID(id string, opts ...OptionFunc) (*KubernetesCluster, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesClusterByID", varargs...)
+	ret0, _ := ret[0].(*KubernetesCluster)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesClusterByID indicates an expected call of GetKubernetesClusterByID.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesClusterByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesClusterByID", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesClusterByID), varargs...)
+}
+
+// GetKubernetesClusterByName mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesClusterByName(name string, opts ...OptionFunc) (*KubernetesCluster, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesClusterByName", varargs...)
+	ret0, _ := ret[0].(*KubernetesCluster)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesClusterByName indicates an expected call of GetKubernetesClusterByName.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesClusterByName(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesClusterByName", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesClusterByName), varargs...)
+}
+
+// GetKubernetesClusterConfig mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesClusterConfig(p *GetKubernetesClusterConfigParams) (*GetKubernetesClusterConfigResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetKubernetesClusterConfig", p)
+	ret0, _ := ret[0].(*GetKubernetesClusterConfigResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetKubernetesClusterConfig indicates an expected call of GetKubernetesClusterConfig.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesClusterConfig(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesClusterConfig", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesClusterConfig), p)
+}
+
+// GetKubernetesClusterID mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesClusterID(name string, opts ...OptionFunc) (string, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesClusterID", varargs...)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesClusterID indicates an expected call of GetKubernetesClusterID.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesClusterID(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesClusterID", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesClusterID), varargs...)
+}
+
+// GetKubernetesSupportedVersionByID mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesSupportedVersionByID(id string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesSupportedVersionByID", varargs...)
+	ret0, _ := ret[0].(*KubernetesSupportedVersion)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesSupportedVersionByID indicates an expected call of GetKubernetesSupportedVersionByID.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesSupportedVersionByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesSupportedVersionByID", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesSupportedVersionByID), varargs...)
+}
+
+// GetKubernetesSupportedVersionByName mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesSupportedVersionByName(name string, opts ...OptionFunc) (*KubernetesSupportedVersion, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesSupportedVersionByName", varargs...)
+	ret0, _ := ret[0].(*KubernetesSupportedVersion)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesSupportedVersionByName indicates an expected call of GetKubernetesSupportedVersionByName.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesSupportedVersionByName(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesSupportedVersionByName", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesSupportedVersionByName), varargs...)
+}
+
+// GetKubernetesSupportedVersionID mocks base method.
+func (m *MockKubernetesServiceIface) GetKubernetesSupportedVersionID(keyword string, opts ...OptionFunc) (string, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{keyword}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetKubernetesSupportedVersionID", varargs...)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetKubernetesSupportedVersionID indicates an expected call of GetKubernetesSupportedVersionID.
+func (mr *MockKubernetesServiceIfaceMockRecorder) GetKubernetesSupportedVersionID(keyword interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{keyword}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubernetesSupportedVersionID", reflect.TypeOf((*MockKubernetesServiceIface)(nil).GetKubernetesSupportedVersionID), varargs...)
+}
+
+// ListKubernetesClusters mocks base method.
+func (m *MockKubernetesServiceIface) ListKubernetesClusters(p *ListKubernetesClustersParams) (*ListKubernetesClustersResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListKubernetesClusters", p)
+	ret0, _ := ret[0].(*ListKubernetesClustersResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListKubernetesClusters indicates an expected call of ListKubernetesClusters.
+func (mr *MockKubernetesServiceIfaceMockRecorder) ListKubernetesClusters(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListKubernetesClusters", reflect.TypeOf((*MockKubernetesServiceIface)(nil).ListKubernetesClusters), p)
+}
+
+// ListKubernetesSupportedVersions mocks base method.
+func (m *MockKubernetesServiceIface) ListKubernetesSupportedVersions(p *ListKubernetesSupportedVersionsParams) (*ListKubernetesSupportedVersionsResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListKubernetesSupportedVersions", p)
+	ret0, _ := ret[0].(*ListKubernetesSupportedVersionsResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListKubernetesSupportedVersions indicates an expected call of ListKubernetesSupportedVersions.
+func (mr *MockKubernetesServiceIfaceMockRecorder) ListKubernetesSupportedVersions(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListKubernetesSupportedVersions", reflect.TypeOf((*MockKubernetesServiceIface)(nil).ListKubernetesSupportedVersions), p)
+}
+
+// NewAddKubernetesSupportedVersionParams mocks base method.
+func (m *MockKubernetesServiceIface) NewAddKubernetesSupportedVersionParams(mincpunumber, minmemory int, semanticversion string) *AddKubernetesSupportedVersionParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewAddKubernetesSupportedVersionParams", mincpunumber, minmemory, semanticversion)
+	ret0, _ := ret[0].(*AddKubernetesSupportedVersionParams)
+	return ret0
+}
+
+// NewAddKubernetesSupportedVersionParams indicates an expected call of NewAddKubernetesSupportedVersionParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewAddKubernetesSupportedVersionParams(mincpunumber, minmemory, semanticversion interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddKubernetesSupportedVersionParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewAddKubernetesSupportedVersionParams), mincpunumber, minmemory, semanticversion)
+}
+
+// NewCreateKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewCreateKubernetesClusterParams(description, kubernetesversionid, name, serviceofferingid string, size int64, zoneid string) *CreateKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewCreateKubernetesClusterParams", description, kubernetesversionid, name, serviceofferingid, size, zoneid)
+	ret0, _ := ret[0].(*CreateKubernetesClusterParams)
+	return ret0
+}
+
+// NewCreateKubernetesClusterParams indicates an expected call of NewCreateKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewCreateKubernetesClusterParams(description, kubernetesversionid, name, serviceofferingid, size, zoneid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewCreateKubernetesClusterParams), description, kubernetesversionid, name, serviceofferingid, size, zoneid)
+}
+
+// NewDeleteKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewDeleteKubernetesClusterParams(id string) *DeleteKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewDeleteKubernetesClusterParams", id)
+	ret0, _ := ret[0].(*DeleteKubernetesClusterParams)
+	return ret0
+}
+
+// NewDeleteKubernetesClusterParams indicates an expected call of NewDeleteKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewDeleteKubernetesClusterParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewDeleteKubernetesClusterParams), id)
+}
+
+// NewDeleteKubernetesSupportedVersionParams mocks base method.
+func (m *MockKubernetesServiceIface) NewDeleteKubernetesSupportedVersionParams(id string) *DeleteKubernetesSupportedVersionParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewDeleteKubernetesSupportedVersionParams", id)
+	ret0, _ := ret[0].(*DeleteKubernetesSupportedVersionParams)
+	return ret0
+}
+
+// NewDeleteKubernetesSupportedVersionParams indicates an expected call of NewDeleteKubernetesSupportedVersionParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewDeleteKubernetesSupportedVersionParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteKubernetesSupportedVersionParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewDeleteKubernetesSupportedVersionParams), id)
+}
+
+// NewGetKubernetesClusterConfigParams mocks base method.
+func (m *MockKubernetesServiceIface) NewGetKubernetesClusterConfigParams() *GetKubernetesClusterConfigParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewGetKubernetesClusterConfigParams")
+	ret0, _ := ret[0].(*GetKubernetesClusterConfigParams)
+	return ret0
+}
+
+// NewGetKubernetesClusterConfigParams indicates an expected call of NewGetKubernetesClusterConfigParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewGetKubernetesClusterConfigParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewGetKubernetesClusterConfigParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewGetKubernetesClusterConfigParams))
+}
+
+// NewListKubernetesClustersParams mocks base method.
+func (m *MockKubernetesServiceIface) NewListKubernetesClustersParams() *ListKubernetesClustersParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewListKubernetesClustersParams")
+	ret0, _ := ret[0].(*ListKubernetesClustersParams)
+	return ret0
+}
+
+// NewListKubernetesClustersParams indicates an expected call of NewListKubernetesClustersParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewListKubernetesClustersParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListKubernetesClustersParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewListKubernetesClustersParams))
+}
+
+// NewListKubernetesSupportedVersionsParams mocks base method.
+func (m *MockKubernetesServiceIface) NewListKubernetesSupportedVersionsParams() *ListKubernetesSupportedVersionsParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewListKubernetesSupportedVersionsParams")
+	ret0, _ := ret[0].(*ListKubernetesSupportedVersionsParams)
+	return ret0
+}
+
+// NewListKubernetesSupportedVersionsParams indicates an expected call of NewListKubernetesSupportedVersionsParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewListKubernetesSupportedVersionsParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListKubernetesSupportedVersionsParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewListKubernetesSupportedVersionsParams))
+}
+
+// NewScaleKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewScaleKubernetesClusterParams(id string) *ScaleKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewScaleKubernetesClusterParams", id)
+	ret0, _ := ret[0].(*ScaleKubernetesClusterParams)
+	return ret0
+}
+
+// NewScaleKubernetesClusterParams indicates an expected call of NewScaleKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewScaleKubernetesClusterParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewScaleKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewScaleKubernetesClusterParams), id)
+}
+
+// NewStartKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewStartKubernetesClusterParams(id string) *StartKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewStartKubernetesClusterParams", id)
+	ret0, _ := ret[0].(*StartKubernetesClusterParams)
+	return ret0
+}
+
+// NewStartKubernetesClusterParams indicates an expected call of NewStartKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewStartKubernetesClusterParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStartKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewStartKubernetesClusterParams), id)
+}
+
+// NewStopKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewStopKubernetesClusterParams(id string) *StopKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewStopKubernetesClusterParams", id)
+	ret0, _ := ret[0].(*StopKubernetesClusterParams)
+	return ret0
+}
+
+// NewStopKubernetesClusterParams indicates an expected call of NewStopKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewStopKubernetesClusterParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStopKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewStopKubernetesClusterParams), id)
+}
+
+// NewUpdateKubernetesSupportedVersionParams mocks base method.
+func (m *MockKubernetesServiceIface) NewUpdateKubernetesSupportedVersionParams(id, state string) *UpdateKubernetesSupportedVersionParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewUpdateKubernetesSupportedVersionParams", id, state)
+	ret0, _ := ret[0].(*UpdateKubernetesSupportedVersionParams)
+	return ret0
+}
+
+// NewUpdateKubernetesSupportedVersionParams indicates an expected call of NewUpdateKubernetesSupportedVersionParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewUpdateKubernetesSupportedVersionParams(id, state interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateKubernetesSupportedVersionParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewUpdateKubernetesSupportedVersionParams), id, state)
+}
+
+// NewUpgradeKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewUpgradeKubernetesClusterParams(id, kubernetesversionid string) *UpgradeKubernetesClusterParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewUpgradeKubernetesClusterParams", id, kubernetesversionid)
+	ret0, _ := ret[0].(*UpgradeKubernetesClusterParams)
+	return ret0
+}
+
+// NewUpgradeKubernetesClusterParams indicates an expected call of NewUpgradeKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) NewUpgradeKubernetesClusterParams(id, kubernetesversionid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpgradeKubernetesClusterParams", reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewUpgradeKubernetesClusterParams), id, kubernetesversionid)
+}
+
+// ScaleKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) ScaleKubernetesCluster(p *ScaleKubernetesClusterParams) (*ScaleKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ScaleKubernetesCluster", p)
+	ret0, _ := ret[0].(*ScaleKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ScaleKubernetesCluster indicates an expected call of ScaleKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) ScaleKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScaleKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).ScaleKubernetesCluster), p)
+}
+
+// StartKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) StartKubernetesCluster(p *StartKubernetesClusterParams) (*StartKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StartKubernetesCluster", p)
+	ret0, _ := ret[0].(*StartKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartKubernetesCluster indicates an expected call of StartKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) StartKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).StartKubernetesCluster), p)
+}
+
+// StopKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) StopKubernetesCluster(p *StopKubernetesClusterParams) (*StopKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StopKubernetesCluster", p)
+	ret0, _ := ret[0].(*StopKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StopKubernetesCluster indicates an expected call of StopKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) StopKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).StopKubernetesCluster), p)
+}
+
+// UpdateKubernetesSupportedVersion mocks base method.
+func (m *MockKubernetesServiceIface) UpdateKubernetesSupportedVersion(p *UpdateKubernetesSupportedVersionParams) (*UpdateKubernetesSupportedVersionResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateKubernetesSupportedVersion", p)
+	ret0, _ := ret[0].(*UpdateKubernetesSupportedVersionResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateKubernetesSupportedVersion indicates an expected call of UpdateKubernetesSupportedVersion.
+func (mr *MockKubernetesServiceIfaceMockRecorder) UpdateKubernetesSupportedVersion(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateKubernetesSupportedVersion", reflect.TypeOf((*MockKubernetesServiceIface)(nil).UpdateKubernetesSupportedVersion), p)
+}
+
+// UpgradeKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) UpgradeKubernetesCluster(p *UpgradeKubernetesClusterParams) (*UpgradeKubernetesClusterResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpgradeKubernetesCluster", p)
+	ret0, _ := ret[0].(*UpgradeKubernetesClusterResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpgradeKubernetesCluster indicates an expected call of UpgradeKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) UpgradeKubernetesCluster(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpgradeKubernetesCluster", reflect.TypeOf((*MockKubernetesServiceIface)(nil).UpgradeKubernetesCluster), p)
+}
diff --git a/cloudstack/LoadBalancerService.go b/cloudstack/LoadBalancerService.go
index 2f0f9d8..3d25513 100644
--- a/cloudstack/LoadBalancerService.go
+++ b/cloudstack/LoadBalancerService.go
@@ -1752,7 +1752,7 @@ func (s *LoadBalancerService) NewCreateLoadBalancerParams(algorithm string, inst
 	return p
 }
 
-// Creates a load balancer
+// Creates an internal load balancer
 func (s *LoadBalancerService) CreateLoadBalancer(p *CreateLoadBalancerParams) (*CreateLoadBalancerResponse, error) {
 	resp, err := s.cs.newRequest("createLoadBalancer", p.toURLValues())
 	if err != nil {
@@ -2430,7 +2430,7 @@ func (s *LoadBalancerService) NewDeleteLoadBalancerParams(id string) *DeleteLoad
 	return p
 }
 
-// Deletes a load balancer
+// Deletes an internal load balancer
 func (s *LoadBalancerService) DeleteLoadBalancer(p *DeleteLoadBalancerParams) (*DeleteLoadBalancerResponse, error) {
 	resp, err := s.cs.newRequest("deleteLoadBalancer", p.toURLValues())
 	if err != nil {
@@ -4535,7 +4535,7 @@ func (s *LoadBalancerService) GetLoadBalancerByID(id string, opts ...OptionFunc)
 	return nil, l.Count, fmt.Errorf("There is more then one result for LoadBalancer UUID: %s!", id)
 }
 
-// Lists load balancers
+// Lists internal load balancers
 func (s *LoadBalancerService) ListLoadBalancers(p *ListLoadBalancersParams) (*ListLoadBalancersResponse, error) {
 	resp, err := s.cs.newRequest("listLoadBalancers", p.toURLValues())
 	if err != nil {
@@ -5674,7 +5674,7 @@ func (s *LoadBalancerService) NewUpdateLoadBalancerParams(id string) *UpdateLoad
 	return p
 }
 
-// Updates a load balancer
+// Updates an internal load balancer
 func (s *LoadBalancerService) UpdateLoadBalancer(p *UpdateLoadBalancerParams) (*UpdateLoadBalancerResponse, error) {
 	resp, err := s.cs.newRequest("updateLoadBalancer", p.toURLValues())
 	if err != nil {
diff --git a/cloudstack/PoolService.go b/cloudstack/PoolService.go
index 09cecee..e0d2959 100644
--- a/cloudstack/PoolService.go
+++ b/cloudstack/PoolService.go
@@ -39,6 +39,8 @@ type PoolServiceIface interface {
 	GetStoragePoolID(name string, opts ...OptionFunc) (string, int, error)
 	GetStoragePoolByName(name string, opts ...OptionFunc) (*StoragePool, int, error)
 	GetStoragePoolByID(id string, opts ...OptionFunc) (*StoragePool, int, error)
+	SyncStoragePool(p *SyncStoragePoolParams) (*SyncStoragePoolResponse, error)
+	NewSyncStoragePoolParams(id string) *SyncStoragePoolParams
 	UpdateStoragePool(p *UpdateStoragePoolParams) (*UpdateStoragePoolResponse, error)
 	NewUpdateStoragePoolParams(id string) *UpdateStoragePoolParams
 }
@@ -958,6 +960,111 @@ type StoragePool struct {
 	Zonename             string            `json:"zonename"`
 }
 
+type SyncStoragePoolParams struct {
+	p map[string]interface{}
+}
+
+func (p *SyncStoragePoolParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *SyncStoragePoolParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *SyncStoragePoolParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new SyncStoragePoolParams instance,
+// as then you are sure you have configured all required params
+func (s *PoolService) NewSyncStoragePoolParams(id string) *SyncStoragePoolParams {
+	p := &SyncStoragePoolParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Sync storage pool with management server (currently supported for Datastore Cluster in VMware and syncs the datastores in it)
+func (s *PoolService) SyncStoragePool(p *SyncStoragePoolParams) (*SyncStoragePoolResponse, error) {
+	resp, err := s.cs.newRequest("syncStoragePool", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r SyncStoragePoolResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type SyncStoragePoolResponse struct {
+	Allocatediops        int64             `json:"allocatediops"`
+	Capacityiops         int64             `json:"capacityiops"`
+	Clusterid            string            `json:"clusterid"`
+	Clustername          string            `json:"clustername"`
+	Created              string            `json:"created"`
+	Disksizeallocated    int64             `json:"disksizeallocated"`
+	Disksizetotal        int64             `json:"disksizetotal"`
+	Disksizeused         int64             `json:"disksizeused"`
+	Hasannotations       bool              `json:"hasannotations"`
+	Hypervisor           string            `json:"hypervisor"`
+	Id                   string            `json:"id"`
+	Ipaddress            string            `json:"ipaddress"`
+	JobID                string            `json:"jobid"`
+	Jobstatus            int               `json:"jobstatus"`
+	Name                 string            `json:"name"`
+	Overprovisionfactor  string            `json:"overprovisionfactor"`
+	Path                 string            `json:"path"`
+	Podid                string            `json:"podid"`
+	Podname              string            `json:"podname"`
+	Provider             string            `json:"provider"`
+	Scope                string            `json:"scope"`
+	State                string            `json:"state"`
+	Storagecapabilities  map[string]string `json:"storagecapabilities"`
+	Suitableformigration bool              `json:"suitableformigration"`
+	Tags                 string            `json:"tags"`
+	Type                 string            `json:"type"`
+	Zoneid               string            `json:"zoneid"`
+	Zonename             string            `json:"zonename"`
+}
+
 type UpdateStoragePoolParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/PoolService_mock.go b/cloudstack/PoolService_mock.go
index 420f83c..a01e7b0 100644
--- a/cloudstack/PoolService_mock.go
+++ b/cloudstack/PoolService_mock.go
@@ -231,6 +231,20 @@ func (mr *MockPoolServiceIfaceMockRecorder) NewListStoragePoolsParams() *gomock.
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListStoragePoolsParams", reflect.TypeOf((*MockPoolServiceIface)(nil).NewListStoragePoolsParams))
 }
 
+// NewSyncStoragePoolParams mocks base method.
+func (m *MockPoolServiceIface) NewSyncStoragePoolParams(id string) *SyncStoragePoolParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewSyncStoragePoolParams", id)
+	ret0, _ := ret[0].(*SyncStoragePoolParams)
+	return ret0
+}
+
+// NewSyncStoragePoolParams indicates an expected call of NewSyncStoragePoolParams.
+func (mr *MockPoolServiceIfaceMockRecorder) NewSyncStoragePoolParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewSyncStoragePoolParams", reflect.TypeOf((*MockPoolServiceIface)(nil).NewSyncStoragePoolParams), id)
+}
+
 // NewUpdateStoragePoolParams mocks base method.
 func (m *MockPoolServiceIface) NewUpdateStoragePoolParams(id string) *UpdateStoragePoolParams {
 	m.ctrl.T.Helper()
@@ -245,6 +259,21 @@ func (mr *MockPoolServiceIfaceMockRecorder) NewUpdateStoragePoolParams(id interf
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateStoragePoolParams", reflect.TypeOf((*MockPoolServiceIface)(nil).NewUpdateStoragePoolParams), id)
 }
 
+// SyncStoragePool mocks base method.
+func (m *MockPoolServiceIface) SyncStoragePool(p *SyncStoragePoolParams) (*SyncStoragePoolResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SyncStoragePool", p)
+	ret0, _ := ret[0].(*SyncStoragePoolResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SyncStoragePool indicates an expected call of SyncStoragePool.
+func (mr *MockPoolServiceIfaceMockRecorder) SyncStoragePool(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyncStoragePool", reflect.TypeOf((*MockPoolServiceIface)(nil).SyncStoragePool), p)
+}
+
 // UpdateStoragePool mocks base method.
 func (m *MockPoolServiceIface) UpdateStoragePool(p *UpdateStoragePoolParams) (*UpdateStoragePoolResponse, error) {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/ProjectService.go b/cloudstack/ProjectService.go
index d08a88f..3c06582 100644
--- a/cloudstack/ProjectService.go
+++ b/cloudstack/ProjectService.go
@@ -30,8 +30,16 @@ import (
 type ProjectServiceIface interface {
 	ActivateProject(p *ActivateProjectParams) (*ActivateProjectResponse, error)
 	NewActivateProjectParams(id string) *ActivateProjectParams
+	AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error)
+	NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams
+	AddUserToProject(p *AddUserToProjectParams) (*AddUserToProjectResponse, error)
+	NewAddUserToProjectParams(projectid string, username string) *AddUserToProjectParams
 	CreateProject(p *CreateProjectParams) (*CreateProjectResponse, error)
 	NewCreateProjectParams(displaytext string, name string) *CreateProjectParams
+	DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error)
+	NewDeleteAccountFromProjectParams(account string, projectid string) *DeleteAccountFromProjectParams
+	DeleteUserFromProject(p *DeleteUserFromProjectParams) (*DeleteUserFromProjectResponse, error)
+	NewDeleteUserFromProjectParams(projectid string, userid string) *DeleteUserFromProjectParams
 	DeleteProject(p *DeleteProjectParams) (*DeleteProjectResponse, error)
 	NewDeleteProjectParams(id string) *DeleteProjectParams
 	DeleteProjectInvitation(p *DeleteProjectInvitationParams) (*DeleteProjectInvitationResponse, error)
@@ -185,6 +193,303 @@ type ActivateProjectResponse struct {
 	Vpctotal                  int64               `json:"vpctotal"`
 }
 
+type AddAccountToProjectParams struct {
+	p map[string]interface{}
+}
+
+func (p *AddAccountToProjectParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["account"]; found {
+		u.Set("account", v.(string))
+	}
+	if v, found := p.p["email"]; found {
+		u.Set("email", v.(string))
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["projectroleid"]; found {
+		u.Set("projectroleid", v.(string))
+	}
+	if v, found := p.p["roletype"]; found {
+		u.Set("roletype", v.(string))
+	}
+	return u
+}
+
+func (p *AddAccountToProjectParams) SetAccount(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["account"] = v
+}
+
+func (p *AddAccountToProjectParams) GetAccount() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["account"].(string)
+	return value, ok
+}
+
+func (p *AddAccountToProjectParams) SetEmail(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["email"] = v
+}
+
+func (p *AddAccountToProjectParams) GetEmail() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["email"].(string)
+	return value, ok
+}
+
+func (p *AddAccountToProjectParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *AddAccountToProjectParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *AddAccountToProjectParams) SetProjectroleid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectroleid"] = v
+}
+
+func (p *AddAccountToProjectParams) GetProjectroleid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectroleid"].(string)
+	return value, ok
+}
+
+func (p *AddAccountToProjectParams) SetRoletype(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["roletype"] = v
+}
+
+func (p *AddAccountToProjectParams) GetRoletype() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["roletype"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new AddAccountToProjectParams instance,
+// as then you are sure you have configured all required params
+func (s *ProjectService) NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams {
+	p := &AddAccountToProjectParams{}
+	p.p = make(map[string]interface{})
+	p.p["projectid"] = projectid
+	return p
+}
+
+// Adds account to a project
+func (s *ProjectService) AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error) {
+	resp, err := s.cs.newRequest("addAccountToProject", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r AddAccountToProjectResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type AddAccountToProjectResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
+type AddUserToProjectParams struct {
+	p map[string]interface{}
+}
+
+func (p *AddUserToProjectParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["email"]; found {
+		u.Set("email", v.(string))
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["projectroleid"]; found {
+		u.Set("projectroleid", v.(string))
+	}
+	if v, found := p.p["roletype"]; found {
+		u.Set("roletype", v.(string))
+	}
+	if v, found := p.p["username"]; found {
+		u.Set("username", v.(string))
+	}
+	return u
+}
+
+func (p *AddUserToProjectParams) SetEmail(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["email"] = v
+}
+
+func (p *AddUserToProjectParams) GetEmail() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["email"].(string)
+	return value, ok
+}
+
+func (p *AddUserToProjectParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *AddUserToProjectParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *AddUserToProjectParams) SetProjectroleid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectroleid"] = v
+}
+
+func (p *AddUserToProjectParams) GetProjectroleid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectroleid"].(string)
+	return value, ok
+}
+
+func (p *AddUserToProjectParams) SetRoletype(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["roletype"] = v
+}
+
+func (p *AddUserToProjectParams) GetRoletype() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["roletype"].(string)
+	return value, ok
+}
+
+func (p *AddUserToProjectParams) SetUsername(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["username"] = v
+}
+
+func (p *AddUserToProjectParams) GetUsername() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["username"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new AddUserToProjectParams instance,
+// as then you are sure you have configured all required params
+func (s *ProjectService) NewAddUserToProjectParams(projectid string, username string) *AddUserToProjectParams {
+	p := &AddUserToProjectParams{}
+	p.p = make(map[string]interface{})
+	p.p["projectid"] = projectid
+	p.p["username"] = username
+	return p
+}
+
+// Adds user to a project
+func (s *ProjectService) AddUserToProject(p *AddUserToProjectParams) (*AddUserToProjectResponse, error) {
+	resp, err := s.cs.newRequest("addUserToProject", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r AddUserToProjectResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type AddUserToProjectResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
 type CreateProjectParams struct {
 	p map[string]interface{}
 }
@@ -401,6 +706,196 @@ type CreateProjectResponse struct {
 	Vpctotal                  int64               `json:"vpctotal"`
 }
 
+type DeleteAccountFromProjectParams struct {
+	p map[string]interface{}
+}
+
+func (p *DeleteAccountFromProjectParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["account"]; found {
+		u.Set("account", v.(string))
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	return u
+}
+
+func (p *DeleteAccountFromProjectParams) SetAccount(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["account"] = v
+}
+
+func (p *DeleteAccountFromProjectParams) GetAccount() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["account"].(string)
+	return value, ok
+}
+
+func (p *DeleteAccountFromProjectParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *DeleteAccountFromProjectParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new DeleteAccountFromProjectParams instance,
+// as then you are sure you have configured all required params
+func (s *ProjectService) NewDeleteAccountFromProjectParams(account string, projectid string) *DeleteAccountFromProjectParams {
+	p := &DeleteAccountFromProjectParams{}
+	p.p = make(map[string]interface{})
+	p.p["account"] = account
+	p.p["projectid"] = projectid
+	return p
+}
+
+// Deletes account from the project
+func (s *ProjectService) DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error) {
+	resp, err := s.cs.newRequest("deleteAccountFromProject", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r DeleteAccountFromProjectResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type DeleteAccountFromProjectResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
+type DeleteUserFromProjectParams struct {
+	p map[string]interface{}
+}
+
+func (p *DeleteUserFromProjectParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["userid"]; found {
+		u.Set("userid", v.(string))
+	}
+	return u
+}
+
+func (p *DeleteUserFromProjectParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *DeleteUserFromProjectParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *DeleteUserFromProjectParams) SetUserid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["userid"] = v
+}
+
+func (p *DeleteUserFromProjectParams) GetUserid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["userid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new DeleteUserFromProjectParams instance,
+// as then you are sure you have configured all required params
+func (s *ProjectService) NewDeleteUserFromProjectParams(projectid string, userid string) *DeleteUserFromProjectParams {
+	p := &DeleteUserFromProjectParams{}
+	p.p = make(map[string]interface{})
+	p.p["projectid"] = projectid
+	p.p["userid"] = userid
+	return p
+}
+
+// Deletes user from the project
+func (s *ProjectService) DeleteUserFromProject(p *DeleteUserFromProjectParams) (*DeleteUserFromProjectResponse, error) {
+	resp, err := s.cs.newRequest("deleteUserFromProject", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r DeleteUserFromProjectResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type DeleteUserFromProjectResponse struct {
+	Displaytext string `json:"displaytext"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Success     bool   `json:"success"`
+}
+
 type DeleteProjectParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/ProjectService_mock.go b/cloudstack/ProjectService_mock.go
index d511fac..a2481e0 100644
--- a/cloudstack/ProjectService_mock.go
+++ b/cloudstack/ProjectService_mock.go
@@ -67,6 +67,36 @@ func (mr *MockProjectServiceIfaceMockRecorder) ActivateProject(p interface{}) *g
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateProject", reflect.TypeOf((*MockProjectServiceIface)(nil).ActivateProject), p)
 }
 
+// AddAccountToProject mocks base method.
+func (m *MockProjectServiceIface) AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AddAccountToProject", p)
+	ret0, _ := ret[0].(*AddAccountToProjectResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AddAccountToProject indicates an expected call of AddAccountToProject.
+func (mr *MockProjectServiceIfaceMockRecorder) AddAccountToProject(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAccountToProject", reflect.TypeOf((*MockProjectServiceIface)(nil).AddAccountToProject), p)
+}
+
+// AddUserToProject mocks base method.
+func (m *MockProjectServiceIface) AddUserToProject(p *AddUserToProjectParams) (*AddUserToProjectResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AddUserToProject", p)
+	ret0, _ := ret[0].(*AddUserToProjectResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AddUserToProject indicates an expected call of AddUserToProject.
+func (mr *MockProjectServiceIfaceMockRecorder) AddUserToProject(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUserToProject", reflect.TypeOf((*MockProjectServiceIface)(nil).AddUserToProject), p)
+}
+
 // CreateProject mocks base method.
 func (m *MockProjectServiceIface) CreateProject(p *CreateProjectParams) (*CreateProjectResponse, error) {
 	m.ctrl.T.Helper()
@@ -97,6 +127,21 @@ func (mr *MockProjectServiceIfaceMockRecorder) CreateProjectRolePermission(p int
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateProjectRolePermission", reflect.TypeOf((*MockProjectServiceIface)(nil).CreateProjectRolePermission), p)
 }
 
+// DeleteAccountFromProject mocks base method.
+func (m *MockProjectServiceIface) DeleteAccountFromProject(p *DeleteAccountFromProjectParams) (*DeleteAccountFromProjectResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteAccountFromProject", p)
+	ret0, _ := ret[0].(*DeleteAccountFromProjectResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteAccountFromProject indicates an expected call of DeleteAccountFromProject.
+func (mr *MockProjectServiceIfaceMockRecorder) DeleteAccountFromProject(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccountFromProject", reflect.TypeOf((*MockProjectServiceIface)(nil).DeleteAccountFromProject), p)
+}
+
 // DeleteProject mocks base method.
 func (m *MockProjectServiceIface) DeleteProject(p *DeleteProjectParams) (*DeleteProjectResponse, error) {
 	m.ctrl.T.Helper()
@@ -142,6 +187,21 @@ func (mr *MockProjectServiceIfaceMockRecorder) DeleteProjectRolePermission(p int
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteProjectRolePermission", reflect.TypeOf((*MockProjectServiceIface)(nil).DeleteProjectRolePermission), p)
 }
 
+// DeleteUserFromProject mocks base method.
+func (m *MockProjectServiceIface) DeleteUserFromProject(p *DeleteUserFromProjectParams) (*DeleteUserFromProjectResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteUserFromProject", p)
+	ret0, _ := ret[0].(*DeleteUserFromProjectResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteUserFromProject indicates an expected call of DeleteUserFromProject.
+func (mr *MockProjectServiceIfaceMockRecorder) DeleteUserFromProject(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUserFromProject", reflect.TypeOf((*MockProjectServiceIface)(nil).DeleteUserFromProject), p)
+}
+
 // GetProjectByID mocks base method.
 func (m *MockProjectServiceIface) GetProjectByID(id string, opts ...OptionFunc) (*Project, int, error) {
 	m.ctrl.T.Helper()
@@ -285,6 +345,34 @@ func (mr *MockProjectServiceIfaceMockRecorder) NewActivateProjectParams(id inter
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewActivateProjectParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewActivateProjectParams), id)
 }
 
+// NewAddAccountToProjectParams mocks base method.
+func (m *MockProjectServiceIface) NewAddAccountToProjectParams(projectid string) *AddAccountToProjectParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewAddAccountToProjectParams", projectid)
+	ret0, _ := ret[0].(*AddAccountToProjectParams)
+	return ret0
+}
+
+// NewAddAccountToProjectParams indicates an expected call of NewAddAccountToProjectParams.
+func (mr *MockProjectServiceIfaceMockRecorder) NewAddAccountToProjectParams(projectid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddAccountToProjectParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewAddAccountToProjectParams), projectid)
+}
+
+// NewAddUserToProjectParams mocks base method.
+func (m *MockProjectServiceIface) NewAddUserToProjectParams(projectid, username string) *AddUserToProjectParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewAddUserToProjectParams", projectid, username)
+	ret0, _ := ret[0].(*AddUserToProjectParams)
+	return ret0
+}
+
+// NewAddUserToProjectParams indicates an expected call of NewAddUserToProjectParams.
+func (mr *MockProjectServiceIfaceMockRecorder) NewAddUserToProjectParams(projectid, username interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddUserToProjectParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewAddUserToProjectParams), projectid, username)
+}
+
 // NewCreateProjectParams mocks base method.
 func (m *MockProjectServiceIface) NewCreateProjectParams(displaytext, name string) *CreateProjectParams {
 	m.ctrl.T.Helper()
@@ -313,6 +401,20 @@ func (mr *MockProjectServiceIfaceMockRecorder) NewCreateProjectRolePermissionPar
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateProjectRolePermissionParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewCreateProjectRolePermissionParams), permission, projectid, projectroleid, rule)
 }
 
+// NewDeleteAccountFromProjectParams mocks base method.
+func (m *MockProjectServiceIface) NewDeleteAccountFromProjectParams(account, projectid string) *DeleteAccountFromProjectParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewDeleteAccountFromProjectParams", account, projectid)
+	ret0, _ := ret[0].(*DeleteAccountFromProjectParams)
+	return ret0
+}
+
+// NewDeleteAccountFromProjectParams indicates an expected call of NewDeleteAccountFromProjectParams.
+func (mr *MockProjectServiceIfaceMockRecorder) NewDeleteAccountFromProjectParams(account, projectid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteAccountFromProjectParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewDeleteAccountFromProjectParams), account, projectid)
+}
+
 // NewDeleteProjectInvitationParams mocks base method.
 func (m *MockProjectServiceIface) NewDeleteProjectInvitationParams(id string) *DeleteProjectInvitationParams {
 	m.ctrl.T.Helper()
@@ -355,6 +457,20 @@ func (mr *MockProjectServiceIfaceMockRecorder) NewDeleteProjectRolePermissionPar
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteProjectRolePermissionParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewDeleteProjectRolePermissionParams), id, projectid)
 }
 
+// NewDeleteUserFromProjectParams mocks base method.
+func (m *MockProjectServiceIface) NewDeleteUserFromProjectParams(projectid, userid string) *DeleteUserFromProjectParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewDeleteUserFromProjectParams", projectid, userid)
+	ret0, _ := ret[0].(*DeleteUserFromProjectParams)
+	return ret0
+}
+
+// NewDeleteUserFromProjectParams indicates an expected call of NewDeleteUserFromProjectParams.
+func (mr *MockProjectServiceIfaceMockRecorder) NewDeleteUserFromProjectParams(projectid, userid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteUserFromProjectParams", reflect.TypeOf((*MockProjectServiceIface)(nil).NewDeleteUserFromProjectParams), projectid, userid)
+}
+
 // NewListProjectInvitationsParams mocks base method.
 func (m *MockProjectServiceIface) NewListProjectInvitationsParams() *ListProjectInvitationsParams {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/RoleService.go b/cloudstack/RoleService.go
index bb07f3e..e50a620 100644
--- a/cloudstack/RoleService.go
+++ b/cloudstack/RoleService.go
@@ -36,6 +36,8 @@ type RoleServiceIface interface {
 	NewDeleteRoleParams(id string) *DeleteRoleParams
 	DeleteRolePermission(p *DeleteRolePermissionParams) (*DeleteRolePermissionResponse, error)
 	NewDeleteRolePermissionParams(id string) *DeleteRolePermissionParams
+	ImportRole(p *ImportRoleParams) (*ImportRoleResponse, error)
+	NewImportRoleParams(name string, rules map[string]string) *ImportRoleParams
 	ListRolePermissions(p *ListRolePermissionsParams) (*ListRolePermissionsResponse, error)
 	NewListRolePermissionsParams() *ListRolePermissionsParams
 	ListRoles(p *ListRolesParams) (*ListRolesResponse, error)
@@ -464,6 +466,148 @@ func (r *DeleteRolePermissionResponse) UnmarshalJSON(b []byte) error {
 	return json.Unmarshal(b, (*alias)(r))
 }
 
+type ImportRoleParams struct {
+	p map[string]interface{}
+}
+
+func (p *ImportRoleParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["description"]; found {
+		u.Set("description", v.(string))
+	}
+	if v, found := p.p["forced"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("forced", vv)
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["rules"]; found {
+		m := v.(map[string]string)
+		for i, k := range getSortedKeysFromMap(m) {
+			u.Set(fmt.Sprintf("rules[%d].key", i), k)
+			u.Set(fmt.Sprintf("rules[%d].value", i), m[k])
+		}
+	}
+	if v, found := p.p["type"]; found {
+		u.Set("type", v.(string))
+	}
+	return u
+}
+
+func (p *ImportRoleParams) SetDescription(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["description"] = v
+}
+
+func (p *ImportRoleParams) GetDescription() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["description"].(string)
+	return value, ok
+}
+
+func (p *ImportRoleParams) SetForced(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["forced"] = v
+}
+
+func (p *ImportRoleParams) GetForced() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["forced"].(bool)
+	return value, ok
+}
+
+func (p *ImportRoleParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *ImportRoleParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *ImportRoleParams) SetRules(v map[string]string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["rules"] = v
+}
+
+func (p *ImportRoleParams) GetRules() (map[string]string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["rules"].(map[string]string)
+	return value, ok
+}
+
+func (p *ImportRoleParams) SetType(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["type"] = v
+}
+
+func (p *ImportRoleParams) GetType() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["type"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new ImportRoleParams instance,
+// as then you are sure you have configured all required params
+func (s *RoleService) NewImportRoleParams(name string, rules map[string]string) *ImportRoleParams {
+	p := &ImportRoleParams{}
+	p.p = make(map[string]interface{})
+	p.p["name"] = name
+	p.p["rules"] = rules
+	return p
+}
+
+// Imports a role based on provided map of rule permissions
+func (s *RoleService) ImportRole(p *ImportRoleParams) (*ImportRoleResponse, error) {
+	resp, err := s.cs.newRequest("importRole", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ImportRoleResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ImportRoleResponse struct {
+	Description string `json:"description"`
+	Id          string `json:"id"`
+	Isdefault   bool   `json:"isdefault"`
+	JobID       string `json:"jobid"`
+	Jobstatus   int    `json:"jobstatus"`
+	Name        string `json:"name"`
+	Type        string `json:"type"`
+}
+
 type ListRolePermissionsParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/RoleService_mock.go b/cloudstack/RoleService_mock.go
index c40472c..cac7e6b 100644
--- a/cloudstack/RoleService_mock.go
+++ b/cloudstack/RoleService_mock.go
@@ -175,6 +175,21 @@ func (mr *MockRoleServiceIfaceMockRecorder) GetRoleID(name interface{}, opts ...
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleID", reflect.TypeOf((*MockRoleServiceIface)(nil).GetRoleID), varargs...)
 }
 
+// ImportRole mocks base method.
+func (m *MockRoleServiceIface) ImportRole(p *ImportRoleParams) (*ImportRoleResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ImportRole", p)
+	ret0, _ := ret[0].(*ImportRoleResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ImportRole indicates an expected call of ImportRole.
+func (mr *MockRoleServiceIfaceMockRecorder) ImportRole(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportRole", reflect.TypeOf((*MockRoleServiceIface)(nil).ImportRole), p)
+}
+
 // ListRolePermissions mocks base method.
 func (m *MockRoleServiceIface) ListRolePermissions(p *ListRolePermissionsParams) (*ListRolePermissionsResponse, error) {
 	m.ctrl.T.Helper()
@@ -261,6 +276,20 @@ func (mr *MockRoleServiceIfaceMockRecorder) NewDeleteRolePermissionParams(id int
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteRolePermissionParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewDeleteRolePermissionParams), id)
 }
 
+// NewImportRoleParams mocks base method.
+func (m *MockRoleServiceIface) NewImportRoleParams(name string, rules map[string]string) *ImportRoleParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewImportRoleParams", name, rules)
+	ret0, _ := ret[0].(*ImportRoleParams)
+	return ret0
+}
+
+// NewImportRoleParams indicates an expected call of NewImportRoleParams.
+func (mr *MockRoleServiceIfaceMockRecorder) NewImportRoleParams(name, rules interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewImportRoleParams", reflect.TypeOf((*MockRoleServiceIface)(nil).NewImportRoleParams), name, rules)
+}
+
 // NewListRolePermissionsParams mocks base method.
 func (m *MockRoleServiceIface) NewListRolePermissionsParams() *ListRolePermissionsParams {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/SSHService.go b/cloudstack/SSHService.go
index a5f9777..aef62e1 100644
--- a/cloudstack/SSHService.go
+++ b/cloudstack/SSHService.go
@@ -24,6 +24,7 @@ import (
 	"fmt"
 	"net/url"
 	"strconv"
+	"strings"
 )
 
 type SSHServiceIface interface {
@@ -34,6 +35,8 @@ type SSHServiceIface interface {
 	ListSSHKeyPairs(p *ListSSHKeyPairsParams) (*ListSSHKeyPairsResponse, error)
 	NewListSSHKeyPairsParams() *ListSSHKeyPairsParams
 	GetSSHKeyPairID(name string, opts ...OptionFunc) (string, int, error)
+	GetSSHKeyPairByName(name string, opts ...OptionFunc) (*SSHKeyPair, int, error)
+	GetSSHKeyPairByID(id string, opts ...OptionFunc) (*SSHKeyPair, int, error)
 	RegisterSSHKeyPair(p *RegisterSSHKeyPairParams) (*RegisterSSHKeyPairResponse, error)
 	NewRegisterSSHKeyPairParams(name string, publickey string) *RegisterSSHKeyPairParams
 	ResetSSHKeyForVirtualMachine(p *ResetSSHKeyForVirtualMachineParams) (*ResetSSHKeyForVirtualMachineResponse, error)
@@ -325,6 +328,9 @@ func (p *ListSSHKeyPairsParams) toURLValues() url.Values {
 	if v, found := p.p["fingerprint"]; found {
 		u.Set("fingerprint", v.(string))
 	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
 	if v, found := p.p["isrecursive"]; found {
 		vv := strconv.FormatBool(v.(bool))
 		u.Set("isrecursive", vv)
@@ -398,6 +404,21 @@ func (p *ListSSHKeyPairsParams) GetFingerprint() (string, bool) {
 	return value, ok
 }
 
+func (p *ListSSHKeyPairsParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListSSHKeyPairsParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
 func (p *ListSSHKeyPairsParams) SetIsrecursive(v bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
@@ -547,6 +568,53 @@ func (s *SSHService) GetSSHKeyPairID(name string, opts ...OptionFunc) (string, i
 	return "", l.Count, fmt.Errorf("Could not find an exact match for %s: %+v", name, l)
 }
 
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *SSHService) GetSSHKeyPairByName(name string, opts ...OptionFunc) (*SSHKeyPair, int, error) {
+	id, count, err := s.GetSSHKeyPairID(name, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+
+	r, count, err := s.GetSSHKeyPairByID(id, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+	return r, count, nil
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *SSHService) GetSSHKeyPairByID(id string, opts ...OptionFunc) (*SSHKeyPair, int, error) {
+	p := &ListSSHKeyPairsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListSSHKeyPairs(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.SSHKeyPairs[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for SSHKeyPair UUID: %s!", id)
+}
+
 // List registered keypairs
 func (s *SSHService) ListSSHKeyPairs(p *ListSSHKeyPairsParams) (*ListSSHKeyPairsResponse, error) {
 	resp, err := s.cs.newRequest("listSSHKeyPairs", p.toURLValues())
diff --git a/cloudstack/SSHService_mock.go b/cloudstack/SSHService_mock.go
index 24d7098..0ea3ed6 100644
--- a/cloudstack/SSHService_mock.go
+++ b/cloudstack/SSHService_mock.go
@@ -82,6 +82,48 @@ func (mr *MockSSHServiceIfaceMockRecorder) DeleteSSHKeyPair(p interface{}) *gomo
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSSHKeyPair", reflect.TypeOf((*MockSSHServiceIface)(nil).DeleteSSHKeyPair), p)
 }
 
+// GetSSHKeyPairByID mocks base method.
+func (m *MockSSHServiceIface) GetSSHKeyPairByID(id string, opts ...OptionFunc) (*SSHKeyPair, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetSSHKeyPairByID", varargs...)
+	ret0, _ := ret[0].(*SSHKeyPair)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetSSHKeyPairByID indicates an expected call of GetSSHKeyPairByID.
+func (mr *MockSSHServiceIfaceMockRecorder) GetSSHKeyPairByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSSHKeyPairByID", reflect.TypeOf((*MockSSHServiceIface)(nil).GetSSHKeyPairByID), varargs...)
+}
+
+// GetSSHKeyPairByName mocks base method.
+func (m *MockSSHServiceIface) GetSSHKeyPairByName(name string, opts ...OptionFunc) (*SSHKeyPair, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetSSHKeyPairByName", varargs...)
+	ret0, _ := ret[0].(*SSHKeyPair)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetSSHKeyPairByName indicates an expected call of GetSSHKeyPairByName.
+func (mr *MockSSHServiceIfaceMockRecorder) GetSSHKeyPairByName(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSSHKeyPairByName", reflect.TypeOf((*MockSSHServiceIface)(nil).GetSSHKeyPairByName), varargs...)
+}
+
 // GetSSHKeyPairID mocks base method.
 func (m *MockSSHServiceIface) GetSSHKeyPairID(name string, opts ...OptionFunc) (string, int, error) {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/VolumeService.go b/cloudstack/VolumeService.go
index 60cc2b0..081086b 100644
--- a/cloudstack/VolumeService.go
+++ b/cloudstack/VolumeService.go
@@ -34,6 +34,8 @@ type VolumeServiceIface interface {
 	NewCreateVolumeParams() *CreateVolumeParams
 	DeleteVolume(p *DeleteVolumeParams) (*DeleteVolumeResponse, error)
 	NewDeleteVolumeParams(id string) *DeleteVolumeParams
+	DestroyVolume(p *DestroyVolumeParams) (*DestroyVolumeResponse, error)
+	NewDestroyVolumeParams(id string) *DestroyVolumeParams
 	DetachVolume(p *DetachVolumeParams) (*DetachVolumeResponse, error)
 	NewDetachVolumeParams() *DetachVolumeParams
 	ExtractVolume(p *ExtractVolumeParams) (*ExtractVolumeResponse, error)
@@ -51,8 +53,15 @@ type VolumeServiceIface interface {
 	GetVolumeID(name string, opts ...OptionFunc) (string, int, error)
 	GetVolumeByName(name string, opts ...OptionFunc) (*Volume, int, error)
 	GetVolumeByID(id string, opts ...OptionFunc) (*Volume, int, error)
+	ListVolumesMetrics(p *ListVolumesMetricsParams) (*ListVolumesMetricsResponse, error)
+	NewListVolumesMetricsParams() *ListVolumesMetricsParams
+	GetVolumesMetricID(name string, opts ...OptionFunc) (string, int, error)
+	GetVolumesMetricByName(name string, opts ...OptionFunc) (*VolumesMetric, int, error)
+	GetVolumesMetricByID(id string, opts ...OptionFunc) (*VolumesMetric, int, error)
 	MigrateVolume(p *MigrateVolumeParams) (*MigrateVolumeResponse, error)
 	NewMigrateVolumeParams(storageid string, volumeid string) *MigrateVolumeParams
+	RecoverVolume(p *RecoverVolumeParams) (*RecoverVolumeResponse, error)
+	NewRecoverVolumeParams(id string) *RecoverVolumeParams
 	ResizeVolume(p *ResizeVolumeParams) (*ResizeVolumeResponse, error)
 	NewResizeVolumeParams(id string) *ResizeVolumeParams
 	UpdateVolume(p *UpdateVolumeParams) (*UpdateVolumeResponse, error)
@@ -692,6 +701,168 @@ func (r *DeleteVolumeResponse) UnmarshalJSON(b []byte) error {
 	return json.Unmarshal(b, (*alias)(r))
 }
 
+type DestroyVolumeParams struct {
+	p map[string]interface{}
+}
+
+func (p *DestroyVolumeParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["expunge"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("expunge", vv)
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *DestroyVolumeParams) SetExpunge(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["expunge"] = v
+}
+
+func (p *DestroyVolumeParams) GetExpunge() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["expunge"].(bool)
+	return value, ok
+}
+
+func (p *DestroyVolumeParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *DestroyVolumeParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new DestroyVolumeParams instance,
+// as then you are sure you have configured all required params
+func (s *VolumeService) NewDestroyVolumeParams(id string) *DestroyVolumeParams {
+	p := &DestroyVolumeParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Destroys a Volume.
+func (s *VolumeService) DestroyVolume(p *DestroyVolumeParams) (*DestroyVolumeResponse, error) {
+	resp, err := s.cs.newRequest("destroyVolume", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r DestroyVolumeResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	// If we have a async client, we need to wait for the async result
+	if s.cs.async {
+		b, err := s.cs.GetAsyncJobResult(r.JobID, s.cs.timeout)
+		if err != nil {
+			if err == AsyncTimeoutErr {
+				return &r, err
+			}
+			return nil, err
+		}
+
+		b, err = getRawValue(b)
+		if err != nil {
+			return nil, err
+		}
+
+		if err := json.Unmarshal(b, &r); err != nil {
+			return nil, err
+		}
+	}
+
+	return &r, nil
+}
+
+type DestroyVolumeResponse struct {
+	Account                    string `json:"account"`
+	Attached                   string `json:"attached"`
+	Chaininfo                  string `json:"chaininfo"`
+	Clusterid                  string `json:"clusterid"`
+	Clustername                string `json:"clustername"`
+	Created                    string `json:"created"`
+	Destroyed                  bool   `json:"destroyed"`
+	Deviceid                   int64  `json:"deviceid"`
+	DiskBytesReadRate          int64  `json:"diskBytesReadRate"`
+	DiskBytesWriteRate         int64  `json:"diskBytesWriteRate"`
+	DiskIopsReadRate           int64  `json:"diskIopsReadRate"`
+	DiskIopsWriteRate          int64  `json:"diskIopsWriteRate"`
+	Diskioread                 int64  `json:"diskioread"`
+	Diskiowrite                int64  `json:"diskiowrite"`
+	Diskkbsread                int64  `json:"diskkbsread"`
+	Diskkbswrite               int64  `json:"diskkbswrite"`
+	Diskofferingdisplaytext    string `json:"diskofferingdisplaytext"`
+	Diskofferingid             string `json:"diskofferingid"`
+	Diskofferingname           string `json:"diskofferingname"`
+	Displayvolume              bool   `json:"displayvolume"`
+	Domain                     string `json:"domain"`
+	Domainid                   string `json:"domainid"`
+	Hasannotations             bool   `json:"hasannotations"`
+	Hypervisor                 string `json:"hypervisor"`
+	Id                         string `json:"id"`
+	Isextractable              bool   `json:"isextractable"`
+	Isodisplaytext             string `json:"isodisplaytext"`
+	Isoid                      string `json:"isoid"`
+	Isoname                    string `json:"isoname"`
+	JobID                      string `json:"jobid"`
+	Jobstatus                  int    `json:"jobstatus"`
+	Maxiops                    int64  `json:"maxiops"`
+	Miniops                    int64  `json:"miniops"`
+	Name                       string `json:"name"`
+	Path                       string `json:"path"`
+	Physicalsize               int64  `json:"physicalsize"`
+	Podid                      string `json:"podid"`
+	Podname                    string `json:"podname"`
+	Project                    string `json:"project"`
+	Projectid                  string `json:"projectid"`
+	Provisioningtype           string `json:"provisioningtype"`
+	Quiescevm                  bool   `json:"quiescevm"`
+	Serviceofferingdisplaytext string `json:"serviceofferingdisplaytext"`
+	Serviceofferingid          string `json:"serviceofferingid"`
+	Serviceofferingname        string `json:"serviceofferingname"`
+	Size                       int64  `json:"size"`
+	Snapshotid                 string `json:"snapshotid"`
+	State                      string `json:"state"`
+	Status                     string `json:"status"`
+	Storage                    string `json:"storage"`
+	Storageid                  string `json:"storageid"`
+	Storagetype                string `json:"storagetype"`
+	Supportsstoragesnapshot    bool   `json:"supportsstoragesnapshot"`
+	Tags                       []Tags `json:"tags"`
+	Templatedisplaytext        string `json:"templatedisplaytext"`
+	Templateid                 string `json:"templateid"`
+	Templatename               string `json:"templatename"`
+	Type                       string `json:"type"`
+	Utilization                string `json:"utilization"`
+	Virtualmachineid           string `json:"virtualmachineid"`
+	Virtualsize                int64  `json:"virtualsize"`
+	Vmdisplayname              string `json:"vmdisplayname"`
+	Vmname                     string `json:"vmname"`
+	Vmstate                    string `json:"vmstate"`
+	Zoneid                     string `json:"zoneid"`
+	Zonename                   string `json:"zonename"`
+}
+
 type DetachVolumeParams struct {
 	p map[string]interface{}
 }
@@ -2011,102 +2182,702 @@ type Volume struct {
 	Zonename                   string `json:"zonename"`
 }
 
-type MigrateVolumeParams struct {
+type ListVolumesMetricsParams struct {
 	p map[string]interface{}
 }
 
-func (p *MigrateVolumeParams) toURLValues() url.Values {
+func (p *ListVolumesMetricsParams) toURLValues() url.Values {
 	u := url.Values{}
 	if p.p == nil {
 		return u
 	}
-	if v, found := p.p["livemigrate"]; found {
+	if v, found := p.p["account"]; found {
+		u.Set("account", v.(string))
+	}
+	if v, found := p.p["clusterid"]; found {
+		u.Set("clusterid", v.(string))
+	}
+	if v, found := p.p["diskofferingid"]; found {
+		u.Set("diskofferingid", v.(string))
+	}
+	if v, found := p.p["displayvolume"]; found {
 		vv := strconv.FormatBool(v.(bool))
-		u.Set("livemigrate", vv)
+		u.Set("displayvolume", vv)
 	}
-	if v, found := p.p["newdiskofferingid"]; found {
-		u.Set("newdiskofferingid", v.(string))
+	if v, found := p.p["domainid"]; found {
+		u.Set("domainid", v.(string))
+	}
+	if v, found := p.p["hostid"]; found {
+		u.Set("hostid", v.(string))
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["ids"]; found {
+		vv := strings.Join(v.([]string), ",")
+		u.Set("ids", vv)
+	}
+	if v, found := p.p["isrecursive"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("isrecursive", vv)
+	}
+	if v, found := p.p["keyword"]; found {
+		u.Set("keyword", v.(string))
+	}
+	if v, found := p.p["listall"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("listall", vv)
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["page"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("page", vv)
+	}
+	if v, found := p.p["pagesize"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("pagesize", vv)
+	}
+	if v, found := p.p["podid"]; found {
+		u.Set("podid", v.(string))
+	}
+	if v, found := p.p["projectid"]; found {
+		u.Set("projectid", v.(string))
+	}
+	if v, found := p.p["state"]; found {
+		u.Set("state", v.(string))
 	}
 	if v, found := p.p["storageid"]; found {
 		u.Set("storageid", v.(string))
 	}
-	if v, found := p.p["volumeid"]; found {
-		u.Set("volumeid", v.(string))
+	if v, found := p.p["tags"]; found {
+		m := v.(map[string]string)
+		for i, k := range getSortedKeysFromMap(m) {
+			u.Set(fmt.Sprintf("tags[%d].key", i), k)
+			u.Set(fmt.Sprintf("tags[%d].value", i), m[k])
+		}
+	}
+	if v, found := p.p["type"]; found {
+		u.Set("type", v.(string))
+	}
+	if v, found := p.p["virtualmachineid"]; found {
+		u.Set("virtualmachineid", v.(string))
+	}
+	if v, found := p.p["zoneid"]; found {
+		u.Set("zoneid", v.(string))
 	}
 	return u
 }
 
-func (p *MigrateVolumeParams) SetLivemigrate(v bool) {
+func (p *ListVolumesMetricsParams) SetAccount(v string) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	p.p["livemigrate"] = v
+	p.p["account"] = v
 }
 
-func (p *MigrateVolumeParams) GetLivemigrate() (bool, bool) {
+func (p *ListVolumesMetricsParams) GetAccount() (string, bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	value, ok := p.p["livemigrate"].(bool)
+	value, ok := p.p["account"].(string)
 	return value, ok
 }
 
-func (p *MigrateVolumeParams) SetNewdiskofferingid(v string) {
+func (p *ListVolumesMetricsParams) SetClusterid(v string) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	p.p["newdiskofferingid"] = v
+	p.p["clusterid"] = v
 }
 
-func (p *MigrateVolumeParams) GetNewdiskofferingid() (string, bool) {
+func (p *ListVolumesMetricsParams) GetClusterid() (string, bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	value, ok := p.p["newdiskofferingid"].(string)
+	value, ok := p.p["clusterid"].(string)
 	return value, ok
 }
 
-func (p *MigrateVolumeParams) SetStorageid(v string) {
+func (p *ListVolumesMetricsParams) SetDiskofferingid(v string) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	p.p["storageid"] = v
+	p.p["diskofferingid"] = v
 }
 
-func (p *MigrateVolumeParams) GetStorageid() (string, bool) {
+func (p *ListVolumesMetricsParams) GetDiskofferingid() (string, bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	value, ok := p.p["storageid"].(string)
+	value, ok := p.p["diskofferingid"].(string)
 	return value, ok
 }
 
-func (p *MigrateVolumeParams) SetVolumeid(v string) {
+func (p *ListVolumesMetricsParams) SetDisplayvolume(v bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	p.p["volumeid"] = v
+	p.p["displayvolume"] = v
 }
 
-func (p *MigrateVolumeParams) GetVolumeid() (string, bool) {
+func (p *ListVolumesMetricsParams) GetDisplayvolume() (bool, bool) {
 	if p.p == nil {
 		p.p = make(map[string]interface{})
 	}
-	value, ok := p.p["volumeid"].(string)
+	value, ok := p.p["displayvolume"].(bool)
 	return value, ok
 }
 
-// You should always use this function to get a new MigrateVolumeParams instance,
-// as then you are sure you have configured all required params
-func (s *VolumeService) NewMigrateVolumeParams(storageid string, volumeid string) *MigrateVolumeParams {
-	p := &MigrateVolumeParams{}
-	p.p = make(map[string]interface{})
-	p.p["storageid"] = storageid
-	p.p["volumeid"] = volumeid
-	return p
-}
-
-// Migrate volume
+func (p *ListVolumesMetricsParams) SetDomainid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["domainid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetDomainid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["domainid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetHostid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["hostid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetHostid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["hostid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetIds(v []string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["ids"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetIds() ([]string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["ids"].([]string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetIsrecursive(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["isrecursive"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetIsrecursive() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["isrecursive"].(bool)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetKeyword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keyword"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetKeyword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keyword"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetListall(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["listall"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetListall() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["listall"].(bool)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetPage(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["page"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetPage() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["page"].(int)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetPagesize(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["pagesize"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetPagesize() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["pagesize"].(int)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetPodid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["podid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetPodid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["podid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetProjectid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["projectid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetProjectid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["projectid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetState(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["state"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetState() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["state"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetStorageid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["storageid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetStorageid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["storageid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetTags(v map[string]string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["tags"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetTags() (map[string]string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["tags"].(map[string]string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetType(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["type"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetType() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["type"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetVirtualmachineid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["virtualmachineid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetVirtualmachineid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["virtualmachineid"].(string)
+	return value, ok
+}
+
+func (p *ListVolumesMetricsParams) SetZoneid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["zoneid"] = v
+}
+
+func (p *ListVolumesMetricsParams) GetZoneid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["zoneid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new ListVolumesMetricsParams instance,
+// as then you are sure you have configured all required params
+func (s *VolumeService) NewListVolumesMetricsParams() *ListVolumesMetricsParams {
+	p := &ListVolumesMetricsParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *VolumeService) GetVolumesMetricID(name string, opts ...OptionFunc) (string, int, error) {
+	p := &ListVolumesMetricsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["name"] = name
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return "", -1, err
+		}
+	}
+
+	l, err := s.ListVolumesMetrics(p)
+	if err != nil {
+		return "", -1, err
+	}
+
+	if l.Count == 0 {
+		return "", l.Count, fmt.Errorf("No match found for %s: %+v", name, l)
+	}
+
+	if l.Count == 1 {
+		return l.VolumesMetrics[0].Id, l.Count, nil
+	}
+
+	if l.Count > 1 {
+		for _, v := range l.VolumesMetrics {
+			if v.Name == name {
+				return v.Id, l.Count, nil
+			}
+		}
+	}
+	return "", l.Count, fmt.Errorf("Could not find an exact match for %s: %+v", name, l)
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *VolumeService) GetVolumesMetricByName(name string, opts ...OptionFunc) (*VolumesMetric, int, error) {
+	id, count, err := s.GetVolumesMetricID(name, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+
+	r, count, err := s.GetVolumesMetricByID(id, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+	return r, count, nil
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *VolumeService) GetVolumesMetricByID(id string, opts ...OptionFunc) (*VolumesMetric, int, error) {
+	p := &ListVolumesMetricsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListVolumesMetrics(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.VolumesMetrics[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for VolumesMetric UUID: %s!", id)
+}
+
+// Lists volume metrics
+func (s *VolumeService) ListVolumesMetrics(p *ListVolumesMetricsParams) (*ListVolumesMetricsResponse, error) {
+	resp, err := s.cs.newRequest("listVolumesMetrics", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ListVolumesMetricsResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ListVolumesMetricsResponse struct {
+	Count          int              `json:"count"`
+	VolumesMetrics []*VolumesMetric `json:"volumesmetric"`
+}
+
+type VolumesMetric struct {
+	Account                    string `json:"account"`
+	Attached                   string `json:"attached"`
+	Chaininfo                  string `json:"chaininfo"`
+	Clusterid                  string `json:"clusterid"`
+	Clustername                string `json:"clustername"`
+	Created                    string `json:"created"`
+	Destroyed                  bool   `json:"destroyed"`
+	Deviceid                   int64  `json:"deviceid"`
+	DiskBytesReadRate          int64  `json:"diskBytesReadRate"`
+	DiskBytesWriteRate         int64  `json:"diskBytesWriteRate"`
+	DiskIopsReadRate           int64  `json:"diskIopsReadRate"`
+	DiskIopsWriteRate          int64  `json:"diskIopsWriteRate"`
+	Diskiopstotal              int64  `json:"diskiopstotal"`
+	Diskioread                 int64  `json:"diskioread"`
+	Diskiowrite                int64  `json:"diskiowrite"`
+	Diskkbsread                int64  `json:"diskkbsread"`
+	Diskkbswrite               int64  `json:"diskkbswrite"`
+	Diskofferingdisplaytext    string `json:"diskofferingdisplaytext"`
+	Diskofferingid             string `json:"diskofferingid"`
+	Diskofferingname           string `json:"diskofferingname"`
+	Displayvolume              bool   `json:"displayvolume"`
+	Domain                     string `json:"domain"`
+	Domainid                   string `json:"domainid"`
+	Hasannotations             bool   `json:"hasannotations"`
+	Hypervisor                 string `json:"hypervisor"`
+	Id                         string `json:"id"`
+	Isextractable              bool   `json:"isextractable"`
+	Isodisplaytext             string `json:"isodisplaytext"`
+	Isoid                      string `json:"isoid"`
+	Isoname                    string `json:"isoname"`
+	JobID                      string `json:"jobid"`
+	Jobstatus                  int    `json:"jobstatus"`
+	Maxiops                    int64  `json:"maxiops"`
+	Miniops                    int64  `json:"miniops"`
+	Name                       string `json:"name"`
+	Path                       string `json:"path"`
+	Physicalsize               int64  `json:"physicalsize"`
+	Podid                      string `json:"podid"`
+	Podname                    string `json:"podname"`
+	Project                    string `json:"project"`
+	Projectid                  string `json:"projectid"`
+	Provisioningtype           string `json:"provisioningtype"`
+	Quiescevm                  bool   `json:"quiescevm"`
+	Serviceofferingdisplaytext string `json:"serviceofferingdisplaytext"`
+	Serviceofferingid          string `json:"serviceofferingid"`
+	Serviceofferingname        string `json:"serviceofferingname"`
+	Size                       int64  `json:"size"`
+	Sizegb                     string `json:"sizegb"`
+	Snapshotid                 string `json:"snapshotid"`
+	State                      string `json:"state"`
+	Status                     string `json:"status"`
+	Storage                    string `json:"storage"`
+	Storageid                  string `json:"storageid"`
+	Storagetype                string `json:"storagetype"`
+	Supportsstoragesnapshot    bool   `json:"supportsstoragesnapshot"`
+	Tags                       []Tags `json:"tags"`
+	Templatedisplaytext        string `json:"templatedisplaytext"`
+	Templateid                 string `json:"templateid"`
+	Templatename               string `json:"templatename"`
+	Type                       string `json:"type"`
+	Utilization                string `json:"utilization"`
+	Virtualmachineid           string `json:"virtualmachineid"`
+	Virtualsize                int64  `json:"virtualsize"`
+	Vmdisplayname              string `json:"vmdisplayname"`
+	Vmname                     string `json:"vmname"`
+	Vmstate                    string `json:"vmstate"`
+	Zoneid                     string `json:"zoneid"`
+	Zonename                   string `json:"zonename"`
+}
+
+type MigrateVolumeParams struct {
+	p map[string]interface{}
+}
+
+func (p *MigrateVolumeParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["livemigrate"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("livemigrate", vv)
+	}
+	if v, found := p.p["newdiskofferingid"]; found {
+		u.Set("newdiskofferingid", v.(string))
+	}
+	if v, found := p.p["storageid"]; found {
+		u.Set("storageid", v.(string))
+	}
+	if v, found := p.p["volumeid"]; found {
+		u.Set("volumeid", v.(string))
+	}
+	return u
+}
+
+func (p *MigrateVolumeParams) SetLivemigrate(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["livemigrate"] = v
+}
+
+func (p *MigrateVolumeParams) GetLivemigrate() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["livemigrate"].(bool)
+	return value, ok
+}
+
+func (p *MigrateVolumeParams) SetNewdiskofferingid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["newdiskofferingid"] = v
+}
+
+func (p *MigrateVolumeParams) GetNewdiskofferingid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["newdiskofferingid"].(string)
+	return value, ok
+}
+
+func (p *MigrateVolumeParams) SetStorageid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["storageid"] = v
+}
+
+func (p *MigrateVolumeParams) GetStorageid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["storageid"].(string)
+	return value, ok
+}
+
+func (p *MigrateVolumeParams) SetVolumeid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["volumeid"] = v
+}
+
+func (p *MigrateVolumeParams) GetVolumeid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["volumeid"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new MigrateVolumeParams instance,
+// as then you are sure you have configured all required params
+func (s *VolumeService) NewMigrateVolumeParams(storageid string, volumeid string) *MigrateVolumeParams {
+	p := &MigrateVolumeParams{}
+	p.p = make(map[string]interface{})
+	p.p["storageid"] = storageid
+	p.p["volumeid"] = volumeid
+	return p
+}
+
+// Migrate volume
 func (s *VolumeService) MigrateVolume(p *MigrateVolumeParams) (*MigrateVolumeResponse, error) {
 	resp, err := s.cs.newRequest("migrateVolume", p.toURLValues())
 	if err != nil {
@@ -2210,6 +2981,129 @@ type MigrateVolumeResponse struct {
 	Zonename                   string `json:"zonename"`
 }
 
+type RecoverVolumeParams struct {
+	p map[string]interface{}
+}
+
+func (p *RecoverVolumeParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	return u
+}
+
+func (p *RecoverVolumeParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *RecoverVolumeParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+// You should always use this function to get a new RecoverVolumeParams instance,
+// as then you are sure you have configured all required params
+func (s *VolumeService) NewRecoverVolumeParams(id string) *RecoverVolumeParams {
+	p := &RecoverVolumeParams{}
+	p.p = make(map[string]interface{})
+	p.p["id"] = id
+	return p
+}
+
+// Recovers a Destroy volume.
+func (s *VolumeService) RecoverVolume(p *RecoverVolumeParams) (*RecoverVolumeResponse, error) {
+	resp, err := s.cs.newRequest("recoverVolume", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r RecoverVolumeResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type RecoverVolumeResponse struct {
+	Account                    string `json:"account"`
+	Attached                   string `json:"attached"`
+	Chaininfo                  string `json:"chaininfo"`
+	Clusterid                  string `json:"clusterid"`
+	Clustername                string `json:"clustername"`
+	Created                    string `json:"created"`
+	Destroyed                  bool   `json:"destroyed"`
+	Deviceid                   int64  `json:"deviceid"`
+	DiskBytesReadRate          int64  `json:"diskBytesReadRate"`
+	DiskBytesWriteRate         int64  `json:"diskBytesWriteRate"`
+	DiskIopsReadRate           int64  `json:"diskIopsReadRate"`
+	DiskIopsWriteRate          int64  `json:"diskIopsWriteRate"`
+	Diskioread                 int64  `json:"diskioread"`
+	Diskiowrite                int64  `json:"diskiowrite"`
+	Diskkbsread                int64  `json:"diskkbsread"`
+	Diskkbswrite               int64  `json:"diskkbswrite"`
+	Diskofferingdisplaytext    string `json:"diskofferingdisplaytext"`
+	Diskofferingid             string `json:"diskofferingid"`
+	Diskofferingname           string `json:"diskofferingname"`
+	Displayvolume              bool   `json:"displayvolume"`
+	Domain                     string `json:"domain"`
+	Domainid                   string `json:"domainid"`
+	Hasannotations             bool   `json:"hasannotations"`
+	Hypervisor                 string `json:"hypervisor"`
+	Id                         string `json:"id"`
+	Isextractable              bool   `json:"isextractable"`
+	Isodisplaytext             string `json:"isodisplaytext"`
+	Isoid                      string `json:"isoid"`
+	Isoname                    string `json:"isoname"`
+	JobID                      string `json:"jobid"`
+	Jobstatus                  int    `json:"jobstatus"`
+	Maxiops                    int64  `json:"maxiops"`
+	Miniops                    int64  `json:"miniops"`
+	Name                       string `json:"name"`
+	Path                       string `json:"path"`
+	Physicalsize               int64  `json:"physicalsize"`
+	Podid                      string `json:"podid"`
+	Podname                    string `json:"podname"`
+	Project                    string `json:"project"`
+	Projectid                  string `json:"projectid"`
+	Provisioningtype           string `json:"provisioningtype"`
+	Quiescevm                  bool   `json:"quiescevm"`
+	Serviceofferingdisplaytext string `json:"serviceofferingdisplaytext"`
+	Serviceofferingid          string `json:"serviceofferingid"`
+	Serviceofferingname        string `json:"serviceofferingname"`
+	Size                       int64  `json:"size"`
+	Snapshotid                 string `json:"snapshotid"`
+	State                      string `json:"state"`
+	Status                     string `json:"status"`
+	Storage                    string `json:"storage"`
+	Storageid                  string `json:"storageid"`
+	Storagetype                string `json:"storagetype"`
+	Supportsstoragesnapshot    bool   `json:"supportsstoragesnapshot"`
+	Tags                       []Tags `json:"tags"`
+	Templatedisplaytext        string `json:"templatedisplaytext"`
+	Templateid                 string `json:"templateid"`
+	Templatename               string `json:"templatename"`
+	Type                       string `json:"type"`
+	Utilization                string `json:"utilization"`
+	Virtualmachineid           string `json:"virtualmachineid"`
+	Virtualsize                int64  `json:"virtualsize"`
+	Vmdisplayname              string `json:"vmdisplayname"`
+	Vmname                     string `json:"vmname"`
+	Vmstate                    string `json:"vmstate"`
+	Zoneid                     string `json:"zoneid"`
+	Zonename                   string `json:"zonename"`
+}
+
 type ResizeVolumeParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/VolumeService_mock.go b/cloudstack/VolumeService_mock.go
index 752077c..3e12e0d 100644
--- a/cloudstack/VolumeService_mock.go
+++ b/cloudstack/VolumeService_mock.go
@@ -97,6 +97,21 @@ func (mr *MockVolumeServiceIfaceMockRecorder) DeleteVolume(p interface{}) *gomoc
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteVolume", reflect.TypeOf((*MockVolumeServiceIface)(nil).DeleteVolume), p)
 }
 
+// DestroyVolume mocks base method.
+func (m *MockVolumeServiceIface) DestroyVolume(p *DestroyVolumeParams) (*DestroyVolumeResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DestroyVolume", p)
+	ret0, _ := ret[0].(*DestroyVolumeResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DestroyVolume indicates an expected call of DestroyVolume.
+func (mr *MockVolumeServiceIfaceMockRecorder) DestroyVolume(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DestroyVolume", reflect.TypeOf((*MockVolumeServiceIface)(nil).DestroyVolume), p)
+}
+
 // DetachVolume mocks base method.
 func (m *MockVolumeServiceIface) DetachVolume(p *DetachVolumeParams) (*DetachVolumeResponse, error) {
 	m.ctrl.T.Helper()
@@ -250,6 +265,69 @@ func (mr *MockVolumeServiceIfaceMockRecorder) GetVolumeiScsiName(p interface{})
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVolumeiScsiName", reflect.TypeOf((*MockVolumeServiceIface)(nil).GetVolumeiScsiName), p)
 }
 
+// GetVolumesMetricByID mocks base method.
+func (m *MockVolumeServiceIface) GetVolumesMetricByID(id string, opts ...OptionFunc) (*VolumesMetric, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetVolumesMetricByID", varargs...)
+	ret0, _ := ret[0].(*VolumesMetric)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetVolumesMetricByID indicates an expected call of GetVolumesMetricByID.
+func (mr *MockVolumeServiceIfaceMockRecorder) GetVolumesMetricByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVolumesMetricByID", reflect.TypeOf((*MockVolumeServiceIface)(nil).GetVolumesMetricByID), varargs...)
+}
+
+// GetVolumesMetricByName mocks base method.
+func (m *MockVolumeServiceIface) GetVolumesMetricByName(name string, opts ...OptionFunc) (*VolumesMetric, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetVolumesMetricByName", varargs...)
+	ret0, _ := ret[0].(*VolumesMetric)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetVolumesMetricByName indicates an expected call of GetVolumesMetricByName.
+func (mr *MockVolumeServiceIfaceMockRecorder) GetVolumesMetricByName(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVolumesMetricByName", reflect.TypeOf((*MockVolumeServiceIface)(nil).GetVolumesMetricByName), varargs...)
+}
+
+// GetVolumesMetricID mocks base method.
+func (m *MockVolumeServiceIface) GetVolumesMetricID(name string, opts ...OptionFunc) (string, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetVolumesMetricID", varargs...)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetVolumesMetricID indicates an expected call of GetVolumesMetricID.
+func (mr *MockVolumeServiceIfaceMockRecorder) GetVolumesMetricID(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVolumesMetricID", reflect.TypeOf((*MockVolumeServiceIface)(nil).GetVolumesMetricID), varargs...)
+}
+
 // ListVolumes mocks base method.
 func (m *MockVolumeServiceIface) ListVolumes(p *ListVolumesParams) (*ListVolumesResponse, error) {
 	m.ctrl.T.Helper()
@@ -265,6 +343,21 @@ func (mr *MockVolumeServiceIfaceMockRecorder) ListVolumes(p interface{}) *gomock
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVolumes", reflect.TypeOf((*MockVolumeServiceIface)(nil).ListVolumes), p)
 }
 
+// ListVolumesMetrics mocks base method.
+func (m *MockVolumeServiceIface) ListVolumesMetrics(p *ListVolumesMetricsParams) (*ListVolumesMetricsResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListVolumesMetrics", p)
+	ret0, _ := ret[0].(*ListVolumesMetricsResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListVolumesMetrics indicates an expected call of ListVolumesMetrics.
+func (mr *MockVolumeServiceIfaceMockRecorder) ListVolumesMetrics(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVolumesMetrics", reflect.TypeOf((*MockVolumeServiceIface)(nil).ListVolumesMetrics), p)
+}
+
 // MigrateVolume mocks base method.
 func (m *MockVolumeServiceIface) MigrateVolume(p *MigrateVolumeParams) (*MigrateVolumeResponse, error) {
 	m.ctrl.T.Helper()
@@ -322,6 +415,20 @@ func (mr *MockVolumeServiceIfaceMockRecorder) NewDeleteVolumeParams(id interface
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteVolumeParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewDeleteVolumeParams), id)
 }
 
+// NewDestroyVolumeParams mocks base method.
+func (m *MockVolumeServiceIface) NewDestroyVolumeParams(id string) *DestroyVolumeParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewDestroyVolumeParams", id)
+	ret0, _ := ret[0].(*DestroyVolumeParams)
+	return ret0
+}
+
+// NewDestroyVolumeParams indicates an expected call of NewDestroyVolumeParams.
+func (mr *MockVolumeServiceIfaceMockRecorder) NewDestroyVolumeParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDestroyVolumeParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewDestroyVolumeParams), id)
+}
+
 // NewDetachVolumeParams mocks base method.
 func (m *MockVolumeServiceIface) NewDetachVolumeParams() *DetachVolumeParams {
 	m.ctrl.T.Helper()
@@ -406,6 +513,20 @@ func (mr *MockVolumeServiceIfaceMockRecorder) NewGetVolumeiScsiNameParams(volume
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewGetVolumeiScsiNameParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewGetVolumeiScsiNameParams), volumeid)
 }
 
+// NewListVolumesMetricsParams mocks base method.
+func (m *MockVolumeServiceIface) NewListVolumesMetricsParams() *ListVolumesMetricsParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewListVolumesMetricsParams")
+	ret0, _ := ret[0].(*ListVolumesMetricsParams)
+	return ret0
+}
+
+// NewListVolumesMetricsParams indicates an expected call of NewListVolumesMetricsParams.
+func (mr *MockVolumeServiceIfaceMockRecorder) NewListVolumesMetricsParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListVolumesMetricsParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewListVolumesMetricsParams))
+}
+
 // NewListVolumesParams mocks base method.
 func (m *MockVolumeServiceIface) NewListVolumesParams() *ListVolumesParams {
 	m.ctrl.T.Helper()
@@ -434,6 +555,20 @@ func (mr *MockVolumeServiceIfaceMockRecorder) NewMigrateVolumeParams(storageid,
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewMigrateVolumeParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewMigrateVolumeParams), storageid, volumeid)
 }
 
+// NewRecoverVolumeParams mocks base method.
+func (m *MockVolumeServiceIface) NewRecoverVolumeParams(id string) *RecoverVolumeParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewRecoverVolumeParams", id)
+	ret0, _ := ret[0].(*RecoverVolumeParams)
+	return ret0
+}
+
+// NewRecoverVolumeParams indicates an expected call of NewRecoverVolumeParams.
+func (mr *MockVolumeServiceIfaceMockRecorder) NewRecoverVolumeParams(id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRecoverVolumeParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewRecoverVolumeParams), id)
+}
+
 // NewResizeVolumeParams mocks base method.
 func (m *MockVolumeServiceIface) NewResizeVolumeParams(id string) *ResizeVolumeParams {
 	m.ctrl.T.Helper()
@@ -476,6 +611,21 @@ func (mr *MockVolumeServiceIfaceMockRecorder) NewUploadVolumeParams(format, name
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUploadVolumeParams", reflect.TypeOf((*MockVolumeServiceIface)(nil).NewUploadVolumeParams), format, name, url, zoneid)
 }
 
+// RecoverVolume mocks base method.
+func (m *MockVolumeServiceIface) RecoverVolume(p *RecoverVolumeParams) (*RecoverVolumeResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RecoverVolume", p)
+	ret0, _ := ret[0].(*RecoverVolumeResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RecoverVolume indicates an expected call of RecoverVolume.
+func (mr *MockVolumeServiceIfaceMockRecorder) RecoverVolume(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecoverVolume", reflect.TypeOf((*MockVolumeServiceIface)(nil).RecoverVolume), p)
+}
+
 // ResizeVolume mocks base method.
 func (m *MockVolumeServiceIface) ResizeVolume(p *ResizeVolumeParams) (*ResizeVolumeResponse, error) {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/ZoneService.go b/cloudstack/ZoneService.go
index 58c99f5..61367a8 100644
--- a/cloudstack/ZoneService.go
+++ b/cloudstack/ZoneService.go
@@ -49,6 +49,11 @@ type ZoneServiceIface interface {
 	GetZoneID(name string, opts ...OptionFunc) (string, int, error)
 	GetZoneByName(name string, opts ...OptionFunc) (*Zone, int, error)
 	GetZoneByID(id string, opts ...OptionFunc) (*Zone, int, error)
+	ListZonesMetrics(p *ListZonesMetricsParams) (*ListZonesMetricsResponse, error)
+	NewListZonesMetricsParams() *ListZonesMetricsParams
+	GetZonesMetricID(name string, opts ...OptionFunc) (string, int, error)
+	GetZonesMetricByName(name string, opts ...OptionFunc) (*ZonesMetric, int, error)
+	GetZonesMetricByID(id string, opts ...OptionFunc) (*ZonesMetric, int, error)
 	ReleaseDedicatedZone(p *ReleaseDedicatedZoneParams) (*ReleaseDedicatedZoneResponse, error)
 	NewReleaseDedicatedZoneParams(zoneid string) *ReleaseDedicatedZoneParams
 	UpdateZone(p *UpdateZoneParams) (*UpdateZoneResponse, error)
@@ -1489,6 +1494,399 @@ type ZoneCapacity struct {
 	Zonename          string `json:"zonename"`
 }
 
+type ListZonesMetricsParams struct {
+	p map[string]interface{}
+}
+
+func (p *ListZonesMetricsParams) toURLValues() url.Values {
+	u := url.Values{}
+	if p.p == nil {
+		return u
+	}
+	if v, found := p.p["available"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("available", vv)
+	}
+	if v, found := p.p["domainid"]; found {
+		u.Set("domainid", v.(string))
+	}
+	if v, found := p.p["id"]; found {
+		u.Set("id", v.(string))
+	}
+	if v, found := p.p["keyword"]; found {
+		u.Set("keyword", v.(string))
+	}
+	if v, found := p.p["name"]; found {
+		u.Set("name", v.(string))
+	}
+	if v, found := p.p["networktype"]; found {
+		u.Set("networktype", v.(string))
+	}
+	if v, found := p.p["page"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("page", vv)
+	}
+	if v, found := p.p["pagesize"]; found {
+		vv := strconv.Itoa(v.(int))
+		u.Set("pagesize", vv)
+	}
+	if v, found := p.p["showcapacities"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("showcapacities", vv)
+	}
+	if v, found := p.p["showicon"]; found {
+		vv := strconv.FormatBool(v.(bool))
+		u.Set("showicon", vv)
+	}
+	if v, found := p.p["tags"]; found {
+		m := v.(map[string]string)
+		for i, k := range getSortedKeysFromMap(m) {
+			u.Set(fmt.Sprintf("tags[%d].key", i), k)
+			u.Set(fmt.Sprintf("tags[%d].value", i), m[k])
+		}
+	}
+	return u
+}
+
+func (p *ListZonesMetricsParams) SetAvailable(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["available"] = v
+}
+
+func (p *ListZonesMetricsParams) GetAvailable() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["available"].(bool)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetDomainid(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["domainid"] = v
+}
+
+func (p *ListZonesMetricsParams) GetDomainid() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["domainid"].(string)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetId(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["id"] = v
+}
+
+func (p *ListZonesMetricsParams) GetId() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["id"].(string)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetKeyword(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["keyword"] = v
+}
+
+func (p *ListZonesMetricsParams) GetKeyword() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["keyword"].(string)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetName(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["name"] = v
+}
+
+func (p *ListZonesMetricsParams) GetName() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["name"].(string)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetNetworktype(v string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["networktype"] = v
+}
+
+func (p *ListZonesMetricsParams) GetNetworktype() (string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["networktype"].(string)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetPage(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["page"] = v
+}
+
+func (p *ListZonesMetricsParams) GetPage() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["page"].(int)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetPagesize(v int) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["pagesize"] = v
+}
+
+func (p *ListZonesMetricsParams) GetPagesize() (int, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["pagesize"].(int)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetShowcapacities(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["showcapacities"] = v
+}
+
+func (p *ListZonesMetricsParams) GetShowcapacities() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["showcapacities"].(bool)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetShowicon(v bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["showicon"] = v
+}
+
+func (p *ListZonesMetricsParams) GetShowicon() (bool, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["showicon"].(bool)
+	return value, ok
+}
+
+func (p *ListZonesMetricsParams) SetTags(v map[string]string) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	p.p["tags"] = v
+}
+
+func (p *ListZonesMetricsParams) GetTags() (map[string]string, bool) {
+	if p.p == nil {
+		p.p = make(map[string]interface{})
+	}
+	value, ok := p.p["tags"].(map[string]string)
+	return value, ok
+}
+
+// You should always use this function to get a new ListZonesMetricsParams instance,
+// as then you are sure you have configured all required params
+func (s *ZoneService) NewListZonesMetricsParams() *ListZonesMetricsParams {
+	p := &ListZonesMetricsParams{}
+	p.p = make(map[string]interface{})
+	return p
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *ZoneService) GetZonesMetricID(name string, opts ...OptionFunc) (string, int, error) {
+	p := &ListZonesMetricsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["name"] = name
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return "", -1, err
+		}
+	}
+
+	l, err := s.ListZonesMetrics(p)
+	if err != nil {
+		return "", -1, err
+	}
+
+	if l.Count == 0 {
+		return "", l.Count, fmt.Errorf("No match found for %s: %+v", name, l)
+	}
+
+	if l.Count == 1 {
+		return l.ZonesMetrics[0].Id, l.Count, nil
+	}
+
+	if l.Count > 1 {
+		for _, v := range l.ZonesMetrics {
+			if v.Name == name {
+				return v.Id, l.Count, nil
+			}
+		}
+	}
+	return "", l.Count, fmt.Errorf("Could not find an exact match for %s: %+v", name, l)
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *ZoneService) GetZonesMetricByName(name string, opts ...OptionFunc) (*ZonesMetric, int, error) {
+	id, count, err := s.GetZonesMetricID(name, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+
+	r, count, err := s.GetZonesMetricByID(id, opts...)
+	if err != nil {
+		return nil, count, err
+	}
+	return r, count, nil
+}
+
+// This is a courtesy helper function, which in some cases may not work as expected!
+func (s *ZoneService) GetZonesMetricByID(id string, opts ...OptionFunc) (*ZonesMetric, int, error) {
+	p := &ListZonesMetricsParams{}
+	p.p = make(map[string]interface{})
+
+	p.p["id"] = id
+
+	for _, fn := range append(s.cs.options, opts...) {
+		if err := fn(s.cs, p); err != nil {
+			return nil, -1, err
+		}
+	}
+
+	l, err := s.ListZonesMetrics(p)
+	if err != nil {
+		if strings.Contains(err.Error(), fmt.Sprintf(
+			"Invalid parameter id value=%s due to incorrect long value format, "+
+				"or entity does not exist", id)) {
+			return nil, 0, fmt.Errorf("No match found for %s: %+v", id, l)
+		}
+		return nil, -1, err
+	}
+
+	if l.Count == 0 {
+		return nil, l.Count, fmt.Errorf("No match found for %s: %+v", id, l)
+	}
+
+	if l.Count == 1 {
+		return l.ZonesMetrics[0], l.Count, nil
+	}
+	return nil, l.Count, fmt.Errorf("There is more then one result for ZonesMetric UUID: %s!", id)
+}
+
+// Lists zone metrics
+func (s *ZoneService) ListZonesMetrics(p *ListZonesMetricsParams) (*ListZonesMetricsResponse, error) {
+	resp, err := s.cs.newRequest("listZonesMetrics", p.toURLValues())
+	if err != nil {
+		return nil, err
+	}
+
+	var r ListZonesMetricsResponse
+	if err := json.Unmarshal(resp, &r); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+type ListZonesMetricsResponse struct {
+	Count        int            `json:"count"`
+	ZonesMetrics []*ZonesMetric `json:"zonesmetric"`
+}
+
+type ZonesMetric struct {
+	Allocationstate                 string                `json:"allocationstate"`
+	Capacity                        []ZonesMetricCapacity `json:"capacity"`
+	Clusters                        string                `json:"clusters"`
+	Cpuallocated                    string                `json:"cpuallocated"`
+	Cpuallocateddisablethreshold    bool                  `json:"cpuallocateddisablethreshold"`
+	Cpuallocatedthreshold           bool                  `json:"cpuallocatedthreshold"`
+	Cpudisablethreshold             bool                  `json:"cpudisablethreshold"`
+	Cpumaxdeviation                 string                `json:"cpumaxdeviation"`
+	Cputhreshold                    bool                  `json:"cputhreshold"`
+	Cputotal                        string                `json:"cputotal"`
+	Cpuused                         string                `json:"cpuused"`
+	Description                     string                `json:"description"`
+	Dhcpprovider                    string                `json:"dhcpprovider"`
+	Displaytext                     string                `json:"displaytext"`
+	Dns1                            string                `json:"dns1"`
+	Dns2                            string                `json:"dns2"`
+	Domain                          string                `json:"domain"`
+	Domainid                        string                `json:"domainid"`
+	Domainname                      string                `json:"domainname"`
+	Guestcidraddress                string                `json:"guestcidraddress"`
+	Hasannotations                  bool                  `json:"hasannotations"`
+	Icon                            string                `json:"icon"`
+	Id                              string                `json:"id"`
+	Internaldns1                    string                `json:"internaldns1"`
+	Internaldns2                    string                `json:"internaldns2"`
+	Ip6dns1                         string                `json:"ip6dns1"`
+	Ip6dns2                         string                `json:"ip6dns2"`
+	JobID                           string                `json:"jobid"`
+	Jobstatus                       int                   `json:"jobstatus"`
+	Localstorageenabled             bool                  `json:"localstorageenabled"`
+	Memoryallocated                 string                `json:"memoryallocated"`
+	Memoryallocateddisablethreshold bool                  `json:"memoryallocateddisablethreshold"`
+	Memoryallocatedthreshold        bool                  `json:"memoryallocatedthreshold"`
+	Memorydisablethreshold          bool                  `json:"memorydisablethreshold"`
+	Memorymaxdeviation              string                `json:"memorymaxdeviation"`
+	Memorythreshold                 bool                  `json:"memorythreshold"`
+	Memorytotal                     string                `json:"memorytotal"`
+	Memoryused                      string                `json:"memoryused"`
+	Name                            string                `json:"name"`
+	Networktype                     string                `json:"networktype"`
+	Resourcedetails                 map[string]string     `json:"resourcedetails"`
+	Securitygroupsenabled           bool                  `json:"securitygroupsenabled"`
+	State                           string                `json:"state"`
+	Tags                            []Tags                `json:"tags"`
+	Zonetoken                       string                `json:"zonetoken"`
+}
+
+type ZonesMetricCapacity struct {
+	Capacityallocated int64  `json:"capacityallocated"`
+	Capacitytotal     int64  `json:"capacitytotal"`
+	Capacityused      int64  `json:"capacityused"`
+	Clusterid         string `json:"clusterid"`
+	Clustername       string `json:"clustername"`
+	Name              string `json:"name"`
+	Percentused       string `json:"percentused"`
+	Podid             string `json:"podid"`
+	Podname           string `json:"podname"`
+	Type              int    `json:"type"`
+	Zoneid            string `json:"zoneid"`
+	Zonename          string `json:"zonename"`
+}
+
 type ReleaseDedicatedZoneParams struct {
 	p map[string]interface{}
 }
diff --git a/cloudstack/ZoneService_mock.go b/cloudstack/ZoneService_mock.go
index bfd3266..bce6929 100644
--- a/cloudstack/ZoneService_mock.go
+++ b/cloudstack/ZoneService_mock.go
@@ -220,6 +220,69 @@ func (mr *MockZoneServiceIfaceMockRecorder) GetZoneID(name interface{}, opts ...
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZoneID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZoneID), varargs...)
 }
 
+// GetZonesMetricByID mocks base method.
+func (m *MockZoneServiceIface) GetZonesMetricByID(id string, opts ...OptionFunc) (*ZonesMetric, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{id}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetZonesMetricByID", varargs...)
+	ret0, _ := ret[0].(*ZonesMetric)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetZonesMetricByID indicates an expected call of GetZonesMetricByID.
+func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricByID(id interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{id}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricByID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricByID), varargs...)
+}
+
+// GetZonesMetricByName mocks base method.
+func (m *MockZoneServiceIface) GetZonesMetricByName(name string, opts ...OptionFunc) (*ZonesMetric, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetZonesMetricByName", varargs...)
+	ret0, _ := ret[0].(*ZonesMetric)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetZonesMetricByName indicates an expected call of GetZonesMetricByName.
+func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricByName(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricByName", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricByName), varargs...)
+}
+
+// GetZonesMetricID mocks base method.
+func (m *MockZoneServiceIface) GetZonesMetricID(name string, opts ...OptionFunc) (string, int, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{name}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetZonesMetricID", varargs...)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(int)
+	ret2, _ := ret[2].(error)
+	return ret0, ret1, ret2
+}
+
+// GetZonesMetricID indicates an expected call of GetZonesMetricID.
+func (mr *MockZoneServiceIfaceMockRecorder) GetZonesMetricID(name interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{name}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZonesMetricID", reflect.TypeOf((*MockZoneServiceIface)(nil).GetZonesMetricID), varargs...)
+}
+
 // ListDedicatedZones mocks base method.
 func (m *MockZoneServiceIface) ListDedicatedZones(p *ListDedicatedZonesParams) (*ListDedicatedZonesResponse, error) {
 	m.ctrl.T.Helper()
@@ -250,6 +313,21 @@ func (mr *MockZoneServiceIfaceMockRecorder) ListZones(p interface{}) *gomock.Cal
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListZones", reflect.TypeOf((*MockZoneServiceIface)(nil).ListZones), p)
 }
 
+// ListZonesMetrics mocks base method.
+func (m *MockZoneServiceIface) ListZonesMetrics(p *ListZonesMetricsParams) (*ListZonesMetricsResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListZonesMetrics", p)
+	ret0, _ := ret[0].(*ListZonesMetricsResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListZonesMetrics indicates an expected call of ListZonesMetrics.
+func (mr *MockZoneServiceIfaceMockRecorder) ListZonesMetrics(p interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListZonesMetrics", reflect.TypeOf((*MockZoneServiceIface)(nil).ListZonesMetrics), p)
+}
+
 // NewCreateZoneParams mocks base method.
 func (m *MockZoneServiceIface) NewCreateZoneParams(dns1, internaldns1, name, networktype string) *CreateZoneParams {
 	m.ctrl.T.Helper()
@@ -362,6 +440,20 @@ func (mr *MockZoneServiceIfaceMockRecorder) NewListDedicatedZonesParams() *gomoc
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListDedicatedZonesParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListDedicatedZonesParams))
 }
 
+// NewListZonesMetricsParams mocks base method.
+func (m *MockZoneServiceIface) NewListZonesMetricsParams() *ListZonesMetricsParams {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "NewListZonesMetricsParams")
+	ret0, _ := ret[0].(*ListZonesMetricsParams)
+	return ret0
+}
+
+// NewListZonesMetricsParams indicates an expected call of NewListZonesMetricsParams.
+func (mr *MockZoneServiceIfaceMockRecorder) NewListZonesMetricsParams() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListZonesMetricsParams", reflect.TypeOf((*MockZoneServiceIface)(nil).NewListZonesMetricsParams))
+}
+
 // NewListZonesParams mocks base method.
 func (m *MockZoneServiceIface) NewListZonesParams() *ListZonesParams {
 	m.ctrl.T.Helper()
diff --git a/cloudstack/cloudstack.go b/cloudstack/cloudstack.go
index 4933845..fcd6db7 100644
--- a/cloudstack/cloudstack.go
+++ b/cloudstack/cloudstack.go
@@ -104,6 +104,7 @@ type CloudStackClient struct {
 	Address             AddressServiceIface
 	AffinityGroup       AffinityGroupServiceIface
 	Alert               AlertServiceIface
+	Annotation          AnnotationServiceIface
 	Asyncjob            AsyncjobServiceIface
 	Authentication      AuthenticationServiceIface
 	AutoScale           AutoScaleServiceIface
@@ -125,6 +126,7 @@ type CloudStackClient struct {
 	ISO                 ISOServiceIface
 	ImageStore          ImageStoreServiceIface
 	InternalLB          InternalLBServiceIface
+	Kubernetes          KubernetesServiceIface
 	LDAP                LDAPServiceIface
 	Limit               LimitServiceIface
 	LoadBalancer        LoadBalancerServiceIface
@@ -207,6 +209,7 @@ func newClient(apiurl string, apikey string, secret string, async bool, verifyss
 	cs.Address = NewAddressService(cs)
 	cs.AffinityGroup = NewAffinityGroupService(cs)
 	cs.Alert = NewAlertService(cs)
+	cs.Annotation = NewAnnotationService(cs)
 	cs.Asyncjob = NewAsyncjobService(cs)
 	cs.Authentication = NewAuthenticationService(cs)
 	cs.AutoScale = NewAutoScaleService(cs)
@@ -228,6 +231,7 @@ func newClient(apiurl string, apikey string, secret string, async bool, verifyss
 	cs.ISO = NewISOService(cs)
 	cs.ImageStore = NewImageStoreService(cs)
 	cs.InternalLB = NewInternalLBService(cs)
+	cs.Kubernetes = NewKubernetesService(cs)
 	cs.LDAP = NewLDAPService(cs)
 	cs.Limit = NewLimitService(cs)
 	cs.LoadBalancer = NewLoadBalancerService(cs)
@@ -283,6 +287,7 @@ func newMockClient(ctrl *gomock.Controller) *CloudStackClient {
 	cs.Address = NewMockAddressServiceIface(ctrl)
 	cs.AffinityGroup = NewMockAffinityGroupServiceIface(ctrl)
 	cs.Alert = NewMockAlertServiceIface(ctrl)
+	cs.Annotation = NewMockAnnotationServiceIface(ctrl)
 	cs.Asyncjob = NewMockAsyncjobServiceIface(ctrl)
 	cs.Authentication = NewMockAuthenticationServiceIface(ctrl)
 	cs.AutoScale = NewMockAutoScaleServiceIface(ctrl)
@@ -304,6 +309,7 @@ func newMockClient(ctrl *gomock.Controller) *CloudStackClient {
 	cs.ISO = NewMockISOServiceIface(ctrl)
 	cs.ImageStore = NewMockImageStoreServiceIface(ctrl)
 	cs.InternalLB = NewMockInternalLBServiceIface(ctrl)
+	cs.Kubernetes = NewMockKubernetesServiceIface(ctrl)
 	cs.LDAP = NewMockLDAPServiceIface(ctrl)
 	cs.Limit = NewMockLimitServiceIface(ctrl)
 	cs.LoadBalancer = NewMockLoadBalancerServiceIface(ctrl)
@@ -733,6 +739,14 @@ func NewAlertService(cs *CloudStackClient) AlertServiceIface {
 	return &AlertService{cs: cs}
 }
 
+type AnnotationService struct {
+	cs *CloudStackClient
+}
+
+func NewAnnotationService(cs *CloudStackClient) AnnotationServiceIface {
+	return &AnnotationService{cs: cs}
+}
+
 type AsyncjobService struct {
 	cs *CloudStackClient
 }
@@ -901,6 +915,14 @@ func NewInternalLBService(cs *CloudStackClient) InternalLBServiceIface {
 	return &InternalLBService{cs: cs}
 }
 
+type KubernetesService struct {
+	cs *CloudStackClient
+}
+
+func NewKubernetesService(cs *CloudStackClient) KubernetesServiceIface {
+	return &KubernetesService{cs: cs}
+}
+
 type LDAPService struct {
 	cs *CloudStackClient
 }
diff --git a/generate/generate.go b/generate/generate.go
index 5f563ae..c6b6e4e 100644
--- a/generate/generate.go
+++ b/generate/generate.go
@@ -1648,7 +1648,9 @@ func (s *service) generateNewAPICallFunc(a *API) {
 		"LockUser",
 		"RegisterSSHKeyPair",
 		"RegisterUserKeys",
-		"GetUserKeys":
+		"GetUserKeys",
+		"AddAnnotation",
+		"RemoveAnnotation":
 		pn("	if resp, err = getRawValue(resp); err != nil {")
 		pn("		return nil, err")
 		pn("	}")
@@ -2009,6 +2011,9 @@ func mapType(aName string, pName string, pType string) string {
 		if pName == "downloaddetails" || pName == "owner" {
 			return "[]map[string]string"
 		}
+		if pName == "virtualmachines" {
+			return "[]*VirtualMachine"
+		}
 		return "[]string"
 	case "map":
 		if mapRequireList[aName] != nil && mapRequireList[aName][pName] {
diff --git a/generate/layout.go b/generate/layout.go
index c30bd96..a7ec89d 100644
--- a/generate/layout.go
+++ b/generate/layout.go
@@ -200,6 +200,7 @@ var layout = apiInfo{
 		"attachVolume",
 		"createVolume",
 		"deleteVolume",
+		"destroyVolume",
 		"detachVolume",
 		"extractVolume",
 		"getPathForVolume",
@@ -207,7 +208,9 @@ var layout = apiInfo{
 		"getUploadParamsForVolume",
 		"getVolumeiScsiName",
 		"listVolumes",
+		"listVolumesMetrics",
 		"migrateVolume",
+		"recoverVolume",
 		"resizeVolume",
 		"updateVolume",
 		"uploadVolume",
@@ -244,10 +247,8 @@ var layout = apiInfo{
 		"upgradeRouterTemplate",
 	},
 	"AccountService": {
-		"addAccountToProject",
 		"createAccount",
 		"deleteAccount",
-		"deleteAccountFromProject",
 		"disableAccount",
 		"enableAccount",
 		"getSolidFireAccountId",
@@ -267,6 +268,7 @@ var layout = apiInfo{
 		"enableHAForZone",
 		"listDedicatedZones",
 		"listZones",
+		"listZonesMetrics",
 		"releaseDedicatedZone",
 		"updateZone",
 	},
@@ -348,7 +350,11 @@ var layout = apiInfo{
 	},
 	"ProjectService": {
 		"activateProject",
+		"addAccountToProject",
+		"addUserToProject",
 		"createProject",
+		"deleteAccountFromProject",
+		"deleteUserFromProject",
 		"deleteProject",
 		"deleteProjectInvitation",
 		"listProjectInvitations",
@@ -366,6 +372,7 @@ var layout = apiInfo{
 		"deleteStoragePool",
 		"findStoragePoolsForMigration",
 		"listStoragePools",
+		"syncStoragePool",
 		"updateStoragePool",
 	},
 	"NetworkACLService": {
@@ -430,6 +437,7 @@ var layout = apiInfo{
 		"createRolePermission",
 		"deleteRole",
 		"deleteRolePermission",
+		"importRole",
 		"listRolePermissions",
 		"listRoles",
 		"updateRole",
@@ -670,4 +678,24 @@ var layout = apiInfo{
 	"APIDiscoveryService": {
 		"listApis",
 	},
+	"AnnotationService": {
+		"addAnnotation",
+		"listAnnotations",
+		"removeAnnotation",
+		"updateAnnotationVisibility",
+	},
+	"KubernetesService": {
+		"addKubernetesSupportedVersion",
+		"createKubernetesCluster",
+		"deleteKubernetesCluster",
+		"deleteKubernetesSupportedVersion",
+		"getKubernetesClusterConfig",
+		"listKubernetesClusters",
+		"listKubernetesSupportedVersions",
+		"scaleKubernetesCluster",
+		"startKubernetesCluster",
+		"stopKubernetesCluster",
+		"updateKubernetesSupportedVersion",
+		"upgradeKubernetesCluster",
+	},
 }
diff --git a/generate/listApis.json b/generate/listApis.json
index 6081aac..d8b16b6 100644
--- a/generate/listApis.json
+++ b/generate/listApis.json
@@ -6,22 +6,33 @@
       "name": "listResourceIcon",
       "params": [
         {
-          "description": "type of the resource",
+          "description": "list of resources to upload the icon/image for",
           "length": 255,
-          "name": "resourcetype",
+          "name": "resourceids",
           "required": true,
-          "type": "string"
+          "type": "list"
         },
         {
-          "description": "list of resources to upload the icon/image for",
+          "description": "type of the resource",
           "length": 255,
-          "name": "resourceids",
+          "name": "resourcetype",
           "required": true,
-          "type": "list"
+          "type": "string"
         }
       ],
       "related": "",
       "response": [
+        {},
+        {
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
+        },
+        {
+          "description": "base64 representation of resource icon",
+          "name": "base64image",
+          "type": "string"
+        },
         {},
         {
           "description": "the UUID of the latest async job acting on this object",
@@ -33,21 +44,10 @@
           "name": "resourcetype",
           "type": "resourceobjecttype"
         },
-        {},
-        {
-          "description": "base64 representation of resource icon",
-          "name": "base64image",
-          "type": "string"
-        },
         {
           "description": "id of the resource",
           "name": "resourceid",
           "type": "string"
-        },
-        {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
         }
       ],
       "since": "4.16.0.0"
@@ -58,20 +58,21 @@
       "name": "createVPCOffering",
       "params": [
         {
-          "description": "desired service capabilities as part of vpc offering",
+          "description": "the ID of the containing zone(s), null for public offerings",
           "length": 255,
-          "name": "servicecapabilitylist",
+          "name": "zoneid",
+          "related": "createZone,updateZone,listZones,listZones",
           "required": false,
-          "since": "4.4",
-          "type": "map"
+          "since": "4.13",
+          "type": "list"
         },
         {
-          "description": "set to true if the offering is to be enabled during creation. Default is false",
+          "description": "the ID of the containing domain(s), null for public offerings",
           "length": 255,
-          "name": "enable",
+          "name": "domainid",
+          "related": "createDomain,listDomainChildren,listDomains,listDomains,updateDomain",
           "required": false,
-          "since": "4.16",
-          "type": "boolean"
+          "type": "list"
         },
         {
           "description": "the ID of the service offering for the VPC router appliance",
@@ -82,19 +83,11 @@
           "type": "uuid"
         },
         {
-          "description": "the name of the vpc offering",
-          "length": 255,
-          "name": "name",
-          "required": true,
-          "type": "string"
-        },
-        {
-          "description": "the ID of the containing domain(s), null for public offerings",
+          "description": "provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network",
           "length": 255,
-          "name": "domainid",
-          "related": "createDomain,listDomainChildren,listDomains,listDomains,updateDomain",
+          "name": "serviceproviderlist",
           "required": false,
-          "type": "list"
+          "type": "map"
         },
         {
           "description": "services supported by the vpc offering",
@@ -104,20 +97,27 @@
           "type": "list"
         },
         {
-          "description": "the ID of the containing zone(s), null for public offerings",
+          "description": "desired service capabilities as part of vpc offering",
           "length": 255,
-          "name": "zoneid",
-          "related": "createZone,updateZone,listZones,listZones",
+          "name": "servicecapabilitylist",
           "required": false,
-          "since": "4.13",
-          "type": "list"
+          "since": "4.4",
+          "type": "map"
         },
         {
-          "description": "provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network",
+          "description": "set to true if the offering is to be enabled during creation. Default is false",
           "length": 255,
-          "name": "serviceproviderlist",
+          "name": "enable",
           "required": false,
-          "type": "map"
+          "since": "4.16",
+          "type": "boolean"
+        },
+        {
+          "description": "the name of the vpc offering",
+          "length": 255,
+          "name": "name",
+          "required": true,
+          "type": "string"
         },
         {
           "description": "the display text of the vpc offering",
@@ -135,72 +135,50 @@
           "type": "string"
         },
         {
-          "description": "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
-          "name": "domainid",
+          "description": "the domain name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
+          "name": "domain",
           "type": "string"
         },
         {
-          "description": "the zone name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
-          "name": "zone",
+          "description": "the UUID of the latest async job acting on this object",
+          "name": "jobid",
           "type": "string"
         },
         {
-          "description": "the id of the vpc offering",
-          "name": "id",
-          "type": "string"
+          "description": "the date this vpc offering was created",
+          "name": "created",
+          "type": "date"
         },
         {
-          "description": "the domain name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
-          "name": "domain",
+          "description": "the name of the vpc offering",
+          "name": "name",
           "type": "string"
         },
+        {},
+        {},
         {
-          "description": "state of the vpc offering. Can be Disabled/Enabled",
-          "name": "state",
+          "description": "the zone ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
+          "name": "zoneid",
           "type": "string"
         },
-        {},
         {
           "description": "the current status of the latest async job acting on this object",
           "name": "jobstatus",
           "type": "integer"
         },
-        {},
         {
-          "description": "the name of the vpc offering",
-          "name": "name",
+          "description": "state of the vpc offering. Can be Disabled/Enabled",
+          "name": "state",
           "type": "string"
         },
-        {
-          "description": "true if vpc offering is default, false otherwise",
-          "name": "isdefault",
-          "type": "boolean"
-        },
         {
           "description": "the list of supported services",
           "name": "service",
           "response": [
             {
-              "description": "the list of capabilities",
-              "name": "capability",
-              "response": [
-                {
-                  "description": "the capability value",
-                  "name": "value",
-                  "type": "string"
-                },
-                {
-                  "description": "the capability name",
-                  "name": "name",
-                  "type": "string"
-                },
-                {
-                  "description": "can this service capability value can be choosable while creatine network offerings",
-                  "name": "canchooseservicecapability",
-                  "type": "boolean"
-                }
-              ],
-              "type": "list"
+              "description": "the service name",
+              "name": "name",
+              "type": "string"
             },
             {
               "description": "the service provider name",
@@ -211,11 +189,26 @@
                   "name": "canenableindividualservice",
                   "type": "boolean"
                 },
+                {
+                  "description": "the destination physical network",
+                  "name": "destinationphysicalnetworkid",
+                  "type": "string"
+                },
+                {
+                  "description": "state of the network provider",
+                  "name": "state",
+                  "type": "string"
+                },
                 {
                   "description": "the physical network this belongs to",
                   "name": "physicalnetworkid",
                   "type": "string"
                 },
+                {
+                  "description": "uuid of the network provider",
+                  "name": "id",
+                  "type": "string"
+                },
                 {
                   "description": "services for this provider",
                   "name": "servicelist",
@@ -225,57 +218,64 @@
                   "description": "the provider name",
                   "name": "name",
                   "type": "string"
-                },
+                }
+              ],
+              "type": "list"
+            },
+            {
+              "description": "the list of capabilities",
+              "name": "capability",
+              "response": [
                 {
-                  "description": "state of the network provider",
-                  "name": "state",
+                  "description": "the capability value",
+                  "name": "value",
                   "type": "string"
                 },
                 {
-                  "description": "uuid of the network provider",
-                  "name": "id",
-                  "type": "string"
+                  "description": "can this service capability value can be choosable while creatine network offerings",
+                  "name": "canchooseservicecapability",
+                  "type": "boolean"
                 },
                 {
-                  "description": "the destination physical network",
-                  "name": "destinationphysicalnetworkid",
+                  "description": "the capability name",
+                  "name": "name",
                   "type": "string"
                 }
               ],
               "type": "list"
-            },
-            {
-              "description": "the service name",
-              "name": "name",
-              "type": "string"
             }
           ],
           "type": "list"
         },
         {
-          "description": " indicates if the vpc offering supports distributed router for one-hop forwarding",
-          "name": "distributedvpcrouter",
+          "description": "true if vpc offering is default, false otherwise",
+          "name": "isdefault",
           "type": "boolean"
         },
         {
-          "description": " indicated if the offering can support region level vpc",
-          "name": "supportsregionLevelvpc",
+          "description": " indicates if the vpc offering supports distributed router for one-hop forwarding",
+          "name": "distributedvpcrouter",
           "type": "boolean"
         },
         {
-          "description": "the UUID of the latest async job acting on this object",
-          "name": "jobid",
+          "description": "the id of the vpc offering",
+          "name": "id",
           "type": "string"
         },
         {
-          "description": "the date this vpc offering was created",
-          "name": "created",
-          "type": "date"
+          "description": "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
+          "name": "domainid",
+          "type": "string"
         },
         {
-          "description": "the zone ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
-          "name": "zoneid",
+          "description": "the zone name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.",
+          "name": "zone",
           "type": "string"
+        },
+        {
+          "description": " indicated if the offering can support region level vpc",
+          "name": "supportsregionLevelvpc",
+          "type": "boolean"
         }
       ]
     },
@@ -285,9 +285,9 @@
       "name": "createPod",
       "params": [
         {
-          "description": "the name of the Pod",
+          "description": "the gateway for the Pod",
           "length": 255,
-          "name": "name",
+          "name": "gateway",
           "required": true,
           "type": "string"
         },
@@ -298,6 +298,13 @@
           "required": false,
           "type": "string"
         },
+        {
+          "description": "the starting IP address for the Pod",
+          "length": 255,
+          "name": "startip",
+          "required": true,
+          "type": "string"
+        },
         {
           "description": "the netmask for the Pod",
           "length": 255,
@@ -313,16 +320,9 @@
           "type": "string"
         },
         {
-          "description": "the gateway for the Pod",
-          "length": 255,
-          "name": "gateway",
-          "required": true,
-          "type": "string"
-        },
-        {
-          "description": "the starting IP address for the Pod",
+          "description": "the name of the Pod",
           "length": 255,
-          "name": "startip",
+          "name": "name",
           "required": true,
           "type": "string"
         },
@@ -337,50 +337,72 @@
       ],
       "related": "listPods,updatePod,createManagementNetworkIpRange",
       "response": [
+        {},
         {
-          "description": "the Zone ID of the Pod",
-          "name": "zoneid",
-          "type": "string"
-        },
-        {
-          "description": "the netmask of the Pod",
-          "name": "netmask",
-          "type": "string"
+          "description": "the IP ranges for the Pod",
+          "name": "ipranges",
+          "response": [
+            {
+              "description": "the ending IP for the range",
+              "name": "endip",
+              "type": "string"
+            },
+            {
+              "description": "indicates if range is dedicated for CPVM and SSVM",
+              "name": "forsystemvms",
+              "type": "string"
+            },
+            {
+              "description": "indicates Vlan ID for the range",
+              "name": "vlanid",
+              "type": "string"
+            },
+            {
+              "description": "the starting IP for the range",
+              "name": "startip",
+              "type": "string"
+            }
+          ],
+          "type": "list"
         },
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
+          "description": "indicates Vlan ID for the range. This parameter is deprecated, please use 'vlanid' from ipranges parameter.",
+          "name": "vlanid",
+          "type": "list"
         },
         {
-          "description": "the gateway of the Pod",
-          "name": "gateway",
+          "description": "the netmask of the Pod",
+          "name": "netmask",
           "type": "string"
         },
-        {
-          "description": "indicates if range is dedicated for CPVM and SSVM. This parameter is deprecated, please use 'forsystemvms' from ipranges parameter.",
-          "name": "forsystemvms",
-          "type": "list"
-        },
         {
           "description": "true if the entity/resource has annotations",
           "name": "hasannotations",
           "type": "boolean"
         },
-        {},
+        {
+          "description": "the name of the Pod",
+          "name": "name",
+          "type": "string"
+        },
         {
           "description": "the UUID of the latest async job acting on this object",
           "name": "jobid",
           "type": "string"
         },
+        {
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
+        },
         {
           "description": "the capacity of the Pod",
           "name": "capacity",
           "response": [
             {
-              "description": "the capacity type",
-              "name": "type",
-              "type": "short"
+              "description": "the Pod ID",
+              "name": "podid",
+              "type": "string"
             },
             {
               "description": "the Cluster name",
@@ -388,9 +410,9 @@
               "type": "string"
             },
             {
-              "description": "the capacity name",
-              "name": "name",
-              "type": "string"
+              "description": "the total capacity available",
+              "name": "capacitytotal",
+              "type": "long"
             },
             {
               "description": "the capacity currently in allocated",
@@ -398,18 +420,18 @@
               "type": "long"
             },
             {
-              "description": "the Pod name",
-              "name": "podname",
+              "description": "the percentage of capacity currently in use",
+              "name": "percentused",
               "type": "string"
             },
             {
-              "description": "the Zone name",
-              "name": "zonename",
+              "description": "the capacity name",
+              "name": "name",
               "type": "string"
             },
             {
-              "description": "the Zone ID",
-              "name": "zoneid",
+              "description": "the Cluster ID",
+              "name": "clusterid",
               "type": "string"
             },
             {
@@ -418,36 +440,41 @@
               "type": "long"
             },
             {
-              "description": "the percentage of capacity currently in use",
-              "name": "percentused",
+              "description": "the Zone name",
+              "name": "zonename",
               "type": "string"
             },
             {
-              "description": "the Pod ID",
-              "name": "podid",
+              "description": "the Pod name",
+              "name": "podname",
               "type": "string"
             },
             {
-              "description": "the Cluster ID",
-              "name": "clusterid",
-              "type": "string"
+              "description": "the capacity type",
+              "name": "type",
+              "type": "short"
             },
             {
-              "description": "the total capacity available",
-              "name": "capacitytotal",
-              "type": "long"
+              "description": "the Zone ID",
+              "name": "zoneid",
+              "type": "string"
             }
           ],
           "type": "list"
         },
         {
-          "description": "the name of the Pod",
-          "name": "name",
+          "description": "the starting IP for the Pod. This parameter is deprecated, please use 'startip' from ipranges parameter.",
+          "name": "startip",
+          "type": "list"
+        },
+        {
+          "description": "the allocation state of the Pod",
+          "name": "allocationstate",
           "type": "string"
         },
         {
-          "description": "the ID of the Pod",
-          "name": "id",
+          "description": "the gateway of the Pod",
+          "name": "gateway",
           "type": "string"
         },
         {
@@ -455,54 +482,27 @@
           "name": "zonename",
           "type": "string"
         },
-        {},
         {
-          "description": "the allocation state of the Pod",
-          "name": "allocationstate",
+          "description": "the Zone ID of the Pod",
+          "name": "zoneid",
           "type": "string"
         },
         {
-          "description": "the ending IP for the Pod. This parameter is deprecated, please use 'endip' from ipranges parameter.",
-          "name": "endip",
-          "type": "list"
+          "description": "the ID of the Pod",
+          "name": "id",
+          "type": "string"
         },
         {
-          "description": "the starting IP for the Pod. This parameter is deprecated, please use 'startip' from ipranges parameter.",
-          "name": "startip",
+          "description": "the ending IP for the Pod. This parameter is deprecated, please use 'endip' from ipranges parameter.",
+          "name": "endip",
           "type": "list"
         },
         {
-          "description": "the IP ranges for the Pod",
-          "name": "ipranges",
-          "response": [
-            {
-              "description": "the starting IP for the range",
-              "name": "startip",
-              "type": "string"
-            },
-            {
-              "description": "indicates if range is dedicated for CPVM and SSVM",
-              "name": "forsystemvms",
-              "type": "string"
-            },
-            {
-              "description": "indicates Vlan ID for the range",
-              "name": "vlanid",
-              "type": "string"
-            },
-            {
-              "description": "the ending IP for the range",
-              "name": "endip",
-              "type": "string"
-            }
-          ],
+          "description": "indicates if range is dedicated for CPVM and SSVM. This parameter is deprecated, please use 'forsystemvms' from ipranges parameter.",
+          "name": "forsystemvms",
           "type": "list"
         },
-        {
-          "description": "indicates Vlan ID for the range. This parameter is deprecated, please use 'vlanid' from ipranges parameter.",
-          "name": "vlanid",
-          "type": "list"
-        }
+        {}
       ]
     },
     {
@@ -510,6 +510,13 @@
       "isasync": false,
       "name": "ldapCreateAccount",
       "params": [
+        {
+          "description": "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.",
+          "length": 255,
+          "name": "timezone",
+          "required": false,
+          "type": "string"
+        },
         {
           "description": "Network domain for the account's networks",
           "length": 255,
@@ -518,9 +525,9 @@
           "type": "string"
         },
         {
-          "description": "User UUID, required for adding account from external provisioning system",
+          "description": "Account UUID, required for adding account from external provisioning system",
           "length": 255,
-          "name": "userid",
+          "name": "accountid",
           "required": false,
           "type": "string"
         },
@@ -533,32 +540,31 @@
           "type": "uuid"
         },
         {
-          "description": "Creates the user under the specified domain.",
+          "description": "details for account used to store specific parameters",
           "length": 255,
-          "name": "domainid",
-          "related": "createDomain,listDomainChildren,listDomains,listDomains,updateDomain",
+          "name": "accountdetails",
           "required": false,
-          "type": "uuid"
+          "type": "map"
         },
         {
-          "description": "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin",
+          "description": "User UUID, required for adding account from external provisioning system",
           "length": 255,
-          "name": "accounttype",
+          "name": "userid",
           "required": false,
-          "type": "short"
+          "type": "string"
         },
         {
-          "description": "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.",
+          "description": "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin",
           "length": 255,
-          "name": "timezone",
+          "name": "accounttype",
           "required": false,
-          "type": "string"
+          "type": "short"
         },
         {
-          "description": "Account UUID, required for adding account from external provisioning system",
+          "description": "Unique username.",
           "length": 255,
-          "name": "accountid",
-          "required": false,
+          "name": "username",
+          "required": true,
           "type": "string"
         },
         {
@@ -569,188 +575,70 @@
           "type": "string"
         },
         {
-          "description": "details for account used to store specific parameters",
+          "description": "Creates the user under the specified domain.",
           "length": 255,
-          "name": "accountdetails",
+          "name": "domainid",
+          "related": "createDomain,listDomainChildren,listDomains,listDomains,updateDomain",
           "required": false,
-          "type": "map"
-        },
-        {
-          "description": "Unique username.",
-          "length": 255,
-          "name": "username",
-          "required": true,
-          "type": "string"
+          "type": "uuid"
         }
       ],
       "related": "createAccount,disableAccount,enableAccount,lockAccount,updateAccount,markDefaultZoneForAccount,listAccounts,listAccounts",
       "response": [
         {
-          "description": "the total number of network traffic bytes sent",
-          "name": "sentbytes",
-          "type": "long"
+          "description": "path of the Domain the account belongs to",
+          "name": "domainpath",
+          "type": "string"
         },
         {
-          "description": "the total secondary storage space (in GiB) owned by account",
-          "name": "secondarystoragetotal",
-          "type": "float"
+          "description": "the total number of cpu cores available to be created for this account",
+          "name": "cpuavailable",
+          "type": "string"
         },
         {
-          "description": "the total primary storage space (in GiB) available to be used for this account",
-          "name": "primarystorageavailable",
+          "description": "the total number of vpcs available to be created for this account",
+          "name": "vpcavailable",
           "type": "string"
         },
         {
-          "description": "the network domain",
-          "name": "networkdomain",
+          "description": "the total memory (in MB) the account can own",
+          "name": "memorylimit",
           "type": "string"
         },
         {
-          "description": "the list of users associated with account",
-          "name": "user",
-          "response": [
-            {
-              "description": "Base64 string representation of the resource icon",
-              "name": "icon",
-              "type": "resourceiconresponse"
-            },
-            {
-              "description": "the domain name of the user",
-              "name": "domain",
-              "type": "string"
-            },
-            {
-              "description": "the ID of the role",
-              "name": "roleid",
-              "type": "string"
-            },
-            {
-              "description": "the timezone user was created in",
-              "name": "timezone",
-              "type": "string"
-            },
-            {
-              "description": "the user state",
-              "name": "state",
-              "type": "string"
-            },
-            {
-              "description": "the user email address",
-              "name": "email",
-              "type": "string"
-            },
-            {
-              "description": "the domain ID of the user",
-              "name": "domainid",
-              "type": "string"
-            },
-            {
-              "description": "the api key of the user",
-              "name": "apikey",
-              "type": "string"
-            },
-            {
-              "description": "the user ID",
-              "name": "id",
-              "type": "string"
-            },
-            {
-              "description": "the date and time the user account was created",
-              "name": "created",
-              "type": "date"
-            },
-            {
-              "description": "the user name",
-              "name": "username",
-              "type": "string"
-            },
-            {
-              "description": "the account name of the user",
-              "name": "account",
-              "type": "string"
-            },
-            {
-              "description": "the secret key of the user",
-              "name": "secretkey",
-              "type": "string"
-            },
-            {
-              "description": "the source type of the user in lowercase, such as native, ldap, saml2",
-              "name": "usersource",
-              "type": "string"
-            },
-            {
-              "description": "true if user is default, false otherwise",
-              "name": "isdefault",
-              "type": "boolean"
-            },
-            {
-              "description": "the user lastname",
-              "name": "lastname",
-              "type": "string"
-            },
-            {
-              "description": "the boolean value representing if the updating target is in caller's child domain",
-              "name": "iscallerchilddomain",
-              "type": "boolean"
-            },
-            {
-              "description": "the account type of the user",
-              "name": "accounttype",
-              "type": "short"
-            },
-            {
-              "description": "the type of the role",
-              "name": "roletype",
-              "type": "string"
-            },
-            {
-              "description": "the name of the role",
-              "name": "rolename",
-              "type": "string"
-            },
-            {
-              "description": "the account ID of the user",
-              "name": "accountid",
-              "type": "string"
-            },
-            {
-              "description": "the user firstname",
-              "name": "firstname",
-              "type": "string"
-            }
-          ],
-          "type": "list"
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
         },
         {
-          "description": "the total number of networks owned by account",
-          "name": "networktotal",
-          "type": "long"
+          "description": "name of the Domain the account belongs to",
+          "name": "domain",
+          "type": "string"
         },
         {
-          "description": "the total number of networks the account can own",
-          "name": "networklimit",
+          "description": "the total number of projects available for administration by this account",
+          "name": "projectavailable",
           "type": "string"
         },
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
+          "description": "the total number of virtual machines available for this account to acquire",
+          "name": "vmavailable",
+          "type": "string"
         },
         {
-          "description": "the total number of virtual machines deployed by this account",
-          "name": "vmtotal",
+          "description": "the total number of projects being administrated by this account",
+          "name": "projecttotal",
           "type": "long"
         },
         {
-          "description": "the total number of vpcs the account can own",
-          "name": "vpclimit",
+          "description": "the name of the role",
+          "name": "rolename",
           "type": "string"
         },
         {
-          "description": "the total number of cpu cores owned by account",
-          "name": "cputotal",
-          "type": "long"
+          "description": "the date when this account was created",
+          "name": "created",
+          "type": "date"
         },
         {
           "description": "the total number of virtual machines that can be deployed by this account",
@@ -758,88 +646,110 @@
           "type": "string"
         },
         {
-          "description": "name of the Domain the account belongs to",
-          "name": "domain",
+          "description": "the total number of templates which can be created by this account",
+          "name": "templatelimit",
           "type": "string"
         },
         {
-          "description": "the name of the role",
-          "name": "rolename",
+          "description": "the total number of network traffic bytes sent",
+          "name": "sentbytes",
+          "type": "long"
+        },
+        {
+          "description": "the total number of public ip addresses this account can acquire",
+          "name": "iplimit",
           "type": "string"
         },
         {
-          "description": "the total number of vpcs owned by account",
-          "name": "vpctotal",
-          "type": "long"
+          "description": "the total number of public ip addresses available for this account to acquire",
+          "name": "ipavailable",
+          "type": "string"
         },
         {
-          "description": "the total memory (in MB) owned by account",
-          "name": "memorytotal",
+          "description": "the total number of virtual machines deployed by this account",
+          "name": "vmtotal",
           "type": "long"
         },
         {
-          "description": "the total primary storage space (in GiB) the account can own",
-          "name": "primarystoragelimit",
+          "description": "the total number of cpu cores the account can own",
+          "name": "cpulimit",
           "type": "string"
         },
+        {},
         {
-          "description": "true if account is default, false otherwise",
-          "name": "isdefault",
+          "description": "true if the account requires cleanup",
+          "name": "iscleanuprequired",
           "type": "boolean"
         },
         {
-          "description": "path of the Domain the account belongs to",
-          "name": "domainpath",
-          "type": "string"
+          "description": "the total volume being used by this account",
+          "name": "volumetotal",
+          "type": "long"
         },
         {
-          "description": "the total number of projects the account can own",
-          "name": "projectlimit",
+          "description": "the id of the account",
+          "name": "id",
           "type": "string"
         },
         {
-          "description": "the type of the role (Admin, ResourceAdmin, DomainAdmin, User)",
-          "name": "roletype",
+          "description": "the total volume available for this account",
+          "name": "volumeavailable",
           "type": "string"
         },
         {
-          "description": "the total number of projects available for administration by this account",
-          "name": "projectavailable",
+          "description": "the total number of snapshots which can be stored by this account",
+          "name": "snapshotlimit",
           "type": "string"
         },
         {
-          "description": "the date when this account was created",
-          "name": "created",
-          "type": "date"
+          "description": "the total number of networks owned by account",
+          "name": "networktotal",
+          "type": "long"
         },
         {
-          "description": "the state of the account",
-          "name": "state",
+          "description": "id of the Domain the account belongs to",
+          "name": "domainid",
           "type": "string"
         },
         {
-          "description": "details for the account",
-          "name": "accountdetails",
-          "type": "map"
+          "description": "the ID of the role",
+          "name": "roleid",
+          "type": "string"
         },
+        {},
         {
           "description": "the total volume which can be used by this account",
           "name": "volumelimit",
           "type": "string"
         },
-        {
-          "description": "the id of the account",
-          "name": "id",
-          "type": "string"
-        },
         {
           "description": "the list of acl groups that account belongs to",
           "name": "groups",
           "type": "list"
         },
         {
-          "description": "the total volume available for this account",
-          "name": "volumeavailable",
+          "description": "the total number of networks the account can own",
+          "name": "networklimit",
+          "type": "string"
+        },
+        {
+          "description": "the total primary storage space (in GiB) available to be used for this account",
+          "name": "primarystorageavailable",
+          "type": "string"
+        },
+        {
+          "description": "Base64 string representation of the resource icon",
+          "name": "icon",
+          "type": "resourceiconresponse"
+        },
+        {
+          "description": "the default zone of the account",
+          "name": "defaultzoneid",
+          "type": "string"
+        },
+        {
+          "description": "the UUID of the latest async job acting on this object",
+          "name": "jobid",
           "type": "string"
         },
         {
@@ -848,161 +758,251 @@
           "type": "long"
         },
         {
-          "description": "the total number of public ip addresses available for this account to acquire",
-          "name": "ipavailable",
-          "type": "string"
+          "description": "the total memory (in MB) owned by account",
+          "name": "memorytotal",
+          "type": "long"
         },
         {
           "description": "the total number of virtual machines running for this account",
           "name": "vmrunning",
           "type": "integer"
         },
-        {
-          "description": "the total number of templates which can be created by this account",
-          "name": "templatelimit",
-          "type": "string"
-        },
         {
           "description": "the total secondary storage space (in GiB) available to be used for this account",
           "name": "secondarystorageavailable",
           "type": "string"
         },
+        {
+          "description": "account type (admin, domain-admin, user)",
+          "name": "accounttype",
+          "type": "short"
+        },
         {
           "description": "the total number of network traffic bytes received",
           "name": "receivedbytes",
           "type": "long"
         },
         {
-          "description": "the UUID of the latest async job acting on this object",
-          "name": "jobid",
+          "description": "the network domain",
+          "name": "networkdomain",
           "type": "string"
         },
         {
-          "description": "the total number of projects being administrated by this account",
-          "name": "projecttotal",
-          "type": "long"
+          "description": "true if account is default, false otherwise",
+          "name": "isdefault",
+          "type": "boolean"
         },
         {
-          "description": "the total number of snapshots available for this account",
-          "name": "snapshotavailable",
+          "description": "the state of the account",
+          "name": "state",
           "type": "string"
         },
         {
-          "description": "the total number of snapshots stored by this account",
-          "name": "snapshottotal",
-          "type": "long"
+          "description": "the total memory (in MB) available to be created for this account",
+          "name": "memoryavailable",
+          "type": "string"
         },
         {
-          "description": "the total volume being used by this account",
-          "name": "volumetotal",
+          "description": "the total number of templates which have been created by this account",
+          "name": "templatetotal",
           "type": "long"
         },
         {
-          "description": "the ID of the role",
-          "name": "roleid",
+          "description": "the total secondary storage space (in GiB) the account can own",
+          "name": "secondarystoragelimit",
           "type": "string"
         },
         {
-          "description": "the name of the account",
-          "name": "name",
-          "type": "string"
+          "description": "details for the account",
+          "name": "accountdetails",
+          "type": "map"
         },
         {
-          "description": "the total number of virtual machines available for this account to acquire",
-          "name": "vmavailable",
+          "description": "the total number of vpcs the account can own",
+          "name": "vpclimit",
           "type": "string"
         },
         {
-          "description": "the total secondary storage space (in GiB) the account can own",
-          "name": "secondarystoragelimit",
+          "description": "the total primary storage space (in GiB) the account can own",
+          "name": "primarystoragelimit",
           "type": "string"
         },
-        {
-          "description": "Base64 string representation of the resource icon",
-          "name": "icon",
-          "type": "resourceiconresponse"
-        },
-        {
-          "description": "account type (admin, domain-admin, user)",
-          "name": "accounttype",
-          "type": "short"
-        },
         {
           "description": "the total number of public ip addresses allocated for this account",
           "name": "iptotal",
           "type": "long"
         },
         {
-          "description": "the total number of snapshots which can be stored by this account",
-          "name": "snapshotlimit",
-          "type": "string"
+          "description": "the total number of snapshots stored by this account",
+          "name": "snapshottotal",
+          "type": "long"
         },
         {
-          "description": "the total number of templates available to be created by this account",
-          "name": "templateavailable",
-          "type": "string"
+          "description": "the list of users associated with account",
+          "name": "user",
+          "response": [
+            {
+              "description": "the user lastname",
+              "name": "lastname",
+              "type": "string"
+            },
+            {
+              "description": "the secret key of the user",
+              "name": "secretkey",
+              "type": "string"
+            },
+            {
+              "description": "the source type of the user in lowercase, such as native, ldap, saml2",
+              "name": "usersource",
+              "type": "string"
+            },
+            {
+              "description": "the timezone user was created in",
+              "name": "timezone",
+              "type": "string"
+            },
+            {
+              "description": "the account ID of the user",
+              "name": "accountid",
+              "type": "string"
+            },
+            {
+              "description": "the user state",
+              "name": "state",
+              "type": "string"
+            },
+            {
+              "description": "the account type of the user",
+              "name": "accounttype",
+              "type": "short"
+            },
+            {
+              "description": "the user ID",
+              "name": "id",
+              "type": "string"
+            },
+            {
+              "description": "true if user is default, false otherwise",
+              "name": "isdefault",
+              "type": "boolean"
+            },
+            {
+              "description": "the type of the role",
+              "name": "roletype",
+              "type": "string"
+            },
+            {
+              "description": "the api key of the user",
+              "name": "apikey",
+              "type": "string"
+            },
+            {
+              "description": "the domain ID of the user",
+              "name": "domainid",
+              "type": "string"
+            },
+            {
+              "description": "the boolean value representing if the updating target is in caller's child domain",
+              "name": "iscallerchilddomain",
+              "type": "boolean"
+            },
+            {
+              "description": "the user name",
+              "name": "username",
+              "type": "string"
+            },
+            {
+              "description": "the ID of the role",
+              "name": "roleid",
+              "type": "string"
+            },
+            {
+              "description": "the name of the role",
+              "name": "rolename",
+              "type": "string"
+            },
+            {
+              "description": "the account name of the user",
+              "name": "account",
+              "type": "string"
+            },
+            {
+              "description": "the user firstname",
+              "name": "firstname",
+              "type": "string"
+            },
+            {
+              "description": "the user email address",
+              "name": "email",
+              "type": "string"
+            },
+            {
+              "description": "the domain name of the user",
+              "name": "domain",
+              "type": "string"
+            },
+            {
+              "description": "the date and time the user account was created",
+              "name": "created",
+              "type": "date"
+            },
+            {
+              "description": "Base64 string representation of the resource icon",
+              "name": "icon",
+              "type": "resourceiconresponse"
+            }
+          ],
+          "type": "list"
         },
         {
-          "description": "the total memory (in MB) available to be created for this account",
-          "name": "memoryavailable",
+          "description": "the type of the role (Admin, ResourceAdmin, DomainAdmin, User)",
+          "name": "roletype",
           "type": "string"
         },
         {
-          "description": "the total number of cpu cores the account can own",
-          "name": "cpulimit",
+          "description": "the total number of projects the account can own",
+          "name": "projectlimit",
           "type": "string"
         },
         {
-          "description": "the total number of public ip addresses this account can acquire",
-          "name": "iplimit",
-          "type": "string"
+          "description": "the total number of virtual machines stopped for this account",
+          "name": "vmstopped",
+          "type": "integer"
         },
         {
-          "description": "the total number of templates which have been created by this account",
-          "name": "templatetotal",
-          "type": "long"
+          "description": "the total secondary storage space (in GiB) owned by account",
+          "name": "secondarystoragetotal",
+          "type": "float"
         },
         {
-          "description": "the total number of vpcs available to be created for this account",
-          "name": "vpcavailable",
+          "description": "the name of the account",
+          "name": "name",
           "type": "string"
         },
         {
-          "description": "the total number of cpu cores available to be created for this account",
-          "name": "cpuavailable",
+          "description": "the total number of templates available to be created by this account",
+          "name": "templateavailable",
           "type": "string"
         },
         {
-          "description": "the total number of networks available to be created for this account",
-          "name": "networkavailable",
-          "type": "string"
+          "description": "the total number of vpcs owned by account",
+          "name": "vpctotal",
+          "type": "long"
         },
         {
-          "description": "the total memory (in MB) the account can own",
-          "name": "memorylimit",
+          "description": "the total number of snapshots available for this account",
+          "name": "snapshotavailable",
           "type": "string"
         },
         {
-          "description": "the total number of virtual machines stopped for this account",
-          "name": "vmstopped",
-          "type": "integer"
-        },
-        {
-          "description": "true if the account requires cleanup",
-          "name": "iscleanuprequired",
-          "type": "boolean"
-        },
-        {},
-        {
-          "description": "id of the Domain the account belongs to",
-          "name": "domainid",
+          "description": "the total number of networks available to be created for this account",
+          "name": "networkavailable",
           "type": "string"
         },
-        {},
         {
-          "description": "the default zone of the account",
-          "name": "defaultzoneid",
-          "type": "string"
+          "description": "the total number of cpu cores owned by account",
+          "name": "cputotal",
+          "type": "long"
         }
       ],
       "since": "4.2.0"
@@ -1021,23 +1021,23 @@
         }
       ],
       "response": [
-        {},
         {
-          "description": "true if operation is executed successfully",
-          "name": "success",
-          "type": "boolean"
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
         },
-        {},
         {
           "description": "the UUID of the latest async job acting on this object",
           "name": "jobid",
           "type": "string"
         },
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
+          "description": "true if operation is executed successfully",
+          "name": "success",
+          "type": "boolean"
         },
+        {},
+        {},
         {
           "description": "any text associated with the success or failure",
           "name": "displaytext",
@@ -1052,9 +1052,9 @@
       "name": "copyIso",
       "params": [
         {
-          "description": "ID of the zone the template is currently hosted on. If not specified and template is cross-zone, then we will sync this template to region wide image store.",
+          "description": "ID of the zone the template is being copied to.",
           "length": 255,
-          "name": "sourcezoneid",
+          "name": "destzoneid",
           "related": "createZone,updateZone,listZones,listZones",
           "required": false,
           "type": "uuid"
@@ -1076,9 +1076,9 @@
           "type": "uuid"
         },
         {
-          "description": "ID of the zone the template is being copied to.",
+          "description": "ID of the zone the template is currently hosted on. If not specified and template is cross-zone, then we will sync this template to region wide image store.",
           "length": 255,
-          "name": "destzoneid",
+          "name": "sourcezoneid",
           "related": "createZone,updateZone,listZones,listZones",
           "required": false,
           "type": "uuid"
@@ -1087,9 +1087,19 @@
       "related": "prepareTemplate,listIsos,registerIso,updateIso,copyTemplate,createTemplate,listTemplates,registerTemplate,updateTemplate,listTemplates,createTemplate,copyTemplate,registerTemplate,registerIso,copyIso,listIsos",
       "response": [
         {
-          "description": "true if the entity/resource has annotations",
-          "name": "hasannotations",
-          "type": "boolean"
+          "description": "if Datadisk template, then id of the root disk template this template belongs to",
+          "name": "parenttemplateid",
+          "type": "string"
+        },
+        {
+          "description": "the tag of this template",
+          "name": "templatetag",
+          "type": "string"
+        },
+        {
+          "description": "if root disk template, then ids of the datas disk templates this template owns",
+          "name": "childtemplates",
+          "type": "set"
         },
         {
           "description": "the size of the template",
@@ -1097,116 +1107,58 @@
           "type": "long"
         },
         {
-          "description": "the date this template was created",
-          "name": "created",
-          "type": "date"
+          "description": "the type of the template",
+          "name": "templatetype",
+          "type": "string"
         },
         {
-          "description": "the list of resource tags associated",
-          "name": "tags",
-          "response": [
-            {
-              "description": "the account associated with the tag",
-              "name": "account",
-              "type": "string"
-            },
-            {
-              "description": "customer associated with the tag",
-              "name": "customer",
-              "type": "string"
-            },
-            {
-              "description": "id of the resource",
-              "name": "resourceid",
-              "type": "string"
-            },
-            {
-              "description": "the project id the tag belongs to",
-              "name": "projectid",
-              "type": "string"
-            },
-            {
-              "description": "the ID of the domain associated with the tag",
-              "name": "domainid",
-              "type": "string"
-            },
-            {
-              "description": "resource type",
-              "name": "resourcetype",
-              "type": "string"
-            },
-            {
-              "description": "the domain associated with the tag",
-              "name": "domain",
-              "type": "string"
-            },
-            {
-              "description": "tag value",
-              "name": "value",
-              "type": "string"
-            },
-            {
-              "description": "the project name where tag belongs to",
-              "name": "project",
-              "type": "string"
-            },
-            {
-              "description": "tag key name",
-              "name": "key",
-              "type": "string"
-            }
-          ],
-          "type": "set"
-        },
-        {
-          "description": "the name of the secondary storage host for the template",
-          "name": "hostname",
-          "type": "string"
+          "description": "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.",
+          "name": "deployasis",
+          "type": "boolean"
         },
         {
-          "description": "the name of the OS type for this template.",
-          "name": "ostypename",
+          "description": "the project name of the template",
+          "name": "project",
           "type": "string"
         },
         {
-          "description": "checksum of the template",
-          "name": "checksum",
-          "type": "string"
+          "description": "true if template is sshkey enabled, false otherwise",
+          "name": "sshkeyenabled",
+          "type": "boolean"
         },
         {
-          "description": "the status of the template",
-          "name": "status",
-          "type": "string"
+          "description": "true if the template is ready to be deployed from, false otherwise.",
+          "name": "isready",
+          "type": "boolean"
         },
         {
-          "description": "the format of the template.",
-          "name": "format",
-          "type": "imageformat"
+          "description": "KVM Only: true if template is directly downloaded to Primary Storage bypassing Secondary Storage",
+          "name": "directdownload",
+          "type": "boolean"
         },
         {
-          "description": "the tag of this template",
-          "name": "templatetag",
+          "description": "the ID of the OS type for this template.",
+          "name": "ostypeid",
           "type": "string"
         },
-        {},
         {
-          "description": "the project id of the template",
-          "name": "projectid",
+          "description": "the template display text",
+          "name": "displaytext",
           "type": "string"
         },
         {
-          "description": "the type of the template",
-          "name": "templatetype",
+          "description": "the template name",
+          "name": "name",
           "type": "string"
         },
         {
-          "description": "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.",
-          "name": "deployasis",
+          "description": "true if the ISO is bootable, false otherwise",
+          "name": "bootable",
           "type": "boolean"
         },
         {
-          "description": "if Datadisk template, then id of the root disk template this template belongs to",
-          "name": "parenttemplateid",
+          "description": "the ID of the secondary storage host for the template",
+          "name": "hostid",
           "type": "string"
         },
         {
@@ -1215,29 +1167,38 @@
           "type": "boolean"
         },
         {
-          "description": "true if the template is extractable, false otherwise",
-          "name": "isextractable",
+          "description": "the template ID",
+          "name": "id",
+          "type": "string"
+        },
+        {
+          "description": "true if the reset password feature is enabled, false otherwise",
+          "name": "passwordenabled",
           "type": "boolean"
         },
-        {},
         {
-          "description": "the account id to which the template belongs",
-          "name": "accountid",
+          "description": "the project id of the template",
+          "name": "projectid",
           "type": "string"
         },
         {
-          "description": "true if the template is ready to be deployed from, false otherwise.",
-          "name": "isready",
-          "type": "boolean"
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
         },
         {
-          "description": "Lists the download progress of a template across all secondary storages",
-          "name": "downloaddetails",
-          "type": "list"
+          "description": "checksum of the template",
+          "name": "checksum",
+          "type": "string"
         },
         {
-          "description": "the ID of the domain to which the template belongs",
-          "name": "domainid",
+          "description": "true if this template is a featured template, false otherwise",
+          "name": "isfeatured",
+          "type": "boolean"
+        },
+        {
+          "description": "the URL which the template/iso is registered from",
+          "name": "url",
           "type": "string"
         },
         {
@@ -1246,68 +1207,126 @@
           "type": "long"
         },
         {
-          "description": "KVM Only: true if template is directly downloaded to Primary Storage bypassing Secondary Storage",
-          "name": "directdownload",
-          "type": "boolean"
+          "description": "Base64 string representation of the resource icon",
+          "name": "icon",
+          "type": "resourceiconresponse"
         },
         {
-          "description": "true if template is sshkey enabled, false otherwise",
-          "name": "sshkeyenabled",
+          "description": "the processor bit size",
+          "name": "bits",
+          "type": "int"
+        },
+        {
+          "description": "true if the entity/resource has annotations",
+          "name": "hasannotations",
           "type": "boolean"
         },
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
+          "description": "true if the template is extractable, false otherwise",
+          "name": "isextractable",
+          "type": "boolean"
         },
         {
-          "description": "the template name",
-          "name": "name",
+          "description": "the ID of the domain to which the template belongs",
+          "name": "domainid",
           "type": "string"
         },
         {
-          "description": "the template ID",
-          "name": "id",
-          "type": "string"
+          "description": "the date this template was removed",
+          "name": "removed",
+          "type": "date"
         },
         {
-          "description": "the template display text",
-          "name": "displaytext",
-          "type": "string"
+          "description": "the date this template was created",
+          "name": "created",
+          "type": "date"
         },
         {
-          "description": "the template ID of the parent template if present",
-          "name": "sourcetemplateid",
-          "type": "string"
+          "description": "the list of resource tags associated",
+          "name": "tags",
+          "response": [
+            {
+              "description": "resource type",
+              "name": "resourcetype",
+              "type": "string"
+            },
+            {
+              "description": "tag value",
+              "name": "value",
+              "type": "string"
+            },
+            {
+              "description": "id of the resource",
+              "name": "resourceid",
+              "type": "string"
+            },
+            {
+              "description": "the ID of the domain associated with the tag",
+              "name": "domainid",
+              "type": "string"
+            },
+            {
+              "description": "the account associated with the tag",
+              "name": "account",
+              "type": "string"
+            },
+            {
+              "description": "the project name where tag belongs to",
+              "name": "project",
+              "type": "string"
+            },
+            {
+              "description": "the domain associated with the tag",
+              "name": "domain",
+              "type": "string"
+            },
+            {
+              "description": "customer associated with the tag",
+              "name": "customer",
+              "type": "string"
+            },
+            {
+              "description": "tag key name",
+              "name": "key",
+              "type": "string"
+            },
+            {
+              "description": "the project id the tag belongs to",
+              "name": "projectid",
+              "type": "string"
+            }
+          ],
+          "type": "set"
         },
         {
-          "description": "true if this template is a public template, false otherwise",
-          "name": "ispublic",
-          "type": "boolean"
+          "description": "additional key/value details tied with template",
+          "name": "details",
+          "type": "map"
         },
         {
-          "description": "the account name to which the template belongs",
-          "name": "account",
+          "description": "the name of the OS type for this template.",
+          "name": "ostypename",
           "type": "string"
         },
         {
-          "description": "additional key/value details tied with template",
-          "name": "details",
-          "type": "map"
+          "description": "the template ID of the parent template if present",
+          "name": "sourcetemplateid",
+          "type": "string"
         },
         {
-          "description": "true if the reset password feature is enabled, false otherwise",
-          "name": "passwordenabled",
+          "description": "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory",
+          "name": "isdynamicallyscalable",
           "type": "boolean"
         },
+        {},
         {
-          "description": "the UUID of the latest async job acting on this object",
-          "name": "jobid",
+          "description": "the account name to which the template belongs",
+          "name": "account",
           "type": "string"
         },
         {
-          "description": "true if this template is a featured template, false otherwise",
-          "name": "isfeatured",
+          "description": "true if this template is a public template, false otherwise",
+          "name": "ispublic",
           "type": "boolean"
         },
         {
@@ -1316,101 +1335,97 @@
           "type": "string"
         },
         {
-          "description": "the hypervisor on which the template runs",
-          "name": "hypervisor",
+          "description": "the UUID of the latest async job acting on this object",
+          "name": "jobid",
           "type": "string"
         },
+        {
+          "description": "VMware only: additional key/value details tied with deploy-as-is template",
+          "name": "deployasisdetails",
+          "type": "map"
+        },
         {
           "description": "true if template requires HVM enabled, false otherwise",
           "name": "requireshvm",
           "type": "boolean"
         },
-        {
-          "description": "the date this template was removed",
-          "name": "removed",
-          "type": "date"
-        },
-        {
-          "description": "the processor bit size",
-          "name": "bits",
-          "type": "int"
-        },
         {
           "description": "the ID of the zone for this template",
           "name": "zoneid",
           "type": "string"
         },
         {
-          "description": "the ID of the OS type for this template.",
-          "name": "ostypeid",
+          "description": "the hypervisor on which the template runs",
+          "name": "hypervisor",
           "type": "string"
         },
         {
-          "description": "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory",
-          "name": "isdynamicallyscalable",
-          "type": "boolean"
-        },
-        {
-          "description": "Base64 string representation of the resource icon",
-          "name": "icon",
-          "type": "resourceiconresponse"
-        },
-        {
-          "description": "the project name of the template",
-          "name": "project",
+          "description": "the status of the template",
+          "name": "status",
           "type": "string"
         },
         {
-          "description": "VMware only: additional key/value details tied with deploy-as-is template",
-          "name": "deployasisdetails",
-          "type": "map"
-        },
-        {
-          "description": "true if the ISO is bootable, false otherwise",
-          "name": "bootable",
-          "type": "boolean"
-        },
-        {
-          "description": "if root disk template, then ids of the datas disk templates this template owns",
-          "name": "childtemplates",
-          "type": "set"
+          "description": "the account id to which the template belongs",
+          "name": "accountid",
+          "type": "string"
         },
         {
-          "description": "the ID of the secondary storage host for the template",
-          "name": "hostid",
-          "type": "string"
+          "description": "the format of the template.",
+          "name": "format",
+          "type": "imageformat"
         },
+        {},
         {
           "description": "the name of the zone for this template",
           "name": "zonename",
           "type": "string"
         },
         {
-          "description": "the URL which the template/iso is registered from",
-          "name": "url",
+          "description": "Lists the download progress of a template across all secondary storages",
+          "name": "downloaddetails",
+          "type": "list"
+        },
+        {
+          "description": "the name of the secondary storage host for the template",
+          "name": "hostname",
           "type": "string"
         }
       ]
     },
     {
-      "description": "Deletes a autoscale vm profile.",
+      "description": "Issues and propagates client certificate on a connected host/agent using configured CA plugin",
       "isasync": true,
-      "name": "deleteAutoScaleVmProfile",
+      "name": "provisionCertificate",
       "params": [
         {
-          "description": "the ID of the autoscale profile",
+          "description": "Name of the CA service provider, otherwise the default configured provider plugin will be used",
           "length": 255,
-          "name": "id",
-          "related": "createAutoScaleVmProfile,listAutoScaleVmProfiles,updateAutoScaleVmProfile",
+          "name": "provider",
+          "required": false,
+          "type": "string"
+        },
+        {
+          "description": "Whether to attempt reconnection with host/agent after successful deployment of certificate. When option is not provided, configured global setting is used",
+          "length": 255,
+          "name": "reconnect",
+          "required": false,
+          "type": "boolean"
+        },
+        {
+          "description": "The host/agent uuid to which the certificate has to be provisioned (issued and propagated)",
+          "length": 255,
+          "name": "hostid",
+          "related": "addHost,cancelHostMaintenance,cancelHostAsDegraded,declareHostAsDegraded,listHosts,prepareHostForMaintenance,reconnectHost,updateHost,addBaremetalHost,listExternalLoadBalancers",
           "required": true,
           "type": "uuid"
         }
       ],
       "response": [
+        {},
         {
-          "description": "true if operation is executed successfully",
-          "name": "success",
-          "type": "boolean"
+          "description": "any text associated with the success or failure",
+          "name": "displaytext",
+          "type": "string"
         },
         {},
         {
@@ -1424,66 +1439,51 @@
           "type": "string"
         },
         {
-          "description": "any text associated with the success or failure",
-          "name": "displaytext",
-          "type": "string"
-        },
-        {}
-      ]
+          "description": "true if operation is executed successfully",
+          "name": "success",
+          "type": "boolean"
+        }
+      ],
+      "since": "4.11.0"
     },
     {
-      "description": "Issues and propagates client certificate on a connected host/agent using configured CA plugin",
+      "description": "Deletes a autoscale vm profile.",
       "isasync": true,
-      "name": "provisionCertificate",
+      "name": "deleteAutoScaleVmProfile",
       "params": [
         {
-          "description": "Whether to attempt reconnection with host/agent after successful deployment of certificate. When option is not provided, configured global setting is used",
-          "length": 255,
-          "name": "reconnect",
-          "required": false,
-          "type": "boolean"
-        },
-        {
-          "description": "The host/agent uuid to which the certificate has to be provisioned (issued and propagated)",
+          "description": "the ID of the autoscale profile",
           "length": 255,
-          "name": "hostid",
-          "related": "addHost,cancelHostMaintenance,cancelHostAsDegraded,declareHostAsDegraded,listHosts,prepareHostForMaintenance,reconnectHost,updateHost,addBaremetalHost,listExternalLoadBalancers",
+          "name": "id",
+          "related": "createAutoScaleVmProfile,listAutoScaleVmProfiles,updateAutoScaleVmProfile",
           "required": true,
           "type": "uuid"
-        },
-        {
-          "description": "Name of the CA service provider, otherwise the default configured provider plugin will be used",
-          "length": 255,
-          "name": "provider",
-          "required": false,
-          "type": "string"
         }
       ],
       "response": [
-        {},
-        {},
         {
           "description": "true if operation is executed successfully",
           "name": "success",
           "type": "boolean"
         },
+        {},
         {
-          "description": "any text associated with the success or failure",
-          "name": "displaytext",
+          "description": "the UUID of the latest async job acting on this object",
+          "name": "jobid",
           "type": "string"
         },
         {
-          "description": "the UUID of the latest async job acting on this object",
-          "name": "jobid",
+          "description": "any text associated with the success or failure",
+          "name": "displaytext",
           "type": "string"
         },
         {
           "description": "the current status of the latest async job acting on this object",
           "name": "jobstatus",
           "type": "integer"
-        }
-      ],
-      "since": "4.11.0"
+        },
+        {}
+      ]
     },
     {
       "description": "Adds an external firewall appliance",
@@ -1491,11 +1491,12 @@
       "name": "addExternalFirewall",
       "params": [
         {
-          "description": "Password of the external firewall appliance.",
+          "description": "Zone in which to add the external firewall appliance.",
           "length": 255,
-          "name": "password",
+          "name": "zoneid",
+          "related": "createZone,updateZone,listZones,listZones",
           "required": true,
-          "type": "string"
+          "type": "uuid"
         },
         {
           "description": "Username of the external firewall appliance.",
@@ -1505,12 +1506,11 @@
           "type": "string"
         },
         {
-          "description": "Zone in which to add the external firewall appliance.",
+          "description": "Password of the external firewall appliance.",
           "length": 255,
-          "name": "zoneid",
-          "related": "createZone,updateZone,listZones,listZones",
+          "name": "password",
           "required": true,
-          "type": "uuid"
+          "type": "string"
         },
         {
           "description": "URL of the external firewall appliance.",
@@ -1523,13 +1523,13 @@
       "related": "listExternalFirewalls",
       "response": [
         {
-          "description": "the usage interface of the external firewall",
-          "name": "usageinterface",
+          "description": "the management IP address of the external firewall",
+          "name": "ipaddress",
           "type": "string"
         },
         {
-          "description": "the private interface of the external firewall",
-          "name": "privateinterface",
+          "description": "the public security zone of the external firewall",
+          "name": "publiczone",
           "type": "string"
         },
         {
@@ -1538,60 +1538,60 @@
           "type": "string"
         },
         {
-          "description": "the public security zone of the external firewall",
-          "name": "publiczone",
+          "description": "the public interface of the external firewall",
+          "name": "publicinterface",
           "type": "string"
         },
         {
-          "description": "the number of times to retry requests to the external firewall",
-          "name": "numretries",
+          "description": "the private interface of the external firewall",
+          "name": "privateinterface",
           "type": "string"
         },
-        {},
         {
-          "description": "the ID of the network device",
-          "name": "id",
+          "description": "the zone ID of the external firewall",
+          "name": "zoneid",
           "type": "string"
         },
-        {},
+        {
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
+        },
         {
           "description": "the UUID of the latest async job acting on this object",
           "name": "jobid",
           "type": "string"
         },
         {
-          "description": "the public interface of the external firewall",
-          "name": "publicinterface",
+          "description": "the username that's used to log in to the external firewall",
+          "name": "username",
           "type": "string"
         },
         {
-          "description": "the management IP address of the external firewall",
-          "name": "ipaddress",
+          "description": "the number of times to retry requests to the external firewall",
+          "name": "numretries",
           "type": "string"
         },
         {
-          "description": "the private security zone of the external firewall",
-          "name": "privatezone",
+          "description": "the usage interface of the external firewall",
+          "name": "usageinterface",
           "type": "string"
         },
         {
-          "description": "the username that's used to log in to the external firewall",
-          "name": "username",
+          "description": "the ID of the external firewall",
+          "name": "id",
           "type": "string"
         },
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
-        },
-        {
-          "description": "the ID of the external firewall",
-          "name": "id",
+          "description": "the private security zone of the external firewall",
+          "name": "privatezone",
           "type": "string"
         },
+        {},
+        {},
         {
-          "description": "the zone ID of the external firewall",
-          "name": "zoneid",
+          "description": "the ID of the network device",
+          "name": "id",
           "type": "string"
         }
       ]
@@ -1613,13 +1613,8 @@
       "response": [
         {},
         {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
-        },
-        {
-          "description": "any text associated with the success or failure",
-          "name": "displaytext",
+          "description": "the UUID of the latest async job acting on this object",
+          "name": "jobid",
           "type": "string"
         },
         {
@@ -1628,8 +1623,13 @@
           "type": "boolean"
         },
         {
-          "description": "the UUID of the latest async job acting on this object",
-          "name": "jobid",
+          "description": "the current status of the latest async job acting on this object",
+          "name": "jobstatus",
+          "type": "integer"
+        },
+        {
+          "description": "any text associated with the success or failure",
+          "name": "displaytext",
           "type": "string"
         },
         {}
@@ -1641,12 +1641,18 @@
       "name": "listVirtualMachinesMetrics",
       "params": [
         {
-          "description": "list vms by vpc",
+          "description": "comma separated list of host details requested, value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp]. If no parameter is passed in, the details will be defaulted to all",
           "length": 255,
-          "name": "vpcid",
-          "related": "createVPC,listVPCs,updateVPC,createVPC,listVPCs,updateVPC,migrateVPC",
+          "name": "details",
           "required": false,
-          "type": "uuid"
+          "type": "list"
+        },
+        {
+          "description": "the target hypervisor for the template",
+          "length": 255,
+          "name": "hypervisor",
+          "required": false,
+          "type": "string"
         },
         {
           "description": "list only resources belonging to the domain specified",
@@ -1657,112 +1663,118 @@
           "type": "uuid"
         },
         {
-          "description": "list resources by display flag; only ROOT admin is eligible to pass this parameter",
+          "description": "the availability zone ID",
           "length": 255,
-          "name": "displayvm",
+          "name": "zoneid",
+          "related": "createZone,updateZone,listZones,listZones",
           "required": false,
-          "since": "4.4",
-          "type": "boolean"
+          "type": "uuid"
         },
         {
-          "description": "the pod ID",
+          "description": "list vms by iso",
           "length": 255,
-          "name": "podid",
-          "related": "listPods,updatePod,createManagementNetworkIpRange",
+          "name": "isoid",
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "the security group ID",
+          "description": "the user ID that created the VM and is under the account that owns the VM",
           "length": 255,
-          "name": "securitygroupid",
-          "related": "createSecurityGroup,listSecurityGroups,updateSecurityGroup",
+          "name": "userid",
+          "related": "createUser,disableUser,enableUser,getUser,listUsers,lockUser,updateUser",
           "required": false,
-          "since": "4.15",
           "type": "uuid"
         },
         {
-          "description": "the storage ID where vm's volumes belong to",
+          "description": "the ID of the virtual machine",
           "length": 255,
-          "name": "storageid",
-          "related": "cancelStorageMaintenance,createStoragePool,listStoragePools,findStoragePoolsForMigration,enableStorageMaintenance,updateStoragePool,syncStoragePool,updateStorageCapabilities,listVsphereStoragePolicyCompatiblePools",
+          "name": "id",
+          "related": "assignVirtualMachine,migrateVirtualMachine,migrateVirtualMachineWithVolume,recoverVirtualMachine,attachIso,detachIso,addNicToVirtualMachine,deployVirtualMachine,destroyVirtualMachine,listVirtualMachines,scaleVirtualMachine,rebootVirtualMachine,removeNicFromVirtualMachine,resetPasswordForVirtualMachine,resetSSHKeyForVirtualMachine,restoreVirtualMachine,startVirtualMachine,stopVirtualMachine,updateDefaultNicForVirtualMachine,updateVirtualMachine,changeServiceForVirtua [...]
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "List by keyword",
+          "description": "defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves.",
           "length": 255,
-          "name": "keyword",
+          "name": "isrecursive",
           "required": false,
-          "type": "string"
+          "type": "boolean"
         },
         {
-          "description": "the group ID",
+          "description": "the host ID",
           "length": 255,
-          "name": "groupid",
-          "related": "createInstanceGroup,listInstanceGroups,updateInstanceGroup",
+          "name": "hostid",
+          "related": "addHost,cancelHostMaintenance,cancelHostAsDegraded,declareHostAsDegraded,listHosts,prepareHostForMaintenance,reconnectHost,updateHost,addBaremetalHost,listExternalLoadBalancers",
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "list vms by ssh keypair name",
+          "description": "",
           "length": 255,
-          "name": "keypair",
+          "name": "pagesize",
           "required": false,
-          "type": "string"
+          "type": "integer"
         },
         {
-          "description": "the availability zone ID",
+          "description": "list resources by display flag; only ROOT admin is eligible to pass this parameter",
           "length": 255,
-          "name": "zoneid",
-          "related": "createZone,updateZone,listZones,listZones",
+          "name": "displayvm",
           "required": false,
-          "type": "uuid"
+          "since": "4.4",
+          "type": "boolean"
         },
         {
-          "description": "list vms by template",
+          "description": "the security group ID",
           "length": 255,
-          "name": "templateid",
-          "related": "prepareTemplate,listIsos,registerIso,updateIso,copyTemplate,createTemplate,listTemplates,registerTemplate,updateTemplate,listTemplates,createTemplate,copyTemplate,registerTemplate,registerIso,copyIso,listIsos",
+          "name": "securitygroupid",
+          "related": "createSecurityGroup,listSecurityGroups,updateSecurityGroup",
           "required": false,
+          "since": "4.15",
           "type": "uuid"
         },
         {
-          "description": "comma separated list of host details requested, value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp]. If no parameter is passed in, the details will be defaulted to all",
+          "description": "list by network type; true if need to list vms using Virtual Network, false otherwise",
           "length": 255,
-          "name": "details",
+          "name": "forvirtualnetwork",
           "required": false,
-          "type": "list"
+          "type": "boolean"
         },
         {
-          "description": "",
+          "description": "List by keyword",
           "length": 255,
-          "name": "pagesize",
+          "name": "keyword",
           "required": false,
-          "type": "integer"
+          "type": "string"
         },
         {
-          "description": "name of the virtual machine (a substring match is made against the parameter value, data for all matching VMs will be returned)",
+          "description": "the storage ID where vm's volumes belong to",
           "length": 255,
-          "name": "name",
+          "name": "storageid",
+          "related": "cancelStorageMaintenance,createStoragePool,listStoragePools,findStoragePoolsForMigration,enableStorageMaintenance,updateStoragePool,syncStoragePool,updateStorageCapabilities,listVsphereStoragePolicyCompatiblePools",
           "required": false,
-          "type": "string"
+          "type": "uuid"
         },
         {
-          "description": "the IDs of the virtual machines, mutually exclusive with id",
+          "description": "list by network id",
           "length": 255,
-          "name": "ids",
-          "related": "assignVirtualMachine,migrateVirtualMachine,migrateVirtualMachineWithVolume,recoverVirtualMachine,attachIso,detachIso,addNicToVirtualMachine,deployVirtualMachine,destroyVirtualMachine,listVirtualMachines,scaleVirtualMachine,rebootVirtualMachine,removeNicFromVirtualMachine,resetPasswordForVirtualMachine,resetSSHKeyForVirtualMachine,restoreVirtualMachine,startVirtualMachine,stopVirtualMachine,updateDefaultNicForVirtualMachine,updateVirtualMachine,changeServiceForVirtua [...]
+          "name": "networkid",
+          "related": "createNetwork,listNetworks,updateNetwork,createNetwork,updateNetwork,listNetworks,migrateNetwork,listF5LoadBalancerNetworks,listNetscalerLoadBalancerNetworks,listNiciraNvpDeviceNetworks,listPaloAltoFirewallNetworks,listSrxFirewallNetworks,listBrocadeVcsDeviceNetworks",
           "required": false,
-          "since": "4.4",
-          "type": "list"
+          "type": "uuid"
         },
         {
-          "description": "the target hypervisor for the template",
+          "description": "If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false",
           "length": 255,
-          "name": "hypervisor",
+          "name": "listall",
           "required": false,
-          "type": "string"
+          "type": "boolean"
+        },
+        {
+          "description": "",
+          "length": 255,
+          "name": "page",
+          "required": false,
+          "type": "integer"
         },
         {
           "description": "list objects by project",
@@ -1773,20 +1785,19 @@
           "type": "uuid"
         },
         {
-          "description": "list vms by affinity group",
+          "description": "name of the virtual machine (a substring match is made against the parameter value, data for all matching VMs will be returned)",
           "length": 255,
-          "name": "affinitygroupid",
-          "related": "createAffinityGroup,listAffinityGroups",
+          "name": "name",
           "required": false,
-          "type": "uuid"
+          "type": "string"
         },
         {
-          "description": "list by the High Availability offering; true if filtering VMs with HA enabled; false for VMs with HA disabled",
+          "description": "list vms by template",
           "length": 255,
-          "name": "haenable",
+          "name": "templateid",
+          "related": "prepareTemplate,listIsos,registerIso,updateIso,copyTemplate,createTemplate,listTemplates,registerTemplate,updateTemplate,listTemplates,createTemplate,copyTemplate,registerTemplate,registerIso,copyIso,listIsos",
           "required": false,
-          "since": "4.15",
-          "type": "boolean"
+          "type": "uuid"
         },
         {
           "description": "List resources by tags (key/value pairs)",
@@ -1796,41 +1807,53 @@
           "type": "map"
         },
         {
-          "description": "the host ID",
+          "description": "list vms by affinity group",
           "length": 255,
-          "name": "hostid",
-          "related": "addHost,cancelHostMaintenance,cancelHostAsDegraded,declareHostAsDegraded,listHosts,prepareHostForMaintenance,reconnectHost,updateHost,addBaremetalHost,listExternalLoadBalancers",
+          "name": "affinitygroupid",
+          "related": "createAffinityGroup,listAffinityGroups",
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "list vms by iso",
+          "description": "list by the High Availability offering; true if filtering VMs with HA enabled; false for VMs with HA disabled",
           "length": 255,
-          "name": "isoid",
+          "name": "haenable",
+          "required": false,
+          "since": "4.15",
+          "type": "boolean"
+        },
+        {
+          "description": "list vms by vpc",
+          "length": 255,
+          "name": "vpcid",
+          "related": "createVPC,listVPCs,updateVPC,createVPC,listVPCs,updateVPC,migrateVPC",
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "state of the virtual machine. Possible values are: Running, Stopped, Present, Destroyed, Expunged. Present is used for the state equal not destroyed.",
+          "description": "the group ID",
           "length": 255,
-          "name": "state",
+          "name": "groupid",
+          "related": "createInstanceGroup,listInstanceGroups,updateInstanceGroup",
           "required": false,
-          "type": "string"
+          "type": "uuid"
         },
         {
-          "description": "the user ID that created the VM and is under the account that owns the VM",
+          "description": "the pod ID",
           "length": 255,
-          "name": "userid",
-          "related": "createUser,disableUser,enableUser,getUser,listUsers,lockUser,updateUser",
+          "name": "podid",
+          "related": "listPods,updatePod,createManagementNetworkIpRange",
           "required": false,
           "type": "uuid"
         },
         {
-          "description": "",
+          "description": "the IDs of the virtual machines, mutually exclusive with id",
           "length": 255,
-          "name": "page",
+          "name": "ids",
+          "related": "assignVirtualMachine,migrateVirtualMachine,migrateVirtualMachineWithVolume,recoverVirtualMachine,attachIso,detachIso,addNicToVirtualMachine,deployVirtualMachine,destroyVirtualMachine,listVirtualMachines,scaleVirtualMachine,rebootVirtualMachine,removeNicFromVirtualMachine,resetPasswordForVirtualMachine,resetSSHKeyForVirtualMachine,restoreVirtualMachine,startVirtualMachine,stopVirtualMachine,updateDefaultNicForVirtualMachine,updateVirtualMachine,changeServiceForVirtua [...]
           "required": false,
-          "type": "integer"
+          "since": "4.4",
+          "type": "list"
         },
         {
           "description": "flag to display the resource icon for VMs",
@@ -1841,11 +1864,11 @@
           "type": "boolean"
         },
         {
-          "description": "If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false",
+          "description": "state of the virtual machine. Possible values are: Running, Stopped, Present, Destroyed, Expunged. Present is used for the state equal not destroyed.",
           "length": 255,
-          "name": "listall",
+          "name": "state",
           "required": false,
-          "type": "boolean"
+          "type": "string"
         },
         {
           "description": "list resources by account. Must be used with the domainId parameter.",
@@ -1854,21 +1877,6 @@
           "required": false,
           "type": "string"
         },
-        {
-          "description": "defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves.",
-          "length": 255,
-          "name": "isrecursive",
-          "required": false,
-          "type": "boolean"
-        },
-        {
-          "description": "list by network id",
-          "length": 255,
-          "name": "networkid",
-          "related": "createNetwork,listNetworks,updateNetwork,createNetwork,updateNetwork,listNetworks,migrateNetwork,listF5LoadBalancerNetworks,listNetscalerLoadBalancerNetworks,listNiciraNvpDeviceNetworks,listPaloAltoFirewallNetworks,listSrxFirewallNetworks,listBrocadeVcsDeviceNetworks",
-          "required": false,
-          "type": "uuid"
-        },
         {
           "description": "list by the service offering",
           "length": 255,
@@ -1879,112 +1887,190 @@
           "type": "uuid"
         },
         {
-          "description": "list by network type; true if need to list vms using Virtual Network, false otherwise",
-          "length": 255,
-          "name": "forvirtualnetwork",
-          "required": false,
-          "type": "boolean"
-        },
-        {
-          "description": "the ID of the virtual machine",
+          "description": "list vms by ssh keypair name",
           "length": 255,
-          "name": "id",
-          "related": "assignVirtualMachine,migrateVirtualMachine,migrateVirtualMachineWithVolume,recoverVirtualMachine,attachIso,detachIso,addNicToVirtualMachine,deployVirtualMachine,destroyVirtualMachine,listVirtualMachines,scaleVirtualMachine,rebootVirtualMachine,removeNicFromVirtualMachine,resetPasswordForVirtualMachine,resetSSHKeyForVirtualMachine,restoreVirtualMachine,startVirtualMachine,stopVirtualMachine,updateDefaultNicForVirtualMachine,updateVirtualMachine,changeServiceForVirtua [...]
+          "name": "keypair",
           "required": false,
-          "type": "uuid"
+          "type": "string"
         }
       ],
       "related": "",
       "response": [
         {
-          "description": "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.",
-          "name": "templateid",
-          "type": "string"
-        },
-        {
-          "description": "the pool type of the virtual machine",
-          "name": "pooltype",
-          "type": "string"
-        },
-        {
-          "description": "the hypervisor on which the template runs",
-          "name": "hypervisor",
-          "type": "string"
-        },
-        {
-          "description": "the write (io) of disk on the vm",
-          "name": "diskiowrite",
-          "type": "long"
-        },
-        {
-          "description": "the current status of the latest async job acting on this object",
-          "name": "jobstatus",
-          "type": "integer"
-        },
-        {
-          "description": "instance name of the user vm; this parameter is returned to the ROOT admin only",
-          "name": "instancename",
-          "type": "string"
-        },
-        {
-          "description": "the date when this virtual machine was created",
-          "name": "created",
-          "type": "date"
-        },
-        {
-          "description": "the name of the virtual machine",
-          "name": "name",
-          "type": "string"
-        },
-        {
-          "description": "the read (io) of disk on the vm",
-          "name": "diskioread",
-          "type": "long"
-        },
-        {
-          "description": "ssh key-pair",
-          "name": "keypair",
-          "type": "string"
+          "description": "Base64 string representation of the resource icon",
+          "name": "icon",
+          "type": "resourceiconresponse"
         },
         {
-          "description": "the ID of the availablility zone for the virtual machine",
-          "name": "zoneid",
+          "description": "List of read-only Vm details as comma separated string.",
+          "name": "readonlydetails",
           "type": "string"
         },
         {
-          "description": "the vgpu type used by the virtual machine",
-          "name": "vgpu",
-          "type": "string"
+          "description": "the list of nics associated with vm",
+          "name": "nic",
+          "response": [
+            {
+              "description": "the cidr of IPv6 network",
+              "name": "ip6cidr",
+              "type": "string"
+            },
+            {
+              "description": "Id of the NSX Logical Switch (if NSX based), null otherwise",
+              "name": "nsxlogicalswitch",
+              "type": "string"
+            },
+            {
+              "description": "true if nic is default, false otherwise",
+              "name": "macaddress",
+              "type": "string"
+            },
+            {
+              "description": "the name of the corresponding network",
+              "name": "networkname",
+              "type": "string"
+            },
+            {
+              "description": "the broadcast uri of the nic",
+              "name": "broadcasturi",
+              "type": "string"
+            },
+            {
+              "description": "the isolated private VLAN type if available",
+              "name": "isolatedpvlantype",
+              "type": "string"
+            },
+            {
+              "description": "the traffic type of the nic",
+              "name": "traffictype",
+              "type": "string"
+            },
+            {
+              "description": "the netmask of the nic",
+              "name": "netmask",
... 165865 lines suppressed ...