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

pearl11594 pushed a commit to branch add-k8s-additional-apis
in repository https://gitbox.apache.org/repos/asf/cloudstack-go.git

commit ac372efaa09316fd06b68584486ab4a51a322a1e
Author: Pearl Dsilva <pearl1...@gmail.com>
AuthorDate: Mon Sep 22 17:09:50 2025 -0400

    Add support to Cni config, Nsx, Netris service management and add 
additional k8s APIs support
---
 cloudstack/ConfigurationService.go      | 775 ++++++++++++++++++++++++++++++++
 cloudstack/ConfigurationService_mock.go | 150 +++++++
 cloudstack/KubernetesService.go         | 368 +++++++++++++++
 cloudstack/KubernetesService_mock.go    |  58 +++
 cloudstack/NetrisService.go             | 507 +++++++++++++++++++++
 cloudstack/NetrisService_mock.go        | 146 ++++++
 cloudstack/NsxService.go                | 534 ++++++++++++++++++++++
 cloudstack/NsxService_mock.go           | 146 ++++++
 cloudstack/cloudstack.go                |  22 +
 generate/layout.go                      |  15 +
 test/ConfigurationService_test.go       |  36 ++
 test/KubernetesService_test.go          |  30 ++
 test/NetrisService_test.go              |  74 +++
 test/NsxService_test.go                 |  74 +++
 14 files changed, 2935 insertions(+)

diff --git a/cloudstack/ConfigurationService.go 
b/cloudstack/ConfigurationService.go
index e5275c0..914322d 100644
--- a/cloudstack/ConfigurationService.go
+++ b/cloudstack/ConfigurationService.go
@@ -21,8 +21,10 @@ package cloudstack
 
 import (
        "encoding/json"
+       "fmt"
        "net/url"
        "strconv"
+       "strings"
 )
 
 type ConfigurationServiceIface interface {
@@ -40,6 +42,15 @@ type ConfigurationServiceIface interface {
        NewResetConfigurationParams(name string) *ResetConfigurationParams
        UpdateStorageCapabilities(p *UpdateStorageCapabilitiesParams) 
(*UpdateStorageCapabilitiesResponse, error)
        NewUpdateStorageCapabilitiesParams(id string) 
*UpdateStorageCapabilitiesParams
+       RegisterCniConfiguration(p *RegisterCniConfigurationParams) 
(*RegisterCniConfigurationResponse, error)
+       NewRegisterCniConfigurationParams(name string) 
*RegisterCniConfigurationParams
+       ListCniConfiguration(p *ListCniConfigurationParams) 
(*ListCniConfigurationResponse, error)
+       NewListCniConfigurationParams() *ListCniConfigurationParams
+       GetCniConfigurationID(name string, opts ...OptionFunc) (string, int, 
error)
+       GetCniConfigurationByName(name string, opts ...OptionFunc) 
(*CniConfiguration, int, error)
+       GetCniConfigurationByID(id string, opts ...OptionFunc) 
(*CniConfiguration, int, error)
+       DeleteCniConfiguration(p *DeleteCniConfigurationParams) 
(*DeleteCniConfigurationResponse, error)
+       NewDeleteCniConfigurationParams(id string) *DeleteCniConfigurationParams
 }
 
 type ListCapabilitiesParams struct {
@@ -1360,3 +1371,767 @@ type UpdateStorageCapabilitiesResponse struct {
        Zoneid               string            `json:"zoneid"`
        Zonename             string            `json:"zonename"`
 }
+
+type RegisterCniConfigurationParams struct {
+       p map[string]interface{}
+}
+
+func (p *RegisterCniConfigurationParams) 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["cniconfig"]; found {
+               u.Set("cniconfig", v.(string))
+       }
+       if v, found := p.p["domainid"]; found {
+               u.Set("domainid", v.(string))
+       }
+       if v, found := p.p["name"]; found {
+               u.Set("name", v.(string))
+       }
+       if v, found := p.p["params"]; found {
+               u.Set("params", v.(string))
+       }
+       if v, found := p.p["projectid"]; found {
+               u.Set("projectid", v.(string))
+       }
+       return u
+}
+
+func (p *RegisterCniConfigurationParams) SetAccount(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["account"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetAccount() {
+       if p.p != nil && p.p["account"] != nil {
+               delete(p.p, "account")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) GetAccount() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["account"].(string)
+       return value, ok
+}
+
+func (p *RegisterCniConfigurationParams) SetCniconfig(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["cniconfig"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetCniconfig() {
+       if p.p != nil && p.p["cniconfig"] != nil {
+               delete(p.p, "cniconfig")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) GetCniconfig() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["cniconfig"].(string)
+       return value, ok
+}
+
+func (p *RegisterCniConfigurationParams) SetDomainid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["domainid"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetDomainid() {
+       if p.p != nil && p.p["domainid"] != nil {
+               delete(p.p, "domainid")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) GetDomainid() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["domainid"].(string)
+       return value, ok
+}
+
+func (p *RegisterCniConfigurationParams) SetName(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["name"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetName() {
+       if p.p != nil && p.p["name"] != nil {
+               delete(p.p, "name")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) GetName() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["name"].(string)
+       return value, ok
+}
+
+func (p *RegisterCniConfigurationParams) SetParams(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["params"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetParams() {
+       if p.p != nil && p.p["params"] != nil {
+               delete(p.p, "params")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) GetParams() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["params"].(string)
+       return value, ok
+}
+
+func (p *RegisterCniConfigurationParams) SetProjectid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["projectid"] = v
+}
+
+func (p *RegisterCniConfigurationParams) ResetProjectid() {
+       if p.p != nil && p.p["projectid"] != nil {
+               delete(p.p, "projectid")
+       }
+}
+
+func (p *RegisterCniConfigurationParams) 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 
RegisterCniConfigurationParams instance,
+// as then you are sure you have configured all required params
+func (s *ConfigurationService) NewRegisterCniConfigurationParams(name string) 
*RegisterCniConfigurationParams {
+       p := &RegisterCniConfigurationParams{}
+       p.p = make(map[string]interface{})
+       p.p["name"] = name
+       return p
+}
+
+// Register a CNI Configuration to be used with CKS cluster
+func (s *ConfigurationService) RegisterCniConfiguration(p 
*RegisterCniConfigurationParams) (*RegisterCniConfigurationResponse, error) {
+       resp, err := s.cs.newPostRequest("registerCniConfiguration", 
p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r RegisterCniConfigurationResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type RegisterCniConfigurationResponse struct {
+       Displaytext string `json:"displaytext"`
+       JobID       string `json:"jobid"`
+       Jobstatus   int    `json:"jobstatus"`
+       Success     bool   `json:"success"`
+}
+
+func (r *RegisterCniConfigurationResponse) UnmarshalJSON(b []byte) error {
+       var m map[string]interface{}
+       err := json.Unmarshal(b, &m)
+       if err != nil {
+               return err
+       }
+
+       if success, ok := m["success"].(string); ok {
+               m["success"] = success == "true"
+               b, err = json.Marshal(m)
+               if err != nil {
+                       return err
+               }
+       }
+
+       if ostypeid, ok := m["ostypeid"].(float64); ok {
+               m["ostypeid"] = strconv.Itoa(int(ostypeid))
+               b, err = json.Marshal(m)
+               if err != nil {
+                       return err
+               }
+       }
+
+       type alias RegisterCniConfigurationResponse
+       return json.Unmarshal(b, (*alias)(r))
+}
+
+type ListCniConfigurationParams struct {
+       p map[string]interface{}
+}
+
+func (p *ListCniConfigurationParams) 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))
+       }
+       return u
+}
+
+func (p *ListCniConfigurationParams) SetAccount(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["account"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetAccount() {
+       if p.p != nil && p.p["account"] != nil {
+               delete(p.p, "account")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetAccount() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["account"].(string)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetDomainid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["domainid"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetDomainid() {
+       if p.p != nil && p.p["domainid"] != nil {
+               delete(p.p, "domainid")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetDomainid() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["domainid"].(string)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetId(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["id"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetId() {
+       if p.p != nil && p.p["id"] != nil {
+               delete(p.p, "id")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetId() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["id"].(string)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetIsrecursive(v bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["isrecursive"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetIsrecursive() {
+       if p.p != nil && p.p["isrecursive"] != nil {
+               delete(p.p, "isrecursive")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetIsrecursive() (bool, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["isrecursive"].(bool)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetKeyword(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["keyword"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetKeyword() {
+       if p.p != nil && p.p["keyword"] != nil {
+               delete(p.p, "keyword")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetKeyword() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["keyword"].(string)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetListall(v bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["listall"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetListall() {
+       if p.p != nil && p.p["listall"] != nil {
+               delete(p.p, "listall")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetListall() (bool, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["listall"].(bool)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetName(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["name"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetName() {
+       if p.p != nil && p.p["name"] != nil {
+               delete(p.p, "name")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetName() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["name"].(string)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetPage(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["page"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetPage() {
+       if p.p != nil && p.p["page"] != nil {
+               delete(p.p, "page")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetPage() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["page"].(int)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetPagesize(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["pagesize"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetPagesize() {
+       if p.p != nil && p.p["pagesize"] != nil {
+               delete(p.p, "pagesize")
+       }
+}
+
+func (p *ListCniConfigurationParams) GetPagesize() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["pagesize"].(int)
+       return value, ok
+}
+
+func (p *ListCniConfigurationParams) SetProjectid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["projectid"] = v
+}
+
+func (p *ListCniConfigurationParams) ResetProjectid() {
+       if p.p != nil && p.p["projectid"] != nil {
+               delete(p.p, "projectid")
+       }
+}
+
+func (p *ListCniConfigurationParams) 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 ListCniConfigurationParams 
instance,
+// as then you are sure you have configured all required params
+func (s *ConfigurationService) NewListCniConfigurationParams() 
*ListCniConfigurationParams {
+       p := &ListCniConfigurationParams{}
+       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 *ConfigurationService) GetCniConfigurationID(name string, opts 
...OptionFunc) (string, int, error) {
+       p := &ListCniConfigurationParams{}
+       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.ListCniConfiguration(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.CniConfiguration[0].Id, l.Count, nil
+       }
+
+       if l.Count > 1 {
+               for _, v := range l.CniConfiguration {
+                       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 *ConfigurationService) GetCniConfigurationByName(name string, opts 
...OptionFunc) (*CniConfiguration, int, error) {
+       id, count, err := s.GetCniConfigurationID(name, opts...)
+       if err != nil {
+               return nil, count, err
+       }
+
+       r, count, err := s.GetCniConfigurationByID(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 *ConfigurationService) GetCniConfigurationByID(id string, opts 
...OptionFunc) (*CniConfiguration, int, error) {
+       p := &ListCniConfigurationParams{}
+       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.ListCniConfiguration(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.CniConfiguration[0], l.Count, nil
+       }
+       return nil, l.Count, fmt.Errorf("There is more then one result for 
CniConfiguration UUID: %s!", id)
+}
+
+// List user data for CNI plugins
+func (s *ConfigurationService) ListCniConfiguration(p 
*ListCniConfigurationParams) (*ListCniConfigurationResponse, error) {
+       resp, err := s.cs.newRequest("listCniConfiguration", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r ListCniConfigurationResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type ListCniConfigurationResponse struct {
+       Count            int                 `json:"count"`
+       CniConfiguration []*CniConfiguration `json:"cniconfiguration"`
+}
+
+type CniConfiguration struct {
+       Account        string `json:"account"`
+       Accountid      string `json:"accountid"`
+       Domain         string `json:"domain"`
+       Domainid       string `json:"domainid"`
+       Domainpath     string `json:"domainpath"`
+       Hasannotations bool   `json:"hasannotations"`
+       Id             string `json:"id"`
+       JobID          string `json:"jobid"`
+       Jobstatus      int    `json:"jobstatus"`
+       Name           string `json:"name"`
+       Params         string `json:"params"`
+       Project        string `json:"project"`
+       Projectid      string `json:"projectid"`
+       Userdata       string `json:"userdata"`
+}
+
+type DeleteCniConfigurationParams struct {
+       p map[string]interface{}
+}
+
+func (p *DeleteCniConfigurationParams) 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["projectid"]; found {
+               u.Set("projectid", v.(string))
+       }
+       return u
+}
+
+func (p *DeleteCniConfigurationParams) SetAccount(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["account"] = v
+}
+
+func (p *DeleteCniConfigurationParams) ResetAccount() {
+       if p.p != nil && p.p["account"] != nil {
+               delete(p.p, "account")
+       }
+}
+
+func (p *DeleteCniConfigurationParams) GetAccount() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["account"].(string)
+       return value, ok
+}
+
+func (p *DeleteCniConfigurationParams) SetDomainid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["domainid"] = v
+}
+
+func (p *DeleteCniConfigurationParams) ResetDomainid() {
+       if p.p != nil && p.p["domainid"] != nil {
+               delete(p.p, "domainid")
+       }
+}
+
+func (p *DeleteCniConfigurationParams) GetDomainid() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["domainid"].(string)
+       return value, ok
+}
+
+func (p *DeleteCniConfigurationParams) SetId(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["id"] = v
+}
+
+func (p *DeleteCniConfigurationParams) ResetId() {
+       if p.p != nil && p.p["id"] != nil {
+               delete(p.p, "id")
+       }
+}
+
+func (p *DeleteCniConfigurationParams) GetId() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["id"].(string)
+       return value, ok
+}
+
+func (p *DeleteCniConfigurationParams) SetProjectid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["projectid"] = v
+}
+
+func (p *DeleteCniConfigurationParams) ResetProjectid() {
+       if p.p != nil && p.p["projectid"] != nil {
+               delete(p.p, "projectid")
+       }
+}
+
+func (p *DeleteCniConfigurationParams) 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 
DeleteCniConfigurationParams instance,
+// as then you are sure you have configured all required params
+func (s *ConfigurationService) NewDeleteCniConfigurationParams(id string) 
*DeleteCniConfigurationParams {
+       p := &DeleteCniConfigurationParams{}
+       p.p = make(map[string]interface{})
+       p.p["id"] = id
+       return p
+}
+
+// Deletes a CNI Configuration
+func (s *ConfigurationService) DeleteCniConfiguration(p 
*DeleteCniConfigurationParams) (*DeleteCniConfigurationResponse, error) {
+       resp, err := s.cs.newPostRequest("deleteCniConfiguration", 
p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r DeleteCniConfigurationResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type DeleteCniConfigurationResponse struct {
+       Displaytext string `json:"displaytext"`
+       JobID       string `json:"jobid"`
+       Jobstatus   int    `json:"jobstatus"`
+       Success     bool   `json:"success"`
+}
+
+func (r *DeleteCniConfigurationResponse) UnmarshalJSON(b []byte) error {
+       var m map[string]interface{}
+       err := json.Unmarshal(b, &m)
+       if err != nil {
+               return err
+       }
+
+       if success, ok := m["success"].(string); ok {
+               m["success"] = success == "true"
+               b, err = json.Marshal(m)
+               if err != nil {
+                       return err
+               }
+       }
+
+       if ostypeid, ok := m["ostypeid"].(float64); ok {
+               m["ostypeid"] = strconv.Itoa(int(ostypeid))
+               b, err = json.Marshal(m)
+               if err != nil {
+                       return err
+               }
+       }
+
+       type alias DeleteCniConfigurationResponse
+       return json.Unmarshal(b, (*alias)(r))
+}
diff --git a/cloudstack/ConfigurationService_mock.go 
b/cloudstack/ConfigurationService_mock.go
index e7efe3e..668403a 100644
--- a/cloudstack/ConfigurationService_mock.go
+++ b/cloudstack/ConfigurationService_mock.go
@@ -58,6 +58,84 @@ func (m *MockConfigurationServiceIface) EXPECT() 
*MockConfigurationServiceIfaceM
        return m.recorder
 }
 
+// DeleteCniConfiguration mocks base method.
+func (m *MockConfigurationServiceIface) DeleteCniConfiguration(p 
*DeleteCniConfigurationParams) (*DeleteCniConfigurationResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "DeleteCniConfiguration", p)
+       ret0, _ := ret[0].(*DeleteCniConfigurationResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// DeleteCniConfiguration indicates an expected call of DeleteCniConfiguration.
+func (mr *MockConfigurationServiceIfaceMockRecorder) DeleteCniConfiguration(p 
any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"DeleteCniConfiguration", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).DeleteCniConfiguration), p)
+}
+
+// GetCniConfigurationByID mocks base method.
+func (m *MockConfigurationServiceIface) GetCniConfigurationByID(id string, 
opts ...OptionFunc) (*CniConfiguration, int, error) {
+       m.ctrl.T.Helper()
+       varargs := []any{id}
+       for _, a := range opts {
+               varargs = append(varargs, a)
+       }
+       ret := m.ctrl.Call(m, "GetCniConfigurationByID", varargs...)
+       ret0, _ := ret[0].(*CniConfiguration)
+       ret1, _ := ret[1].(int)
+       ret2, _ := ret[2].(error)
+       return ret0, ret1, ret2
+}
+
+// GetCniConfigurationByID indicates an expected call of 
GetCniConfigurationByID.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
GetCniConfigurationByID(id any, opts ...any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       varargs := append([]any{id}, opts...)
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"GetCniConfigurationByID", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).GetCniConfigurationByID), 
varargs...)
+}
+
+// GetCniConfigurationByName mocks base method.
+func (m *MockConfigurationServiceIface) GetCniConfigurationByName(name string, 
opts ...OptionFunc) (*CniConfiguration, int, error) {
+       m.ctrl.T.Helper()
+       varargs := []any{name}
+       for _, a := range opts {
+               varargs = append(varargs, a)
+       }
+       ret := m.ctrl.Call(m, "GetCniConfigurationByName", varargs...)
+       ret0, _ := ret[0].(*CniConfiguration)
+       ret1, _ := ret[1].(int)
+       ret2, _ := ret[2].(error)
+       return ret0, ret1, ret2
+}
+
+// GetCniConfigurationByName indicates an expected call of 
GetCniConfigurationByName.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
GetCniConfigurationByName(name any, opts ...any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       varargs := append([]any{name}, opts...)
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"GetCniConfigurationByName", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).GetCniConfigurationByName),
 varargs...)
+}
+
+// GetCniConfigurationID mocks base method.
+func (m *MockConfigurationServiceIface) GetCniConfigurationID(name string, 
opts ...OptionFunc) (string, int, error) {
+       m.ctrl.T.Helper()
+       varargs := []any{name}
+       for _, a := range opts {
+               varargs = append(varargs, a)
+       }
+       ret := m.ctrl.Call(m, "GetCniConfigurationID", varargs...)
+       ret0, _ := ret[0].(string)
+       ret1, _ := ret[1].(int)
+       ret2, _ := ret[2].(error)
+       return ret0, ret1, ret2
+}
+
+// GetCniConfigurationID indicates an expected call of GetCniConfigurationID.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
GetCniConfigurationID(name any, opts ...any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       varargs := append([]any{name}, opts...)
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"GetCniConfigurationID", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).GetCniConfigurationID), 
varargs...)
+}
+
 // ListCapabilities mocks base method.
 func (m *MockConfigurationServiceIface) ListCapabilities(p 
*ListCapabilitiesParams) (*ListCapabilitiesResponse, error) {
        m.ctrl.T.Helper()
@@ -73,6 +151,21 @@ func (mr *MockConfigurationServiceIfaceMockRecorder) 
ListCapabilities(p any) *go
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"ListCapabilities", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).ListCapabilities), p)
 }
 
+// ListCniConfiguration mocks base method.
+func (m *MockConfigurationServiceIface) ListCniConfiguration(p 
*ListCniConfigurationParams) (*ListCniConfigurationResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "ListCniConfiguration", p)
+       ret0, _ := ret[0].(*ListCniConfigurationResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// ListCniConfiguration indicates an expected call of ListCniConfiguration.
+func (mr *MockConfigurationServiceIfaceMockRecorder) ListCniConfiguration(p 
any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"ListCniConfiguration", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).ListCniConfiguration), p)
+}
+
 // ListConfigurationGroups mocks base method.
 func (m *MockConfigurationServiceIface) ListConfigurationGroups(p 
*ListConfigurationGroupsParams) (*ListConfigurationGroupsResponse, error) {
        m.ctrl.T.Helper()
@@ -118,6 +211,20 @@ func (mr *MockConfigurationServiceIfaceMockRecorder) 
ListDeploymentPlanners(p an
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"ListDeploymentPlanners", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).ListDeploymentPlanners), p)
 }
 
+// NewDeleteCniConfigurationParams mocks base method.
+func (m *MockConfigurationServiceIface) NewDeleteCniConfigurationParams(id 
string) *DeleteCniConfigurationParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewDeleteCniConfigurationParams", id)
+       ret0, _ := ret[0].(*DeleteCniConfigurationParams)
+       return ret0
+}
+
+// NewDeleteCniConfigurationParams indicates an expected call of 
NewDeleteCniConfigurationParams.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewDeleteCniConfigurationParams(id any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewDeleteCniConfigurationParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewDeleteCniConfigurationParams),
 id)
+}
+
 // NewListCapabilitiesParams mocks base method.
 func (m *MockConfigurationServiceIface) NewListCapabilitiesParams() 
*ListCapabilitiesParams {
        m.ctrl.T.Helper()
@@ -132,6 +239,20 @@ func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewListCapabilitiesParams()
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListCapabilitiesParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewListCapabilitiesParams))
 }
 
+// NewListCniConfigurationParams mocks base method.
+func (m *MockConfigurationServiceIface) NewListCniConfigurationParams() 
*ListCniConfigurationParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewListCniConfigurationParams")
+       ret0, _ := ret[0].(*ListCniConfigurationParams)
+       return ret0
+}
+
+// NewListCniConfigurationParams indicates an expected call of 
NewListCniConfigurationParams.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewListCniConfigurationParams() *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListCniConfigurationParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewListCniConfigurationParams))
+}
+
 // NewListConfigurationGroupsParams mocks base method.
 func (m *MockConfigurationServiceIface) NewListConfigurationGroupsParams() 
*ListConfigurationGroupsParams {
        m.ctrl.T.Helper()
@@ -174,6 +295,20 @@ func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewListDeploymentPlannersPa
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListDeploymentPlannersParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewListDeploymentPlannersParams))
 }
 
+// NewRegisterCniConfigurationParams mocks base method.
+func (m *MockConfigurationServiceIface) NewRegisterCniConfigurationParams(name 
string) *RegisterCniConfigurationParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewRegisterCniConfigurationParams", name)
+       ret0, _ := ret[0].(*RegisterCniConfigurationParams)
+       return ret0
+}
+
+// NewRegisterCniConfigurationParams indicates an expected call of 
NewRegisterCniConfigurationParams.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewRegisterCniConfigurationParams(name any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewRegisterCniConfigurationParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewRegisterCniConfigurationParams),
 name)
+}
+
 // NewResetConfigurationParams mocks base method.
 func (m *MockConfigurationServiceIface) NewResetConfigurationParams(name 
string) *ResetConfigurationParams {
        m.ctrl.T.Helper()
@@ -216,6 +351,21 @@ func (mr *MockConfigurationServiceIfaceMockRecorder) 
NewUpdateStorageCapabilitie
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewUpdateStorageCapabilitiesParams", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).NewUpdateStorageCapabilitiesParams),
 id)
 }
 
+// RegisterCniConfiguration mocks base method.
+func (m *MockConfigurationServiceIface) RegisterCniConfiguration(p 
*RegisterCniConfigurationParams) (*RegisterCniConfigurationResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "RegisterCniConfiguration", p)
+       ret0, _ := ret[0].(*RegisterCniConfigurationResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// RegisterCniConfiguration indicates an expected call of 
RegisterCniConfiguration.
+func (mr *MockConfigurationServiceIfaceMockRecorder) 
RegisterCniConfiguration(p any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"RegisterCniConfiguration", 
reflect.TypeOf((*MockConfigurationServiceIface)(nil).RegisterCniConfiguration), 
p)
+}
+
 // ResetConfiguration mocks base method.
 func (m *MockConfigurationServiceIface) ResetConfiguration(p 
*ResetConfigurationParams) (*ResetConfigurationResponse, error) {
        m.ctrl.T.Helper()
diff --git a/cloudstack/KubernetesService.go b/cloudstack/KubernetesService.go
index 35064e2..373ec6c 100644
--- a/cloudstack/KubernetesService.go
+++ b/cloudstack/KubernetesService.go
@@ -62,6 +62,10 @@ type KubernetesServiceIface interface {
        NewAddVirtualMachinesToKubernetesClusterParams(id string, 
virtualmachineids []string) *AddVirtualMachinesToKubernetesClusterParams
        RemoveVirtualMachinesFromKubernetesCluster(p 
*RemoveVirtualMachinesFromKubernetesClusterParams) 
(*RemoveVirtualMachinesFromKubernetesClusterResponse, error)
        NewRemoveVirtualMachinesFromKubernetesClusterParams(id string, 
virtualmachineids []string) *RemoveVirtualMachinesFromKubernetesClusterParams
+       AddNodesToKubernetesCluster(p *AddNodesToKubernetesClusterParams) 
(*AddNodesToKubernetesClusterResponse, error)
+       NewAddNodesToKubernetesClusterParams(id string, nodeids []string) 
*AddNodesToKubernetesClusterParams
+       RemoveNodesFromKubernetesCluster(p 
*RemoveNodesFromKubernetesClusterParams) 
(*RemoveNodesFromKubernetesClusterResponse, error)
+       NewRemoveNodesFromKubernetesClusterParams(id string, nodeids []string) 
*RemoveNodesFromKubernetesClusterParams
 }
 
 type AddKubernetesSupportedVersionParams struct {
@@ -3309,3 +3313,367 @@ func (r 
*RemoveVirtualMachinesFromKubernetesClusterResponse) UnmarshalJSON(b []b
        type alias RemoveVirtualMachinesFromKubernetesClusterResponse
        return json.Unmarshal(b, (*alias)(r))
 }
+
+type AddNodesToKubernetesClusterParams struct {
+       p map[string]interface{}
+}
+
+func (p *AddNodesToKubernetesClusterParams) 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["manualupgrade"]; found {
+               vv := strconv.FormatBool(v.(bool))
+               u.Set("manualupgrade", vv)
+       }
+       if v, found := p.p["mountcksisoonvr"]; found {
+               vv := strconv.FormatBool(v.(bool))
+               u.Set("mountcksisoonvr", vv)
+       }
+       if v, found := p.p["nodeids"]; found {
+               vv := strings.Join(v.([]string), ",")
+               u.Set("nodeids", vv)
+       }
+       return u
+}
+
+func (p *AddNodesToKubernetesClusterParams) SetId(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["id"] = v
+}
+
+func (p *AddNodesToKubernetesClusterParams) ResetId() {
+       if p.p != nil && p.p["id"] != nil {
+               delete(p.p, "id")
+       }
+}
+
+func (p *AddNodesToKubernetesClusterParams) GetId() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["id"].(string)
+       return value, ok
+}
+
+func (p *AddNodesToKubernetesClusterParams) SetManualupgrade(v bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["manualupgrade"] = v
+}
+
+func (p *AddNodesToKubernetesClusterParams) ResetManualupgrade() {
+       if p.p != nil && p.p["manualupgrade"] != nil {
+               delete(p.p, "manualupgrade")
+       }
+}
+
+func (p *AddNodesToKubernetesClusterParams) GetManualupgrade() (bool, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["manualupgrade"].(bool)
+       return value, ok
+}
+
+func (p *AddNodesToKubernetesClusterParams) SetMountcksisoonvr(v bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["mountcksisoonvr"] = v
+}
+
+func (p *AddNodesToKubernetesClusterParams) ResetMountcksisoonvr() {
+       if p.p != nil && p.p["mountcksisoonvr"] != nil {
+               delete(p.p, "mountcksisoonvr")
+       }
+}
+
+func (p *AddNodesToKubernetesClusterParams) GetMountcksisoonvr() (bool, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["mountcksisoonvr"].(bool)
+       return value, ok
+}
+
+func (p *AddNodesToKubernetesClusterParams) SetNodeids(v []string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["nodeids"] = v
+}
+
+func (p *AddNodesToKubernetesClusterParams) ResetNodeids() {
+       if p.p != nil && p.p["nodeids"] != nil {
+               delete(p.p, "nodeids")
+       }
+}
+
+func (p *AddNodesToKubernetesClusterParams) GetNodeids() ([]string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["nodeids"].([]string)
+       return value, ok
+}
+
+// You should always use this function to get a new 
AddNodesToKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewAddNodesToKubernetesClusterParams(id string, 
nodeids []string) *AddNodesToKubernetesClusterParams {
+       p := &AddNodesToKubernetesClusterParams{}
+       p.p = make(map[string]interface{})
+       p.p["id"] = id
+       p.p["nodeids"] = nodeids
+       return p
+}
+
+// Add nodes as workers to an existing CKS cluster.
+func (s *KubernetesService) AddNodesToKubernetesCluster(p 
*AddNodesToKubernetesClusterParams) (*AddNodesToKubernetesClusterResponse, 
error) {
+       resp, err := s.cs.newPostRequest("addNodesToKubernetesCluster", 
p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r AddNodesToKubernetesClusterResponse
+       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 AddNodesToKubernetesClusterResponse struct {
+       Account               string            `json:"account"`
+       Associatednetworkname string            `json:"associatednetworkname"`
+       Autoscalingenabled    bool              `json:"autoscalingenabled"`
+       Clustertype           string            `json:"clustertype"`
+       Cniconfigname         string            `json:"cniconfigname"`
+       Cniconfigurationid    string            `json:"cniconfigurationid"`
+       Consoleendpoint       string            `json:"consoleendpoint"`
+       Controlnodes          int64             `json:"controlnodes"`
+       Controlofferingid     string            `json:"controlofferingid"`
+       Controlofferingname   string            `json:"controlofferingname"`
+       Cpunumber             string            `json:"cpunumber"`
+       Created               string            `json:"created"`
+       Description           string            `json:"description"`
+       Domain                string            `json:"domain"`
+       Domainid              string            `json:"domainid"`
+       Domainpath            string            `json:"domainpath"`
+       Endpoint              string            `json:"endpoint"`
+       Etcdips               map[string]string `json:"etcdips"`
+       Etcdnodes             int64             `json:"etcdnodes"`
+       Etcdofferingid        string            `json:"etcdofferingid"`
+       Etcdofferingname      string            `json:"etcdofferingname"`
+       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"`
+       Workerofferingid      string            `json:"workerofferingid"`
+       Workerofferingname    string            `json:"workerofferingname"`
+       Zoneid                string            `json:"zoneid"`
+       Zonename              string            `json:"zonename"`
+}
+
+type RemoveNodesFromKubernetesClusterParams struct {
+       p map[string]interface{}
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) 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["nodeids"]; found {
+               vv := strings.Join(v.([]string), ",")
+               u.Set("nodeids", vv)
+       }
+       return u
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) SetId(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["id"] = v
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) ResetId() {
+       if p.p != nil && p.p["id"] != nil {
+               delete(p.p, "id")
+       }
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) GetId() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["id"].(string)
+       return value, ok
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) SetNodeids(v []string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["nodeids"] = v
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) ResetNodeids() {
+       if p.p != nil && p.p["nodeids"] != nil {
+               delete(p.p, "nodeids")
+       }
+}
+
+func (p *RemoveNodesFromKubernetesClusterParams) GetNodeids() ([]string, bool) 
{
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["nodeids"].([]string)
+       return value, ok
+}
+
+// You should always use this function to get a new 
RemoveNodesFromKubernetesClusterParams instance,
+// as then you are sure you have configured all required params
+func (s *KubernetesService) NewRemoveNodesFromKubernetesClusterParams(id 
string, nodeids []string) *RemoveNodesFromKubernetesClusterParams {
+       p := &RemoveNodesFromKubernetesClusterParams{}
+       p.p = make(map[string]interface{})
+       p.p["id"] = id
+       p.p["nodeids"] = nodeids
+       return p
+}
+
+// Removes external nodes from a CKS cluster.
+func (s *KubernetesService) RemoveNodesFromKubernetesCluster(p 
*RemoveNodesFromKubernetesClusterParams) 
(*RemoveNodesFromKubernetesClusterResponse, error) {
+       resp, err := s.cs.newPostRequest("removeNodesFromKubernetesCluster", 
p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r RemoveNodesFromKubernetesClusterResponse
+       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 RemoveNodesFromKubernetesClusterResponse struct {
+       Account               string            `json:"account"`
+       Associatednetworkname string            `json:"associatednetworkname"`
+       Autoscalingenabled    bool              `json:"autoscalingenabled"`
+       Clustertype           string            `json:"clustertype"`
+       Cniconfigname         string            `json:"cniconfigname"`
+       Cniconfigurationid    string            `json:"cniconfigurationid"`
+       Consoleendpoint       string            `json:"consoleendpoint"`
+       Controlnodes          int64             `json:"controlnodes"`
+       Controlofferingid     string            `json:"controlofferingid"`
+       Controlofferingname   string            `json:"controlofferingname"`
+       Cpunumber             string            `json:"cpunumber"`
+       Created               string            `json:"created"`
+       Description           string            `json:"description"`
+       Domain                string            `json:"domain"`
+       Domainid              string            `json:"domainid"`
+       Domainpath            string            `json:"domainpath"`
+       Endpoint              string            `json:"endpoint"`
+       Etcdips               map[string]string `json:"etcdips"`
+       Etcdnodes             int64             `json:"etcdnodes"`
+       Etcdofferingid        string            `json:"etcdofferingid"`
+       Etcdofferingname      string            `json:"etcdofferingname"`
+       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"`
+       Workerofferingid      string            `json:"workerofferingid"`
+       Workerofferingname    string            `json:"workerofferingname"`
+       Zoneid                string            `json:"zoneid"`
+       Zonename              string            `json:"zonename"`
+}
diff --git a/cloudstack/KubernetesService_mock.go 
b/cloudstack/KubernetesService_mock.go
index 645f25b..65dea25 100644
--- a/cloudstack/KubernetesService_mock.go
+++ b/cloudstack/KubernetesService_mock.go
@@ -73,6 +73,21 @@ func (mr *MockKubernetesServiceIfaceMockRecorder) 
AddKubernetesSupportedVersion(
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"AddKubernetesSupportedVersion", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).AddKubernetesSupportedVersion),
 p)
 }
 
+// AddNodesToKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) AddNodesToKubernetesCluster(p 
*AddNodesToKubernetesClusterParams) (*AddNodesToKubernetesClusterResponse, 
error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "AddNodesToKubernetesCluster", p)
+       ret0, _ := ret[0].(*AddNodesToKubernetesClusterResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// AddNodesToKubernetesCluster indicates an expected call of 
AddNodesToKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) 
AddNodesToKubernetesCluster(p any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"AddNodesToKubernetesCluster", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).AddNodesToKubernetesCluster), 
p)
+}
+
 // AddVirtualMachinesToKubernetesCluster mocks base method.
 func (m *MockKubernetesServiceIface) AddVirtualMachinesToKubernetesCluster(p 
*AddVirtualMachinesToKubernetesClusterParams) 
(*AddVirtualMachinesToKubernetesClusterResponse, error) {
        m.ctrl.T.Helper()
@@ -318,6 +333,20 @@ func (mr *MockKubernetesServiceIfaceMockRecorder) 
NewAddKubernetesSupportedVersi
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewAddKubernetesSupportedVersionParams", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewAddKubernetesSupportedVersionParams),
 mincpunumber, minmemory, semanticversion)
 }
 
+// NewAddNodesToKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) NewAddNodesToKubernetesClusterParams(id 
string, nodeids []string) *AddNodesToKubernetesClusterParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewAddNodesToKubernetesClusterParams", id, 
nodeids)
+       ret0, _ := ret[0].(*AddNodesToKubernetesClusterParams)
+       return ret0
+}
+
+// NewAddNodesToKubernetesClusterParams indicates an expected call of 
NewAddNodesToKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) 
NewAddNodesToKubernetesClusterParams(id, nodeids any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewAddNodesToKubernetesClusterParams", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewAddNodesToKubernetesClusterParams),
 id, nodeids)
+}
+
 // NewAddVirtualMachinesToKubernetesClusterParams mocks base method.
 func (m *MockKubernetesServiceIface) 
NewAddVirtualMachinesToKubernetesClusterParams(id string, virtualmachineids 
[]string) *AddVirtualMachinesToKubernetesClusterParams {
        m.ctrl.T.Helper()
@@ -416,6 +445,20 @@ func (mr *MockKubernetesServiceIfaceMockRecorder) 
NewListKubernetesSupportedVers
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListKubernetesSupportedVersionsParams", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewListKubernetesSupportedVersionsParams))
 }
 
+// NewRemoveNodesFromKubernetesClusterParams mocks base method.
+func (m *MockKubernetesServiceIface) 
NewRemoveNodesFromKubernetesClusterParams(id string, nodeids []string) 
*RemoveNodesFromKubernetesClusterParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewRemoveNodesFromKubernetesClusterParams", id, 
nodeids)
+       ret0, _ := ret[0].(*RemoveNodesFromKubernetesClusterParams)
+       return ret0
+}
+
+// NewRemoveNodesFromKubernetesClusterParams indicates an expected call of 
NewRemoveNodesFromKubernetesClusterParams.
+func (mr *MockKubernetesServiceIfaceMockRecorder) 
NewRemoveNodesFromKubernetesClusterParams(id, nodeids any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewRemoveNodesFromKubernetesClusterParams", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewRemoveNodesFromKubernetesClusterParams),
 id, nodeids)
+}
+
 // NewRemoveVirtualMachinesFromKubernetesClusterParams mocks base method.
 func (m *MockKubernetesServiceIface) 
NewRemoveVirtualMachinesFromKubernetesClusterParams(id string, 
virtualmachineids []string) *RemoveVirtualMachinesFromKubernetesClusterParams {
        m.ctrl.T.Helper()
@@ -500,6 +543,21 @@ func (mr *MockKubernetesServiceIfaceMockRecorder) 
NewUpgradeKubernetesClusterPar
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewUpgradeKubernetesClusterParams", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).NewUpgradeKubernetesClusterParams),
 id, kubernetesversionid)
 }
 
+// RemoveNodesFromKubernetesCluster mocks base method.
+func (m *MockKubernetesServiceIface) RemoveNodesFromKubernetesCluster(p 
*RemoveNodesFromKubernetesClusterParams) 
(*RemoveNodesFromKubernetesClusterResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "RemoveNodesFromKubernetesCluster", p)
+       ret0, _ := ret[0].(*RemoveNodesFromKubernetesClusterResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// RemoveNodesFromKubernetesCluster indicates an expected call of 
RemoveNodesFromKubernetesCluster.
+func (mr *MockKubernetesServiceIfaceMockRecorder) 
RemoveNodesFromKubernetesCluster(p any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"RemoveNodesFromKubernetesCluster", 
reflect.TypeOf((*MockKubernetesServiceIface)(nil).RemoveNodesFromKubernetesCluster),
 p)
+}
+
 // RemoveVirtualMachinesFromKubernetesCluster mocks base method.
 func (m *MockKubernetesServiceIface) 
RemoveVirtualMachinesFromKubernetesCluster(p 
*RemoveVirtualMachinesFromKubernetesClusterParams) 
(*RemoveVirtualMachinesFromKubernetesClusterResponse, error) {
        m.ctrl.T.Helper()
diff --git a/cloudstack/NetrisService.go b/cloudstack/NetrisService.go
new file mode 100644
index 0000000..6e63cdc
--- /dev/null
+++ b/cloudstack/NetrisService.go
@@ -0,0 +1,507 @@
+//
+// 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"
+       "net/url"
+       "strconv"
+)
+
+type NetrisServiceIface interface {
+       AddNetrisProvider(p *AddNetrisProviderParams) 
(*AddNetrisProviderResponse, error)
+       NewAddNetrisProviderParams(name string, netristag string, netrisurl 
string, password string, sitename string, tenantname string, username string, 
zoneid string) *AddNetrisProviderParams
+       DeleteNetrisProvider(p *DeleteNetrisProviderParams) 
(*DeleteNetrisProviderResponse, error)
+       NewDeleteNetrisProviderParams(id string) *DeleteNetrisProviderParams
+       ListNetrisProviders(p *ListNetrisProvidersParams) 
(*ListNetrisProvidersResponse, error)
+       NewListNetrisProvidersParams() *ListNetrisProvidersParams
+}
+
+type AddNetrisProviderParams struct {
+       p map[string]interface{}
+}
+
+func (p *AddNetrisProviderParams) toURLValues() url.Values {
+       u := url.Values{}
+       if p.p == nil {
+               return u
+       }
+       if v, found := p.p["name"]; found {
+               u.Set("name", v.(string))
+       }
+       if v, found := p.p["netristag"]; found {
+               u.Set("netristag", v.(string))
+       }
+       if v, found := p.p["netrisurl"]; found {
+               u.Set("netrisurl", v.(string))
+       }
+       if v, found := p.p["password"]; found {
+               u.Set("password", v.(string))
+       }
+       if v, found := p.p["sitename"]; found {
+               u.Set("sitename", v.(string))
+       }
+       if v, found := p.p["tenantname"]; found {
+               u.Set("tenantname", v.(string))
+       }
+       if v, found := p.p["username"]; found {
+               u.Set("username", v.(string))
+       }
+       if v, found := p.p["zoneid"]; found {
+               u.Set("zoneid", v.(string))
+       }
+       return u
+}
+
+func (p *AddNetrisProviderParams) SetName(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["name"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetName() {
+       if p.p != nil && p.p["name"] != nil {
+               delete(p.p, "name")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetName() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["name"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetNetristag(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["netristag"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetNetristag() {
+       if p.p != nil && p.p["netristag"] != nil {
+               delete(p.p, "netristag")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetNetristag() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["netristag"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetNetrisurl(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["netrisurl"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetNetrisurl() {
+       if p.p != nil && p.p["netrisurl"] != nil {
+               delete(p.p, "netrisurl")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetNetrisurl() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["netrisurl"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetPassword(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["password"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetPassword() {
+       if p.p != nil && p.p["password"] != nil {
+               delete(p.p, "password")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetPassword() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["password"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetSitename(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["sitename"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetSitename() {
+       if p.p != nil && p.p["sitename"] != nil {
+               delete(p.p, "sitename")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetSitename() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["sitename"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetTenantname(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["tenantname"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetTenantname() {
+       if p.p != nil && p.p["tenantname"] != nil {
+               delete(p.p, "tenantname")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetTenantname() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["tenantname"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetUsername(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["username"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetUsername() {
+       if p.p != nil && p.p["username"] != nil {
+               delete(p.p, "username")
+       }
+}
+
+func (p *AddNetrisProviderParams) GetUsername() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["username"].(string)
+       return value, ok
+}
+
+func (p *AddNetrisProviderParams) SetZoneid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["zoneid"] = v
+}
+
+func (p *AddNetrisProviderParams) ResetZoneid() {
+       if p.p != nil && p.p["zoneid"] != nil {
+               delete(p.p, "zoneid")
+       }
+}
+
+func (p *AddNetrisProviderParams) 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 AddNetrisProviderParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NetrisService) NewAddNetrisProviderParams(name string, netristag 
string, netrisurl string, password string, sitename string, tenantname string, 
username string, zoneid string) *AddNetrisProviderParams {
+       p := &AddNetrisProviderParams{}
+       p.p = make(map[string]interface{})
+       p.p["name"] = name
+       p.p["netristag"] = netristag
+       p.p["netrisurl"] = netrisurl
+       p.p["password"] = password
+       p.p["sitename"] = sitename
+       p.p["tenantname"] = tenantname
+       p.p["username"] = username
+       p.p["zoneid"] = zoneid
+       return p
+}
+
+// Add Netris Provider to CloudStack
+func (s *NetrisService) AddNetrisProvider(p *AddNetrisProviderParams) 
(*AddNetrisProviderResponse, error) {
+       resp, err := s.cs.newPostRequest("addNetrisProvider", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r AddNetrisProviderResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type AddNetrisProviderResponse struct {
+       JobID      string `json:"jobid"`
+       Jobstatus  int    `json:"jobstatus"`
+       Name       string `json:"name"`
+       Netristag  string `json:"netristag"`
+       Netrisurl  string `json:"netrisurl"`
+       Sitename   string `json:"sitename"`
+       Tenantname string `json:"tenantname"`
+       Uuid       string `json:"uuid"`
+       Zoneid     string `json:"zoneid"`
+       Zonename   string `json:"zonename"`
+}
+
+type DeleteNetrisProviderParams struct {
+       p map[string]interface{}
+}
+
+func (p *DeleteNetrisProviderParams) 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 *DeleteNetrisProviderParams) SetId(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["id"] = v
+}
+
+func (p *DeleteNetrisProviderParams) ResetId() {
+       if p.p != nil && p.p["id"] != nil {
+               delete(p.p, "id")
+       }
+}
+
+func (p *DeleteNetrisProviderParams) 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 DeleteNetrisProviderParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NetrisService) NewDeleteNetrisProviderParams(id string) 
*DeleteNetrisProviderParams {
+       p := &DeleteNetrisProviderParams{}
+       p.p = make(map[string]interface{})
+       p.p["id"] = id
+       return p
+}
+
+// delete Netris Provider to CloudStack
+func (s *NetrisService) DeleteNetrisProvider(p *DeleteNetrisProviderParams) 
(*DeleteNetrisProviderResponse, error) {
+       resp, err := s.cs.newPostRequest("deleteNetrisProvider", 
p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r DeleteNetrisProviderResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type DeleteNetrisProviderResponse struct {
+       JobID      string `json:"jobid"`
+       Jobstatus  int    `json:"jobstatus"`
+       Name       string `json:"name"`
+       Netristag  string `json:"netristag"`
+       Netrisurl  string `json:"netrisurl"`
+       Sitename   string `json:"sitename"`
+       Tenantname string `json:"tenantname"`
+       Uuid       string `json:"uuid"`
+       Zoneid     string `json:"zoneid"`
+       Zonename   string `json:"zonename"`
+}
+
+type ListNetrisProvidersParams struct {
+       p map[string]interface{}
+}
+
+func (p *ListNetrisProvidersParams) toURLValues() url.Values {
+       u := url.Values{}
+       if p.p == nil {
+               return u
+       }
+       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["zoneid"]; found {
+               u.Set("zoneid", v.(string))
+       }
+       return u
+}
+
+func (p *ListNetrisProvidersParams) SetKeyword(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["keyword"] = v
+}
+
+func (p *ListNetrisProvidersParams) ResetKeyword() {
+       if p.p != nil && p.p["keyword"] != nil {
+               delete(p.p, "keyword")
+       }
+}
+
+func (p *ListNetrisProvidersParams) GetKeyword() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["keyword"].(string)
+       return value, ok
+}
+
+func (p *ListNetrisProvidersParams) SetPage(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["page"] = v
+}
+
+func (p *ListNetrisProvidersParams) ResetPage() {
+       if p.p != nil && p.p["page"] != nil {
+               delete(p.p, "page")
+       }
+}
+
+func (p *ListNetrisProvidersParams) GetPage() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["page"].(int)
+       return value, ok
+}
+
+func (p *ListNetrisProvidersParams) SetPagesize(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["pagesize"] = v
+}
+
+func (p *ListNetrisProvidersParams) ResetPagesize() {
+       if p.p != nil && p.p["pagesize"] != nil {
+               delete(p.p, "pagesize")
+       }
+}
+
+func (p *ListNetrisProvidersParams) GetPagesize() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["pagesize"].(int)
+       return value, ok
+}
+
+func (p *ListNetrisProvidersParams) SetZoneid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["zoneid"] = v
+}
+
+func (p *ListNetrisProvidersParams) ResetZoneid() {
+       if p.p != nil && p.p["zoneid"] != nil {
+               delete(p.p, "zoneid")
+       }
+}
+
+func (p *ListNetrisProvidersParams) 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 ListNetrisProvidersParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NetrisService) NewListNetrisProvidersParams() 
*ListNetrisProvidersParams {
+       p := &ListNetrisProvidersParams{}
+       p.p = make(map[string]interface{})
+       return p
+}
+
+// list all Netris providers added to CloudStack
+func (s *NetrisService) ListNetrisProviders(p *ListNetrisProvidersParams) 
(*ListNetrisProvidersResponse, error) {
+       resp, err := s.cs.newRequest("listNetrisProviders", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r ListNetrisProvidersResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type ListNetrisProvidersResponse struct {
+       Count           int               `json:"count"`
+       NetrisProviders []*NetrisProvider `json:"netrisprovider"`
+}
+
+type NetrisProvider struct {
+       JobID      string `json:"jobid"`
+       Jobstatus  int    `json:"jobstatus"`
+       Name       string `json:"name"`
+       Netristag  string `json:"netristag"`
+       Netrisurl  string `json:"netrisurl"`
+       Sitename   string `json:"sitename"`
+       Tenantname string `json:"tenantname"`
+       Uuid       string `json:"uuid"`
+       Zoneid     string `json:"zoneid"`
+       Zonename   string `json:"zonename"`
+}
diff --git a/cloudstack/NetrisService_mock.go b/cloudstack/NetrisService_mock.go
new file mode 100644
index 0000000..2f1ea84
--- /dev/null
+++ b/cloudstack/NetrisService_mock.go
@@ -0,0 +1,146 @@
+//
+// 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/NetrisService.go
+//
+// Generated by this command:
+//
+//     mockgen -destination=./cloudstack/NetrisService_mock.go 
-package=cloudstack -copyright_file=header.txt 
-source=./cloudstack/NetrisService.go
+//
+
+// Package cloudstack is a generated GoMock package.
+package cloudstack
+
+import (
+       reflect "reflect"
+
+       gomock "go.uber.org/mock/gomock"
+)
+
+// MockNetrisServiceIface is a mock of NetrisServiceIface interface.
+type MockNetrisServiceIface struct {
+       ctrl     *gomock.Controller
+       recorder *MockNetrisServiceIfaceMockRecorder
+       isgomock struct{}
+}
+
+// MockNetrisServiceIfaceMockRecorder is the mock recorder for 
MockNetrisServiceIface.
+type MockNetrisServiceIfaceMockRecorder struct {
+       mock *MockNetrisServiceIface
+}
+
+// NewMockNetrisServiceIface creates a new mock instance.
+func NewMockNetrisServiceIface(ctrl *gomock.Controller) 
*MockNetrisServiceIface {
+       mock := &MockNetrisServiceIface{ctrl: ctrl}
+       mock.recorder = &MockNetrisServiceIfaceMockRecorder{mock}
+       return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockNetrisServiceIface) EXPECT() *MockNetrisServiceIfaceMockRecorder {
+       return m.recorder
+}
+
+// AddNetrisProvider mocks base method.
+func (m *MockNetrisServiceIface) AddNetrisProvider(p *AddNetrisProviderParams) 
(*AddNetrisProviderResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "AddNetrisProvider", p)
+       ret0, _ := ret[0].(*AddNetrisProviderResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// AddNetrisProvider indicates an expected call of AddNetrisProvider.
+func (mr *MockNetrisServiceIfaceMockRecorder) AddNetrisProvider(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"AddNetrisProvider", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).AddNetrisProvider), p)
+}
+
+// DeleteNetrisProvider mocks base method.
+func (m *MockNetrisServiceIface) DeleteNetrisProvider(p 
*DeleteNetrisProviderParams) (*DeleteNetrisProviderResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "DeleteNetrisProvider", p)
+       ret0, _ := ret[0].(*DeleteNetrisProviderResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// DeleteNetrisProvider indicates an expected call of DeleteNetrisProvider.
+func (mr *MockNetrisServiceIfaceMockRecorder) DeleteNetrisProvider(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"DeleteNetrisProvider", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).DeleteNetrisProvider), p)
+}
+
+// ListNetrisProviders mocks base method.
+func (m *MockNetrisServiceIface) ListNetrisProviders(p 
*ListNetrisProvidersParams) (*ListNetrisProvidersResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "ListNetrisProviders", p)
+       ret0, _ := ret[0].(*ListNetrisProvidersResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// ListNetrisProviders indicates an expected call of ListNetrisProviders.
+func (mr *MockNetrisServiceIfaceMockRecorder) ListNetrisProviders(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"ListNetrisProviders", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).ListNetrisProviders), p)
+}
+
+// NewAddNetrisProviderParams mocks base method.
+func (m *MockNetrisServiceIface) NewAddNetrisProviderParams(name, netristag, 
netrisurl, password, sitename, tenantname, username, zoneid string) 
*AddNetrisProviderParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewAddNetrisProviderParams", name, netristag, 
netrisurl, password, sitename, tenantname, username, zoneid)
+       ret0, _ := ret[0].(*AddNetrisProviderParams)
+       return ret0
+}
+
+// NewAddNetrisProviderParams indicates an expected call of 
NewAddNetrisProviderParams.
+func (mr *MockNetrisServiceIfaceMockRecorder) NewAddNetrisProviderParams(name, 
netristag, netrisurl, password, sitename, tenantname, username, zoneid any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewAddNetrisProviderParams", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).NewAddNetrisProviderParams), 
name, netristag, netrisurl, password, sitename, tenantname, username, zoneid)
+}
+
+// NewDeleteNetrisProviderParams mocks base method.
+func (m *MockNetrisServiceIface) NewDeleteNetrisProviderParams(id string) 
*DeleteNetrisProviderParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewDeleteNetrisProviderParams", id)
+       ret0, _ := ret[0].(*DeleteNetrisProviderParams)
+       return ret0
+}
+
+// NewDeleteNetrisProviderParams indicates an expected call of 
NewDeleteNetrisProviderParams.
+func (mr *MockNetrisServiceIfaceMockRecorder) NewDeleteNetrisProviderParams(id 
any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewDeleteNetrisProviderParams", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).NewDeleteNetrisProviderParams), 
id)
+}
+
+// NewListNetrisProvidersParams mocks base method.
+func (m *MockNetrisServiceIface) NewListNetrisProvidersParams() 
*ListNetrisProvidersParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewListNetrisProvidersParams")
+       ret0, _ := ret[0].(*ListNetrisProvidersParams)
+       return ret0
+}
+
+// NewListNetrisProvidersParams indicates an expected call of 
NewListNetrisProvidersParams.
+func (mr *MockNetrisServiceIfaceMockRecorder) NewListNetrisProvidersParams() 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListNetrisProvidersParams", 
reflect.TypeOf((*MockNetrisServiceIface)(nil).NewListNetrisProvidersParams))
+}
diff --git a/cloudstack/NsxService.go b/cloudstack/NsxService.go
new file mode 100644
index 0000000..f87bb1c
--- /dev/null
+++ b/cloudstack/NsxService.go
@@ -0,0 +1,534 @@
+//
+// 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"
+       "net/url"
+       "strconv"
+)
+
+type NsxServiceIface interface {
+       AddNsxController(p *AddNsxControllerParams) (*AddNsxControllerResponse, 
error)
+       NewAddNsxControllerParams(edgecluster string, name string, 
nsxproviderhostname string, password string, tier0gateway string, transportzone 
string, username string, zoneid string) *AddNsxControllerParams
+       DeleteNsxController(p *DeleteNsxControllerParams) 
(*DeleteNsxControllerResponse, error)
+       NewDeleteNsxControllerParams(nsxcontrollerid string) 
*DeleteNsxControllerParams
+       ListNsxControllers(p *ListNsxControllersParams) 
(*ListNsxControllersResponse, error)
+       NewListNsxControllersParams() *ListNsxControllersParams
+}
+
+type AddNsxControllerParams struct {
+       p map[string]interface{}
+}
+
+func (p *AddNsxControllerParams) toURLValues() url.Values {
+       u := url.Values{}
+       if p.p == nil {
+               return u
+       }
+       if v, found := p.p["edgecluster"]; found {
+               u.Set("edgecluster", v.(string))
+       }
+       if v, found := p.p["name"]; found {
+               u.Set("name", v.(string))
+       }
+       if v, found := p.p["nsxproviderhostname"]; found {
+               u.Set("nsxproviderhostname", v.(string))
+       }
+       if v, found := p.p["nsxproviderport"]; found {
+               u.Set("nsxproviderport", v.(string))
+       }
+       if v, found := p.p["password"]; found {
+               u.Set("password", v.(string))
+       }
+       if v, found := p.p["tier0gateway"]; found {
+               u.Set("tier0gateway", v.(string))
+       }
+       if v, found := p.p["transportzone"]; found {
+               u.Set("transportzone", v.(string))
+       }
+       if v, found := p.p["username"]; found {
+               u.Set("username", v.(string))
+       }
+       if v, found := p.p["zoneid"]; found {
+               u.Set("zoneid", v.(string))
+       }
+       return u
+}
+
+func (p *AddNsxControllerParams) SetEdgecluster(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["edgecluster"] = v
+}
+
+func (p *AddNsxControllerParams) ResetEdgecluster() {
+       if p.p != nil && p.p["edgecluster"] != nil {
+               delete(p.p, "edgecluster")
+       }
+}
+
+func (p *AddNsxControllerParams) GetEdgecluster() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["edgecluster"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetName(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["name"] = v
+}
+
+func (p *AddNsxControllerParams) ResetName() {
+       if p.p != nil && p.p["name"] != nil {
+               delete(p.p, "name")
+       }
+}
+
+func (p *AddNsxControllerParams) GetName() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["name"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetNsxproviderhostname(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["nsxproviderhostname"] = v
+}
+
+func (p *AddNsxControllerParams) ResetNsxproviderhostname() {
+       if p.p != nil && p.p["nsxproviderhostname"] != nil {
+               delete(p.p, "nsxproviderhostname")
+       }
+}
+
+func (p *AddNsxControllerParams) GetNsxproviderhostname() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["nsxproviderhostname"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetNsxproviderport(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["nsxproviderport"] = v
+}
+
+func (p *AddNsxControllerParams) ResetNsxproviderport() {
+       if p.p != nil && p.p["nsxproviderport"] != nil {
+               delete(p.p, "nsxproviderport")
+       }
+}
+
+func (p *AddNsxControllerParams) GetNsxproviderport() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["nsxproviderport"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetPassword(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["password"] = v
+}
+
+func (p *AddNsxControllerParams) ResetPassword() {
+       if p.p != nil && p.p["password"] != nil {
+               delete(p.p, "password")
+       }
+}
+
+func (p *AddNsxControllerParams) GetPassword() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["password"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetTier0gateway(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["tier0gateway"] = v
+}
+
+func (p *AddNsxControllerParams) ResetTier0gateway() {
+       if p.p != nil && p.p["tier0gateway"] != nil {
+               delete(p.p, "tier0gateway")
+       }
+}
+
+func (p *AddNsxControllerParams) GetTier0gateway() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["tier0gateway"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetTransportzone(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["transportzone"] = v
+}
+
+func (p *AddNsxControllerParams) ResetTransportzone() {
+       if p.p != nil && p.p["transportzone"] != nil {
+               delete(p.p, "transportzone")
+       }
+}
+
+func (p *AddNsxControllerParams) GetTransportzone() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["transportzone"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetUsername(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["username"] = v
+}
+
+func (p *AddNsxControllerParams) ResetUsername() {
+       if p.p != nil && p.p["username"] != nil {
+               delete(p.p, "username")
+       }
+}
+
+func (p *AddNsxControllerParams) GetUsername() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["username"].(string)
+       return value, ok
+}
+
+func (p *AddNsxControllerParams) SetZoneid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["zoneid"] = v
+}
+
+func (p *AddNsxControllerParams) ResetZoneid() {
+       if p.p != nil && p.p["zoneid"] != nil {
+               delete(p.p, "zoneid")
+       }
+}
+
+func (p *AddNsxControllerParams) 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 AddNsxControllerParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NsxService) NewAddNsxControllerParams(edgecluster string, name 
string, nsxproviderhostname string, password string, tier0gateway string, 
transportzone string, username string, zoneid string) *AddNsxControllerParams {
+       p := &AddNsxControllerParams{}
+       p.p = make(map[string]interface{})
+       p.p["edgecluster"] = edgecluster
+       p.p["name"] = name
+       p.p["nsxproviderhostname"] = nsxproviderhostname
+       p.p["password"] = password
+       p.p["tier0gateway"] = tier0gateway
+       p.p["transportzone"] = transportzone
+       p.p["username"] = username
+       p.p["zoneid"] = zoneid
+       return p
+}
+
+// Add NSX Controller to CloudStack
+func (s *NsxService) AddNsxController(p *AddNsxControllerParams) 
(*AddNsxControllerResponse, error) {
+       resp, err := s.cs.newPostRequest("addNsxController", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r AddNsxControllerResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type AddNsxControllerResponse struct {
+       Edgecluster     string `json:"edgecluster"`
+       Hostname        string `json:"hostname"`
+       JobID           string `json:"jobid"`
+       Jobstatus       int    `json:"jobstatus"`
+       Name            string `json:"name"`
+       Nsxprovideruuid string `json:"nsxprovideruuid"`
+       Port            string `json:"port"`
+       Tier0gateway    string `json:"tier0gateway"`
+       Transportzone   string `json:"transportzone"`
+       Zoneid          string `json:"zoneid"`
+       Zonename        string `json:"zonename"`
+}
+
+type DeleteNsxControllerParams struct {
+       p map[string]interface{}
+}
+
+func (p *DeleteNsxControllerParams) toURLValues() url.Values {
+       u := url.Values{}
+       if p.p == nil {
+               return u
+       }
+       if v, found := p.p["nsxcontrollerid"]; found {
+               u.Set("nsxcontrollerid", v.(string))
+       }
+       return u
+}
+
+func (p *DeleteNsxControllerParams) SetNsxcontrollerid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["nsxcontrollerid"] = v
+}
+
+func (p *DeleteNsxControllerParams) ResetNsxcontrollerid() {
+       if p.p != nil && p.p["nsxcontrollerid"] != nil {
+               delete(p.p, "nsxcontrollerid")
+       }
+}
+
+func (p *DeleteNsxControllerParams) GetNsxcontrollerid() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["nsxcontrollerid"].(string)
+       return value, ok
+}
+
+// You should always use this function to get a new DeleteNsxControllerParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NsxService) NewDeleteNsxControllerParams(nsxcontrollerid string) 
*DeleteNsxControllerParams {
+       p := &DeleteNsxControllerParams{}
+       p.p = make(map[string]interface{})
+       p.p["nsxcontrollerid"] = nsxcontrollerid
+       return p
+}
+
+// delete NSX Controller to CloudStack
+func (s *NsxService) DeleteNsxController(p *DeleteNsxControllerParams) 
(*DeleteNsxControllerResponse, error) {
+       resp, err := s.cs.newPostRequest("deleteNsxController", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r DeleteNsxControllerResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type DeleteNsxControllerResponse struct {
+       Edgecluster     string `json:"edgecluster"`
+       Hostname        string `json:"hostname"`
+       JobID           string `json:"jobid"`
+       Jobstatus       int    `json:"jobstatus"`
+       Name            string `json:"name"`
+       Nsxprovideruuid string `json:"nsxprovideruuid"`
+       Port            string `json:"port"`
+       Tier0gateway    string `json:"tier0gateway"`
+       Transportzone   string `json:"transportzone"`
+       Zoneid          string `json:"zoneid"`
+       Zonename        string `json:"zonename"`
+}
+
+type ListNsxControllersParams struct {
+       p map[string]interface{}
+}
+
+func (p *ListNsxControllersParams) toURLValues() url.Values {
+       u := url.Values{}
+       if p.p == nil {
+               return u
+       }
+       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["zoneid"]; found {
+               u.Set("zoneid", v.(string))
+       }
+       return u
+}
+
+func (p *ListNsxControllersParams) SetKeyword(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["keyword"] = v
+}
+
+func (p *ListNsxControllersParams) ResetKeyword() {
+       if p.p != nil && p.p["keyword"] != nil {
+               delete(p.p, "keyword")
+       }
+}
+
+func (p *ListNsxControllersParams) GetKeyword() (string, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["keyword"].(string)
+       return value, ok
+}
+
+func (p *ListNsxControllersParams) SetPage(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["page"] = v
+}
+
+func (p *ListNsxControllersParams) ResetPage() {
+       if p.p != nil && p.p["page"] != nil {
+               delete(p.p, "page")
+       }
+}
+
+func (p *ListNsxControllersParams) GetPage() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["page"].(int)
+       return value, ok
+}
+
+func (p *ListNsxControllersParams) SetPagesize(v int) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["pagesize"] = v
+}
+
+func (p *ListNsxControllersParams) ResetPagesize() {
+       if p.p != nil && p.p["pagesize"] != nil {
+               delete(p.p, "pagesize")
+       }
+}
+
+func (p *ListNsxControllersParams) GetPagesize() (int, bool) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       value, ok := p.p["pagesize"].(int)
+       return value, ok
+}
+
+func (p *ListNsxControllersParams) SetZoneid(v string) {
+       if p.p == nil {
+               p.p = make(map[string]interface{})
+       }
+       p.p["zoneid"] = v
+}
+
+func (p *ListNsxControllersParams) ResetZoneid() {
+       if p.p != nil && p.p["zoneid"] != nil {
+               delete(p.p, "zoneid")
+       }
+}
+
+func (p *ListNsxControllersParams) 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 ListNsxControllersParams 
instance,
+// as then you are sure you have configured all required params
+func (s *NsxService) NewListNsxControllersParams() *ListNsxControllersParams {
+       p := &ListNsxControllersParams{}
+       p.p = make(map[string]interface{})
+       return p
+}
+
+// list all NSX controllers added to CloudStack
+func (s *NsxService) ListNsxControllers(p *ListNsxControllersParams) 
(*ListNsxControllersResponse, error) {
+       resp, err := s.cs.newRequest("listNsxControllers", p.toURLValues())
+       if err != nil {
+               return nil, err
+       }
+
+       var r ListNsxControllersResponse
+       if err := json.Unmarshal(resp, &r); err != nil {
+               return nil, err
+       }
+
+       return &r, nil
+}
+
+type ListNsxControllersResponse struct {
+       Count          int              `json:"count"`
+       NsxControllers []*NsxController `json:"nsxcontroller"`
+}
+
+type NsxController struct {
+       Edgecluster     string `json:"edgecluster"`
+       Hostname        string `json:"hostname"`
+       JobID           string `json:"jobid"`
+       Jobstatus       int    `json:"jobstatus"`
+       Name            string `json:"name"`
+       Nsxprovideruuid string `json:"nsxprovideruuid"`
+       Port            string `json:"port"`
+       Tier0gateway    string `json:"tier0gateway"`
+       Transportzone   string `json:"transportzone"`
+       Zoneid          string `json:"zoneid"`
+       Zonename        string `json:"zonename"`
+}
diff --git a/cloudstack/NsxService_mock.go b/cloudstack/NsxService_mock.go
new file mode 100644
index 0000000..34e27df
--- /dev/null
+++ b/cloudstack/NsxService_mock.go
@@ -0,0 +1,146 @@
+//
+// 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/NsxService.go
+//
+// Generated by this command:
+//
+//     mockgen -destination=./cloudstack/NsxService_mock.go 
-package=cloudstack -copyright_file=header.txt 
-source=./cloudstack/NsxService.go
+//
+
+// Package cloudstack is a generated GoMock package.
+package cloudstack
+
+import (
+       reflect "reflect"
+
+       gomock "go.uber.org/mock/gomock"
+)
+
+// MockNsxServiceIface is a mock of NsxServiceIface interface.
+type MockNsxServiceIface struct {
+       ctrl     *gomock.Controller
+       recorder *MockNsxServiceIfaceMockRecorder
+       isgomock struct{}
+}
+
+// MockNsxServiceIfaceMockRecorder is the mock recorder for 
MockNsxServiceIface.
+type MockNsxServiceIfaceMockRecorder struct {
+       mock *MockNsxServiceIface
+}
+
+// NewMockNsxServiceIface creates a new mock instance.
+func NewMockNsxServiceIface(ctrl *gomock.Controller) *MockNsxServiceIface {
+       mock := &MockNsxServiceIface{ctrl: ctrl}
+       mock.recorder = &MockNsxServiceIfaceMockRecorder{mock}
+       return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockNsxServiceIface) EXPECT() *MockNsxServiceIfaceMockRecorder {
+       return m.recorder
+}
+
+// AddNsxController mocks base method.
+func (m *MockNsxServiceIface) AddNsxController(p *AddNsxControllerParams) 
(*AddNsxControllerResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "AddNsxController", p)
+       ret0, _ := ret[0].(*AddNsxControllerResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// AddNsxController indicates an expected call of AddNsxController.
+func (mr *MockNsxServiceIfaceMockRecorder) AddNsxController(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"AddNsxController", 
reflect.TypeOf((*MockNsxServiceIface)(nil).AddNsxController), p)
+}
+
+// DeleteNsxController mocks base method.
+func (m *MockNsxServiceIface) DeleteNsxController(p 
*DeleteNsxControllerParams) (*DeleteNsxControllerResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "DeleteNsxController", p)
+       ret0, _ := ret[0].(*DeleteNsxControllerResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// DeleteNsxController indicates an expected call of DeleteNsxController.
+func (mr *MockNsxServiceIfaceMockRecorder) DeleteNsxController(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"DeleteNsxController", 
reflect.TypeOf((*MockNsxServiceIface)(nil).DeleteNsxController), p)
+}
+
+// ListNsxControllers mocks base method.
+func (m *MockNsxServiceIface) ListNsxControllers(p *ListNsxControllersParams) 
(*ListNsxControllersResponse, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "ListNsxControllers", p)
+       ret0, _ := ret[0].(*ListNsxControllersResponse)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// ListNsxControllers indicates an expected call of ListNsxControllers.
+func (mr *MockNsxServiceIfaceMockRecorder) ListNsxControllers(p any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"ListNsxControllers", 
reflect.TypeOf((*MockNsxServiceIface)(nil).ListNsxControllers), p)
+}
+
+// NewAddNsxControllerParams mocks base method.
+func (m *MockNsxServiceIface) NewAddNsxControllerParams(edgecluster, name, 
nsxproviderhostname, password, tier0gateway, transportzone, username, zoneid 
string) *AddNsxControllerParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewAddNsxControllerParams", edgecluster, name, 
nsxproviderhostname, password, tier0gateway, transportzone, username, zoneid)
+       ret0, _ := ret[0].(*AddNsxControllerParams)
+       return ret0
+}
+
+// NewAddNsxControllerParams indicates an expected call of 
NewAddNsxControllerParams.
+func (mr *MockNsxServiceIfaceMockRecorder) 
NewAddNsxControllerParams(edgecluster, name, nsxproviderhostname, password, 
tier0gateway, transportzone, username, zoneid any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewAddNsxControllerParams", 
reflect.TypeOf((*MockNsxServiceIface)(nil).NewAddNsxControllerParams), 
edgecluster, name, nsxproviderhostname, password, tier0gateway, transportzone, 
username, zoneid)
+}
+
+// NewDeleteNsxControllerParams mocks base method.
+func (m *MockNsxServiceIface) NewDeleteNsxControllerParams(nsxcontrollerid 
string) *DeleteNsxControllerParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewDeleteNsxControllerParams", nsxcontrollerid)
+       ret0, _ := ret[0].(*DeleteNsxControllerParams)
+       return ret0
+}
+
+// NewDeleteNsxControllerParams indicates an expected call of 
NewDeleteNsxControllerParams.
+func (mr *MockNsxServiceIfaceMockRecorder) 
NewDeleteNsxControllerParams(nsxcontrollerid any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewDeleteNsxControllerParams", 
reflect.TypeOf((*MockNsxServiceIface)(nil).NewDeleteNsxControllerParams), 
nsxcontrollerid)
+}
+
+// NewListNsxControllersParams mocks base method.
+func (m *MockNsxServiceIface) NewListNsxControllersParams() 
*ListNsxControllersParams {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "NewListNsxControllersParams")
+       ret0, _ := ret[0].(*ListNsxControllersParams)
+       return ret0
+}
+
+// NewListNsxControllersParams indicates an expected call of 
NewListNsxControllersParams.
+func (mr *MockNsxServiceIfaceMockRecorder) NewListNsxControllersParams() 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"NewListNsxControllersParams", 
reflect.TypeOf((*MockNsxServiceIface)(nil).NewListNsxControllersParams))
+}
diff --git a/cloudstack/cloudstack.go b/cloudstack/cloudstack.go
index ee8df3c..e4dd391 100644
--- a/cloudstack/cloudstack.go
+++ b/cloudstack/cloudstack.go
@@ -142,6 +142,7 @@ type CloudStackClient struct {
        Metrics                 MetricsServiceIface
        Misc                    MiscServiceIface
        NAT                     NATServiceIface
+       Netris                  NetrisServiceIface
        Netscaler               NetscalerServiceIface
        NetworkACL              NetworkACLServiceIface
        NetworkDevice           NetworkDeviceServiceIface
@@ -149,6 +150,7 @@ type CloudStackClient struct {
        Network                 NetworkServiceIface
        Nic                     NicServiceIface
        NiciraNVP               NiciraNVPServiceIface
+       Nsx                     NsxServiceIface
        Oauth                   OauthServiceIface
        ObjectStore             ObjectStoreServiceIface
        OutofbandManagement     OutofbandManagementServiceIface
@@ -269,6 +271,7 @@ func newClient(apiurl string, apikey string, secret string, 
async bool, verifyss
        cs.Metrics = NewMetricsService(cs)
        cs.Misc = NewMiscService(cs)
        cs.NAT = NewNATService(cs)
+       cs.Netris = NewNetrisService(cs)
        cs.Netscaler = NewNetscalerService(cs)
        cs.NetworkACL = NewNetworkACLService(cs)
        cs.NetworkDevice = NewNetworkDeviceService(cs)
@@ -276,6 +279,7 @@ func newClient(apiurl string, apikey string, secret string, 
async bool, verifyss
        cs.Network = NewNetworkService(cs)
        cs.Nic = NewNicService(cs)
        cs.NiciraNVP = NewNiciraNVPService(cs)
+       cs.Nsx = NewNsxService(cs)
        cs.Oauth = NewOauthService(cs)
        cs.ObjectStore = NewObjectStoreService(cs)
        cs.OutofbandManagement = NewOutofbandManagementService(cs)
@@ -369,6 +373,7 @@ func newMockClient(ctrl *gomock.Controller) 
*CloudStackClient {
        cs.Metrics = NewMockMetricsServiceIface(ctrl)
        cs.Misc = NewMockMiscServiceIface(ctrl)
        cs.NAT = NewMockNATServiceIface(ctrl)
+       cs.Netris = NewMockNetrisServiceIface(ctrl)
        cs.Netscaler = NewMockNetscalerServiceIface(ctrl)
        cs.NetworkACL = NewMockNetworkACLServiceIface(ctrl)
        cs.NetworkDevice = NewMockNetworkDeviceServiceIface(ctrl)
@@ -376,6 +381,7 @@ func newMockClient(ctrl *gomock.Controller) 
*CloudStackClient {
        cs.Network = NewMockNetworkServiceIface(ctrl)
        cs.Nic = NewMockNicServiceIface(ctrl)
        cs.NiciraNVP = NewMockNiciraNVPServiceIface(ctrl)
+       cs.Nsx = NewMockNsxServiceIface(ctrl)
        cs.Oauth = NewMockOauthServiceIface(ctrl)
        cs.ObjectStore = NewMockObjectStoreServiceIface(ctrl)
        cs.OutofbandManagement = NewMockOutofbandManagementServiceIface(ctrl)
@@ -1148,6 +1154,14 @@ func NewNATService(cs *CloudStackClient) NATServiceIface 
{
        return &NATService{cs: cs}
 }
 
+type NetrisService struct {
+       cs *CloudStackClient
+}
+
+func NewNetrisService(cs *CloudStackClient) NetrisServiceIface {
+       return &NetrisService{cs: cs}
+}
+
 type NetscalerService struct {
        cs *CloudStackClient
 }
@@ -1204,6 +1218,14 @@ func NewNiciraNVPService(cs *CloudStackClient) 
NiciraNVPServiceIface {
        return &NiciraNVPService{cs: cs}
 }
 
+type NsxService struct {
+       cs *CloudStackClient
+}
+
+func NewNsxService(cs *CloudStackClient) NsxServiceIface {
+       return &NsxService{cs: cs}
+}
+
 type OauthService struct {
        cs *CloudStackClient
 }
diff --git a/generate/layout.go b/generate/layout.go
index a878a67..9f55719 100644
--- a/generate/layout.go
+++ b/generate/layout.go
@@ -727,6 +727,9 @@ var layout = apiInfo{
                "updateConfiguration",
                "resetConfiguration",
                "updateStorageCapabilities",
+               "registerCniConfiguration",
+               "listCniConfiguration",
+               "deleteCniConfiguration",
        },
        "BrocadeVCSService": {
                "addBrocadeVcsDevice",
@@ -852,6 +855,8 @@ var layout = apiInfo{
                "upgradeKubernetesCluster",
                "addVirtualMachinesToKubernetesCluster",
                "removeVirtualMachinesFromKubernetesCluster",
+               "addNodesToKubernetesCluster",
+               "removeNodesFromKubernetesCluster",
        },
        "InfrastructureUsageService": {
                "listDbMetrics",
@@ -903,6 +908,11 @@ var layout = apiInfo{
        "MiscService": {
                "listElastistorInterface",
        },
+       "NetrisService": {
+               "addNetrisProvider",
+               "deleteNetrisProvider",
+               "listNetrisProviders",
+       },
        "NetscalerService": {
                "addNetscalerLoadBalancer",
                "configureNetscalerLoadBalancer",
@@ -914,6 +924,11 @@ var layout = apiInfo{
                "registerNetscalerControlCenter",
                "registerNetscalerServicePackage",
        },
+       "NsxService": {
+               "addNsxController",
+               "deleteNsxController",
+               "listNsxControllers",
+       },
        "ResourceIconService": {
                "deleteResourceIcon",
                "listResourceIcon",
diff --git a/test/ConfigurationService_test.go 
b/test/ConfigurationService_test.go
index a0a72d8..623232d 100644
--- a/test/ConfigurationService_test.go
+++ b/test/ConfigurationService_test.go
@@ -122,4 +122,40 @@ func TestConfigurationService(t *testing.T) {
        }
        t.Run("UpdateStorageCapabilities", testupdateStorageCapabilities)
 
+       testregisterCniConfiguration := func(t *testing.T) {
+               if _, ok := response["registerCniConfiguration"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := 
client.Configuration.NewRegisterCniConfigurationParams("name")
+               _, err := client.Configuration.RegisterCniConfiguration(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("RegisterCniConfiguration", testregisterCniConfiguration)
+
+       testlistCniConfiguration := func(t *testing.T) {
+               if _, ok := response["listCniConfiguration"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Configuration.NewListCniConfigurationParams()
+               _, err := client.Configuration.ListCniConfiguration(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("ListCniConfiguration", testlistCniConfiguration)
+
+       testdeleteCniConfiguration := func(t *testing.T) {
+               if _, ok := response["deleteCniConfiguration"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Configuration.NewDeleteCniConfigurationParams("id")
+               _, err := client.Configuration.DeleteCniConfiguration(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("DeleteCniConfiguration", testdeleteCniConfiguration)
+
 }
diff --git a/test/KubernetesService_test.go b/test/KubernetesService_test.go
index 81e0993..e7c0276 100644
--- a/test/KubernetesService_test.go
+++ b/test/KubernetesService_test.go
@@ -227,4 +227,34 @@ func TestKubernetesService(t *testing.T) {
        }
        t.Run("RemoveVirtualMachinesFromKubernetesCluster", 
testremoveVirtualMachinesFromKubernetesCluster)
 
+       testaddNodesToKubernetesCluster := func(t *testing.T) {
+               if _, ok := response["addNodesToKubernetesCluster"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := 
client.Kubernetes.NewAddNodesToKubernetesClusterParams("id", []string{})
+               r, err := client.Kubernetes.AddNodesToKubernetesCluster(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+               if r.Id == "" {
+                       t.Errorf("Failed to parse response. ID not found")
+               }
+       }
+       t.Run("AddNodesToKubernetesCluster", testaddNodesToKubernetesCluster)
+
+       testremoveNodesFromKubernetesCluster := func(t *testing.T) {
+               if _, ok := response["removeNodesFromKubernetesCluster"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := 
client.Kubernetes.NewRemoveNodesFromKubernetesClusterParams("id", []string{})
+               r, err := client.Kubernetes.RemoveNodesFromKubernetesCluster(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+               if r.Id == "" {
+                       t.Errorf("Failed to parse response. ID not found")
+               }
+       }
+       t.Run("RemoveNodesFromKubernetesCluster", 
testremoveNodesFromKubernetesCluster)
+
 }
diff --git a/test/NetrisService_test.go b/test/NetrisService_test.go
new file mode 100644
index 0000000..6780d04
--- /dev/null
+++ b/test/NetrisService_test.go
@@ -0,0 +1,74 @@
+//
+// 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 test
+
+import (
+       "testing"
+
+       "github.com/apache/cloudstack-go/v2/cloudstack"
+)
+
+func TestNetrisService(t *testing.T) {
+       service := "NetrisService"
+       response, err := readData(service)
+       if err != nil {
+               t.Skipf("Skipping test as %v", err)
+       }
+       server := CreateTestServer(t, response)
+       client := cloudstack.NewClient(server.URL, "APIKEY", "SECRETKEY", true)
+       defer server.Close()
+
+       testaddNetrisProvider := func(t *testing.T) {
+               if _, ok := response["addNetrisProvider"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Netris.NewAddNetrisProviderParams("name", 
"netristag", "netrisurl", "password", "sitename", "tenantname", "username", 
"zoneid")
+               _, err := client.Netris.AddNetrisProvider(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("AddNetrisProvider", testaddNetrisProvider)
+
+       testdeleteNetrisProvider := func(t *testing.T) {
+               if _, ok := response["deleteNetrisProvider"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Netris.NewDeleteNetrisProviderParams("id")
+               _, err := client.Netris.DeleteNetrisProvider(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("DeleteNetrisProvider", testdeleteNetrisProvider)
+
+       testlistNetrisProviders := func(t *testing.T) {
+               if _, ok := response["listNetrisProviders"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Netris.NewListNetrisProvidersParams()
+               _, err := client.Netris.ListNetrisProviders(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("ListNetrisProviders", testlistNetrisProviders)
+
+}
diff --git a/test/NsxService_test.go b/test/NsxService_test.go
new file mode 100644
index 0000000..d690fa6
--- /dev/null
+++ b/test/NsxService_test.go
@@ -0,0 +1,74 @@
+//
+// 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 test
+
+import (
+       "testing"
+
+       "github.com/apache/cloudstack-go/v2/cloudstack"
+)
+
+func TestNsxService(t *testing.T) {
+       service := "NsxService"
+       response, err := readData(service)
+       if err != nil {
+               t.Skipf("Skipping test as %v", err)
+       }
+       server := CreateTestServer(t, response)
+       client := cloudstack.NewClient(server.URL, "APIKEY", "SECRETKEY", true)
+       defer server.Close()
+
+       testaddNsxController := func(t *testing.T) {
+               if _, ok := response["addNsxController"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Nsx.NewAddNsxControllerParams("edgecluster", 
"name", "nsxproviderhostname", "password", "tier0gateway", "transportzone", 
"username", "zoneid")
+               _, err := client.Nsx.AddNsxController(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("AddNsxController", testaddNsxController)
+
+       testdeleteNsxController := func(t *testing.T) {
+               if _, ok := response["deleteNsxController"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Nsx.NewDeleteNsxControllerParams("nsxcontrollerid")
+               _, err := client.Nsx.DeleteNsxController(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("DeleteNsxController", testdeleteNsxController)
+
+       testlistNsxControllers := func(t *testing.T) {
+               if _, ok := response["listNsxControllers"]; !ok {
+                       t.Skipf("Skipping as no json response is provided in 
testdata")
+               }
+               p := client.Nsx.NewListNsxControllersParams()
+               _, err := client.Nsx.ListNsxControllers(p)
+               if err != nil {
+                       t.Errorf(err.Error())
+               }
+       }
+       t.Run("ListNsxControllers", testlistNsxControllers)
+
+}

Reply via email to