Skip to content

Commit

Permalink
[Feat.] Enterprise VPN Connection Monitoring and EVPN Tags
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-sidelnikov committed Oct 3, 2024
1 parent 9184246 commit 85e7626
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 1 deletion.
78 changes: 77 additions & 1 deletion acceptance/openstack/evpn/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import (
"github.com/opentelekomcloud/gophertelekomcloud/openstack/common/pointerto"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/common/tags"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/connection"
cm "github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/connection-monitoring"
cgw "github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/customer-gateway"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/gateway"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/quota"
vpntags "github.com/opentelekomcloud/gophertelekomcloud/openstack/evpn/v5/tags"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/networking/v1/eips"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/networking/v2/subnets"
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
Expand Down Expand Up @@ -73,7 +76,6 @@ func TestConnectionLifecycle(t *testing.T) {
t.Logf("Attempting to DELETE Enterprise VPN Connection: %s", gw.ID)
th.AssertNoErr(t, connection.Delete(client, conn.ID))
th.AssertNoErr(t, WaitForConnectionDeleted(client, conn.ID, 800))

})

t.Logf("Attempting to GET Enterprise VPN Connection: %s", conn.ID)
Expand Down Expand Up @@ -106,6 +108,52 @@ func TestConnectionLifecycle(t *testing.T) {
})
th.AssertNoErr(t, err)
th.AssertEquals(t, 1, len(connList))

t.Logf("Attempting to CREATE Enterprise VPN Connection Monitoring")
monitoring, err := cm.Create(client, cm.CreateOpts{ConnectionID: conn.ID})
th.AssertNoErr(t, err)
th.AssertNoErr(t, WaitForConnectionMonitoringActive(client, monitoring.ID, 800))
th.AssertEquals(t, conn.ID, monitoring.ConnectionId)

t.Cleanup(func() {
t.Logf("Attempting to DELETE Enterprise VPN Connection Monitoring: %s", monitoring.ID)
th.AssertNoErr(t, cm.Delete(client, monitoring.ID))
th.AssertNoErr(t, WaitForConnectionMonitoringDeleted(client, monitoring.ID, 800))
})

t.Logf("Attempting to GET Enterprise VPN Connection Monitor: %s", monitoring.ID)
monitor, err := cm.Get(client, monitoring.ID)
th.AssertNoErr(t, err)
th.AssertEquals(t, "ACTIVE", monitor.Status)

t.Logf("Attempting to LIST Enterprise VPN Connection Monitor: %s", monitoring.ID)
monitorList, err := cm.List(client, cm.ListOpts{ConnectionId: conn.ID})
th.AssertNoErr(t, err)
th.AssertEquals(t, 1, len(monitorList))

t.Logf("Attempting to GET Enterprise VPN Quotas: %s", monitoring.ID)
quotas, err := quota.Get(client)
th.AssertNoErr(t, err)
th.AssertEquals(t, 3, len(quotas.Resources))

extraTag := []tags.ResourceTag{
{
Key: "One",
Value: "gopher",
},
}
t.Logf("Attempting to CREATE Enterprise VPN Connection Tag: %s", extraTag)
err = vpntags.Create(client, "vpn-connection", conn.ID, vpntags.TagsOpts{Tags: extraTag})
th.AssertNoErr(t, err)

t.Cleanup(func() {
t.Logf("Attempting to DELETE Enterprise VPN Connection Tag: %s", extraTag)
th.AssertNoErr(t, vpntags.Delete(client, "vpn-connection", conn.ID, vpntags.TagsOpts{Tags: extraTag}))
})
t.Logf("Attempting to LIST Enterprise VPN Connection Tags: %s", conn.ID)
tagList, err := vpntags.List(client, "vpn-connection", conn.ID)
th.AssertNoErr(t, err)
th.AssertEquals(t, 2, len(tagList))
}

func createEvpnCustomerGateway(t *testing.T, client *golangsdk.ServiceClient) *cgw.CustomerGateway {
Expand All @@ -132,6 +180,7 @@ func createEvpnCustomerGateway(t *testing.T, client *golangsdk.ServiceClient) *c
})
return gw
}

func createEvpnGateway(t *testing.T, subnet *subnets.Subnet, vpcId string, client *golangsdk.ServiceClient) *gateway.Gateway {
clientNetV1, err := clients.NewNetworkV1Client()
th.AssertNoErr(t, err)
Expand Down Expand Up @@ -210,3 +259,30 @@ func WaitForConnectionActive(c *golangsdk.ServiceClient, id string, secs int) er
return false, nil
})
}

func WaitForConnectionMonitoringDeleted(c *golangsdk.ServiceClient, id string, secs int) error {
return golangsdk.WaitFor(secs, func() (bool, error) {
_, err := cm.Get(c, id)
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
return true, nil
}
return false, fmt.Errorf("error retriving connection status: %w", err)
}
return false, nil
})
}

func WaitForConnectionMonitoringActive(c *golangsdk.ServiceClient, id string, secs int) error {
return golangsdk.WaitFor(secs, func() (bool, error) {
current, err := cm.Get(c, id)
if err != nil {
return false, err
}

if current.Status == "ACTIVE" {
return true, nil
}
return false, nil
})
}
50 changes: 50 additions & 0 deletions openstack/evpn/v5/connection-monitoring/Create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package connection_monitoring

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type CreateOpts struct {
// Specifies the ID of the VPN connection to be monitored.
ConnectionID string `json:"vpn_connection_id" required:"true"`
}

func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*Monitor, error) {
b, err := build.RequestBody(opts, "connection_monitor")
if err != nil {
return nil, err
}

raw, err := client.Post(client.ServiceURL("connection-monitors"), b, nil, &golangsdk.RequestOpts{
OkCodes: []int{202, 201},
})
if err != nil {
return nil, err
}

var res Monitor
return &res, extract.IntoStructPtr(raw.Body, &res, "connection_monitor")
}

type Monitor struct {
// Specifies the ID of a VPN connection monitor.
ID string `json:"id"`
// Specifies the ID of the VPN connection to be monitored.
ConnectionId string `json:"vpn_connection_id"`
// Specifies the type of objects to be monitored.
Type string `json:"type"`
// Specifies the source address to be monitored.
SourceIp string `json:"source_ip"`
// Specifies the destination address to be monitored.
DestinationIp string `json:"destination_ip"`
// Specifies the protocol used by NQA.
ProtoType string `json:"proto_type"`
// Specifies the status of the VPN connection monitor.
// Value range:
// ACTIVE: normal
// PENDING_CREATE: creating
// PENDING_DELETE: deleting
Status string `json:"status"`
}
10 changes: 10 additions & 0 deletions openstack/evpn/v5/connection-monitoring/Delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package connection_monitoring

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
)

func Delete(client *golangsdk.ServiceClient, id string) (err error) {
_, err = client.Delete(client.ServiceURL("connection-monitors", id), nil)
return
}
17 changes: 17 additions & 0 deletions openstack/evpn/v5/connection-monitoring/Get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package connection_monitoring

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

func Get(client *golangsdk.ServiceClient, monitorId string) (*Monitor, error) {
raw, err := client.Get(client.ServiceURL("connection-monitors", monitorId), nil, nil)
if err != nil {
return nil, err
}

var res Monitor
err = extract.IntoStructPtr(raw.Body, &res, "connection_monitor")
return &res, err
}
28 changes: 28 additions & 0 deletions openstack/evpn/v5/connection-monitoring/List.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package connection_monitoring

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type ListOpts struct {
// Specifies a VPN connection ID.
ConnectionId string `q:"vpn_connection_id"`
}

func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Monitor, error) {
url, err := golangsdk.NewURLBuilder().
WithEndpoints("connection-monitors").WithQueryParams(&opts).Build()
if err != nil {
return nil, err
}

raw, err := client.Get(client.ServiceURL(url.String()), nil, nil)
if err != nil {
return nil, err
}

var res []Monitor
err = extract.IntoSlicePtr(raw.Body, &res, "connection_monitors")
return res, err
}
40 changes: 40 additions & 0 deletions openstack/evpn/v5/quota/Get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package quota

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

func Get(client *golangsdk.ServiceClient) (*Quota, error) {
url, err := golangsdk.NewURLBuilder().
WithEndpoints("vpn", "quotas").Build()
if err != nil {
return nil, err
}

raw, err := client.Get(client.ServiceURL(url.String()), nil, nil)
if err != nil {
return nil, err
}

var res Quota
err = extract.IntoStructPtr(raw.Body, &res, "quotas")
return &res, err
}

type Quota struct {
Resources []Info `json:"resources"`
}

type Info struct {
// Specifies a resource type.
// Value range:
// customer_gateway: customer gateway
// vpn_connection: Enterprise Edition VPN connection
// vpn_gateway: Enterprise Edition VPN gateway
Type string `json:"type"`
// Specifies the quota upper limit.
Quota int `json:"quota"`
// Specifies the number of resources in use.
Used int `json:"used"`
}
28 changes: 28 additions & 0 deletions openstack/evpn/v5/tags/Create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package tags

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/common/tags"
)

type TagsOpts struct {
// Specifies a tag list.
// A maximum of 20 tags can be specified.
Tags []tags.ResourceTag `json:"tags" required:"true"`
}

// Create creates tags
// resourceType Specifies the resource type.
// The value can be vpn-gateway, customer-gateway, or vpn-connection.
func Create(client *golangsdk.ServiceClient, resourceType, resourceId string, opts TagsOpts) error {
b, err := build.RequestBody(opts, "")
if err != nil {
return err
}
_, err = client.Post(client.ServiceURL(resourceType, resourceId, "tags", "create"), b, nil, &golangsdk.RequestOpts{
OkCodes: []int{204},
MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en-us"},
})
return err
}
18 changes: 18 additions & 0 deletions openstack/evpn/v5/tags/Delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tags

import (
"github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
)

func Delete(client *golangsdk.ServiceClient, resourceType, resourceId string, opts TagsOpts) error {
b, err := build.RequestBody(opts, "")
if err != nil {
return err
}
_, err = client.Post(client.ServiceURL(resourceType, resourceId, "tags", "delete"), b, nil, &golangsdk.RequestOpts{
OkCodes: []int{204},
MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en-us"},
})
return err
}
24 changes: 24 additions & 0 deletions openstack/evpn/v5/tags/List.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package tags

import (
golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/common/tags"
)

func List(client *golangsdk.ServiceClient, resourceType, resourceId string) ([]tags.ResourceTag, error) {
url, err := golangsdk.NewURLBuilder().
WithEndpoints(resourceType, resourceId, "tags").Build()
if err != nil {
return nil, err
}

raw, err := client.Get(client.ServiceURL(url.String()), nil, nil)
if err != nil {
return nil, err
}

var res []tags.ResourceTag
err = extract.IntoSlicePtr(raw.Body, &res, "tags")
return res, err
}

0 comments on commit 85e7626

Please sign in to comment.