Skip to content

Commit 15a9feb

Browse files
authored
Merge pull request #2537 from Nordix/port-value-specs
Support value_specs for Ports
2 parents d68edf4 + 14f8f68 commit 15a9feb

4 files changed

Lines changed: 212 additions & 20 deletions

File tree

openstack/networking/v2/ports/requests.go

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,19 @@ type CreateOptsBuilder interface {
110110

111111
// CreateOpts represents the attributes used when creating a new port.
112112
type CreateOpts struct {
113-
NetworkID string `json:"network_id" required:"true"`
114-
Name string `json:"name,omitempty"`
115-
Description string `json:"description,omitempty"`
116-
AdminStateUp *bool `json:"admin_state_up,omitempty"`
117-
MACAddress string `json:"mac_address,omitempty"`
118-
FixedIPs interface{} `json:"fixed_ips,omitempty"`
119-
DeviceID string `json:"device_id,omitempty"`
120-
DeviceOwner string `json:"device_owner,omitempty"`
121-
TenantID string `json:"tenant_id,omitempty"`
122-
ProjectID string `json:"project_id,omitempty"`
123-
SecurityGroups *[]string `json:"security_groups,omitempty"`
124-
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
113+
NetworkID string `json:"network_id" required:"true"`
114+
Name string `json:"name,omitempty"`
115+
Description string `json:"description,omitempty"`
116+
AdminStateUp *bool `json:"admin_state_up,omitempty"`
117+
MACAddress string `json:"mac_address,omitempty"`
118+
FixedIPs interface{} `json:"fixed_ips,omitempty"`
119+
DeviceID string `json:"device_id,omitempty"`
120+
DeviceOwner string `json:"device_owner,omitempty"`
121+
TenantID string `json:"tenant_id,omitempty"`
122+
ProjectID string `json:"project_id,omitempty"`
123+
SecurityGroups *[]string `json:"security_groups,omitempty"`
124+
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
125+
ValueSpecs *map[string]string `json:"value_specs,omitempty"`
125126
}
126127

127128
// ToPortCreateMap builds a request body from CreateOpts.
@@ -150,14 +151,15 @@ type UpdateOptsBuilder interface {
150151

151152
// UpdateOpts represents the attributes used when updating an existing port.
152153
type UpdateOpts struct {
153-
Name *string `json:"name,omitempty"`
154-
Description *string `json:"description,omitempty"`
155-
AdminStateUp *bool `json:"admin_state_up,omitempty"`
156-
FixedIPs interface{} `json:"fixed_ips,omitempty"`
157-
DeviceID *string `json:"device_id,omitempty"`
158-
DeviceOwner *string `json:"device_owner,omitempty"`
159-
SecurityGroups *[]string `json:"security_groups,omitempty"`
160-
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
154+
Name *string `json:"name,omitempty"`
155+
Description *string `json:"description,omitempty"`
156+
AdminStateUp *bool `json:"admin_state_up,omitempty"`
157+
FixedIPs interface{} `json:"fixed_ips,omitempty"`
158+
DeviceID *string `json:"device_id,omitempty"`
159+
DeviceOwner *string `json:"device_owner,omitempty"`
160+
SecurityGroups *[]string `json:"security_groups,omitempty"`
161+
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
162+
ValueSpecs *map[string]string `json:"value_specs,omitempty"`
161163

162164
// RevisionNumber implements extension:standard-attr-revisions. If != "" it
163165
// will set revision_number=%s. If the revision number does not match, the

openstack/networking/v2/ports/results.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ type Port struct {
111111
// Tags optionally set via extensions/attributestags
112112
Tags []string `json:"tags"`
113113

114+
// Extra parameters to include in the request.
115+
ValueSpecs map[string]string `json:"value_specs"`
116+
114117
// RevisionNumber optionally set via extensions/standard-attr-revisions
115118
RevisionNumber int `json:"revision_number"`
116119

openstack/networking/v2/ports/testing/fixtures.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,66 @@ const CreateOmitSecurityGroupsResponse = `
240240
}
241241
`
242242

243+
const CreateValueSpecRequest = `
244+
{
245+
"port": {
246+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
247+
"name": "private-port",
248+
"admin_state_up": true,
249+
"fixed_ips": [
250+
{
251+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
252+
"ip_address": "10.0.0.2"
253+
}
254+
],
255+
"security_groups": ["foo"],
256+
"allowed_address_pairs": [
257+
{
258+
"ip_address": "10.0.0.4",
259+
"mac_address": "fa:16:3e:c9:cb:f0"
260+
}
261+
],
262+
"value_specs": {
263+
"key": "value"
264+
}
265+
}
266+
}
267+
`
268+
269+
const CreateValueSpecResponse = `
270+
{
271+
"port": {
272+
"status": "DOWN",
273+
"name": "private-port",
274+
"admin_state_up": true,
275+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
276+
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
277+
"device_owner": "",
278+
"mac_address": "fa:16:3e:c9:cb:f0",
279+
"fixed_ips": [
280+
{
281+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
282+
"ip_address": "10.0.0.2"
283+
}
284+
],
285+
"id": "65c0ee9f-d634-4522-8954-51021b570b0d",
286+
"security_groups": [
287+
"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
288+
],
289+
"allowed_address_pairs": [
290+
{
291+
"ip_address": "10.0.0.4",
292+
"mac_address": "fa:16:3e:c9:cb:f0"
293+
}
294+
],
295+
"value_specs": {
296+
"key": "value"
297+
},
298+
"device_id": ""
299+
}
300+
}
301+
`
302+
243303
const CreatePortSecurityRequest = `
244304
{
245305
"port": {
@@ -401,6 +461,50 @@ const UpdateOmitSecurityGroupsResponse = `
401461
}
402462
`
403463

464+
const UpdateValueSpecsRequest = `
465+
{
466+
"port": {
467+
"value_specs": {
468+
"key": "value"
469+
}
470+
}
471+
}
472+
`
473+
474+
const UpdateValueSpecsResponse = `
475+
{
476+
"port": {
477+
"status": "DOWN",
478+
"name": "new_port_name",
479+
"admin_state_up": true,
480+
"network_id": "a87cc70a-3e15-4acf-8205-9b711a3531b7",
481+
"tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
482+
"device_owner": "",
483+
"mac_address": "fa:16:3e:c9:cb:f0",
484+
"fixed_ips": [
485+
{
486+
"subnet_id": "a0304c3a-4f08-4c43-88af-d796509c97d2",
487+
"ip_address": "10.0.0.3"
488+
}
489+
],
490+
"allowed_address_pairs": [
491+
{
492+
"ip_address": "10.0.0.4",
493+
"mac_address": "fa:16:3e:c9:cb:f0"
494+
}
495+
],
496+
"id": "65c0ee9f-d634-4522-8954-51021b570b0d",
497+
"security_groups": [
498+
"f0ac4394-7e4a-4409-9701-ba8be283dbc3"
499+
],
500+
"value_specs": {
501+
"key": "value"
502+
},
503+
"device_id": ""
504+
}
505+
}
506+
`
507+
404508
const UpdatePortSecurityRequest = `
405509
{
406510
"port": {

openstack/networking/v2/ports/testing/requests_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,60 @@ func TestCreateWithNoSecurityGroup(t *testing.T) {
314314
})
315315
}
316316

317+
func TestCreateWithValueSpecs(t *testing.T) {
318+
th.SetupHTTP()
319+
defer th.TeardownHTTP()
320+
321+
th.Mux.HandleFunc("/v2.0/ports", func(w http.ResponseWriter, r *http.Request) {
322+
th.TestMethod(t, r, "POST")
323+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
324+
th.TestHeader(t, r, "Content-Type", "application/json")
325+
th.TestHeader(t, r, "Accept", "application/json")
326+
th.TestJSONRequest(t, r, CreateValueSpecRequest)
327+
328+
w.Header().Add("Content-Type", "application/json")
329+
w.WriteHeader(http.StatusCreated)
330+
331+
fmt.Fprintf(w, CreateValueSpecResponse)
332+
})
333+
334+
asu := true
335+
options := ports.CreateOpts{
336+
Name: "private-port",
337+
AdminStateUp: &asu,
338+
NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7",
339+
FixedIPs: []ports.IP{
340+
{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
341+
},
342+
SecurityGroups: &[]string{"foo"},
343+
AllowedAddressPairs: []ports.AddressPair{
344+
{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
345+
},
346+
ValueSpecs: &map[string]string{
347+
"key": "value",
348+
},
349+
}
350+
n, err := ports.Create(fake.ServiceClient(), options).Extract()
351+
th.AssertNoErr(t, err)
352+
353+
th.AssertEquals(t, n.Status, "DOWN")
354+
th.AssertEquals(t, n.Name, "private-port")
355+
th.AssertEquals(t, n.AdminStateUp, true)
356+
th.AssertEquals(t, n.NetworkID, "a87cc70a-3e15-4acf-8205-9b711a3531b7")
357+
th.AssertEquals(t, n.TenantID, "d6700c0c9ffa4f1cb322cd4a1f3906fa")
358+
th.AssertEquals(t, n.DeviceOwner, "")
359+
th.AssertEquals(t, n.MACAddress, "fa:16:3e:c9:cb:f0")
360+
th.AssertDeepEquals(t, n.FixedIPs, []ports.IP{
361+
{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
362+
})
363+
th.AssertEquals(t, n.ID, "65c0ee9f-d634-4522-8954-51021b570b0d")
364+
th.AssertDeepEquals(t, n.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"})
365+
th.AssertDeepEquals(t, n.AllowedAddressPairs, []ports.AddressPair{
366+
{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
367+
})
368+
th.AssertDeepEquals(t, n.ValueSpecs, map[string]string{"key": "value"})
369+
}
370+
317371
func TestRequiredCreateOpts(t *testing.T) {
318372
res := ports.Create(fake.ServiceClient(), ports.CreateOpts{})
319373
if res.Err == nil {
@@ -452,6 +506,35 @@ func TestUpdateOmitSecurityGroups(t *testing.T) {
452506
th.AssertDeepEquals(t, s.SecurityGroups, []string{"f0ac4394-7e4a-4409-9701-ba8be283dbc3"})
453507
}
454508

509+
func TestUpdateValueSpecs(t *testing.T) {
510+
th.SetupHTTP()
511+
defer th.TeardownHTTP()
512+
513+
th.Mux.HandleFunc("/v2.0/ports/65c0ee9f-d634-4522-8954-51021b570b0d", func(w http.ResponseWriter, r *http.Request) {
514+
th.TestMethod(t, r, "PUT")
515+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
516+
th.TestHeader(t, r, "Content-Type", "application/json")
517+
th.TestHeader(t, r, "Accept", "application/json")
518+
th.TestJSONRequest(t, r, UpdateValueSpecsRequest)
519+
520+
w.Header().Add("Content-Type", "application/json")
521+
w.WriteHeader(http.StatusOK)
522+
523+
fmt.Fprintf(w, UpdateValueSpecsResponse)
524+
})
525+
526+
options := ports.UpdateOpts{
527+
ValueSpecs: &map[string]string{
528+
"key": "value",
529+
},
530+
}
531+
532+
s, err := ports.Update(fake.ServiceClient(), "65c0ee9f-d634-4522-8954-51021b570b0d", options).Extract()
533+
th.AssertNoErr(t, err)
534+
535+
th.AssertDeepEquals(t, s.ValueSpecs, map[string]string{"key": "value"})
536+
}
537+
455538
func TestUpdatePortSecurity(t *testing.T) {
456539
th.SetupHTTP()
457540
defer th.TeardownHTTP()

0 commit comments

Comments
 (0)