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/19 11:14:28 UTC

[cloudstack-go] branch 4161 updated (a660e87 -> e4e63d1)

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

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


 discard a660e87  cleanup
 discard 7666e92  Updating for 4.16.1
    omit a646d95  Merge branch 'main' of https://github.com/apache/cloudstack-go into autogen-tests
    omit f1ceb5a  Autogenereate tests
    omit 82aeaf7  Decouple tests from autogenerated code
     add ac35fe8  Autogenerate tests (#32)
     new e4e63d1  Updating to 4.16.1

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (a660e87)
            \
             N -- N -- N   refs/heads/4161 (e4e63d1)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Makefile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)


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

Posted by da...@apache.org.
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 e4e63d13806e08d42903812261f89e8513ae5d9d
Author: davidjumani <dj...@gmail.com>
AuthorDate: Tue Apr 19 16:42:23 2022 +0530

    Updating to 4.16.1
---
 Makefile                                           |      6 +-
 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, 65330 insertions(+), 55610 deletions(-)

diff --git a/Makefile b/Makefile
index 3c52362..01def1a 100644
--- a/Makefile
+++ b/Makefile
@@ -11,19 +11,19 @@ endif
 SHELL = /usr/bin/env bash -o pipefail
 .SHELLFLAGS = -ec
 
-all: code mock-gen test
+all: code mocks test
 
 code:
 	go run generate/generate.go generate/layout.go --api=generate/listApis.json
 
 FILES=$(shell for file in `pwd`/cloudstack/*Service.go ;do basename $$file .go ; done)
-mock-gen:
+mocks:
 	@for f in $(FILES); do \
 		$(MOCKGEN) -destination=./cloudstack/$${f}_mock.go -package=cloudstack -copyright_file="header.txt" -source=./cloudstack/$${f}.go ; \
 	done
 
 test:
-	go test -v ./...
+	go test -v 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 0e30601..0ca6a12 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 b50dc62..bdb95a3 100644
--- a/generate/generate.go
+++ b/generate/generate.go
@@ -1622,7 +1622,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("	}")
@@ -1985,6 +1987,9 @@ func mapType(aName string, pName string, pType string) string {
 		} else if pName == "network" {
 			return "[]*Network"
 		}
+		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"
... 165879 lines suppressed ...