Skip to content

Commit

Permalink
feat: Add support for bgp dynamic neighbours subcommand for metal gat…
Browse files Browse the repository at this point in the history
…eway

Signed-off-by: Ayush Rangwala <[email protected]>
  • Loading branch information
aayushrangwala committed Jan 15, 2024
1 parent 01f781b commit 9eb41dd
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/metal_gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ A Metal Gateway provides a single IPv4 address as a gateway for a subnet. For mo
### SEE ALSO

* [metal](metal.md) - Command line interface for Equinix Metal
* [metal gateway bgp-dynamic-neighbour](metal_gateway_bgp-dynamic-neighbour.md) - Metal Gateway BGP Dynamic Neighbour operations: create, delete, and get, list
* [metal gateway create](metal_gateway_create.md) - Creates a Metal Gateway.
* [metal gateway delete](metal_gateway_delete.md) - Deletes a Metal Gateway.
* [metal gateway get](metal_gateway_get.md) - Lists Metal Gateways.
Expand Down
33 changes: 33 additions & 0 deletions docs/metal_gateway_bgp-dynamic-neighbour.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## metal gateway bgp-dynamic-neighbour

Metal Gateway BGP Dynamic Neighbour operations: create, delete, and get, list

### Options

```
-h, --help help for bgp-dynamic-neighbour
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal gateway](metal_gateway.md) - Metal Gateway operations: create, delete, and retrieve.
* [metal gateway bgp-dynamic-neighbour ](metal_gateway_bgp-dynamic-neighbour_.md) -
* [metal gateway bgp-dynamic-neighbour ](metal_gateway_bgp-dynamic-neighbour_.md) -
* [metal gateway bgp-dynamic-neighbour ](metal_gateway_bgp-dynamic-neighbour_.md) -
* [metal gateway bgp-dynamic-neighbour ](metal_gateway_bgp-dynamic-neighbour_.md) -

34 changes: 34 additions & 0 deletions docs/metal_gateway_bgp-dynamic-neighbour_.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## metal gateway bgp-dynamic-neighbour



```
metal gateway bgp-dynamic-neighbour [flags]
```

### Options

```
--bgp-neighbour-id string
-h, --help help for this command
```

### Options inherited from parent commands

```
--config string Path to JSON or YAML configuration file (METAL_CONFIG)
--exclude strings Comma separated Href references to collapse in results, may be dotted three levels deep
--filter stringArray Filter 'get' actions with name value pairs. Filter is not supported by all resources and is implemented as request query parameters.
--http-header strings Headers to add to requests (in format key=value)
--include strings Comma separated Href references to expand in results, may be dotted three levels deep
-o, --output string Output format (*table, json, yaml). env output formats are (*sh, terraform, capp).
--search string Search keyword for use in 'get' actions. Search is not supported by all resources.
--sort-by string Sort fields for use in 'get' actions. Sort is not supported by all resources.
--sort-dir string Sort field direction for use in 'get' actions. Sort is not supported by all resources.
--token string Metal API Token (METAL_AUTH_TOKEN)
```

### SEE ALSO

* [metal gateway bgp-dynamic-neighbour](metal_gateway_bgp-dynamic-neighbour.md) - Metal Gateway BGP Dynamic Neighbour operations: create, delete, and get, list

55 changes: 55 additions & 0 deletions internal/gateway/bgp-dynamic-neighbours/bgp-dynamic-neighbours.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package bgp_dynamic_neighbours

import (
metal "github.com/equinix/equinix-sdk-go/services/metalv1"
"github.com/equinix/metal-cli/internal/outputs"

"github.com/spf13/cobra"
)

type Client struct {
Servicer Servicer
Service *metal.VRFsApiService
Out outputs.Outputer
}

func (c *Client) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: `bgp-dynamic-neighbour`,
Aliases: []string{"bgp-neighbour", "neighbours"},
Short: "Metal Gateway BGP Dynamic Neighbour operations: create, delete, and get, list",
Long: "",

PersistentPreRun: func(cmd *cobra.Command, args []string) {
if root := cmd.Root(); root != nil {
if root.PersistentPreRun != nil {
root.PersistentPreRun(cmd, args)
}

c.Service = c.Servicer.MetalAPI(cmd).VRFsApi
}
},
}

cmd.AddCommand(
c.Create(),
c.Get(),
c.List(),
c.Delete(),
)
return cmd
}

type Servicer interface {
MetalAPI(*cobra.Command) *metal.APIClient
Filters() map[string]string
Includes(defaultIncludes []string) (incl []string)
Excludes(defaultExcludes []string) (excl []string)
}

func NewClient(s Servicer, out outputs.Outputer) *Client {
return &Client{
Servicer: s,
Out: out,
}
}
81 changes: 81 additions & 0 deletions internal/gateway/bgp-dynamic-neighbours/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright © 2024 Equinix Metal Developers <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package bgp_dynamic_neighbours

import (
"context"
"fmt"
"strconv"

"github.com/pkg/errors"

metal "github.com/equinix/equinix-sdk-go/services/metalv1"
"github.com/spf13/cobra"
)

func (c *Client) Create() *cobra.Command {
var gatewayId, bgpNeighbourRange string
var asn int32

// createGwBgpCmd represents the creation of gateway bgp dynamic neighbour command
createGwBgpCmd := &cobra.Command{
Use: ``,
Short: "",
Long: "",
Example: ``,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

// "192.168.1.0/25", int32(12345)
if bgpNeighbourRange == "" {
fmt.Println("Please provide BGP neighbour IP range")
return nil
}
if asn == 0 {
fmt.Println("Please provide BGP neighbour ASN")
return nil
}

bgpNeighbour, _, err := c.Service.
CreateBgpDynamicNeighbor(context.Background(), gatewayId).
BgpDynamicNeighborCreateInput(*metal.NewBgpDynamicNeighborCreateInput(bgpNeighbourRange, asn)).
Execute()
if err != nil {
return errors.WithMessage(err, "Could not create BGP Dynamic Neighbour")
}

data := make([][]string, 1)
data[0] = []string{bgpNeighbour.GetId(), bgpNeighbour.GetBgpNeighborRange(),
strconv.Itoa(int(bgpNeighbour.GetBgpNeighborAsn())), string(bgpNeighbour.GetState()), bgpNeighbour.GetCreatedAt().String()}
header := []string{"ID", "Range", "ASN", "State", "Created"}

return c.Out.Output(bgpNeighbour, header, &data)
},
}

createGwBgpCmd.Flags().StringVar(&gatewayId, "gateway-id", "", "")
createGwBgpCmd.Flags().StringVar(&bgpNeighbourRange, "bgp-neighbour-range", "", "")
createGwBgpCmd.Flags().Int32Var(&asn, "asn", 0, "")

_ = createGwBgpCmd.MarkFlagRequired("gateway-id")
return createGwBgpCmd
}
61 changes: 61 additions & 0 deletions internal/gateway/bgp-dynamic-neighbours/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright © 2024 Equinix Metal Developers <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package bgp_dynamic_neighbours

import (
"context"
"fmt"

"github.com/pkg/errors"

"github.com/spf13/cobra"
)

func (c *Client) Delete() *cobra.Command {
var bgpNeighbourId string

// deleteGwBgpCmd represents the delete gateway bgp dynamic neighbour command
deleteGwBgpCmd := &cobra.Command{
Use: ``,
Short: "",
Long: "",
Example: ``,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

_, _, err := c.Service.
DeleteBgpDynamicNeighborById(context.Background(), bgpNeighbourId).
Execute()
if err != nil {
return errors.WithMessage(err, "Could not create BGP Dynamic Neighbour")
}

fmt.Println("BGP Dynamic Neighbour deletion initiated. Please check 'metal gateway bgp-dynamic-neighbour get -i", bgpNeighbourId, "' for status")
return nil
},
}

deleteGwBgpCmd.Flags().StringVar(&bgpNeighbourId, "bgp-neighbour-id", "", "")

_ = deleteGwBgpCmd.MarkFlagRequired("bgp-neighbour-id")
return deleteGwBgpCmd
}
44 changes: 44 additions & 0 deletions internal/gateway/bgp-dynamic-neighbours/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package bgp_dynamic_neighbours

import (
"context"
"fmt"
"strconv"

"github.com/spf13/cobra"
)

func (c *Client) Get() *cobra.Command {
var bgpNeighbourID string

// getGwayBgpDynamicNeighbourCmd represents command to get Metal Gateway Dynamic Neighbour by ID.
getGwayBgpDynamicNeighbourCmd := &cobra.Command{
Use: ``,
Short: "",
Long: "",
Example: ``,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

n, _, err := c.Service.
BgpDynamicNeighborsIdGet(context.Background(), bgpNeighbourID).
Execute()
if err != nil {
return fmt.Errorf("Could not create Metal Gateway: %w", err)
}

data := make([][]string, 1)

data[0] = []string{n.GetId(), n.GetBgpNeighborRange(),
strconv.Itoa(int(n.GetBgpNeighborAsn())), string(n.GetState()), n.GetCreatedAt().String()}
header := []string{"ID", "Range", "ASN", "State", "Created"}

return c.Out.Output(n, header, &data)
},
}

getGwayBgpDynamicNeighbourCmd.Flags().StringVar(&bgpNeighbourID, "bgp-dynamic-neighbour-id", "", "BGP Dynamic Neighbour ID. Ex: []")
_ = getGwayBgpDynamicNeighbourCmd.MarkFlagRequired("bgp-dynamic-neighbour-id")
return getGwayBgpDynamicNeighbourCmd
}
46 changes: 46 additions & 0 deletions internal/gateway/bgp-dynamic-neighbours/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package bgp_dynamic_neighbours

import (
"context"
"fmt"
"strconv"

"github.com/spf13/cobra"
)

func (c *Client) List() *cobra.Command {
var gatewayId string

// createMetalGatewayCmd represents the createMetalGateway command
createMetalGatewayCmd := &cobra.Command{
Use: ``,
Short: "",
Long: "",
Example: ``,

RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

n, _, err := c.Service.
GetBgpDynamicNeighbors(context.Background(), gatewayId).
Execute()
if err != nil {
return fmt.Errorf("Could not list BGP Dynamic Neighbours for Metal Gateway [%s]: %w", gatewayId, err)
}

data := make([][]string, len(n.GetBgpDynamicNeighbors()))
for _, neighbour := range n.GetBgpDynamicNeighbors() {
data[0] = []string{neighbour.GetId(), neighbour.GetBgpNeighborRange(),
strconv.Itoa(int(neighbour.GetBgpNeighborAsn())), string(neighbour.GetState()), neighbour.GetCreatedAt().String()}
}

header := []string{"ID", "Range", "ASN", "State", "Created"}
return c.Out.Output(n, header, &data)
},
}

createMetalGatewayCmd.Flags().StringVar(&gatewayId, "gateway-id", "", "")

_ = createMetalGatewayCmd.MarkFlagRequired("gateway-id")
return createMetalGatewayCmd
}
2 changes: 2 additions & 0 deletions internal/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package gateway

import (
neighbours "github.com/equinix/metal-cli/internal/gateway/bgp-dynamic-neighbours"
"github.com/equinix/metal-cli/internal/outputs"

metal "github.com/equinix/equinix-sdk-go/services/metalv1"
Expand Down Expand Up @@ -54,6 +55,7 @@ func (c *Client) NewCommand() *cobra.Command {
c.Retrieve(),
c.Create(),
c.Delete(),
neighbours.NewClient(c.Servicer, c.Out).NewCommand(),
)
return cmd
}
Expand Down

0 comments on commit 9eb41dd

Please sign in to comment.