Skip to content

Commit

Permalink
support for Privnet Options. (#644)
Browse files Browse the repository at this point in the history
# Description


```
./exo compute private-network create test -z ch-gva-2 --dns-server="1.1.1.1" --dns-server="0.0.0.0" --ntp-server="1.1.1.1"
 ✔ Creating Private Network "test"... 3s
┼─────────────────┼──────────────────────────────────────┼
│ PRIVATE NETWORK │                                      │
┼─────────────────┼──────────────────────────────────────┼
│ ID              │ 3bef01a2-98de-4c7b-9c90-8df1ff103c47 │
│ Name            │ test                                 │
│ Description     │                                      │
│ Zone            │ ch-gva-2                             │
│ Type            │ manual                               │
│ Options         │                                      │
│                 │   DNS Servers   1.1.1.1, 0.0.0.0     │
│                 │   NTP Servers   1.1.1.1              │
│                 │                                      │
┼─────────────────┼──────────────────────────────────────┼

./exo compute private-network update test -z ch-gva-2 --dns-server="" --ntp-server="100.100.100.100" --domain-search="hello.com hello.world" --router="0.0.0.0"
 ✔ Updating Private Network ""... 3s
┼─────────────────┼───────────────────────────────────────────┼
│ PRIVATE NETWORK │                                           │
┼─────────────────┼───────────────────────────────────────────┼
│ ID              │ 24b642e0-9728-4b42-b103-a9484d860c1d      │
│ Name            │ test                                      │
│ Description     │                                           │
│ Zone            │ ch-gva-2                                  │
│ Type            │ manual                                    │
│ Options         │                                           │
│                 │   Routers         0.0.0.0                 │
│                 │   NTP Servers     100.100.100.100         │
│                 │   Domain Search   hello.com hello.world   │
│                 │                                           │
┼─────────────────┼───────────────────────────────────────────┼

./exo compute private-network show test
┼─────────────────┼───────────────────────────────────────────┼
│ PRIVATE NETWORK │                                           │
┼─────────────────┼───────────────────────────────────────────┼
│ ID              │ 24b642e0-9728-4b42-b103-a9484d860c1d      │
│ Name            │ test                                      │
│ Description     │                                           │
│ Zone            │ ch-gva-2                                  │
│ Type            │ manual                                    │
│ Options         │                                           │
│                 │   Routers         0.0.0.0                 │
│                 │   NTP Servers     100.100.100.100         │
│                 │   Domain Search   hello.com hello.world   │
│                 │                                           │
┼─────────────────┼───────────────────────────────────────────┼
```

<!--
* Prefix: the title with the component name being changed. Add a short
and self describing sentence to ease the review
* Please add a few lines providing context and describing the change
* Please self comment changes whenever applicable to help with the
review process
* Please keep the checklist as part of the PR. Tick what applies to this
change.
-->

## Checklist
(For exoscale contributors)

* [ ] Changelog updated (under *Unreleased* block)
* [ ] Testing

## Testing

Manual

---------

Signed-off-by: Pierre-Emmanuel Jacquier <[email protected]>
Co-authored-by: Your Name <[email protected]>
Co-authored-by: Pierre-Emmanuel Jacquier <[email protected]>
  • Loading branch information
3 people authored Nov 4, 2024
1 parent f0aea5f commit ad822e9
Show file tree
Hide file tree
Showing 13 changed files with 561 additions and 151 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased

### Features

- Private Network: support for DHCP options (dns-server/ntp-server/router/domain-search)

### Improvements

- Private Network: related commands are migrated to egoscale v3

### Bug fixes

- storage: handle errors in batch objects delete action #627
Expand Down
99 changes: 64 additions & 35 deletions cmd/private_network_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ import (

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/utils"
egoscale "github.com/exoscale/egoscale/v2"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

type privateNetworkCreateCmd struct {
Expand All @@ -22,11 +19,15 @@ type privateNetworkCreateCmd struct {

Name string `cli-arg:"#"`

Description string `cli-usage:"Private Network description"`
EndIP string `cli-usage:"managed Private Network range end IP address"`
Netmask string `cli-usage:"managed Private Network netmask"`
StartIP string `cli-usage:"managed Private Network range start IP address"`
Zone string `cli-short:"z" cli-usage:"Private Network zone"`
Description string `cli-usage:"Private Network description"`
EndIP string `cli-usage:"Private Network range end IP address"`
StartIP string `cli-usage:"Private Network range start IP address"`
Zone v3.ZoneName `cli-short:"z" cli-usage:"Private Network zone"`
Netmask string `cli-usage:"DHCP option 1: Subnet netmask"`
DNSServers []string `cli-flag:"dns-server" cli-usage:"DHCP option 6: DNS servers (can be specified multiple times)"`
NTPServers []string `cli-flag:"ntp-server" cli-usage:"DHCP option 42: NTP servers (can be specified multiple times)"`
Routers []string `cli-flag:"router" cli-usage:"DHCP option 3: Routers (can be specified multiple times)"`
DomainSearch []string `cli-usage:"DHCP option 119: domain search list (limited to 255 octets, can be specified multiple times)"`
}

func (c *privateNetworkCreateCmd) cmdAliases() []string { return gCreateAlias }
Expand All @@ -48,37 +49,65 @@ func (c *privateNetworkCreateCmd) cmdPreRun(cmd *cobra.Command, args []string) e
}

func (c *privateNetworkCreateCmd) cmdRun(_ *cobra.Command, _ []string) error {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, c.Zone))

privateNetwork := &egoscale.PrivateNetwork{
Description: utils.NonEmptyStringPtr(c.Description),
EndIP: func() (v *net.IP) {
if c.EndIP != "" {
ip := net.ParseIP(c.EndIP)
v = &ip
ctx := gContext
client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

req := v3.CreatePrivateNetworkRequest{
Name: c.Name,
Description: c.Description,
EndIP: net.ParseIP(c.EndIP),
Netmask: net.ParseIP(c.Netmask),
StartIP: net.ParseIP(c.StartIP),
}

opts := &v3.PrivateNetworkOptions{}

if len(c.DNSServers) > 0 {
for _, server := range c.DNSServers {
if ip := net.ParseIP(server); ip != nil {
opts.DNSServers = append(opts.DNSServers, ip)
} else {
return fmt.Errorf("invalid DNS server IP address: %q", server)
}
return
}(),
Name: &c.Name,
Netmask: func() (v *net.IP) {
if c.Netmask != "" {
ip := net.ParseIP(c.Netmask)
v = &ip
}
}

if len(c.NTPServers) > 0 {
for _, server := range c.NTPServers {
if ip := net.ParseIP(server); ip != nil {
opts.NtpServers = append(opts.NtpServers, ip)
} else {
return fmt.Errorf("invalid NTP server IP address: %q", server)
}
return
}(),
StartIP: func() (v *net.IP) {
if c.StartIP != "" {
ip := net.ParseIP(c.StartIP)
v = &ip
}
}

if len(c.Routers) > 0 {
for _, router := range c.Routers {
if ip := net.ParseIP(router); ip != nil {
opts.Routers = append(opts.Routers, ip)
} else {
return fmt.Errorf("invalid router IP address: %q", router)
}
return
}(),
}
}

if len(c.DomainSearch) > 0 {
opts.DomainSearch = c.DomainSearch
}

req.Options = opts

op, err := client.CreatePrivateNetwork(ctx, req)
if err != nil {
return err
}

var err error
decorateAsyncOperation(fmt.Sprintf("Creating Private Network %q...", c.Name), func() {
privateNetwork, err = globalstate.EgoscaleClient.CreatePrivateNetwork(ctx, c.Zone, privateNetwork)
op, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})
if err != nil {
return err
Expand All @@ -87,7 +116,7 @@ func (c *privateNetworkCreateCmd) cmdRun(_ *cobra.Command, _ []string) error {
if !globalstate.Quiet {
return (&privateNetworkShowCmd{
cliCommandSettings: c.cliCommandSettings,
PrivateNetwork: *privateNetwork.ID,
PrivateNetwork: op.Reference.ID.String(),
Zone: c.Zone,
}).cmdRun(nil, nil)
}
Expand Down
31 changes: 20 additions & 11 deletions cmd/private_network_delete.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package cmd

import (
"errors"
"fmt"

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

type privateNetworkDeleteCmd struct {
Expand All @@ -18,8 +16,8 @@ type privateNetworkDeleteCmd struct {

PrivateNetwork string `cli-arg:"#" cli-usage:"NAME|ID"`

Force bool `cli-short:"f" cli-usage:"don't prompt for confirmation"`
Zone string `cli-short:"z" cli-usage:"Private Network zone"`
Force bool `cli-short:"f" cli-usage:"don't prompt for confirmation"`
Zone v3.ZoneName `cli-short:"z" cli-usage:"Private Network zone"`
}

func (c *privateNetworkDeleteCmd) cmdAliases() []string { return gRemoveAlias }
Expand All @@ -36,13 +34,19 @@ func (c *privateNetworkDeleteCmd) cmdPreRun(cmd *cobra.Command, args []string) e
}

func (c *privateNetworkDeleteCmd) cmdRun(_ *cobra.Command, _ []string) error {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, c.Zone))
ctx := gContext
client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

privateNetwork, err := globalstate.EgoscaleClient.FindPrivateNetwork(ctx, c.Zone, c.PrivateNetwork)
resp, err := client.ListPrivateNetworks(ctx)
if err != nil {
return err
}

pn, err := resp.FindPrivateNetwork(c.PrivateNetwork)
if err != nil {
if errors.Is(err, exoapi.ErrNotFound) {
return fmt.Errorf("resource not found in zone %q", c.Zone)
}
return err
}

Expand All @@ -52,8 +56,13 @@ func (c *privateNetworkDeleteCmd) cmdRun(_ *cobra.Command, _ []string) error {
}
}

op, err := client.DeletePrivateNetwork(ctx, pn.ID)
if err != nil {
return err
}

decorateAsyncOperation(fmt.Sprintf("Deleting Private Network %s...", c.PrivateNetwork), func() {
err = globalstate.EgoscaleClient.DeletePrivateNetwork(ctx, c.Zone, privateNetwork)
_, err = client.Wait(ctx, op, v3.OperationStateSuccess)
})
if err != nil {
return err
Expand Down
42 changes: 25 additions & 17 deletions cmd/private_network_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ import (

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
"github.com/exoscale/cli/pkg/output"
"github.com/exoscale/cli/utils"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

type privateNetworkListItemOutput struct {
ID string `json:"id"`
Name string `json:"name"`
Zone string `json:"zone"`
ID v3.UUID `json:"id"`
Name string `json:"name"`
Zone v3.ZoneName `json:"zone"`
}

type privateNetworkListOutput []privateNetworkListItemOutput
Expand All @@ -31,7 +30,7 @@ type privateNetworkListCmd struct {

_ bool `cli-cmd:"list"`

Zone string `cli-short:"z" cli-usage:"zone to filter results to"`
Zone v3.ZoneName `cli-short:"z" cli-usage:"zone to filter results to"`
}

func (c *privateNetworkListCmd) cmdAliases() []string { return gListAlias }
Expand All @@ -50,12 +49,21 @@ func (c *privateNetworkListCmd) cmdPreRun(cmd *cobra.Command, args []string) err
}

func (c *privateNetworkListCmd) cmdRun(_ *cobra.Command, _ []string) error {
var zones []string
client := globalstate.EgoscaleV3Client
ctx := gContext

resp, err := client.ListZones(ctx)
if err != nil {
return err
}
zones := resp.Zones

if c.Zone != "" {
zones = []string{c.Zone}
} else {
zones = utils.AllZones
endpoint, err := client.GetZoneAPIEndpoint(ctx, c.Zone)
if err != nil {
return err
}
zones = []v3.Zone{{APIEndpoint: endpoint}}
}

out := make(privateNetworkListOutput, 0)
Expand All @@ -68,19 +76,19 @@ func (c *privateNetworkListCmd) cmdRun(_ *cobra.Command, _ []string) error {
}
done <- struct{}{}
}()
err := utils.ForEachZone(zones, func(zone string) error {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone))
err = utils.ForEveryZone(zones, func(zone v3.Zone) error {

list, err := globalstate.EgoscaleClient.ListPrivateNetworks(ctx, zone)
c := client.WithEndpoint((zone.APIEndpoint))
resp, err := c.ListPrivateNetworks(ctx)
if err != nil {
return fmt.Errorf("unable to list Private Networks in zone %s: %w", zone, err)
}

for _, p := range list {
for _, p := range resp.PrivateNetworks {
res <- privateNetworkListItemOutput{
ID: *p.ID,
Name: *p.Name,
Zone: zone,
ID: p.ID,
Name: p.Name,
Zone: zone.Name,
}
}

Expand Down
Loading

0 comments on commit ad822e9

Please sign in to comment.