Skip to content

Commit

Permalink
fix: vapi - special param encoding for edge cluster lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
benjvi committed Feb 9, 2022
1 parent fd21c74 commit 0f0201a
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
1 change: 1 addition & 0 deletions govc/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3721,6 +3721,7 @@ Examples:
-cluster "Workload-Cluster" \
-service-cidr 10.96.0.0/23 \
-pod-cidrs 10.244.0.0/20 \
-control-plane-dns 10.10.10.10 \
-control-plane-dns-names wcp.example.com \
-workload-network.egress-cidrs 10.0.0.128/26 \
-workload-network.ingress-cidrs "10.0.0.64/26" \
Expand Down
3 changes: 2 additions & 1 deletion govc/namespace/cluster/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ Examples:
-cluster "Workload-Cluster" \
-service-cidr 10.96.0.0/23 \
-pod-cidrs 10.244.0.0/20 \
-control-plane-dns 10.10.10.10 \
-control-plane-dns-names wcp.example.com \
-workload-network.egress-cidrs 10.0.0.128/26 \
-workload-network.ingress-cidrs "10.0.0.64/26" \
Expand Down Expand Up @@ -243,7 +244,7 @@ func (cmd *enableCluster) Run(ctx context.Context, f *flag.FlagSet) error {
edgeClusterDisplayName := cmd.NcpClusterNetworkSpec.NsxEdgeCluster
edgeClusters, err := m.ListCompatibleEdgeClusters(ctx, clusterId, switchId)
if err != nil {
return fmt.Errorf("error in compatible switch lookup: %s", err)
return fmt.Errorf("error in compatible edge cluster lookup: %s", err)
}

matchingEdgeClusters := make([]string, 0)
Expand Down
4 changes: 2 additions & 2 deletions vapi/namespace/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ type EdgeClusterCompatibilitySummary struct {
func (c *Manager) ListCompatibleEdgeClusters(ctx context.Context, clusterId string, switchId string) (result []EdgeClusterCompatibilitySummary, err error) {
listUrl := c.Resource(internal.NamespaceEdgeClusterCompatibility).
WithParam("cluster", clusterId).
WithParam("distributed_switch", switchId).
WithParam("compatible", "true")
WithParam("compatible", "true").
WithPathEncodedParam("distributed_switch", switchId)
return result, c.Do(ctx, listUrl.Request(http.MethodGet), &result)
}
26 changes: 25 additions & 1 deletion vapi/rest/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,36 @@ func (r *Resource) WithAction(action string) *Resource {
// WithParam adds one parameter on the URL.RawQuery
func (r *Resource) WithParam(name string, value string) *Resource {
// ParseQuery handles empty case, and we control access to query string so shouldn't encounter an error case
params, _ := url.ParseQuery(r.u.RawQuery)
params, err := url.ParseQuery(r.u.RawQuery)
if err != nil {
panic(err)
}
params[name] = append(params[name], value)
r.u.RawQuery = params.Encode()
return r
}

// WithPathEncodedParam appends a parameter on the URL.RawQuery,
// For special cases where URL Path-style encoding is needed
func (r *Resource) WithPathEncodedParam(name string, value string) *Resource {
t := &url.URL{Path: value}
encodedValue := t.String()
t = &url.URL{Path: name}
encodedName := t.String()
// ParseQuery handles empty case, and we control access to query string so shouldn't encounter an error case
params, err := url.ParseQuery(r.u.RawQuery)
if err != nil {
panic(err)
}
// Values.Encode() doesn't escape exactly how we want, so we need to build the query string ourselves
if len(params) >= 1 {
r.u.RawQuery = r.u.RawQuery + "&" + encodedName + "=" + encodedValue
} else {
r.u.RawQuery = r.u.RawQuery + encodedName + "=" + encodedValue
}
return r
}

// Request returns a new http.Request for the given method.
// An optional body can be provided for POST and PATCH methods.
func (r *Resource) Request(method string, body ...interface{}) *http.Request {
Expand Down
31 changes: 31 additions & 0 deletions vapi/rest/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,34 @@ func TestResource_WithParam(t *testing.T) {
}
})
}

func TestResource_WithPathEncodedParam(t *testing.T) {
simulator.Test(func(ctx context.Context, vc *vim25.Client) {
c := rest.NewClient(vc)

// path is correctly formatted when Path-Encoded param is first
url := c.Resource("api/some/resource").
WithPathEncodedParam("key1", "value 1")
expectedPath := "api/some/resource?key1=value%201"
if !strings.Contains(url.String(), expectedPath) {
t.Errorf("First path-encoded param incorrectly added to resource, URL %q, expected path %q", url.String(), expectedPath)
}

// path is correctly formatted when Path-Encoded param is last
url = c.Resource("api/some/resource").
WithParam("key1", "value 1").
WithPathEncodedParam("key2", "value 2")
expectedPath = "api/some/resource?key1=value+1&key2=value%202"
if !strings.Contains(url.String(), expectedPath) {
t.Errorf("Last path-encoded param incorrectly added to resource, URL %q, expected path %q", url.String(), expectedPath)
}

// if WithParam is used again, it will re-encode the Path-Encoded value
url = url.WithParam("key3", "value 3")
expectedPath = "api/some/resource?key1=value+1&key2=value+2&key3=value+3"
if !strings.Contains(url.String(), expectedPath) {
t.Errorf("Middle path-encoded param not endcoded as expected, URL %q, expected path %q", url.String(), expectedPath)
}

})
}

0 comments on commit 0f0201a

Please sign in to comment.