Skip to content
Permalink
Browse files
Generate packages based on latest API output
Also cleanup the old packages and make sure the the current package is
backwards compatible.
  • Loading branch information
Sander van Harmelen committed Apr 19, 2016
1 parent 252eb1b commit e97322d41dfcfa9c75cf5bd57fba14564969e460
Show file tree
Hide file tree
Showing 181 changed files with 86,709 additions and 292,984 deletions.
@@ -4,21 +4,19 @@ A CloudStack API client enabling Go programs to interact with CloudStack in a si

## Status

This package is completely finished (is something ever really finished...? :wink:) and tested. Of course there will still be untested corner cases when you have over 250 API commands that you can use, but over all it's save to use this package.
This package covers the complete CloudStack API and is well tested. Of course there will still be untested corner cases when you have over 400 API commands that you can use, but over all it's save to use this package.

I know there are more Go CloudStack packages out there, but I created yet another one because non of them seemed to be complete... This one is. It uses the code in the generate package to generate the static code needed for all available API commands. It does this per CloudStack version, because some API command change over time.

To be able to find the API command you want, they are grouped by 'services' which match the grouping you can see/find on the [CloudStack API docs](http://cloudstack.apache.org/docs/api/apidocs-4.4/TOC_Root_Admin.html) website.
To be able to find the API command you want, they are grouped by 'services' which match the grouping you can see/find on the [CloudStack API docs](http://cloudstack.apache.org/docs/api/apidocs-4.8/TOC_Root_Admin.html) website.

## Usage

For the most part the generic API commands do not change that much, so you should be able to use just the cloudstack package opposed to the specific cloudstackXX packages. The cloudstack package is always the one generate against the latest stable CloudStack release (currently v4.4.x). If you need some specific API command of a specific CloudStack version, you should use the matching cloudstackXX package instead.
The cloudstack package is always generated against the latest stable CloudStack release (currently v4.8.x). Luckily the API doesn't change that much, and were it does we try to make sure the generated package is able handle both the old and the new case. Over time it will be impossible to support all version with just one package, but until now we seem to manage this pretty well.

When you have choosen the package you want to use, please see the details about it on [GoDocs](http://godoc.org/github.com/xanzy/go-cloudstack). It can use some more documentation, but generaly it speaks for itself.
Please see the package documentation on [GoDocs](http://godoc.org/github.com/xanzy/go-cloudstack/cloudstack).

## Features

Next to the API commands CloudStack itself offers, there are a few additional features/function that are helpful. For starters there are two clients, an normal one (created with `NewClient(...)`) and an async client (created with `NewAsyncClient(...)`). The async client has a buildin waiting/polling feature that waits for a configured amount of time (defaults to 60 seconds) on running async jobs. This is very helpfull if you do not want to continue with your program execution until the async job is done.
Next to the API commands CloudStack itself offers, there are a few additional features/function that are helpful. For starters there are two clients, an normal one (created with `NewClient(...)`) and an async client (created with `NewAsyncClient(...)`). The async client has a buildin waiting/polling feature that waits for a configured amount of time (defaults to 300 seconds) on running async jobs. This is very helpfull if you do not want to continue with your program execution until the async job is done.

There is also a function you can call manually (`GetAsyncJobResult(...)`) that does the same, but then as a seperate call after you started the async job.

@@ -894,7 +894,7 @@ func (s *AccountService) NewLockAccountParams(account string, domainid string) *
return p
}

// Locks an account
// This deprecated function used to locks an account. Look for the API DisableAccount instead
func (s *AccountService) LockAccount(p *LockAccountParams) (*LockAccountResponse, error) {
resp, err := s.cs.newRequest("lockAccount", p.toURLValues())
if err != nil {
@@ -1512,7 +1512,7 @@ func (s *AccountService) NewAddAccountToProjectParams(projectid string) *AddAcco
return p
}

// Adds acoount to a project
// Adds account to a project
func (s *AccountService) AddAccountToProject(p *AddAccountToProjectParams) (*AddAccountToProjectResponse, error) {
resp, err := s.cs.newRequest("addAccountToProject", p.toURLValues())
if err != nil {
@@ -1831,3 +1831,65 @@ type ProjectAccount struct {
Vpclimit string `json:"vpclimit,omitempty"`
Vpctotal int64 `json:"vpctotal,omitempty"`
}

type GetSolidFireAccountIdParams struct {
p map[string]interface{}
}

func (p *GetSolidFireAccountIdParams) toURLValues() url.Values {
u := url.Values{}
if p.p == nil {
return u
}
if v, found := p.p["accountid"]; found {
u.Set("accountid", v.(string))
}
if v, found := p.p["storageid"]; found {
u.Set("storageid", v.(string))
}
return u
}

func (p *GetSolidFireAccountIdParams) SetAccountid(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["accountid"] = v
return
}

func (p *GetSolidFireAccountIdParams) SetStorageid(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["storageid"] = v
return
}

// You should always use this function to get a new GetSolidFireAccountIdParams instance,
// as then you are sure you have configured all required params
func (s *AccountService) NewGetSolidFireAccountIdParams(accountid string, storageid string) *GetSolidFireAccountIdParams {
p := &GetSolidFireAccountIdParams{}
p.p = make(map[string]interface{})
p.p["accountid"] = accountid
p.p["storageid"] = storageid
return p
}

// Get SolidFire Account ID
func (s *AccountService) GetSolidFireAccountId(p *GetSolidFireAccountIdParams) (*GetSolidFireAccountIdResponse, error) {
resp, err := s.cs.newRequest("getSolidFireAccountId", p.toURLValues())
if err != nil {
return nil, err
}

var r GetSolidFireAccountIdResponse
if err := json.Unmarshal(resp, &r); err != nil {
return nil, err
}
return &r, nil
}

type GetSolidFireAccountIdResponse struct {
SolidFireAccountId int64 `json:"solidFireAccountId,omitempty"`
}
@@ -257,7 +257,7 @@ func (s *AddressService) NewDisassociateIpAddressParams(id string) *Disassociate
return p
}

// Disassociates an ip address from the account.
// Disassociates an IP address from the account.
func (s *AddressService) DisassociateIpAddress(p *DisassociateIpAddressParams) (*DisassociateIpAddressResponse, error) {
resp, err := s.cs.newRequest("disassociateIpAddress", p.toURLValues())
if err != nil {
@@ -365,6 +365,9 @@ func (p *ListPublicIpAddressesParams) toURLValues() url.Values {
if v, found := p.p["projectid"]; found {
u.Set("projectid", v.(string))
}
if v, found := p.p["state"]; found {
u.Set("state", v.(string))
}
if v, found := p.p["tags"]; found {
i := 0
for k, vv := range v.(map[string]string) {
@@ -529,6 +532,14 @@ func (p *ListPublicIpAddressesParams) SetProjectid(v string) {
return
}

func (p *ListPublicIpAddressesParams) SetState(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["state"] = v
return
}

func (p *ListPublicIpAddressesParams) SetTags(v map[string]string) {
if p.p == nil {
p.p = make(map[string]interface{})
@@ -729,7 +740,7 @@ func (s *AddressService) NewUpdateIpAddressParams(id string) *UpdateIpAddressPar
return p
}

// Updates an ip address
// Updates an IP address
func (s *AddressService) UpdateIpAddress(p *UpdateIpAddressParams) (*UpdateIpAddressResponse, error) {
resp, err := s.cs.newRequest("updateIpAddress", p.toURLValues())
if err != nil {
@@ -45,6 +45,9 @@ func (p *CreateAffinityGroupParams) toURLValues() url.Values {
if v, found := p.p["name"]; found {
u.Set("name", v.(string))
}
if v, found := p.p["projectid"]; found {
u.Set("projectid", v.(string))
}
if v, found := p.p["type"]; found {
u.Set("type", v.(string))
}
@@ -83,6 +86,14 @@ func (p *CreateAffinityGroupParams) SetName(v string) {
return
}

func (p *CreateAffinityGroupParams) SetProjectid(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["projectid"] = v
return
}

func (p *CreateAffinityGroupParams) SetType(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
@@ -143,6 +154,8 @@ type CreateAffinityGroupResponse struct {
Domainid string `json:"domainid,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Project string `json:"project,omitempty"`
Projectid string `json:"projectid,omitempty"`
Type string `json:"type,omitempty"`
VirtualmachineIds []string `json:"virtualmachineIds,omitempty"`
}
@@ -168,6 +181,9 @@ func (p *DeleteAffinityGroupParams) toURLValues() url.Values {
if v, found := p.p["name"]; found {
u.Set("name", v.(string))
}
if v, found := p.p["projectid"]; found {
u.Set("projectid", v.(string))
}
return u
}

@@ -203,6 +219,14 @@ func (p *DeleteAffinityGroupParams) SetName(v string) {
return
}

func (p *DeleteAffinityGroupParams) SetProjectid(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["projectid"] = v
return
}

// You should always use this function to get a new DeleteAffinityGroupParams instance,
// as then you are sure you have configured all required params
func (s *AffinityGroupService) NewDeleteAffinityGroupParams() *DeleteAffinityGroupParams {
@@ -286,6 +310,9 @@ func (p *ListAffinityGroupsParams) toURLValues() url.Values {
vv := strconv.Itoa(v.(int))
u.Set("pagesize", vv)
}
if v, found := p.p["projectid"]; found {
u.Set("projectid", v.(string))
}
if v, found := p.p["type"]; found {
u.Set("type", v.(string))
}
@@ -367,6 +394,14 @@ func (p *ListAffinityGroupsParams) SetPagesize(v int) {
return
}

func (p *ListAffinityGroupsParams) SetProjectid(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
}
p.p["projectid"] = v
return
}

func (p *ListAffinityGroupsParams) SetType(v string) {
if p.p == nil {
p.p = make(map[string]interface{})
@@ -403,6 +438,16 @@ func (s *AffinityGroupService) GetAffinityGroupID(name string) (string, error) {
return "", err
}

if l.Count == 0 {
// If no matches, search all projects
p.p["projectid"] = "-1"

l, err = s.ListAffinityGroups(p)
if err != nil {
return "", err
}
}

if l.Count == 0 {
return "", fmt.Errorf("No match found for %s: %+v", name, l)
}
@@ -452,6 +497,21 @@ func (s *AffinityGroupService) GetAffinityGroupByID(id string) (*AffinityGroup,
return nil, -1, err
}

if l.Count == 0 {
// If no matches, search all projects
p.p["projectid"] = "-1"

l, err = s.ListAffinityGroups(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)
}
@@ -488,6 +548,8 @@ type AffinityGroup struct {
Domainid string `json:"domainid,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Project string `json:"project,omitempty"`
Projectid string `json:"projectid,omitempty"`
Type string `json:"type,omitempty"`
VirtualmachineIds []string `json:"virtualmachineIds,omitempty"`
}
@@ -592,6 +654,8 @@ type UpdateVMAffinityGroupResponse struct {
Domainid string `json:"domainid,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Project string `json:"project,omitempty"`
Projectid string `json:"projectid,omitempty"`
Type string `json:"type,omitempty"`
VirtualmachineIds []string `json:"virtualmachineIds,omitempty"`
} `json:"affinitygroup,omitempty"`
@@ -728,6 +792,8 @@ type UpdateVMAffinityGroupResponse struct {
Resourcetype string `json:"resourcetype,omitempty"`
Value string `json:"value,omitempty"`
} `json:"tags,omitempty"`
Virtualmachinecount int `json:"virtualmachinecount,omitempty"`
Virtualmachineids []string `json:"virtualmachineids,omitempty"`
} `json:"securitygroup,omitempty"`
Serviceofferingid string `json:"serviceofferingid,omitempty"`
Serviceofferingname string `json:"serviceofferingname,omitempty"`
@@ -748,6 +814,8 @@ type UpdateVMAffinityGroupResponse struct {
Templatedisplaytext string `json:"templatedisplaytext,omitempty"`
Templateid string `json:"templateid,omitempty"`
Templatename string `json:"templatename,omitempty"`
Userid string `json:"userid,omitempty"`
Username string `json:"username,omitempty"`
Vgpu string `json:"vgpu,omitempty"`
Zoneid string `json:"zoneid,omitempty"`
Zonename string `json:"zonename,omitempty"`

0 comments on commit e97322d

Please sign in to comment.