Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CRUD operations for Org user #210

Merged
merged 13 commits into from
Jul 5, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Added load balancer server pool [#205](https://github.com/vmware/go-vcloud-director/pull/205)
* Added functions for refreshing, getting and update Org VDC [#206](https://github.com/vmware/go-vcloud-director/pull/206)
* Added VDC meta data create/get/delete functions [#203](https://github.com/vmware/go-vcloud-director/pull/203)
* Added org user create/delete/update functions [#18](https://github.com/vmware/go-vcloud-director/issues/18)
dataclouder marked this conversation as resolved.
Show resolved Hide resolved

## 2.2.0 (May 15, 2019)

Expand Down
80 changes: 79 additions & 1 deletion govcd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"bytes"
"encoding/xml"
"fmt"

"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"reflect"
"strings"

Expand All @@ -36,6 +36,80 @@ type Client struct {
MaxRetryTimeout int
}

// General purpose error to be used whenever an entity is not found from a "GET" request
// Allows a simpler checking of the call result
// such as
// if err == ErrorEntityNotFound {
// // do what is needed in case of not found
// }
var ErrorEntityNotFound = fmt.Errorf("entity not found")

// Triggers for debugging functions that show requests and responses
var debugShowRequestEnabled = os.Getenv("GOVCD_SHOW_REQ") != ""
var debugShowResponseEnabled = os.Getenv("GOVCD_SHOW_RESP") != ""

// Enables the debugging hook to show requests as they are processed.
func enableDebugShowRequest() {
debugShowRequestEnabled = true
}

// Disables the debugging hook to show requests as they are processed.
func disableDebugShowRequest() {
debugShowRequestEnabled = false
_ = os.Setenv("GOVCD_SHOW_REQ", "")
}

// Enables the debugging hook to show responses as they are processed.
func enableDebugShowResponse() {
debugShowResponseEnabled = true
}

// Disables the debugging hook to show responses as they are processed.
func disableDebugShowResponse() {
debugShowResponseEnabled = false
_ = os.Setenv("GOVCD_SHOW_RESP", "")
}

// On-the-fly debug hook. If either debugShowRequestEnabled or the environment
// variable "GOVCD_SHOW_REQ" are enabled, this function will show the contents
// of the request as it is being processed.
func debugShowRequest(req *http.Request, payload string) {
if debugShowRequestEnabled {
header := "[\n"
for key, value := range req.Header {
header += fmt.Sprintf("\t%s => %s\n", key, value)
}
header += "]\n"
fmt.Printf("method: %s\n", req.Method)
fmt.Printf("host: %s\n", req.Host)
fmt.Printf("length: %d\n", req.ContentLength)
fmt.Printf("URL: %s\n", req.URL.String())
fmt.Printf("header: %s\n", header)
fmt.Printf("payload: %s\n", payload)
}
}

// On-the-fly debug hook. If either debugShowResponseEnabled or the environment
// variable "GOVCD_SHOW_RESP" are enabled, this function will show the contents
// of the response as it is being processed.
func debugShowResponse(resp *http.Response, body []byte) {
if debugShowResponseEnabled {
fmt.Printf("status: %d - %s \n", resp.StatusCode, resp.Status)
fmt.Printf("length: %d\n", resp.ContentLength)
fmt.Printf("header: %v\n", resp.Header)
fmt.Printf("body: %s\n", body)
}
}

// Convenience function, similar to os.IsNotExist that checks whether a given error
// is a "Not found" error, such as
// if isNotFound(err) {
// // do what is needed in case of not found
// }
func IsNotFound(err error) bool {
return err != nil && err == ErrorEntityNotFound
}

// Function allow to pass complex values params which shouldn't be encoded like for queries. e.g. /query?filter=(name=foo)
func (cli *Client) NewRequestWitNotEncodedParams(params map[string]string, notEncodedParams map[string]string, method string, reqUrl url.URL, body io.Reader) *http.Request {
reqValues := url.Values{}
Expand Down Expand Up @@ -86,6 +160,8 @@ func (cli *Client) NewRequestWitNotEncodedParams(params map[string]string, notEn
}
}
util.ProcessRequestOutput(util.FuncNameCallStack(), method, reqUrl.String(), payload, req)

debugShowRequest(req, payload)
}
return req

Expand Down Expand Up @@ -119,6 +195,7 @@ func decodeBody(resp *http.Response, out interface{}) error {
return err
}

debugShowResponse(resp, body)
// Unmarshal the XML.
if err = xml.Unmarshal(body, &out); err != nil {
return err
Expand Down Expand Up @@ -238,6 +315,7 @@ func (client *Client) ExecuteRequestWithoutResponse(pathURL, requestType, conten
// log response explicitly because decodeBody() was not triggered
util.ProcessResponseOutput(util.FuncNameCallStack(), resp, fmt.Sprintf("%s", resp.Body))

debugShowResponse(resp, []byte("SKIPPED RESPONSE"))
err = resp.Body.Close()
if err != nil {
return fmt.Errorf("error closing response body: %s", err)
Expand Down
24 changes: 23 additions & 1 deletion govcd/api_vcd_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build api functional catalog vapp gateway network org query extnetwork task vm vdc system disk lbServerPool lbServiceMonitor ALL
// +build api functional catalog vapp gateway network org query extnetwork task vm vdc system disk lbServerPool lbServiceMonitor user ALL

/*
* Copyright 2019 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
Expand Down Expand Up @@ -545,6 +545,28 @@ func (vcd *TestVCD) removeLeftoverEntities(entity CleanupEntity) {
vcd.infoCleanup(notDeletedMsg, entity.EntityType, entity.Name, err)
}
return
case "user":
dataclouder marked this conversation as resolved.
Show resolved Hide resolved
if entity.Parent == "" {
vcd.infoCleanup("removeLeftoverEntries: [ERROR] No ORG provided for user '%s'\n", entity.Name)
return
}
org, err := GetAdminOrgByName(vcd.client, entity.Parent)
if org == (AdminOrg{}) || err != nil {
vcd.infoCleanup(notFoundMsg, "org", entity.Parent)
return
}
user, err := org.GetUserByNameOrId(entity.Name, true)
if err != nil {
vcd.infoCleanup(notFoundMsg, "user", entity.Name)
return
}
err = user.SafeDelete()
if err == nil {
vcd.infoCleanup(removedMsg, entity.EntityType, entity.Name, entity.CreatedBy)
} else {
vcd.infoCleanup(notDeletedMsg, entity.EntityType, entity.Name, err)
}
return
case "vdc":
if entity.Parent == "" {
vcd.infoCleanup("removeLeftoverEntries: [ERROR] No ORG provided for VDC '%s'\n", entity.Name)
Expand Down
17 changes: 17 additions & 0 deletions govcd/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ func prettyVapp(vapp types.VApp) string {
return ""
}

// Returns an OrgUser structure as JSON
func prettyUser(user types.User) string {
byteBuf, err := json.MarshalIndent(user, " ", " ")
if err == nil {
return fmt.Sprintf("%s\n", string(byteBuf))
}
return ""
}

// Returns a VDC structure as JSON
func prettyVdc(vdc types.Vdc) string {
byteBuf, err := json.MarshalIndent(vdc, " ", " ")
Expand Down Expand Up @@ -202,6 +211,14 @@ func LogVdc(vdc types.Vdc) {
out("log", prettyVdc(vdc))
}

func ShowUser(user types.User) {
out("screen", prettyUser(user))
}

func LogUser(user types.User) {
out("log", prettyUser(user))
}

func ShowDisk(disk types.Disk) {
out("screen", prettyDisk(disk))
}
Expand Down
Loading