Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for Privnet Options. #644

Merged
merged 21 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 78 additions & 28 deletions cmd/private_network_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ 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 +20,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 +50,85 @@ 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))
ctx := gContext
client, err := switchClientZoneV3(ctx, globalstate.EgoscaleV3Client, c.Zone)
if err != nil {
return err
}

privateNetwork := &egoscale.PrivateNetwork{
Description: utils.NonEmptyStringPtr(c.Description),
EndIP: func() (v *net.IP) {
req := v3.CreatePrivateNetworkRequest{
Description: func() string {
if c.Description != "" {
return *utils.NonEmptyStringPtr(c.Description)
}
return ""
}(),
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
EndIP: func() net.IP {
if c.EndIP != "" {
ip := net.ParseIP(c.EndIP)
v = &ip
return net.ParseIP(c.EndIP)
}
return
return nil
}(),
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
Name: &c.Name,
Netmask: func() (v *net.IP) {
Name: c.Name,
Netmask: func() net.IP {
if c.Netmask != "" {
ip := net.ParseIP(c.Netmask)
v = &ip
return net.ParseIP(c.Netmask)
}
return
return nil
}(),
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
StartIP: func() (v *net.IP) {
StartIP: func() net.IP {
if c.StartIP != "" {
ip := net.ParseIP(c.StartIP)
v = &ip
return net.ParseIP(c.StartIP)
}
return
return nil
}(),
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
}

var err error
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)
}
}
}

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)
}
}
}

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)
}
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
}
}

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

req.Options = opts

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

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,8 +137,8 @@ func (c *privateNetworkCreateCmd) cmdRun(_ *cobra.Command, _ []string) error {
if !globalstate.Quiet {
return (&privateNetworkShowCmd{
cliCommandSettings: c.cliCommandSettings,
PrivateNetwork: *privateNetwork.ID,
Zone: c.Zone,
PrivateNetwork: op.Reference.ID.String(),
Zone: v3.ZoneName(c.Zone),
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
}).cmdRun(nil, nil)
}

Expand Down
36 changes: 25 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,24 @@ 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 {
return err
}

privateNetwork, err := client.GetPrivateNetwork(ctx, pn.ID)
arthuraliiev marked this conversation as resolved.
Show resolved Hide resolved
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 +61,13 @@ func (c *privateNetworkDeleteCmd) cmdRun(_ *cobra.Command, _ []string) error {
}
}

op, err := client.DeletePrivateNetwork(ctx, privateNetwork.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
77 changes: 37 additions & 40 deletions cmd/private_network_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ 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 +29,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,50 +48,49 @@ 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)
res := make(chan privateNetworkListItemOutput)
done := make(chan struct{})

go func() {
for nlb := range res {
out = append(out, nlb)
}
done <- struct{}{}
}()
err := utils.ForEachZone(zones, func(zone string) error {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, zone))
var responseError error
var errorZones []string

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

for _, p := range list {
res <- privateNetworkListItemOutput{
ID: *p.ID,
Name: *p.Name,
Zone: zone,
resp, err := c.ListPrivateNetworks(ctx)
if err != nil {
responseError = err
errorZones = append(errorZones, string(zone.Name))
pierre-emmanuelJ marked this conversation as resolved.
Show resolved Hide resolved
} else {
for _, p := range resp.PrivateNetworks {
out = append(out, privateNetworkListItemOutput{
ID: p.ID,
Name: p.Name,
Zone: zone.Name,
})
}
}

return nil
})
if err != nil {
_, _ = fmt.Fprintf(os.Stderr,
"warning: errors during listing, results might be incomplete.\n%s\n", err) // nolint:golint
}

close(res)
<-done

if responseError != nil {
fmt.Fprintf(os.Stderr, "warning: error during listing private networks in %s zones, results might be incomplete:\n%s\n", errorZones, responseError) // nolint:golint
}
return c.outputFunc(&out, nil)
}

Expand Down
Loading
Loading